From d7825cf87cd61a65b20fc2277b8f5e52bd7ec5f7 Mon Sep 17 00:00:00 2001 From: Rudolf Rakos <51080118+rrakos-evo@users.noreply.github.com> Date: Thu, 5 Sep 2019 15:42:09 +0200 Subject: [PATCH 001/980] Use atomics instead of synchronized for Gauge (#482) * Use atomic update instead of synchronized for Gauge * Introduce DoubleAdder#set to avoid allocations in Gauge#set Signed-off-by: Rudolf Rakos --- .../io/prometheus/client/DoubleAdder.java | 68 ++++++++++++++++++- .../main/java/io/prometheus/client/Gauge.java | 13 +--- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java b/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java index cf24031ce..8be7a6e26 100644 --- a/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java +++ b/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java @@ -94,8 +94,37 @@ public void add(double x) { * @return the sum */ public double sum() { - Cell[] as = cells; - double sum = Double.longBitsToDouble(base); + // On concurrent `sum` and `set`, it is acceptable to `get` an outdated `value`. + // On concurrent `sum` and `add`, it is acceptable to `get` an outdated `value`. + // On concurrent `sum` and `set` and `add`, it is possible to `get` an outdated `value`. + + // Correctness is guaranteed by `volatile` memory access ordering and visibility semantics. + // Program order: + // - writes in `set` - `busy` (CAS), `cells` (Wc), `base` (Wb), `busy` + // - reads in `sum` - `cells` (Rc), `base` (Rb), `busy`, `cells` (Cc), `base` (Cb) + // Note that: + // - `busy` is written after `cells` and `base` + // - `busy` is read after `cells` and `base`, then `cells` and `base` is re-read after `busy` + // In other words: + // - if we see the write to `busy`, then we must see the write to `cells` and `busy` on re-read + // - if we don't see the write to `busy`, then we must retry as we have no guarantees + // Execution order (in the former case): + // - serial + // - old result - Rc, Rb, Cc, Cb, Wc, Wb + // - new result - Wc, Wb, Rc, Rb, Cc, Cb + // - concurrent + // - old result - Rc, Wc, Rb, Wb, Cc, Cb - retry (superfluous) + // - new result - Wc, Rc, Wb, Rb, Cc, Cb + // - invalid result - Rc, Wc, Wb, Rb, Cc, Cb - retry + // - invalid result - Wc, Rc, Rb, Wb, Cc, Cb - retry + Cell[] as = cells; long b = base; + while (as != null && !(busy == 0 && cells == as && base == b)) { + // busy waiting, retry loop + Thread.yield(); + as = cells; b = base; + } + + double sum = Double.longBitsToDouble(b); if (as != null) { int n = as.length; for (int i = 0; i < n; ++i) { @@ -118,6 +147,41 @@ public void reset() { internalReset(0L); } + public void set(double x) { + // On concurrent `set` and `set`, it should be acceptable to lose one `set` measurement. + // On concurrent `set` and `add`, it should be acceptable to lose the `add` measurement. + + // Correctness is ensured by different techniques: + // - `set` waits on contention (blocking) + // - `add` avoids contention (non-blocking) + // - `sum` retries on conflicts (non-blocking) + // Performance characteristics by use cases: + // - only `set` - `cells` is always `null` - no allocations + // - only `add` - `cells` allocated on contention + // - mixed `set` and `add` - `cells` allocated on contention, `cells` deallocated on `set` + for (;;) { + Cell[] as; + if ((as = cells) != null) { // have cells + if (busy == 0 && casBusy()) { + try { + if (cells == as) { // recheck under lock + // update cells and base (not atomic) + cells = null; + base = Double.doubleToLongBits(x); + break; + } + } finally { + busy = 0; + } + } + } else { // no cells + // update base (atomic) + base = Double.doubleToLongBits(x); + break; + } + } + } + /** * Equivalent in effect to {@link #sum} followed by {@link * #reset}. This method may apply for example during quiescent diff --git a/simpleclient/src/main/java/io/prometheus/client/Gauge.java b/simpleclient/src/main/java/io/prometheus/client/Gauge.java index dc1b0d568..d646dc370 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Gauge.java +++ b/simpleclient/src/main/java/io/prometheus/client/Gauge.java @@ -134,6 +134,7 @@ public void close() { * {@link SimpleCollector#remove} or {@link SimpleCollector#clear}, */ public static class Child { + private final DoubleAdder value = new DoubleAdder(); static TimeProvider timeProvider = new TimeProvider(); @@ -166,13 +167,7 @@ public void dec(double amt) { * Set the gauge to the given value. */ public void set(double val) { - synchronized(this) { - value.reset(); - // If get() were called here it'd see an invalid value, so use a lock. - // inc()/dec() don't need locks, as all the possible outcomes - // are still possible if set() were atomic so no new races are introduced. - value.add(val); - } + value.set(val); } /** * Set the gauge to the current unixtime. @@ -234,9 +229,7 @@ public E setToTime(Callable timeable){ * Get the value of the gauge. */ public double get() { - synchronized(this) { - return value.sum(); - } + return value.sum(); } } From 3f3bf76d62cae7ab44445a788a8f9e671189e218 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Tue, 24 Sep 2019 11:42:23 +0100 Subject: [PATCH 002/980] [maven-release-plugin] prepare release parent-0.7.0 --- benchmark/pom.xml | 4 ++-- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 6 +++--- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_vertx/pom.xml | 6 +++--- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 5a8b768af..a066b407b 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -44,7 +44,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 com.codahale.metrics diff --git a/pom.xml b/pom.xml index 29822221b..47604a062 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.7.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index e102bb988..d9f1a1bb5 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index f882b57ba..1cf0d11b0 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 33c60ee9d..993b27d90 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 23593cd5b..da963c085 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index fd51174ff..14e9fb3ab 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 3fe4875e5..da45c6260 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 0c9454e2a..4700b0043 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 31b9c9882..37b32a2a0 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_servlet - 0.6.1-SNAPSHOT + 0.7.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 4be38ee34..b0877c9e0 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index ca1f6ff1e..f6360284d 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index de0325196..7888c918f 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index ae9ffba9a..348b1b875 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 9a58516af..3854703c7 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 786e8f734..ac269dec8 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 7c624b46a..58ff232ef 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 2d4925689..c123b3c57 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 362dc636b..0c326ec31 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_spring_web - 0.6.1-SNAPSHOT + 0.7.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 6cc592adb..0e1ed5c1e 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 1c0dd1dcf..9a0045159 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.6.1-SNAPSHOT + 0.7.0 io.prometheus simpleclient_common - 0.6.1-SNAPSHOT + 0.7.0 io.vertx From c2cc42921d465b2b7f5a7eb23c901126b24a5c4a Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Tue, 24 Sep 2019 11:42:31 +0100 Subject: [PATCH 003/980] [maven-release-plugin] prepare for next development iteration --- benchmark/pom.xml | 4 ++-- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 6 +++--- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_vertx/pom.xml | 6 +++--- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index a066b407b..84535b094 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -44,7 +44,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT com.codahale.metrics diff --git a/pom.xml b/pom.xml index 47604a062..4ee608a45 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.7.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index d9f1a1bb5..fc6211e55 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 1cf0d11b0..44283a3f9 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 993b27d90..9591dda53 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index da963c085..6072c2e39 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 14e9fb3ab..c9f9023f6 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index da45c6260..370251101 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 4700b0043..a982aa1c1 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 37b32a2a0..a4199dd9f 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.7.0 + 0.7.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index b0877c9e0..c1f482d43 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index f6360284d..e774cea98 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 7888c918f..2beaec384 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 348b1b875..02c60f472 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 3854703c7..4044751fc 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index ac269dec8..f50ff987a 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 58ff232ef..8f8a9ad4b 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index c123b3c57..df72f6f2d 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 0c326ec31..6e7c0cdbe 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.7.0 + 0.7.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 0e1ed5c1e..1dd2f9ef8 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 9a0045159..1eec7a254 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.7.0 + 0.7.1-SNAPSHOT io.prometheus simpleclient_common - 0.7.0 + 0.7.1-SNAPSHOT io.vertx From cc85e9a0a81d96afe6d80d0ba39ad1b347b96b8d Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Tue, 24 Sep 2019 12:43:51 +0100 Subject: [PATCH 004/980] Update for 0.7.0 We've on circleci now. Signed-off-by: Brian Brazil --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 41037dddf..591afd27b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Prometheus JVM Client It supports Java, Clojure, Scala, JRuby, and anything else that runs on the JVM. -[![Build Status](https://travis-ci.org/prometheus/client_java.png?branch=master)](https://travis-ci.org/prometheus/client_java) +[![Build Status](https://circleci.com/gh/prometheus/client_java.svg?style=svg)](https://circleci.com/gh/prometheus/client_java) + Table of Contents ================= @@ -40,25 +41,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.6.0 + 0.7.0 io.prometheus simpleclient_hotspot - 0.6.0 + 0.7.0 io.prometheus simpleclient_httpserver - 0.6.0 + 0.7.0 io.prometheus simpleclient_pushgateway - 0.6.0 + 0.7.0 ``` From ba220f75c8d4ced25b4a18cbb92abb61e6fc626e Mon Sep 17 00:00:00 2001 From: Christophe TARDELLA Date: Mon, 7 Oct 2019 13:19:28 +0200 Subject: [PATCH 005/980] Add a class cast check to avoid ClassCastException (#505) FIX #504 Signed-off-by: Christophe TARDELLA --- .../hotspot/MemoryAllocationExports.java | 10 ++++++-- .../hotspot/MemoryAllocationExportsTest.java | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java index afad2590f..b5a2754d7 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java @@ -25,8 +25,10 @@ public class MemoryAllocationExports extends Collector { public MemoryAllocationExports() { AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter); - for (GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) { - ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); + for (GarbageCollectorMXBean garbageCollectorMXBean : getGarbageCollectorMXBeans()) { + if (garbageCollectorMXBean instanceof NotificationEmitter) { + ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); + } } } @@ -97,4 +99,8 @@ private static long getAndSet(Map map, String key, long value) { return last == null ? 0 : last; } } + + protected List getGarbageCollectorMXBeans() { + return ManagementFactory.getGarbageCollectorMXBeans(); + } } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java index 0eb4d38c2..367b86333 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java @@ -2,6 +2,13 @@ import io.prometheus.client.Counter; import org.junit.Test; +import org.mockito.Mockito; + +import javax.management.NotificationEmitter; +import javax.management.NotificationFilter; +import java.lang.management.GarbageCollectorMXBean; +import java.util.Arrays; +import java.util.List; import static org.junit.Assert.assertEquals; @@ -42,4 +49,20 @@ public void testListenerLogic() { listener.handleMemoryPool("TestPool", 17, 20); assertEquals(153, child.get(), 0.001); } + + @Test + public void testConstructorShouldIgnoreNotNotificationEmitterClasses() { + final GarbageCollectorMXBean notificationEmitterMXBean = Mockito.mock(GarbageCollectorMXBean.class, Mockito.withSettings().extraInterfaces(NotificationEmitter.class)); + final GarbageCollectorMXBean notNotificationEmitterMXBean = Mockito.mock(GarbageCollectorMXBean.class); + + new MemoryAllocationExports() { + @Override + protected List getGarbageCollectorMXBeans() { + return Arrays.asList(notificationEmitterMXBean, notNotificationEmitterMXBean); + } + }; + + Mockito.verify((NotificationEmitter) notificationEmitterMXBean).addNotificationListener(Mockito.any(MemoryAllocationExports.AllocationCountingNotificationListener.class), Mockito.isNull(NotificationFilter.class), Mockito.isNull()); + Mockito.verifyZeroInteractions(notNotificationEmitterMXBean); + } } From ddf03f1a939d7c41659bdf7b4a150657ffa5cadb Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 14 Oct 2019 11:52:36 +0100 Subject: [PATCH 006/980] Allow for 200 response code from pgw 0.10.0 Signed-off-by: Brian Brazil --- .../io/prometheus/client/exporter/PushGateway.java | 4 ++-- .../io/prometheus/client/exporter/PushGatewayTest.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java index 161871acf..b8a3bbc18 100644 --- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java @@ -313,10 +313,10 @@ void doRequest(CollectorRegistry registry, String job, Map group } int response = connection.getResponseCode(); - if (response != HttpURLConnection.HTTP_ACCEPTED) { + if (response/100 != 2) { String errorMessage; InputStream errorStream = connection.getErrorStream(); - if(response >= 400 && errorStream != null) { + if(errorStream != null) { String errBody = readFromStream(errorStream); errorMessage = "Response code from " + url + " was " + response + ", response body: " + errBody; } else { diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java index e3be4dde5..0127f1db5 100644 --- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java +++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java @@ -60,6 +60,16 @@ public void testPush() throws IOException { pg.push(registry, "j"); } + @Test + public void testPush200Response() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(200)); + pg.push(registry, "j"); + } + @Test(expected=IOException.class) public void testNon202ResponseThrows() throws IOException { mockServerClient.when( From 2e002d336f08d22bb17ca9fdaae2fcdd5439e22e Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Wed, 23 Oct 2019 12:17:02 +0100 Subject: [PATCH 007/980] [maven-release-plugin] prepare release parent-0.8.0 --- benchmark/pom.xml | 4 ++-- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 6 +++--- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_vertx/pom.xml | 6 +++--- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 84535b094..cf1f81f4a 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -44,7 +44,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 com.codahale.metrics diff --git a/pom.xml b/pom.xml index 4ee608a45..a09d3f560 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.8.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index fc6211e55..116416f7f 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 44283a3f9..cbfa6fb9f 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 9591dda53..2923060c7 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 6072c2e39..3cdae3dc7 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index c9f9023f6..d6fc7a97c 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 370251101..483d62017 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index a982aa1c1..04d00d218 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index a4199dd9f..ac2ca49c2 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_servlet - 0.7.1-SNAPSHOT + 0.8.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index c1f482d43..599acd118 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index e774cea98..46f6750b3 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 2beaec384..1ece34a60 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 02c60f472..b51a37028 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 4044751fc..8b2e3d3bf 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index f50ff987a..78e842af0 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 8f8a9ad4b..4b8ae4e16 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index df72f6f2d..6d7c69a71 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 6e7c0cdbe..358eb4c2b 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_spring_web - 0.7.1-SNAPSHOT + 0.8.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 1dd2f9ef8..9cf315aeb 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 1eec7a254..8634f94d7 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.7.1-SNAPSHOT + 0.8.0 io.prometheus simpleclient_common - 0.7.1-SNAPSHOT + 0.8.0 io.vertx From 2e250e4efa5f770af9309e9ba6a3db3b4af5368c Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Wed, 23 Oct 2019 12:17:14 +0100 Subject: [PATCH 008/980] [maven-release-plugin] prepare for next development iteration --- benchmark/pom.xml | 4 ++-- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 6 +++--- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_vertx/pom.xml | 6 +++--- 21 files changed, 49 insertions(+), 49 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index cf1f81f4a..a1bcf0485 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -44,7 +44,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT com.codahale.metrics diff --git a/pom.xml b/pom.xml index a09d3f560..c33b175c8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.8.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 116416f7f..eebf7e0db 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index cbfa6fb9f..21ff86e84 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 2923060c7..840500430 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 3cdae3dc7..7a0c41b60 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index d6fc7a97c..c80fbaac0 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 483d62017..b5f62eebb 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 04d00d218..33503b925 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index ac2ca49c2..d69bdf0b8 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.8.0 + 0.8.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 599acd118..f17a7eb38 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 46f6750b3..311485d47 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 1ece34a60..1712f1645 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index b51a37028..f154d1ed1 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 8b2e3d3bf..0f9bd69fd 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 78e842af0..82493313e 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 4b8ae4e16..cd657c0ae 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 6d7c69a71..d0ac2558f 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 358eb4c2b..1e6156d34 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.8.0 + 0.8.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 9cf315aeb..54aca62c6 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 8634f94d7..e2ea10a48 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.8.0 + 0.8.1-SNAPSHOT io.prometheus simpleclient_common - 0.8.0 + 0.8.1-SNAPSHOT io.vertx From c33fab09d78d360128ad62e99d1880039e38b604 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Wed, 23 Oct 2019 12:57:07 +0100 Subject: [PATCH 009/980] Update for 0.8.0 Signed-off-by: Brian Brazil --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 591afd27b..023c6bb33 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.7.0 + 0.8.0 io.prometheus simpleclient_hotspot - 0.7.0 + 0.8.0 io.prometheus simpleclient_httpserver - 0.7.0 + 0.8.0 io.prometheus simpleclient_pushgateway - 0.7.0 + 0.8.0 ``` From b61dd232a504e20dad404a2bf3e2c0b8661c212a Mon Sep 17 00:00:00 2001 From: Dzmitry Lazerka Date: Thu, 14 Nov 2019 04:58:07 -0800 Subject: [PATCH 010/980] Don't throw NPE if `.help()` wasn't called (#458) See issue #457 Signed-off-by: Dzmitry Lazerka --- .../src/main/java/io/prometheus/client/SimpleCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java index ed8c5c8a0..a70d5d4e7 100644 --- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java +++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java @@ -162,7 +162,7 @@ protected SimpleCollector(Builder b) { } fullname = name; checkMetricName(fullname); - if (b.help.isEmpty()) throw new IllegalStateException("Help hasn't been set."); + if (b.help != null && b.help.isEmpty()) throw new IllegalStateException("Help hasn't been set."); help = b.help; labelNames = Arrays.asList(b.labelNames); From ef16c43f63128c14627eeff301a32c12e7751a4e Mon Sep 17 00:00:00 2001 From: Christian Schlichtherle Date: Thu, 5 Dec 2019 20:14:02 +0400 Subject: [PATCH 011/980] Don't wrap a RuntimeException in another RuntimeException. (#488) * Don't wrap a RuntimeException in another RuntimeException. Signed-off-by: Christian Schlichtherle --- simpleclient/src/main/java/io/prometheus/client/Histogram.java | 2 ++ simpleclient/src/main/java/io/prometheus/client/Summary.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index 2b289806a..1d8b1a2fa 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -219,6 +219,8 @@ public E time(Callable timeable) { try { return timeable.call(); + } catch (RuntimeException e) { + throw e; } catch (Exception e) { throw new RuntimeException(e); } finally { diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index a341f2515..4d79e558a 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -226,6 +226,8 @@ public E time(Callable timeable) { try { return timeable.call(); + } catch (RuntimeException e) { + throw e; } catch (Exception e) { throw new RuntimeException(e); } finally { From 58ec05265e11793af2c854789a152ce28d62fcba Mon Sep 17 00:00:00 2001 From: Simon Legner Date: Wed, 22 Jan 2020 00:47:15 +0100 Subject: [PATCH 012/980] Fix typo "Caffiene" (#521) Signed-off-by: Simon Legner --- .../prometheus/client/cache/caffeine/CacheMetricsCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java b/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java index d32ddb44c..4b7d32edf 100644 --- a/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java +++ b/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java @@ -18,7 +18,7 @@ /** - * Collect metrics from Caffiene's com.github.benmanes.caffeine.cache.Cache. + * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache. *

*

{@code
  *

From 49c355753f2a00db7bfc5ceb2cf20f0113b65642 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 23 Jan 2020 11:34:27 +0000
Subject: [PATCH 013/980] Update to also work on JVM11, use consistent mockito
 version. (#522)

Signed-off-by: Brian Brazil 
---
 benchmark/pom.xml                                            | 5 +++++
 simpleclient_caffeine/pom.xml                                | 2 +-
 simpleclient_dropwizard/pom.xml                              | 2 +-
 simpleclient_guava/pom.xml                                   | 2 +-
 simpleclient_hotspot/pom.xml                                 | 2 +-
 simpleclient_log4j/pom.xml                                   | 2 +-
 simpleclient_log4j2/pom.xml                                  | 2 +-
 simpleclient_logback/pom.xml                                 | 2 +-
 simpleclient_pushgateway/pom.xml                             | 5 +++++
 simpleclient_servlet/pom.xml                                 | 2 +-
 .../io/prometheus/client/exporter/MetricsServletTest.java    | 2 ++
 11 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index a1bcf0485..faff9340b 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -35,6 +35,11 @@
             jmh-generator-annprocess
             1.3.2
         
+        
+            javax.annotation
+            javax.annotation-api
+            1.3.1
+        
 
         
             io.prometheus
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index 21ff86e84..3f89ecb9e 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -56,7 +56,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
         
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index 7a0c41b60..1f5fd5bc4 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -58,7 +58,7 @@
         
             org.mockito
             mockito-core
-            2.10.0
+            2.28.2
             test
         
     
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index b5f62eebb..e426aabb7 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -56,7 +56,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index d69bdf0b8..6615f5237 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -56,7 +56,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
 
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index f154d1ed1..fbeed7a58 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -56,7 +56,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
     
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index 0f9bd69fd..0a5c2ea79 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -55,7 +55,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
     
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index 82493313e..06d5c7648 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -56,7 +56,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
     
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index cd657c0ae..8112f2abf 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -45,6 +45,11 @@
             simpleclient_common
             0.8.1-SNAPSHOT
         
+        
+            javax.xml.bind
+            jaxb-api
+            2.3.0
+        
         
         
             junit
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index d0ac2558f..51b89ef8d 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -76,7 +76,7 @@
         
             org.mockito
             mockito-core
-            1.9.5
+            2.28.2
             test
         
     
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
index 78e73e7fa..43f3c7d59 100644
--- a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
@@ -15,6 +15,7 @@
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.api.Assertions.fail;
 import static org.mockito.Matchers.anyChar;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -63,6 +64,7 @@ public void testWriterIsClosedOnException() throws IOException, ServletException
     PrintWriter writer = mock(PrintWriter.class);
     when(resp.getWriter()).thenReturn(writer);
     doThrow(new RuntimeException()).when(writer).write(anyChar());
+    doThrow(new RuntimeException()).when(writer).write(anyInt());
     CollectorRegistry registry = new CollectorRegistry();
     Gauge a = Gauge.build("a", "a help").register(registry);
 

From 89a69478fa1d3702919858fe57ad812fe3e35506 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 23 Jan 2020 11:47:59 +0000
Subject: [PATCH 014/980] Make javadoc work for release on jvm11

Signed-off-by: Brian Brazil 
---
 pom.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/pom.xml b/pom.xml
index c33b175c8..9fc5cc248 100644
--- a/pom.xml
+++ b/pom.xml
@@ -117,6 +117,8 @@
                     UTF-8
                     UTF-8
                     true
+                    8
+                    ${java.home}/bin/javadoc
                 
                 
                     

From 325c332317ef6055326421420f9898daee5345ed Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 23 Jan 2020 11:51:46 +0000
Subject: [PATCH 015/980] [maven-release-plugin] prepare release parent-0.8.1

---
 benchmark/pom.xml                    | 4 ++--
 pom.xml                              | 4 ++--
 simpleclient/pom.xml                 | 2 +-
 simpleclient_caffeine/pom.xml        | 4 ++--
 simpleclient_common/pom.xml          | 4 ++--
 simpleclient_dropwizard/pom.xml      | 4 ++--
 simpleclient_graphite_bridge/pom.xml | 4 ++--
 simpleclient_guava/pom.xml           | 4 ++--
 simpleclient_hibernate/pom.xml       | 4 ++--
 simpleclient_hotspot/pom.xml         | 6 +++---
 simpleclient_httpserver/pom.xml      | 6 +++---
 simpleclient_jetty/pom.xml           | 4 ++--
 simpleclient_jetty_jdk8/pom.xml      | 4 ++--
 simpleclient_log4j/pom.xml           | 4 ++--
 simpleclient_log4j2/pom.xml          | 4 ++--
 simpleclient_logback/pom.xml         | 4 ++--
 simpleclient_pushgateway/pom.xml     | 6 +++---
 simpleclient_servlet/pom.xml         | 6 +++---
 simpleclient_spring_boot/pom.xml     | 8 ++++----
 simpleclient_spring_web/pom.xml      | 6 +++---
 simpleclient_vertx/pom.xml           | 6 +++---
 21 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index faff9340b..b10c48260 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -49,7 +49,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
           com.codahale.metrics
diff --git a/pom.xml b/pom.xml
index 9fc5cc248..e7561cf6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     io.prometheus
     parent
-    0.8.1-SNAPSHOT
+    0.8.1
 
     
         org.sonatype.oss
@@ -31,7 +31,7 @@
         scm:git:git@github.com:prometheus/client_java.git
         scm:git:git@github.com:prometheus/client_java.git
         git@github.com:prometheus/client_java.git
-        HEAD
+        parent-0.8.1
     
 
     
diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml
index eebf7e0db..c0ccb6d18 100644
--- a/simpleclient/pom.xml
+++ b/simpleclient/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index 3f89ecb9e..1eb6b9e03 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             com.github.ben-manes.caffeine
diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml
index 840500430..2a101362c 100644
--- a/simpleclient_common/pom.xml
+++ b/simpleclient_common/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
         
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index 1f5fd5bc4..2823593dd 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.dropwizard.metrics
diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml
index c80fbaac0..de3e30786 100644
--- a/simpleclient_graphite_bridge/pom.xml
+++ b/simpleclient_graphite_bridge/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
         
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index e426aabb7..92c5c7bdf 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             com.google.guava
diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml
index 33503b925..c027a3c82 100644
--- a/simpleclient_hibernate/pom.xml
+++ b/simpleclient_hibernate/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
 
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index 6615f5237..15f67089a 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,14 +37,14 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
         
         
             io.prometheus
             simpleclient_servlet
-            0.8.1-SNAPSHOT
+            0.8.1
             test
         
         
diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml
index f17a7eb38..4528ff10f 100644
--- a/simpleclient_httpserver/pom.xml
+++ b/simpleclient_httpserver/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,12 +37,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
         
diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml
index 311485d47..309262e64 100644
--- a/simpleclient_jetty/pom.xml
+++ b/simpleclient_jetty/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             org.eclipse.jetty
diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml
index 1712f1645..dc6804c85 100644
--- a/simpleclient_jetty_jdk8/pom.xml
+++ b/simpleclient_jetty_jdk8/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -48,7 +48,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             org.eclipse.jetty
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index fbeed7a58..8900dc53b 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             log4j
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index 0a5c2ea79..6307a35fc 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             org.apache.logging.log4j
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index 06d5c7648..5e4b57c52 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             ch.qos.logback
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index 8112f2abf..b33843cff 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -38,12 +38,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             javax.xml.bind
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index 51b89ef8d..e3909e132 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -41,12 +41,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             javax.servlet
diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml
index 1e6156d34..e7b22c7be 100644
--- a/simpleclient_spring_boot/pom.xml
+++ b/simpleclient_spring_boot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -52,17 +52,17 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
           io.prometheus
           simpleclient_spring_web
-          0.8.1-SNAPSHOT
+          0.8.1
         
         
             org.springframework.boot
diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml
index 54aca62c6..69e9649fe 100644
--- a/simpleclient_spring_web/pom.xml
+++ b/simpleclient_spring_web/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     simpleclient_spring_web
@@ -51,12 +51,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             org.springframework
diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml
index e2ea10a48..e5bc8e603 100644
--- a/simpleclient_vertx/pom.xml
+++ b/simpleclient_vertx/pom.xml
@@ -17,7 +17,7 @@
     
         io.prometheus
         parent
-        0.8.1-SNAPSHOT
+        0.8.1
     
 
     io.prometheus
@@ -53,12 +53,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.prometheus
             simpleclient_common
-            0.8.1-SNAPSHOT
+            0.8.1
         
         
             io.vertx

From a859e18fefdf15112bb5aa1468953c7560919052 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 23 Jan 2020 11:51:54 +0000
Subject: [PATCH 016/980] [maven-release-plugin] prepare for next development
 iteration

---
 benchmark/pom.xml                    | 4 ++--
 pom.xml                              | 4 ++--
 simpleclient/pom.xml                 | 2 +-
 simpleclient_caffeine/pom.xml        | 4 ++--
 simpleclient_common/pom.xml          | 4 ++--
 simpleclient_dropwizard/pom.xml      | 4 ++--
 simpleclient_graphite_bridge/pom.xml | 4 ++--
 simpleclient_guava/pom.xml           | 4 ++--
 simpleclient_hibernate/pom.xml       | 4 ++--
 simpleclient_hotspot/pom.xml         | 6 +++---
 simpleclient_httpserver/pom.xml      | 6 +++---
 simpleclient_jetty/pom.xml           | 4 ++--
 simpleclient_jetty_jdk8/pom.xml      | 4 ++--
 simpleclient_log4j/pom.xml           | 4 ++--
 simpleclient_log4j2/pom.xml          | 4 ++--
 simpleclient_logback/pom.xml         | 4 ++--
 simpleclient_pushgateway/pom.xml     | 6 +++---
 simpleclient_servlet/pom.xml         | 6 +++---
 simpleclient_spring_boot/pom.xml     | 8 ++++----
 simpleclient_spring_web/pom.xml      | 6 +++---
 simpleclient_vertx/pom.xml           | 6 +++---
 21 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index b10c48260..adbda13af 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -49,7 +49,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
           com.codahale.metrics
diff --git a/pom.xml b/pom.xml
index e7561cf6c..d3f19a302 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     io.prometheus
     parent
-    0.8.1
+    0.8.2-SNAPSHOT
 
     
         org.sonatype.oss
@@ -31,7 +31,7 @@
         scm:git:git@github.com:prometheus/client_java.git
         scm:git:git@github.com:prometheus/client_java.git
         git@github.com:prometheus/client_java.git
-        parent-0.8.1
+        HEAD
     
 
     
diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml
index c0ccb6d18..1136898b4 100644
--- a/simpleclient/pom.xml
+++ b/simpleclient/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index 1eb6b9e03..6b03d5c03 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             com.github.ben-manes.caffeine
diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml
index 2a101362c..a6dd61562 100644
--- a/simpleclient_common/pom.xml
+++ b/simpleclient_common/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
         
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index 2823593dd..d8b815063 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.dropwizard.metrics
diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml
index de3e30786..c796f5ce2 100644
--- a/simpleclient_graphite_bridge/pom.xml
+++ b/simpleclient_graphite_bridge/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
         
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index 92c5c7bdf..0637bc4e1 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             com.google.guava
diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml
index c027a3c82..b4a82d6e6 100644
--- a/simpleclient_hibernate/pom.xml
+++ b/simpleclient_hibernate/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
 
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index 15f67089a..19041684c 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,14 +37,14 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
         
         
             io.prometheus
             simpleclient_servlet
-            0.8.1
+            0.8.2-SNAPSHOT
             test
         
         
diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml
index 4528ff10f..6f3d7ef37 100644
--- a/simpleclient_httpserver/pom.xml
+++ b/simpleclient_httpserver/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,12 +37,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
         
diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml
index 309262e64..65bdb3399 100644
--- a/simpleclient_jetty/pom.xml
+++ b/simpleclient_jetty/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             org.eclipse.jetty
diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml
index dc6804c85..3d98ceef8 100644
--- a/simpleclient_jetty_jdk8/pom.xml
+++ b/simpleclient_jetty_jdk8/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -48,7 +48,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             org.eclipse.jetty
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index 8900dc53b..61606b344 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             log4j
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index 6307a35fc..fb089d7c4 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             org.apache.logging.log4j
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index 5e4b57c52..277b57eaa 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             ch.qos.logback
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index b33843cff..97d61c4d1 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -38,12 +38,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             javax.xml.bind
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index e3909e132..85de8f241 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -41,12 +41,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             javax.servlet
diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml
index e7b22c7be..9a8c9710d 100644
--- a/simpleclient_spring_boot/pom.xml
+++ b/simpleclient_spring_boot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -52,17 +52,17 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
           io.prometheus
           simpleclient_spring_web
-          0.8.1
+          0.8.2-SNAPSHOT
         
         
             org.springframework.boot
diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml
index 69e9649fe..914be8247 100644
--- a/simpleclient_spring_web/pom.xml
+++ b/simpleclient_spring_web/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     simpleclient_spring_web
@@ -51,12 +51,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             org.springframework
diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml
index e5bc8e603..b50df92e4 100644
--- a/simpleclient_vertx/pom.xml
+++ b/simpleclient_vertx/pom.xml
@@ -17,7 +17,7 @@
     
         io.prometheus
         parent
-        0.8.1
+        0.8.2-SNAPSHOT
     
 
     io.prometheus
@@ -53,12 +53,12 @@
         
             io.prometheus
             simpleclient
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.8.1
+            0.8.2-SNAPSHOT
         
         
             io.vertx

From a814b67a3f5a04771fd4a1ab3c5061849b9537b1 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 23 Jan 2020 12:07:51 +0000
Subject: [PATCH 017/980] Update for 0.8.1

Signed-off-by: Brian Brazil 
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 023c6bb33..a917249d4 100644
--- a/README.md
+++ b/README.md
@@ -41,25 +41,25 @@ version can be found on in the maven repository for
 
   io.prometheus
   simpleclient
-  0.8.0
+  0.8.1
 
 
 
   io.prometheus
   simpleclient_hotspot
-  0.8.0
+  0.8.1
 
 
 
   io.prometheus
   simpleclient_httpserver
-  0.8.0
+  0.8.1
 
 
 
   io.prometheus
   simpleclient_pushgateway
-  0.8.0
+  0.8.1
 
 ```
 

From 72593071d99924eb9c71eb0e385c78d218fec220 Mon Sep 17 00:00:00 2001
From: Max 
Date: Thu, 13 Feb 2020 17:55:15 +0100
Subject: [PATCH 018/980] Remove the mention of JMX from the included
 connectors (#527)

Signed-off-by: Max Streese 
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index a917249d4..f49f65f26 100644
--- a/README.md
+++ b/README.md
@@ -294,7 +294,7 @@ class YourClass {
 
 ## Included Collectors
 
-The Java client includes collectors for garbage collection, memory pools, JMX, classloading, and thread counts.
+The Java client includes collectors for garbage collection, memory pools, classloading, and thread counts.
 These can be added individually or just use the `DefaultExports` to conveniently register them.
 
 ```java

From c3dc1f2506108761414309210c3a98e775e331a4 Mon Sep 17 00:00:00 2001
From: Brajesh Kumar 
Date: Fri, 28 Feb 2020 17:11:20 +0000
Subject: [PATCH 019/980] Added health check api to the client. (#534)

* Added health check api to the client.
https://github.com/prometheus/jmx_exporter/issues/465

Signed-off-by: Brajesh Kumar 
---
 .../client/exporter/HTTPServer.java           | 16 ++++++++--
 .../client/exporter/TestHTTPServer.java       | 29 ++++++++++++++++---
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
index 85eb4e5cc..2a6c033dd 100644
--- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
+++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
@@ -42,9 +42,13 @@ protected ByteArrayOutputStream initialValue()
         }
     }
 
+    /**
+     * Handles Metrics collections from the given registry.
+     */
     static class HTTPMetricHandler implements HttpHandler {
         private CollectorRegistry registry;
         private final LocalByteArray response = new LocalByteArray();
+        private final static String HEALTHY_RESPONSE = "Exporter is Healthy.";
 
         HTTPMetricHandler(CollectorRegistry registry) {
           this.registry = registry;
@@ -54,16 +58,21 @@ static class HTTPMetricHandler implements HttpHandler {
         public void handle(HttpExchange t) throws IOException {
             String query = t.getRequestURI().getRawQuery();
 
+            String contextPath = t.getHttpContext().getPath();
             ByteArrayOutputStream response = this.response.get();
             response.reset();
             OutputStreamWriter osw = new OutputStreamWriter(response);
-            TextFormat.write004(osw,
-                    registry.filteredMetricFamilySamples(parseQuery(query)));
+            if ("/-/healthy".equals(contextPath)) {
+                osw.write(HEALTHY_RESPONSE);
+            } else {
+                TextFormat.write004(osw,
+                        registry.filteredMetricFamilySamples(parseQuery(query)));
+            }
+
             osw.flush();
             osw.close();
             response.flush();
             response.close();
-
             t.getResponseHeaders().set("Content-Type",
                     TextFormat.CONTENT_TYPE_004);
             if (shouldUseCompression(t)) {
@@ -154,6 +163,7 @@ public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean dae
         HttpHandler mHandler = new HTTPMetricHandler(registry);
         server.createContext("/", mHandler);
         server.createContext("/metrics", mHandler);
+        server.createContext("/-/healthy", mHandler);
         executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon));
         server.setExecutor(executorService);
         start(daemon);
diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
index f8ee97285..1a49b0f95 100644
--- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
+++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
@@ -35,8 +35,9 @@ public void cleanup() {
     s.stop();
   }
 
-  String request(String suffix) throws IOException {
-    String url = "http://localhost:" + s.server.getAddress().getPort() + "/metrics" + suffix;
+
+  String request(String context, String suffix) throws IOException {
+    String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix;
     URLConnection connection = new URL(url).openConnection();
     connection.setDoOutput(true);
     connection.connect();
@@ -44,8 +45,16 @@ String request(String suffix) throws IOException {
     return s.hasNext() ? s.next() : "";
   }
 
+  String request(String suffix) throws IOException {
+    return request("/metrics", suffix);
+  }
+
   String requestWithCompression(String suffix) throws IOException {
-    String url = "http://localhost:" + s.server.getAddress().getPort() + "/metrics" + suffix;
+    return requestWithCompression("/metrics", suffix);
+  }
+
+  String requestWithCompression(String context, String suffix) throws IOException {
+    String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix;
     URLConnection connection = new URL(url).openConnection();
     connection.setDoOutput(true);
     connection.setDoInput(true);
@@ -63,8 +72,8 @@ public void testUnbound() throws IOException {
       HTTPServer s = new HTTPServer(HttpServer.create(), registry, true);
       s.stop();
       fail("Should refuse to use an unbound HttpServer");
+    } catch (IllegalArgumentException expected) {
     }
-    catch (IllegalArgumentException expected) {}
   }
 
   @Test
@@ -114,4 +123,16 @@ public void testGzipCompression() throws IOException {
     assertThat(response).contains("b 0.0");
     assertThat(response).contains("c 0.0");
   }
+
+  @Test
+  public void testHealth() throws IOException {
+    String response = request("/-/healthy", "");
+    assertThat(response).contains("Exporter is Healthy");
+  }
+
+  @Test
+  public void testHealthGzipCompression() throws IOException {
+    String response = requestWithCompression("/-/healthy", "");
+    assertThat(response).contains("Exporter is Healthy");
+  }
 }

From ac5136b864d5d90a7ce5e1da0c235da2dcfc18e2 Mon Sep 17 00:00:00 2001
From: Takanori Takase 
Date: Sun, 15 Mar 2020 00:30:24 +0900
Subject: [PATCH 020/980] Wrap PrintWriter with BufferedWriter (#540)

* Wrap PrintWriter with BufferedWriter
* Microbenchmark for BufferedWriter wrapper

Signed-off-by: Takanori Takase 
Co-authored-by: Takanori Takase 
---
 .../client/exporter/MetricsServlet.java       |  3 +-
 .../client/exporter/ExampleBenchmark.java     | 52 +++++++++++++++++++
 .../client/exporter/MetricsServletTest.java   |  6 +--
 3 files changed, 56 insertions(+), 5 deletions(-)
 create mode 100644 simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java

diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java
index db579e424..81c5453be 100644
--- a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java
+++ b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java
@@ -7,6 +7,7 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.Writer;
 import java.util.Arrays;
@@ -43,7 +44,7 @@ protected void doGet(final HttpServletRequest req, final HttpServletResponse res
     resp.setStatus(HttpServletResponse.SC_OK);
     resp.setContentType(TextFormat.CONTENT_TYPE_004);
 
-    Writer writer = resp.getWriter();
+    Writer writer = new BufferedWriter(resp.getWriter());
     try {
       TextFormat.write004(writer, registry.filteredMetricFamilySamples(parse(req)));
       writer.flush();
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java
new file mode 100644
index 000000000..066da1499
--- /dev/null
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java
@@ -0,0 +1,52 @@
+package io.prometheus.client.exporter;
+
+import io.prometheus.client.Gauge;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.UUID;
+
+public class ExampleBenchmark {
+
+    public static void main(String[] args) throws Exception {
+
+        Gauge gauge = Gauge.build().name("labels").help("foo").labelNames("bar").register();
+        for (int i = 0; i < 10000; i++) {
+            gauge.labels(UUID.randomUUID().toString()).set(Math.random());
+        }
+
+        ServletContextHandler context = new ServletContextHandler();
+        context.setContextPath("/");
+        context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
+
+        Server server = new Server(0);
+        server.setHandler(context);
+        server.start();
+        Thread.sleep(1000);
+
+        byte[] bytes = new byte[8192];
+        URL url = new URL("http", "localhost", server.getConnectors()[0].getLocalPort(), "/metrics");
+
+        long start = System.nanoTime();
+        for (int i = 0; i < 100; i++) {
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+            InputStream in = connection.getInputStream();
+            try {
+                while (in.read(bytes) != -1) in.available();
+            } finally {
+                in.close();
+            }
+            connection.disconnect();
+        }
+        System.out.println(String.format("%,3d ns", System.nanoTime() - start));
+
+        server.stop();
+        server.join();
+
+    }
+
+}
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
index 43f3c7d59..2fccbc502 100644
--- a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
@@ -12,9 +12,8 @@
 import java.io.StringWriter;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.assertj.core.api.Assertions.fail;
-import static org.mockito.Matchers.anyChar;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
@@ -63,8 +62,7 @@ public void testWriterIsClosedOnException() throws IOException, ServletException
     HttpServletResponse resp = mock(HttpServletResponse.class);
     PrintWriter writer = mock(PrintWriter.class);
     when(resp.getWriter()).thenReturn(writer);
-    doThrow(new RuntimeException()).when(writer).write(anyChar());
-    doThrow(new RuntimeException()).when(writer).write(anyInt());
+    doThrow(new RuntimeException()).when(writer).write(any(char[].class), anyInt(), anyInt());
     CollectorRegistry registry = new CollectorRegistry();
     Gauge a = Gauge.build("a", "a help").register(registry);
 

From fe42313813b96dc92cf61f94fcfb79a8157b88a4 Mon Sep 17 00:00:00 2001
From: Andre Masella 
Date: Thu, 7 May 2020 08:18:15 -0400
Subject: [PATCH 021/980] Remove dependency on sun.misc.Unsafe (#547)

This replaces `sun.misc.Unsafe` with
`java.util.concurrent.atomic.AtomicLongFieldUpdater` and
`AtomicIntegerFieldUpdater`. This is to enable compatibility with Jigsaw
modules where `sun.misc.Unsafe` is no longer available.

Closes #468

Signed-off-by: Andre Masella 
---
 .../java/io/prometheus/client/Striped64.java  | 69 +++----------------
 1 file changed, 8 insertions(+), 61 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/Striped64.java b/simpleclient/src/main/java/io/prometheus/client/Striped64.java
index fa9054483..954210b1e 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Striped64.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Striped64.java
@@ -9,6 +9,8 @@
 package io.prometheus.client;
 
 import java.util.Random;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 
 /**
  * A package-local class holding common representation and mechanics
@@ -94,22 +96,10 @@ static final class Cell {
         Cell(long x) { value = x; }
 
         final boolean cas(long cmp, long val) {
-            return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
+            return CAS_VALUE.compareAndSet(this, cmp, val);
         }
 
-        // Unsafe mechanics
-        private static final sun.misc.Unsafe UNSAFE;
-        private static final long valueOffset;
-        static {
-            try {
-                UNSAFE = getUnsafe();
-                Class ak = Cell.class;
-                valueOffset = UNSAFE.objectFieldOffset
-                        (ak.getDeclaredField("value"));
-            } catch (Exception e) {
-                throw new Error(e);
-            }
-        }
+        private static final AtomicLongFieldUpdater CAS_VALUE = AtomicLongFieldUpdater.newUpdater(Cell.class, "value");
 
     }
 
@@ -155,14 +145,14 @@ final boolean cas(long cmp, long val) {
      * CASes the base field.
      */
     final boolean casBase(long cmp, long val) {
-        return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
+        return CAS_BASE.compareAndSet(this, cmp, val);
     }
 
     /**
      * CASes the busy field from 0 to 1 to acquire lock.
      */
     final boolean casBusy() {
-        return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
+        return CAS_BUSY.compareAndSet(this, 0, 1);
     }
 
     /**
@@ -287,50 +277,7 @@ final void internalReset(long initialValue) {
         }
     }
 
-    // Unsafe mechanics
-    private static final sun.misc.Unsafe UNSAFE;
-    private static final long baseOffset;
-    private static final long busyOffset;
-    static {
-        try {
-            UNSAFE = getUnsafe();
-            Class sk = Striped64.class;
-            baseOffset = UNSAFE.objectFieldOffset
-                    (sk.getDeclaredField("base"));
-            busyOffset = UNSAFE.objectFieldOffset
-                    (sk.getDeclaredField("busy"));
-        } catch (Exception e) {
-            throw new Error(e);
-        }
-    }
+    private static final AtomicLongFieldUpdater CAS_BASE = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base");
+    private static final AtomicIntegerFieldUpdater CAS_BUSY = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy");
 
-    /**
-     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
-     * Replace with a simple call to Unsafe.getUnsafe when integrating
-     * into a jdk.
-     *
-     * @return a sun.misc.Unsafe
-     */
-    private static sun.misc.Unsafe getUnsafe() {
-        try {
-            return sun.misc.Unsafe.getUnsafe();
-        } catch (SecurityException tryReflectionInstead) {}
-        try {
-            return java.security.AccessController.doPrivileged
-                    (new java.security.PrivilegedExceptionAction() {
-                        public sun.misc.Unsafe run() throws Exception {
-                            Class k = sun.misc.Unsafe.class;
-                            for (java.lang.reflect.Field f : k.getDeclaredFields()) {
-                                f.setAccessible(true);
-                                Object x = f.get(null);
-                                if (k.isInstance(x))
-                                    return k.cast(x);
-                            }
-                            throw new NoSuchFieldError("the Unsafe");
-                        }});
-        } catch (java.security.PrivilegedActionException e) {
-            throw new RuntimeException("Could not initialize intrinsics",
-                    e.getCause());
-        }
-    }
 }

From b3b9790d1fe5520c6eebc3a805e9774f4963331a Mon Sep 17 00:00:00 2001
From: Mariano Gonzalez 
Date: Fri, 8 May 2020 23:55:50 -0500
Subject: [PATCH 022/980] Bump up caffeine dependencies (#549)

Signed-off-by: Mariano Gonzalez 
---
 simpleclient_caffeine/pom.xml                                 | 2 +-
 .../client/cache/caffeine/CacheMetricsCollector.java          | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index 6b03d5c03..de33864bd 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -42,7 +42,7 @@
         
             com.github.ben-manes.caffeine
             caffeine
-            2.3.0
+            2.7.0
         
         
 
diff --git a/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java b/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java
index 4b7d32edf..bc48dd86f 100644
--- a/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java
+++ b/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java
@@ -1,6 +1,6 @@
 package io.prometheus.client.cache.caffeine;
 
-import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
+import com.github.benmanes.caffeine.cache.AsyncCache;
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.LoadingCache;
 import com.github.benmanes.caffeine.cache.stats.CacheStats;
@@ -72,7 +72,7 @@ public void addCache(String cacheName, Cache cache) {
      * @param cacheName The name of the cache, will be the metrics label value
      * @param cache The cache being monitored
      */
-    public void addCache(String cacheName, AsyncLoadingCache cache) {
+    public void addCache(String cacheName, AsyncCache cache) {
         children.put(cacheName, cache.synchronous());
     }
 

From baf7a33972f136140172ff8db71b449fed4cc1ad Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Mon, 11 May 2020 12:06:11 +0100
Subject: [PATCH 023/980] [maven-release-plugin] prepare release parent-0.9.0

---
 benchmark/pom.xml                    | 4 ++--
 pom.xml                              | 4 ++--
 simpleclient/pom.xml                 | 2 +-
 simpleclient_caffeine/pom.xml        | 4 ++--
 simpleclient_common/pom.xml          | 4 ++--
 simpleclient_dropwizard/pom.xml      | 4 ++--
 simpleclient_graphite_bridge/pom.xml | 4 ++--
 simpleclient_guava/pom.xml           | 4 ++--
 simpleclient_hibernate/pom.xml       | 4 ++--
 simpleclient_hotspot/pom.xml         | 6 +++---
 simpleclient_httpserver/pom.xml      | 6 +++---
 simpleclient_jetty/pom.xml           | 4 ++--
 simpleclient_jetty_jdk8/pom.xml      | 4 ++--
 simpleclient_log4j/pom.xml           | 4 ++--
 simpleclient_log4j2/pom.xml          | 4 ++--
 simpleclient_logback/pom.xml         | 4 ++--
 simpleclient_pushgateway/pom.xml     | 6 +++---
 simpleclient_servlet/pom.xml         | 6 +++---
 simpleclient_spring_boot/pom.xml     | 8 ++++----
 simpleclient_spring_web/pom.xml      | 6 +++---
 simpleclient_vertx/pom.xml           | 6 +++---
 21 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index adbda13af..92226557c 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -49,7 +49,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
           com.codahale.metrics
diff --git a/pom.xml b/pom.xml
index d3f19a302..17d94f523 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     io.prometheus
     parent
-    0.8.2-SNAPSHOT
+    0.9.0
 
     
         org.sonatype.oss
@@ -31,7 +31,7 @@
         scm:git:git@github.com:prometheus/client_java.git
         scm:git:git@github.com:prometheus/client_java.git
         git@github.com:prometheus/client_java.git
-        HEAD
+        parent-0.9.0
     
 
     
diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml
index 1136898b4..e9b18bb59 100644
--- a/simpleclient/pom.xml
+++ b/simpleclient/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index de33864bd..b1c1fe15c 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             com.github.ben-manes.caffeine
diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml
index a6dd61562..24ec812c6 100644
--- a/simpleclient_common/pom.xml
+++ b/simpleclient_common/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
         
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index d8b815063..dad5c826d 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.dropwizard.metrics
diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml
index c796f5ce2..86054441e 100644
--- a/simpleclient_graphite_bridge/pom.xml
+++ b/simpleclient_graphite_bridge/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
         
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index 0637bc4e1..26b52d7f9 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             com.google.guava
diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml
index b4a82d6e6..f203a7ec9 100644
--- a/simpleclient_hibernate/pom.xml
+++ b/simpleclient_hibernate/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
 
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index 19041684c..542886714 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,14 +37,14 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
         
         
             io.prometheus
             simpleclient_servlet
-            0.8.2-SNAPSHOT
+            0.9.0
             test
         
         
diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml
index 6f3d7ef37..09c769571 100644
--- a/simpleclient_httpserver/pom.xml
+++ b/simpleclient_httpserver/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,12 +37,12 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
         
diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml
index 65bdb3399..46e5205f8 100644
--- a/simpleclient_jetty/pom.xml
+++ b/simpleclient_jetty/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             org.eclipse.jetty
diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml
index 3d98ceef8..9a812b0b4 100644
--- a/simpleclient_jetty_jdk8/pom.xml
+++ b/simpleclient_jetty_jdk8/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -48,7 +48,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             org.eclipse.jetty
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index 61606b344..39a8409cb 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             log4j
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index fb089d7c4..3fb05cf02 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             org.apache.logging.log4j
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index 277b57eaa..d451cd14b 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             ch.qos.logback
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index 97d61c4d1..1d3b98d7f 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -38,12 +38,12 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             javax.xml.bind
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index 85de8f241..d3d5c869e 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -41,12 +41,12 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             javax.servlet
diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml
index 9a8c9710d..f2ae28981 100644
--- a/simpleclient_spring_boot/pom.xml
+++ b/simpleclient_spring_boot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -52,17 +52,17 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
           io.prometheus
           simpleclient_spring_web
-          0.8.2-SNAPSHOT
+          0.9.0
         
         
             org.springframework.boot
diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml
index 914be8247..3d7f43f5a 100644
--- a/simpleclient_spring_web/pom.xml
+++ b/simpleclient_spring_web/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     simpleclient_spring_web
@@ -51,12 +51,12 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             org.springframework
diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml
index b50df92e4..4dcae53a2 100644
--- a/simpleclient_vertx/pom.xml
+++ b/simpleclient_vertx/pom.xml
@@ -17,7 +17,7 @@
     
         io.prometheus
         parent
-        0.8.2-SNAPSHOT
+        0.9.0
     
 
     io.prometheus
@@ -53,12 +53,12 @@
         
             io.prometheus
             simpleclient
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.prometheus
             simpleclient_common
-            0.8.2-SNAPSHOT
+            0.9.0
         
         
             io.vertx

From 2cb32b9623941d1f90afe64362505f76ad36f2e7 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Mon, 11 May 2020 12:06:20 +0100
Subject: [PATCH 024/980] [maven-release-plugin] prepare for next development
 iteration

---
 benchmark/pom.xml                    | 4 ++--
 pom.xml                              | 4 ++--
 simpleclient/pom.xml                 | 2 +-
 simpleclient_caffeine/pom.xml        | 4 ++--
 simpleclient_common/pom.xml          | 4 ++--
 simpleclient_dropwizard/pom.xml      | 4 ++--
 simpleclient_graphite_bridge/pom.xml | 4 ++--
 simpleclient_guava/pom.xml           | 4 ++--
 simpleclient_hibernate/pom.xml       | 4 ++--
 simpleclient_hotspot/pom.xml         | 6 +++---
 simpleclient_httpserver/pom.xml      | 6 +++---
 simpleclient_jetty/pom.xml           | 4 ++--
 simpleclient_jetty_jdk8/pom.xml      | 4 ++--
 simpleclient_log4j/pom.xml           | 4 ++--
 simpleclient_log4j2/pom.xml          | 4 ++--
 simpleclient_logback/pom.xml         | 4 ++--
 simpleclient_pushgateway/pom.xml     | 6 +++---
 simpleclient_servlet/pom.xml         | 6 +++---
 simpleclient_spring_boot/pom.xml     | 8 ++++----
 simpleclient_spring_web/pom.xml      | 6 +++---
 simpleclient_vertx/pom.xml           | 6 +++---
 21 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index 92226557c..56e3beb52 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -49,7 +49,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
           com.codahale.metrics
diff --git a/pom.xml b/pom.xml
index 17d94f523..776c56f63 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     io.prometheus
     parent
-    0.9.0
+    0.9.1-SNAPSHOT
 
     
         org.sonatype.oss
@@ -31,7 +31,7 @@
         scm:git:git@github.com:prometheus/client_java.git
         scm:git:git@github.com:prometheus/client_java.git
         git@github.com:prometheus/client_java.git
-        parent-0.9.0
+        HEAD
     
 
     
diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml
index e9b18bb59..9a1a1129f 100644
--- a/simpleclient/pom.xml
+++ b/simpleclient/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index b1c1fe15c..a8501a300 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             com.github.ben-manes.caffeine
diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml
index 24ec812c6..de61ce93b 100644
--- a/simpleclient_common/pom.xml
+++ b/simpleclient_common/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
         
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index dad5c826d..ee4ef639f 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.dropwizard.metrics
diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml
index 86054441e..9aae84659 100644
--- a/simpleclient_graphite_bridge/pom.xml
+++ b/simpleclient_graphite_bridge/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
         
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index 26b52d7f9..9969aef2c 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             com.google.guava
diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml
index f203a7ec9..503cc5f89 100644
--- a/simpleclient_hibernate/pom.xml
+++ b/simpleclient_hibernate/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -38,7 +38,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
 
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index 542886714..53b0be250 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,14 +37,14 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
         
         
             io.prometheus
             simpleclient_servlet
-            0.9.0
+            0.9.1-SNAPSHOT
             test
         
         
diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml
index 09c769571..742447494 100644
--- a/simpleclient_httpserver/pom.xml
+++ b/simpleclient_httpserver/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,12 +37,12 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
         
diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml
index 46e5205f8..a75b50cdd 100644
--- a/simpleclient_jetty/pom.xml
+++ b/simpleclient_jetty/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -35,7 +35,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             org.eclipse.jetty
diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml
index 9a812b0b4..ebfbf4a67 100644
--- a/simpleclient_jetty_jdk8/pom.xml
+++ b/simpleclient_jetty_jdk8/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -48,7 +48,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             org.eclipse.jetty
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index 39a8409cb..c719b33f2 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             log4j
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index 3fb05cf02..46de3223c 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             org.apache.logging.log4j
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index d451cd14b..9525d9896 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -37,7 +37,7 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             ch.qos.logback
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index 1d3b98d7f..a7db63ab9 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -38,12 +38,12 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             javax.xml.bind
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index d3d5c869e..ea76a21a9 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -41,12 +41,12 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             javax.servlet
diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml
index f2ae28981..e001658ea 100644
--- a/simpleclient_spring_boot/pom.xml
+++ b/simpleclient_spring_boot/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -52,17 +52,17 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
           io.prometheus
           simpleclient_spring_web
-          0.9.0
+          0.9.1-SNAPSHOT
         
         
             org.springframework.boot
diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml
index 3d7f43f5a..016a8f572 100644
--- a/simpleclient_spring_web/pom.xml
+++ b/simpleclient_spring_web/pom.xml
@@ -5,7 +5,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     simpleclient_spring_web
@@ -51,12 +51,12 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             org.springframework
diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml
index 4dcae53a2..f085630c4 100644
--- a/simpleclient_vertx/pom.xml
+++ b/simpleclient_vertx/pom.xml
@@ -17,7 +17,7 @@
     
         io.prometheus
         parent
-        0.9.0
+        0.9.1-SNAPSHOT
     
 
     io.prometheus
@@ -53,12 +53,12 @@
         
             io.prometheus
             simpleclient
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.prometheus
             simpleclient_common
-            0.9.0
+            0.9.1-SNAPSHOT
         
         
             io.vertx

From 5554fc7f36e773d50484b3675291456e14283ef2 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Wed, 13 May 2020 23:48:50 +0100
Subject: [PATCH 025/980] Update for 0.9.0

Signed-off-by: Brian Brazil 
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index f49f65f26..9da88925e 100644
--- a/README.md
+++ b/README.md
@@ -41,25 +41,25 @@ version can be found on in the maven repository for
 
   io.prometheus
   simpleclient
-  0.8.1
+  0.9.0
 
 
 
   io.prometheus
   simpleclient_hotspot
-  0.8.1
+  0.9.0
 
 
 
   io.prometheus
   simpleclient_httpserver
-  0.8.1
+  0.9.0
 
 
 
   io.prometheus
   simpleclient_pushgateway
-  0.8.1
+  0.9.0
 
 ```
 

From e4cab67f476ec97ccf6757ecb868f7f30c0db828 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 14 May 2020 14:14:27 +0100
Subject: [PATCH 026/980] Handle empty label values for the pushgateway. (#553)

Fixes #552

Signed-off-by: Brian Brazil 
---
 .../prometheus/client/exporter/PushGateway.java   |  4 +++-
 .../client/exporter/PushGatewayTest.java          | 15 ++++++++++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java
index b8a3bbc18..cde5071fc 100644
--- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java
+++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java
@@ -286,7 +286,9 @@ void doRequest(CollectorRegistry registry, String job, Map group
 
     if (groupingKey != null) {
       for (Map.Entry entry: groupingKey.entrySet()) {
-        if (entry.getValue().contains("/")) {
+        if (entry.getValue().isEmpty()) {
+          url += "/" + entry.getKey() + "@base64/=";
+        } else if (entry.getValue().contains("/")) {
           url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue());
         } else {
           url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8");
diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
index 0127f1db5..9e7cb0b5c 100644
--- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
+++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
@@ -111,6 +111,17 @@ public void testPushWithMultiGroupingKey() throws IOException {
     pg.push(registry, "j", groupingKey);
   }
 
+  @Test
+  public void testPushWithEmptyLabelGroupingKey() throws IOException {
+    mockServerClient.when(
+        request()
+          .withMethod("PUT")
+          .withPath("/metrics/job/j/l/v/l2@base64/=")
+      ).respond(response().withStatusCode(202));
+    groupingKey.put("l2", "");
+    pg.push(registry, "j", groupingKey);
+  }
+
   @Test
   public void testPushWithGroupingKeyWithSlashes() throws IOException {
     mockServerClient.when(
@@ -192,14 +203,12 @@ public void testDeleteWithGroupingKey() throws IOException {
     pg.delete("j", groupingKey);
   }
 
-
-
   @Test
   public void testOldPushWithoutInstance() throws IOException {
     mockServerClient.when(
         request()
           .withMethod("PUT")
-          .withPath("/metrics/job/j/instance/")
+          .withPath("/metrics/job/j/instance@base64/=")
       ).respond(response().withStatusCode(202));
     pg.push(registry, "j", "");
   }

From d516a970aff314b4667d05ce2f02dfe6bfc42b92 Mon Sep 17 00:00:00 2001
From: PrometheusBot 
Date: Tue, 23 Jun 2020 13:11:18 +0300
Subject: [PATCH 027/980] Update common Prometheus files (#557)

Signed-off-by: prombot 
---
 CODE_OF_CONDUCT.md | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 CODE_OF_CONDUCT.md

diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..9a1aff412
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+## Prometheus Community Code of Conduct
+
+Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).

From ca22b57da76ae38e3c2da7a49e4d6b374014599f Mon Sep 17 00:00:00 2001
From: Ken Dombeck 
Date: Mon, 13 Jul 2020 11:33:39 -0500
Subject: [PATCH 028/980] Mockito Matchers has been deprecated and replaced
 with ArgumentMatchers (#559)

Signed-off-by: Ken Dombeck 
---
 .../client/cache/caffeine/CacheMetricsCollectorTest.java     | 4 +---
 .../client/guava/cache/CacheMetricsCollectorTest.java        | 5 +----
 .../io/prometheus/client/exporter/MetricsServletTest.java    | 2 +-
 .../java/io/prometheus/client/filter/MetricsFilterTest.java  | 4 ++--
 4 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
index 3bc034b17..65429f337 100644
--- a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
+++ b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
@@ -1,6 +1,5 @@
 package io.prometheus.client.cache.caffeine;
 
-import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.CacheLoader;
 import com.github.benmanes.caffeine.cache.Caffeine;
@@ -8,11 +7,10 @@
 import io.prometheus.client.CollectorRegistry;
 import org.junit.Test;
 
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 
 import static org.assertj.core.api.Java6Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
diff --git a/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java b/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java
index 2050c8975..dab30b9fb 100644
--- a/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java
+++ b/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java
@@ -7,11 +7,8 @@
 import io.prometheus.client.CollectorRegistry;
 import org.junit.Test;
 
-
-import java.util.Arrays;
-
 import static org.assertj.core.api.Java6Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
index 2fccbc502..6ca5e3312 100644
--- a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java
@@ -14,7 +14,7 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
index 4c69f0b1f..627b2e88c 100644
--- a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
@@ -16,8 +16,8 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;

From a526bae96dcee88747b485f5410975b2cd70bf11 Mon Sep 17 00:00:00 2001
From: Ken Dombeck 
Date: Thu, 16 Jul 2020 06:10:34 -0500
Subject: [PATCH 029/980] Count HTTP statuses returned along with the HTTP
 response times (#560)

Signed-off-by: Ken Dombeck 
---
 .../client/filter/MetricsFilter.java          | 27 ++++++++--
 .../client/filter/MetricsFilterTest.java      | 51 +++++++++++++++++++
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java
index 742dcf5a1..3b61a0ed3 100644
--- a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java
+++ b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java
@@ -1,5 +1,6 @@
 package io.prometheus.client.filter;
 
+import io.prometheus.client.Counter;
 import io.prometheus.client.Histogram;
 
 import javax.servlet.Filter;
@@ -9,13 +10,14 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
 /**
  * The MetricsFilter class exists to provide a high-level filter that enables tunable collection of metrics for Servlet
  * performance.
  *
- * 

The Histogram name itself is required, and configured with a {@code metric-name} init parameter. + *

The metric name itself is required, and configured with a {@code metric-name} init parameter. * *

The help parameter, configured with the {@code help} init parameter, is not required but strongly recommended. * @@ -26,6 +28,8 @@ *

The Histogram buckets can be configured with a {@code buckets} init parameter whose value is a comma-separated list * of valid {@code double} values. * + *

HTTP statuses will be aggregated via Counter. The name for this counter will be derived from the {@code metric-name} init parameter. + * *

{@code
  * 
  *   prometheusFilter
@@ -34,7 +38,7 @@
  *      metric-name
  *      webapp_metrics_filter
  *   
- *    
+ *   
  *      help
  *      The time taken fulfilling servlet requests
  *   
@@ -56,8 +60,10 @@ public class MetricsFilter implements Filter {
     static final String HELP_PARAM = "help";
     static final String METRIC_NAME_PARAM = "metric-name";
     static final String BUCKET_CONFIG_PARAM = "buckets";
+    static final String UNKNOWN_HTTP_STATUS_CODE = "";
 
     private Histogram histogram = null;
+    private Counter statusCounter = null;
 
     // Package-level for testing purposes.
     int pathComponents = 1;
@@ -149,6 +155,10 @@ public void init(FilterConfig filterConfig) throws ServletException {
                 .help(help)
                 .name(metricName)
                 .register();
+
+        statusCounter = Counter.build(metricName + "_status_total", "HTTP status codes of " + help)
+                .labelNames("path", "method", "status")
+                .register();
     }
 
     @Override
@@ -162,17 +172,28 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
 
         String path = request.getRequestURI();
 
+        String components = getComponents(path);
+        String method = request.getMethod();
         Histogram.Timer timer = histogram
-            .labels(getComponents(path), request.getMethod())
+            .labels(components, method)
             .startTimer();
 
         try {
             filterChain.doFilter(servletRequest, servletResponse);
         } finally {
             timer.observeDuration();
+            statusCounter.labels(components, method, getStatusCode(servletResponse)).inc();
         }
     }
 
+    private String getStatusCode(ServletResponse servletResponse) {
+        if (!(servletResponse instanceof HttpServletResponse)) {
+            return UNKNOWN_HTTP_STATUS_CODE;
+        }
+
+        return Integer.toString(((HttpServletResponse) servletResponse).getStatus());
+    }
+
     @Override
     public void destroy() {
     }
diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
index 627b2e88c..622756b6b 100644
--- a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
+++ b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java
@@ -10,6 +10,7 @@
 
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.Enumeration;
@@ -180,4 +181,54 @@ public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
         assertEquals(buckets.split(",").length+1, count);
     }
 
+    @Test
+    public void testStatusCode() throws Exception {
+        HttpServletRequest req = mock(HttpServletRequest.class);
+        when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang");
+        when(req.getMethod()).thenReturn(HttpMethods.GET);
+
+        HttpServletResponse res = mock(HttpServletResponse.class);
+        when(res.getStatus()).thenReturn(200);
+
+        FilterChain c = mock(FilterChain.class);
+
+        MetricsFilter constructed = new MetricsFilter(
+                "foobar_filter",
+                "Help for my filter",
+                2,
+                null
+        );
+        constructed.init(mock(FilterConfig.class));
+
+        constructed.doFilter(req, res, c);
+
+        final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue("foobar_filter_status_total", new String[]{"path", "method", "status"}, new String[]{"/foo/bar", HttpMethods.GET, "200"});
+        assertNotNull(sampleValue);
+        assertEquals(1, sampleValue, 0.0001);
+    }
+
+    @Test
+    public void testStatusCodeWithNonHttpServletResponse() throws Exception {
+        HttpServletRequest req = mock(HttpServletRequest.class);
+        when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang");
+        when(req.getMethod()).thenReturn(HttpMethods.GET);
+
+        ServletResponse res = mock(ServletResponse.class);
+
+        FilterChain c = mock(FilterChain.class);
+
+        MetricsFilter constructed = new MetricsFilter(
+                "foobar_filter",
+                "Help for my filter",
+                2,
+                null
+        );
+        constructed.init(mock(FilterConfig.class));
+
+        constructed.doFilter(req, res, c);
+
+        final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue("foobar_filter_status_total", new String[]{"path", "method", "status"}, new String[]{"/foo/bar", HttpMethods.GET, MetricsFilter.UNKNOWN_HTTP_STATUS_CODE});
+        assertNotNull(sampleValue);
+        assertEquals(1, sampleValue, 0.0001);
+    }
 }

From 2009e7dea583b6b569cd85b21a242fd3ff694c22 Mon Sep 17 00:00:00 2001
From: Tom Wieczorek 
Date: Fri, 17 Jul 2020 09:48:04 +0200
Subject: [PATCH 030/980] Add Bill of Materials (#561)

* Add Bill of Materials

Fixes #508.

Signed-off-by: Tom Wieczorek 
---
 pom.xml                  |   1 +
 simpleclient_bom/pom.xml | 126 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)
 create mode 100644 simpleclient_bom/pom.xml

diff --git a/pom.xml b/pom.xml
index 776c56f63..4587c171e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,6 +62,7 @@
         simpleclient_jetty
         simpleclient_jetty_jdk8
         simpleclient_vertx
+        simpleclient_bom
         benchmark
     
 
diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml
new file mode 100644
index 000000000..858584048
--- /dev/null
+++ b/simpleclient_bom/pom.xml
@@ -0,0 +1,126 @@
+
+
+    4.0.0
+
+    
+        io.prometheus
+        parent
+        0.9.1-SNAPSHOT
+    
+
+    simpleclient_bom
+    pom
+
+    Prometheus Java Simpleclient BOM
+    
+        Bill of Materials for the Simpleclient.
+    
+
+    
+        
+            The Apache Software License, Version 2.0
+            http://www.apache.org/licenses/LICENSE-2.0.txt
+            repo
+        
+    
+
+    
+        
+            
+                io.prometheus
+                simpleclient
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_common
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_caffeine
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_dropwizard
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_graphite_bridge
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_hibernate
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_guava
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_hotspot
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_httpserver
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_log4j
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_log4j2
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_logback
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_pushgateway
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_servlet
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_spring_web
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_spring_boot
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_jetty
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_jetty_jdk8
+                0.9.1-SNAPSHOT
+            
+            
+                io.prometheus
+                simpleclient_vertx
+                0.9.1-SNAPSHOT
+            
+        
+    
+

From f48acbb1d034dc2196657b6814241d76da66b385 Mon Sep 17 00:00:00 2001
From: Jason Parraga 
Date: Sat, 25 Jul 2020 01:06:44 -0700
Subject: [PATCH 031/980] Fix typo in README (#563)

Signed-off-by: Jason Parraga 
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9da88925e..f5359bfbc 100644
--- a/README.md
+++ b/README.md
@@ -537,7 +537,7 @@ server.setHandler(context);
 context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");
 ```
 
-All HTTP expostion integrations support restricting which time series to return
+All HTTP exposition integrations support restricting which time series to return
 using `?name[]=` URL parameters. Due to implementation limitations, this may
 have false negatives.
 

From 570f8bb70ae6f5a0a950dc563b68fb495d2f4d69 Mon Sep 17 00:00:00 2001
From: Stefan Birkner 
Date: Sun, 9 Aug 2020 11:31:02 +0200
Subject: [PATCH 032/980] Verify exception messages in tests (#566)

Improve test coverage and make refactorings more safe.

Signed-off-by: Stefan Birkner 
---
 .../io/prometheus/client/CounterTest.java     | 11 +++++-
 .../io/prometheus/client/HistogramTest.java   | 11 +++++-
 .../client/SimpleCollectorTest.java           | 39 +++++++++++++++----
 .../client/exporter/PushGatewayTest.java      | 20 +++++++++-
 4 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
index 16d025f73..b7e9ac6ea 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
@@ -1,17 +1,24 @@
 package io.prometheus.client;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.rules.ExpectedException.none;
 
 import java.util.ArrayList;
 import java.util.List;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.Before;
+import org.junit.rules.ExpectedException;
 
 
 public class CounterTest {
   CollectorRegistry registry;
   Counter noLabels, labels;
 
+  @Rule
+  public final ExpectedException thrown = none();
+
   @Before
   public void setUp() {
     registry = new CollectorRegistry();
@@ -39,8 +46,10 @@ public void testIncrement() {
     assertEquals(8.0, noLabels.get(), .001);
   }
     
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testNegativeIncrementFails() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Amount to increment must be non-negative.");
     noLabels.inc(-1);
   }
   
diff --git a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
index d5d44e3d4..1a09a8939 100644
--- a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
@@ -3,6 +3,7 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.rules.ExpectedException.none;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -11,7 +12,9 @@
 import java.util.concurrent.Callable;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 
 public class HistogramTest {
@@ -19,6 +22,10 @@ public class HistogramTest {
   CollectorRegistry registry;
   Histogram noLabels, labels;
 
+
+  @Rule
+  public final ExpectedException thrown = none();
+
   @Before
   public void setUp() {
     registry = new CollectorRegistry();
@@ -166,8 +173,10 @@ public void testLabels() {
     assertEquals(3.0, getLabelsSum("b").doubleValue(), .001);
   }
 
-  @Test(expected=IllegalStateException.class)
+  @Test
   public void testLeLabelThrows() {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Histogram cannot have a label named 'le'.");
     Histogram.build().name("labels").help("help").labelNames("le").create();
   }
 
diff --git a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
index d5c7e3e32..e2b7d1a4e 100644
--- a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
@@ -3,9 +3,12 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.rules.ExpectedException.none;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.Before;
+import org.junit.rules.ExpectedException;
 
 
 public class SimpleCollectorTest {
@@ -14,6 +17,9 @@ public class SimpleCollectorTest {
   Gauge metric;
   Gauge noLabels;
 
+  @Rule
+  public final ExpectedException thrown = none();
+
   @Before
   public void setUp() {
     registry = new CollectorRegistry();
@@ -29,18 +35,24 @@ private Double getValueNoLabels() {
     return registry.getSampleValue("nolabels");
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testTooFewLabelsThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Incorrect number of labels.");
     metric.labels();
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testNullLabelThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Label cannot be null.");
     metric.labels(new String[]{null});
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testTooManyLabelsThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Incorrect number of labels.");
     metric.labels("a", "b");
   }
   
@@ -97,28 +109,39 @@ public void testNameIsConcatenated() {
     assertEquals("a_b_c", Gauge.build().name("c").subsystem("b").namespace("a").help("h").create().fullname);
   }
 
-  @Test(expected=IllegalStateException.class)
+  @Test
   public void testNameIsRequired() {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Name hasn't been set.");
     Gauge.build().help("h").create();
   }
 
-  @Test(expected=IllegalStateException.class)
+  @Test
   public void testHelpIsRequired() {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("Help hasn't been set.");
     Gauge.build().name("c").create();
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testInvalidNameThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Invalid metric name: c'a");
     Gauge.build().name("c'a").create();
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testInvalidLabelNameThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Invalid metric label name: c:d");
     Gauge.build().name("a").labelNames("c:d").help("h").create();
   }
 
-  @Test(expected=IllegalArgumentException.class)
+  @Test
   public void testReservedLabelNameThrows() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage(
+            "Invalid metric label name, reserved for internal use: __name__");
     Gauge.build().name("a").labelNames("__name__").help("h").create();
   }
 
diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
index 9e7cb0b5c..9e7cb71f3 100644
--- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
+++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
@@ -1,6 +1,7 @@
 package io.prometheus.client.exporter;
 
 
+import static org.junit.rules.ExpectedException.none;
 import static org.mockserver.model.HttpRequest.request;
 import static org.mockserver.model.HttpResponse.response;
 
@@ -13,11 +14,16 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.mockserver.junit.MockServerRule;
 import org.mockserver.client.server.MockServerClient;
 
 public class PushGatewayTest {
 
+
+  @Rule
+  public final ExpectedException thrown = none();
+
   @Rule
   public MockServerRule mockServerRule = new MockServerRule(this);
   private MockServerClient mockServerClient;
@@ -70,13 +76,18 @@ public void testPush200Response() throws IOException {
     pg.push(registry, "j");
   }
 
-  @Test(expected=IOException.class)
+  @Test
   public void testNon202ResponseThrows() throws IOException {
     mockServerClient.when(
         request()
           .withMethod("PUT")
           .withPath("/metrics/job/j")
       ).respond(response().withStatusCode(500));
+    thrown.expect(IOException.class);
+    thrown.expectMessage(
+            "Response code from http://localhost:"
+                    + mockServerRule.getHttpPort()
+                    + "/metrics/job/j was 500");
     pg.push(registry, "j");
   }
 
@@ -223,13 +234,18 @@ public void testOldPushWithInstance() throws IOException {
     pg.push(registry, "j", "i");
   }
 
-  @Test(expected=IOException.class)
+  @Test
   public void testOldNon202ResponseThrows() throws IOException {
     mockServerClient.when(
         request()
           .withMethod("PUT")
           .withPath("/metrics/job/j/instance/i")
       ).respond(response().withStatusCode(500));
+    thrown.expect(IOException.class);
+    thrown.expectMessage(
+            "Response code from http://localhost:"
+                    + mockServerRule.getHttpPort()
+                    + "/metrics/job/j/instance/i was 500");
     pg.push(registry,"j", "i");
   }
 

From 01e1e9edb6f0a4667afd99ae224673318130f36f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Paulo?= 
Date: Tue, 11 Aug 2020 18:08:27 -0300
Subject: [PATCH 033/980] Specify the charset of HTTPServer response (#564)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Update to specify the charset of response

In some Operational Systems (Like IBM Z/OS and IBM Z/Unix) the JRE runs with a charset different of UTF-8, those default charsets produce wrong behavior and truncated responses.

To avoid this kind of situations I put the specifc charset in the output writer.

This create a consistent response between different platforms.

Signed-off-by: João Paulo Binda Delboni 

* Specify the charset of Graphite Request
To prevent problems with encoding in some Operational Systems we set the charset of Graphite Charset.

Signed-off-by: João Paulo Binda Delboni 
---
 .../src/main/java/io/prometheus/client/bridge/Graphite.java   | 4 +++-
 .../main/java/io/prometheus/client/exporter/HTTPServer.java   | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java b/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java
index 708b025bd..5e292800c 100644
--- a/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java
+++ b/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java
@@ -5,8 +5,10 @@
 
 import java.io.BufferedWriter;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.Socket;
+import java.nio.charset.Charset;
 import java.util.Collections;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -50,7 +52,7 @@ public Graphite(String host, int port) {
    */
   public void push(CollectorRegistry registry) throws IOException {
     Socket s = new Socket(host, port);
-    BufferedWriter writer = new BufferedWriter(new PrintWriter(s.getOutputStream()));
+    BufferedWriter writer = new BufferedWriter(new PrintWriter(new OutputStreamWriter(s.getOutputStream(), Charset.forName("UTF-8"))));
     Matcher m = INVALID_GRAPHITE_CHARS.matcher("");
     long now = System.currentTimeMillis() / 1000;
     for (Collector.MetricFamilySamples metricFamilySamples: Collections.list(registry.metricFamilySamples())) {
diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
index 2a6c033dd..53a4afef5 100644
--- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
+++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
@@ -9,6 +9,7 @@
 import java.net.HttpURLConnection;
 import java.net.InetSocketAddress;
 import java.net.URLDecoder;
+import java.nio.charset.Charset;
 import java.util.List;
 import java.util.Set;
 import java.util.HashSet;
@@ -61,7 +62,7 @@ public void handle(HttpExchange t) throws IOException {
             String contextPath = t.getHttpContext().getPath();
             ByteArrayOutputStream response = this.response.get();
             response.reset();
-            OutputStreamWriter osw = new OutputStreamWriter(response);
+            OutputStreamWriter osw = new OutputStreamWriter(response, Charset.forName("UTF-8"));
             if ("/-/healthy".equals(contextPath)) {
                 osw.write(HEALTHY_RESPONSE);
             } else {

From c41bef4ca5bcb68ebaf1319e2df400a002a60f06 Mon Sep 17 00:00:00 2001
From: Elvys Soares 
Date: Thu, 13 Aug 2020 12:29:58 -0300
Subject: [PATCH 034/980] signing off (#567)

Signed-off-by: Elvys Soares 
---
 .../prometheus/client/exporter/TestHTTPServer.java   | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
index 1a49b0f95..3b5040d6c 100644
--- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
+++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java
@@ -65,15 +65,11 @@ String requestWithCompression(String context, String suffix) throws IOException
     return s.hasNext() ? s.next() : "";
   }
 
-  @Test
-  public void testUnbound() throws IOException {
+  @Test(expected = IllegalArgumentException.class)
+  public void testRefuseUsingUnbound() throws IOException {
     CollectorRegistry registry = new CollectorRegistry();
-    try {
-      HTTPServer s = new HTTPServer(HttpServer.create(), registry, true);
-      s.stop();
-      fail("Should refuse to use an unbound HttpServer");
-    } catch (IllegalArgumentException expected) {
-    }
+    HTTPServer s = new HTTPServer(HttpServer.create(), registry, true);
+    s.stop();
   }
 
   @Test

From 40e6eec96f4b68870e8bf18ccecf3019355e6bdb Mon Sep 17 00:00:00 2001
From: Charney Kaye 
Date: Mon, 5 Oct 2020 14:58:44 -0700
Subject: [PATCH 035/980] Fix code example for YourCustomCollector in README
 (#572)

In order to run the example, this method must have public visibility.

Signed-off-by: Charney Kaye 
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index f5359bfbc..294f83797 100644
--- a/README.md
+++ b/README.md
@@ -629,7 +629,7 @@ To do so you need to create a custom collector (which will need to be registered
 
 ```java
 class YourCustomCollector extends Collector {
-  List collect() {
+  public List collect() {
     List mfs = new ArrayList();
     // With no labels.
     mfs.add(new GaugeMetricFamily("my_gauge", "help", 42));

From 3a54fdffe5df9a3d3db2071fda0d4fcee7915656 Mon Sep 17 00:00:00 2001
From: Vasily Vasilkov 
Date: Wed, 14 Oct 2020 11:39:17 +0300
Subject: [PATCH 036/980] Add ability to filter metrics in DropwizardExports
 (#574)

* Add ability to filter metrics in DropwizardExports

Signed-off-by: Vasily Vasilkov 
---
 .../client/dropwizard/DropwizardExports.java  | 48 ++++++++++++++++---
 1 file changed, 41 insertions(+), 7 deletions(-)

diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java b/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
index e8011dd34..4bf89899f 100644
--- a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
+++ b/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
@@ -1,6 +1,14 @@
 package io.prometheus.client.dropwizard;
 
-import com.codahale.metrics.*;
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Gauge;
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricFilter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Snapshot;
+import com.codahale.metrics.Timer;
 import io.prometheus.client.dropwizard.samplebuilder.SampleBuilder;
 import io.prometheus.client.dropwizard.samplebuilder.DefaultSampleBuilder;
 
@@ -20,15 +28,29 @@
 public class DropwizardExports extends io.prometheus.client.Collector implements io.prometheus.client.Collector.Describable {
     private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName());
     private MetricRegistry registry;
+    private MetricFilter metricFilter;
     private SampleBuilder sampleBuilder;
 
     /**
-     * Creates a new DropwizardExports with a {@link DefaultSampleBuilder}.
+     * Creates a new DropwizardExports with a {@link DefaultSampleBuilder} and {@link MetricFilter#ALL}.
      *
      * @param registry a metric registry to export in prometheus.
      */
     public DropwizardExports(MetricRegistry registry) {
         this.registry = registry;
+        this.metricFilter = MetricFilter.ALL;
+        this.sampleBuilder = new DefaultSampleBuilder();
+    }
+
+    /**
+     * Creates a new DropwizardExports with a {@link DefaultSampleBuilder} and custom {@link MetricFilter}.
+     *
+     * @param registry     a metric registry to export in prometheus.
+     * @param metricFilter a custom metric filter.
+     */
+    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) {
+        this.registry = registry;
+        this.metricFilter = metricFilter;
         this.sampleBuilder = new DefaultSampleBuilder();
     }
 
@@ -38,6 +60,18 @@ public DropwizardExports(MetricRegistry registry) {
      */
     public DropwizardExports(MetricRegistry registry, SampleBuilder sampleBuilder) {
         this.registry = registry;
+        this.metricFilter = MetricFilter.ALL;
+        this.sampleBuilder = sampleBuilder;
+    }
+
+    /**
+     * @param registry      a metric registry to export in prometheus.
+     * @param metricFilter  a custom metric filter.
+     * @param sampleBuilder sampleBuilder to use to create prometheus samples.
+     */
+    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter, SampleBuilder sampleBuilder) {
+        this.registry = registry;
+        this.metricFilter = metricFilter;
         this.sampleBuilder = sampleBuilder;
     }
 
@@ -128,19 +162,19 @@ MetricFamilySamples fromMeter(String dropwizardName, Meter meter) {
     public List collect() {
         Map mfSamplesMap = new HashMap();
 
-        for (SortedMap.Entry entry : registry.getGauges().entrySet()) {
+        for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) {
             addToMap(mfSamplesMap, fromGauge(entry.getKey(), entry.getValue()));
         }
-        for (SortedMap.Entry entry : registry.getCounters().entrySet()) {
+        for (SortedMap.Entry entry : registry.getCounters(metricFilter).entrySet()) {
             addToMap(mfSamplesMap, fromCounter(entry.getKey(), entry.getValue()));
         }
-        for (SortedMap.Entry entry : registry.getHistograms().entrySet()) {
+        for (SortedMap.Entry entry : registry.getHistograms(metricFilter).entrySet()) {
             addToMap(mfSamplesMap, fromHistogram(entry.getKey(), entry.getValue()));
         }
-        for (SortedMap.Entry entry : registry.getTimers().entrySet()) {
+        for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) {
             addToMap(mfSamplesMap, fromTimer(entry.getKey(), entry.getValue()));
         }
-        for (SortedMap.Entry entry : registry.getMeters().entrySet()) {
+        for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) {
             addToMap(mfSamplesMap, fromMeter(entry.getKey(), entry.getValue()));
         }
         return new ArrayList(mfSamplesMap.values());

From 4618df7471c8ed49ba09f25b9b64e2674debb5a5 Mon Sep 17 00:00:00 2001
From: Turbanov Andrey 
Date: Thu, 15 Oct 2020 19:22:17 +0300
Subject: [PATCH 037/980] Make sure GZIPOutputStream is always closed (#598)

Signed-off-by: Andrey Turbanov 
---
 .../client/exporter/HTTPServer.java           | 23 ++++++++++---------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
index 53a4afef5..10445a7c3 100644
--- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
+++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
@@ -10,20 +10,20 @@
 import java.net.InetSocketAddress;
 import java.net.URLDecoder;
 import java.nio.charset.Charset;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.HashSet;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.GZIPOutputStream;
 
+import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
-import com.sun.net.httpserver.HttpExchange;
 
 /**
  * Expose Prometheus metrics using a plain Java HttpServer.
@@ -37,6 +37,7 @@
  * */
 public class HTTPServer {
     private static class LocalByteArray extends ThreadLocal {
+        @Override
         protected ByteArrayOutputStream initialValue()
         {
             return new ByteArrayOutputStream(1 << 20);
@@ -47,7 +48,7 @@ protected ByteArrayOutputStream initialValue()
      * Handles Metrics collections from the given registry.
      */
     static class HTTPMetricHandler implements HttpHandler {
-        private CollectorRegistry registry;
+        private final CollectorRegistry registry;
         private final LocalByteArray response = new LocalByteArray();
         private final static String HEALTHY_RESPONSE = "Exporter is Healthy.";
 
@@ -55,7 +56,7 @@ static class HTTPMetricHandler implements HttpHandler {
           this.registry = registry;
         }
 
-
+        @Override
         public void handle(HttpExchange t) throws IOException {
             String query = t.getRequestURI().getRawQuery();
 
@@ -70,18 +71,18 @@ public void handle(HttpExchange t) throws IOException {
                         registry.filteredMetricFamilySamples(parseQuery(query)));
             }
 
-            osw.flush();
             osw.close();
-            response.flush();
-            response.close();
             t.getResponseHeaders().set("Content-Type",
                     TextFormat.CONTENT_TYPE_004);
             if (shouldUseCompression(t)) {
                 t.getResponseHeaders().set("Content-Encoding", "gzip");
                 t.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0);
                 final GZIPOutputStream os = new GZIPOutputStream(t.getResponseBody());
-                response.writeTo(os);
-                os.close();
+                try {
+                    response.writeTo(os);
+                } finally {
+                    os.close();
+                }
             } else {
                 t.getResponseHeaders().set("Content-Length",
                         String.valueOf(response.size()));
@@ -100,7 +101,7 @@ protected static boolean shouldUseCompression(HttpExchange exchange) {
         for (String encodingHeader : encodingHeaders) {
             String[] encodings = encodingHeader.split(",");
             for (String encoding : encodings) {
-                if (encoding.trim().toLowerCase().equals("gzip")) {
+                if (encoding.trim().equalsIgnoreCase("gzip")) {
                     return true;
                 }
             }

From 6ed8bee926c52d8ffa0fe5e0642fa91100d6f945 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Mon, 9 Nov 2020 16:32:13 +0000
Subject: [PATCH 038/980] Bump junit version. (#600)

This silences a dependabot warning about an issue that doesn't
affect us.

Signed-off-by: Brian Brazil 
---
 simpleclient/pom.xml                 | 2 +-
 simpleclient_caffeine/pom.xml        | 2 +-
 simpleclient_common/pom.xml          | 2 +-
 simpleclient_dropwizard/pom.xml      | 2 +-
 simpleclient_graphite_bridge/pom.xml | 2 +-
 simpleclient_guava/pom.xml           | 2 +-
 simpleclient_hotspot/pom.xml         | 2 +-
 simpleclient_httpserver/pom.xml      | 2 +-
 simpleclient_jetty/pom.xml           | 2 +-
 simpleclient_jetty_jdk8/pom.xml      | 2 +-
 simpleclient_log4j/pom.xml           | 2 +-
 simpleclient_log4j2/pom.xml          | 2 +-
 simpleclient_logback/pom.xml         | 2 +-
 simpleclient_pushgateway/pom.xml     | 2 +-
 simpleclient_servlet/pom.xml         | 2 +-
 simpleclient_vertx/pom.xml           | 2 +-
 16 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml
index 9a1a1129f..7d863af41 100644
--- a/simpleclient/pom.xml
+++ b/simpleclient/pom.xml
@@ -42,7 +42,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
     
diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml
index a8501a300..faec46eff 100644
--- a/simpleclient_caffeine/pom.xml
+++ b/simpleclient_caffeine/pom.xml
@@ -49,7 +49,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml
index de61ce93b..909c23722 100644
--- a/simpleclient_common/pom.xml
+++ b/simpleclient_common/pom.xml
@@ -43,7 +43,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
     
diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml
index ee4ef639f..641e15653 100644
--- a/simpleclient_dropwizard/pom.xml
+++ b/simpleclient_dropwizard/pom.xml
@@ -46,7 +46,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml
index 9aae84659..2d7248c51 100644
--- a/simpleclient_graphite_bridge/pom.xml
+++ b/simpleclient_graphite_bridge/pom.xml
@@ -44,7 +44,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
     
diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml
index 9969aef2c..c646d64ae 100644
--- a/simpleclient_guava/pom.xml
+++ b/simpleclient_guava/pom.xml
@@ -49,7 +49,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml
index 53b0be250..e0ec8d4d9 100644
--- a/simpleclient_hotspot/pom.xml
+++ b/simpleclient_hotspot/pom.xml
@@ -50,7 +50,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml
index 742447494..e8a6fcb85 100644
--- a/simpleclient_httpserver/pom.xml
+++ b/simpleclient_httpserver/pom.xml
@@ -48,7 +48,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml
index a75b50cdd..c4be38c43 100644
--- a/simpleclient_jetty/pom.xml
+++ b/simpleclient_jetty/pom.xml
@@ -51,7 +51,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml
index ebfbf4a67..2db5b8e19 100644
--- a/simpleclient_jetty_jdk8/pom.xml
+++ b/simpleclient_jetty_jdk8/pom.xml
@@ -64,7 +64,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml
index c719b33f2..ea604987a 100644
--- a/simpleclient_log4j/pom.xml
+++ b/simpleclient_log4j/pom.xml
@@ -49,7 +49,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml
index 46de3223c..4606131b2 100644
--- a/simpleclient_log4j2/pom.xml
+++ b/simpleclient_log4j2/pom.xml
@@ -48,7 +48,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
 
diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml
index 9525d9896..7780bf906 100644
--- a/simpleclient_logback/pom.xml
+++ b/simpleclient_logback/pom.xml
@@ -49,7 +49,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml
index a7db63ab9..388353c9d 100644
--- a/simpleclient_pushgateway/pom.xml
+++ b/simpleclient_pushgateway/pom.xml
@@ -54,7 +54,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml
index ea76a21a9..3ca6d221a 100644
--- a/simpleclient_servlet/pom.xml
+++ b/simpleclient_servlet/pom.xml
@@ -58,7 +58,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         
diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml
index f085630c4..1d25a97d8 100644
--- a/simpleclient_vertx/pom.xml
+++ b/simpleclient_vertx/pom.xml
@@ -70,7 +70,7 @@
         
             junit
             junit
-            4.11
+            4.13.1
             test
         
         

From 683466fcf100b7f52ba2ab5c8b73a3b74251869d Mon Sep 17 00:00:00 2001
From: Andrey Turbanov 
Date: Sun, 3 Jan 2021 20:53:32 +0300
Subject: [PATCH 039/980] java's method Double.toString is able to convert
 not-a-number values to "NaN" string (#611)

Signed-off-by: Andrey Turbanov 
---
 .../src/main/java/io/prometheus/client/Collector.java        | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java
index 11599af58..49c29e9b8 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Collector.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java
@@ -88,7 +88,7 @@ public Sample(String name, List labelNames, List labelValues, do
       }
 
       public Sample(String name, List labelNames, List labelValues, double value) {
-    	  this(name, labelNames, labelValues, value, null);
+        this(name, labelNames, labelValues, value, null);
       }
 
       @Override
@@ -217,9 +217,6 @@ public static String doubleToGoString(double d) {
     if (d == Double.NEGATIVE_INFINITY) {
       return "-Inf";
     }
-    if (Double.isNaN(d)) {
-      return "NaN";
-    }
     return Double.toString(d);
   }
 }

From 61c2b0cc302e6111b9ecad17ed4e61ad8e902bd4 Mon Sep 17 00:00:00 2001
From: Julien Pivotto 
Date: Fri, 15 Jan 2021 19:30:38 +0100
Subject: [PATCH 040/980] Add SECURITY.md

This commit adds a security policy to this repository. SECURITY.md files
are threated in a special way by GitHub, helping users to know how to
best submit security issues for the projects.

In this case, we simply point to our existing documentation on
prometheus.io.

The content of this file will be synced automatically with the
prometheus/prometheus repository, as our security policy covers all the
repositories. This sync is automated with prombot, like other files
(LICENSE, Makefile.common).

https://docs.github.com/en/free-pro-team@latest/github/managing-security-vulnerabilities/adding-a-security-policy-to-your-repository
Signed-off-by: Julien Pivotto 
---
 SECURITY.md | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 SECURITY.md

diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..67741f015
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,6 @@
+# Reporting a security issue
+
+The Prometheus security policy, including how to report vulnerabilities, can be
+found here:
+
+https://prometheus.io/docs/operating/security/

From 819a8576ccb159d4c3769ac49e97a59ae67858fc Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Wed, 25 Nov 2020 17:48:54 +0000
Subject: [PATCH 041/980] Add support for OM Units, and Counter naming.

Signed-off-by: Brian Brazil 
---
 .../java/io/prometheus/client/Collector.java  | 31 +++++++++++++++----
 .../prometheus/client/CollectorRegistry.java  |  5 +++
 .../java/io/prometheus/client/Counter.java    |  6 +++-
 .../io/prometheus/client/SimpleCollector.java | 15 ++++++++-
 .../client/CollectorRegistryTest.java         |  4 +--
 .../io/prometheus/client/CounterTest.java     | 22 ++++++++++---
 .../client/SimpleCollectorTest.java           |  9 ++++++
 .../client/exporter/common/TextFormat.java    | 11 +++++--
 .../exporter/common/TextFormatTest.java       | 29 +++++++++++++++--
 9 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java
index 49c29e9b8..6855e3a51 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Collector.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java
@@ -19,11 +19,14 @@ public abstract class Collector {
    */
   public abstract List collect();
   public enum Type {
+    UNTYPED, // XXX This is Unknown in OpenMetrics.
     COUNTER,
     GAUGE,
-    SUMMARY,
+    STATE_SET,
+    INFO,
     HISTOGRAM,
-    UNTYPED,
+    GAUGE_HISTOGRAM,
+    SUMMARY,
   }
 
   /**
@@ -31,17 +34,29 @@ public enum Type {
    */
   static public class MetricFamilySamples {
     public final String name;
+    public final String unit;
     public final Type type;
     public final String help;
     public final List samples;
 
-    public MetricFamilySamples(String name, Type type, String help, List samples) {
+    public MetricFamilySamples(String name, String unit, Type type, String help, List samples) {
+      if (!unit.isEmpty() && !name.endsWith("_" + unit)) {
+        throw new IllegalArgumentException("Metric's unit is not the suffix of the metric name: " + name);
+      }
+      if ((type == Type.INFO || type == Type.STATE_SET) && !unit.isEmpty()) {
+        throw new IllegalArgumentException("Metric is of a type that cannot have a unit: " + name);
+      }
       this.name = name;
+      this.unit = unit;
       this.type = type;
       this.help = help;
       this.samples = samples;
     }
 
+    public MetricFamilySamples(String name, Type type, String help, List samples) {
+      this(name, "", type, help, samples);
+    }
+
     @Override
     public boolean equals(Object obj) {
       if (!(obj instanceof MetricFamilySamples)) {
@@ -49,14 +64,18 @@ public boolean equals(Object obj) {
       }
       MetricFamilySamples other = (MetricFamilySamples) obj;
       
-      return other.name.equals(name) && other.type.equals(type)
-        && other.help.equals(help) && other.samples.equals(samples) ;
+      return other.name.equals(name)
+        && other.unit.equals(unit)
+        && other.type.equals(type)
+        && other.help.equals(help)
+        && other.samples.equals(samples);
     }
 
     @Override
     public int hashCode() {
       int hash = 1;
       hash = 37 * hash + name.hashCode();
+      hash = 37 * hash + unit.hashCode();
       hash = 37 * hash + type.hashCode();
       hash = 37 * hash + help.hashCode();
       hash = 37 * hash + samples.hashCode();
@@ -65,7 +84,7 @@ public int hashCode() {
 
     @Override
     public String toString() {
-      return "Name: " + name + " Type: " + type + " Help: " + help + 
+      return "Name: " + name + " Unit:" + unit + " Type: " + type + " Help: " + help +
         " Samples: " + samples;
     }
 
diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
index d2a12c95c..b7bc0284b 100644
--- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
+++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
@@ -105,6 +105,11 @@ private List collectorNames(Collector m) {
     List names = new ArrayList();
     for (Collector.MetricFamilySamples family : mfs) {
       switch (family.type) {
+        case COUNTER:
+          names.add(family.name + "_total");
+          names.add(family.name + "_created");
+          names.add(family.name);
+          break;
         case SUMMARY:
           names.add(family.name + "_count");
           names.add(family.name + "_sum");
diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java
index 180a8d5c9..27a7d5627 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Counter.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java
@@ -74,6 +74,10 @@ public class Counter extends SimpleCollector implements Collector
   public static class Builder extends SimpleCollector.Builder {
     @Override
     public Counter create() {
+      // Gracefully handle pre-OpenMetrics counters.
+      if (name.endsWith("_total")) {
+        name = name.substring(0, name.length() - 6);
+      }
       return new Counter(this);
     }
   }
@@ -158,7 +162,7 @@ public double get() {
   public List collect() {
     List samples = new ArrayList(children.size());
     for(Map.Entry, Child> c: children.entrySet()) {
-      samples.add(new MetricFamilySamples.Sample(fullname, labelNames, c.getKey(), c.getValue().get()));
+      samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get()));
     }
     return familySamplesList(Type.COUNTER, samples);
   }
diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java
index a70d5d4e7..6a0183961 100644
--- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java
+++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java
@@ -49,6 +49,7 @@
 public abstract class SimpleCollector extends Collector {
   protected final String fullname;
   protected final String help;
+  protected final String unit;
   protected final List labelNames;
 
   protected final ConcurrentMap, Child> children = new ConcurrentHashMap, Child>();
@@ -145,7 +146,7 @@ public  T setChild(Child child, String... labelValues) {
   protected abstract Child newChild();
 
   protected List familySamplesList(Collector.Type type, List samples) {
-    MetricFamilySamples mfs = new MetricFamilySamples(fullname, type, help, samples);
+    MetricFamilySamples mfs = new MetricFamilySamples(fullname, unit, type, help, samples);
     List mfsList = new ArrayList(1);
     mfsList.add(mfs);
     return mfsList;
@@ -160,6 +161,10 @@ protected SimpleCollector(Builder b) {
     if (!b.namespace.isEmpty()) {
       name = b.namespace + '_' + name;
     }
+    unit = b.unit;
+    if (!unit.isEmpty() && !name.endsWith("_" + unit)) {
+      name += "_" + unit;
+    }
     fullname = name;
     checkMetricName(fullname);
     if (b.help != null && b.help.isEmpty()) throw new IllegalStateException("Help hasn't been set.");
@@ -183,6 +188,7 @@ public abstract static class Builder, C extends SimpleCo
     String subsystem = "";
     String name = "";
     String fullname = "";
+    String unit = "";
     String help = "";
     String[] labelNames = new String[]{};
     // Some metrics require additional setup before the initialization can be done.
@@ -209,6 +215,13 @@ public B namespace(String namespace) {
       this.namespace = namespace;
       return (B)this;
     }
+    /**
+     * Set the uit of the metric. Required.
+     */
+    public B unit(String unit) {
+      this.unit = unit;
+      return (B)this;
+    }
     /**
      * Set the help string of the metric. Required.
      */
diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java
index 3f96dcbe3..4404f247a 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java
@@ -83,7 +83,7 @@ public void testMetricFamilySamples_filterNames() {
     HashSet metrics = new HashSet();
     HashSet series = new HashSet();
     for (Collector.MetricFamilySamples metricFamilySamples : Collections.list(registry.filteredMetricFamilySamples(
-            new HashSet(Arrays.asList("", "s_sum", "c", "part_filter_a", "part_filter_c"))))) {
+            new HashSet(Arrays.asList("", "s_sum", "c_total", "part_filter_a", "part_filter_c"))))) {
       metrics.add(metricFamilySamples.name);
       for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) {
         series.add(sample.name);
@@ -93,7 +93,7 @@ public void testMetricFamilySamples_filterNames() {
     assertEquals(1, sr.collectCallCount);
     assertEquals(2, pfr.collectCallCount);
     assertEquals(new HashSet(Arrays.asList("s", "c", "part_filter_a", "part_filter_c")), metrics);
-    assertEquals(new HashSet(Arrays.asList("s_sum", "c", "part_filter_a", "part_filter_c")), series);
+    assertEquals(new HashSet(Arrays.asList("s_sum", "c_total", "part_filter_a", "part_filter_c")), series);
   }
 
   @Test
diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
index b7e9ac6ea..6dc089d6a 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
@@ -23,11 +23,11 @@ public class CounterTest {
   public void setUp() {
     registry = new CollectorRegistry();
     noLabels = Counter.build().name("nolabels").help("help").register(registry);
-    labels = Counter.build().name("labels").help("help").labelNames("l").register(registry);
+    labels = Counter.build().name("labels").unit("seconds").help("help").labelNames("l").register(registry);
   }
 
   private double getValue() {
-    return registry.getSampleValue("nolabels").doubleValue();
+    return registry.getSampleValue("nolabels_total").doubleValue();
   }
   
   @Test
@@ -59,7 +59,7 @@ public void noLabelsDefaultZeroValue() {
   }
   
   private Double getLabelsValue(String labelValue) {
-    return registry.getSampleValue("labels", new String[]{"l"}, new String[]{labelValue});
+    return registry.getSampleValue("labels_seconds_total", new String[]{"l"}, new String[]{labelValue});
   }
 
   @Test
@@ -74,6 +74,18 @@ public void testLabels() {
     assertEquals(3.0, getLabelsValue("b").doubleValue(), .001);
   }
 
+  @Test
+  public void testTotalStrippedFromName() {
+    Counter c = Counter.build().name("foo_total").unit("seconds").help("h").create();
+    assertEquals("foo_seconds", c.fullname);
+
+    // This is not a good unit, but test it anyway.
+    c = Counter.build().name("foo_total").unit("total").help("h").create();
+    assertEquals("foo_total", c.fullname);
+    c = Counter.build().name("foo").unit("total").help("h").create();
+    assertEquals("foo_total", c.fullname);
+  }
+
   @Test
   public void testCollect() {
     labels.labels("a").inc();
@@ -84,8 +96,8 @@ public void testCollect() {
     labelNames.add("l");
     ArrayList labelValues = new ArrayList();
     labelValues.add("a");
-    samples.add(new Collector.MetricFamilySamples.Sample("labels", labelNames, labelValues, 1.0));
-    Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.COUNTER, "help", samples);
+    samples.add(new Collector.MetricFamilySamples.Sample("labels_seconds_total", labelNames, labelValues, 1.0));
+    Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels_seconds", "seconds", Collector.Type.COUNTER, "help", samples);
 
     assertEquals(1, mfs.size());
     assertEquals(mfsFixture, mfs.get(0));
diff --git a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
index e2b7d1a4e..74b01db52 100644
--- a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java
@@ -145,6 +145,15 @@ public void testReservedLabelNameThrows() {
     Gauge.build().name("a").labelNames("__name__").help("h").create();
   }
 
+  @Test
+  public void testUnitsAdded() {
+    Gauge g = Gauge.build().name("a").unit("seconds").help("h").create();
+    assertEquals("a_seconds", g.fullname);
+
+    Gauge g2 = Gauge.build().name("a_seconds").unit("seconds").help("h").create();
+    assertEquals("a_seconds", g2.fullname);
+  }
+
   @Test
   public void testSetChild() {
     metric.setChild(new Gauge.Child(){
diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
index 954edfda8..de6726ec3 100644
--- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
+++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
@@ -20,20 +20,27 @@ public static void write004(Writer writer, Enumeration 0) {
           writer.write('{');
           for (int i = 0; i < sample.labelNames.size(); ++i) {
diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
index 67a01b38e..f1886eeb7 100644
--- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
+++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
@@ -52,9 +52,32 @@ public void testCounterOutput() throws IOException {
     Counter noLabels = Counter.build().name("nolabels").help("help").register(registry);
     noLabels.inc();
     TextFormat.write004(writer, registry.metricFamilySamples());
-    assertEquals("# HELP nolabels help\n"
-                 + "# TYPE nolabels counter\n"
-                 + "nolabels 1.0\n", writer.toString());
+    assertEquals("# HELP nolabels_total help\n"
+                 + "# TYPE nolabels_total counter\n"
+                 + "nolabels_total 1.0\n", writer.toString());
+  }
+
+  @Test
+  public void testCounterSamplesMissingTotal() throws IOException {
+
+    class CustomCollector extends Collector {
+      public List collect() {
+        List mfs = new ArrayList();
+        ArrayList labelNames = new ArrayList();
+        ArrayList labelValues = new ArrayList();
+        ArrayList samples = new ArrayList();
+        MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0);
+        samples.add(sample);
+        mfs.add(new MetricFamilySamples("nolabels", Collector.Type.COUNTER, "help", samples));
+        return mfs;
+      }
+    }
+
+    new CustomCollector().register(registry);
+    TextFormat.write004(writer, registry.metricFamilySamples());
+    assertEquals("# HELP nolabels_total help\n"
+                 + "# TYPE nolabels_total counter\n"
+                 + "nolabels_total 1.0\n", writer.toString());
   }
 
   @Test

From 6847f9fff1f0d6f79a4d8e646052da7554e56565 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Thu, 14 Jan 2021 16:09:56 +0000
Subject: [PATCH 042/980] Get basic OM rendering working with HttpServer.

Signed-off-by: Brian Brazil 
---
 .../java/io/prometheus/client/Collector.java  |  19 ++-
 .../client/exporter/common/TextFormat.java    | 131 +++++++++++++++++-
 .../client/exporter/HTTPServer.java           |   7 +-
 3 files changed, 152 insertions(+), 5 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java
index 6855e3a51..a6c52b302 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Collector.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java
@@ -1,6 +1,7 @@
 
 package io.prometheus.client;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -46,11 +47,27 @@ public MetricFamilySamples(String name, String unit, Type type, String help, Lis
       if ((type == Type.INFO || type == Type.STATE_SET) && !unit.isEmpty()) {
         throw new IllegalArgumentException("Metric is of a type that cannot have a unit: " + name);
       }
+      List mungedSamples = samples;
+      // Deal with _total from pre-OM automatically.
+      if (type == Type.COUNTER) {
+        if (name.endsWith("_total")) {
+          name = name.substring(0, name.length() - 6);
+        }
+        String withTotal = name + "_total";
+        mungedSamples = new ArrayList(samples.size());
+        for (Sample s: samples) {
+          String n = s.name;
+          if (name.equals(n)) {
+            n = withTotal;
+          }
+          mungedSamples.add(new Sample(n, s.labelNames, s.labelValues, s.value, s.timestampMs));
+        }
+      }
       this.name = name;
       this.unit = unit;
       this.type = type;
       this.help = help;
-      this.samples = samples;
+      this.samples = mungedSamples;
     }
 
     public MetricFamilySamples(String name, Type type, String help, List samples) {
diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
index de6726ec3..901454ca7 100644
--- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
+++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
@@ -8,9 +8,46 @@
 
 public class TextFormat {
   /**
-   * Content-type for text version 0.0.4.
+   * Content-type for Prometheus text version 0.0.4.
    */
   public final static String CONTENT_TYPE_004 = "text/plain; version=0.0.4; charset=utf-8";
+  
+  /**
+   * Content-type for Openmetrics text version 1.0.0.
+   */
+  public final static String CONTENT_TYPE_OPENMETRICS_100 = "application/openmetrics-text; version=1.0.0; charset=utf-8";
+
+  /**
+   * Return the content type that should be used for a given Accept HTTP header.
+   */
+  public static String chooseContentType(String acceptHeader) {
+    if (acceptHeader == null) {
+      return CONTENT_TYPE_004;
+    }
+ 
+    for (String accepts : acceptHeader.split(",")) {
+      if ("application/openmetrics-text".equals(accepts.split(";")[0].trim())) {
+        return CONTENT_TYPE_OPENMETRICS_100;
+      }
+    }
+
+    return CONTENT_TYPE_004;
+  }
+
+  /**
+   * Write out the given MetricFamilySamples in a format per the contentType.
+   */
+  public static void writeFormat(String contentType, Writer writer, Enumeration mfs) throws IOException {
+    if (CONTENT_TYPE_004.equals(contentType)) {
+        write004(writer, mfs);
+        return;
+    }
+    if (CONTENT_TYPE_OPENMETRICS_100.equals(contentType)) {
+        writeOpenMetrics100(writer, mfs);
+        return;
+    }
+    throw new IllegalArgumentException("Unknown contentType " + contentType);
+  }
 
   /**
    * Write out the text version 0.0.4 of the given MetricFamilySamples.
@@ -107,8 +144,100 @@ private static String typeString(Collector.Type t) {
         return "summary";
       case HISTOGRAM:
         return "histogram";
+      case GAUGE_HISTOGRAM:
+        return "histogram";
+      case STATE_SET:
+        return "gauge";
+      case INFO:
+        return "gauge";
       default:
         return "untyped";
     }
   }
+
+  /**
+   * Write out the OpenMetrics text version 1.0.0 of the given MetricFamilySamples.
+   */
+  public static void writeOpenMetrics100(Writer writer, Enumeration mfs) throws IOException {
+    while(mfs.hasMoreElements()) {
+      Collector.MetricFamilySamples metricFamilySamples = mfs.nextElement();
+      String name = metricFamilySamples.name;
+ 
+      writer.write("# TYPE ");
+      writer.write(name);
+      writer.write(' ');
+      writer.write(omTypeString(metricFamilySamples.type));
+      writer.write('\n');
+ 
+      if (!metricFamilySamples.unit.isEmpty()) {
+        writer.write("# UNIT ");
+        writer.write(name);
+        writer.write(' ');
+        writer.write(metricFamilySamples.unit);
+        writer.write('\n');
+      }
+
+      writer.write("# HELP ");
+      writer.write(name);
+      writer.write(' ');
+      writeEscapedLabelValue(writer, metricFamilySamples.help);
+      writer.write('\n');
+ 
+      for (Collector.MetricFamilySamples.Sample sample: metricFamilySamples.samples) {
+        writer.write(sample.name);
+        if (sample.labelNames.size() > 0) {
+          writer.write('{');
+          for (int i = 0; i < sample.labelNames.size(); ++i) {
+            if (i > 0) {
+              writer.write(",");
+            }
+            writer.write(sample.labelNames.get(i));
+            writer.write("=\"");
+            writeEscapedLabelValue(writer, sample.labelValues.get(i));
+            writer.write("\"");
+          }
+          writer.write('}');
+        }
+        writer.write(' ');
+        writer.write(Collector.doubleToGoString(sample.value));
+        if (sample.timestampMs != null){
+          writer.write(' ');
+          long ts = sample.timestampMs.longValue();
+          writer.write(Long.toString(ts / 1000));
+          writer.write(".");
+          long ms = ts % 1000;
+          if (ms < 100) {
+            writer.write("0");
+          }
+          if (ms < 10) {
+            writer.write("0");
+          }
+          writer.write(Long.toString(ts % 1000));
+
+        }
+        writer.write('\n');
+      }
+    }
+  }
+
+  private static String omTypeString(Collector.Type t) {
+    switch (t) {
+      case GAUGE:
+        return "gauge";
+      case COUNTER:
+        return "counter";
+      case SUMMARY:
+        return "summary";
+      case HISTOGRAM:
+        return "histogram";
+      case GAUGE_HISTOGRAM:
+        return "gauge_histogram";
+      case STATE_SET:
+        return "stateset";
+      case INFO:
+        return "info";
+      default:
+        return "unknown";
+    }
+  }
 }
diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
index 10445a7c3..e016ab260 100644
--- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
+++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
@@ -67,13 +67,14 @@ public void handle(HttpExchange t) throws IOException {
             if ("/-/healthy".equals(contextPath)) {
                 osw.write(HEALTHY_RESPONSE);
             } else {
-                TextFormat.write004(osw,
+                String contentType = TextFormat.chooseContentType(t.getRequestHeaders().getFirst("Accept"));
+                t.getResponseHeaders().set("Content-Type", contentType);
+                TextFormat.writeFormat(contentType, osw,
                         registry.filteredMetricFamilySamples(parseQuery(query)));
             }
 
             osw.close();
-            t.getResponseHeaders().set("Content-Type",
-                    TextFormat.CONTENT_TYPE_004);
+
             if (shouldUseCompression(t)) {
                 t.getResponseHeaders().set("Content-Encoding", "gzip");
                 t.sendResponseHeaders(HttpURLConnection.HTTP_OK, 0);

From 99e209d234e40ddc4b10ae468e3ff0aff945bed7 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Fri, 15 Jan 2021 12:31:07 +0000
Subject: [PATCH 043/980] Update and add tests and code for _total handling.

Signed-off-by: Brian Brazil 
---
 .../client/CounterMetricFamily.java           |  4 +-
 .../io/prometheus/client/CollectorTest.java   | 31 +++++++++++++++
 .../client/CounterMetricFamilyTest.java       | 38 ++++++++++++++++---
 .../caffeine/CacheMetricsCollectorTest.java   |  1 +
 .../dropwizard/DropwizardExportsTest.java     |  8 ++--
 .../spring/boot/PrometheusEndpointTest.java   |  4 +-
 6 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java b/simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java
index c477bba1b..8c6156b35 100644
--- a/simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java
+++ b/simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java
@@ -37,7 +37,7 @@ public CounterMetricFamily(String name, String help, double value) {
     labelNames = Collections.emptyList();
     samples.add(
         new Sample(
-          name,
+          this.name + "_total",
           labelNames, 
           Collections.emptyList(),
           value));
@@ -52,7 +52,7 @@ public CounterMetricFamily addMetric(List labelValues, double value) {
     if (labelValues.size() != labelNames.size()) {
       throw new IllegalArgumentException("Incorrect number of labels.");
     }
-    samples.add(new Sample(name, labelNames, labelValues, value));
+    samples.add(new Sample(name + "_total", labelNames, labelValues, value));
     return this;
   }
 }
diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java
index 6c7fd358e..67840594e 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java
@@ -1,5 +1,10 @@
 package io.prometheus.client;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -11,4 +16,30 @@ public void sanitizeMetricName() throws Exception {
       assertEquals("foo_bar0", Collector.sanitizeMetricName("foo.bar0"));
       assertEquals(":baz::", Collector.sanitizeMetricName(":baz::"));
   }
+
+  @Test
+  public void testTotalHandling() throws Exception {
+    class YourCustomCollector extends Collector {
+      public List collect() {
+        List emptyList = new ArrayList();
+        return Arrays.asList(
+            new MetricFamilySamples("a_total", Type.COUNTER, "help", Arrays.asList(
+                new MetricFamilySamples.Sample("a_total", emptyList, emptyList, 1.0))),
+            new MetricFamilySamples("b", Type.COUNTER, "help", Arrays.asList(
+                new MetricFamilySamples.Sample("b", emptyList, emptyList, 2.0))),
+            new MetricFamilySamples("c_total", Type.COUNTER, "help", Arrays.asList(
+                new MetricFamilySamples.Sample("c", emptyList, emptyList, 3.0))),
+            new MetricFamilySamples("d", Type.COUNTER, "help", Arrays.asList(
+                new MetricFamilySamples.Sample("d_total", emptyList, emptyList, 4.0)))
+        );
+      }
+    }
+    CollectorRegistry registry = new CollectorRegistry();
+    new YourCustomCollector().register(registry);
+
+    assertEquals(1.0, registry.getSampleValue("a_total").doubleValue(), .001);
+    assertEquals(2.0, registry.getSampleValue("b_total").doubleValue(), .001);
+    assertEquals(3.0, registry.getSampleValue("c_total").doubleValue(), .001);
+    assertEquals(4.0, registry.getSampleValue("d_total").doubleValue(), .001);
+  }
 }
diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java b/simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java
index f2b3e1b1a..ffa8396a4 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java
@@ -35,10 +35,10 @@ public List collect() {
     }
     new YourCustomCollector().register(registry);
 
-    assertEquals(42.0, registry.getSampleValue("my_counter").doubleValue(), .001);
-    assertEquals(null, registry.getSampleValue("my_other_counter"));
-    assertEquals(4.0, registry.getSampleValue("my_other_counter", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001);
-    assertEquals(5.0, registry.getSampleValue("my_other_counter", new String[]{"labelname"}, new String[]{"bar"}).doubleValue(), .001);
+    assertEquals(42.0, registry.getSampleValue("my_counter_total").doubleValue(), .001);
+    assertEquals(null, registry.getSampleValue("my_other_counter_total"));
+    assertEquals(4.0, registry.getSampleValue("my_other_counter_total", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001);
+    assertEquals(5.0, registry.getSampleValue("my_other_counter_total", new String[]{"labelname"}, new String[]{"bar"}).doubleValue(), .001);
   }
 
   @Test
@@ -55,11 +55,37 @@ public List collect() {
     new YourCustomCollector().register(registry);
 
     assertEquals(1.0,
-        registry.getSampleValue("my_metric", new String[]{"name"}, new String[]{"value1"})
+        registry.getSampleValue("my_metric_total", new String[]{"name"}, new String[]{"value1"})
             .doubleValue(), .001);
     assertEquals(2.0,
-        registry.getSampleValue("my_metric", new String[]{"name"}, new String[]{"value2"})
+        registry.getSampleValue("my_metric_total", new String[]{"name"}, new String[]{"value2"})
             .doubleValue(), .001);
   }
 
+  @Test
+  public void testTotalHandling() {
+    class YourCustomCollector extends Collector {
+      public List collect() {
+        return Arrays.asList(
+            new CounterMetricFamily("a_total", "help", Arrays.asList("name"))
+                .addMetric(Arrays.asList("value"), 1.0),
+            new CounterMetricFamily("b", "help", Arrays.asList("name"))
+                .addMetric(Arrays.asList("value"), 2.0),
+            new CounterMetricFamily("c_total", "help", 3.0),
+            new CounterMetricFamily("d_total", "help", 4.0)
+        );
+      }
+    }
+    new YourCustomCollector().register(registry);
+
+    assertEquals(1.0,
+        registry.getSampleValue("a_total", new String[]{"name"}, new String[]{"value"})
+            .doubleValue(), .001);
+    assertEquals(2.0,
+        registry.getSampleValue("b_total", new String[]{"name"}, new String[]{"value"})
+            .doubleValue(), .001);
+    assertEquals(3.0, registry.getSampleValue("c_total").doubleValue(), .001);
+    assertEquals(4.0, registry.getSampleValue("d_total").doubleValue(), .001);
+  }
+
 }
diff --git a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
index 65429f337..75f198d1b 100644
--- a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
+++ b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java
@@ -70,6 +70,7 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception {
         }
         cache.get("user3");
 
+
         assertMetric(registry, "caffeine_cache_hit_total", "loadingusers", 1.0);
         assertMetric(registry, "caffeine_cache_miss_total", "loadingusers", 3.0);
 
diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
index da721f75c..409dfaa51 100644
--- a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
+++ b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
@@ -224,7 +224,7 @@ public void testThatMetricHelpUsesOriginalDropwizardName() {
 
         assertTrue(elements.keySet().contains("my_application_namedTimer1"));
         assertTrue(elements.keySet().contains("my_application_namedCounter1"));
-        assertTrue(elements.keySet().contains("my_application_namedMeter1_total"));
+        assertTrue(elements.keySet().contains("my_application_namedMeter1"));
         assertTrue(elements.keySet().contains("my_application_namedHistogram1"));
         assertTrue(elements.keySet().contains("my_application_namedGauge1"));
 
@@ -234,7 +234,7 @@ public void testThatMetricHelpUsesOriginalDropwizardName() {
         assertThat(elements.get("my_application_namedCounter1").help,
                 is("Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=com.codahale.metrics.Counter)"));
 
-        assertThat(elements.get("my_application_namedMeter1_total").help,
+        assertThat(elements.get("my_application_namedMeter1").help,
                 is("Generated from Dropwizard metric import (metric=my.application.namedMeter1, type=com.codahale.metrics.Meter)"));
 
         assertThat(elements.get("my_application_namedHistogram1").help,
@@ -321,7 +321,7 @@ public void testThatMetricsMappedToSameNameAreGroupedInSameFamily() {
         assertTrue(namedCounter.samples.contains(namedCounter1));
         assertTrue(namedCounter.samples.contains(namedCounter2));
 
-        final Collector.MetricFamilySamples namedMeter = elements.get("my_application_namedMeter_total");
+        final Collector.MetricFamilySamples namedMeter = elements.get("my_application_namedMeter");
         assertNotNull(namedMeter);
         assertEquals(Collector.Type.COUNTER, namedMeter.type);
         assertEquals(2, namedMeter.samples.size());
@@ -349,4 +349,4 @@ public Double getValue() {
             return 0.0;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java
index 377034964..737788f76 100644
--- a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java
+++ b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java
@@ -55,7 +55,7 @@ public void testMetricsExportedThroughPrometheusEndpoint() {
     HttpHeaders headers = new HttpHeaders();
     headers.set("Accept", "text/plain");
 
-    ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus?name[]=foo_bar", HttpMethod.GET, new HttpEntity(headers), String.class);
+    ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus?name[]=foo_bar_total", HttpMethod.GET, new HttpEntity(headers), String.class);
 
     // then:
     assertEquals(HttpStatus.OK, metricsResponse.getStatusCode());
@@ -63,7 +63,7 @@ public void testMetricsExportedThroughPrometheusEndpoint() {
 
     List responseLines = Arrays.asList(metricsResponse.getBody().split("\n"));
     assertThat(responseLines, CustomMatchers.exactlyNItems(1,
-            matchesPattern("foo_bar\\{label1=\"val1\",label2=\"val2\",?\\} 3.0")));
+            matchesPattern("foo_bar_total\\{label1=\"val1\",label2=\"val2\",?\\} 3.0")));
   }
 
   private String getBaseUrl() {

From d4f32a2c1467aabb19110ff524ac6c5af47faf3f Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Fri, 15 Jan 2021 13:17:08 +0000
Subject: [PATCH 044/980] Get all the http servers working with OM.

Signed-off-by: Brian Brazil 
---
 .../client/exporter/common/TextFormat.java    |  1 +
 .../client/exporter/TestHTTPServer.java       | 17 +++++++++++++++++
 .../client/exporter/MetricsServlet.java       |  5 +++--
 .../client/exporter/MetricsServletTest.java   | 19 +++++++++++++++++++
 .../spring/boot/PrometheusEndpoint.java       |  6 +++---
 .../spring/boot/PrometheusMvcEndpoint.java    |  9 ++++++---
 .../boot/PrometheusMvcEndpointTest.java       | 16 +++++++++++++++-
 .../client/vertx/MetricsHandler.java          |  6 ++++--
 8 files changed, 68 insertions(+), 11 deletions(-)

diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
index 901454ca7..ed3992f24 100644
--- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
+++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
@@ -218,6 +218,7 @@ public static void writeOpenMetrics100(Writer writer, Enumeration {
 
   @Override
   public String invoke() {
-    return writeRegistry(Collections.emptySet());
+    return writeRegistry(Collections.emptySet(), "");
   }
 
-  public String writeRegistry(Set metricsToInclude) {
+  public String writeRegistry(Set metricsToInclude, String contentType) {
     try {
       Writer writer = new StringWriter();
-      TextFormat.write004(writer, collectorRegistry.filteredMetricFamilySamples(metricsToInclude));
+      TextFormat.writeFormat(contentType, writer, collectorRegistry.filteredMetricFamilySamples(metricsToInclude));
       return writer.toString();
     } catch (IOException e) {
       // This actually never happens since StringWriter::write() doesn't throw any IOException
diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java
index 816fde7f3..fafd4dc69 100644
--- a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java
+++ b/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java
@@ -4,6 +4,7 @@
 import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -29,16 +30,18 @@ public PrometheusMvcEndpoint(PrometheusEndpoint delegate) {
   )
   @ResponseBody
   public ResponseEntity value(
-          @RequestParam(value = "name[]", required = false, defaultValue = "") Set name) {
+          @RequestParam(value = "name[]", required = false, defaultValue = "") Set name,
+          @RequestHeader(value = "Accept", required = false, defaultValue = "") String accept) {
     if (!getDelegate().isEnabled()) {
       // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's
       // disabled
       return getDisabledResponse();
     }
 
-    String result = delgate.writeRegistry(name);
+    String contentType = TextFormat.chooseContentType(accept);
+    String result = delgate.writeRegistry(name, contentType);
     return ResponseEntity.ok()
-            .header(CONTENT_TYPE, TextFormat.CONTENT_TYPE_004)
+            .header(CONTENT_TYPE, contentType)
             .body(result);
   }
 }
diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java
index e0b1567f4..5f7eea102 100644
--- a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java
+++ b/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java
@@ -17,6 +17,7 @@
 import org.springframework.test.context.junit4.SpringRunner;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
 
 @RunWith(SpringRunner.class)
@@ -50,6 +51,19 @@ public void testAcceptPlainText() throws Exception {
         assertEquals(HttpStatus.OK, metricsResponse.getStatusCode());
     }
 
+    @Test
+    public void testAcceptOpenMetrics() throws Exception {
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("Accept", "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1");
+
+        ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus", HttpMethod.GET, new HttpEntity(headers), String.class);
+
+        assertEquals(HttpStatus.OK, metricsResponse.getStatusCode());
+        assertEquals(StringUtils.deleteWhitespace(TextFormat.CONTENT_TYPE_OPENMETRICS_100), metricsResponse.getHeaders().getContentType().toString().toLowerCase());
+        assertTrue(metricsResponse.getBody().contains("# EOF"));
+    }
+
     @Test
     public void testNameParamIsNotNull() {
         ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus?name[]=foo_bar", HttpMethod.GET, getEntity(), String.class);
@@ -68,4 +82,4 @@ public HttpEntity getEntity() {
     private String getBaseUrl() {
         return "http://localhost:" + localServerPort;
     }
-}
\ No newline at end of file
+}
diff --git a/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java b/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java
index 4f763a541..5f1cbfafd 100644
--- a/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java
+++ b/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java
@@ -73,10 +73,12 @@ public MetricsHandler(CollectorRegistry registry) {
   public void handle(RoutingContext ctx) {
     try {
       final BufferWriter writer = new BufferWriter();
-      TextFormat.write004(writer, registry.filteredMetricFamilySamples(parse(ctx.request())));
+      String contentType = TextFormat.chooseContentType(ctx.request().headers().get("Accept"));
+
+      TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(parse(ctx.request())));
       ctx.response()
               .setStatusCode(200)
-              .putHeader("Content-Type", TextFormat.CONTENT_TYPE_004)
+              .putHeader("Content-Type", contentType)
               .end(writer.getBuffer());
     } catch (IOException e) {
       ctx.fail(e);

From 706672af5d7266b9b94b576adb4f2eebc99e12de Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Fri, 15 Jan 2021 13:36:23 +0000
Subject: [PATCH 045/980] Add OM output tests.

Signed-off-by: Brian Brazil 
---
 .../common/TextFormatOpenMetricsTest.java     | 173 ++++++++++++++++++
 .../exporter/common/TextFormatTest.java       |  10 +
 2 files changed, 183 insertions(+)
 create mode 100644 simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java

diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java
new file mode 100644
index 000000000..c8e6f4848
--- /dev/null
+++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java
@@ -0,0 +1,173 @@
+package io.prometheus.client.exporter.common;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import io.prometheus.client.Collector;
+import io.prometheus.client.CollectorRegistry;
+import io.prometheus.client.Counter;
+import io.prometheus.client.Gauge;
+import io.prometheus.client.Summary;
+
+
+public class TextFormatOpenMetricsTest {
+  CollectorRegistry registry;
+  StringWriter writer;
+
+  @Before
+  public void setUp() {
+    registry = new CollectorRegistry();
+    writer = new StringWriter();
+  }
+
+  @Test
+  public void testGaugeOutput() throws IOException {
+    Gauge noLabels = Gauge.build().name("nolabels").help("help").register(registry);
+    noLabels.inc();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels gauge\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testValueInfinity() throws IOException {
+    Gauge noLabels = Gauge.build().name("nolabels").help("help").register(registry);
+    noLabels.set(Double.POSITIVE_INFINITY);
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels gauge\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels +Inf\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testCounterOutput() throws IOException {
+    Counter noLabels = Counter.build().name("nolabels").help("help").register(registry);
+    noLabels.inc();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels counter\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels_total 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testCounterSamplesMissingTotal() throws IOException {
+
+    class CustomCollector extends Collector {
+      public List collect() {
+        List mfs = new ArrayList();
+        ArrayList labelNames = new ArrayList();
+        ArrayList labelValues = new ArrayList();
+        ArrayList samples = new ArrayList();
+        MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0);
+        samples.add(sample);
+        mfs.add(new MetricFamilySamples("nolabels", Collector.Type.COUNTER, "help", samples));
+        return mfs;
+      }
+    }
+
+    new CustomCollector().register(registry);
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels counter\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels_total 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testMetricOutputWithTimestamp() throws IOException {
+
+    class CustomCollector extends Collector {
+      public List collect() {
+        List mfs = new ArrayList();
+        ArrayList labelNames = new ArrayList();
+        ArrayList labelValues = new ArrayList();
+        ArrayList samples = new ArrayList();
+        MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0, 1518123006L);
+        samples.add(sample);
+        mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNTYPED, "help", samples));
+        return mfs;
+      }
+    }
+    
+    new CustomCollector().register(registry);
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels unknown\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels 1.0 1518123.006\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testSummaryOutput() throws IOException {
+    Summary noLabels = Summary.build().name("nolabels").help("help").register(registry);
+    noLabels.observe(2);
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels summary\n"
+                 + "# HELP nolabels help\n"
+                 + "nolabels_count 1.0\n"
+                 + "nolabels_sum 2.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testSummaryOutputWithQuantiles() throws IOException {
+    Summary labelsAndQuantiles = Summary.build()
+            .quantile(0.5, 0.05).quantile(0.9, 0.01).quantile(0.99, 0.001)
+            .labelNames("l").name("labelsAndQuantiles").help("help").register(registry);
+    labelsAndQuantiles.labels("a").observe(2);
+    writer = new StringWriter();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE labelsAndQuantiles summary\n"
+            + "# HELP labelsAndQuantiles help\n"
+            + "labelsAndQuantiles{l=\"a\",quantile=\"0.5\"} 2.0\n"
+            + "labelsAndQuantiles{l=\"a\",quantile=\"0.9\"} 2.0\n"
+            + "labelsAndQuantiles{l=\"a\",quantile=\"0.99\"} 2.0\n"
+            + "labelsAndQuantiles_count{l=\"a\"} 1.0\n"
+            + "labelsAndQuantiles_sum{l=\"a\"} 2.0\n"
+            + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testLabelsOutput() throws IOException {
+    Gauge labels = Gauge.build().name("labels").help("help").labelNames("l").register(registry);
+    labels.labels("a").inc();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE labels gauge\n"
+                 + "# HELP labels help\n"
+                 + "labels{l=\"a\"} 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testLabelValuesEscaped() throws IOException {
+    Gauge labels = Gauge.build().name("labels").help("help").labelNames("l").register(registry);
+    labels.labels("ąćčęntěd a\nb\\c\"d").inc();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE labels gauge\n"
+                 + "# HELP labels help\n"
+                 + "labels{l=\"ąćčęntěd a\\nb\\\\c\\\"d\"} 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+
+  @Test
+  public void testHelpEscaped() throws IOException {
+    Gauge noLabels = Gauge.build().name("nolabels").help("ąćčęntěd h\"e\\l\np").register(registry);
+    noLabels.inc();
+    TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples());
+    assertEquals("# TYPE nolabels gauge\n"
+                 + "# HELP nolabels ąćčęntěd h\\\"e\\\\l\\np\n"
+                 + "nolabels 1.0\n"
+                 + "# EOF\n", writer.toString());
+  }
+}
diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
index f1886eeb7..b98972a26 100644
--- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
+++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
@@ -160,4 +160,14 @@ public void testHelpEscaped() throws IOException {
                  + "# TYPE nolabels gauge\n"
                  + "nolabels 1.0\n", writer.toString());
   }
+
+  @Test
+  public void testChooseContentType() throws IOException {
+    assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType(null));
+    assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType(""));
+    assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType("text/plain;version=0.0.4"));
+    assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType("foo"));
+    assertEquals(TextFormat.CONTENT_TYPE_OPENMETRICS_100, TextFormat.chooseContentType("application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"));
+    assertEquals(TextFormat.CONTENT_TYPE_OPENMETRICS_100, TextFormat.chooseContentType("application/openmetrics-text; version=1.0.0"));
+  }
 }

From 801f91e05cbee4dfe99bd65724d6a7cfede8e94a Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Fri, 15 Jan 2021 14:22:35 +0000
Subject: [PATCH 046/980] Add handling for gsum/gcount/created in Prometheus
 exposition format.

Signed-off-by: Brian Brazil 
---
 .../client/exporter/common/TextFormat.java    | 37 ++++++++++++---
 .../exporter/common/TextFormatTest.java       | 45 +++++++++++++++++++
 2 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
index ed3992f24..a16a57632 100644
--- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
+++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java
@@ -2,7 +2,12 @@
 
 import java.io.IOException;
 import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
 
 import io.prometheus.client.Collector;
 
@@ -53,31 +58,47 @@ public static void writeFormat(String contentType, Writer writer, Enumeration mfs) throws IOException {
+    Map omFamilies = new TreeMap();
     /* See http://prometheus.io/docs/instrumenting/exposition_formats/
      * for the output format specification. */
     while(mfs.hasMoreElements()) {
       Collector.MetricFamilySamples metricFamilySamples = mfs.nextElement();
       String name = metricFamilySamples.name;
-      if (metricFamilySamples.type == Collector.Type.COUNTER) {
-        name += "_total";
-      }
       writer.write("# HELP ");
       writer.write(name);
+      if (metricFamilySamples.type == Collector.Type.COUNTER) {
+        writer.write("_total");
+      }
       writer.write(' ');
       writeEscapedHelp(writer, metricFamilySamples.help);
       writer.write('\n');
 
       writer.write("# TYPE ");
       writer.write(name);
+      if (metricFamilySamples.type == Collector.Type.COUNTER) {
+        writer.write("_total");
+      }
       writer.write(' ');
       writer.write(typeString(metricFamilySamples.type));
       writer.write('\n');
 
+      String createdName = name + "_created";
+      String gcountName = name + "_gcount";
+      String gsumName = name + "_gsum";
       for (Collector.MetricFamilySamples.Sample sample: metricFamilySamples.samples) {
-        writer.write(sample.name);
-        if (metricFamilySamples.type == Collector.Type.COUNTER && sample.name.equals(metricFamilySamples.name)) {
-          writer.write("_total");
+        /* OpenMetrics specific sample, put in a gauge at the end. */
+        if (sample.name.equals(createdName)
+            || sample.name.equals(gcountName)
+            || sample.name.equals(gsumName)) {
+          Collector.MetricFamilySamples omFamily = omFamilies.get(sample.name);
+          if (omFamily == null) {
+            omFamily = new Collector.MetricFamilySamples(sample.name, Collector.Type.GAUGE, metricFamilySamples.help, new ArrayList());
+            omFamilies.put(sample.name, omFamily);
+          }
+          omFamily.samples.add(sample);
+          continue;
         }
+        writer.write(sample.name);
         if (sample.labelNames.size() > 0) {
           writer.write('{');
           for (int i = 0; i < sample.labelNames.size(); ++i) {
@@ -97,6 +118,10 @@ public static void write004(Writer writer, Enumeration collect() {
+        List mfs = new ArrayList();
+        ArrayList labelNames = new ArrayList();
+        ArrayList labelValues = new ArrayList();
+        ArrayList samples = new ArrayList();
+        samples.add(new MetricFamilySamples.Sample("nolabels_bucket", Arrays.asList("le"), Arrays.asList("+Inf"), 2.0));
+        samples.add(new MetricFamilySamples.Sample("nolabels_gcount", labelNames, labelValues, 2.0));
+        samples.add(new MetricFamilySamples.Sample("nolabels_gsum", labelNames, labelValues, 7.0));
+        samples.add(new MetricFamilySamples.Sample("nolabels_created", labelNames, labelValues, 1234.0));
+        mfs.add(new MetricFamilySamples("nolabels", Collector.Type.GAUGE_HISTOGRAM, "help", samples));
+        return mfs;
+      }
+    }
+    new CustomCollector().register(registry);
+    writer = new StringWriter();
+    TextFormat.write004(writer, registry.metricFamilySamples());
+    assertEquals("# HELP nolabels help\n"
+            + "# TYPE nolabels histogram\n"
+            + "nolabels_bucket{le=\"+Inf\",} 2.0\n"
+            + "# HELP nolabels_created help\n"
+            + "# TYPE nolabels_created gauge\n"
+            + "nolabels_created 1234.0\n"
+            + "# HELP nolabels_gcount help\n"
+            + "# TYPE nolabels_gcount gauge\n"
+            + "nolabels_gcount 2.0\n"
+            + "# HELP nolabels_gsum help\n"
+            + "# TYPE nolabels_gsum gauge\n"
+            + "nolabels_gsum 7.0\n", writer.toString());
+  }
+
   @Test
   public void testLabelsOutput() throws IOException {
     Gauge labels = Gauge.build().name("labels").help("help").labelNames("l").register(registry);

From 5c0d1e7ee22897b87f73358caee43d95dcd07408 Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Fri, 15 Jan 2021 14:47:38 +0000
Subject: [PATCH 047/980] Add _created for direct instrumentation.

Signed-off-by: Brian Brazil 
---
 .../prometheus/client/CollectorRegistry.java  |  8 ++++++
 .../java/io/prometheus/client/Counter.java    |  8 ++++++
 .../java/io/prometheus/client/Histogram.java  |  8 ++++--
 .../java/io/prometheus/client/Summary.java    |  8 ++++--
 .../io/prometheus/client/CounterTest.java     |  1 +
 .../io/prometheus/client/HistogramTest.java   |  2 ++
 .../io/prometheus/client/SummaryTest.java     |  2 ++
 .../common/TextFormatOpenMetricsTest.java     |  9 ++++---
 .../exporter/common/TextFormatTest.java       | 26 +++++++++++++++----
 9 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
index b7bc0284b..590beeba5 100644
--- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
+++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java
@@ -113,12 +113,20 @@ private List collectorNames(Collector m) {
         case SUMMARY:
           names.add(family.name + "_count");
           names.add(family.name + "_sum");
+          names.add(family.name + "_created");
           names.add(family.name);
           break;
         case HISTOGRAM:
           names.add(family.name + "_count");
           names.add(family.name + "_sum");
           names.add(family.name + "_bucket");
+          names.add(family.name + "_created");
+          names.add(family.name);
+          break;
+        case GAUGE_HISTOGRAM:
+          names.add(family.name + "_gcount");
+          names.add(family.name + "_gsum");
+          names.add(family.name + "_bucket");
           names.add(family.name);
           break;
         default:
diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java
index 27a7d5627..900812b16 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Counter.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java
@@ -112,6 +112,7 @@ protected Child newChild() {
    */
   public static class Child {
     private final DoubleAdder value = new DoubleAdder();
+    private final long created = System.currentTimeMillis();
     /**
      * Increment the counter by 1.
      */
@@ -134,6 +135,12 @@ public void inc(double amt) {
     public double get() {
       return value.sum();
     }
+    /**
+     * Get the created time of the counter in milliseconds.
+     */
+    public long created() {
+      return created;
+    }
   }
 
   // Convenience methods.
@@ -163,6 +170,7 @@ public List collect() {
     List samples = new ArrayList(children.size());
     for(Map.Entry, Child> c: children.entrySet()) {
       samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get()));
+      samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0));
     }
     return familySamplesList(Type.COUNTER, samples);
   }
diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java
index 1d8b1a2fa..30595e187 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java
@@ -231,10 +231,12 @@ public  E time(Callable timeable) {
     public static class Value {
       public final double sum;
       public final double[] buckets;
+      public final long created;
 
-      public Value(double sum, double[] buckets) {
+      public Value(double sum, double[] buckets, long created) {
         this.sum = sum;
         this.buckets = buckets;
+        this.created = created;
       }
     }
 
@@ -248,6 +250,7 @@ private Child(double[] buckets) {
     private final double[] upperBounds;
     private final DoubleAdder[] cumulativeCounts;
     private final DoubleAdder sum = new DoubleAdder();
+    private final long created = System.currentTimeMillis();
 
 
     /**
@@ -283,7 +286,7 @@ public Value get() {
         acc += cumulativeCounts[i].sum();
         buckets[i] = acc;
       }
-      return new Value(sum.sum(), buckets);
+      return new Value(sum.sum(), buckets, created);
     }
   }
 
@@ -337,6 +340,7 @@ public List collect() {
       }
       samples.add(new MetricFamilySamples.Sample(fullname + "_count", labelNames, c.getKey(), v.buckets[buckets.length-1]));
       samples.add(new MetricFamilySamples.Sample(fullname + "_sum", labelNames, c.getKey(), v.sum));
+      samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0));
     }
 
     return familySamplesList(Type.HISTOGRAM, samples);
diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java
index 4d79e558a..9d2aca3f8 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Summary.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java
@@ -239,11 +239,13 @@ public static class Value {
       public final double count;
       public final double sum;
       public final SortedMap quantiles;
+      public final long created;
 
-      private Value(double count, double sum, List quantiles, TimeWindowQuantiles quantileValues) {
+      private Value(double count, double sum, List quantiles, TimeWindowQuantiles quantileValues, long created) {
         this.count = count;
         this.sum = sum;
         this.quantiles = Collections.unmodifiableSortedMap(snapshot(quantiles, quantileValues));
+        this.created = created;
       }
 
       private SortedMap snapshot(List quantiles, TimeWindowQuantiles quantileValues) {
@@ -263,6 +265,7 @@ private SortedMap snapshot(List quantiles, TimeWindowQ
     private final DoubleAdder sum = new DoubleAdder();
     private final List quantiles;
     private final TimeWindowQuantiles quantileValues;
+    private final long created = System.currentTimeMillis();
 
     private Child(List quantiles, long maxAgeSeconds, int ageBuckets) {
       this.quantiles = quantiles;
@@ -297,7 +300,7 @@ public Timer startTimer() {
      * Warning: The definition of {@link Value} is subject to change.
      */
     public Value get() {
-      return new Value(count.sum(), sum.sum(), quantiles, quantileValues);
+      return new Value(count.sum(), sum.sum(), quantiles, quantileValues, created);
     }
   }
 
@@ -360,6 +363,7 @@ public List collect() {
       }
       samples.add(new MetricFamilySamples.Sample(fullname + "_count", labelNames, c.getKey(), v.count));
       samples.add(new MetricFamilySamples.Sample(fullname + "_sum", labelNames, c.getKey(), v.sum));
+      samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0));
     }
 
     return familySamplesList(Type.SUMMARY, samples);
diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
index 6dc089d6a..2d7ba0735 100644
--- a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java
@@ -97,6 +97,7 @@ public void testCollect() {
     ArrayList labelValues = new ArrayList();
     labelValues.add("a");
     samples.add(new Collector.MetricFamilySamples.Sample("labels_seconds_total", labelNames, labelValues, 1.0));
+    samples.add(new Collector.MetricFamilySamples.Sample("labels_seconds_created", labelNames, labelValues, labels.labels("a").created() / 1000.0));
     Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels_seconds", "seconds", Collector.Type.COUNTER, "help", samples);
 
     assertEquals(1, mfs.size());
diff --git a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
index 1a09a8939..15ac00a76 100644
--- a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java
@@ -204,6 +204,8 @@ public void testCollect() {
     }
     samples.add(new Collector.MetricFamilySamples.Sample("labels_count", labelNames, labelValues, 1.0));
     samples.add(new Collector.MetricFamilySamples.Sample("labels_sum", labelNames, labelValues, 2.0));
+    samples.add(new Collector.MetricFamilySamples.Sample("labels_created", labelNames, labelValues, labels.labels("a").get().created / 1000.0));
+
     Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.HISTOGRAM, "help", samples);
 
     assertEquals(1, mfs.size());
diff --git a/simpleclient/src/test/java/io/prometheus/client/SummaryTest.java b/simpleclient/src/test/java/io/prometheus/client/SummaryTest.java
index 06e1f9d9b..c6f70506d 100644
--- a/simpleclient/src/test/java/io/prometheus/client/SummaryTest.java
+++ b/simpleclient/src/test/java/io/prometheus/client/SummaryTest.java
@@ -183,6 +183,7 @@ public void testCollect() {
     labelValues.add("a");
     samples.add(new Collector.MetricFamilySamples.Sample("labels_count", labelNames, labelValues, 1.0));
     samples.add(new Collector.MetricFamilySamples.Sample("labels_sum", labelNames, labelValues, 2.0));
+    samples.add(new Collector.MetricFamilySamples.Sample("labels_created", labelNames, labelValues, labels.labels("a").get().created / 1000.0));
     Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.SUMMARY, "help", samples);
 
     assertEquals(1, mfs.size());
@@ -200,6 +201,7 @@ public void testCollectWithQuantiles() {
     samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles", asList("l", "quantile"), asList("a", "0.99"), 2.0));
     samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_count", asList("l"), asList("a"), 1.0));
     samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_sum", asList("l"), asList("a"), 2.0));
+    samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_created", asList("l"), asList("a"), labelsAndQuantiles.labels("a").get().created / 1000.0));
     Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels_and_quantiles", Collector.Type.SUMMARY, "help", samples);
 
     assertEquals(1, mfs.size());
diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java
index c8e6f4848..3d013ee5c 100644
--- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java
+++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java
@@ -57,7 +57,8 @@ public void testCounterOutput() throws IOException {
     assertEquals("# TYPE nolabels counter\n"
                  + "# HELP nolabels help\n"
                  + "nolabels_total 1.0\n"
-                 + "# EOF\n", writer.toString());
+                 + "nolabels_created 1234.0\n"
+                 + "# EOF\n", writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0"));
   }
 
   @Test
@@ -117,7 +118,8 @@ public void testSummaryOutput() throws IOException {
                  + "# HELP nolabels help\n"
                  + "nolabels_count 1.0\n"
                  + "nolabels_sum 2.0\n"
-                 + "# EOF\n", writer.toString());
+                 + "nolabels_created 1234.0\n"
+                 + "# EOF\n", writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0"));
   }
 
   @Test
@@ -135,7 +137,8 @@ public void testSummaryOutputWithQuantiles() throws IOException {
             + "labelsAndQuantiles{l=\"a\",quantile=\"0.99\"} 2.0\n"
             + "labelsAndQuantiles_count{l=\"a\"} 1.0\n"
             + "labelsAndQuantiles_sum{l=\"a\"} 2.0\n"
-            + "# EOF\n", writer.toString());
+            + "labelsAndQuantiles_created{l=\"a\"} 1234.0\n"
+            + "# EOF\n", writer.toString().replaceAll("(_created\\{.*\\}) [0-9E.]+", "$1 1234.0"));
   }
 
   @Test
diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
index a1b367f06..98fbabfb2 100644
--- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
+++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java
@@ -55,7 +55,11 @@ public void testCounterOutput() throws IOException {
     TextFormat.write004(writer, registry.metricFamilySamples());
     assertEquals("# HELP nolabels_total help\n"
                  + "# TYPE nolabels_total counter\n"
-                 + "nolabels_total 1.0\n", writer.toString());
+                 + "nolabels_total 1.0\n"
+                 + "# HELP nolabels_created help\n"
+                 + "# TYPE nolabels_created gauge\n"
+                 + "nolabels_created 1234.0\n",
+                 writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0"));
   }
 
   @Test
@@ -65,7 +69,11 @@ public void testCounterWithTotalOutput() throws IOException {
     TextFormat.write004(writer, registry.metricFamilySamples());
     assertEquals("# HELP nolabels_total help\n"
                  + "# TYPE nolabels_total counter\n"
-                 + "nolabels_total 1.0\n", writer.toString());
+                 + "nolabels_total 1.0\n"
+                 + "# HELP nolabels_created help\n"
+                 + "# TYPE nolabels_created gauge\n"
+                 + "nolabels_created 1234.0\n",
+                 writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0"));
   }
 
 
@@ -107,7 +115,7 @@ public List collect() {
         return mfs;
       }
     }
-    
+
     new CustomCollector().register(registry);
     TextFormat.write004(writer, registry.metricFamilySamples());
     assertEquals("# HELP nolabels help\n"
@@ -123,7 +131,11 @@ public void testSummaryOutput() throws IOException {
     assertEquals("# HELP nolabels help\n"
                  + "# TYPE nolabels summary\n"
                  + "nolabels_count 1.0\n"
-                 + "nolabels_sum 2.0\n", writer.toString());
+                 + "nolabels_sum 2.0\n"
+                 + "# HELP nolabels_created help\n"
+                 + "# TYPE nolabels_created gauge\n"
+                 + "nolabels_created 1234.0\n",
+                 writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0"));
   }
 
   @Test
@@ -140,7 +152,11 @@ public void testSummaryOutputWithQuantiles() throws IOException {
             + "labelsAndQuantiles{l=\"a\",quantile=\"0.9\",} 2.0\n"
             + "labelsAndQuantiles{l=\"a\",quantile=\"0.99\",} 2.0\n"
             + "labelsAndQuantiles_count{l=\"a\",} 1.0\n"
-            + "labelsAndQuantiles_sum{l=\"a\",} 2.0\n", writer.toString());
+            + "labelsAndQuantiles_sum{l=\"a\",} 2.0\n"
+            + "# HELP labelsAndQuantiles_created help\n"
+            + "# TYPE labelsAndQuantiles_created gauge\n"
+            + "labelsAndQuantiles_created{l=\"a\",} 1234.0\n",
+            writer.toString().replaceAll("(_created\\{.*\\}) [0-9E.]+", "$1 1234.0"));
   }
 
   @Test

From 92d34e36ef1d75c8b99af652484003bc212e03dc Mon Sep 17 00:00:00 2001
From: Brian Brazil 
Date: Mon, 18 Jan 2021 12:47:14 +0000
Subject: [PATCH 048/980] Add support for Enumeration.

Signed-off-by: Brian Brazil 
---
 .../io/prometheus/client/Enumeration.java     | 223 ++++++++++++++++++
 .../io/prometheus/client/EnumerationTest.java | 114 +++++++++
 2 files changed, 337 insertions(+)
 create mode 100644 simpleclient/src/main/java/io/prometheus/client/Enumeration.java
 create mode 100644 simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java

diff --git a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java
new file mode 100644
index 000000000..900f1ec30
--- /dev/null
+++ b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java
@@ -0,0 +1,223 @@
+package io.prometheus.client;
+
+import io.prometheus.client.CKMSQuantiles.Quantile;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Enumeration metric, to track which of a set of states something is in.
+ *
+ * The first provided state will be the default.
+ *
+ * 

+ * Example enumeration: + *

+ * {@code
+ *   class YourClass {
+ *     static final Enumeration taskState = Enumeration.build()
+ *         .name("task_state").help("State of the task.")
+ *         .states("stopped", "starting", "running")
+ *         .register();
+ *
+ *     void stop() {
+ *          // Your code here.
+ *          taskState.state("stopped")
+ *     }
+ *   }
+ * }
+ * 
+ * + * You can also use a Java Enum: + *
+ *   class YourClass {
+ *     public enum yourEnum {
+ *       STOPPED,
+ *       STARTING,
+ *       RUNNING,
+ *     }
+ *     static final Enumeration taskState = Enumeration.build()
+ *         .name("task_state").help("State of the task.")
+ *         .states(yourEnum.class)
+ *         .register();
+ *
+ *     void stop() {
+ *          // Your code here.
+ *          taskState.state(yourEnum.STOPPED)
+ *     }
+ *   }
+ * }
+ * 
+ */ +public class Enumeration extends SimpleCollector implements Counter.Describable { + + private final Set states; + + Enumeration(Builder b) { + super(b); + for (String label : labelNames) { + if (label.equals(fullname)) { + throw new IllegalStateException("Enumeration cannot have a label named the same as its metric name."); + } + } + states = b.states; + initializeNoLabelsChild(); + } + + public static class Builder extends SimpleCollector.Builder { + + private Set states; + + public Builder states(String... s) { + if (s.length == 0) { + throw new IllegalArgumentException("There must be at least one state"); + } + // LinkedHashSet so we can know which was the first state. + states = new LinkedHashSet(); + states.addAll(Arrays.asList(s)); + return this; + } + + /** + * Take states from the names of the values in an Enum class. + */ + public Builder states(Class e) { + Object[] vals = e.getEnumConstants(); + String[] s = new String[vals.length]; + for(int i = 0; i < vals.length; i++) { + s[i] = ((Enum)vals[i]).name(); + } + return states(s); + } + + @Override + public Enumeration create() { + if (states == null) { + throw new IllegalStateException("Enumeration states must be specified."); + } + if (!unit.isEmpty()) { + throw new IllegalStateException("Enumeration metrics cannot have a unit."); + } + dontInitializeNoLabelsChild = true; + return new Enumeration(this); + } + } + + /** + * Return a Builder to allow configuration of a new Enumeration. Ensures required fields are provided. + * + * @param name The name of the metric + * @param help The help string of the metric + */ + public static Builder build(String name, String help) { + return new Builder().name(name).help(help); + } + + /** + * Return a Builder to allow configuration of a new Enumeration. + */ + public static Builder build() { + return new Builder(); + } + + @Override + protected Child newChild() { + return new Child(states); + } + + + /** + * The value of a single Enumeration. + *

+ * Warning: References to a Child become invalid after using + * {@link SimpleCollector#remove} or {@link SimpleCollector#clear}. + */ + public static class Child { + + private String value; + private final Set states; + + private Child(Set states) { + this.states = states; + value = states.iterator().next(); // Initialize with the first state. + } + + /** + * Set the state. + */ + public void state(String s) { + if (!states.contains(s)) { + throw new IllegalArgumentException("Unknown state " + s); + } + value = s; + } + + /** + * Set the state. + */ + public void state(Enum e) { + state(e.name()); + } + + /** + * Get the state. + */ + public String get() { + return value; + } + } + + // Convenience methods. + /** + * Set the state on the enum with no labels. + */ + public void state(String s) { + noLabelsChild.state(s); + } + + /** + * Set the state on the enum with no labels. + */ + public void state(Enum e) { + noLabelsChild.state(e); + } + + /** + * Get the value of the Enumeration. + */ + public String get() { + return noLabelsChild.get(); + } + + @Override + public List collect() { + List samples = new ArrayList(); + for(Map.Entry, Child> c: children.entrySet()) { + String v = c.getValue().get(); + List labelNamesWithState = new ArrayList(labelNames); + labelNamesWithState.add(fullname); + for(String s : states) { + List labelValuesWithState = new ArrayList(c.getKey()); + labelValuesWithState.add(s); + samples.add(new MetricFamilySamples.Sample(fullname, labelNamesWithState, labelValuesWithState, s.equals(v) ? 1.0 : 0.0)); + } + } + + return familySamplesList(Type.STATE_SET, samples); + } + + @Override + public List describe() { + return Collections.singletonList( + new MetricFamilySamples(fullname, Type.STATE_SET, help, Collections.emptyList())); + } + +} diff --git a/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java b/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java new file mode 100644 index 000000000..158036360 --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java @@ -0,0 +1,114 @@ +package io.prometheus.client; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class EnumerationTest { + + CollectorRegistry registry; + Enumeration noLabels, labels; + + @Before + public void setUp() { + registry = new CollectorRegistry(); + noLabels = Enumeration.build().states("foo", "bar").name("nolabels").help("help").register(registry); + labels = Enumeration.build().states("foo", "bar").name("labels").help("help").labelNames("l").register(registry); + } + + private Double getNoLabelState(String s) { + return registry.getSampleValue("nolabels", new String[]{"nolabels"}, new String[]{s}); + } + private Double getLabeledState(String labelValue, String s) { + return registry.getSampleValue("labels", new String[]{"l", "labels"}, new String[]{labelValue, s}); + } + + @Test + public void testState() { + noLabels.state("bar"); + assertEquals(0.0, getNoLabelState("foo"), .001); + assertEquals(1.0, getNoLabelState("bar"), .001); + noLabels.state("foo"); + assertEquals(1.0, getNoLabelState("foo"), .001); + assertEquals(0.0, getNoLabelState("bar"), .001); + } + + @Test + public void testDefaultValue() { + assertEquals(1.0, getNoLabelState("foo"), .001); + assertEquals(0.0, getNoLabelState("bar"), .001); + } + + @Test + public void testLabels() { + assertEquals(null, getLabeledState("a", "foo")); + assertEquals(null, getLabeledState("a", "bar")); + assertEquals(null, getLabeledState("b", "foo")); + assertEquals(null, getLabeledState("b", "bar")); + labels.labels("a").state("foo"); + assertEquals(1.0, getLabeledState("a", "foo"), .001); + assertEquals(0.0, getLabeledState("a", "bar"), .001); + assertEquals(null, getLabeledState("b", "foo")); + assertEquals(null, getLabeledState("b", "bar")); + labels.labels("b").state("bar"); + assertEquals(1.0, getLabeledState("a", "foo"), .001); + assertEquals(0.0, getLabeledState("a", "bar"), .001); + assertEquals(0.0, getLabeledState("b", "foo"), .001); + assertEquals(1.0, getLabeledState("b", "bar"), .001); + } + + public enum myEnum { + FOO, + BAR, + } + + @Test + public void testJavaEnum() { + Enumeration metric = Enumeration.build().states(myEnum.class).name("enum").help("help").register(registry); + metric.state(myEnum.BAR); + assertEquals(0.0, registry.getSampleValue("enum", new String[]{"enum"}, new String[]{"FOO"}), .001); + assertEquals(1.0, registry.getSampleValue("enum", new String[]{"enum"}, new String[]{"BAR"}), .001); + } + + @Test(expected=IllegalStateException.class) + public void testDuplicateNameLabelThrows() { + Enumeration.build().states("foo", "bar").name("labels").help("help").labelNames("labels").create(); + } + + @Test(expected=IllegalStateException.class) + public void testNoStatesThrows() { + Enumeration.build().name("nolabels").help("help").create(); + } + + @Test(expected=IllegalArgumentException.class) + public void testEmptyStatesThrows() { + Enumeration.build().states().name("nolabels").help("help").create(); + } + + @Test(expected=IllegalStateException.class) + public void testUnitThrows() { + Enumeration.build().states("foo", "bar").unit("seconds").name("nolabels").help("help").create(); + } + + @Test + public void testCollect() { + labels.labels("a").state("bar"); + List mfs = labels.collect(); + + ArrayList samples = new ArrayList(); + samples.add(new Collector.MetricFamilySamples.Sample("labels", asList("l", "labels"), asList("a", "foo"), 0.0)); + samples.add(new Collector.MetricFamilySamples.Sample("labels", asList("l", "labels"), asList("a", "bar"), 1.0)); + Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.STATE_SET, "help", samples); + + assertEquals(1, mfs.size()); + assertEquals(mfsFixture, mfs.get(0)); + } +} From 37fa7fb33c49cfbb9d2620ee59e350e23af8d2fc Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 18 Jan 2021 13:57:02 +0000 Subject: [PATCH 049/980] Add support for Info metrics Signed-off-by: Brian Brazil --- .../prometheus/client/CollectorRegistry.java | 4 + .../main/java/io/prometheus/client/Info.java | 177 ++++++++++++++++++ .../io/prometheus/client/EnumerationTest.java | 2 +- .../java/io/prometheus/client/InfoTest.java | 96 ++++++++++ .../client/exporter/common/TextFormat.java | 6 + .../common/TextFormatOpenMetricsTest.java | 12 ++ .../exporter/common/TextFormatTest.java | 10 + 7 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 simpleclient/src/main/java/io/prometheus/client/Info.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/InfoTest.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index 590beeba5..55d33287d 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -129,6 +129,10 @@ private List collectorNames(Collector m) { names.add(family.name + "_bucket"); names.add(family.name); break; + case INFO: + names.add(family.name + "_info"); + names.add(family.name); + break; default: names.add(family.name); } diff --git a/simpleclient/src/main/java/io/prometheus/client/Info.java b/simpleclient/src/main/java/io/prometheus/client/Info.java new file mode 100644 index 000000000..e878ae386 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/Info.java @@ -0,0 +1,177 @@ +package io.prometheus.client; + +import io.prometheus.client.CKMSQuantiles.Quantile; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +/** + * Info metric, key-value pairs. + * + * Examples of Info include, build information, version information, and potential target metadata, + * The first provided state will be the default. + * + *

+ * Example enumeration: + *

+ * {@code
+ *   class YourClass {
+ *     static final Info buildInfo = Info.build()
+ *         .name("your_build_info").help("Build information.")
+ *         .register();
+ *
+ *     void func() {
+ *          // Your code here.
+ *         buildInfo.info("branch", "HEAD", "version", "1.2.3", "revision", "e0704b");
+ *     }
+ *   }
+ * }
+ * 
+ */ +public class Info extends SimpleCollector implements Counter.Describable { + + Info(Builder b) { + super(b); + } + + public static class Builder extends SimpleCollector.Builder { + @Override + public Info create() { + if (!unit.isEmpty()) { + throw new IllegalStateException("Info metrics cannot have a unit."); + } + return new Info(this); + } + } + + /** + * Return a Builder to allow configuration of a new Info. Ensures required fields are provided. + * + * @param name The name of the metric + * @param help The help string of the metric + */ + public static Builder build(String name, String help) { + return new Builder().name(name).help(help); + } + + /** + * Return a Builder to allow configuration of a new Info. + */ + public static Builder build() { + return new Builder(); + } + + @Override + protected Child newChild() { + return new Child(labelNames); + } + + + /** + * The value of a single Info. + *

+ * Warning: References to a Child become invalid after using + * {@link SimpleCollector#remove} or {@link SimpleCollector#clear}. + */ + public static class Child { + + private Map value = Collections.emptyMap(); + private List labelNames; + + private Child(List labelNames) { + this.labelNames = labelNames; + } + + /** + * Set the info. + */ + public void info(Map v) { + for (String key : v.keySet()) { + checkMetricLabelName(key); + } + for (String label : labelNames) { + if (v.containsKey(label)) { + throw new IllegalArgumentException("Info and its value cannot have the same label name."); + } + } + this.value = v; + } + /** + * Set the info. + * + * @param v labels as pairs of key values + */ + public void info(String... v) { + if (v.length % 2 != 0) { + throw new IllegalArgumentException("An even number of arguments must be passed"); + } + Map m = new TreeMap(); + for (int i = 0; i < v.length; i+=2) { + m.put(v[i], v[i+1]); + } + info(m); + } + + /** + * Get the info. + */ + public Map get() { + return value; + } + } + + // Convenience methods. + /** + * Set the info on the info with no labels. + */ + public void info(String... v) { + noLabelsChild.info(v); + } + + /** + * Set the info on the info with no labels. + * + * @param v labels as pairs of key values + */ + public void info(Map v) { + noLabelsChild.info(v); + } + + /** + * Get the the info. + */ + public Map get() { + return noLabelsChild.get(); + } + + @Override + public List collect() { + List samples = new ArrayList(); + for(Map.Entry, Child> c: children.entrySet()) { + Map v = c.getValue().get(); + List names = new ArrayList(labelNames); + List values = new ArrayList(c.getKey()); + for(Map.Entry l: v.entrySet()) { + names.add(l.getKey()); + values.add(l.getValue()); + } + samples.add(new MetricFamilySamples.Sample(fullname + "_info", names, values, 1.0)); + } + + return familySamplesList(Type.INFO, samples); + } + + @Override + public List describe() { + return Collections.singletonList( + new MetricFamilySamples(fullname, Type.INFO, help, Collections.emptyList())); + } + +} diff --git a/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java b/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java index 158036360..4c8fd893a 100644 --- a/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java @@ -65,7 +65,7 @@ public void testLabels() { assertEquals(1.0, getLabeledState("b", "bar"), .001); } - public enum myEnum { + enum myEnum { FOO, BAR, } diff --git a/simpleclient/src/test/java/io/prometheus/client/InfoTest.java b/simpleclient/src/test/java/io/prometheus/client/InfoTest.java new file mode 100644 index 000000000..02b1dbbe8 --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/InfoTest.java @@ -0,0 +1,96 @@ +package io.prometheus.client; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + + +public class InfoTest { + + CollectorRegistry registry; + Info noLabels, labels; + + @Before + public void setUp() { + registry = new CollectorRegistry(); + noLabels = Info.build().name("nolabels").help("help").register(registry); + labels = Info.build().name("labels").help("help").labelNames("l").register(registry); + } + + private Double getInfo(String metric, String... labels) { + String[] names = new String[labels.length / 2]; + String[] values = new String[labels.length / 2]; + for (int i = 0; i < labels.length; i+=2) { + names[i/2] = labels[i]; + values[i/2] = labels[i+1]; + } + return registry.getSampleValue(metric + "_info", names, values); + } + + @Test + public void testInfo() { + assertEquals(null, getInfo("nolabels", "foo", "bar")); + noLabels.info("foo", "bar"); + assertEquals(1.0, getInfo("nolabels", "foo", "bar"), .001); + noLabels.info("foo", "bar", "baz", "meh"); + assertEquals(null, getInfo("nolabels", "foo", "bar")); + assertEquals(1.0, getInfo("nolabels", "baz", "meh", "foo", "bar"), .001); + } + + @Test + public void testDefaultValue() { + assertEquals(1.0, getInfo("nolabels"), .001); + } + + @Test + public void testLabels() { + assertEquals(null, getInfo("labels", "l", "a", "foo", "bar")); + assertEquals(null, getInfo("labels", "l", "b", "baz", "meh")); + labels.labels("a").info("foo", "bar"); + assertEquals(1.0, getInfo("labels", "l", "a", "foo", "bar"), .001); + assertEquals(null, getInfo("labels", "l", "b", "baz", "meh")); + labels.labels("b").info("baz", "meh"); + assertEquals(1.0, getInfo("labels", "l", "a", "foo", "bar"), .001); + assertEquals(1.0, getInfo("labels", "l", "b", "baz", "meh"), .001); + + assertEquals(null, getInfo("nolabels", "l", "a")); + assertEquals(null, getInfo("nolabels", "l", "b")); + } + + @Test(expected=IllegalArgumentException.class) + public void testDuplicateNameLabelThrows() { + Info i = Info.build().name("labels").help("help").labelNames("l").create(); + i.labels("a").info("l", "bar"); + } + + @Test(expected=IllegalArgumentException.class) + public void testOddInfoThrows() { + Info i = Info.build().name("labels").help("help").create(); + i.info("odd"); + } + + @Test(expected=IllegalStateException.class) + public void testUnitThrows() { + Info.build().unit("seconds").name("nolabels").help("help").create(); + } + + @Test + public void testCollect() { + labels.labels("a").info("foo", "bar", "baz", "meh"); + List mfs = labels.collect(); + + ArrayList samples = new ArrayList(); + samples.add(new Collector.MetricFamilySamples.Sample("labels_info", asList("l", "baz", "foo"), asList("a", "meh", "bar"), 1.0)); + Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.INFO, "help", samples); + + assertEquals(1, mfs.size()); + assertEquals(mfsFixture, mfs.get(0)); + } +} diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index a16a57632..7e4aaa4a2 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -69,6 +69,9 @@ public static void write004(Writer writer, Enumeration Date: Mon, 18 Jan 2021 14:15:23 +0000 Subject: [PATCH 050/980] Make jvm_info use an Info. UNTYPED -> UNKNOWN. Signed-off-by: Brian Brazil --- .../java/io/prometheus/client/Collector.java | 2 +- .../io/prometheus/client/Enumeration.java | 4 ++-- .../main/java/io/prometheus/client/Info.java | 2 +- .../java/io/prometheus/client/InfoTest.java | 2 +- .../client/exporter/common/TextFormat.java | 8 +++---- .../common/TextFormatOpenMetricsTest.java | 4 ++-- .../exporter/common/TextFormatTest.java | 2 +- .../client/hotspot/VersionInfoExports.java | 24 +++++++------------ .../hotspot/VersionInfoExportsTest.java | 6 ++++- .../client/exporter/TestHTTPServer.java | 1 - 10 files changed, 25 insertions(+), 30 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java index a6c52b302..327b9b01b 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Collector.java +++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java @@ -20,7 +20,7 @@ public abstract class Collector { */ public abstract List collect(); public enum Type { - UNTYPED, // XXX This is Unknown in OpenMetrics. + UNKNOWN, // This is untyped in Prometheus text format. COUNTER, GAUGE, STATE_SET, diff --git a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java index 900f1ec30..93c7265ec 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java +++ b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java @@ -58,7 +58,7 @@ *

*/ public class Enumeration extends SimpleCollector implements Counter.Describable { - + private final Set states; Enumeration(Builder b) { @@ -166,7 +166,7 @@ public void state(String s) { public void state(Enum e) { state(e.name()); } - + /** * Get the state. */ diff --git a/simpleclient/src/main/java/io/prometheus/client/Info.java b/simpleclient/src/main/java/io/prometheus/client/Info.java index e878ae386..c240d5b0b 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Info.java +++ b/simpleclient/src/main/java/io/prometheus/client/Info.java @@ -36,7 +36,7 @@ *
*/ public class Info extends SimpleCollector implements Counter.Describable { - + Info(Builder b) { super(b); } diff --git a/simpleclient/src/test/java/io/prometheus/client/InfoTest.java b/simpleclient/src/test/java/io/prometheus/client/InfoTest.java index 02b1dbbe8..f17673286 100644 --- a/simpleclient/src/test/java/io/prometheus/client/InfoTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/InfoTest.java @@ -59,7 +59,7 @@ public void testLabels() { labels.labels("b").info("baz", "meh"); assertEquals(1.0, getInfo("labels", "l", "a", "foo", "bar"), .001); assertEquals(1.0, getInfo("labels", "l", "b", "baz", "meh"), .001); - + assertEquals(null, getInfo("nolabels", "l", "a")); assertEquals(null, getInfo("nolabels", "l", "b")); } diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index 7e4aaa4a2..2b81635ef 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -16,7 +16,7 @@ public class TextFormat { * Content-type for Prometheus text version 0.0.4. */ public final static String CONTENT_TYPE_004 = "text/plain; version=0.0.4; charset=utf-8"; - + /** * Content-type for Openmetrics text version 1.0.0. */ @@ -29,7 +29,7 @@ public static String chooseContentType(String acceptHeader) { if (acceptHeader == null) { return CONTENT_TYPE_004; } - + for (String accepts : acceptHeader.split(",")) { if ("application/openmetrics-text".equals(accepts.split(";")[0].trim())) { return CONTENT_TYPE_OPENMETRICS_100; @@ -193,13 +193,13 @@ public static void writeOpenMetrics100(Writer writer, Enumeration collect() { ArrayList samples = new ArrayList(); MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0, 1518123006L); samples.add(sample); - mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNTYPED, "help", samples)); + mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNKNOWN, "help", samples)); return mfs; } } - + new CustomCollector().register(registry); TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples()); assertEquals("# TYPE nolabels unknown\n" diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java index 2c8877bb4..7ecac1a76 100644 --- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java +++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java @@ -121,7 +121,7 @@ public List collect() { ArrayList samples = new ArrayList(); MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0, 1518123456L); samples.add(sample); - mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNTYPED, "help", samples)); + mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNKNOWN, "help", samples)); return mfs; } } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java index f50d79f21..8dd711080 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java @@ -1,7 +1,7 @@ package io.prometheus.client.hotspot; import io.prometheus.client.Collector; -import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.Info; import java.util.ArrayList; import java.util.Arrays; @@ -26,20 +26,12 @@ public class VersionInfoExports extends Collector { public List collect() { - List mfs = new ArrayList(); - - GaugeMetricFamily jvmInfo = new GaugeMetricFamily( - "jvm_info", - "JVM version info", - Arrays.asList("version", "vendor", "runtime")); - jvmInfo.addMetric( - Arrays.asList( - System.getProperty("java.runtime.version", "unknown"), - System.getProperty("java.vm.vendor", "unknown"), - System.getProperty("java.runtime.name", "unknown")), - 1L); - mfs.add(jvmInfo); - - return mfs; + Info i = Info.build().name("jvm").help("VM version info").create(); + i.info( + "version", System.getProperty("java.runtime.version", "unknown"), + "vendor", System.getProperty("java.vm.vendor", "unknown"), + "runtime", System.getProperty("java.runtime.name", "unknown") + ); + return i.collect(); } } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java index 036105e05..718ceecd5 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java @@ -21,7 +21,11 @@ public void testVersionInfo() { assertEquals( 1L, registry.getSampleValue( - "jvm_info", new String[]{"version", "vendor", "runtime"}, new String[]{System.getProperty("java.runtime.version", "unknown"), System.getProperty("java.vm.vendor", "unknown"), System.getProperty("java.runtime.name", "unknown")}), + "jvm_info", new String[]{"runtime", "vendor", "version"}, + new String[]{ + System.getProperty("java.runtime.name", "unknown"), + System.getProperty("java.vm.vendor", "unknown"), + System.getProperty("java.runtime.version", "unknown")}), .0000001); } } diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index 78521136b..c9f6beed6 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -75,7 +75,6 @@ String requestWithAccept(String accept) throws IOException { return s.hasNext() ? s.next() : ""; } - @Test @Test(expected = IllegalArgumentException.class) public void testRefuseUsingUnbound() throws IOException { CollectorRegistry registry = new CollectorRegistry(); From cf018d19b321fccb760cdf7fb89ce47bd50dbd63 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Thu, 21 Jan 2021 09:22:24 +0000 Subject: [PATCH 051/980] Address code review comments. Signed-off-by: Brian Brazil --- .../src/main/java/io/prometheus/client/Counter.java | 6 ++++++ .../src/main/java/io/prometheus/client/SimpleCollector.java | 2 +- .../client/cache/caffeine/CacheMetricsCollectorTest.java | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java index 900812b16..bcff43eb2 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Counter.java +++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java @@ -64,6 +64,12 @@ * * These can be aggregated and processed together much more easily in the Prometheus * server than individual metrics for each labelset. + * + * If there is a suffix of _total on the metric name, it will be + * removed. When exposing the time series for counter value, a + * _total suffix will be added. This is for compatibility between + * OpenMetrics and the Prometheus text format, as OpenMetrics requires the + * _total suffix. */ public class Counter extends SimpleCollector implements Collector.Describable { diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java index 6a0183961..a228c6851 100644 --- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java +++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java @@ -216,7 +216,7 @@ public B namespace(String namespace) { return (B)this; } /** - * Set the uit of the metric. Required. + * Set the unit of the metric. Required. */ public B unit(String unit) { this.unit = unit; diff --git a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java index 75f198d1b..65429f337 100644 --- a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java +++ b/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java @@ -70,7 +70,6 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { } cache.get("user3"); - assertMetric(registry, "caffeine_cache_hit_total", "loadingusers", 1.0); assertMetric(registry, "caffeine_cache_miss_total", "loadingusers", 3.0); From f09c46bba1a900e60d01b4c473818eaace9f3745 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Fri, 22 Jan 2021 11:00:59 +0000 Subject: [PATCH 052/980] Remove deprecated pushgateway methods. (#617) These were deprecated back in 2015, and take an explicit instance label which is not good practice for using the pushgateway. Signed-off-by: Brian Brazil --- .../client/exporter/PushGateway.java | 62 -------------- .../client/exporter/PushGatewayTest.java | 85 ------------------- 2 files changed, 147 deletions(-) diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java index cde5071fc..88857fa84 100644 --- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java @@ -94,8 +94,6 @@ public void setConnectionFactory(HttpConnectionFactory connectionFactory) { * Creates a URL instance from a String representation of a URL without throwing a checked exception. * Required because you can't wrap a call to another constructor in a try statement. * - * TODO: Remove this along with other deprecated methods before version 1.0 is released. - * * @param urlString the String representation of the URL. * @return The URL instance. */ @@ -216,66 +214,6 @@ public void delete(String job, Map groupingKey) throws IOExcepti doRequest(null, job, groupingKey, "DELETE"); } - - /** - * Pushes all metrics in a registry, replacing all those with the same job and instance. - *

- * This uses the PUT HTTP method. - * @deprecated use {@link #push(CollectorRegistry, String, Map)} - */ - @Deprecated - public void push(CollectorRegistry registry, String job, String instance) throws IOException { - push(registry, job, Collections.singletonMap("instance", instance)); - } - - /** - * Pushes all metrics in a Collector, replacing all those with the same job and instance. - *

- * This is useful for pushing a single Gauge. - *

- * This uses the PUT HTTP method. - * @deprecated use {@link #push(Collector, String, Map)} - */ - @Deprecated - public void push(Collector collector, String job, String instance) throws IOException { - push(collector, job, Collections.singletonMap("instance", instance)); - } - - /** - * Pushes all metrics in a registry, replacing only previously pushed metrics of the same name. - *

- * This uses the POST HTTP method. - * @deprecated use {@link #pushAdd(CollectorRegistry, String, Map)} - */ - @Deprecated - public void pushAdd(CollectorRegistry registry, String job, String instance) throws IOException { - pushAdd(registry, job, Collections.singletonMap("instance", instance)); - } - - /** - * Pushes all metrics in a Collector, replacing only previously pushed metrics of the same name. - *

- * This is useful for pushing a single Gauge. - *

- * This uses the POST HTTP method. - * @deprecated use {@link #pushAdd(Collector, String, Map)} - */ - @Deprecated - public void pushAdd(Collector collector, String job, String instance) throws IOException { - pushAdd(collector, job, Collections.singletonMap("instance", instance)); - } - - /** - * Deletes metrics from the Pushgateway. - *

- * This uses the DELETE HTTP method. - * @deprecated use {@link #delete(String, Map)} - */ - @Deprecated - public void delete(String job, String instance) throws IOException { - delete(job, Collections.singletonMap("instance", instance)); - } - void doRequest(CollectorRegistry registry, String job, Map groupingKey, String method) throws IOException { String url = gatewayBaseURL; if (job.contains("/")) { diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java index 9e7cb71f3..874595b18 100644 --- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java +++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java @@ -214,91 +214,6 @@ public void testDeleteWithGroupingKey() throws IOException { pg.delete("j", groupingKey); } - @Test - public void testOldPushWithoutInstance() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/instance@base64/=") - ).respond(response().withStatusCode(202)); - pg.push(registry, "j", ""); - } - - @Test - public void testOldPushWithInstance() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(202)); - pg.push(registry, "j", "i"); - } - - @Test - public void testOldNon202ResponseThrows() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(500)); - thrown.expect(IOException.class); - thrown.expectMessage( - "Response code from http://localhost:" - + mockServerRule.getHttpPort() - + "/metrics/job/j/instance/i was 500"); - pg.push(registry,"j", "i"); - } - - @Test - public void testOldPushWithSlashes() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job@base64/YS9i/instance@base64/Yy9k") - ).respond(response().withStatusCode(202)); - pg.push(registry, "a/b", "c/d"); - } - - @Test - public void testOldPushCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(202)); - pg.push(gauge, "j", "i"); - } - - @Test - public void testOldPushAdd() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(202)); - pg.pushAdd(registry, "j", "i"); - } - - @Test - public void testOldPushAddCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(202)); - pg.pushAdd(gauge, "j", "i"); - } - - @Test - public void testOldDelete() throws IOException { - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j/instance/i") - ).respond(response().withStatusCode(202)); - pg.delete("j", "i"); - } - @Test public void testInstanceIPGroupingKey() throws IOException { groupingKey = PushGateway.instanceIPGroupingKey(); From eb4e694b00024043f948e407510f516dea58cbc7 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 25 Jan 2021 13:48:25 +0000 Subject: [PATCH 053/980] [maven-release-plugin] prepare release parent-0.10.0 --- benchmark/pom.xml | 4 +-- pom.xml | 4 +-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 40 ++++++++++++++-------------- simpleclient_caffeine/pom.xml | 4 +-- simpleclient_common/pom.xml | 4 +-- simpleclient_dropwizard/pom.xml | 4 +-- simpleclient_graphite_bridge/pom.xml | 4 +-- simpleclient_guava/pom.xml | 4 +-- simpleclient_hibernate/pom.xml | 4 +-- simpleclient_hotspot/pom.xml | 6 ++--- simpleclient_httpserver/pom.xml | 6 ++--- simpleclient_jetty/pom.xml | 4 +-- simpleclient_jetty_jdk8/pom.xml | 4 +-- simpleclient_log4j/pom.xml | 4 +-- simpleclient_log4j2/pom.xml | 4 +-- simpleclient_logback/pom.xml | 4 +-- simpleclient_pushgateway/pom.xml | 6 ++--- simpleclient_servlet/pom.xml | 6 ++--- simpleclient_spring_boot/pom.xml | 8 +++--- simpleclient_spring_web/pom.xml | 6 ++--- simpleclient_vertx/pom.xml | 6 ++--- 22 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 56e3beb52..b46f70a76 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -49,7 +49,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 com.codahale.metrics diff --git a/pom.xml b/pom.xml index 4587c171e..fd394a88d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.10.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 7d863af41..e3e571b69 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 858584048..c4cb26ac5 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 simpleclient_bom @@ -29,97 +29,97 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_caffeine - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_dropwizard - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_graphite_bridge - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_hibernate - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_guava - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_hotspot - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_httpserver - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_log4j - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_log4j2 - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_logback - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_pushgateway - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_servlet - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_spring_web - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_spring_boot - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_jetty - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_jetty_jdk8 - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_vertx - 0.9.1-SNAPSHOT + 0.10.0 diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index faec46eff..a8fd42f90 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 909c23722..f2b6ed314 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 641e15653..858dbba12 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 2d7248c51..cbf11a04f 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index c646d64ae..569f15c8a 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 503cc5f89..60f09c7b5 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index e0ec8d4d9..537ec27c1 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_servlet - 0.9.1-SNAPSHOT + 0.10.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index e8a6fcb85..73793dd6f 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index c4be38c43..a63e4e624 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 2db5b8e19..fd1f30367 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index ea604987a..44af01cbe 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 4606131b2..412c50bff 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 7780bf906..c9e705f50 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 388353c9d..cbb8aee8d 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 3ca6d221a..ea72f4e37 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index e001658ea..a0e6b2c8d 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_spring_web - 0.9.1-SNAPSHOT + 0.10.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 016a8f572..df38f0847 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 1d25a97d8..b12dc7877 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.9.1-SNAPSHOT + 0.10.0 io.prometheus simpleclient_common - 0.9.1-SNAPSHOT + 0.10.0 io.vertx From e8e38d029ec3a1d19a9bd1028dbaac58936a705e Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 25 Jan 2021 13:48:34 +0000 Subject: [PATCH 054/980] [maven-release-plugin] prepare for next development iteration --- benchmark/pom.xml | 4 +-- pom.xml | 4 +-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 40 ++++++++++++++-------------- simpleclient_caffeine/pom.xml | 4 +-- simpleclient_common/pom.xml | 4 +-- simpleclient_dropwizard/pom.xml | 4 +-- simpleclient_graphite_bridge/pom.xml | 4 +-- simpleclient_guava/pom.xml | 4 +-- simpleclient_hibernate/pom.xml | 4 +-- simpleclient_hotspot/pom.xml | 6 ++--- simpleclient_httpserver/pom.xml | 6 ++--- simpleclient_jetty/pom.xml | 4 +-- simpleclient_jetty_jdk8/pom.xml | 4 +-- simpleclient_log4j/pom.xml | 4 +-- simpleclient_log4j2/pom.xml | 4 +-- simpleclient_logback/pom.xml | 4 +-- simpleclient_pushgateway/pom.xml | 6 ++--- simpleclient_servlet/pom.xml | 6 ++--- simpleclient_spring_boot/pom.xml | 8 +++--- simpleclient_spring_web/pom.xml | 6 ++--- simpleclient_vertx/pom.xml | 6 ++--- 22 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index b46f70a76..6f1757d8a 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -49,7 +49,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT com.codahale.metrics diff --git a/pom.xml b/pom.xml index fd394a88d..23a8ec8c7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT org.sonatype.oss @@ -31,7 +31,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.10.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index e3e571b69..f49421a2f 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index c4cb26ac5..7d112f409 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT simpleclient_bom @@ -29,97 +29,97 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_caffeine - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_dropwizard - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_graphite_bridge - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_hibernate - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_guava - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_hotspot - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_httpserver - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_log4j - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_log4j2 - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_logback - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_pushgateway - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_spring_boot - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_jetty - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_jetty_jdk8 - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_vertx - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index a8fd42f90..ff2114b3d 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index f2b6ed314..93692c790 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 858dbba12..037c1819a 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index cbf11a04f..88034cf70 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 569f15c8a..6a975e0a0 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 60f09c7b5..e1b7ecc43 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 537ec27c1..664493731 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.10.0 + 0.10.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 73793dd6f..cca04f1b8 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index a63e4e624..d093f01f0 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index fd1f30367..6a4c5d645 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 44af01cbe..f7416bebf 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 412c50bff..3378d6f8f 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index c9e705f50..945aec4bd 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index cbb8aee8d..924843a34 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index ea72f4e37..a6423e25e 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index a0e6b2c8d..d7845ddc6 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.10.0 + 0.10.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index df38f0847..1a2c7b1e7 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT org.springframework diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index b12dc7877..1e7a4186b 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.10.0 + 0.10.1-SNAPSHOT io.prometheus simpleclient_common - 0.10.0 + 0.10.1-SNAPSHOT io.vertx From 9bdf85d0e21904453470a7deef884fb53b7e51a0 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Mon, 25 Jan 2021 14:17:34 +0000 Subject: [PATCH 055/980] Update for 0.10.0 Signed-off-by: Brian Brazil --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 294f83797..fef751950 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.9.0 + 0.10.0 io.prometheus simpleclient_hotspot - 0.9.0 + 0.10.0 io.prometheus simpleclient_httpserver - 0.9.0 + 0.10.0 io.prometheus simpleclient_pushgateway - 0.9.0 + 0.10.0 ``` From 72ac4afbe4ee77784bafdb38a26c09a68b884fbb Mon Sep 17 00:00:00 2001 From: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> Date: Wed, 27 Jan 2021 17:39:06 +0900 Subject: [PATCH 056/980] Use JavaDoc since tag on new public API (#618) This will help other libraries that depend on this library to identify when they are using new API that will raise the minimum version of this library required by end users. Signed-off-by: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> --- .../src/main/java/io/prometheus/client/Enumeration.java | 2 ++ simpleclient/src/main/java/io/prometheus/client/Info.java | 2 ++ .../main/java/io/prometheus/client/SimpleCollector.java | 2 ++ .../io/prometheus/client/exporter/common/TextFormat.java | 8 ++++++++ 4 files changed, 14 insertions(+) diff --git a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java index 93c7265ec..7aa3d09d6 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java +++ b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java @@ -56,6 +56,8 @@ * } * } * + * + * @since 0.10.0 */ public class Enumeration extends SimpleCollector implements Counter.Describable { diff --git a/simpleclient/src/main/java/io/prometheus/client/Info.java b/simpleclient/src/main/java/io/prometheus/client/Info.java index c240d5b0b..348226948 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Info.java +++ b/simpleclient/src/main/java/io/prometheus/client/Info.java @@ -34,6 +34,8 @@ * } * } * + * + * @since 0.10.0 */ public class Info extends SimpleCollector implements Counter.Describable { diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java index a228c6851..dda12997e 100644 --- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java +++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java @@ -217,6 +217,8 @@ public B namespace(String namespace) { } /** * Set the unit of the metric. Required. + * + * @since 0.10.0 */ public B unit(String unit) { this.unit = unit; diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index 2b81635ef..13d065ed6 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -19,11 +19,15 @@ public class TextFormat { /** * Content-type for Openmetrics text version 1.0.0. + * + * @since 0.10.0 */ public final static String CONTENT_TYPE_OPENMETRICS_100 = "application/openmetrics-text; version=1.0.0; charset=utf-8"; /** * Return the content type that should be used for a given Accept HTTP header. + * + * @since 0.10.0 */ public static String chooseContentType(String acceptHeader) { if (acceptHeader == null) { @@ -41,6 +45,8 @@ public static String chooseContentType(String acceptHeader) { /** * Write out the given MetricFamilySamples in a format per the contentType. + * + * @since 0.10.0 */ public static void writeFormat(String contentType, Writer writer, Enumeration mfs) throws IOException { if (CONTENT_TYPE_004.equals(contentType)) { @@ -188,6 +194,8 @@ private static String typeString(Collector.Type t) { /** * Write out the OpenMetrics text version 1.0.0 of the given MetricFamilySamples. + * + * @since 0.10.0 */ public static void writeOpenMetrics100(Writer writer, Enumeration mfs) throws IOException { while(mfs.hasMoreElements()) { From 0196c289a03c20911010cf0beb5a4e794817451e Mon Sep 17 00:00:00 2001 From: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> Date: Wed, 27 Jan 2021 18:30:18 +0900 Subject: [PATCH 057/980] Document unit as optional (#619) It was incorrectly documented as required when initially introduced. See https://github.com/prometheus/client_java/pull/615#discussion_r565027894 Signed-off-by: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com> --- .../src/main/java/io/prometheus/client/SimpleCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java index dda12997e..ec321ba0a 100644 --- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java +++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java @@ -216,7 +216,7 @@ public B namespace(String namespace) { return (B)this; } /** - * Set the unit of the metric. Required. + * Set the unit of the metric. Optional. * * @since 0.10.0 */ From 0fa8ad630df972f3c44550e073878debb9bd02f6 Mon Sep 17 00:00:00 2001 From: Robin Karlsson Date: Wed, 27 Jan 2021 16:44:38 +0100 Subject: [PATCH 058/980] Clarify Info javadoc (#620) * Clarify Info javadoc * Fix capitalization in Enumeration javadoc Signed-off-by: Robin Karlsson --- .../java/io/prometheus/client/Enumeration.java | 7 +------ .../src/main/java/io/prometheus/client/Info.java | 14 ++++---------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java index 7aa3d09d6..31b8ee82c 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java +++ b/simpleclient/src/main/java/io/prometheus/client/Enumeration.java @@ -1,8 +1,5 @@ package io.prometheus.client; -import io.prometheus.client.CKMSQuantiles.Quantile; - -import java.io.Closeable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -10,8 +7,6 @@ import java.util.Map; import java.util.Set; import java.util.LinkedHashSet; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; /** * Enumeration metric, to track which of a set of states something is in. @@ -19,7 +14,7 @@ * The first provided state will be the default. * *

- * Example enumeration: + * Example Enumeration: *

  * {@code
  *   class YourClass {
diff --git a/simpleclient/src/main/java/io/prometheus/client/Info.java b/simpleclient/src/main/java/io/prometheus/client/Info.java
index 348226948..89595af6a 100644
--- a/simpleclient/src/main/java/io/prometheus/client/Info.java
+++ b/simpleclient/src/main/java/io/prometheus/client/Info.java
@@ -1,30 +1,24 @@
 package io.prometheus.client;
 
-import io.prometheus.client.CKMSQuantiles.Quantile;
-
-import java.io.Closeable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Info metric, key-value pairs.
  *
- * Examples of Info include, build information, version information, and potential target metadata,
- * The first provided state will be the default.
+ * Examples of Info include build information, version information, and potential target metadata.
+ * The string "_info" will be appended to the sample name.
  *
  * 

- * Example enumeration: + * Example Info: *

  * {@code
  *   class YourClass {
  *     static final Info buildInfo = Info.build()
- *         .name("your_build_info").help("Build information.")
+ *         .name("your_build").help("Build information.")
  *         .register();
  *
  *     void func() {

From 7b84103bd5f10c5ba437081d1f40b80387f7bfbc Mon Sep 17 00:00:00 2001
From: beorn7 
Date: Fri, 29 Jan 2021 20:19:27 +0100
Subject: [PATCH 059/980] Change maintainer from @brian-brazil to @fstab and
 @tomwilkie

Signed-off-by: beorn7 
---
 MAINTAINERS.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS.md b/MAINTAINERS.md
index d1cb20b89..e3deed2ca 100644
--- a/MAINTAINERS.md
+++ b/MAINTAINERS.md
@@ -1 +1,2 @@
-* Brian Brazil 
+* Fabian Stäber  @fstab
+* Tom Wilkie  @tomwilkie

From 7a6b9f1300c5445f477fb0452c5ec7b6f80464a1 Mon Sep 17 00:00:00 2001
From: Mirco 
Date: Tue, 2 Mar 2021 16:25:13 +0100
Subject: [PATCH 060/980] Updated Hibernate Documentation (#630)

* Updated Hibernate Documentation

Added a code snippet which shows how to get the session factory from an EntityManager instead of an EntityManagerFactory.

* Update README.md

Added the missing semicolon.
---
 README.md | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/README.md b/README.md
index fef751950..7086f8c30 100644
--- a/README.md
+++ b/README.md
@@ -401,6 +401,12 @@ or `EntityManagerFactory`, you can use this code to access the underlying `Sessi
 ```java
 SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
 ```
+
+respectively 
+
+```java
+SessionFactory sessionFactory = entityManager.unwrap(Session.class).getSessionFactory();
+```
 ### Jetty
 
 There is a collector for recording various Jetty server metrics. You can do it by  registering the collector like this:

From 29dfd0a2bf9b93282764d31447b843a1d36d4f10 Mon Sep 17 00:00:00 2001
From: Per Lundberg 
Date: Sat, 20 Mar 2021 00:14:03 +0200
Subject: [PATCH 061/980] Set HTTPServer request/response timeouts (#643)

Closes #636

Signed-off-by: Per Lundberg 
---
 .../io/prometheus/client/exporter/HTTPServer.java    | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
index e016ab260..20455df74 100644
--- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
+++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java
@@ -36,6 +36,17 @@
  * 
* */ public class HTTPServer { + + static { + if (!System.getProperties().containsKey("sun.net.httpserver.maxReqTime")) { + System.setProperty("sun.net.httpserver.maxReqTime", "60"); + } + + if (!System.getProperties().containsKey("sun.net.httpserver.maxRspTime")) { + System.setProperty("sun.net.httpserver.maxRspTime", "600"); + } + } + private static class LocalByteArray extends ThreadLocal { @Override protected ByteArrayOutputStream initialValue() @@ -256,4 +267,3 @@ public int getPort() { return server.getAddress().getPort(); } } - From ee34417215824c86e419f04f807139e7048a77c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 3 Apr 2021 15:01:09 +0200 Subject: [PATCH 062/980] #646 document implications of negative observations for summaries and histograms --- .../java/io/prometheus/client/Histogram.java | 8 ++++ .../java/io/prometheus/client/Summary.java | 8 ++++ .../io/prometheus/client/HistogramTest.java | 44 +++++++++++++++++-- .../io/prometheus/client/SummaryTest.java | 9 ++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index 30595e187..8ab7790ba 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -255,6 +255,10 @@ private Child(double[] buckets) { /** * Observe the given amount. + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * + * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for + * implications and alternatives. */ public void observe(double amt) { for (int i = 0; i < upperBounds.length; ++i) { @@ -293,6 +297,10 @@ public Value get() { // Convenience methods. /** * Observe the given amount on the histogram with no labels. + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * + * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for + * implications and alternatives. */ public void observe(double amt) { noLabelsChild.observe(amt); diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index 9d2aca3f8..3b911c134 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -278,6 +278,10 @@ private Child(List quantiles, long maxAgeSeconds, int ageBuckets) { /** * Observe the given amount. + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * + * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for + * implications and alternatives. */ public void observe(double amt) { count.add(1); @@ -307,6 +311,10 @@ public Value get() { // Convenience methods. /** * Observe the given amount on the summary with no labels. + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * + * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for + * implications and alternatives. */ public void observe(double amt) { noLabelsChild.observe(amt); diff --git a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java index 15ac00a76..19242dc4c 100644 --- a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java @@ -39,13 +39,27 @@ public void tearDown() { } private double getCount() { - return registry.getSampleValue("nolabels_count").doubleValue(); + return getCount("nolabels"); } + + private double getCount(String name) { + return registry.getSampleValue(name + "_count").doubleValue(); + } + private double getSum() { - return registry.getSampleValue("nolabels_sum").doubleValue(); + return getSum("nolabels"); } + + private double getSum(String name) { + return registry.getSampleValue(name + "_sum").doubleValue(); + } + private double getBucket(double b) { - return registry.getSampleValue("nolabels_bucket", + return getBucket(b, "nolabels"); + } + + private double getBucket(double b, String name) { + return registry.getSampleValue(name + "_bucket", new String[]{"le"}, new String[]{Collector.doubleToGoString(b)}).doubleValue(); } @@ -68,6 +82,30 @@ public void testObserve() { assertEquals(2.0, getBucket(Double.POSITIVE_INFINITY), .001); } + @Test + // See https://github.com/prometheus/client_java/issues/646 + public void testNegativeAmount() { + Histogram histogram = Histogram.build() + .name("histogram") + .help("test histogram for negative values") + .buckets(-10, -5, 0, 5, 10) + .register(registry); + double expectedCount = 0; + double expectedSum = 0; + for (int i=10; i>=-11; i--) { + histogram.observe(i); + expectedCount++; + expectedSum += i; + assertEquals(expectedSum, getSum("histogram"), .001); + assertEquals(expectedCount, getCount("histogram"), .001); + } + double[] expectedBucketValues = new double[]{2.0, 7.0, 12.0, 17.0, 22.0, 22.0}; // buckets -10, -5, 0, 5, 10, +Inf + for (int i=0; i Date: Sat, 3 Apr 2021 20:47:48 +0200 Subject: [PATCH 063/980] Update common Prometheus files (#648) Signed-off-by: prombot --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 044b82b11..96bd70d06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,8 +4,7 @@ jobs: working_directory: ~/circleci-java docker: - image: circleci/openjdk:8-jdk-stretch - - steps: + steps: - checkout - restore_cache: # restore the saved cache after the first run or if `pom.xml` has changed key: circleci-demo-java-spring-{{ checksum "pom.xml" }} @@ -14,5 +13,6 @@ jobs: paths: - ~/.m2 key: circleci-demo-java-spring-{{ checksum "pom.xml" }} - - run: mvn package +orbs: + prometheus: prometheus/prometheus@0.11.0 From 44421f65c410d2ac05ae01997e187bb0dd648806 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Wed, 25 Nov 2020 09:36:25 +0100 Subject: [PATCH 064/980] Bump junit dependencies Update junit version requirement to fix CVE-2020-15250 warnings. Signed-off-by: Ben Kochie --- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_spring_boot/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index f49421a2f..b2b118643 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -42,7 +42,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index ff2114b3d..21e749430 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -49,7 +49,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 93692c790..fefbb1311 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -43,7 +43,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 037c1819a..5284bd77c 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -46,7 +46,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 88034cf70..ff6d550dc 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -44,7 +44,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 6a975e0a0..bfb466c31 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -49,7 +49,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index e1b7ecc43..0cc79b11e 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -53,7 +53,7 @@ junit junit - 4.12 + 4.13.2 test diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 664493731..b23999108 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -50,7 +50,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index cca04f1b8..248228755 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -48,7 +48,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index d093f01f0..3a8b79a82 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -51,7 +51,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 6a4c5d645..be6be72e4 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -64,7 +64,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index f7416bebf..be6d64e51 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -49,7 +49,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 3378d6f8f..aaf3edcd1 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -48,7 +48,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 945aec4bd..93cfc8ca5 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -49,7 +49,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 924843a34..63f8b2894 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -54,7 +54,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index a6423e25e..11efdae1f 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -58,7 +58,7 @@ junit junit - 4.13.1 + 4.13.2 test diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index d7845ddc6..dd564617f 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -84,7 +84,7 @@ junit junit - 4.12 + 4.13.2 test diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 1a2c7b1e7..27b582ff8 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -88,7 +88,7 @@ junit junit - 4.12 + 4.13.2 test diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 1e7a4186b..3ef195c5c 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -70,7 +70,7 @@ junit junit - 4.13.1 + 4.13.2 test From 8fcc7bc03dfbabd0c15776640d5fe52942aa9309 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 May 2021 00:03:04 +0200 Subject: [PATCH 065/980] Bump jetty version (#663) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump jetty-server in /simpleclient_jetty Bumps [jetty-server](https://github.com/eclipse/jetty.project) from 9.0.2.v20130417 to 9.3.27.v20190418. - [Release notes](https://github.com/eclipse/jetty.project/releases) - [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.0.2.v20130417...jetty-9.3.27.v20190418) Signed-off-by: dependabot[bot] * Bump jetty-servlet in /simpleclient_jetty Signed-off-by: Fabian Stäber Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabian Stäber --- simpleclient_jetty/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 3a8b79a82..5affa23f6 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -40,12 +40,12 @@ org.eclipse.jetty jetty-server - 9.0.2.v20130417 + 9.3.27.v20190418 org.eclipse.jetty jetty-servlet - 9.0.2.v20130417 + 9.3.27.v20190418 From b76e1e95d1c8ce3141584e2a2d260519c3a6eb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 29 Mar 2021 23:18:58 +0200 Subject: [PATCH 066/980] add Exemplar support for OpenTelemetry tracing --- .circleci/config.yml | 14 +- .gitignore | 2 +- .mvn/wrapper/MavenWrapperDownloader.java | 117 ++++++ .mvn/wrapper/maven-wrapper.jar | Bin 49519 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 3 +- OTEL_EXEMPLARS.md | 80 ++++ README.md | 122 ++++++ benchmark/README.md | 188 ++++----- benchmark/pom.xml | 8 +- .../benchmark/CounterBenchmark.java | 30 +- .../client/benchmark/ExemplarsBenchmark.java | 80 ++++ .../benchmark/GaugeBenchmark.java | 58 +-- .../benchmark/SummaryBenchmark.java | 30 +- integration_tests/example_application/pom.xml | 66 +++ .../prometheus/client/smoketest/Server.java | 18 + integration_tests/exemplars_otel/pom.xml | 113 +++++ .../client/it/exemplars_otel/Server.java | 70 ++++ .../it/exemplars_otel/ExemplarsOtelIT.java | 103 +++++ .../src/test/resources/Dockerfile | 5 + .../src/test/resources/logback-test.xml | 14 + .../exemplars_otel_agent/pom.xml | 115 ++++++ .../SampleRestApplication.java | 98 +++++ .../src/main/resources/application.properties | 1 + .../ExemplarsClientJavaIT.java | 235 +++++++++++ .../src/test/resources/Dockerfile | 10 + .../src/test/resources/logback-test.xml | 14 + integration_tests/java_versions/pom.xml | 75 ++++ .../client/smoketest/JavaVersionsIT.java | 101 +++++ .../src/test/resources/logback-test.xml | 14 + integration_tests/pom.xml | 52 +++ mvnw | 154 +++++-- mvnw.cmd | 328 ++++++++------- pom.xml | 2 + simpleclient/pom.xml | 34 +- .../java/io/prometheus/client/Collector.java | 30 +- .../java/io/prometheus/client/Counter.java | 189 ++++++++- .../java/io/prometheus/client/Histogram.java | 292 +++++++++++-- .../exemplars/CounterExemplarSampler.java | 15 + .../exemplars/DefaultExemplarSampler.java | 65 +++ .../prometheus/client/exemplars/Exemplar.java | 185 +++++++++ .../client/exemplars/ExemplarConfig.java | 76 ++++ .../client/exemplars/ExemplarSampler.java | 8 + .../exemplars/HistogramExemplarSampler.java | 18 + .../prometheus/client/exemplars/Tracer.java | 44 ++ .../io/prometheus/client/CollectorTest.java | 1 - .../io/prometheus/client/CounterTest.java | 51 ++- .../io/prometheus/client/HistogramTest.java | 156 ++++++- .../exemplars/DefaultExemplarSamplerTest.java | 91 ++++ .../client/exemplars/ExemplarConfigTest.java | 178 ++++++++ .../client/exemplars/ExemplarTest.java | 186 +++++++++ .../client/exporter/common/TextFormat.java | 42 +- .../client/exporter/common/ExemplarTest.java | 391 ++++++++++++++++++ simpleclient_tracer/pom.xml | 41 ++ .../simpleclient_tracer_common/pom.xml | 25 ++ .../tracer/common/SpanContextSupplier.java | 14 + .../simpleclient_tracer_otel/pom.xml | 49 +++ .../OpenTelemetrySpanContextSupplier.java | 39 ++ .../simpleclient_tracer_otel_agent/pom.xml | 75 ++++ ...OpenTelemetryAgentSpanContextSupplier.java | 44 ++ 59 files changed, 4156 insertions(+), 503 deletions(-) create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java create mode 100644 OTEL_EXEMPLARS.md rename benchmark/src/main/java/io/prometheus/{ => client}/benchmark/CounterBenchmark.java (78%) create mode 100644 benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java rename benchmark/src/main/java/io/prometheus/{ => client}/benchmark/GaugeBenchmark.java (72%) rename benchmark/src/main/java/io/prometheus/{ => client}/benchmark/SummaryBenchmark.java (83%) create mode 100644 integration_tests/example_application/pom.xml create mode 100644 integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java create mode 100644 integration_tests/exemplars_otel/pom.xml create mode 100644 integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java create mode 100644 integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java create mode 100644 integration_tests/exemplars_otel/src/test/resources/Dockerfile create mode 100644 integration_tests/exemplars_otel/src/test/resources/logback-test.xml create mode 100644 integration_tests/exemplars_otel_agent/pom.xml create mode 100644 integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java create mode 100644 integration_tests/exemplars_otel_agent/src/main/resources/application.properties create mode 100644 integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java create mode 100644 integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile create mode 100644 integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml create mode 100644 integration_tests/java_versions/pom.xml create mode 100644 integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java create mode 100644 integration_tests/java_versions/src/test/resources/logback-test.xml create mode 100644 integration_tests/pom.xml create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java create mode 100644 simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java create mode 100644 simpleclient_tracer/pom.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_common/pom.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java create mode 100644 simpleclient_tracer/simpleclient_tracer_otel/pom.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java create mode 100644 simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java diff --git a/.circleci/config.yml b/.circleci/config.yml index 96bd70d06..d5e2c0a76 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,18 +1,18 @@ version: 2 +machine: true jobs: build: + machine: + image: ubuntu-2004:202010-01 working_directory: ~/circleci-java - docker: - - image: circleci/openjdk:8-jdk-stretch steps: - checkout - - restore_cache: # restore the saved cache after the first run or if `pom.xml` has changed - key: circleci-demo-java-spring-{{ checksum "pom.xml" }} - - run: mvn dependency:go-offline # gets the project dependencies + - restore_cache: + key: maven-dependencies-{{ checksum "pom.xml" }} + - run: ./mvnw clean verify - save_cache: paths: - ~/.m2 - key: circleci-demo-java-spring-{{ checksum "pom.xml" }} - - run: mvn package + key: maven-dependencies-{{ checksum "pom.xml" }} orbs: prometheus: prometheus/prometheus@0.11.0 diff --git a/.gitignore b/.gitignore index 66caafdaf..cec774d92 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ target/ simpleclient_pushgateway/mockserver.log simpleclient_pushgateway/mockserver_request.log nb-configuration.xml - +dependency-reduced-pom.xml diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 000000000..b901097f2 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index c6feb8bb6f76f2553e266ff8bf8867105154237e..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 100644 GIT binary patch literal 50710 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 EfAhh=DF6Tf literal 49519 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%0A$pwhjXzyA0ZzErH{1@M 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 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 6637cedb2..ffdc10e59 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,2 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip \ No newline at end of file +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/OTEL_EXEMPLARS.md b/OTEL_EXEMPLARS.md new file mode 100644 index 000000000..779f2d4d3 --- /dev/null +++ b/OTEL_EXEMPLARS.md @@ -0,0 +1,80 @@ +# OpenTelemetry Exemplars + +The `DefaultExemplarSampler` will provide OpenTelemetry exemplars if the [opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java) library version 0.16.0 or higher is found. When `client_java` 0.11.0 was released, the current [opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java) version was 1.2.0. + +## Running the Example + +If you want to see this in action, you can run the example from the `ExemplarsClientJavaIT`: + +``` +./mvnw package +cd integration_tests/exemplars_otel_agent/target/ +curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.2.0/opentelemetry-javaagent-all.jar +java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent-all.jar -jar ./sample-rest-application.jar +``` + +Now you have a Spring REST service running on [http://localhost:8080/hello](http://localhost:8080/hello) that is instrumented with the OpenTelemetry Java agent. + +Run a request to generate an OpenTelemetry trace + +``` +curl http://localhost:8080/hello +``` + +In order to get metrics in [OpenMetrics](http://openmetrics.io) format, run + +``` +curl -H 'Accept: application/openmetrics-text; version=1.0.0; charset=utf-8' http://localhost:8080/metrics +``` + +You should see metrics with Exemplars, for example in the `request_duration_histogram` metric: + +``` +request_duration_histogram_bucket{path="/god-of-fire",le="0.004"} 4.0 # {trace_id="043cd631811e373e4180a678c06b128e",span_id="cd122e457d2ca5b0"} 0.0033 1618261159.027 +``` + +Note that this is an example application for demonstration, so durations don't represent real durations, and some example metrics might not make sense in the real world. + +## Disabling OpenTelemetry Exemplars + +If you use OpenTelemetry tracing but do not want Exemplars, you can disable OpenTelemetries in multiple ways. + +### Disabling OpenTelemetry Exemplars in Code + +The default exemplar sampler can be disabled via the `ExemplarConfig` API. This is described in [README.md], as this is not specific to OpenTelemetry. + +### Disabling OpenTelemetry Exemplars at Compile Time + +If you don't want to change code, but still build an application that uses OpenTelemetry but does not provide OpenTelemetry exemplars, +you can exclude the corresponding dependencies in your `pom.xml`: + +```xml + + + io.prometheus + simpleclient + 0.11.0 + + + + io.prometheus + simpleclient_tracer_otel + + + + io.prometheus + simpleclient_tracer_otel_agent + + + + +``` + +### Disable OpenTelemetry Exemplars at Runtime + +If your application uses OpenTelemetry tracing, but you want to disable OpenTelemetry at runtime without changing code, +start your application with the `io.prometheus.otelExemplars` system property: + +``` +java -Dio.prometheus.otelExemplars=inactive -jar my-application.jar +``` diff --git a/README.md b/README.md index 7086f8c30..35114236d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@ Table of Contents * [Histogram](#histogram) * [Labels](#labels) * [Registering Metrics](#registering-metrics) + * [Exemplars](#exemplars) + * [Global Exemplar Samplers](#global-exemplar-samplers) + * [Per Metric Exemplar Samplers](#per-metric-exemplar-samplers) + * [Per Observation Exemplars](#per-observation-exemplars) + * [Built-in Support for Tracing Systems](#built-in-support-for-tracing-systems) * [Included Collectors](#included-collectors) * [Logging](#logging) * [Caches](#caches) @@ -291,6 +296,123 @@ class YourClass { } ``` +## Exemplars + +Exemplars are a feature of the [OpenMetrics](http://openmetrics.io) format that allows applications to link metrics to example traces. +Exemplars are supported since `client_java` version 0.11.0. Exemplars are supported for `Counter` and `Histogram` metrics. + +### Global Exemplar Samplers + +An `ExemplarSampler` is used implicitly under the hood to add exemplars to your metrics. The idea is that you get exemplars without changing your code. + +The `DefaultExemplarSampler` comes with built-in support for [OpenTelemetry tracing](https://github.com/open-telemetry/opentelemetry-java), see [built-in support for tracing systems](#built-in-support-for-tracing-systems) below. + +You can disable the default exemplar samplers globally with: + +```java +ExemplarConfig.disableExemplars(); +``` + +You can set your own custom implementation of `ExemplarSampler` as a global default like this: + +```java +ExemplarSampler myExemplarSampler = new MyExemplarSampler(); +ExemplarConfig.setCounterExemplarSampler(myExemplarSampler); +ExemplarConfig.setHistogramExemplarSampler(myExemplarSampler); +``` + +### Per Metric Exemplar Samplers + +The metric builders for `Counter` and `Histogram` have methods for setting the exemplar sampler for that individual metric. This takes precedence over the global setting in `ExemplarConfig`. + +The following calls enable the default exemplar sampler for individual metrics. This is useful if you disabled the exemplar sampler globally with `ExemplarConfig.disableExemplars()`. + +```java +Counter myCounter = Counter.build() + .name("number_of_events_total") + .help("help") + .withExemplars() + ... + .register(); +``` + +```java +Histogram myHistogram = Histogram.build() + .name("my_latency") + .help("help") + .withExemplars() + ... + .register(); +``` + +The following calls disable exemplars for individual metrics: + +```java +Counter myCounter = Counter.build() + .name("number_of_events_total") + .help("help") + .withoutExemplars() + ... + .register(); +``` + +```java +Histogram myHistogram = Histogram.build() + .name("my_latency") + .help("help") + .withoutExemplars() + ... + .register(); +``` + +The following calls enable exemplars and set a custom `MyExemplarSampler` for individual metrics: + +```java +// CounterExemplarSampler +Counter myCounter = Counter.build() + .name("number_of_events_total") + .help("help") + .withExemplarSampler(new MyExemplarSampler()) + ... + .register(); +``` + +```java +// HistogramExemplarSampler +Histogram myHistogram = Histogram.build() + .name("my_latency") + .help("help") + .withExemplarSampler(new MyExemplarSampler()) + ... + .register(); +``` + +### Per Observation Exemplars + +You can explicitly provide an exemplar for an individual observation. This takes precedence over the exemplar sampler configured with the metric. + +The following call will increment a counter, and create an exemplar with the specified `span_id` and `trace_id` labels: + +```java +myCounter.incWithExemplar("span_id", "abcdef", "trace_id", "123456"); +``` + +The following call will observe a value of `0.12` in a histogram, and create an exemplar with the specified `span_id` and `trace_id` labels: + +```java +myHistogram.observeWithExemplar(0.12, "span_id", "abcdef", "trace_id", "123456"); +``` + +All methods for observing and incrementing values have `...withExemplar` equivalents. There are versions taking the exemplar labels as a `String...` as shown in the example, as well as versions taking the exemplar labels as a `Map`. + +### Built-in Support for Tracing Systems + +The `DefaultExemplarSampler` detects if a tracing library is found on startup, and provides exemplars for that tracing library by default. Currently, only [OpenTelemetry tracing](https://github.com/open-telemetry/opentelemetry-java) is supported. +If you are a tracing vendor, feel free to open a PR and add support for your tracing library. + +Documentation of the individual tracer integrations: + +* [OTEL_EXEMPLARS.md]: OpenTelemetry ## Included Collectors diff --git a/benchmark/README.md b/benchmark/README.md index 628a4d444..4afefd30c 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -6,114 +6,88 @@ This module contains microbenchmarks for client instrumentation operations. The main outcomes of the benchmarks: * Simpleclient Counters/Gauges have similar performance to Codahale Counters. -* The original client is much slower than the Simpleclient or Codahale, especially when used concurrently. * Codahale Meters are slower than Codahale/Simpleclient Counters -* Codahale and original client Summaries are 10x slower than other metrics. -* Simpleclient Histograms are 10-100X faster than Codahale and original client Summaries. +* Codahale Summaries are 10x slower than other metrics. +* Simpleclient Histograms are 10-100X faster than Codahale Summaries. * Simpleclient `Gauge.Child.set` is relatively slow, especially when done concurrently. -* Label lookups in both Prometheus clients are relatively slow. +* Label lookups in simpleclient are relatively slow. +* The `System.currentTimeMillis()` call in the `DefaultExemplarSampler` takes about 17ns on Linux. Accordingly, in terms of client instrumentation performance I suggest the following: * It's cheap to extensively instrument your code with Simpleclient Counters/Gauges/Summaries without labels, or Codahale Counters. * Avoid Codahale Meters, in favour of Codahale/Simpleclient Counters and calculating the rate in your monitoring system (e.g. the `rate()` function in Prometheus). -* Use Simpleclient Histograms rather than original client Summaries and Codahale Histograms/Timers. -* Avoid the original client. +* Use Simpleclient Histograms rather than Codahale Histograms/Timers. * For high update rate (>1000 per second) prometheus metrics using labels, you should cache the Child. Java 8 may make this better due to an improved ConcurrentHashMap implementation. * If a use case appears for high update rate use of SimpleClient's `Gauge.Child.set`, we should alter `DoubleAdder` to more efficiently handle this use case. ## Benchmark Results -These benchmarks were run using JMH on a 2-core MacBook Pro with a 2.5GHz i5 processor, -with Oracle Java 64 1.7.0\_51. +These benchmarks were run using JMH on a Linux laptop with a 4 Core Intel i7-8550U CPU with OpenJDK 1.8.0_292-b10. ### Counters java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 11.554 ± 0.251 ns/op - i.p.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 75.305 ± 7.147 ns/op - i.p.b.CounterBenchmark.prometheusCounterChildIncBenchmark avgt 5 13.249 ± 0.029 ns/op - i.p.b.CounterBenchmark.prometheusCounterIncBenchmark avgt 5 127.397 ± 4.072 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 12.989 ± 0.285 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 54.822 ± 7.994 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 13.131 ± 1.661 ns/op + i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 8.587 ± 0.530 ns/op + i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 40.820 ± 5.550 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 10.387 ± 0.698 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 32.357 ± 1.742 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 10.102 ± 0.524 ns/op java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 16.707 ± 2.116 ns/op - i.p.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 107.346 ± 23.127 ns/op - i.p.b.CounterBenchmark.prometheusCounterChildIncBenchmark avgt 5 41.912 ± 18.167 ns/op - i.p.b.CounterBenchmark.prometheusCounterIncBenchmark avgt 5 170.860 ± 5.110 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 17.782 ± 2.764 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 89.656 ± 4.577 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 16.109 ± 1.723 ns/op + i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 8.236 ± 0.409 ns/op + i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 57.797 ± 4.758 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 11.123 ± 2.041 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 41.512 ± 5.128 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 11.455 ± 0.586 ns/op java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 17.628 ± 0.501 ns/op - i.p.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 121.836 ± 15.888 ns/op - i.p.b.CounterBenchmark.prometheusCounterChildIncBenchmark avgt 5 377.916 ± 7.965 ns/op - i.p.b.CounterBenchmark.prometheusCounterIncBenchmark avgt 5 250.919 ± 2.728 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 18.055 ± 1.391 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 120.543 ± 1.770 ns/op - i.p.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 19.334 ± 1.471 ns/op + i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 9.613 ± 1.024 ns/op + i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 90.632 ± 6.027 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 14.857 ± 0.694 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 67.335 ± 15.512 ns/op + i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 15.808 ± 1.073 ns/op ### Gauges Codahale lacks a metric with a `set` method, so we'll compare to `Counter` which has `inc` and `dec`. java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 11.620 ± 0.288 ns/op - i.p.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 11.718 ± 0.333 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildDecBenchmark avgt 5 13.358 ± 0.554 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildIncBenchmark avgt 5 13.268 ± 0.276 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildSetBenchmark avgt 5 11.624 ± 0.210 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeDecBenchmark avgt 5 125.058 ± 2.764 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeIncBenchmark avgt 5 127.814 ± 7.741 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeSetBenchmark avgt 5 127.899 ± 6.690 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 12.961 ± 0.393 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 12.932 ± 0.212 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 36.672 ± 1.112 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 54.677 ± 3.704 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 53.278 ± 1.104 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 79.724 ± 2.723 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 12.957 ± 0.437 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 12.932 ± 0.284 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 40.235 ± 1.735 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 8.476 ± 0.379 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 8.566 ± 0.555 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 10.532 ± 0.652 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 10.112 ± 0.740 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 6.833 ± 0.301 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 34.962 ± 2.310 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 28.474 ± 1.965 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 10.183 ± 0.580 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 10.061 ± 0.525 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 6.790 ± 0.505 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 30.993 ± 1.626 ns/op java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 17.443 ± 4.819 ns/op - i.p.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 14.882 ± 2.875 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildDecBenchmark avgt 5 45.206 ± 29.575 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildIncBenchmark avgt 5 46.657 ± 33.518 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildSetBenchmark avgt 5 21.810 ± 9.370 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeDecBenchmark avgt 5 177.370 ± 2.477 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeIncBenchmark avgt 5 172.136 ± 3.056 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeSetBenchmark avgt 5 186.791 ± 7.996 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 15.978 ± 2.762 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 15.457 ± 1.052 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 156.604 ± 10.953 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 107.134 ± 33.620 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 89.362 ± 16.608 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 163.823 ± 25.270 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 16.380 ± 1.915 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 17.042 ± 1.113 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 164.930 ± 2.565 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 9.249 ± 0.651 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 8.266 ± 1.095 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 10.185 ± 0.404 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 10.669 ± 0.384 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 46.205 ± 3.406 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 39.633 ± 1.520 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 40.184 ± 3.697 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 10.955 ± 0.496 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 10.877 ± 0.595 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 45.394 ± 3.192 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 86.524 ± 2.633 ns/op java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 17.291 ± 1.769 ns/op - i.p.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 17.445 ± 0.709 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildDecBenchmark avgt 5 389.411 ± 13.078 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildIncBenchmark avgt 5 399.549 ± 29.274 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeChildSetBenchmark avgt 5 123.700 ± 3.894 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeDecBenchmark avgt 5 244.741 ± 22.477 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeIncBenchmark avgt 5 243.525 ± 6.332 ns/op - i.p.b.GaugeBenchmark.prometheusGaugeSetBenchmark avgt 5 252.363 ± 2.664 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 18.330 ± 2.673 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 20.633 ± 1.219 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 335.455 ± 4.562 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 116.432 ± 4.793 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 129.390 ± 2.360 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 613.186 ± 20.548 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 19.765 ± 3.189 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 19.589 ± 1.634 ns/op - i.p.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 307.238 ± 1.918 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 9.347 ± 0.798 ns/op + i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 11.991 ± 0.977 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 14.019 ± 0.592 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 14.870 ± 0.549 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 120.478 ± 16.162 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 54.028 ± 7.432 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 55.782 ± 7.767 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 14.083 ± 0.820 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 14.275 ± 0.590 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 146.348 ± 11.097 ns/op + i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 154.449 ± 10.655 ns/op ### Summaries @@ -123,39 +97,39 @@ The closest to the original client's `Summary` is Codahale's `Timer`, but that includes timing calls so we compare with `Histogram` instead. java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 186.306 ± 4.958 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 81.595 ± 4.491 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 22.143 ± 1.713 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 22.066 ± 0.812 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 59.588 ± 2.087 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 15.300 ± 0.659 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 15.608 ± 0.271 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryBenchmark avgt 5 981.640 ± 315.146 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryChildBenchmark avgt 5 1155.179 ± 850.237 ns/op + i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 116.902 ± 5.797 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 39.897 ± 1.581 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 17.692 ± 1.435 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 17.844 ± 1.213 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 32.840 ± 1.453 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 10.862 ± 0.874 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 11.290 ± 0.613 ns/op java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 289.245 ± 39.721 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 127.014 ± 19.285 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 52.597 ± 10.781 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 53.295 ± 9.891 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 117.810 ± 11.694 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 31.933 ± 3.439 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 33.918 ± 5.571 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryBenchmark avgt 5 2059.498 ± 616.954 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryChildBenchmark avgt 5 2346.163 ± 1503.034 ns/op + i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 326.477 ± 47.550 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 53.194 ± 3.719 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 30.660 ± 2.403 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 30.361 ± 1.727 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 47.051 ± 1.927 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 15.596 ± 0.660 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 16.168 ± 1.059 ns/op java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 587.956 ± 2.788 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 163.313 ± 5.163 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 66.957 ± 1.746 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 67.064 ± 1.681 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 140.166 ± 4.263 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 40.065 ± 0.138 ns/op - i.p.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 41.331 ± 1.899 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryBenchmark avgt 5 3950.152 ± 1214.866 ns/op - i.p.b.SummaryBenchmark.prometheusSummaryChildBenchmark avgt 5 4676.946 ± 3625.977 ns/op + i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 820.989 ± 46.036 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 86.183 ± 11.741 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 40.051 ± 1.309 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 41.475 ± 4.742 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 63.493 ± 3.490 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 21.829 ± 2.226 ns/op + i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 25.150 ± 2.173 ns/op Note the high error bars for the original client, it got slower with each iteration so I suspect a flaw in the test setup. +### Exemplars + java -jar target/benchmarks.jar ExemplarsBenchmark + Benchmark Mode Samples Score Error Units + i.p.c.b.ExemplarsBenchmark.testCounter avgt 200 27.318 ± 0.347 ns/op + i.p.c.b.ExemplarsBenchmark.testCounterWithExemplars avgt 200 45.785 ± 0.177 ns/op + i.p.c.b.ExemplarsBenchmark.testCounterWithoutExemplars avgt 200 25.404 ± 0.184 ns/op \ No newline at end of file diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 6f1757d8a..0726e3486 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -40,16 +40,10 @@ javax.annotation-api 1.3.1 - - - io.prometheus - client - 0.0.10 - io.prometheus simpleclient - 0.10.1-SNAPSHOT + ${project.version} com.codahale.metrics diff --git a/benchmark/src/main/java/io/prometheus/benchmark/CounterBenchmark.java b/benchmark/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java similarity index 78% rename from benchmark/src/main/java/io/prometheus/benchmark/CounterBenchmark.java rename to benchmark/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java index ca644070c..592efc6f2 100644 --- a/benchmark/src/main/java/io/prometheus/benchmark/CounterBenchmark.java +++ b/benchmark/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java @@ -1,11 +1,9 @@ -package io.prometheus.benchmark; +package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; - -import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; @@ -15,6 +13,8 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; +import java.util.concurrent.TimeUnit; + @State(Scope.Benchmark) public class CounterBenchmark { @@ -22,20 +22,12 @@ public class CounterBenchmark { com.codahale.metrics.Counter codahaleCounter; com.codahale.metrics.Meter codahaleMeter; - io.prometheus.client.metrics.Counter prometheusCounter; - io.prometheus.client.metrics.Counter.Child prometheusCounterChild; io.prometheus.client.Counter prometheusSimpleCounter; io.prometheus.client.Counter.Child prometheusSimpleCounterChild; io.prometheus.client.Counter prometheusSimpleCounterNoLabels; @Setup public void setup() { - prometheusCounter = io.prometheus.client.metrics.Counter.newBuilder() - .name("name") - .documentation("some description..") - .build(); - prometheusCounterChild = prometheusCounter.newPartial().apply(); - prometheusSimpleCounter = io.prometheus.client.Counter.build() .name("name") .help("some description..") @@ -52,20 +44,6 @@ public void setup() { codahaleMeter = registry.meter("meter"); } - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusCounterIncBenchmark() { - prometheusCounter.newPartial().apply().increment(); - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusCounterChildIncBenchmark() { - prometheusCounterChild.increment(); - } - @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) diff --git a/benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java b/benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java new file mode 100644 index 000000000..2c2acc29c --- /dev/null +++ b/benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java @@ -0,0 +1,80 @@ +package io.prometheus.client.benchmark; + +import io.prometheus.client.Counter; +import io.prometheus.client.exemplars.DefaultExemplarSampler; +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +public class ExemplarsBenchmark { + + private Counter counter; + private Counter counterWithExemplars; + private Counter counterWithoutExemplars; + + @Setup + public void setup() { + + counter = Counter.build() + .name("counter_total") + .help("Total number of requests.") + .labelNames("path") + .create(); + + counterWithExemplars = Counter.build() + .name("counter_with_exemplars_total") + .help("Total number of requests.") + .labelNames("path") + .withExemplarSampler(new DefaultExemplarSampler(new MockSpanContextSupplier())) + .create(); + + counterWithoutExemplars = Counter.build() + .name("counter_without_exemplars_total") + .help("Total number of requests.") + .labelNames("path") + .withoutExemplars() + .create(); + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void testCounter() { + counter.labels("test").inc(); + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void testCounterWithExemplars() { + counterWithExemplars.labels("test").inc(); + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void testCounterWithoutExemplars() { + counterWithoutExemplars.labels("test").inc(); + } + + private static class MockSpanContextSupplier implements SpanContextSupplier { + + @Override + public String getTraceId() { + return "trace-id"; + } + + @Override + public String getSpanId() { + return "span-id"; + } + } +} diff --git a/benchmark/src/main/java/io/prometheus/benchmark/GaugeBenchmark.java b/benchmark/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java similarity index 72% rename from benchmark/src/main/java/io/prometheus/benchmark/GaugeBenchmark.java rename to benchmark/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java index d8037723f..d088d280d 100644 --- a/benchmark/src/main/java/io/prometheus/benchmark/GaugeBenchmark.java +++ b/benchmark/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java @@ -1,11 +1,9 @@ -package io.prometheus.benchmark; +package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; - -import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; @@ -15,26 +13,20 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; +import java.util.concurrent.TimeUnit; + @State(Scope.Benchmark) public class GaugeBenchmark { MetricRegistry registry; com.codahale.metrics.Counter codahaleCounter; - io.prometheus.client.metrics.Gauge prometheusGauge; - io.prometheus.client.metrics.Gauge.Child prometheusGaugeChild; io.prometheus.client.Gauge prometheusSimpleGauge; io.prometheus.client.Gauge.Child prometheusSimpleGaugeChild; io.prometheus.client.Gauge prometheusSimpleGaugeNoLabels; @Setup public void setup() { - prometheusGauge = io.prometheus.client.metrics.Gauge.newBuilder() - .name("name") - .documentation("some description..") - .build(); - prometheusGaugeChild = prometheusGauge.newPartial().apply(); - prometheusSimpleGauge = io.prometheus.client.Gauge.build() .name("name") .help("some description..") @@ -51,20 +43,6 @@ public void setup() { } // Increment. - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeIncBenchmark() { - prometheusGauge.newPartial().apply().increment(); - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeChildIncBenchmark() { - prometheusGaugeChild.increment(); - } - @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @@ -95,20 +73,6 @@ public void codahaleCounterIncBenchmark() { // Decrement. - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeDecBenchmark() { - prometheusGauge.newPartial().apply().decrement(); - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeChildDecBenchmark() { - prometheusGaugeChild.decrement(); - } - @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @@ -138,20 +102,6 @@ public void codahaleCounterDecBenchmark() { } // Set. - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeSetBenchmark() { - prometheusGauge.newPartial().apply().set(42); - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusGaugeChildSetBenchmark() { - prometheusGaugeChild.set(42); - } - @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) diff --git a/benchmark/src/main/java/io/prometheus/benchmark/SummaryBenchmark.java b/benchmark/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java similarity index 83% rename from benchmark/src/main/java/io/prometheus/benchmark/SummaryBenchmark.java rename to benchmark/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java index 3a77dc5ec..973106c68 100644 --- a/benchmark/src/main/java/io/prometheus/benchmark/SummaryBenchmark.java +++ b/benchmark/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java @@ -1,11 +1,9 @@ -package io.prometheus.benchmark; +package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; - -import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; -import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; @@ -15,14 +13,14 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; +import java.util.concurrent.TimeUnit; + @State(Scope.Benchmark) public class SummaryBenchmark { MetricRegistry registry; com.codahale.metrics.Histogram codahaleHistogram; - io.prometheus.client.metrics.Summary prometheusSummary; - io.prometheus.client.metrics.Summary.Child prometheusSummaryChild; io.prometheus.client.Summary prometheusSimpleSummary; io.prometheus.client.Summary.Child prometheusSimpleSummaryChild; io.prometheus.client.Summary prometheusSimpleSummaryNoLabels; @@ -32,12 +30,6 @@ public class SummaryBenchmark { @Setup public void setup() { - prometheusSummary = io.prometheus.client.metrics.Summary.newBuilder() - .name("name") - .documentation("some description..") - .build(); - prometheusSummaryChild = prometheusSummary.newPartial().apply(); - prometheusSimpleSummary = io.prometheus.client.Summary.build() .name("name") .help("some description..") @@ -64,20 +56,6 @@ public void setup() { codahaleHistogram = registry.histogram("name"); } - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusSummaryBenchmark() { - prometheusSummary.newPartial().apply().observe(1.0); - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void prometheusSummaryChildBenchmark() { - prometheusSummaryChild.observe(1.0); - } - @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml new file mode 100644 index 000000000..431a64579 --- /dev/null +++ b/integration_tests/example_application/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.10.1-SNAPSHOT + + + example_application + Integration Test - Example Application + + + + io.prometheus + simpleclient + ${project.version} + + + io.prometheus + simpleclient_hotspot + ${project.version} + + + io.prometheus + simpleclient_httpserver + ${project.version} + + + + + ${artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + io.prometheus.client.smoketest.Server + + + + + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java b/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java new file mode 100644 index 000000000..73ab219f1 --- /dev/null +++ b/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java @@ -0,0 +1,18 @@ +package io.prometheus.client.smoketest; + +import io.prometheus.client.exporter.HTTPServer; +import io.prometheus.client.hotspot.DefaultExports; + +import java.io.IOException; + +/** + * Simple example application that compiles with Java 6. + */ +public class Server { + + public static void main(String[] args) throws IOException, InterruptedException { + DefaultExports.initialize(); + new HTTPServer(9000); + Thread.currentThread().join(); // sleep forever + } +} diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml new file mode 100644 index 000000000..7b168f1ed --- /dev/null +++ b/integration_tests/exemplars_otel/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.10.1-SNAPSHOT + + + exemplars_otel + Integration Test - Exemplars with OpenTelemetry + + + 1.2.0 + + + + + io.prometheus + simpleclient + ${project.version} + + + io.opentelemetry + opentelemetry-api + ${otel.version} + + + io.opentelemetry + opentelemetry-sdk + ${otel.version} + + + io.prometheus + simpleclient_httpserver + ${project.version} + + + com.squareup.okhttp3 + okhttp + 4.9.1 + + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + 1.1.2 + + + + + ${artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + integration-test + integration-test + + integration-test + + + + verify + verify + + verify + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 + + + copy-dependencies + package + + copy-dependencies + + + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java b/integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java new file mode 100644 index 000000000..c6329a97d --- /dev/null +++ b/integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java @@ -0,0 +1,70 @@ +package io.prometheus.client.it.exemplars_otel; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.prometheus.client.Counter; +import io.prometheus.client.exporter.HTTPServer; + +import java.io.IOException; + +public class Server { + + public static void main(String[] args) throws IOException, InterruptedException { + Counter counter = Counter.build() + .name("test") + .help("help") + .register(); + + // The following code compiles with OpenTelemetry versions 0.13.0 and higher. + // Starting with 0.16.0 you will see exemplars. With 0.15.0 or lower the code will run but you won't see exemplars. + System.out.println(Tracer.class.getProtectionDomain().getCodeSource().getLocation()); + Tracer tracer = SdkTracerProvider.builder().build().get(null); + Span span = tracer.spanBuilder("my span").startSpan(); + span.makeCurrent(); + counter.inc(1); + span.end(); + + // Examples with older OpenTelemetry versions used for manual testing: + + /* + // OpenTelemetry versions 0.10.0 - 0.12.0 + System.out.println(Tracer.class.getProtectionDomain().getCodeSource().getLocation()); + Tracer tracer = OpenTelemetrySdk.get().getTracer("test"); + Span span = tracer.spanBuilder("my span").startSpan(); + span.makeCurrent(); + counter.inc(1); + span.end(); + */ + + /* + // OpenTelemetry versions 0.4.0 - 0.9.1 + System.out.println(TracerSdkProvider.class.getProtectionDomain().getCodeSource().getLocation()); + Tracer tracer = TracerSdkProvider.builder().build().get("test"); + Span span = tracer.spanBuilder("my span").startSpan(); + counter.inc(1); + span.end(); + */ + + /* + // OpenTelemetry version 0.3.0 + System.out.println(TracerSdkProvider.class.getProtectionDomain().getCodeSource().getLocation()); + TracerSdk tracer = TracerSdkProvider.builder().build().get("test"); + Span span = tracer.spanBuilder("my span").startSpan(); + counter.inc(1); + span.end(); + */ + + /* + // OpenTelemetry version 0.2.0 + System.out.println(TracerSdkFactory.class.getProtectionDomain().getCodeSource().getLocation()); + TracerSdk tracer = TracerSdkFactory.create().get("test"); + Span span = tracer.spanBuilder("my span").startSpan(); + counter.inc(1); + span.end(); + */ + + new HTTPServer(9000); + Thread.currentThread().join(); // sleep forever + } +} diff --git a/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java b/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java new file mode 100644 index 000000000..3a34445e5 --- /dev/null +++ b/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java @@ -0,0 +1,103 @@ +package io.prometheus.client.it.exemplars_otel; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.junit.Assert; +import org.junit.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +/** + * This is just a smoke test, as completeness is already tested with exemplars_otel_agent + */ +public class ExemplarsOtelIT { + + private final String cmd = "java -cp \"/app/exemplars_otel.jar:/app/lib/*\" io.prometheus.client.it.exemplars_otel.Server"; + private final OkHttpClient client = new OkHttpClient(); + + private static class DockerContainer extends GenericContainer { + DockerContainer() { + super(new ImageFromDockerfile("exemplars-otel-test") + .withFileFromPath("exemplars_otel.jar", Paths.get("target/exemplars_otel.jar")) + .withFileFromPath("dependency", Paths.get("target/dependency")) + .withFileFromClasspath("Dockerfile", "Dockerfile")); + } + } + + @Test + public void testGoodCase() throws IOException { + runTest(":", true); + } + + @Test + public void testOtelAgentMissing() throws IOException { + runTest("rm /app/lib/simpleclient_tracer_otel_agent-*", true); + } + + @Test + public void testOtelMissing() throws IOException { + runTest("rm /app/lib/simpleclient_tracer_otel-*", false); + } + + @Test + public void testOtelAllMissing() throws IOException { + runTest("rm /app/lib/simpleclient_tracer_otel*", false); + } + + @Test + public void testTracerCommonMissing() throws IOException { + runTest("rm /app/lib/simpleclient_tracer_common-*", false); + } + + @Test + public void testAllMissing() throws IOException { + runTest("rm /app/lib/simpleclient_tracer*", false); + } + + private void runTest(String rmCmd, boolean exemplarsExpected) throws IOException { + try (DockerContainer container = new DockerContainer() + .withExposedPorts(9000) + .withCommand("/bin/bash", "-c", rmCmd + " ; " + cmd)) { + container.start(); + List metrics = scrapeMetrics(container); + boolean testTotalWithExemplarFound = false; + boolean testTotalWithoutExemplarFound = false; + for (String metric : metrics) { + System.out.println(metric); + if (metric.matches("^test_total 1\\.0 # \\{span_id=\"[0-9a-f]+\",trace_id=\"[0-9a-f]+\"} 1.0 [0-9.]+$")) { + testTotalWithExemplarFound = true; + } + if (metric.matches("^test_total 1\\.0$")) { + testTotalWithoutExemplarFound = true; + } + } + if (exemplarsExpected) { + Assert.assertTrue("test_total metric with exemplars expected", testTotalWithExemplarFound); + Assert.assertFalse("test_total without exemplar should not be there", testTotalWithoutExemplarFound); + } else { + Assert.assertFalse("test_total metric with exemplar should not be there", testTotalWithExemplarFound); + Assert.assertTrue("test_total without exemplar expected", testTotalWithoutExemplarFound); + } + } + } + + private List scrapeMetrics(DockerContainer dockerContainer) throws IOException { + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(9000) + "/metrics") + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .build(); + try (Response response = client.newCall(request).execute()) { + String body = response.body().string(); + System.out.println("body:---"); + System.out.println(body); + System.out.println("---"); + return Arrays.asList(body.split("\\n")); + } + } +} diff --git a/integration_tests/exemplars_otel/src/test/resources/Dockerfile b/integration_tests/exemplars_otel/src/test/resources/Dockerfile new file mode 100644 index 000000000..b15745aab --- /dev/null +++ b/integration_tests/exemplars_otel/src/test/resources/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:11-jre +RUN mkdir -p /app/ +COPY dependency /app/lib +COPY exemplars_otel.jar /app/ +CMD java -cp "/app/exemplars_otel.jar:/app/lib/*" io.prometheus.client.it.exemplars_otel.Server \ No newline at end of file diff --git a/integration_tests/exemplars_otel/src/test/resources/logback-test.xml b/integration_tests/exemplars_otel/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/exemplars_otel/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/exemplars_otel_agent/pom.xml new file mode 100644 index 000000000..ef0d23991 --- /dev/null +++ b/integration_tests/exemplars_otel_agent/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.10.1-SNAPSHOT + + + exemplars_otel_agent + Integration Test - Exemplars with the OpenTelemetry Agent + + + + + org.springframework.boot + spring-boot-dependencies + 2.4.4 + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + com.squareup.okhttp3 + okhttp + 4.9.1 + + + io.prometheus + simpleclient + ${project.version} + + + io.prometheus + simpleclient_hotspot + ${project.version} + + + io.prometheus + simpleclient_servlet + ${project.version} + + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + + + + + sample-rest-application + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + integration-test + integration-test + + integration-test + + + + verify + verify + + verify + + + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java b/integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java new file mode 100644 index 000000000..dc01c4c58 --- /dev/null +++ b/integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java @@ -0,0 +1,98 @@ +package io.prometheus.client.it.exemplars_otel_agent; + +import io.prometheus.client.Counter; +import io.prometheus.client.Gauge; +import io.prometheus.client.Histogram; +import io.prometheus.client.Summary; +import io.prometheus.client.exporter.MetricsServlet; +import io.prometheus.client.hotspot.DefaultExports; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; + +@SpringBootApplication +@RestController +public class SampleRestApplication { + + private double durationOuterMs = 0.5; + private double durationInnerMs = 0.3; + + private final OkHttpClient client = new OkHttpClient(); + + private final Counter requestCounter = Counter.build() + .name("requests_total") + .help("Total number of requests.") + .labelNames("path") + .register(); + private final Gauge lastRequestTimestamp = Gauge.build() + .name("last_request_timestamp") + .help("unix time of the last request") + .labelNames("path") + .register(); + private final Histogram requestDurationHistogram = Histogram.build() + .name("request_duration_histogram") + .help("Request duration in seconds") + .labelNames("path") + .buckets(0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009) + .register(); + private final Summary requestDurationSummary = Summary.build() + .name("request_duration_summary") + .help("Request duration in seconds") + .labelNames("path") + .quantile(0.75, 0.01) + .quantile(0.85, 0.01) + .register(); + + public static void main(String[] args) { + DefaultExports.initialize(); + SpringApplication.run(SampleRestApplication.class, args); + } + + @GetMapping("/hello") + public String hello() throws IOException { + String path = "/hello"; + requestCounter.labels(path).inc(); + lastRequestTimestamp.labels(path).setToCurrentTime(); + requestDurationHistogram.labels(path).observe(durationOuterMs / 1000.0); + requestDurationSummary.labels(path).observe(durationOuterMs / 1000.0); + durationOuterMs += 1; + if (durationOuterMs > 10) { + durationOuterMs = 0.5; + } + Request request = new Request.Builder() + .url("http://localhost:8080/god-of-fire") + .build(); + try (Response response = client.newCall(request).execute()) { + return "Hello, " + response.body().string() + "!\n"; + } + } + + @GetMapping("/god-of-fire") + public String godOfFire() { + String path = "/god-of-fire"; + requestCounter.labels(path).inc(); + lastRequestTimestamp.labels(path).setToCurrentTime(); + requestDurationHistogram.labels(path).observe(durationInnerMs / 1000.0); + requestDurationSummary.labels(path).observe(durationInnerMs / 1000.0); + durationInnerMs += 1; + if (durationInnerMs > 10) { + durationInnerMs = 0.3; + } + return "Prometheus"; + } + + @Bean + public ServletRegistrationBean metricsServlet() { + ServletRegistrationBean bean = new ServletRegistrationBean<>(new MetricsServlet(), "/metrics"); + bean.setLoadOnStartup(1); + return bean; + } +} diff --git a/integration_tests/exemplars_otel_agent/src/main/resources/application.properties b/integration_tests/exemplars_otel_agent/src/main/resources/application.properties new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/integration_tests/exemplars_otel_agent/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java b/integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java new file mode 100644 index 000000000..24b41171c --- /dev/null +++ b/integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java @@ -0,0 +1,235 @@ +package io.prometheus.client.it.exemplars_otel_agent; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ExemplarsClientJavaIT { + + private final OkHttpClient client = new OkHttpClient(); + + private static class DockerContainer extends GenericContainer { + DockerContainer() { + super(new ImageFromDockerfile("exemplars-otel-agent-test") + .withFileFromPath("sample-rest-application.jar", Paths.get("target/sample-rest-application.jar")) + .withFileFromClasspath("Dockerfile", "Dockerfile")); + } + } + + @Rule + public DockerContainer dockerContainer = new DockerContainer() + .withExposedPorts(8080) + .waitingFor(Wait.forLogMessage(".* Started .*", 1)); + + @Test + public void testExemplars() throws IOException { + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/hello") + .build(); + + // --------------------------------------------------- + // first request + // --------------------------------------------------- + + execute(request); + List metrics = scrapeMetrics(); + SpanContext outer = getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/hello", "le", "0.001"); + SpanContext inner = getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", "0.001"); + Assert.assertEquals(outer.traceId, inner.traceId); + Assert.assertNotEquals(outer.spanId, inner.spanId); + + // counter + assertExemplar(outer, metrics, "requests_total", "path", "/hello"); + assertNoExemplar(metrics, "requests_created", "path", "/hello"); + assertExemplar(inner, metrics, "requests_total", "path", "/god-of-fire"); + assertNoExemplar(metrics, "requests_created", "path", "/god-of-fire"); + + // gauge (Gauges don't have Exemplars according to the OpenMetrics Spec) + assertNoExemplar(metrics, "last_request_timestamp", "path", "/hello"); + assertNoExemplar(metrics, "last_request_timestamp", "path", "/god-of-fire"); + + // histogram: simulated duration is 0.5ms for the outer and 0.3ms for the inner request + assertExemplar(outer, metrics, "request_duration_histogram_bucket", "path", "/hello", "le", "0.001"); + assertExemplar(inner, metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", "0.001"); + for (int i=2; i<=9; i++) { + assertNoExemplar(metrics, "request_duration_histogram_bucket", "path", "/hello", "le", "0.00" + i); + assertNoExemplar(metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", "0.00" + i); + } + assertNoExemplar(metrics, "request_duration_histogram_bucket", "path", "/hello", "le", "+Inf"); + assertNoExemplar(metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", "+Inf"); + + // summary: all values are identical because there is only one observation. Summaries don't have exempalrs + assertNoExemplar(metrics, "request_duration_summary", "path", "/hello", "quantile", "0.75"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/hello", "quantile", "0.85"); + assertNoExemplar(metrics, "request_duration_summary_count", "path", "/hello"); + assertNoExemplar(metrics, "request_duration_summary_sum", "path", "/hello"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/god-of-fire", "quantile", "0.75"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/god-of-fire", "quantile", "0.85"); + assertNoExemplar(metrics, "request_duration_summary_count", "path", "/god-of-fire"); + assertNoExemplar(metrics, "request_duration_summary_sum", "path", "/god-of-fire"); + + // random unrelated metric + assertNoExemplar(metrics, "jvm_threads_current"); + + // --------------------------------------------------- + // 10 more requests + // --------------------------------------------------- + + for (int i=0; i<10; i++) { + execute(request); + } + metrics = scrapeMetrics(); + Map outers = new HashMap<>(); + Map inners = new HashMap<>(); + for (String bucket : new String[]{"0.001", "0.002", "0.003", "0.004", "0.005", "0.006", "0.007", "0.008", "0.009", "+Inf"}) { + outers.put(bucket, getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/hello", "le", bucket)); + inners.put(bucket, getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", bucket)); + } + + // counter: not updated, because the minimum retention interval is not over yet + assertExemplar(outer, metrics, "requests_total", "path", "/hello"); + assertNoExemplar(metrics, "requests_created", "path", "/hello"); + assertExemplar(inner, metrics, "requests_total", "path", "/god-of-fire"); + assertNoExemplar(metrics, "requests_created", "path", "/god-of-fire"); + + // gauge (still no Exemplar) + assertNoExemplar(metrics, "last_request_timestamp", "path", "/hello"); + assertNoExemplar(metrics, "last_request_timestamp", "path", "/god-of-fire"); + + // histogram + assertHistogramAfterMoreThenTenCalls(outers, inners); + + // summary: each call is 1ms slower than the previous one, up to 10ms, then we start again. + assertNoExemplar(metrics, "request_duration_summary", "path", "/hello", "quantile", "0.75"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/hello", "quantile", "0.85"); + assertNoExemplar(metrics, "request_duration_summary_count", "path", "/hello"); + assertNoExemplar(metrics, "request_duration_summary_sum", "path", "/hello"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/god-of-fire", "quantile", "0.75"); + assertNoExemplar(metrics, "request_duration_summary", "path", "/god-of-fire", "quantile", "0.85"); + assertNoExemplar(metrics, "request_duration_summary_count", "path", "/god-of-fire"); + assertNoExemplar(metrics, "request_duration_summary_sum", "path", "/god-of-fire"); + + // random unrelated metric + assertNoExemplar(metrics, "jvm_threads_current"); + } + + private void assertHistogramAfterMoreThenTenCalls(Map outers, Map inners) { + for (String outerKey : outers.keySet()) { + for (String innerKey : inners.keySet()) { + if (outerKey.equals(innerKey)) { + // same bucket == same trace, because the sample application simulates the same duration for both calls + Assert.assertEquals(outers.get(outerKey).traceId, inners.get(innerKey).traceId); + } else { + // different bucket -> different trace + Assert.assertNotEquals(outers.get(outerKey).traceId, inners.get(innerKey).traceId); + } + // span ids are unique + Assert.assertNotEquals(outers.get(outerKey).spanId, inners.get(innerKey).spanId); + } + } + } + + private void assertExemplar(SpanContext spanContext, List responseBody, String metricName, String... labels) { + String prefix = makeFullMetricName(metricName, labels); + for (String line : responseBody) { + if (line.startsWith(prefix)) { + String exemplarLabels = "# {span_id=\"" + spanContext.spanId + "\",trace_id=\"" + spanContext.traceId + "\"}"; + String message = prefix + " did not have the expected exemplar labels " + exemplarLabels + ":\n" + line; + Assert.assertTrue(message, line.contains(exemplarLabels)); + return; + } + } + Assert.fail(prefix + " metric not found"); + } + + private void assertNoExemplar(List responseBody, String metricName, String... labels) { + String prefix = makeFullMetricName(metricName, labels); + for (String line : responseBody) { + if (line.startsWith(prefix)) { + if (line.contains("trace_id")) { + Assert.fail("unexpected exemplars in metric:\n" + line); + } else { + return; + } + } + } + Assert.fail(prefix + " metric not found"); + } + + private void execute(Request request) throws IOException { + try (Response response = client.newCall(request).execute()) { + Assert.assertEquals("Hello, Prometheus!\n", response.body().string()); + } + } + + private static class SpanContext { + final String spanId; + final String traceId; + + private SpanContext(String spanId, String traceId) { + this.spanId = spanId; + this.traceId = traceId; + } + } + + private List scrapeMetrics() throws IOException { + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/metrics") + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .build(); + try (Response response = client.newCall(request).execute()) { + return Arrays.asList(response.body().string().split("\\n")); + } + } + + private SpanContext getSpanContext(List responseBody, String metricName, String... labels) { + String prefix = makeFullMetricName(metricName, labels); + Pattern pattern = Pattern.compile(".*span_id=\"([0-9a-f]+)\",trace_id=\"([0-9a-f]+).*"); + for (String line : responseBody) { + if (line.startsWith(prefix)) { + Matcher matcher = pattern.matcher(line); + Assert.assertTrue(prefix + " should have an exemplar", matcher.matches()); + return new SpanContext(matcher.group(1), matcher.group(2)); + } + } + Assert.fail(prefix + " not found"); + return null; + } + + // does not need to be perfect, it's ok if this works for the examples used in this test + private String makeFullMetricName(String metricName, String... labels) { + if (labels.length % 2 != 0) { + throw new IllegalArgumentException("labels must be a list of key/value pairs"); + } + if (labels.length == 0) { + return metricName; + } else { + StringBuilder result = new StringBuilder() + .append(metricName) + .append("{"); + for (int i = 0; i < labels.length; i += 2) { + if (i > 0) { + result.append(","); + } + result.append(labels[i]).append("=\"").append(labels[i + 1]).append("\""); + } + result.append("}"); + return result.toString(); + } + } +} diff --git a/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile b/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile new file mode 100644 index 000000000..ec91f5fb0 --- /dev/null +++ b/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile @@ -0,0 +1,10 @@ +FROM openjdk:11-jre +RUN mkdir -p /app/ +ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.2.0/opentelemetry-javaagent-all.jar /app/ +COPY sample-rest-application.jar /app/ +CMD java \ + -Dotel.traces.exporter=logging \ + -Dotel.metrics.exporter=none \ + -javaagent:/app/opentelemetry-javaagent-all.jar \ + -jar \ + /app/sample-rest-application.jar diff --git a/integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml b/integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/java_versions/pom.xml new file mode 100644 index 000000000..26b930d05 --- /dev/null +++ b/integration_tests/java_versions/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.10.1-SNAPSHOT + + + java_versions + Integration Test - Java Versions Smoke Test + + + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + 1.2.3 + test + + + com.squareup.okhttp3 + okhttp + 4.9.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + integration-test + integration-test + + integration-test + + + + verify + verify + + verify + + + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java new file mode 100644 index 000000000..2df4b34d0 --- /dev/null +++ b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java @@ -0,0 +1,101 @@ +package io.prometheus.client.smoketest; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Smoke test with different Java versions. + */ +@RunWith(Parameterized.class) +public class JavaVersionsIT { + + private final int port = 9000; + private final OkHttpClient client = new OkHttpClient(); + + @Rule + public JavaContainer javaContainer; + + public JavaVersionsIT(String baseImage) { + javaContainer = new JavaContainer(baseImage).withExposedPorts(port); + } + + @Parameterized.Parameters(name="{0}") + public static String[] images() { + return new String[] { + "openjdk:11-jre", + "openjdk:8-jre", + "ticketfly/java:6", + "ibmjava:8-jre", + }; + } + + @Test + public void testExampleMetric() { + List metrics = scrapeMetrics(TimeUnit.SECONDS.toMillis(10)); + System.out.println(javaContainer.getLogs()); + Assert.assertTrue("jvm_memory_bytes_used{area=\"heap\"} not found", metrics.stream() + .filter(m -> m.startsWith("jvm_memory_bytes_used{area=\"heap\"} ")) + .peek(System.out::println) + .findAny() + .isPresent()); + } + + private static class JavaContainer extends GenericContainer { + JavaContainer(String baseImage) { + super(new ImageFromDockerfile("prometheus-client-java-example-application") + .withDockerfileFromBuilder(builder -> + builder + .from(baseImage) + .run("mkdir /app") + .workDir("/app") + .copy("example_application.jar", "/app/") + .cmd("java -version && java -jar example_application.jar") + .build()) + .withFileFromPath("example_application.jar", + Paths.get("../example_application/target/example_application.jar"))); + } + } + + private List scrapeMetrics(long timeoutMillis) { + long start = System.currentTimeMillis(); + Exception exception = null; + String host = javaContainer.getHost(); + Integer mappedPort = javaContainer.getMappedPort(port); + String metricsUrl = "http://" + host + ":" + mappedPort + "/metrics"; + while (System.currentTimeMillis() - start < timeoutMillis) { + try { + Request request = new Request.Builder() + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .url(metricsUrl) + .build(); + try (Response response = client.newCall(request).execute()) { + return Arrays.asList(response.body().string().split("\\n")); + } + } catch (Exception e) { + exception = e; + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { + } + } + } + if (exception != null) { + exception.printStackTrace(); + } + Assert.fail("Timeout while getting metrics from " + metricsUrl + " (orig port: " + port + ")"); + return null; // will not happen + } +} diff --git a/integration_tests/java_versions/src/test/resources/logback-test.xml b/integration_tests/java_versions/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/java_versions/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml new file mode 100644 index 000000000..998c7ef6e --- /dev/null +++ b/integration_tests/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + io.prometheus + parent + 0.10.1-SNAPSHOT + + + integration_tests + pom + + Prometheus Java Suit - Integration Tests + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + exemplars_otel + exemplars_otel_agent + example_application + java_versions + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.22.2 + + + + + + + + org.testcontainers + testcontainers + 1.15.2 + test + + + + diff --git a/mvnw b/mvnw index 6ecc150ae..41c0f0c23 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -54,38 +54,16 @@ case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; esac if [ -z "$JAVA_HOME" ] ; then @@ -130,13 +108,12 @@ if $cygwin ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -187,14 +164,25 @@ CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround done echo "${basedir}" } @@ -206,7 +194,94 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java @@ -228,7 +303,6 @@ export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@ exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ diff --git a/mvnw.cmd b/mvnw.cmd index 8e2b7459f..86115719e 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,146 +1,182 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %* -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 23a8ec8c7..585ad30b3 100644 --- a/pom.xml +++ b/pom.xml @@ -61,9 +61,11 @@ simpleclient_spring_boot simpleclient_jetty simpleclient_jetty_jdk8 + simpleclient_tracer simpleclient_vertx simpleclient_bom benchmark + integration_tests diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index b2b118643..7ade134f7 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -34,16 +34,26 @@ - - - - - junit - junit - 4.13.2 - test - - + + + + io.prometheus + simpleclient_tracer_otel + ${project.version} + + + io.prometheus + simpleclient_tracer_otel_agent + ${project.version} + + + + junit + junit + 4.13.2 + test + + diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java index 327b9b01b..fd02a0c1a 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Collector.java +++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java @@ -1,6 +1,8 @@ package io.prometheus.client; +import io.prometheus.client.exemplars.Exemplar; + import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -60,7 +62,7 @@ public MetricFamilySamples(String name, String unit, Type type, String help, Lis if (name.equals(n)) { n = withTotal; } - mungedSamples.add(new Sample(n, s.labelNames, s.labelValues, s.value, s.timestampMs)); + mungedSamples.add(new Sample(n, s.labelNames, s.labelValues, s.value, s.exemplar, s.timestampMs)); } } this.name = name; @@ -113,18 +115,28 @@ public static class Sample { public final List labelNames; public final List labelValues; // Must have same length as labelNames. public final double value; + public final Exemplar exemplar; public final Long timestampMs; // It's an epoch format with milliseconds value included (this field is subject to change). - public Sample(String name, List labelNames, List labelValues, double value, Long timestampMs) { + public Sample(String name, List labelNames, List labelValues, double value, Exemplar exemplar, Long timestampMs) { this.name = name; this.labelNames = labelNames; this.labelValues = labelValues; this.value = value; + this.exemplar = exemplar; this.timestampMs = timestampMs; } + public Sample(String name, List labelNames, List labelValues, double value, Long timestampMs) { + this(name, labelNames, labelValues, value, null, timestampMs); + } + + public Sample(String name, List labelNames, List labelValues, double value, Exemplar exemplar) { + this(name, labelNames, labelValues, value, exemplar, null); + } + public Sample(String name, List labelNames, List labelValues, double value) { - this(name, labelNames, labelValues, value, null); + this(name, labelNames, labelValues, value, null, null); } @Override @@ -134,9 +146,12 @@ public boolean equals(Object obj) { } Sample other = (Sample) obj; - return other.name.equals(name) && other.labelNames.equals(labelNames) - && other.labelValues.equals(labelValues) && other.value == value - && ((timestampMs == null && other.timestampMs == null) || (other.timestampMs != null) && (other.timestampMs.equals(timestampMs))); + return other.name.equals(name) && + other.labelNames.equals(labelNames) && + other.labelValues.equals(labelValues) && + other.value == value && + (exemplar == null && other.exemplar == null || other.exemplar != null && other.exemplar.equals(exemplar)) && + (timestampMs == null && other.timestampMs == null || other.timestampMs != null && other.timestampMs.equals(timestampMs)); } @Override @@ -150,6 +165,9 @@ public int hashCode() { if (timestampMs != null) { hash = 37 * hash + timestampMs.hashCode(); } + if (exemplar != null) { + hash = 37 * exemplar.hashCode(); + } return hash; } diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java index bcff43eb2..35a21880c 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Counter.java +++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java @@ -1,9 +1,17 @@ package io.prometheus.client; +import io.prometheus.client.exemplars.CounterExemplarSampler; +import io.prometheus.client.exemplars.Exemplar; +import io.prometheus.client.exemplars.ExemplarConfig; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; /** * Counter metric, to track counts of events or running totals. @@ -73,33 +81,78 @@ */ public class Counter extends SimpleCollector implements Collector.Describable { + private final Boolean exemplarsEnabled; // null means default from ExemplarConfig applies + private final CounterExemplarSampler exemplarSampler; + Counter(Builder b) { super(b); + this.exemplarsEnabled = b.exemplarsEnabled; + this.exemplarSampler = b.exemplarSampler; + initializeNoLabelsChild(); } public static class Builder extends SimpleCollector.Builder { + + private Boolean exemplarsEnabled = null; + private CounterExemplarSampler exemplarSampler = null; + @Override public Counter create() { // Gracefully handle pre-OpenMetrics counters. if (name.endsWith("_total")) { name = name.substring(0, name.length() - 6); } + dontInitializeNoLabelsChild = true; return new Counter(this); } + + /** + * Enable exemplars and provide a custom {@link CounterExemplarSampler}. + */ + public Builder withExemplarSampler(CounterExemplarSampler exemplarSampler) { + if (exemplarSampler == null) { + throw new NullPointerException(); + } + this.exemplarSampler = exemplarSampler; + return withExemplars(); + } + + /** + * Allow this counter to load exemplars from a {@link CounterExemplarSampler}. + *

+ * If a specific exemplar sampler is configured for this counter that exemplar sampler is used + * (see {@link #withExemplarSampler(CounterExemplarSampler)}). + * Otherwise the default from {@link ExemplarConfig} is used. + */ + public Builder withExemplars() { + this.exemplarsEnabled = TRUE; + return this; + } + + /** + * Prevent this counter from loading exemplars from a {@link CounterExemplarSampler}. + *

+ * You can still provide exemplars for explicitly individual observations, e.g. using + * {@link #incWithExemplar(double, String...)}. + */ + public Builder withoutExemplars() { + this.exemplarsEnabled = FALSE; + return this; + } } /** - * Return a Builder to allow configuration of a new Counter. Ensures required fields are provided. + * Return a Builder to allow configuration of a new Counter. Ensures required fields are provided. * - * @param name The name of the metric - * @param help The help string of the metric + * @param name The name of the metric + * @param help The help string of the metric */ public static Builder build(String name, String help) { return new Builder().name(name).help(help); } /** - * Return a Builder to allow configuration of a new Counter. + * Return a Builder to allow configuration of a new Counter. */ public static Builder build() { return new Builder(); @@ -107,7 +160,7 @@ public static Builder build() { @Override protected Child newChild() { - return new Child(); + return new Child(exemplarsEnabled, exemplarSampler); } /** @@ -119,28 +172,119 @@ protected Child newChild() { public static class Child { private final DoubleAdder value = new DoubleAdder(); private final long created = System.currentTimeMillis(); + private final Boolean exemplarsEnabled; + private final CounterExemplarSampler exemplarSampler; + private final AtomicReference exemplar = new AtomicReference(); + + public Child(Boolean exemplarsEnabled, CounterExemplarSampler exemplarSampler) { + this.exemplarsEnabled = exemplarsEnabled; + this.exemplarSampler = exemplarSampler; + } + /** * Increment the counter by 1. */ public void inc() { inc(1); } + + /** + * Same as {@link #incWithExemplar(double, String...) incWithExemplar(1, exemplarLabels)}. + */ + public void incWithExemplar(String... exemplarLabels) { + incWithExemplar(1, exemplarLabels); + } + + /** + * Same as {@link #incWithExemplar(double, Map) incWithExemplar(1, exemplarLabels)}. + */ + public void incWithExemplar(Map exemplarLabels) { + incWithExemplar(1, exemplarLabels); + } + /** * Increment the counter by the given amount. + * * @throws IllegalArgumentException If amt is negative. */ public void inc(double amt) { + incWithExemplar(amt, (String[]) null); + } + + /** + * Like {@link #inc(double)}, but additionally creates an exemplar. + *

+ * This exemplar takes precedence over any exemplar returned by the {@link CounterExemplarSampler} configured + * in {@link ExemplarConfig}. + *

+ * The exemplar will have {@code amt} as the value, {@code System.currentTimeMillis()} as the timestamp, + * and the specified labels. + * + * @param amt same as in {@link #inc(double)} + * @param exemplarLabels list of name/value pairs, as documented in {@link Exemplar#Exemplar(double, String...)}. + * A commonly used name is {@code "trace_id"}. + * Calling {@code incWithExemplar(amt)} means that an exemplar without labels will be created. + * Calling {@code incWithExemplar(amt, (String[]) null)} is equivalent + * to calling {@code inc(amt)}. + */ + public void incWithExemplar(double amt, String... exemplarLabels) { + Exemplar exemplar = exemplarLabels == null ? null : new Exemplar(amt, System.currentTimeMillis(), exemplarLabels); if (amt < 0) { throw new IllegalArgumentException("Amount to increment must be non-negative."); } value.add(amt); + updateExemplar(amt, exemplar); } + + /** + * Same as {@link #incWithExemplar(double, String...)}, but the exemplar labels are passed as a {@link Map}. + */ + public void incWithExemplar(double amt, Map exemplarLabels) { + incWithExemplar(amt, Exemplar.mapToArray(exemplarLabels)); + } + + private void updateExemplar(double amt, Exemplar userProvidedExemplar) { + Exemplar prev, next; + do { + prev = exemplar.get(); + if (userProvidedExemplar == null) { + next = sampleNextExemplar(amt, prev); + } else { + next = userProvidedExemplar; + } + if (next == null || next == prev) { + return; + } + } while (!exemplar.compareAndSet(prev, next)); + } + + private Exemplar sampleNextExemplar(double amt, Exemplar prev) { + if (FALSE.equals(exemplarsEnabled)) { + return null; + } + if (exemplarSampler != null) { + return exemplarSampler.sample(amt, prev); + } + if (TRUE.equals(exemplarsEnabled) || ExemplarConfig.isExemplarsEnabled()) { + CounterExemplarSampler exemplarSampler = ExemplarConfig.getCounterExemplarSampler(); + if (exemplarSampler != null) { + return exemplarSampler.sample(amt, prev); + } + } + return null; + } + /** * Get the value of the counter. */ public double get() { return value.sum(); } + + private Exemplar getExemplar() { + return exemplar.get(); + } + /** * Get the created time of the counter in milliseconds. */ @@ -150,20 +294,51 @@ public long created() { } // Convenience methods. + /** * Increment the counter with no labels by 1. */ public void inc() { inc(1); } + + /** + * Like {@link Child#incWithExemplar(String...)}, but for the counter without labels. + */ + public void incWithExemplar(String... exemplarLabels) { + incWithExemplar(1, exemplarLabels); + } + + /** + * Like {@link Child#incWithExemplar(Map)}, but for the counter without labels. + */ + public void incWithExemplar(Map exemplarLabels) { + incWithExemplar(1, exemplarLabels); + } + /** * Increment the counter with no labels by the given amount. + * * @throws IllegalArgumentException If amt is negative. */ public void inc(double amt) { noLabelsChild.inc(amt); } - + + /** + * Like {@link Child#incWithExemplar(double, String...)}, but for the counter without labels. + */ + public void incWithExemplar(double amt, String... exemplarLabels) { + noLabelsChild.incWithExemplar(amt, exemplarLabels); + } + + /** + * Like {@link Child#incWithExemplar(double, Map)}, but for the counter without labels. + */ + public void incWithExemplar(double amt, Map exemplarLabels) { + noLabelsChild.incWithExemplar(amt, exemplarLabels); + } + /** * Get the value of the counter. */ @@ -175,7 +350,7 @@ public double get() { public List collect() { List samples = new ArrayList(children.size()); for(Map.Entry, Child> c: children.entrySet()) { - samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get())); + samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get(), c.getValue().getExemplar())); samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0)); } return familySamplesList(Type.COUNTER, samples); diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index 8ab7790ba..11335473e 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -1,11 +1,19 @@ package io.prometheus.client; +import io.prometheus.client.exemplars.Exemplar; +import io.prometheus.client.exemplars.ExemplarConfig; +import io.prometheus.client.exemplars.HistogramExemplarSampler; + import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; /** * Histogram metric, to track distributions of events. @@ -62,15 +70,22 @@ */ public class Histogram extends SimpleCollector implements Collector.Describable { private final double[] buckets; + private final Boolean exemplarsEnabled; // null means default from ExemplarConfig applies + private final HistogramExemplarSampler exemplarSampler; Histogram(Builder b) { super(b); + this.exemplarsEnabled = b.exemplarsEnabled; + this.exemplarSampler = b.exemplarSampler; buckets = b.buckets; initializeNoLabelsChild(); } public static class Builder extends SimpleCollector.Builder { - private double[] buckets = new double[]{.005, .01, .025, .05, .075, .1, .25, .5, .75, 1, 2.5, 5, 7.5, 10}; + + private Boolean exemplarsEnabled = null; + private HistogramExemplarSampler exemplarSampler = null; + private double[] buckets = new double[] { .005, .01, .025, .05, .075, .1, .25, .5, .75, 1, 2.5, 5, 7.5, 10 }; @Override public Histogram create() { @@ -81,11 +96,11 @@ public Histogram create() { } } if (buckets.length == 0) { - throw new IllegalStateException("Histogram must have at least one bucket."); + throw new IllegalStateException("Histogram must have at least one bucket."); } - for (String label: labelNames) { + for (String label : labelNames) { if (label.equals("le")) { - throw new IllegalStateException("Histogram cannot have a label named 'le'."); + throw new IllegalStateException("Histogram cannot have a label named 'le'."); } } @@ -101,26 +116,27 @@ public Histogram create() { } /** - * Set the upper bounds of buckets for the histogram. - */ + * Set the upper bounds of buckets for the histogram. + */ public Builder buckets(double... buckets) { this.buckets = buckets; return this; } /** - * Set the upper bounds of buckets for the histogram with a linear sequence. - */ + * Set the upper bounds of buckets for the histogram with a linear sequence. + */ public Builder linearBuckets(double start, double width, int count) { buckets = new double[count]; - for (int i = 0; i < count; i++){ - buckets[i] = start + i*width; + for (int i = 0; i < count; i++) { + buckets[i] = start + i * width; } return this; } + /** - * Set the upper bounds of buckets for the histogram with an exponential sequence. - */ + * Set the upper bounds of buckets for the histogram with an exponential sequence. + */ public Builder exponentialBuckets(double start, double factor, int count) { buckets = new double[count]; for (int i = 0; i < count; i++) { @@ -129,20 +145,53 @@ public Builder exponentialBuckets(double start, double factor, int count) { return this; } + /** + * Enable exemplars and provide a custom {@link HistogramExemplarSampler}. + */ + public Builder withExemplarSampler(HistogramExemplarSampler exemplarSampler) { + if (exemplarSampler == null) { + throw new NullPointerException(); + } + this.exemplarSampler = exemplarSampler; + return withExemplars(); + } + + /** + * Allow this histogram to load exemplars from a {@link HistogramExemplarSampler}. + *

+ * If a specific exemplar sampler is configured for this histogram that exemplar sampler is used + * (see {@link #withExemplarSampler(HistogramExemplarSampler)}). + * Otherwise the default from {@link ExemplarConfig} is used. + */ + public Builder withExemplars() { + this.exemplarsEnabled = TRUE; + return this; + } + + /** + * Prevent this histogram from loading exemplars from a {@link HistogramExemplarSampler}. + *

+ * You can still provide exemplars for explicitly individual observations, e.g. using + * {@link #observeWithExemplar(double, String...)}. + */ + public Builder withoutExemplars() { + this.exemplarsEnabled = FALSE; + return this; + } } /** - * Return a Builder to allow configuration of a new Histogram. Ensures required fields are provided. + * Return a Builder to allow configuration of a new Histogram. Ensures required fields are provided. * - * @param name The name of the metric - * @param help The help string of the metric + * @param name The name of the metric + * @param help The help string of the metric */ public static Builder build(String name, String help) { return new Builder().name(name).help(help); } /** - * Return a Builder to allow configuration of a new Histogram. + * Return a Builder to allow configuration of a new Histogram. */ public static Builder build() { return new Builder(); @@ -150,7 +199,7 @@ public static Builder build() { @Override protected Child newChild() { - return new Child(buckets); + return new Child(buckets, exemplarsEnabled, exemplarSampler); } /** @@ -159,18 +208,29 @@ protected Child newChild() { public static class Timer implements Closeable { private final Child child; private final long start; + private Timer(Child child, long start) { this.child = child; this.start = start; } + /** * Observe the amount of time in seconds since {@link Child#startTimer} was called. + * * @return Measured duration in seconds since {@link Child#startTimer} was called. */ public double observeDuration() { - double elapsed = SimpleTimer.elapsedSecondsFromNanos(start, SimpleTimer.defaultTimeProvider.nanoTime()); - child.observe(elapsed); - return elapsed; + return observeDurationWithExemplar((String[]) null); + } + + public double observeDurationWithExemplar(String... exemplarLabels) { + double elapsed = SimpleTimer.elapsedSecondsFromNanos(start, SimpleTimer.defaultTimeProvider.nanoTime()); + child.observeWithExemplar(elapsed, exemplarLabels); + return elapsed; + } + + public double observeDurationWithExemplar(Map exemplarLabels) { + return observeDurationWithExemplar(Exemplar.mapToArray(exemplarLabels)); } /** @@ -197,17 +257,35 @@ public static class Child { * @return Measured duration in seconds for timeable to complete. */ public double time(Runnable timeable) { + return timeWithExemplar(timeable, (String[]) null); + } + + /** + * Like {@link #time(Runnable)}, but additionally create an exemplar. + *

+ * See {@link #observeWithExemplar(double, String...)} for documentation on the {@code exemplarLabels} parameter. + */ + public double timeWithExemplar(Runnable timeable, String... exemplarLabels) { Timer timer = startTimer(); double elapsed; try { timeable.run(); } finally { - elapsed = timer.observeDuration(); + elapsed = timer.observeDurationWithExemplar(exemplarLabels); } return elapsed; } + /** + * Like {@link #time(Runnable)}, but additionally create an exemplar. + *

+ * See {@link #observeWithExemplar(double, Map)} for documentation on the {@code exemplarLabels} parameter. + */ + public double timeWithExemplar(Runnable timeable, Map exemplarLabels) { + return timeWithExemplar(timeable, Exemplar.mapToArray(exemplarLabels)); + } + /** * Executes callable code (e.g. a Java 8 Lambda) and observes a duration of how long it took to run. * @@ -215,6 +293,15 @@ public double time(Runnable timeable) { * @return Result returned by callable. */ public E time(Callable timeable) { + return timeWithExemplar(timeable, (String[]) null); + } + + /** + * Like {@link #time(Callable)}, but additionally create an exemplar. + *

+ * See {@link #observeWithExemplar(double, String...)} for documentation on the {@code exemplarLabels} parameter. + */ + public E timeWithExemplar(Callable timeable, String... exemplarLabels) { Timer timer = startTimer(); try { @@ -224,52 +311,135 @@ public E time(Callable timeable) { } catch (Exception e) { throw new RuntimeException(e); } finally { - timer.observeDuration(); + timer.observeDurationWithExemplar(exemplarLabels); } } + /** + * Like {@link #time(Callable)}, but additionally create an exemplar. + *

+ * See {@link #observeWithExemplar(double, Map)} for documentation on the {@code exemplarLabels} parameter. + */ + public E timeWithExemplar(Callable timeable, Map exemplarLabels) { + return timeWithExemplar(timeable, Exemplar.mapToArray(exemplarLabels)); + } + public static class Value { public final double sum; public final double[] buckets; + public final Exemplar[] exemplars; public final long created; - public Value(double sum, double[] buckets, long created) { + public Value(double sum, double[] buckets, Exemplar[] exemplars, long created) { this.sum = sum; this.buckets = buckets; + this.exemplars = exemplars; this.created = created; } } - private Child(double[] buckets) { + private Child(double[] buckets, Boolean exemplarsEnabled, HistogramExemplarSampler exemplarSampler) { upperBounds = buckets; + this.exemplarsEnabled = exemplarsEnabled; + this.exemplarSampler = exemplarSampler; + exemplars = new ArrayList>(buckets.length); cumulativeCounts = new DoubleAdder[buckets.length]; for (int i = 0; i < buckets.length; ++i) { cumulativeCounts[i] = new DoubleAdder(); + exemplars.add(new AtomicReference()); } } + + private final ArrayList> exemplars; + private final Boolean exemplarsEnabled; + private final HistogramExemplarSampler exemplarSampler; private final double[] upperBounds; private final DoubleAdder[] cumulativeCounts; private final DoubleAdder sum = new DoubleAdder(); private final long created = System.currentTimeMillis(); - /** * Observe the given amount. + * * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for * implications and alternatives. */ public void observe(double amt) { + observeWithExemplar(amt, (String[]) null); + } + + /** + * Like {@link #observe(double)}, but additionally creates an exemplar. + *

+ * This exemplar takes precedence over any exemplar returned by the {@link HistogramExemplarSampler} configured + * in {@link ExemplarConfig}. + *

+ * The exemplar will have {@code amt} as the value, {@code System.currentTimeMillis()} as the timestamp, + * and the specified labels. + * + * @param amt same as in {@link #observe(double)} (double)} + * @param exemplarLabels list of name/value pairs, as documented in {@link Exemplar#Exemplar(double, String...)}. + * A commonly used name is {@code "trace_id"}. + * Calling {@code observeWithExemplar(amt)} means that an exemplar without labels is created. + * Calling {@code observeWithExemplar(amt, (String[]) null)} is equivalent + * to calling {@code observe(amt)}. + */ + public void observeWithExemplar(double amt, String... exemplarLabels) { + Exemplar exemplar = exemplarLabels == null ? null : new Exemplar(amt, System.currentTimeMillis(), exemplarLabels); for (int i = 0; i < upperBounds.length; ++i) { // The last bucket is +Inf, so we always increment. if (amt <= upperBounds[i]) { cumulativeCounts[i].add(1); + updateExemplar(amt, i, exemplar); break; } } sum.add(amt); } + + /** + * Like {@link #observeWithExemplar(double, String...)}, but the exemplar labels are passed as a {@link Map}. + */ + public void observeWithExemplar(double amt, Map exemplarLabels) { + observeWithExemplar(amt, Exemplar.mapToArray(exemplarLabels)); + } + + private void updateExemplar(double amt, int i, Exemplar userProvidedExemplar) { + AtomicReference exemplar = exemplars.get(i); + double bucketFrom = i == 0 ? Double.NEGATIVE_INFINITY : upperBounds[i - 1]; + double bucketTo = upperBounds[i]; + Exemplar prev, next; + do { + prev = exemplar.get(); + if (userProvidedExemplar != null) { + next = userProvidedExemplar; + } else { + next = sampleNextExemplar(amt, bucketFrom, bucketTo, prev); + } + if (next == null || next == prev) { + return; + } + } while (!exemplar.compareAndSet(prev, next)); + } + + private Exemplar sampleNextExemplar(double amt, double bucketFrom, double bucketTo, Exemplar prev) { + if (FALSE.equals(exemplarsEnabled)) { + return null; + } + if (exemplarSampler != null) { + return exemplarSampler.sample(amt, bucketFrom, bucketTo, prev); + } + if (TRUE.equals(exemplarsEnabled) || ExemplarConfig.isExemplarsEnabled()) { + HistogramExemplarSampler exemplarSampler = ExemplarConfig.getHistogramExemplarSampler(); + if (exemplarSampler != null) { + return exemplarSampler.sample(amt, bucketFrom, bucketTo, prev); + } + } + return null; + } + /** * Start a timer to track a duration. *

@@ -278,6 +448,7 @@ public void observe(double amt) { public Timer startTimer() { return new Timer(this, SimpleTimer.defaultTimeProvider.nanoTime()); } + /** * Get the value of the Histogram. *

@@ -285,18 +456,22 @@ public Timer startTimer() { */ public Value get() { double[] buckets = new double[cumulativeCounts.length]; + Exemplar[] exemplars = new Exemplar[cumulativeCounts.length]; double acc = 0; for (int i = 0; i < cumulativeCounts.length; ++i) { acc += cumulativeCounts[i].sum(); buckets[i] = acc; + exemplars[i] = this.exemplars.get(i).get(); } - return new Value(sum.sum(), buckets, created); + return new Value(sum.sum(), buckets, exemplars, created); } } // Convenience methods. + /** * Observe the given amount on the histogram with no labels. + * * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for @@ -305,6 +480,21 @@ public Value get() { public void observe(double amt) { noLabelsChild.observe(amt); } + + /** + * Like {@link Child#observeWithExemplar(double, String...)}, but for the histogram without labels. + */ + public void observeWithExemplar(double amt, String... exemplarLabels) { + noLabelsChild.observeWithExemplar(amt, exemplarLabels); + } + + /** + * Like {@link Child#observeWithExemplar(double, Map)}, but for the histogram without labels. + */ + public void observeWithExemplar(double amt, Map exemplarLabels) { + noLabelsChild.observeWithExemplar(amt, exemplarLabels); + } + /** * Start a timer to track a duration on the histogram with no labels. *

@@ -320,31 +510,67 @@ public Timer startTimer() { * @param timeable Code that is being timed * @return Measured duration in seconds for timeable to complete. */ - public double time(Runnable timeable){ + public double time(Runnable timeable) { return noLabelsChild.time(timeable); } + /** + * Like {@link #time(Runnable)}, but additionally create an exemplar. + *

+ * See {@link Child#observeWithExemplar(double, String...)} for documentation on the {@code exemplarLabels} parameter. + */ + public double timeWithExemplar(Runnable timeable, String... exemplarLabels) { + return noLabelsChild.timeWithExemplar(timeable, exemplarLabels); + } + + /** + * Like {@link #time(Runnable)}, but additionally create an exemplar. + *

+ * See {@link Child#observeWithExemplar(double, Map)} for documentation on the {@code exemplarLabels} parameter. + */ + public double timeWithExemplar(Runnable timeable, Map exemplarLabels) { + return noLabelsChild.timeWithExemplar(timeable, exemplarLabels); + } + /** * Executes callable code (e.g. a Java 8 Lambda) and observes a duration of how long it took to run. * * @param timeable Code that is being timed * @return Result returned by callable. */ - public E time(Callable timeable){ + public E time(Callable timeable) { return noLabelsChild.time(timeable); } + /** + * Like {@link #time(Callable)}, but additionally create an exemplar. + *

+ * See {@link Child#observeWithExemplar(double, String...)} for documentation on the {@code exemplarLabels} parameter. + */ + public E timeWithExemplar(Callable timeable, String... exemplarLabels) { + return noLabelsChild.timeWithExemplar(timeable, exemplarLabels); + } + + /** + * Like {@link #time(Callable)}, but additionally create an exemplar. + *

+ * See {@link Child#observeWithExemplar(double, Map)} for documentation on the {@code exemplarLabels} parameter. + */ + public E timeWithExemplar(Callable timeable, Map exemplarLabels) { + return noLabelsChild.timeWithExemplar(timeable, exemplarLabels); + } + @Override public List collect() { List samples = new ArrayList(); - for(Map.Entry, Child> c: children.entrySet()) { + for (Map.Entry, Child> c : children.entrySet()) { Child.Value v = c.getValue().get(); List labelNamesWithLe = new ArrayList(labelNames); labelNamesWithLe.add("le"); for (int i = 0; i < v.buckets.length; ++i) { List labelValuesWithLe = new ArrayList(c.getKey()); labelValuesWithLe.add(doubleToGoString(buckets[i])); - samples.add(new MetricFamilySamples.Sample(fullname + "_bucket", labelNamesWithLe, labelValuesWithLe, v.buckets[i])); + samples.add(new MetricFamilySamples.Sample(fullname + "_bucket", labelNamesWithLe, labelValuesWithLe, v.buckets[i], v.exemplars[i])); } samples.add(new MetricFamilySamples.Sample(fullname + "_count", labelNames, c.getKey(), v.buckets[buckets.length-1])); samples.add(new MetricFamilySamples.Sample(fullname + "_sum", labelNames, c.getKey(), v.sum)); @@ -357,12 +583,10 @@ public List collect() { @Override public List describe() { return Collections.singletonList( - new MetricFamilySamples(fullname, Type.HISTOGRAM, help, Collections.emptyList())); + new MetricFamilySamples(fullname, Type.HISTOGRAM, help, Collections.emptyList())); } double[] getBuckets() { return buckets; } - - -} +} \ No newline at end of file diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java new file mode 100644 index 000000000..81ab4e9d4 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java @@ -0,0 +1,15 @@ +package io.prometheus.client.exemplars; + +/** + * Exemplar sampler for counter metrics. + */ +public interface CounterExemplarSampler { + + /** + * @param increment the value added to the counter on this event + * @param previous the previously sampled exemplar, or {@code null} if there is none. + * @return an Exemplar to be sampled, or {@code null} if the previous exemplar does not need to be updated. + * Returning {@code null} and returning {@code previous} is equivalent. + */ + Exemplar sample(double increment, Exemplar previous); +} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java new file mode 100644 index 000000000..f57fd86c4 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java @@ -0,0 +1,65 @@ +package io.prometheus.client.exemplars; + +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; + +/** + * Default Exemplar sampler. + *

+ * Keeps each Exemplar for a minimum of ~7 seconds, then samples a new one. + */ +public class DefaultExemplarSampler implements ExemplarSampler { + + private static final String SPAN_ID = "span_id"; + private static final String TRACE_ID = "trace_id"; + + private final SpanContextSupplier spanContextSupplier; + // Choosing a prime number for the retention interval makes behavior more predictable, + // because it is unlikely that retention happens at the exact same time as a Prometheus scrape. + private final long minRetentionIntervalMs = 7109; + private final Clock clock; + + public DefaultExemplarSampler(SpanContextSupplier spanContextSupplier) { + this.spanContextSupplier = spanContextSupplier; + this.clock = new SystemClock(); + } + + // for unit tests only + DefaultExemplarSampler(SpanContextSupplier spanContextSupplier, Clock clock) { + this.spanContextSupplier = spanContextSupplier; + this.clock = clock; + } + + @Override + public Exemplar sample(double increment, Exemplar previous) { + return doSample(increment, previous); + } + + @Override + public Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous) { + return doSample(value, previous); + } + + private Exemplar doSample(double value, Exemplar previous) { + long timestampMs = clock.currentTimeMillis(); + if (previous == null || previous.getTimestampMs() == null + || timestampMs - previous.getTimestampMs() > minRetentionIntervalMs) { + String spanId = spanContextSupplier.getSpanId(); + String traceId = spanContextSupplier.getTraceId(); + if (traceId != null && spanId != null) { + return new Exemplar(value, timestampMs, SPAN_ID, spanId, TRACE_ID, traceId); + } + } + return null; + } + + interface Clock { + long currentTimeMillis(); + } + + static class SystemClock implements Clock { + @Override + public long currentTimeMillis() { + return System.currentTimeMillis(); + } + } +} \ No newline at end of file diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java new file mode 100644 index 000000000..899ac2990 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java @@ -0,0 +1,185 @@ +package io.prometheus.client.exemplars; + +import java.util.Arrays; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Immutable data class holding an Exemplar. + */ +public class Exemplar { + + private final String[] labels; + private final double value; + private final Long timestampMs; + + private static final Pattern labelNameRegex = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*"); + + /** + * Create an Exemplar without a timestamp + * + * @param value the observed value + * @param labels name/value pairs. Expecting an even number of strings. The combined length of the label names and + * values must not exceed 128 UTF-8 characters. Neither a label name nor a label value may be null. + */ + public Exemplar(double value, String... labels) { + this(value, null, labels); + } + + /** + * Create an Exemplar + * + * @param value the observed value + * @param timestampMs as in {@link System#currentTimeMillis()} + * @param labels name/value pairs. Expecting an even number of strings. The combined length of the + * label names and values must not exceed 128 UTF-8 characters. Neither a label name + * nor a label value may be null. + */ + public Exemplar(double value, Long timestampMs, String... labels) { + this.labels = sortedCopy(labels); + this.value = value; + this.timestampMs = timestampMs; + } + + /** + * Create an Exemplar + * + * @param value the observed value + * @param labels the labels. Must not be null. The combined length of the label names and values must not exceed + * 128 UTF-8 characters. Neither a label name nor a label value may be null. + */ + public Exemplar(double value, Map labels) { + this(value, null, mapToArray(labels)); + } + + /** + * Create an Exemplar + * + * @param value the observed value + * @param timestampMs as in {@link System#currentTimeMillis()} + * @param labels the labels. Must not be null. The combined length of the label names and values must not exceed + * 128 UTF-8 characters. Neither a label name nor a label value may be null. + */ + public Exemplar(double value, Long timestampMs, Map labels) { + this(value, timestampMs, mapToArray(labels)); + } + + public int getNumberOfLabels() { + return labels.length / 2; + } + + /** + * Get the label name at index {@code i}. + * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. + * @return the label name at index {@code i} + */ + public String getLabelName(int i) { + return labels[2 * i]; + } + + /** + * Get the label value at index {@code i}. + * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. + * @return the label value at index {@code i} + */ + public String getLabelValue(int i) { + return labels[2 * i + 1]; + } + + public double getValue() { + return value; + } + + /** + * @return Unix timestamp or {@code null} if no timestamp is present. + */ + public Long getTimestampMs() { + return timestampMs; + } + + private String[] sortedCopy(String... labels) { + if (labels.length % 2 != 0) { + throw new IllegalArgumentException("labels are name/value pairs, expecting an even number"); + } + String[] result = new String[labels.length]; + int charsTotal = 0; + for (int i = 0; i < labels.length; i+=2) { + if (labels[i] == null) { + throw new IllegalArgumentException("labels[" + i + "] is null"); + } + if (labels[i+1] == null) { + throw new IllegalArgumentException("labels[" + (i+1) + "] is null"); + } + if (!labelNameRegex.matcher(labels[i]).matches()) { + throw new IllegalArgumentException(labels[i] + " is not a valid label name"); + } + result[i] = labels[i]; // name + result[i+1] = labels[i+1]; // value + charsTotal += labels[i].length() + labels[i+1].length(); + // Move the current tuple down while the previous name is greater than current name. + for (int j=i-2; j>=0; j-=2) { + int compareResult = result[j+2].compareTo(result[j]); + if (compareResult == 0) { + throw new IllegalArgumentException(result[j] + ": label name is not unique"); + } else if (compareResult < 0) { + String tmp = result[j]; + result[j] = result[j+2]; + result[j+2] = tmp; + tmp = result[j+1]; + result[j+1] = result[j+3]; + result[j+3] = tmp; + } else { + break; + } + } + } + if (charsTotal > 128) { + throw new IllegalArgumentException( + "the combined length of the label names and values must not exceed 128 UTF-8 characters"); + } + return result; + } + + /** + * Convert the map to an array {@code [key1, value1, key2, value2, ...]}. + */ + public static String[] mapToArray(Map labelMap) { + if (labelMap == null) { + return null; + } + String[] result = new String[2 * labelMap.size()]; + int i = 0; + for (Map.Entry entry : labelMap.entrySet()) { + result[i] = entry.getKey(); + result[i + 1] = entry.getValue(); + i += 2; + } + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Exemplar)) { + return false; + } + Exemplar other = (Exemplar) obj; + return Arrays.equals(this.labels, other.labels) && + Double.compare(other.value, value) == 0 && + (timestampMs == null && other.timestampMs == null + || timestampMs != null && timestampMs.equals(other.timestampMs)); + } + + @Override + public int hashCode() { + int hash = Arrays.hashCode(labels); + long d = Double.doubleToLongBits(value); + hash = 37 * hash + (int) (d ^ (d >>> 32)); + if (timestampMs != null) { + hash = 37 * hash + timestampMs.intValue(); + } + return hash; + } +} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java new file mode 100644 index 000000000..aa2fdeb29 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java @@ -0,0 +1,76 @@ +package io.prometheus.client.exemplars; + +/** + * Static configuration for Exemplar behavior. + */ +public class ExemplarConfig { + + private static volatile boolean enabled = true; + private static volatile HistogramExemplarSampler histogramExemplarSampler; + private static volatile CounterExemplarSampler counterExemplarSampler; + + static { + ExemplarSampler defaultExemplarSampler = new Tracer().initExemplarSampler(); + counterExemplarSampler = defaultExemplarSampler; + histogramExemplarSampler = defaultExemplarSampler; + } + + /** + * Set the default exemplar sampler for Counters. + */ + public static void setCounterExemplarSampler(CounterExemplarSampler counterExemplarSampler) { + ExemplarConfig.counterExemplarSampler = counterExemplarSampler; + } + + /** + * Set the default exemplar sampler for Histograms. + */ + public static void setHistogramExemplarSampler(HistogramExemplarSampler histogramExemplarSampler) { + ExemplarConfig.histogramExemplarSampler = histogramExemplarSampler; + } + + /** + * Prevent metrics from loading exemplars from an {@link ExemplarSampler} by default. + *

+ * You can still enable individual metrics to load exemplars from an {@link ExemplarSampler} by calling the + * metric builder's {@code withExemplars()} method, and you can still provide single exemplars explicitly + * for individual observations with the {@code ...withExemplar()} methods. + */ + public static void disableExemplars() { + enabled = false; + } + + /** + * Allow metrics to load exemplars from an {@link ExemplarSampler} by default. + *

+ * You can still disallow individual metrics to load exemplars from an {@link ExemplarSampler} by calling + * the metric builder's {@code withoutExemplars()} method. + *

+ * Exemplars are enabled by default. This method is here so that you can temporarily {@link #disableExemplars()} + * and then {@link #enableExemplars()} again. + */ + public static void enableExemplars() { + enabled = true; + } + + /** + * @return the {@link CounterExemplarSampler} that is used by default in {@code Counter} metrics. + */ + public static CounterExemplarSampler getCounterExemplarSampler() { + return counterExemplarSampler; + } + + /** + * @return the {@link HistogramExemplarSampler} that is used by default in {@code Histogram} metrics. + */ + public static HistogramExemplarSampler getHistogramExemplarSampler() { + return histogramExemplarSampler; + } + + /** + * @return true by default, false if {@link #disableExemplars()} was called. + */ + public static boolean isExemplarsEnabled() { + return enabled; + } +} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java new file mode 100644 index 000000000..39ff34c26 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java @@ -0,0 +1,8 @@ +package io.prometheus.client.exemplars; + +/** + * For convenience, an interface for implementing both, + * the {@link CounterExemplarSampler} and the {@link HistogramExemplarSampler}. + */ +public interface ExemplarSampler extends CounterExemplarSampler, HistogramExemplarSampler { +} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java new file mode 100644 index 000000000..03d300112 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java @@ -0,0 +1,18 @@ +package io.prometheus.client.exemplars; + +/** + * Exemplar sampler for histogram metrics. + */ +public interface HistogramExemplarSampler { + /** + * @param value the value to be observed. + * @param bucketFrom upper boundary of the previous bucket in the histogram. + * Will be {@link Double#NEGATIVE_INFINITY} if there is no previous bucket. + * @param bucketTo upper boundary of this histogram bucket. + * Will be {@link Double#POSITIVE_INFINITY} if this is the last bucket. + * @param previous the previously sampled exemplar, or {@code null} if there is none. + * @return an Exemplar to be sampled, or {@code null} if the previous exemplar does not need to be updated. + * Returning {@code null} and returning {@code previous} is equivalent. + */ + Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous); +} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java new file mode 100644 index 000000000..97ec4f41f --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java @@ -0,0 +1,44 @@ +package io.prometheus.client.exemplars; + +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; +import io.prometheus.client.exemplars.tracer.otel.OpenTelemetrySpanContextSupplier; +import io.prometheus.client.exemplars.tracer.otel_agent.OpenTelemetryAgentSpanContextSupplier; + +class Tracer { + + ExemplarSampler initExemplarSampler() { + try { + Object spanContextSupplier = findSpanContextSupplier(); + if (spanContextSupplier != null) { + return new DefaultExemplarSampler((SpanContextSupplier) spanContextSupplier); + } + } catch (NoClassDefFoundError ignored) { + // simpleclient_tracer_common dependency not found + } + return null; + } + + // Avoid SpanContextSupplier in the method signature so that we can handle the NoClassDefFoundError + // even if the user excluded simpleclient_tracer_common from the classpath. + private Object findSpanContextSupplier() { + try { + if (OpenTelemetrySpanContextSupplier.isAvailable()) { + return new OpenTelemetrySpanContextSupplier(); + } + } catch (NoClassDefFoundError ignored) { + // tracer_otel dependency not found + } catch (UnsupportedClassVersionError ignored) { + // OpenTelemetry requires Java 8, but client_java might run on Java 6. + } + try { + if (OpenTelemetryAgentSpanContextSupplier.isAvailable()) { + return new OpenTelemetryAgentSpanContextSupplier(); + } + } catch (NoClassDefFoundError ignored) { + // tracer_otel_agent dependency not found + } catch (UnsupportedClassVersionError ignored) { + // OpenTelemetry requires Java 8, but client_java might run on Java 6. + } + return null; + } +} diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java index 67840594e..dbf611322 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.junit.Test; diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java index 2d7ba0735..01f17170f 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CounterTest.java @@ -4,14 +4,17 @@ import static org.junit.rules.ExpectedException.none; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import io.prometheus.client.exemplars.Exemplar; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.Before; import org.junit.rules.ExpectedException; - public class CounterTest { CollectorRegistry registry; Counter noLabels, labels; @@ -104,4 +107,50 @@ public void testCollect() { assertEquals(mfsFixture, mfs.get(0)); } + @Test + public void testExemplars() { + Map labels = new HashMap(); + labels.put("mapKey1", "mapValue1"); + labels.put("mapKey2", "mapValue2"); + + noLabels.incWithExemplar("key", "value"); + assertExemplar(noLabels, 1, "key", "value"); + + noLabels.incWithExemplar(); + assertExemplar(noLabels, 1); + + noLabels.incWithExemplar(labels); + assertExemplar(noLabels, 1, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + noLabels.incWithExemplar(2, "key1", "value1", "key2", "value2"); + assertExemplar(noLabels, 2, "key1", "value1", "key2", "value2"); + + noLabels.incWithExemplar(3); + assertExemplar(noLabels, 3); + + noLabels.incWithExemplar(4, new HashMap()); + assertExemplar(noLabels, 4); + + noLabels.incWithExemplar(5, labels); + assertExemplar(noLabels, 5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + noLabels.inc(); // should not alter the exemplar + assertExemplar(noLabels, 5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + noLabels.incWithExemplar(5, (String[]) null); // should not alter the exemplar + assertExemplar(noLabels, 5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + noLabels.incWithExemplar(5, (Map) null); // should not alter the exemplar + assertExemplar(noLabels, 5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + } + + private void assertExemplar(Counter counter, double value, String... labels) { + List mfs = counter.collect(); + Exemplar exemplar = mfs.get(0).samples.get(0).exemplar; + Assert.assertEquals(value, exemplar.getValue(), 0.001); + Assert.assertEquals(labels.length/2, exemplar.getNumberOfLabels()); + for (int i=0; i labels = new HashMap(); + labels.put("mapKey1", "mapValue1"); + labels.put("mapKey2", "mapValue2"); + + noLabels.observeWithExemplar(0.5, "key", "value"); + assertExemplar(noLabels, 0.5, "key", "value"); + + noLabels.observeWithExemplar(0.5); + assertExemplar(noLabels, 0.5); + + noLabels.observeWithExemplar(0.5, labels); + assertExemplar(noLabels, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + // default buckets are {.005, .01, .025, .05, .075, .1, .25, .5, .75, 1, 2.5, 5, 7.5, 10} + noLabels.observeWithExemplar(2.0, "key1", "value1", "key2", "value2"); + assertExemplar(noLabels, 2.0, "key1", "value1", "key2", "value2"); + assertExemplar(noLabels, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + noLabels.observeWithExemplar(0.4, new HashMap()); // same bucket as 0.5 + assertNoExemplar(noLabels, 0.5); + assertExemplar(noLabels, 0.4); + assertExemplar(noLabels, 2.0, "key1", "value1", "key2", "value2"); + + noLabels.observeWithExemplar(2.0, (String[]) null); // should not alter the exemplar + assertExemplar(noLabels, 2.0, "key1", "value1", "key2", "value2"); + + noLabels.observeWithExemplar(2.0, (Map) null); // should not alter the exemplar + assertExemplar(noLabels, 2.0, "key1", "value1", "key2", "value2"); + } + + @Test + public void testTimeWithExemplar() { + Map labels = new HashMap(); + labels.put("mapKey1", "mapValue1"); + labels.put("mapKey2", "mapValue2"); + + noLabels.timeWithExemplar(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(15); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + assertExemplar(noLabels, 0.015); + + noLabels.timeWithExemplar(new Callable() { + @Override + public Object call() throws Exception { + Thread.sleep(20); + return null; + } + }, labels); + assertNoExemplar(noLabels, 0.015); + assertExemplar(noLabels, 0.02,"mapKey1", "mapValue1", "mapKey2", "mapValue2"); + } + + private void assertExemplar(Histogram histogram, double value, String... labels) { + List mfs = histogram.collect(); + double lowerBound; + double upperBound = Double.NEGATIVE_INFINITY; + for (Sample bucket : mfs.get(0).samples) { + if (!bucket.name.endsWith("_bucket")) { + continue; + } + lowerBound = upperBound; + if ("+Inf".equals(findLabelValue(bucket, "le"))) { + upperBound = Double.POSITIVE_INFINITY; + } else { + upperBound = Double.parseDouble(findLabelValue(bucket, "le")); + } + if (lowerBound < value && value <= upperBound) { + Assert.assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", bucket.exemplar); + Assert.assertEquals(value, bucket.exemplar.getValue(), 0.001); + Assert.assertEquals(labels.length/2, bucket.exemplar.getNumberOfLabels()); + for (int i=0; i mfs = histogram.collect(); + double lowerBound; + double upperBound = Double.NEGATIVE_INFINITY; + for (Sample bucket : mfs.get(0).samples) { + if (!bucket.name.endsWith("_bucket")) { + continue; + } + lowerBound = upperBound; + if ("+Inf".equals(findLabelValue(bucket, "le"))) { + upperBound = Double.POSITIVE_INFINITY; + } else { + upperBound = Double.parseDouble(findLabelValue(bucket, "le")); + } + if (lowerBound < value && value <= upperBound) { + if (bucket.exemplar != null) { + Assert.assertNotEquals("expecting no exemplar with value " + value, value, bucket.exemplar.getValue(), 0.001); + } + } + } + } + + private String findLabelValue(Sample sample, String labelName) { + for (int i = 0; i < sample.labelNames.size(); i++) { + if (sample.labelNames.get(i).equals(labelName)) { + return sample.labelValues.get(i); + } + } + throw new AssertionError("label " + labelName + " not found in " + sample); + } + @Test public void testCollect() { labels.labels("a").observe(2); List mfs = labels.collect(); - ArrayList samples = new ArrayList(); + ArrayList samples = new ArrayList(); ArrayList labelNames = new ArrayList(); labelNames.add("l"); ArrayList labelValues = new ArrayList(); @@ -233,16 +357,16 @@ public void testCollect() { for (String bucket: new String[]{"0.005", "0.01", "0.025", "0.05", "0.075", "0.1", "0.25", "0.5", "0.75", "1.0"}) { ArrayList labelValuesLe = new ArrayList(labelValues); labelValuesLe.add(bucket); - samples.add(new Collector.MetricFamilySamples.Sample("labels_bucket", labelNamesLe, labelValuesLe, 0.0)); + samples.add(new Sample("labels_bucket", labelNamesLe, labelValuesLe, 0.0)); } for (String bucket: new String[]{"2.5", "5.0", "7.5", "10.0", "+Inf"}) { ArrayList labelValuesLe = new ArrayList(labelValues); labelValuesLe.add(bucket); - samples.add(new Collector.MetricFamilySamples.Sample("labels_bucket", labelNamesLe, labelValuesLe, 1.0)); + samples.add(new Sample("labels_bucket", labelNamesLe, labelValuesLe, 1.0)); } - samples.add(new Collector.MetricFamilySamples.Sample("labels_count", labelNames, labelValues, 1.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_sum", labelNames, labelValues, 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_created", labelNames, labelValues, labels.labels("a").get().created / 1000.0)); + samples.add(new Sample("labels_count", labelNames, labelValues, 1.0)); + samples.add(new Sample("labels_sum", labelNames, labelValues, 2.0)); + samples.add(new Sample("labels_created", labelNames, labelValues, labels.labels("a").get().created / 1000.0)); Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.HISTOGRAM, "help", samples); diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java new file mode 100644 index 000000000..8936e6e5f --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java @@ -0,0 +1,91 @@ +package io.prometheus.client.exemplars; + +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +import static java.lang.Double.NEGATIVE_INFINITY; +import static java.lang.Double.POSITIVE_INFINITY; + +public class DefaultExemplarSamplerTest { + + private static final String SPAN_ID = "span_id"; + private static final String TRACE_ID = "trace_id"; + + final AtomicReference traceId = new AtomicReference(); + final AtomicReference spanId = new AtomicReference(); + final AtomicLong timestamp = new AtomicLong(); + DefaultExemplarSampler defaultSampler; + + final SpanContextSupplier testContext = new SpanContextSupplier() { + @Override + public String getTraceId() { + return traceId.get(); + } + + @Override + public String getSpanId() { + return spanId.get(); + } + }; + + final DefaultExemplarSampler.Clock testClock = new DefaultExemplarSampler.Clock() { + @Override + public long currentTimeMillis() { + return timestamp.get(); + } + }; + + @Before + public void setUp() { + traceId.set("trace-1"); + spanId.set("span-1"); + timestamp.set(System.currentTimeMillis()); + defaultSampler = new DefaultExemplarSampler(testContext, testClock); + } + + @Test + public void testCounter() { + CounterExemplarSampler sampler = defaultSampler; + Exemplar first = new Exemplar(2.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertEquals(first, sampler.sample(2.0, null)); + traceId.set("trace-2"); + spanId.set("span-2"); + timestamp.getAndAdd(100); // 100ms later + Exemplar second = new Exemplar(3.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertNull(sampler.sample(3.0, first)); // no new exemplar yet + Assert.assertEquals(second, sampler.sample(3.0, null)); + timestamp.getAndAdd(10 * 1000); // 10s later + traceId.set("trace-3"); + spanId.set("span-3"); + Exemplar third = new Exemplar(4.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertEquals(third, sampler.sample(4.0, second)); + traceId.set(null); + Assert.assertNull(sampler.sample(4.0, null)); + } + + @Test + public void testHistogram() { + HistogramExemplarSampler sampler = defaultSampler; + // Almost identical to Counter and Gauge, except that the value is passed directly and not via valueHolder. + Exemplar first = new Exemplar(2.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertEquals(first, sampler.sample(2.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, null)); + traceId.set("trace-2"); + spanId.set("span-2"); + timestamp.getAndAdd(100); // 100ms later + Exemplar second = new Exemplar(3.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertNull(sampler.sample(3.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, first)); // no new exemplar yet + Assert.assertEquals(second, sampler.sample(3.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, null)); + timestamp.getAndAdd(10 * 1000); // 10s later + traceId.set("trace-3"); + spanId.set("span-3"); + Exemplar third = new Exemplar(4.0, timestamp.get(), TRACE_ID, traceId.get(), SPAN_ID, spanId.get()); + Assert.assertEquals(third, sampler.sample(4.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, second)); + traceId.set(null); + Assert.assertNull(sampler.sample(4.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, null)); + } +} diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java new file mode 100644 index 000000000..0d197bac0 --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java @@ -0,0 +1,178 @@ +package io.prometheus.client.exemplars; + +import io.prometheus.client.Counter; +import io.prometheus.client.Histogram; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ExemplarConfigTest { + + private boolean origEnabled; + private CounterExemplarSampler origCounterExemplarSampler; + private HistogramExemplarSampler origHistogramExemplarSampler; + + private TestExemplarSampler defaultSampler; + private TestExemplarSampler customSampler; + + @Before + public void setUp() { + origEnabled = ExemplarConfig.isExemplarsEnabled(); + origCounterExemplarSampler = ExemplarConfig.getCounterExemplarSampler(); + origHistogramExemplarSampler = ExemplarConfig.getHistogramExemplarSampler(); + + defaultSampler = new TestExemplarSampler(); + customSampler = new TestExemplarSampler(); + ExemplarConfig.enableExemplars(); + ExemplarConfig.setCounterExemplarSampler(defaultSampler); + ExemplarConfig.setHistogramExemplarSampler(defaultSampler); + } + + @After + public void tearDown() { + ExemplarConfig.setCounterExemplarSampler(origCounterExemplarSampler); + ExemplarConfig.setHistogramExemplarSampler(origHistogramExemplarSampler); + if (origEnabled) { + ExemplarConfig.enableExemplars(); + } else { + ExemplarConfig.disableExemplars(); + } + } + + private static class TestExemplarSampler implements ExemplarSampler { + + private boolean called = false; + + @Override + public Exemplar sample(double increment, Exemplar previous) { + called = true; + return null; + } + + @Override + public Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous) { + called = true; + return null; + } + } + + @Test + public void testCounterWithExemplarSampler() { + Counter counter = Counter.build() + .withExemplarSampler(customSampler) + .name("test") + .help("help") + .create(); + counter.inc(3); + Assert.assertTrue(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testCounterWithoutExemplars() { + Counter counter = Counter.build() + .withoutExemplars() + .name("test") + .help("help") + .create(); + counter.inc(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testCounterWithExemplars() { + ExemplarConfig.disableExemplars(); + Counter counter = Counter.build() + .withExemplars() + .name("test") + .help("help") + .create(); + counter.inc(3); + Assert.assertFalse(customSampler.called); + Assert.assertTrue(defaultSampler.called); + } + + @Test + public void testCounterDefaultDisabled() { + ExemplarConfig.disableExemplars(); + Counter counter = Counter.build() + .name("test") + .help("help") + .create(); + counter.inc(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testCounterIncWithExemplar() { + Counter counter = Counter.build() + .name("test") + .help("help") + .create(); + counter.incWithExemplar(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testHistogramWithExemplarSampler() { + Histogram histogram = Histogram.build() + .withExemplarSampler(customSampler) + .name("test") + .help("help") + .create(); + histogram.observe(3); + Assert.assertTrue(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testHistogramWithoutExemplars() { + Histogram histogram = Histogram.build() + .withoutExemplars() + .name("test") + .help("help") + .create(); + histogram.observe(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + + @Test + public void testHistogramWithExemplars() { + ExemplarConfig.disableExemplars(); + Histogram histogram = Histogram.build() + .withExemplars() + .name("test") + .help("help") + .create(); + histogram.observe(3); + Assert.assertFalse(customSampler.called); + Assert.assertTrue(defaultSampler.called); + } + + @Test + public void testHistogramDefaultDisabled() { + ExemplarConfig.disableExemplars(); + Histogram histogram = Histogram.build() + .name("test") + .help("help") + .create(); + histogram.observe(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } + @Test + public void testHistogramObserveWithExemplar() { + Histogram histogram = Histogram.build() + .name("test") + .help("help") + .create(); + histogram.observeWithExemplar(3); + Assert.assertFalse(customSampler.called); + Assert.assertFalse(defaultSampler.called); + } +} diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java new file mode 100644 index 000000000..a7960aa8a --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java @@ -0,0 +1,186 @@ +package io.prometheus.client.exemplars; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +public class ExemplarTest { + + private final String SPAN_ID = "span_id"; + private final String TRACE_ID = "trace_id"; + + @Test + public void testCompleteExemplar() { + double value = 42; + long timestamp = System.currentTimeMillis(); + String traceId = "abc"; + String spanId = "def"; + Exemplar exemplar = new Exemplar(value, timestamp, SPAN_ID, spanId, TRACE_ID, traceId); + Assert.assertEquals(42, exemplar.getValue(), 0.001); + Assert.assertEquals(timestamp, exemplar.getTimestampMs().longValue()); + Assert.assertEquals(2, exemplar.getNumberOfLabels()); + Assert.assertEquals(SPAN_ID, exemplar.getLabelName(0)); + Assert.assertEquals(spanId, exemplar.getLabelValue(0)); + Assert.assertEquals(TRACE_ID, exemplar.getLabelName(1)); + Assert.assertEquals(traceId, exemplar.getLabelValue(1)); + } + + @Test + public void testNoTimestamp() { + double value = 42; + String traceId = "abc"; + String spanId = "def"; + Exemplar exemplar = new Exemplar(value, SPAN_ID, spanId, TRACE_ID, traceId); + Assert.assertEquals(42, exemplar.getValue(), 0.001); + Assert.assertNull(exemplar.getTimestampMs()); + Assert.assertEquals(2, exemplar.getNumberOfLabels()); + Assert.assertEquals(SPAN_ID, exemplar.getLabelName(0)); + Assert.assertEquals(spanId, exemplar.getLabelValue(0)); + Assert.assertEquals(TRACE_ID, exemplar.getLabelName(1)); + Assert.assertEquals(traceId, exemplar.getLabelValue(1)); + } + + @Test + public void testNoLabels() { + double value = 42; + long timestamp = System.currentTimeMillis(); + Exemplar exemplar = new Exemplar(value, timestamp); + Assert.assertEquals(42, exemplar.getValue(), 0.001); + Assert.assertEquals(timestamp, exemplar.getTimestampMs().longValue()); + Assert.assertEquals(0, exemplar.getNumberOfLabels()); + } + + @Test + public void testMissingLabelValue() { + try { + new Exemplar(42, TRACE_ID); + } catch (IllegalArgumentException e) { + return; + } + Assert.fail("expected IllegalArgumentException"); + } + + @Test + public void testNullLabelValue() { + try { + new Exemplar(42, TRACE_ID, null); + } catch (IllegalArgumentException e) { + return; + } + Assert.fail("expected IllegalArgumentException"); + } + + @Test + public void testMaxLabelLength() { + String eight = "_2345678"; + String ten = "_234567890"; + String twenty = ten + ten; + String thirty = twenty + ten; + String forty = thirty + ten; + new Exemplar(42, ten, twenty, thirty, forty, eight, twenty); // 128 chars total + try { + new Exemplar(42, ten, twenty, thirty, forty, eight, twenty + "1"); // 129 chars total + } catch (IllegalArgumentException e) { + return; + } + Assert.fail("expected IllegalArgumentException"); + } + + @Test + public void testSortedLabels() { + Exemplar exemplar = new Exemplar(42, "name4", "value4", "name3", "value3", + "name2", "value2", "name5", "value5", "name1", "value1"); + Assert.assertEquals(5, exemplar.getNumberOfLabels()); + for (int i=0; i map = new TreeMap(); + map.put("label1", "value1"); + map.put("label2", "value2"); + Exemplar e = new Exemplar(3, map); + Assert.assertEquals(3, e.getValue(), 0.001); + Assert.assertNull(e.getTimestampMs()); + Assert.assertEquals(2, e.getNumberOfLabels()); + Assert.assertEquals("label1", e.getLabelName(0)); + Assert.assertEquals("value1", e.getLabelValue(0)); + Assert.assertEquals("label2", e.getLabelName(1)); + Assert.assertEquals("value2", e.getLabelValue(1)); + } + + @Test + public void testEmptyLabelMap() { + Map map = new HashMap(); + long timestamp = System.currentTimeMillis(); + Exemplar e = new Exemplar(3, timestamp, map); + Assert.assertEquals(3, e.getValue(), 0.001); + Assert.assertEquals(timestamp, e.getTimestampMs().longValue()); + Assert.assertEquals(0, e.getNumberOfLabels()); + } +} diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index 13d065ed6..69fa8d6d2 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -1,11 +1,11 @@ package io.prometheus.client.exporter.common; import java.io.IOException; +import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; -import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -241,18 +241,25 @@ public static void writeOpenMetrics100(Writer writer, Enumeration 0) { + writer.write(","); + } + writer.write(sample.exemplar.getLabelName(i)); + writer.write("=\""); + writeEscapedLabelValue(writer, sample.exemplar.getLabelValue(i)); + writer.write("\""); } - if (ms < 10) { - writer.write("0"); + writer.write("} "); + writer.write(Collector.doubleToGoString(sample.exemplar.getValue())); + if (sample.exemplar.getTimestampMs() != null) { + writer.write(' '); + omWriteTimestamp(writer, sample.exemplar.getTimestampMs()); } - writer.write(Long.toString(ts % 1000)); - } writer.write('\n'); } @@ -260,6 +267,19 @@ public static void writeOpenMetrics100(Writer writer, Enumeration + + 4.0.0 + + + io.prometheus + parent + 0.10.1-SNAPSHOT + + + simpleclient_tracer + pom + + Prometheus Java Span Context Supplier - Parent + + + + + io.opentelemetry + opentelemetry-api + 1.0.1 + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + simpleclient_tracer_common + simpleclient_tracer_otel + simpleclient_tracer_otel_agent + + + diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml new file mode 100644 index 000000000..26a305ecc --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + + io.prometheus + simpleclient_tracer + 0.10.1-SNAPSHOT + + + simpleclient_tracer_common + Prometheus Java Span Context Supplier - Common + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java new file mode 100644 index 000000000..ce068323e --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java @@ -0,0 +1,14 @@ +package io.prometheus.client.exemplars.tracer.common; + +public interface SpanContextSupplier { + + /** + * @return the current trace id, or {@code null} if this call is not happening within a span context. + */ + String getTraceId(); + + /** + * @return the current span id, or {@code null} if this call is not happening within a span context. + */ + String getSpanId(); +} \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml new file mode 100644 index 000000000..c9bd0ebae --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + + io.prometheus + simpleclient_tracer + 0.10.1-SNAPSHOT + + + simpleclient_tracer_otel + Prometheus Java Span Context Supplier - OpenTelemetry + + + + io.prometheus + simpleclient_tracer_common + ${project.version} + + + io.opentelemetry + opentelemetry-api + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java new file mode 100644 index 000000000..1d298e522 --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java @@ -0,0 +1,39 @@ +package io.prometheus.client.exemplars.tracer.otel; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; + +public class OpenTelemetrySpanContextSupplier implements SpanContextSupplier { + + public static boolean isAvailable() { + try { + if ("inactive".equalsIgnoreCase(System.getProperties().getProperty("io.prometheus.otelExemplars"))) { + return false; + } + OpenTelemetrySpanContextSupplier test = new OpenTelemetrySpanContextSupplier(); + test.getSpanId(); + test.getTraceId(); + return true; + } catch (LinkageError ignored) { + // NoClassDefFoundError: + // Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist. + // IncompatibleClassChangeError: + // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface. + return false; + } + } + + @Override + public String getTraceId() { + String traceId = Span.current().getSpanContext().getTraceId(); + return TraceId.isValid(traceId) ? traceId : null; + } + + @Override + public String getSpanId() { + String spanId = Span.current().getSpanContext().getSpanId(); + return SpanId.isValid(spanId) ? spanId : null; + } +} diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml new file mode 100644 index 000000000..d3a6b67ac --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + io.prometheus + simpleclient_tracer + 0.10.1-SNAPSHOT + + + simpleclient_tracer_otel_agent + Prometheus Java Span Context Supplier - OpenTelemetry Agent + + + + io.prometheus + simpleclient_tracer_common + ${project.version} + + + io.opentelemetry + opentelemetry-api + provided + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + io.opentelemetry.api + io.opentelemetry.javaagent.shaded.io.opentelemetry.api + + + + + io.prometheus:simpleclient_tracer_common + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java new file mode 100644 index 000000000..dca7c8488 --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java @@ -0,0 +1,44 @@ +package io.prometheus.client.exemplars.tracer.otel_agent; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; + +/** + * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}. + * However, the {@code io.opentelemetry.api} package is relocated to + * {@code io.opentelemetry.javaagent.shaded.io.opentelemetry.api} in the OpenTelemetry agent. + */ +public class OpenTelemetryAgentSpanContextSupplier implements SpanContextSupplier { + + public static boolean isAvailable() { + try { + if ("inactive".equalsIgnoreCase(System.getProperties().getProperty("io.prometheus.otelExemplars"))) { + return false; + } + OpenTelemetryAgentSpanContextSupplier test = new OpenTelemetryAgentSpanContextSupplier(); + test.getSpanId(); + test.getTraceId(); + return true; + } catch (LinkageError ignored) { + // NoClassDefFoundError: + // Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist. + // IncompatibleClassChangeError: + // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface. + return false; + } + } + + @Override + public String getTraceId() { + String traceId = Span.current().getSpanContext().getTraceId(); + return TraceId.isValid(traceId) ? traceId : null; + } + + @Override + public String getSpanId() { + String spanId = Span.current().getSpanContext().getSpanId(); + return SpanId.isValid(spanId) ? spanId : null; + } +} From d216b3f5ee03a901405be44deb3ac3d1d20c9447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 24 May 2021 21:53:04 +0200 Subject: [PATCH 067/980] fix flaky JettyStatisticsCollectorTest --- .circleci/config.yml | 1 + .../client/jetty/JettyStatisticsCollectorTest.java | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d5e2c0a76..c1190b988 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,6 +9,7 @@ jobs: - checkout - restore_cache: key: maven-dependencies-{{ checksum "pom.xml" }} + - run: java -version - run: ./mvnw clean verify - save_cache: paths: diff --git a/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java b/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java index 80969c2c8..dcf6b8c7c 100644 --- a/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java +++ b/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java @@ -61,7 +61,15 @@ public void collect() throws Exception { } assertThat(CollectorRegistry.defaultRegistry.getSampleValue("jetty_requests_total"), is(1.0)); - assertThat(CollectorRegistry.defaultRegistry.getSampleValue("jetty_requests_active"), is(0.0)); + Double jettyRequestsActive = null; + for (int i=0; i<10; i++) { + jettyRequestsActive = CollectorRegistry.defaultRegistry.getSampleValue("jetty_requests_active"); + if (Double.valueOf(0.0).equals(jettyRequestsActive)) { + break; + } + Thread.sleep(50); + } + assertThat(jettyRequestsActive, is(0.0)); assertThat(CollectorRegistry.defaultRegistry.getSampleValue("jetty_requests_active_max"), is(1.0)); assertThat(CollectorRegistry.defaultRegistry.getSampleValue("jetty_request_time_max_seconds"), From 7c2fc3e8841bfb67bc94b26bbe8a3aa387ab5696 Mon Sep 17 00:00:00 2001 From: Bernd Ahlers Date: Tue, 25 May 2021 18:34:05 +0200 Subject: [PATCH 068/980] Make HTTPMetricHandler class public This makes the HTTPMetricHandler reusable to allow custom HTTPServer implementations. Fixes #529 Signed-off-by: Bernd Ahlers --- .../src/main/java/io/prometheus/client/exporter/HTTPServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index 20455df74..d6afdcd69 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -58,7 +58,7 @@ protected ByteArrayOutputStream initialValue() /** * Handles Metrics collections from the given registry. */ - static class HTTPMetricHandler implements HttpHandler { + public static class HTTPMetricHandler implements HttpHandler { private final CollectorRegistry registry; private final LocalByteArray response = new LocalByteArray(); private final static String HEALTHY_RESPONSE = "Exporter is Healthy."; From ac3e086ff17b13caf933c788919a14edc4b86c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 27 May 2021 22:18:09 +0200 Subject: [PATCH 069/980] fix invalid JavaDoc --- .circleci/config.yml | 3 ++- .../src/main/java/io/prometheus/client/Histogram.java | 4 ++-- simpleclient/src/main/java/io/prometheus/client/Summary.java | 4 ++-- .../prometheus/client/exemplars/DefaultExemplarSampler.java | 2 +- .../main/java/io/prometheus/client/exemplars/Exemplar.java | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c1190b988..a49761689 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,8 @@ jobs: - restore_cache: key: maven-dependencies-{{ checksum "pom.xml" }} - run: java -version - - run: ./mvnw clean verify + - run: ./mvnw clean install + - run: ./mvnw javadoc:jar - save_cache: paths: - ~/.m2 diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index 11335473e..e0491579e 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -361,7 +361,7 @@ private Child(double[] buckets, Boolean exemplarsEnabled, HistogramExemplarSampl /** * Observe the given amount. * - * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for * implications and alternatives. @@ -472,7 +472,7 @@ public Value get() { /** * Observe the given amount on the histogram with no labels. * - * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for * implications and alternatives. diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index 3b911c134..34b123ba0 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -278,7 +278,7 @@ private Child(List quantiles, long maxAgeSeconds, int ageBuckets) { /** * Observe the given amount. - * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for * implications and alternatives. @@ -311,7 +311,7 @@ public Value get() { // Convenience methods. /** * Observe the given amount on the summary with no labels. - * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read + * @param amt in most cases amt should be >= 0. Negative values are supported, but you should read * * https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations for * implications and alternatives. diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java index f57fd86c4..759055cb9 100644 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java @@ -4,7 +4,7 @@ /** * Default Exemplar sampler. - *

+ *

* Keeps each Exemplar for a minimum of ~7 seconds, then samples a new one. */ public class DefaultExemplarSampler implements ExemplarSampler { diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java index 899ac2990..6e1cee36f 100644 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java @@ -70,7 +70,7 @@ public int getNumberOfLabels() { /** * Get the label name at index {@code i}. - * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. + * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. * @return the label name at index {@code i} */ public String getLabelName(int i) { @@ -79,7 +79,7 @@ public String getLabelName(int i) { /** * Get the label value at index {@code i}. - * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. + * @param i the index, must be >= 0 and < {@link #getNumberOfLabels()}. * @return the label value at index {@code i} */ public String getLabelValue(int i) { From e81e17a6e167b21ce48f632c886a4fe27e8711e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 27 May 2021 23:23:11 +0200 Subject: [PATCH 070/980] add Maven plugin version for reproducible builds --- benchmark/pom.xml | 1 - integration_tests/example_application/pom.xml | 1 - integration_tests/exemplars_otel/pom.xml | 2 - integration_tests/pom.xml | 1 - pom.xml | 109 +++++++++++++++--- .../simpleclient_tracer_otel/pom.xml | 1 - .../simpleclient_tracer_otel_agent/pom.xml | 2 - 7 files changed, 95 insertions(+), 22 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 0726e3486..c70ff6f09 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -56,7 +56,6 @@ org.apache.maven.plugins maven-shade-plugin - 2.2 package diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index 431a64579..9c3f4d28e 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -36,7 +36,6 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 package diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index 7b168f1ed..e2283c3d9 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -68,7 +68,6 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.22.2 integration-test @@ -89,7 +88,6 @@ org.apache.maven.plugins maven-dependency-plugin - 3.1.2 copy-dependencies diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 998c7ef6e..5644fcb17 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -34,7 +34,6 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.22.2 diff --git a/pom.xml b/pom.xml index 585ad30b3..c0d241b5c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,12 +7,6 @@ parent 0.10.1-SNAPSHOT - - org.sonatype.oss - oss-parent - 7 - - Prometheus Java Suite http://github.com/prometheus/client_java @@ -84,11 +78,105 @@ + + + + + + maven-install-plugin + 2.4 + + + maven-deploy-plugin + 2.7 + + + maven-resources-plugin + 2.6 + + + maven-compiler-plugin + 3.1 + + + maven-surefire-plugin + 2.12.4 + + + maven-jar-plugin + 2.4 + + + maven-deploy-plugin + 2.7 + + + maven-clean-plugin + 2.5 + + + maven-site-plugin + 3.3 + + + + maven-shade-plugin + 3.2.4 + + + maven-failsafe-plugin + 2.22.2 + + + maven-release-plugin + 2.5.3 + + + maven-dependency-plugin + 3.1.2 + + + maven-javadoc-plugin + 3.3.0 + + + maven-gpg-plugin + 3.0.1 + + + maven-source-plugin + 3.2.1 + + + maven-enforcer-plugin + 1.4.1 + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-plugin-versions + + enforce + + + + + org.springframework.boot:spring-boot-maven-plugin + + + + + + + maven-release-plugin org.apache.maven.plugins - 2.5 true false @@ -99,7 +187,6 @@ maven-deploy-plugin org.apache.maven.plugins - 2.7 org.apache.felix @@ -110,12 +197,10 @@ org.apache.maven.plugins maven-surefire-plugin - 2.15 org.apache.maven.plugins maven-javadoc-plugin - 2.8 UTF-8 UTF-8 @@ -136,7 +221,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 1.6 1.6 @@ -153,7 +237,6 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 sign-artifacts @@ -167,7 +250,6 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 attach-sources @@ -180,7 +262,6 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 attach-javadocs diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index c9bd0ebae..210959448 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -30,7 +30,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 1.8 1.8 diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index d3a6b67ac..5c2104ad3 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -30,7 +30,6 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 package @@ -56,7 +55,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 1.8 1.8 From 5452faeeade1a732c37eaa4faa6a5ea973d50c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 29 May 2021 23:09:03 +0200 Subject: [PATCH 071/980] test more Java versions --- .../prometheus/client/smoketest/Server.java | 7 +++++ .../client/smoketest/JavaVersionsIT.java | 27 ++++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java b/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java index 73ab219f1..1a5f481f0 100644 --- a/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java +++ b/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java @@ -1,5 +1,6 @@ package io.prometheus.client.smoketest; +import io.prometheus.client.Counter; import io.prometheus.client.exporter.HTTPServer; import io.prometheus.client.hotspot.DefaultExports; @@ -12,6 +13,12 @@ public class Server { public static void main(String[] args) throws IOException, InterruptedException { DefaultExports.initialize(); + Counter counter = Counter.build() + .name("test") + .help("test counter") + .labelNames("path") + .register(); + counter.labels("/hello-world").inc(); new HTTPServer(9000); Thread.currentThread().join(); // sleep forever } diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java index 2df4b34d0..b9d3da3f5 100644 --- a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java +++ b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java @@ -35,22 +35,35 @@ public JavaVersionsIT(String baseImage) { @Parameterized.Parameters(name="{0}") public static String[] images() { return new String[] { - "openjdk:11-jre", + + // HotSpot "openjdk:8-jre", + "openjdk:11-jre", "ticketfly/java:6", + "adoptopenjdk/openjdk16:ubi-minimal-jre", + + // OpenJ9 "ibmjava:8-jre", + "adoptopenjdk/openjdk11-openj9", }; } + private final List exampleMetrics = Arrays.asList( + "test_total{path=\"/hello-world\"}", + "jvm_memory_bytes_used{area=\"heap\"}" + ); + @Test - public void testExampleMetric() { + public void testExampleMetrics() { List metrics = scrapeMetrics(TimeUnit.SECONDS.toMillis(10)); System.out.println(javaContainer.getLogs()); - Assert.assertTrue("jvm_memory_bytes_used{area=\"heap\"} not found", metrics.stream() - .filter(m -> m.startsWith("jvm_memory_bytes_used{area=\"heap\"} ")) - .peek(System.out::println) - .findAny() - .isPresent()); + for (String metric : exampleMetrics) { + Assert.assertTrue(metric + " not found", metrics.stream() + .filter(m -> m.startsWith(metric + " ")) + .peek(System.out::println) + .findAny() + .isPresent()); + } } private static class JavaContainer extends GenericContainer { From 17b552c225392e3331319bced40f83e2eb7ea597 Mon Sep 17 00:00:00 2001 From: Rainer Jung Date: Thu, 6 May 2021 13:56:05 +0200 Subject: [PATCH 072/980] Add "jvm_memory_pool_collection_bytes_xxx" providing access to MemoryPoolMXBean.getCollectionUsage() Signed-off-by: Rainer Jung --- .../client/hotspot/MemoryPoolsExports.java | 35 ++++++++++ .../hotspot/MemoryPoolsExportsTest.java | 68 +++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index 50f46fb4d..73bceed62 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -102,6 +102,26 @@ void addMemoryPoolMetrics(List sampleFamilies) { "Initial bytes of a given JVM memory pool.", Collections.singletonList("pool")); sampleFamilies.add(init); + GaugeMetricFamily collectionUsed = new GaugeMetricFamily( + "jvm_memory_pool_collection_bytes_used", + "Used bytes after last collection of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionUsed); + GaugeMetricFamily collectionCommitted = new GaugeMetricFamily( + "jvm_memory_pool_collection_bytes_committed", + "Committed after last collection bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionCommitted); + GaugeMetricFamily collectionMax = new GaugeMetricFamily( + "jvm_memory_pool_collection_bytes_max", + "Max bytes after last collection of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionMax); + GaugeMetricFamily collectionInit = new GaugeMetricFamily( + "jvm_memory_pool_collection_bytes_init", + "Initial after last collection bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionInit); for (final MemoryPoolMXBean pool : poolBeans) { MemoryUsage poolUsage = pool.getUsage(); used.addMetric( @@ -116,6 +136,21 @@ void addMemoryPoolMetrics(List sampleFamilies) { init.addMetric( Collections.singletonList(pool.getName()), poolUsage.getInit()); + MemoryUsage collectionPoolUsage = pool.getCollectionUsage(); + if (collectionPoolUsage != null) { + collectionUsed.addMetric( + Collections.singletonList(pool.getName()), + collectionPoolUsage.getUsed()); + collectionCommitted.addMetric( + Collections.singletonList(pool.getName()), + collectionPoolUsage.getCommitted()); + collectionMax.addMetric( + Collections.singletonList(pool.getName()), + collectionPoolUsage.getMax()); + collectionInit.addMetric( + Collections.singletonList(pool.getName()), + collectionPoolUsage.getInit()); + } } } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java index 23467b1e7..de8c06aae 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java @@ -20,7 +20,9 @@ public class MemoryPoolsExportsTest { private MemoryPoolMXBean mockPoolsBean2 = Mockito.mock(MemoryPoolMXBean.class); private MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); private MemoryUsage mockUsage1 = Mockito.mock(MemoryUsage.class); + private MemoryUsage mockCollectionUsage1 = Mockito.mock(MemoryUsage.class); private MemoryUsage mockUsage2 = Mockito.mock(MemoryUsage.class); + private MemoryUsage mockCollectionUsage2 = Mockito.mock(MemoryUsage.class); private List mockList = Arrays.asList(mockPoolsBean1, mockPoolsBean2); private CollectorRegistry registry = new CollectorRegistry(); private MemoryPoolsExports collectorUnderTest; @@ -29,18 +31,28 @@ public class MemoryPoolsExportsTest { public void setUp() { when(mockPoolsBean1.getName()).thenReturn("PS Eden Space"); when(mockPoolsBean1.getUsage()).thenReturn(mockUsage1); + when(mockPoolsBean1.getCollectionUsage()).thenReturn(mockCollectionUsage1); when(mockPoolsBean2.getName()).thenReturn("PS Old Gen"); when(mockPoolsBean2.getUsage()).thenReturn(mockUsage2); + when(mockPoolsBean2.getCollectionUsage()).thenReturn(mockCollectionUsage2); when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(mockUsage1); when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(mockUsage2); when(mockUsage1.getUsed()).thenReturn(500000L); when(mockUsage1.getCommitted()).thenReturn(1000000L); when(mockUsage1.getMax()).thenReturn(2000000L); when(mockUsage1.getInit()).thenReturn(1000L); + when(mockCollectionUsage1.getUsed()).thenReturn(400000L); + when(mockCollectionUsage1.getCommitted()).thenReturn(800000L); + when(mockCollectionUsage1.getMax()).thenReturn(1600000L); + when(mockCollectionUsage1.getInit()).thenReturn(2000L); when(mockUsage2.getUsed()).thenReturn(10000L); when(mockUsage2.getCommitted()).thenReturn(20000L); when(mockUsage2.getMax()).thenReturn(3000000L); when(mockUsage2.getInit()).thenReturn(2000L); + when(mockCollectionUsage2.getUsed()).thenReturn(20000L); + when(mockCollectionUsage2.getCommitted()).thenReturn(40000L); + when(mockCollectionUsage2.getMax()).thenReturn(6000000L); + when(mockCollectionUsage2.getInit()).thenReturn(4000L); collectorUnderTest = new MemoryPoolsExports(mockMemoryBean, mockList).register(registry); } @@ -74,6 +86,34 @@ public void testMemoryPools() { new String[]{"pool"}, new String[]{"PS Eden Space"}), .0000001); + assertEquals( + 400000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_used", + new String[]{"pool"}, + new String[]{"PS Eden Space"}), + .0000001); + assertEquals( + 800000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_committed", + new String[]{"pool"}, + new String[]{"PS Eden Space"}), + .0000001); + assertEquals( + 1600000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_max", + new String[]{"pool"}, + new String[]{"PS Eden Space"}), + .0000001); + assertEquals( + 2000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_init", + new String[]{"pool"}, + new String[]{"PS Eden Space"}), + .0000001); assertEquals( 10000L, registry.getSampleValue( @@ -102,6 +142,34 @@ public void testMemoryPools() { new String[]{"pool"}, new String[]{"PS Old Gen"}), .0000001); + assertEquals( + 20000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_used", + new String[]{"pool"}, + new String[]{"PS Old Gen"}), + .0000001); + assertEquals( + 40000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_committed", + new String[]{"pool"}, + new String[]{"PS Old Gen"}), + .0000001); + assertEquals( + 6000000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_max", + new String[]{"pool"}, + new String[]{"PS Old Gen"}), + .0000001); + assertEquals( + 4000L, + registry.getSampleValue( + "jvm_memory_pool_collection_bytes_init", + new String[]{"pool"}, + new String[]{"PS Old Gen"}), + .0000001); } @Test From d37ad738d8a503aba9fca841afbdc366aecbf901 Mon Sep 17 00:00:00 2001 From: Rainer Jung Date: Thu, 6 May 2021 13:47:52 +0200 Subject: [PATCH 073/980] Add "jvm_objects_pending_finalization" counter providing access to MemoryMXBean.getObjectPendingFinalizationCount() --- .../io/prometheus/client/hotspot/MemoryPoolsExports.java | 6 ++++++ .../prometheus/client/hotspot/MemoryPoolsExportsTest.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index 73bceed62..dfcd8d8e3 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -48,6 +48,12 @@ void addMemoryAreaMetrics(List sampleFamilies) { MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); + GaugeMetricFamily finalizer = new GaugeMetricFamily( + "jvm_objects_pending_finalization", + "The number of objects waiting in the finalizer queue.", + memoryBean.getObjectPendingFinalizationCount()); + sampleFamilies.add(finalizer); + GaugeMetricFamily used = new GaugeMetricFamily( "jvm_memory_bytes_used", "Used bytes of a given JVM memory area.", diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java index de8c06aae..75d378331 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java @@ -35,6 +35,7 @@ public void setUp() { when(mockPoolsBean2.getName()).thenReturn("PS Old Gen"); when(mockPoolsBean2.getUsage()).thenReturn(mockUsage2); when(mockPoolsBean2.getCollectionUsage()).thenReturn(mockCollectionUsage2); + when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn(10); when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(mockUsage1); when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(mockUsage2); when(mockUsage1.getUsed()).thenReturn(500000L); @@ -174,6 +175,11 @@ public void testMemoryPools() { @Test public void testMemoryAreas() { + assertEquals( + 10L, + registry.getSampleValue( + "jvm_objects_pending_finalization"), + .0000001); assertEquals( 500000L, registry.getSampleValue( From 96ce10fdfcab07b6bfe0fdb371304ac991ab8853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 May 2021 01:34:19 +0200 Subject: [PATCH 074/980] use consistent prefix for memory pool metrics --- .../java/io/prometheus/client/hotspot/MemoryPoolsExports.java | 2 +- .../io/prometheus/client/hotspot/MemoryPoolsExportsTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index dfcd8d8e3..5a1ff07b2 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -49,7 +49,7 @@ void addMemoryAreaMetrics(List sampleFamilies) { MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); GaugeMetricFamily finalizer = new GaugeMetricFamily( - "jvm_objects_pending_finalization", + "jvm_memory_objects_pending_finalization", "The number of objects waiting in the finalizer queue.", memoryBean.getObjectPendingFinalizationCount()); sampleFamilies.add(finalizer); diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java index 75d378331..5b300bfed 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java @@ -178,7 +178,7 @@ public void testMemoryAreas() { assertEquals( 10L, registry.getSampleValue( - "jvm_objects_pending_finalization"), + "jvm_memory_objects_pending_finalization"), .0000001); assertEquals( 500000L, From a0796c6ca3d5f068d2b2e9551318cb0e4fd41cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 May 2021 13:29:06 +0200 Subject: [PATCH 075/980] follow Prometheus naming conventions for new metric names --- .../client/hotspot/MemoryPoolsExports.java | 13 +++++++++---- .../client/hotspot/MemoryPoolsExportsTest.java | 16 ++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index 5a1ff07b2..0b37e72ba 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -88,6 +88,11 @@ void addMemoryAreaMetrics(List sampleFamilies) { } void addMemoryPoolMetrics(List sampleFamilies) { + + // Note: The Prometheus naming convention is that units belong at the end of the metric name. + // For new metrics like jvm_memory_pool_collection_used_bytes we follow that convention. + // For old metrics like jvm_memory_pool_bytes_used we keep the names as they are to avoid a breaking change. + GaugeMetricFamily used = new GaugeMetricFamily( "jvm_memory_pool_bytes_used", "Used bytes of a given JVM memory pool.", @@ -109,22 +114,22 @@ void addMemoryPoolMetrics(List sampleFamilies) { Collections.singletonList("pool")); sampleFamilies.add(init); GaugeMetricFamily collectionUsed = new GaugeMetricFamily( - "jvm_memory_pool_collection_bytes_used", + "jvm_memory_pool_collection_used_bytes", "Used bytes after last collection of a given JVM memory pool.", Collections.singletonList("pool")); sampleFamilies.add(collectionUsed); GaugeMetricFamily collectionCommitted = new GaugeMetricFamily( - "jvm_memory_pool_collection_bytes_committed", + "jvm_memory_pool_collection_committed_bytes", "Committed after last collection bytes of a given JVM memory pool.", Collections.singletonList("pool")); sampleFamilies.add(collectionCommitted); GaugeMetricFamily collectionMax = new GaugeMetricFamily( - "jvm_memory_pool_collection_bytes_max", + "jvm_memory_pool_collection_max_bytes", "Max bytes after last collection of a given JVM memory pool.", Collections.singletonList("pool")); sampleFamilies.add(collectionMax); GaugeMetricFamily collectionInit = new GaugeMetricFamily( - "jvm_memory_pool_collection_bytes_init", + "jvm_memory_pool_collection_init_bytes", "Initial after last collection bytes of a given JVM memory pool.", Collections.singletonList("pool")); sampleFamilies.add(collectionInit); diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java index 5b300bfed..613b16708 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java @@ -90,28 +90,28 @@ public void testMemoryPools() { assertEquals( 400000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_used", + "jvm_memory_pool_collection_used_bytes", new String[]{"pool"}, new String[]{"PS Eden Space"}), .0000001); assertEquals( 800000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_committed", + "jvm_memory_pool_collection_committed_bytes", new String[]{"pool"}, new String[]{"PS Eden Space"}), .0000001); assertEquals( 1600000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_max", + "jvm_memory_pool_collection_max_bytes", new String[]{"pool"}, new String[]{"PS Eden Space"}), .0000001); assertEquals( 2000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_init", + "jvm_memory_pool_collection_init_bytes", new String[]{"pool"}, new String[]{"PS Eden Space"}), .0000001); @@ -146,28 +146,28 @@ public void testMemoryPools() { assertEquals( 20000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_used", + "jvm_memory_pool_collection_used_bytes", new String[]{"pool"}, new String[]{"PS Old Gen"}), .0000001); assertEquals( 40000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_committed", + "jvm_memory_pool_collection_committed_bytes", new String[]{"pool"}, new String[]{"PS Old Gen"}), .0000001); assertEquals( 6000000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_max", + "jvm_memory_pool_collection_max_bytes", new String[]{"pool"}, new String[]{"PS Old Gen"}), .0000001); assertEquals( 4000L, registry.getSampleValue( - "jvm_memory_pool_collection_bytes_init", + "jvm_memory_pool_collection_init_bytes", new String[]{"pool"}, new String[]{"PS Old Gen"}), .0000001); From 9f1fb4f471f59e1308da33e179a8e88bfd1a0568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 May 2021 21:38:22 +0200 Subject: [PATCH 076/980] [maven-release-plugin] prepare release parent-0.11.0 --- benchmark/pom.xml | 2 +- integration_tests/example_application/pom.xml | 5 +-- integration_tests/exemplars_otel/pom.xml | 5 +-- .../exemplars_otel_agent/pom.xml | 5 +-- integration_tests/java_versions/pom.xml | 5 +-- integration_tests/pom.xml | 2 +- pom.xml | 4 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 40 +++++++++---------- simpleclient_caffeine/pom.xml | 4 +- simpleclient_common/pom.xml | 4 +- simpleclient_dropwizard/pom.xml | 4 +- simpleclient_graphite_bridge/pom.xml | 4 +- simpleclient_guava/pom.xml | 4 +- simpleclient_hibernate/pom.xml | 4 +- simpleclient_hotspot/pom.xml | 6 +-- simpleclient_httpserver/pom.xml | 6 +-- simpleclient_jetty/pom.xml | 4 +- simpleclient_jetty_jdk8/pom.xml | 4 +- simpleclient_log4j/pom.xml | 4 +- simpleclient_log4j2/pom.xml | 4 +- simpleclient_logback/pom.xml | 4 +- simpleclient_pushgateway/pom.xml | 6 +-- simpleclient_servlet/pom.xml | 6 +-- simpleclient_spring_boot/pom.xml | 8 ++-- simpleclient_spring_web/pom.xml | 6 +-- simpleclient_tracer/pom.xml | 5 +-- .../simpleclient_tracer_common/pom.xml | 5 +-- .../simpleclient_tracer_otel/pom.xml | 5 +-- .../simpleclient_tracer_otel_agent/pom.xml | 5 +-- simpleclient_vertx/pom.xml | 6 +-- 31 files changed, 85 insertions(+), 93 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index c70ff6f09..bbc65e424 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index 9c3f4d28e..43cfa8e20 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration_tests - 0.10.1-SNAPSHOT + 0.11.0 example_application diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index e2283c3d9..0e7c82d91 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration_tests - 0.10.1-SNAPSHOT + 0.11.0 exemplars_otel diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/exemplars_otel_agent/pom.xml index ef0d23991..98b0953ed 100644 --- a/integration_tests/exemplars_otel_agent/pom.xml +++ b/integration_tests/exemplars_otel_agent/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration_tests - 0.10.1-SNAPSHOT + 0.11.0 exemplars_otel_agent diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/java_versions/pom.xml index 26b930d05..e8d892a7c 100644 --- a/integration_tests/java_versions/pom.xml +++ b/integration_tests/java_versions/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration_tests - 0.10.1-SNAPSHOT + 0.11.0 java_versions diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 5644fcb17..d2f9f86ee 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 integration_tests diff --git a/pom.xml b/pom.xml index c0d241b5c..5a3dd1ca4 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.11.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 7ade134f7..e6202f8c2 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 7d112f409..8275f8473 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_bom @@ -29,97 +29,97 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_caffeine - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_dropwizard - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_graphite_bridge - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_hibernate - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_guava - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_hotspot - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_httpserver - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_log4j - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_log4j2 - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_logback - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_pushgateway - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_servlet - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_spring_web - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_spring_boot - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_jetty - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_jetty_jdk8 - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_vertx - 0.10.1-SNAPSHOT + 0.11.0 diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 21e749430..d1edf5ade 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index fefbb1311..3aae51232 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 5284bd77c..c2ea0f83a 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index ff6d550dc..2d95e9d55 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index bfb466c31..48bde8c24 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 0cc79b11e..641ec3348 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index b23999108..b00fc7ef8 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_servlet - 0.10.1-SNAPSHOT + 0.11.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 248228755..2888d95de 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 5affa23f6..9df0bf0a3 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index be6be72e4..503095695 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index be6d64e51..49f542785 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index aaf3edcd1..faeefc007 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 93cfc8ca5..12395efb0 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 63f8b2894..9481c48e3 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 11efdae1f..5390c49b6 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index dd564617f..7d50d5afe 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_spring_web - 0.10.1-SNAPSHOT + 0.11.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 27b582ff8..f6c8472e2 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 25342e02b..7ed299ce4 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 26a305ecc..f777fa70c 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus simpleclient_tracer - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 210959448..42359dc0c 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus simpleclient_tracer - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 5c2104ad3..96dfb7eb8 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus simpleclient_tracer - 0.10.1-SNAPSHOT + 0.11.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 3ef195c5c..aafd05533 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.10.1-SNAPSHOT + 0.11.0 io.prometheus simpleclient_common - 0.10.1-SNAPSHOT + 0.11.0 io.vertx From 6ae0c961cfc19b8ef0575c98ac82ee55b11002ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 May 2021 21:38:29 +0200 Subject: [PATCH 077/980] [maven-release-plugin] prepare for next development iteration --- benchmark/pom.xml | 2 +- integration_tests/example_application/pom.xml | 2 +- integration_tests/exemplars_otel/pom.xml | 2 +- .../exemplars_otel_agent/pom.xml | 2 +- integration_tests/java_versions/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 40 +++++++++---------- simpleclient_caffeine/pom.xml | 4 +- simpleclient_common/pom.xml | 4 +- simpleclient_dropwizard/pom.xml | 4 +- simpleclient_graphite_bridge/pom.xml | 4 +- simpleclient_guava/pom.xml | 4 +- simpleclient_hibernate/pom.xml | 4 +- simpleclient_hotspot/pom.xml | 6 +-- simpleclient_httpserver/pom.xml | 6 +-- simpleclient_jetty/pom.xml | 4 +- simpleclient_jetty_jdk8/pom.xml | 4 +- simpleclient_log4j/pom.xml | 4 +- simpleclient_log4j2/pom.xml | 4 +- simpleclient_logback/pom.xml | 4 +- simpleclient_pushgateway/pom.xml | 6 +-- simpleclient_servlet/pom.xml | 6 +-- simpleclient_spring_boot/pom.xml | 8 ++-- simpleclient_spring_web/pom.xml | 6 +-- simpleclient_tracer/pom.xml | 2 +- .../simpleclient_tracer_common/pom.xml | 2 +- .../simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +-- 31 files changed, 77 insertions(+), 77 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index bbc65e424..a670245f2 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index 43cfa8e20..7faa6a7de 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.0 + 0.11.1-SNAPSHOT example_application diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index 0e7c82d91..eaac05f2f 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.0 + 0.11.1-SNAPSHOT exemplars_otel diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/exemplars_otel_agent/pom.xml index 98b0953ed..80ee9f089 100644 --- a/integration_tests/exemplars_otel_agent/pom.xml +++ b/integration_tests/exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.0 + 0.11.1-SNAPSHOT exemplars_otel_agent diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/java_versions/pom.xml index e8d892a7c..0bb95d83e 100644 --- a/integration_tests/java_versions/pom.xml +++ b/integration_tests/java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.0 + 0.11.1-SNAPSHOT java_versions diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index d2f9f86ee..fa2609678 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index 5a3dd1ca4..de267f7be 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.11.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index e6202f8c2..6b603330e 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 8275f8473..a46892b02 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_bom @@ -29,97 +29,97 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_caffeine - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_dropwizard - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_graphite_bridge - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_hibernate - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_guava - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_hotspot - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_httpserver - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_log4j - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_log4j2 - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_logback - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_pushgateway - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_spring_boot - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_jetty - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_jetty_jdk8 - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_vertx - 0.11.0 + 0.11.1-SNAPSHOT diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index d1edf5ade..c1f8be0e6 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 3aae51232..dcd8ffdd0 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index c2ea0f83a..018cefb6e 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 2d95e9d55..79925e2f7 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 48bde8c24..2e166b999 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 641ec3348..fbdb97611 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index b00fc7ef8..ee1d61559 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,14 +37,14 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.11.0 + 0.11.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 2888d95de..84235bb9b 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 9df0bf0a3..c5697d1cc 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -35,7 +35,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 503095695..d7ac3fac5 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -48,7 +48,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 49f542785..f5f9f22cd 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index faeefc007..3ef4b77b7 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 12395efb0..aa29f7076 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 9481c48e3..3e2197471 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -38,12 +38,12 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 5390c49b6..6f7911e15 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -41,12 +41,12 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT javax.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 7d50d5afe..9e677b393 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -52,17 +52,17 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.11.0 + 0.11.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index f6c8472e2..6de55c30b 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 7ed299ce4..d15ff824d 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index f777fa70c..0f2042ca4 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 42359dc0c..11d36bbf9 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 96dfb7eb8..67272ebff 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.0 + 0.11.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index aafd05533..f4ae3a9a7 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus @@ -53,12 +53,12 @@ io.prometheus simpleclient - 0.11.0 + 0.11.1-SNAPSHOT io.prometheus simpleclient_common - 0.11.0 + 0.11.1-SNAPSHOT io.vertx From bddce55e1b77a778d2e1e22ade792ef32ea899f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 May 2021 22:54:22 +0200 Subject: [PATCH 078/980] fix link in REAMDE.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35114236d..6aa7d2704 100644 --- a/README.md +++ b/README.md @@ -412,7 +412,7 @@ If you are a tracing vendor, feel free to open a PR and add support for your tra Documentation of the individual tracer integrations: -* [OTEL_EXEMPLARS.md]: OpenTelemetry +* [OTEL_EXEMPLARS.md](OTEL_EXEMPLARS.md): OpenTelemetry ## Included Collectors From a9a5952354c5de9733bb680808c3f3fb26629356 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Jun 2021 17:40:13 +0000 Subject: [PATCH 079/980] Bump logback-classic from 1.1.2 to 1.2.0 in /simpleclient_logback Bumps logback-classic from 1.1.2 to 1.2.0. --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- simpleclient_logback/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index aa29f7076..2298c7cc6 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -42,7 +42,7 @@ ch.qos.logback logback-classic - 1.1.2 + 1.2.0 From b178c5e1879e8d3d3c6e50ede8968340ba9f2488 Mon Sep 17 00:00:00 2001 From: Robin Karlsson Date: Fri, 11 Jun 2021 22:51:50 +0200 Subject: [PATCH 080/980] Add Counter.Child no-arg constructor Fix backwards incompatible change introduced in exemplar commit, b76e1e95d1c8ce3141584e2a2d260519c3a6eb19 Signed-off-by: Robin Karlsson --- simpleclient/src/main/java/io/prometheus/client/Counter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java index 35a21880c..51f0a24a2 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Counter.java +++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java @@ -176,6 +176,10 @@ public static class Child { private final CounterExemplarSampler exemplarSampler; private final AtomicReference exemplar = new AtomicReference(); + public Child() { + this(null, null); + } + public Child(Boolean exemplarsEnabled, CounterExemplarSampler exemplarSampler) { this.exemplarsEnabled = exemplarsEnabled; this.exemplarSampler = exemplarSampler; From dfad5af60748c609426115b90d3a8c89b806ffb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 19 Jun 2021 10:15:42 +0200 Subject: [PATCH 081/980] document OpenMetrics Accept header --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6aa7d2704..2a4bb3196 100644 --- a/README.md +++ b/README.md @@ -299,6 +299,12 @@ class YourClass { ## Exemplars Exemplars are a feature of the [OpenMetrics](http://openmetrics.io) format that allows applications to link metrics to example traces. +In order to see exemplars, you need to set the `Accept` header for the [OpenMetrics](http://openmetrics.io) format like this: + +``` +curl -H 'Accept: application/openmetrics-text; version=1.0.0; charset=utf-8' http://localhost:8080/metrics +``` + Exemplars are supported since `client_java` version 0.11.0. Exemplars are supported for `Counter` and `Histogram` metrics. ### Global Exemplar Samplers From 1a4420e87c3e449485adad2c2f01247b91d8c3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 27 Jun 2021 22:28:05 +0200 Subject: [PATCH 082/980] Fix javadoc site report --- pom.xml | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de267f7be..889c512db 100644 --- a/pom.xml +++ b/pom.xml @@ -213,7 +213,7 @@ generate-javadoc-site-report site - javadoc + aggregate @@ -229,6 +229,34 @@ + + + + + maven-project-info-reports-plugin + 2.9 + + + maven-javadoc-plugin + + + aggregate + false + + aggregate + + + + default + + javadoc + + + + + + + release From 9c2d621ff831cf78cab49bb2a91a04d3bd00d287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 27 Jun 2021 23:35:35 +0200 Subject: [PATCH 083/980] Update for 0.11.0 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2a4bb3196..6d8aaa07e 100644 --- a/README.md +++ b/README.md @@ -46,25 +46,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.10.0 + 0.11.0 io.prometheus simpleclient_hotspot - 0.10.0 + 0.11.0 io.prometheus simpleclient_httpserver - 0.10.0 + 0.11.0 io.prometheus simpleclient_pushgateway - 0.10.0 + 0.11.0 ``` From 70e0f5ab5bf8f8876a18c75d33d1c9dc4cac9232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 19 Jul 2021 16:59:37 +0200 Subject: [PATCH 084/980] fix typo in OpenMetrics type string for gaugehistogram --- .../java/io/prometheus/client/exporter/common/TextFormat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index 69fa8d6d2..db2de3a5b 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -291,7 +291,7 @@ private static String omTypeString(Collector.Type t) { case HISTOGRAM: return "histogram"; case GAUGE_HISTOGRAM: - return "gauge_histogram"; + return "gaugehistogram"; case STATE_SET: return "stateset"; case INFO: From 8976c99f70e8939c5405594d3af0d625ec3fc573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 31 Jul 2021 21:40:39 +0200 Subject: [PATCH 085/980] Bump jetty-server from 9.3.27.v20190418 to 9.4.41.v20210516 --- simpleclient_jetty/pom.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index c5697d1cc..c06936994 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -8,15 +8,17 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_jetty - bundle Prometheus Java Simpleclient Jetty Collector of data from Jetty StatisticsHandler. + + 9.4.41.v20210516 + + The Apache Software License, Version 2.0 @@ -40,12 +42,12 @@ org.eclipse.jetty jetty-server - 9.3.27.v20190418 + ${jetty.version} org.eclipse.jetty jetty-servlet - 9.3.27.v20190418 + ${jetty.version} From d663d040e19fa07cf8f928492b3a99e2ebce8f6b Mon Sep 17 00:00:00 2001 From: Lapo Luchini Date: Sat, 31 Jul 2021 15:50:56 -0400 Subject: [PATCH 086/980] Add parameter to optionally strip deploy path. (#639) * Add parameter to optionally strip deploy path. Closes #631. Signed-off-by: Lapo Luchini * Add documentation and test as requested in PR#639. Signed-off-by: Lapo Luchini --- README.md | 10 +++++++- .../client/filter/MetricsFilter.java | 18 +++++++++++++++ .../client/filter/MetricsFilterTest.java | 23 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d8aaa07e..8afb50af7 100644 --- a/README.md +++ b/README.md @@ -577,7 +577,10 @@ measuring is also configurable, via the `path-components` init parameter. By default, the servlet filter will record each path differently, but by setting an integer here, you can tell the filter to only record up to the Nth slashes. That is, all requests with greater than N "/" characters in the servlet URI path will -be measured in the same bucket and you will lose that granularity. +be measured in the same bucket and you will lose that granularity. The init +parameter `strip-context-path` can be used to strip the leading part of the URL +which is part of the deploy context (i.e. the folder the servlet is deployed to), +so that the same servlet deployed to different paths can lead to similar metrics. The code below is an example of the XML configuration for the filter. You will need to place this (replace your own values) code in your @@ -605,6 +608,11 @@ need to place this (replace your own values) code in your path-components 1 + + + strip-context-path + false + + * + * strip-context-path + * false + * * * } * @@ -60,6 +69,7 @@ public class MetricsFilter implements Filter { static final String HELP_PARAM = "help"; static final String METRIC_NAME_PARAM = "metric-name"; static final String BUCKET_CONFIG_PARAM = "buckets"; + static final String STRIP_CONTEXT_PATH_PARAM = "strip-context-path"; static final String UNKNOWN_HTTP_STATUS_CODE = ""; private Histogram histogram = null; @@ -68,6 +78,7 @@ public class MetricsFilter implements Filter { // Package-level for testing purposes. int pathComponents = 1; private String metricName = null; + boolean stripContextPath = false; private String help = "The time taken fulfilling servlet requests"; private double[] buckets = null; @@ -145,6 +156,10 @@ public void init(FilterConfig filterConfig) throws ServletException { buckets[i] = Double.parseDouble(bucketParams[i]); } } + + if (!isEmpty(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM))) { + stripContextPath = Boolean.parseBoolean(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM)); + } } if (buckets != null) { @@ -171,6 +186,9 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo HttpServletRequest request = (HttpServletRequest) servletRequest; String path = request.getRequestURI(); + if (stripContextPath) { + path = path.substring(request.getContextPath().length()); + } String components = getComponents(path); String method = request.getMethod(); diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java index 622756b6b..40bccaa6f 100644 --- a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java +++ b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doAnswer; @@ -231,4 +232,26 @@ public void testStatusCodeWithNonHttpServletResponse() throws Exception { assertNotNull(sampleValue); assertEquals(1, sampleValue, 0.0001); } + + @Test + public void testStripContextPath() throws Exception { + String metricName = "foo"; + FilterConfig cfg = mock(FilterConfig.class); + when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn(metricName); + when(cfg.getInitParameter(MetricsFilter.PATH_COMPONENT_PARAM)).thenReturn("0"); + when(cfg.getInitParameter(MetricsFilter.STRIP_CONTEXT_PATH_PARAM)).thenReturn("true"); + f.init(cfg); + assertTrue(f.stripContextPath); + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang"); + when(req.getContextPath()).thenReturn("/foo/bar"); + when(req.getMethod()).thenReturn(HttpMethods.GET); + HttpServletResponse res = mock(HttpServletResponse.class); + FilterChain c = mock(FilterChain.class); + f.doFilter(req, res, c); + verify(c).doFilter(req, res); + final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(metricName + "_count", new String[]{"path", "method"}, new String[]{"/baz/bang", HttpMethods.GET}); + assertNotNull(sampleValue); + assertEquals(1, sampleValue, 0.0001); + } } From 9701230610aa499a4d75b45b351aa52532779f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 1 Aug 2021 21:17:06 +0200 Subject: [PATCH 087/980] Add support for Jakarta servlet #647 --- README.md | 26 +- pom.xml | 2 + simpleclient_servlet/pom.xml | 9 +- .../java/io/prometheus/client/Adapter.java | 103 +++++++ .../client/exporter/MetricsServlet.java | 59 +--- .../client/filter/MetricsFilter.java | 206 +++++--------- .../client/exporter/MetricsServletTest.java | 96 ------- .../client/filter/MetricsFilterTest.java | 257 ------------------ simpleclient_servlet_common/pom.xml | 65 +++++ .../common/adapter/FilterConfigAdapter.java | 5 + .../adapter/HttpServletRequestAdapter.java | 9 + .../adapter/HttpServletResponseAdapter.java | 11 + .../servlet/common/exporter/Exporter.java | 66 +++++ .../client/servlet/common/filter/Filter.java | 170 ++++++++++++ .../filter/FilterConfigurationException.java | 10 + .../servlet/common/exporter/ExporterTest.java | 158 +++++++++++ .../servlet/common/filter/FilterTest.java | 238 ++++++++++++++++ simpleclient_servlet_jakarta/pom.xml | 88 ++++++ .../client/servlet/jakarta/Adapter.java | 103 +++++++ .../jakarta/exporter/MetricsServlet.java | 28 ++ .../servlet/jakarta/filter/MetricsFilter.java | 125 +++++++++ .../client/exporter/ExampleBenchmark.java | 56 ++++ .../client/exporter/ExampleExporter.java | 35 +++ 23 files changed, 1370 insertions(+), 555 deletions(-) create mode 100644 simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java delete mode 100644 simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java delete mode 100644 simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java create mode 100644 simpleclient_servlet_common/pom.xml create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java create mode 100644 simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java create mode 100644 simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java create mode 100644 simpleclient_servlet_jakarta/pom.xml create mode 100644 simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java create mode 100644 simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java create mode 100644 simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java create mode 100644 simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java create mode 100644 simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java diff --git a/README.md b/README.md index 8afb50af7..f62a6e90a 100644 --- a/README.md +++ b/README.md @@ -567,8 +567,16 @@ new QueuedThreadPoolStatisticsCollector() #### Servlet Filter -There is a servlet filter available for measuring the duration taken by servlet -requests. The `metric-name` init parameter is required, and is the name of the +There is a servlet filter available for measuring the duration taken by servlet requests: + +* `javax` version: `io.prometheus.client.filter.MetricsFilter` provided by `simpleclient_servlet` +* `jakarta` version: `io.prometheus.client.servlet.jakarta.filter.MetricsFilter` provided by `simpleclient_servlet_jakarta` + +Both versions implement the same functionality. + +Configuration is as follows: + +The `metric-name` init parameter is required, and is the name of the metric prometheus will expose for the timing metrics. Help text via the `help` init parameter is not required, although it is highly recommended. The number of buckets is overridable, and can be configured by passing a comma-separated @@ -577,9 +585,9 @@ measuring is also configurable, via the `path-components` init parameter. By default, the servlet filter will record each path differently, but by setting an integer here, you can tell the filter to only record up to the Nth slashes. That is, all requests with greater than N "/" characters in the servlet URI path will -be measured in the same bucket and you will lose that granularity. The init +be measured in the same bucket, and you will lose that granularity. The init parameter `strip-context-path` can be used to strip the leading part of the URL -which is part of the deploy context (i.e. the folder the servlet is deployed to), +which is part of the deployment context (i.e. the folder the servlet is deployed to), so that the same servlet deployed to different paths can lead to similar metrics. The code below is an example of the XML configuration for the filter. You will @@ -589,21 +597,24 @@ need to place this (replace your own values) code in your ```xml prometheusFilter + + io.prometheus.client.filter.MetricsFilter metric-name webapp_metrics_filter + help This is the help for your metrics filter + buckets 0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10 - + path-components 1 @@ -627,8 +638,7 @@ the most accurate measurement of latency. --> Additionally, you can instantiate your servlet filter directly in Java code. To do this, you just need to call the non-empty constructor. The first parameter, the metric name, is required. The second, help, is optional but highly -recommended. The last two (path-components, and buckets) are optional and will -default sensibly if omitted. +recommended. The other parameters are optional and will default sensibly if omitted. #### Spring AOP diff --git a/pom.xml b/pom.xml index 889c512db..2b4a05bde 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,8 @@ simpleclient_logback simpleclient_pushgateway simpleclient_servlet + simpleclient_servlet_common + simpleclient_servlet_jakarta simpleclient_spring_web simpleclient_spring_boot simpleclient_jetty diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 6f7911e15..bf610b7ab 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -8,11 +8,10 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_servlet bundle - Prometheus Java Simpleclient Servlet + Prometheus Java Simpleclient Servlet - Javax HTTP servlet exporter for the simpleclient. @@ -48,6 +47,11 @@ simpleclient_common 0.11.1-SNAPSHOT + + io.prometheus + simpleclient_servlet_common + 0.11.1-SNAPSHOT + javax.servlet javax.servlet-api @@ -80,4 +84,5 @@ test + diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java new file mode 100644 index 000000000..6c1f493a5 --- /dev/null +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java @@ -0,0 +1,103 @@ +package io.prometheus.client; + +import io.prometheus.client.servlet.common.adapter.FilterConfigAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; + +import javax.servlet.FilterConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +public class Adapter { + + private static class HttpServletRequestAdapterImpl implements HttpServletRequestAdapter { + + private final HttpServletRequest delegate; + + HttpServletRequestAdapterImpl(HttpServletRequest delegate) { + this.delegate = delegate; + } + + @Override + public String getHeader(String name) { + return delegate.getHeader(name); + } + + @Override + public String getRequestURI() { + return delegate.getRequestURI(); + } + + @Override + public String getMethod() { + return delegate.getMethod(); + } + + @Override + public String[] getParameterValues(String name) { + return delegate.getParameterValues(name); + } + + @Override + public String getContextPath() { + return delegate.getContextPath(); + } + } + + private static class HttpServletResponseAdapterImpl implements HttpServletResponseAdapter { + + private final HttpServletResponse delegate; + + HttpServletResponseAdapterImpl(HttpServletResponse delegate) { + this.delegate = delegate; + } + + @Override + public void setStatus(int httpStatusCode) { + delegate.setBufferSize(httpStatusCode); + } + + @Override + public void setContentType(String contentType) { + delegate.setContentType(contentType); + } + + @Override + public PrintWriter getWriter() throws IOException { + return delegate.getWriter(); + } + + @Override + public int getStatus() { + return delegate.getStatus(); + } + } + + private static class FilterConfigAdapterImpl implements FilterConfigAdapter { + + private final FilterConfig delegate; + + private FilterConfigAdapterImpl(FilterConfig delegate) { + this.delegate = delegate; + } + + @Override + public String getInitParameter(String name) { + return delegate.getInitParameter(name); + } + } + + public static HttpServletRequestAdapter wrap(HttpServletRequest req) { + return new HttpServletRequestAdapterImpl(req); + } + + public static HttpServletResponseAdapter wrap(HttpServletResponse resp) { + return new HttpServletResponseAdapterImpl(resp); + } + + public static FilterConfigAdapter wrap(FilterConfig filterConfig) { + return new FilterConfigAdapterImpl(filterConfig); + } +} \ No newline at end of file diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java index 7abb34d09..77560335b 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java @@ -1,72 +1,37 @@ package io.prometheus.client.exporter; import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.exporter.common.TextFormat; +import io.prometheus.client.servlet.common.exporter.Exporter; -import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.Writer; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; + +import static io.prometheus.client.Adapter.wrap; /** - * The MetricsServlet class exists to provide a simple way of exposing the metrics values. - * + * The MetricsServlet class provides a simple way of exposing the metrics values. */ public class MetricsServlet extends HttpServlet { - private CollectorRegistry registry; + private final Exporter exporter; - /** - * Construct a MetricsServlet for the default registry. - */ public MetricsServlet() { - this(CollectorRegistry.defaultRegistry); + exporter = new Exporter(); } - /** - * Construct a MetricsServlet for the given registry. - * @param registry collector registry - */ public MetricsServlet(CollectorRegistry registry) { - this.registry = registry; + exporter = new Exporter(registry); } @Override - protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) - throws ServletException, IOException { - resp.setStatus(HttpServletResponse.SC_OK); - String contentType = TextFormat.chooseContentType(req.getHeader("Accept")); - resp.setContentType(contentType); - - Writer writer = new BufferedWriter(resp.getWriter()); - try { - TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(parse(req))); - writer.flush(); - } finally { - writer.close(); - } - } - - private Set parse(HttpServletRequest req) { - String[] includedParam = req.getParameterValues("name[]"); - if (includedParam == null) { - return Collections.emptySet(); - } else { - return new HashSet(Arrays.asList(includedParam)); - } + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { + exporter.doGet(wrap(req), wrap(resp)); } @Override - protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) - throws ServletException, IOException { - doGet(req, resp); + protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { + exporter.doPost(wrap(req), wrap(resp)); } - -} +} \ No newline at end of file diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java index 3fb0236a8..21d5b3343 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java @@ -1,26 +1,29 @@ package io.prometheus.client.filter; -import io.prometheus.client.Counter; -import io.prometheus.client.Histogram; +import io.prometheus.client.Adapter; +import io.prometheus.client.servlet.common.filter.Filter; +import io.prometheus.client.servlet.common.filter.FilterConfigurationException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** - * The MetricsFilter class exists to provide a high-level filter that enables tunable collection of metrics for Servlet + * The MetricsFilter class provides a high-level filter that enables tunable collection of metrics for Servlet * performance. * + * This is the Javax version of the MetricsFilter. If you are using Jakarta Servlet, there is a Jakarta version + * available in {@code simpleclient-servlet-jakarta}. + * *

The metric name itself is required, and configured with a {@code metric-name} init parameter. * *

The help parameter, configured with the {@code help} init parameter, is not required but strongly recommended. * + *

The Histogram buckets can be configured with a {@code buckets} init parameter whose value is a comma-separated + * list * of valid {@code double} values. If omitted, the default buckets from {@link io.prometheus.client.Histogram} + * are used. + * *

By default, this filter will provide metrics that distinguish only 1 level deep for the request path * (including servlet context path), but can be configured with the {@code path-components} init parameter. Any number * provided that is less than 1 will provide the full path granularity (warning, this may affect performance). @@ -29,189 +32,102 @@ * part of the context (i.e. the folder where the servlet is deployed) so that the same project deployed under different * paths can produce the same metrics. * - *

The Histogram buckets can be configured with a {@code buckets} init parameter whose value is a comma-separated list - * of valid {@code double} values. - * - *

HTTP statuses will be aggregated via Counter. The name for this counter will be derived from the {@code metric-name} init parameter. + *

HTTP statuses will be aggregated via Counter. The name for this counter will be derived from the + * {@code metric-name} init parameter. * *

{@code
  * 
  *   prometheusFilter
+ *   
+ *   
  *   io.prometheus.client.filter.MetricsFilter
  *   
- *      metric-name
- *      webapp_metrics_filter
+ *     metric-name
+ *     webapp_metrics_filter
  *   
+ *   
  *   
- *      help
- *      The time taken fulfilling servlet requests
+ *     help
+ *     This is the help for your metrics filter
  *   
+ *   
  *   
- *      buckets
- *      0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10
+ *     buckets
+ *     0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10
  *   
+ *   
  *   
- *      path-components
- *      0
+ *     path-components
+ *     1
  *   
  *   
  *   
- *      strip-context-path
- *      false
+ *     strip-context-path
+ *     false
  *   
  * 
- * }
* - * @author Andrew Stuart <andrew.stuart2@gmail.com> + * + * + * prometheusFilter + * /* + * + * } */ -public class MetricsFilter implements Filter { - static final String PATH_COMPONENT_PARAM = "path-components"; - static final String HELP_PARAM = "help"; - static final String METRIC_NAME_PARAM = "metric-name"; - static final String BUCKET_CONFIG_PARAM = "buckets"; - static final String STRIP_CONTEXT_PATH_PARAM = "strip-context-path"; - static final String UNKNOWN_HTTP_STATUS_CODE = ""; - - private Histogram histogram = null; - private Counter statusCounter = null; +public class MetricsFilter implements javax.servlet.Filter { - // Package-level for testing purposes. - int pathComponents = 1; - private String metricName = null; - boolean stripContextPath = false; - private String help = "The time taken fulfilling servlet requests"; - private double[] buckets = null; + private final Filter delegate; - public MetricsFilter() {} + public MetricsFilter() { + this.delegate = new Filter(); + } + // compatibility with 0.11.1 and older public MetricsFilter( String metricName, String help, Integer pathComponents, double[] buckets) { - this.metricName = metricName; - this.buckets = buckets; - if (help != null) { - this.help = help; - } - if (pathComponents != null) { - this.pathComponents = pathComponents; - } + this(metricName, help, pathComponents, buckets, false); } - private boolean isEmpty(String s) { - return s == null || s.length() == 0; - } - - private String getComponents(String str) { - if (str == null || pathComponents < 1) { - return str; - } - int count = 0; - int i = -1; - do { - i = str.indexOf("/", i + 1); - if (i < 0) { - // Path is longer than specified pathComponents. - return str; - } - count++; - } while (count <= pathComponents); - - return str.substring(0, i); + /** + * See {@link Filter#Filter(String, String, Integer, double[], boolean)}. + */ + public MetricsFilter( + String metricName, + String help, + Integer pathComponents, + double[] buckets, + boolean stripContextPath) { + this.delegate = new Filter(metricName, help, pathComponents, buckets, stripContextPath); } @Override public void init(FilterConfig filterConfig) throws ServletException { - Histogram.Builder builder = Histogram.build() - .labelNames("path", "method"); - - if (filterConfig == null && isEmpty(metricName)) { - throw new ServletException("No configuration object provided, and no metricName passed via constructor"); - } - - if (filterConfig != null) { - if (isEmpty(metricName)) { - metricName = filterConfig.getInitParameter(METRIC_NAME_PARAM); - if (isEmpty(metricName)) { - throw new ServletException("Init parameter \"" + METRIC_NAME_PARAM + "\" is required; please supply a value"); - } - } - - if (!isEmpty(filterConfig.getInitParameter(HELP_PARAM))) { - help = filterConfig.getInitParameter(HELP_PARAM); - } - - // Allow overriding of the path "depth" to track - if (!isEmpty(filterConfig.getInitParameter(PATH_COMPONENT_PARAM))) { - pathComponents = Integer.valueOf(filterConfig.getInitParameter(PATH_COMPONENT_PARAM)); - } - - // Allow users to override the default bucket configuration - if (!isEmpty(filterConfig.getInitParameter(BUCKET_CONFIG_PARAM))) { - String[] bucketParams = filterConfig.getInitParameter(BUCKET_CONFIG_PARAM).split(","); - buckets = new double[bucketParams.length]; - - for (int i = 0; i < bucketParams.length; i++) { - buckets[i] = Double.parseDouble(bucketParams[i]); - } - } - - if (!isEmpty(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM))) { - stripContextPath = Boolean.parseBoolean(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM)); - } - } - - if (buckets != null) { - builder = builder.buckets(buckets); + try { + delegate.init(Adapter.wrap(filterConfig)); + } catch (FilterConfigurationException e) { + throw new ServletException(e); } - - histogram = builder - .help(help) - .name(metricName) - .register(); - - statusCounter = Counter.build(metricName + "_status_total", "HTTP status codes of " + help) - .labelNames("path", "method", "status") - .register(); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - if (!(servletRequest instanceof HttpServletRequest)) { + if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) { filterChain.doFilter(servletRequest, servletResponse); return; } - - HttpServletRequest request = (HttpServletRequest) servletRequest; - - String path = request.getRequestURI(); - if (stripContextPath) { - path = path.substring(request.getContextPath().length()); - } - - String components = getComponents(path); - String method = request.getMethod(); - Histogram.Timer timer = histogram - .labels(components, method) - .startTimer(); - + Filter.MetricData data = delegate.startTimer(Adapter.wrap((HttpServletRequest) servletRequest)); try { filterChain.doFilter(servletRequest, servletResponse); } finally { - timer.observeDuration(); - statusCounter.labels(components, method, getStatusCode(servletResponse)).inc(); + delegate.observeDuration(data, Adapter.wrap((HttpServletResponse) servletResponse)); } } - private String getStatusCode(ServletResponse servletResponse) { - if (!(servletResponse instanceof HttpServletResponse)) { - return UNKNOWN_HTTP_STATUS_CODE; - } - - return Integer.toString(((HttpServletResponse) servletResponse).getStatus()); - } - @Override public void destroy() { } diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java deleted file mode 100644 index 366d9087e..000000000 --- a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/MetricsServletTest.java +++ /dev/null @@ -1,96 +0,0 @@ -package io.prometheus.client.exporter; - -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Gauge; -import org.junit.Test; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class MetricsServletTest { - - @Test - public void testWriterFiltersBasedOnParameter() throws IOException, ServletException { - CollectorRegistry registry = new CollectorRegistry(); - Gauge.build("a", "a help").register(registry); - Gauge.build("b", "a help").register(registry); - Gauge.build("c", "a help").register(registry); - - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getParameterValues("name[]")).thenReturn(new String[]{"a", "b", "oneTheDoesntExist", ""}); - HttpServletResponse resp = mock(HttpServletResponse.class); - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter); - when(resp.getWriter()).thenReturn(writer); - - new MetricsServlet(registry).doGet(req, resp); - - assertThat(stringWriter.toString()).contains("a 0.0"); - assertThat(stringWriter.toString()).contains("b 0.0"); - assertThat(stringWriter.toString()).doesNotContain("c 0.0"); - } - - @Test - public void testWriterIsClosedNormally() throws IOException, ServletException { - HttpServletRequest req = mock(HttpServletRequest.class); - HttpServletResponse resp = mock(HttpServletResponse.class); - PrintWriter writer = mock(PrintWriter.class); - when(resp.getWriter()).thenReturn(writer); - CollectorRegistry registry = new CollectorRegistry(); - Gauge a = Gauge.build("a", "a help").register(registry); - - new MetricsServlet(registry).doGet(req, resp); - verify(writer).close(); - } - - @Test - public void testWriterIsClosedOnException() throws IOException, ServletException { - HttpServletRequest req = mock(HttpServletRequest.class); - HttpServletResponse resp = mock(HttpServletResponse.class); - PrintWriter writer = mock(PrintWriter.class); - when(resp.getWriter()).thenReturn(writer); - doThrow(new RuntimeException()).when(writer).write(any(char[].class), anyInt(), anyInt()); - CollectorRegistry registry = new CollectorRegistry(); - Gauge a = Gauge.build("a", "a help").register(registry); - - try { - new MetricsServlet(registry).doGet(req, resp); - fail("Exception expected"); - } catch (Exception e) { - } - - verify(writer).close(); - } - - @Test - public void testOpenMetricsNegotiated() throws IOException, ServletException { - CollectorRegistry registry = new CollectorRegistry(); - Gauge.build("a", "a help").register(registry); - - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getHeader("Accept")).thenReturn("application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"); - HttpServletResponse resp = mock(HttpServletResponse.class); - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter); - when(resp.getWriter()).thenReturn(writer); - - new MetricsServlet(registry).doGet(req, resp); - - assertThat(stringWriter.toString()).contains("a 0.0"); - assertThat(stringWriter.toString()).contains("# EOF"); - } - -} diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java b/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java deleted file mode 100644 index 40bccaa6f..000000000 --- a/simpleclient_servlet/src/test/java/io/prometheus/client/filter/MetricsFilterTest.java +++ /dev/null @@ -1,257 +0,0 @@ -package io.prometheus.client.filter; - -import io.prometheus.client.Collector; -import io.prometheus.client.CollectorRegistry; -import org.eclipse.jetty.http.HttpMethods; -import org.junit.After; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Enumeration; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class MetricsFilterTest { - MetricsFilter f = new MetricsFilter(); - - @After - public void clear() { - CollectorRegistry.defaultRegistry.clear(); - } - - @Test - public void init() throws Exception { - FilterConfig cfg = mock(FilterConfig.class); - when(cfg.getInitParameter(anyString())).thenReturn(null); - - String metricName = "foo"; - - when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn(metricName); - when(cfg.getInitParameter(MetricsFilter.PATH_COMPONENT_PARAM)).thenReturn("4"); - - f.init(cfg); - - assertEquals(f.pathComponents, 4); - - HttpServletRequest req = mock(HttpServletRequest.class); - - when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang/zilch/zip/nada"); - when(req.getMethod()).thenReturn(HttpMethods.GET); - - HttpServletResponse res = mock(HttpServletResponse.class); - FilterChain c = mock(FilterChain.class); - - f.doFilter(req, res, c); - - verify(c).doFilter(req, res); - - final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(metricName + "_count", new String[]{"path", "method"}, new String[]{"/foo/bar/baz/bang", HttpMethods.GET}); - assertNotNull(sampleValue); - assertEquals(1, sampleValue, 0.0001); - } - - @Test - public void doFilter() throws Exception { - HttpServletRequest req = mock(HttpServletRequest.class); - final String path = "/foo/bar/baz/bang/zilch/zip/nada"; - - when(req.getRequestURI()).thenReturn(path); - when(req.getMethod()).thenReturn(HttpMethods.GET); - - HttpServletResponse res = mock(HttpServletResponse.class); - FilterChain c = mock(FilterChain.class); - - String name = "foo"; - FilterConfig cfg = mock(FilterConfig.class); - when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn(name); - when(cfg.getInitParameter(MetricsFilter.PATH_COMPONENT_PARAM)).thenReturn("0"); - - f.init(cfg); - f.doFilter(req, res, c); - - verify(c).doFilter(req, res); - - - final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(name + "_count", new String[]{"path", "method"}, new String[]{path, HttpMethods.GET}); - assertNotNull(sampleValue); - assertEquals(1, sampleValue, 0.0001); - } - - @Test - public void testConstructor() throws Exception { - HttpServletRequest req = mock(HttpServletRequest.class); - final String path = "/foo/bar/baz/bang"; - when(req.getRequestURI()).thenReturn(path); - when(req.getMethod()).thenReturn(HttpMethods.POST); - - FilterChain c = mock(FilterChain.class); - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocationOnMock) throws Throwable { - Thread.sleep(100); - return null; - } - }).when(c).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); - - MetricsFilter constructed = new MetricsFilter( - "foobar_baz_filter_duration_seconds", - "Help for my filter", - 0, - null - ); - constructed.init(mock(FilterConfig.class)); - - HttpServletResponse res = mock(HttpServletResponse.class); - constructed.doFilter(req, res, c); - - final Double sum = CollectorRegistry.defaultRegistry.getSampleValue("foobar_baz_filter_duration_seconds_sum", new String[]{"path", "method"}, new String[]{path, HttpMethods.POST}); - assertNotNull(sum); - assertEquals(0.1, sum, 0.01); - } - - @Test - public void testBucketsAndName() throws Exception { - HttpServletRequest req = mock(HttpServletRequest.class); - final String path = "/foo/bar/baz/bang"; - when(req.getRequestURI()).thenReturn(path); - when(req.getMethod()).thenReturn(HttpMethods.POST); - - FilterChain c = mock(FilterChain.class); - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocationOnMock) throws Throwable { - Thread.sleep(100); - return null; - } - }).when(c).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); - - final String buckets = "0.01,0.05,0.1,0.15,0.25"; - FilterConfig cfg = mock(FilterConfig.class); - when(cfg.getInitParameter(MetricsFilter.BUCKET_CONFIG_PARAM)).thenReturn(buckets); - when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn("foo"); - - HttpServletResponse res = mock(HttpServletResponse.class); - - f.init(cfg); - - f.doFilter(req, res, c); - - final Double sum = CollectorRegistry.defaultRegistry.getSampleValue("foo_sum", new String[]{"path", "method"}, new String[]{"/foo", HttpMethods.POST}); - assertEquals(0.1, sum, 0.01); - - final Double le05 = CollectorRegistry.defaultRegistry.getSampleValue("foo_bucket", new String[]{"path", "method", "le"}, new String[]{"/foo", HttpMethods.POST, "0.05"}); - assertNotNull(le05); - assertEquals(0, le05, 0.01); - final Double le15 = CollectorRegistry.defaultRegistry.getSampleValue("foo_bucket", new String[]{"path", "method", "le"}, new String[]{"/foo", HttpMethods.POST, "0.15"}); - assertNotNull(le15); - assertEquals(1, le15, 0.01); - - - final Enumeration samples = CollectorRegistry.defaultRegistry.metricFamilySamples(); - Collector.MetricFamilySamples sample = null; - while(samples.hasMoreElements()) { - sample = samples.nextElement(); - if (sample.name.equals("foo")) { - break; - } - } - - assertNotNull(sample); - - int count = 0; - for (Collector.MetricFamilySamples.Sample s : sample.samples) { - if (s.name.equals("foo_bucket")) { - count++; - } - } - // +1 because of the final le=+infinity bucket - assertEquals(buckets.split(",").length+1, count); - } - - @Test - public void testStatusCode() throws Exception { - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang"); - when(req.getMethod()).thenReturn(HttpMethods.GET); - - HttpServletResponse res = mock(HttpServletResponse.class); - when(res.getStatus()).thenReturn(200); - - FilterChain c = mock(FilterChain.class); - - MetricsFilter constructed = new MetricsFilter( - "foobar_filter", - "Help for my filter", - 2, - null - ); - constructed.init(mock(FilterConfig.class)); - - constructed.doFilter(req, res, c); - - final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue("foobar_filter_status_total", new String[]{"path", "method", "status"}, new String[]{"/foo/bar", HttpMethods.GET, "200"}); - assertNotNull(sampleValue); - assertEquals(1, sampleValue, 0.0001); - } - - @Test - public void testStatusCodeWithNonHttpServletResponse() throws Exception { - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang"); - when(req.getMethod()).thenReturn(HttpMethods.GET); - - ServletResponse res = mock(ServletResponse.class); - - FilterChain c = mock(FilterChain.class); - - MetricsFilter constructed = new MetricsFilter( - "foobar_filter", - "Help for my filter", - 2, - null - ); - constructed.init(mock(FilterConfig.class)); - - constructed.doFilter(req, res, c); - - final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue("foobar_filter_status_total", new String[]{"path", "method", "status"}, new String[]{"/foo/bar", HttpMethods.GET, MetricsFilter.UNKNOWN_HTTP_STATUS_CODE}); - assertNotNull(sampleValue); - assertEquals(1, sampleValue, 0.0001); - } - - @Test - public void testStripContextPath() throws Exception { - String metricName = "foo"; - FilterConfig cfg = mock(FilterConfig.class); - when(cfg.getInitParameter(MetricsFilter.METRIC_NAME_PARAM)).thenReturn(metricName); - when(cfg.getInitParameter(MetricsFilter.PATH_COMPONENT_PARAM)).thenReturn("0"); - when(cfg.getInitParameter(MetricsFilter.STRIP_CONTEXT_PATH_PARAM)).thenReturn("true"); - f.init(cfg); - assertTrue(f.stripContextPath); - HttpServletRequest req = mock(HttpServletRequest.class); - when(req.getRequestURI()).thenReturn("/foo/bar/baz/bang"); - when(req.getContextPath()).thenReturn("/foo/bar"); - when(req.getMethod()).thenReturn(HttpMethods.GET); - HttpServletResponse res = mock(HttpServletResponse.class); - FilterChain c = mock(FilterChain.class); - f.doFilter(req, res, c); - verify(c).doFilter(req, res); - final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(metricName + "_count", new String[]{"path", "method"}, new String[]{"/baz/bang", HttpMethods.GET}); - assertNotNull(sampleValue); - assertEquals(1, sampleValue, 0.0001); - } -} diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml new file mode 100644 index 000000000..d5d203025 --- /dev/null +++ b/simpleclient_servlet_common/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + + io.prometheus + parent + 0.11.1-SNAPSHOT + + + io.prometheus + simpleclient_servlet_common + bundle + + Prometheus Java Simpleclient Servlet - Common + + HTTP servlet exporter for the simpleclient. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + brian-brazil + Brian Brazil + brian.brazil@boxever.com + + + + + UTF-8 + + + + + io.prometheus + simpleclient + 0.11.1-SNAPSHOT + + + io.prometheus + simpleclient_common + 0.11.1-SNAPSHOT + + + + junit + junit + 4.13.2 + test + + + org.assertj + assertj-core + 2.6.0 + test + + + diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java new file mode 100644 index 000000000..f48e2259c --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java @@ -0,0 +1,5 @@ +package io.prometheus.client.servlet.common.adapter; + +public interface FilterConfigAdapter { + String getInitParameter(String name); +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java new file mode 100644 index 000000000..d8b70b94c --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java @@ -0,0 +1,9 @@ +package io.prometheus.client.servlet.common.adapter; + +public interface HttpServletRequestAdapter { + String getHeader(String name); + String getRequestURI(); + String getMethod(); + String[] getParameterValues(String name); + String getContextPath(); +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java new file mode 100644 index 000000000..cb140dd83 --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java @@ -0,0 +1,11 @@ +package io.prometheus.client.servlet.common.adapter; + +import java.io.IOException; +import java.io.PrintWriter; + +public interface HttpServletResponseAdapter { + int getStatus(); + void setStatus(int httpStatusCode); + void setContentType(String contentType); + PrintWriter getWriter() throws IOException; +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java new file mode 100644 index 000000000..4797710b0 --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java @@ -0,0 +1,66 @@ +package io.prometheus.client.servlet.common.exporter; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; +import io.prometheus.client.exporter.common.TextFormat; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * The MetricsServlet class exists to provide a simple way of exposing the metrics values. + * + */ +public class Exporter { + + private CollectorRegistry registry; + + /** + * Construct a MetricsServlet for the default registry. + */ + public Exporter() { + this(CollectorRegistry.defaultRegistry); + } + + /** + * Construct a MetricsServlet for the given registry. + * @param registry collector registry + */ + public Exporter(CollectorRegistry registry) { + this.registry = registry; + } + + public void doGet(final HttpServletRequestAdapter req, final HttpServletResponseAdapter resp) throws IOException { + resp.setStatus(200); + String contentType = TextFormat.chooseContentType(req.getHeader("Accept")); + resp.setContentType(contentType); + + Writer writer = new BufferedWriter(resp.getWriter()); + try { + TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(parse(req))); + writer.flush(); + } finally { + writer.close(); + } + } + + private Set parse(HttpServletRequestAdapter req) { + String[] includedParam = req.getParameterValues("name[]"); + if (includedParam == null) { + return Collections.emptySet(); + } else { + return new HashSet(Arrays.asList(includedParam)); + } + } + + public void doPost(final HttpServletRequestAdapter req, final HttpServletResponseAdapter resp) + throws IOException { + doGet(req, resp); + } +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java new file mode 100644 index 000000000..9acb2f3a5 --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java @@ -0,0 +1,170 @@ +package io.prometheus.client.servlet.common.filter; + +import io.prometheus.client.*; +import io.prometheus.client.servlet.common.adapter.*; + +/** + * Filter implements the common functionality provided by the two MetricsFilter implementations: + *
    + *
  • javax version: {@code io.prometheus.client.filter.MetricsFilter} provided by {@code simpleclient_servlet} + *
  • jakarta version: {@code io.prometheus.client.servlet.jakarta.filter.MetricsFilter} provided by {@code simpleclient_servlet_jakarta} + *
+ * @author Andrew Stuart <andrew.stuart2@gmail.com> + */ +public class Filter { + static final String PATH_COMPONENT_PARAM = "path-components"; + static final String HELP_PARAM = "help"; + static final String METRIC_NAME_PARAM = "metric-name"; + static final String BUCKET_CONFIG_PARAM = "buckets"; + static final String STRIP_CONTEXT_PATH_PARAM = "strip-context-path"; + + private Histogram histogram = null; + private Counter statusCounter = null; + + // Package-level for testing purposes. + int pathComponents = 1; + private String metricName = null; + boolean stripContextPath = false; + private String help = "The time taken fulfilling servlet requests"; + private double[] buckets = null; + + public Filter() {} + + /** + * If you want to configure the filter programmatically instead of via {@code web.xml}, you can + * pass all configuration parameters to this constructor. + */ + public Filter( + String metricName, + String help, + Integer pathComponents, + double[] buckets, + boolean stripContextPath) { + this.metricName = metricName; + this.buckets = buckets; + if (help != null) { + this.help = help; + } + if (pathComponents != null) { + this.pathComponents = pathComponents; + } + this.stripContextPath = stripContextPath; + } + + private boolean isEmpty(String s) { + return s == null || s.length() == 0; + } + + private String getComponents(String str) { + if (str == null || pathComponents < 1) { + return str; + } + int count = 0; + int i = -1; + do { + i = str.indexOf("/", i + 1); + if (i < 0) { + // Path is longer than specified pathComponents. + return str; + } + count++; + } while (count <= pathComponents); + + return str.substring(0, i); + } + + /** + * Common implementation of {@code javax.servlet.Filter.init()} and {@code jakarta.servlet.Filter.init()}. + */ + public void init(FilterConfigAdapter filterConfig) throws FilterConfigurationException { + Histogram.Builder builder = Histogram.build() + .labelNames("path", "method"); + + if (filterConfig == null && isEmpty(metricName)) { + throw new FilterConfigurationException("No configuration object provided, and no metricName passed via constructor"); + } + + if (filterConfig != null) { + if (isEmpty(metricName)) { + metricName = filterConfig.getInitParameter(METRIC_NAME_PARAM); + if (isEmpty(metricName)) { + throw new FilterConfigurationException("Init parameter \"" + METRIC_NAME_PARAM + "\" is required; please supply a value"); + } + } + + if (!isEmpty(filterConfig.getInitParameter(HELP_PARAM))) { + help = filterConfig.getInitParameter(HELP_PARAM); + } + + // Allow users to override the default bucket configuration + if (!isEmpty(filterConfig.getInitParameter(BUCKET_CONFIG_PARAM))) { + String[] bucketParams = filterConfig.getInitParameter(BUCKET_CONFIG_PARAM).split(","); + buckets = new double[bucketParams.length]; + + for (int i = 0; i < bucketParams.length; i++) { + buckets[i] = Double.parseDouble(bucketParams[i]); + } + } + + // Allow overriding of the path "depth" to track + if (!isEmpty(filterConfig.getInitParameter(PATH_COMPONENT_PARAM))) { + pathComponents = Integer.parseInt(filterConfig.getInitParameter(PATH_COMPONENT_PARAM)); + } + + if (!isEmpty(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM))) { + stripContextPath = Boolean.parseBoolean(filterConfig.getInitParameter(STRIP_CONTEXT_PATH_PARAM)); + } + } + + if (buckets != null) { + builder = builder.buckets(buckets); + } + + histogram = builder + .help(help) + .name(metricName) + .register(); + + statusCounter = Counter.build(metricName + "_status_total", "HTTP status codes of " + help) + .labelNames("path", "method", "status") + .register(); + } + + /** + * To be called at the beginning of {@code javax.servlet.Filter.doFilter()} or + * {@code jakarta.servlet.Filter.doFilter()}. + */ + public MetricData startTimer(HttpServletRequestAdapter request) { + String path = request.getRequestURI(); + if (stripContextPath) { + path = path.substring(request.getContextPath().length()); + } + String components = getComponents(path); + String method = request.getMethod(); + Histogram.Timer timer = histogram.labels(components, method).startTimer(); + return new MetricData(components, method, timer); + } + + /** + * To be called at the end of {@code javax.servlet.Filter.doFilter()} or + * {@code jakarta.servlet.Filter.doFilter()}. + */ + public void observeDuration(MetricData data, HttpServletResponseAdapter resp) { + String status = Integer.toString(resp.getStatus()); + data.timer.observeDuration(); + statusCounter.labels(data.components, data.method, status).inc(); + } + + public static class MetricData { + + final String components; + final String method; + final Histogram.Timer timer; + + private MetricData(String components, String method, Histogram.Timer timer) { + this.components = components; + this.method = method; + this.timer = timer; + } + } +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java new file mode 100644 index 000000000..5d70f063b --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java @@ -0,0 +1,10 @@ +package io.prometheus.client.servlet.common.filter; + +/** + * Thrown when there is a misconfiguration in {@code web.xml}. + */ +public class FilterConfigurationException extends Exception { + public FilterConfigurationException(String msg) { + super(msg); + } +} diff --git a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java new file mode 100644 index 000000000..ed10fb10f --- /dev/null +++ b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java @@ -0,0 +1,158 @@ +package io.prometheus.client.servlet.common.exporter; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Gauge; +import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Java6Assertions.fail; + +public class ExporterTest { + + private HttpServletRequestAdapter mockHttpServletRequest() { + return mockHttpServletRequest(null, false); + } + + private HttpServletRequestAdapter mockHttpServletRequest(final String[] nameParam, final boolean openMetrics) { + return new HttpServletRequestAdapter() { + @Override + public String getHeader(String name) { + if (openMetrics && "Accept".equals(name)) { + return "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"; + } + return null; + } + + @Override + public String getMethod() { + return null; + } + + @Override + public String getRequestURI() { + return null; + } + + @Override + public String[] getParameterValues(String name) { + if ("name[]".equals(name)) { + return nameParam; + } + return null; + } + + @Override + public String getContextPath() { + return ""; + } + }; + } + + private HttpServletResponseAdapter mockHttpServletResponse(final PrintWriter writer) { + return new HttpServletResponseAdapter() { + @Override + public int getStatus() { + return 0; + } + + @Override + public void setStatus(int httpStatusCode) { + } + + @Override + public void setContentType(String contentType) { + } + + @Override + public PrintWriter getWriter() { + return writer; + } + }; + } + + @Test + public void testWriterFiltersBasedOnParameter() throws IOException { + CollectorRegistry registry = new CollectorRegistry(); + Gauge.build("a", "a help").register(registry); + Gauge.build("b", "a help").register(registry); + Gauge.build("c", "a help").register(registry); + + HttpServletRequestAdapter req = mockHttpServletRequest(new String[]{"a", "b", "oneTheDoesntExist", ""}, false); + StringWriter responseBody = new StringWriter(); + HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); + + new Exporter(registry).doGet(req, resp); + + assertThat(responseBody.toString()).contains("a 0.0"); + assertThat(responseBody.toString()).contains("b 0.0"); + assertThat(responseBody.toString()).doesNotContain("c 0.0"); + } + + @Test + public void testWriterIsClosedNormally() throws IOException { + final AtomicBoolean closed = new AtomicBoolean(false); + StringWriter responseBody = new StringWriter() { + @Override + public void close() { + closed.set(true); + } + }; + HttpServletRequestAdapter req = mockHttpServletRequest(); + HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); + CollectorRegistry registry = new CollectorRegistry(); + Gauge a = Gauge.build("a", "a help").register(registry); + + new Exporter(registry).doGet(req, resp); + Assert.assertTrue(closed.get()); + } + + @Test + public void testWriterIsClosedOnException() { + final AtomicBoolean closed = new AtomicBoolean(false); + StringWriter responseBody = new StringWriter() { + @Override + public void write(char cbuf[], int off, int len) { + throw new RuntimeException(); + } + @Override + public void close() { + closed.set(true); + } + }; + HttpServletRequestAdapter req = mockHttpServletRequest(); + HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); + CollectorRegistry registry = new CollectorRegistry(); + Gauge a = Gauge.build("a", "a help").register(registry); + + try { + new Exporter(registry).doGet(req, resp); + fail("Exception expected"); + } catch (Exception e) { + } + + Assert.assertTrue(closed.get()); + } + + @Test + public void testOpenMetricsNegotiated() throws IOException { + CollectorRegistry registry = new CollectorRegistry(); + Gauge.build("a", "a help").register(registry); + + HttpServletRequestAdapter req = mockHttpServletRequest(null, true); + StringWriter responseBody = new StringWriter(); + HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); + + new Exporter(registry).doGet(req, resp); + + assertThat(responseBody.toString()).contains("a 0.0"); + assertThat(responseBody.toString()).contains("# EOF"); + } +} diff --git a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java new file mode 100644 index 000000000..583b6f1c9 --- /dev/null +++ b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java @@ -0,0 +1,238 @@ +package io.prometheus.client.servlet.common.filter; + +import io.prometheus.client.Collector; +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.exporter.common.TextFormat; +import io.prometheus.client.servlet.common.adapter.FilterConfigAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; +import org.junit.After; +import org.junit.Test; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Enumeration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class FilterTest { + + public static final String GET = "GET"; + public static final String POST = "POST"; + public static final String METRIC_NAME = "foo"; + + private FilterConfigAdapter mockFilterConfig() { + return mockFilterConfig(null, null); + } + + private FilterConfigAdapter mockFilterConfig(final String metricName, final String pathComponents) { + return mockFilterConfig(metricName, pathComponents, null); + } + + private FilterConfigAdapter mockFilterConfig(final String metricName, final String pathComponents, final String buckets) { + return new FilterConfigAdapter() { + @Override + public String getInitParameter(String name) { + if (Filter.METRIC_NAME_PARAM.equals(name)) { + return metricName; + } + if (Filter.PATH_COMPONENT_PARAM.equals(name)) { + return pathComponents; + } + if (Filter.BUCKET_CONFIG_PARAM.equals(name)) { + return buckets; + } + return null; + } + }; + } + + private HttpServletRequestAdapter mockHttpServletRequest(final String method, final String uri) { + return new HttpServletRequestAdapter() { + @Override + public String getHeader(String name) { + return null; + } + + @Override + public String getMethod() { + return method; + } + + @Override + public String getRequestURI() { + return uri; + } + + @Override + public String[] getParameterValues(String name) { + return null; + } + + @Override + public String getContextPath() { + return ""; + } + }; + } + + private HttpServletResponseAdapter mockHttpServletResponse() { + return mockHttpServletResponse(0); + } + + private HttpServletResponseAdapter mockHttpServletResponse(final int status) { + return new HttpServletResponseAdapter() { + @Override + public int getStatus() { + return status; + } + + @Override + public void setStatus(int httpStatusCode) { + } + + @Override + public void setContentType(String contentType) { + } + + @Override + public PrintWriter getWriter() throws IOException { + return null; + } + }; + } + + + @After + public void clear() { + CollectorRegistry.defaultRegistry.clear(); + } + + @Test + public void testPathComponents4() throws Exception { + Filter filter = new Filter(); + String metricName = "foo"; + int pathComponents = 4; + filter.init(mockFilterConfig(metricName, Integer.toString(pathComponents))); + assertEquals(filter.pathComponents, 4); + Filter.MetricData data = filter.startTimer(mockHttpServletRequest(GET, "/foo/bar/baz/bang/zilch/zip/nada")); + filter.observeDuration(data, mockHttpServletResponse()); + + final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(METRIC_NAME + "_count", new String[]{"path", "method"}, new String[]{"/foo/bar/baz/bang", GET}); + assertNotNull(sampleValue); + assertEquals(1, sampleValue, 0.0001); + } + + @Test + public void testPathComponents0() throws Exception { + Filter filter = new Filter(); + String metricName = "foo"; + int pathComponents = 0; + String path = "/foo/bar/baz/bang/zilch/zip/nada"; + filter.init(mockFilterConfig(metricName, Integer.toString(pathComponents))); + assertEquals(filter.pathComponents, 0); + Filter.MetricData data = filter.startTimer(mockHttpServletRequest(GET, path)); + filter.observeDuration(data, mockHttpServletResponse()); + + final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue(metricName + "_count", new String[]{"path", "method"}, new String[]{path, GET}); + assertNotNull(sampleValue); + assertEquals(1, sampleValue, 0.0001); + } + + @Test + public void testConstructor() throws Exception { + final String path = "/foo/bar/baz/bang"; + HttpServletRequestAdapter req = mockHttpServletRequest(POST, path); + HttpServletResponseAdapter res = mockHttpServletResponse(); + + Filter constructed = new Filter( + "foobar_baz_filter_duration_seconds", + "Help for my filter", + 0, + null, + false + ); + constructed.init(mockFilterConfig(null, null)); + + Filter.MetricData data = constructed.startTimer(req); + Thread.sleep(100); + constructed.observeDuration(data, res); + + final Double sum = CollectorRegistry.defaultRegistry.getSampleValue("foobar_baz_filter_duration_seconds_sum", new String[]{"path", "method"}, new String[]{path, POST}); + assertNotNull(sum); + assertEquals(0.1, sum, 0.01); + } + + @Test + public void testBucketsAndName() throws Exception { + final String path = "/foo/bar/baz/bang"; + HttpServletRequestAdapter req = mockHttpServletRequest(POST, path); + + final String buckets = "0.01,0.05,0.1,0.15,0.25"; + FilterConfigAdapter cfg = mockFilterConfig("foo", null, buckets); + + HttpServletResponseAdapter res = mockHttpServletResponse(); + + Filter filter = new Filter(); + filter.init(cfg); + + Filter.MetricData data = filter.startTimer(req); + Thread.sleep(100); + filter.observeDuration(data, res); + + final Double sum = CollectorRegistry.defaultRegistry.getSampleValue("foo_sum", new String[]{"path", "method"}, new String[]{"/foo", POST}); + assertEquals(0.1, sum, 0.01); + + final Double le05 = CollectorRegistry.defaultRegistry.getSampleValue("foo_bucket", new String[]{"path", "method", "le"}, new String[]{"/foo", POST, "0.05"}); + assertNotNull(le05); + assertEquals(0, le05, 0.01); + final Double le15 = CollectorRegistry.defaultRegistry.getSampleValue("foo_bucket", new String[]{"path", "method", "le"}, new String[]{"/foo", POST, "0.15"}); + assertNotNull(le15); + assertEquals(1, le15, 0.01); + + + final Enumeration samples = CollectorRegistry.defaultRegistry.metricFamilySamples(); + Collector.MetricFamilySamples sample = null; + while(samples.hasMoreElements()) { + sample = samples.nextElement(); + if (sample.name.equals("foo")) { + break; + } + } + + assertNotNull(sample); + + int count = 0; + for (Collector.MetricFamilySamples.Sample s : sample.samples) { + if (s.name.equals("foo_bucket")) { + count++; + } + } + // +1 because of the final le=+infinity bucket + assertEquals(buckets.split(",").length+1, count); + } + + @Test + public void testStatusCode() throws Exception { + HttpServletRequestAdapter req = mockHttpServletRequest(GET, "/foo/bar/baz/bang"); + HttpServletResponseAdapter res = mockHttpServletResponse(200); + + Filter constructed = new Filter( + "foobar_filter", + "Help for my filter", + 2, + null, + false + ); + constructed.init(mockFilterConfig()); + + Filter.MetricData data = constructed.startTimer(req); + constructed.observeDuration(data, res); + + final Double sampleValue = CollectorRegistry.defaultRegistry.getSampleValue("foobar_filter_status_total", new String[]{"path", "method", "status"}, new String[]{"/foo/bar", GET, "200"}); + assertNotNull(sampleValue); + assertEquals(1, sampleValue, 0.0001); + } +} diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml new file mode 100644 index 000000000..69bf3424f --- /dev/null +++ b/simpleclient_servlet_jakarta/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + + io.prometheus + parent + 0.11.1-SNAPSHOT + + + io.prometheus + simpleclient_servlet_jakarta + bundle + + Prometheus Java Simpleclient Servlet - Jakarta + + HTTP jakarta servlet exporter for the simpleclient. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + brian-brazil + Brian Brazil + brian.brazil@boxever.com + + + + + UTF-8 + + + + + io.prometheus + simpleclient + 0.11.1-SNAPSHOT + + + io.prometheus + simpleclient_common + 0.11.1-SNAPSHOT + + + io.prometheus + simpleclient_servlet_common + 0.11.1-SNAPSHOT + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + + + junit + junit + 4.13.2 + test + + + org.assertj + assertj-core + 2.6.0 + test + + + org.eclipse.jetty + jetty-servlet + 11.0.2 + test + + + org.mockito + mockito-core + 2.28.2 + test + + + diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java new file mode 100644 index 000000000..3321a1582 --- /dev/null +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java @@ -0,0 +1,103 @@ +package io.prometheus.client.servlet.jakarta; + +import io.prometheus.client.servlet.common.adapter.FilterConfigAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; +import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; + +import jakarta.servlet.FilterConfig; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +public class Adapter { + + private static class HttpServletRequestAdapterImpl implements HttpServletRequestAdapter { + + private final HttpServletRequest delegate; + + HttpServletRequestAdapterImpl(HttpServletRequest delegate) { + this.delegate = delegate; + } + + @Override + public String getHeader(String name) { + return delegate.getHeader(name); + } + + @Override + public String getRequestURI() { + return delegate.getRequestURI(); + } + + @Override + public String getMethod() { + return delegate.getMethod(); + } + + @Override + public String[] getParameterValues(String name) { + return delegate.getParameterValues(name); + } + + @Override + public String getContextPath() { + return delegate.getContextPath(); + } + } + + private static class HttpServletResponseAdapterImpl implements HttpServletResponseAdapter { + + private final HttpServletResponse delegate; + + HttpServletResponseAdapterImpl(HttpServletResponse delegate) { + this.delegate = delegate; + } + + @Override + public void setStatus(int httpStatusCode) { + delegate.setBufferSize(httpStatusCode); + } + + @Override + public void setContentType(String contentType) { + delegate.setContentType(contentType); + } + + @Override + public PrintWriter getWriter() throws IOException { + return delegate.getWriter(); + } + + @Override + public int getStatus() { + return delegate.getStatus(); + } + } + + private static class FilterConfigAdapterImpl implements FilterConfigAdapter { + + private final FilterConfig delegate; + + private FilterConfigAdapterImpl(FilterConfig delegate) { + this.delegate = delegate; + } + + @Override + public String getInitParameter(String name) { + return delegate.getInitParameter(name); + } + } + + public static HttpServletRequestAdapter wrap(HttpServletRequest req) { + return new HttpServletRequestAdapterImpl(req); + } + + public static HttpServletResponseAdapter wrap(HttpServletResponse resp) { + return new HttpServletResponseAdapterImpl(resp); + } + + public static FilterConfigAdapter wrap(FilterConfig filterConfig) { + return new FilterConfigAdapterImpl(filterConfig); + } +} \ No newline at end of file diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java new file mode 100644 index 000000000..749d835f9 --- /dev/null +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java @@ -0,0 +1,28 @@ +package io.prometheus.client.servlet.jakarta.exporter; + +import io.prometheus.client.servlet.common.exporter.Exporter; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static io.prometheus.client.servlet.jakarta.Adapter.wrap; + +/** + * The MetricsServlet class provides a simple way of exposing the metrics values. + */ +public class MetricsServlet extends HttpServlet { + + private final Exporter exporter = new Exporter(); + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { + exporter.doGet(wrap(req), wrap(resp)); + } + + @Override + protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { + exporter.doPost(wrap(req), wrap(resp)); + } +} diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java new file mode 100644 index 000000000..47452a687 --- /dev/null +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java @@ -0,0 +1,125 @@ +package io.prometheus.client.servlet.jakarta.filter; + +import io.prometheus.client.servlet.jakarta.Adapter; +import io.prometheus.client.servlet.common.filter.Filter; +import io.prometheus.client.servlet.common.filter.FilterConfigurationException; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * The MetricsFilter class provides a high-level filter that enables tunable collection of metrics for Servlet + * performance. + * + * This is the Jakarta version of the MetricsFilter. If you are using Javax Servlet, there is a Javax version + * available in {@code simpleclient-servlet}. + * + *

The metric name itself is required, and configured with a {@code metric-name} init parameter. + * + *

The help parameter, configured with the {@code help} init parameter, is not required but strongly recommended. + * + *

The Histogram buckets can be configured with a {@code buckets} init parameter whose value is a comma-separated + * list * of valid {@code double} values. If omitted, the default buckets from {@link io.prometheus.client.Histogram} + * are used. + * + *

By default, this filter will provide metrics that distinguish only 1 level deep for the request path + * (including servlet context path), but can be configured with the {@code path-components} init parameter. Any number + * provided that is less than 1 will provide the full path granularity (warning, this may affect performance). + * + *

The {@code strip-context-path} init parameter can be used to avoid including the leading path components which are + * part of the context (i.e. the folder where the servlet is deployed) so that the same project deployed under different + * paths can produce the same metrics. + * + *

HTTP statuses will be aggregated via Counter. The name for this counter will be derived from the + * {@code metric-name} init parameter. + * + *

{@code
+ * 
+ *   prometheusFilter
+ *   
+ *   
+ *   io.prometheus.client.filter.MetricsFilter
+ *   
+ *     metric-name
+ *     webapp_metrics_filter
+ *   
+ *   
+ *   
+ *     help
+ *     This is the help for your metrics filter
+ *   
+ *   
+ *   
+ *     buckets
+ *     0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10
+ *   
+ *   
+ *   
+ *     path-components
+ *     1
+ *   
+ *   
+ *   
+ *     strip-context-path
+ *     false
+ *   
+ * 
+ *
+ * 
+ * 
+ *   prometheusFilter
+ *   /*
+ * 
+ * }
+ */ +public class MetricsFilter implements jakarta.servlet.Filter { + + private final Filter delegate; + + public MetricsFilter() { + this.delegate = new Filter(); + } + + /** + * See {@link Filter#Filter(String, String, Integer, double[], boolean)}. + */ + public MetricsFilter( + String metricName, + String help, + Integer pathComponents, + double[] buckets, + boolean stripContextPath) { + this.delegate = new Filter(metricName, help, pathComponents, buckets, stripContextPath); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + try { + delegate.init(Adapter.wrap(filterConfig)); + } catch (FilterConfigurationException e) { + throw new ServletException(e); + } + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) { + filterChain.doFilter(servletRequest, servletResponse); + return; + } + Filter.MetricData data = delegate.startTimer(Adapter.wrap((HttpServletRequest) servletRequest)); + try { + filterChain.doFilter(servletRequest, servletResponse); + } finally { + delegate.observeDuration(data, Adapter.wrap((HttpServletResponse) servletResponse)); + } + } + + @Override + public void destroy() { + } +} diff --git a/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java b/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java new file mode 100644 index 000000000..30936a60c --- /dev/null +++ b/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java @@ -0,0 +1,56 @@ +package io.prometheus.client.exporter; + +import io.prometheus.client.Gauge; + +import io.prometheus.client.servlet.jakarta.exporter.MetricsServlet; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.UUID; + +public class ExampleBenchmark { + + public static void main(String[] args) throws Exception { + + Gauge gauge = Gauge.build().name("labels").help("foo").labelNames("bar").register(); + for (int i = 0; i < 10000; i++) { + gauge.labels(UUID.randomUUID().toString()).set(Math.random()); + } + + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics"); + + Server server = new Server(0); + server.setHandler(context); + server.start(); + Thread.sleep(1000); + + ServerConnector connector = (ServerConnector) server.getConnectors()[0]; + byte[] bytes = new byte[8192]; + URL url = new URL("http", "localhost", connector.getLocalPort(), "/metrics"); + + long start = System.nanoTime(); + for (int i = 0; i < 100; i++) { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + InputStream in = connection.getInputStream(); + try { + while (in.read(bytes) != -1) in.available(); + } finally { + in.close(); + } + connection.disconnect(); + } + System.out.println(String.format("%,3d ns", System.nanoTime() - start)); + + server.stop(); + server.join(); + + } + +} diff --git a/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java b/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java new file mode 100644 index 000000000..5d4871818 --- /dev/null +++ b/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java @@ -0,0 +1,35 @@ +package io.prometheus.client.exporter; + +import io.prometheus.client.Counter; +import io.prometheus.client.Gauge; +import io.prometheus.client.Histogram; +import io.prometheus.client.Summary; +import io.prometheus.client.servlet.jakarta.exporter.MetricsServlet; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +public class ExampleExporter { + + static final Gauge g = Gauge.build().name("gauge").help("blah").register(); + static final Counter c = Counter.build().name("counter").help("meh").register(); + static final Summary s = Summary.build().name("summary").help("meh").register(); + static final Histogram h = Histogram.build().name("histogram").help("meh").register(); + static final Gauge l = Gauge.build().name("labels").help("blah").labelNames("l").register(); + + public static void main(String[] args) throws Exception { + Server server = new Server(1234); + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + server.setHandler(context); + context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics"); + g.set(1); + c.inc(2); + s.observe(3); + h.observe(4); + l.labels("foo").inc(5); + server.start(); + server.join(); + } + +} From 17c98ebe505e583ffe9927f8ab9d910426860c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 7 Aug 2021 00:25:35 +0200 Subject: [PATCH 088/980] Prevent name conflicts and rename jvm_classes_loaded (#681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../io/prometheus/client/CollectorRegistry.java | 15 ++++++++++++++- .../client/hotspot/ClassLoadingExports.java | 4 ++-- .../client/hotspot/ClassLoadingExportsTest.java | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index 55d33287d..0d37cca27 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -48,10 +48,13 @@ public CollectorRegistry(boolean autoDescribe) { */ public void register(Collector m) { List names = collectorNames(m); + assertNoDuplicateNames(m, names); synchronized (namesCollectorsLock) { for (String name : names) { if (namesToCollectors.containsKey(name)) { - throw new IllegalArgumentException("Collector already registered that provides name: " + name); + throw new IllegalArgumentException("Failed to register Collector of type " + m.getClass().getSimpleName() + + ": " + name + " is already in use by another Collector of type " + + namesToCollectors.get(name).getClass().getSimpleName()); } } for (String name : names) { @@ -61,6 +64,16 @@ public void register(Collector m) { } } + private void assertNoDuplicateNames(Collector m, List names) { + Set uniqueNames = new HashSet(); + for (String name : names) { + if (!uniqueNames.add(name)) { + throw new IllegalArgumentException("Failed to register Collector of type " + m.getClass().getSimpleName() + + ": The Collector exposes the same name multiple times: " + name); + } + } + } + /** * Unregister a Collector. */ diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java index 65f86cfba..feeffe11f 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java @@ -20,7 +20,7 @@ * * Example metrics being exported: *
- *   jvm_classes_loaded{} 1000
+ *   jvm_classes_currently_loaded{} 1000
  *   jvm_classes_loaded_total{} 2000
  *   jvm_classes_unloaded_total{} 500
  * 
@@ -38,7 +38,7 @@ public ClassLoadingExports(ClassLoadingMXBean clBean) { void addClassLoadingMetrics(List sampleFamilies) { sampleFamilies.add(new GaugeMetricFamily( - "jvm_classes_loaded", + "jvm_classes_currently_loaded", "The number of classes that are currently loaded in the JVM", clBean.getLoadedClassCount())); sampleFamilies.add(new CounterMetricFamily( diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java index 62370dc67..b407e00d3 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java @@ -13,7 +13,7 @@ public class ClassLoadingExportsTest { private ClassLoadingMXBean mockClassLoadingsBean = Mockito.mock(ClassLoadingMXBean.class); - private CollectorRegistry registry = new CollectorRegistry(); + private CollectorRegistry registry = new CollectorRegistry(true); private ClassLoadingExports collectorUnderTest; private static final String[] EMPTY_LABEL = new String[0]; @@ -31,7 +31,7 @@ public void testClassLoading() { assertEquals( 1000, registry.getSampleValue( - "jvm_classes_loaded", EMPTY_LABEL, EMPTY_LABEL), + "jvm_classes_currently_loaded", EMPTY_LABEL, EMPTY_LABEL), .0000001); assertEquals( 2000L, From e68daf23336eb5de7856df406eb1d497f51ad3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 26 Aug 2021 22:27:29 +0200 Subject: [PATCH 089/980] Add a sample name filter for in-/excluding metrics by name or name prefix (#680) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- README.md | 12 +- integration_tests/example_application/pom.xml | 2 +- integration_tests/exemplars_otel/pom.xml | 2 +- integration_tests/pom.xml | 1 + .../servlet_jakarta_exporter_webxml/pom.xml | 116 +++++++ .../it/servlet/jakarta/ExampleServlet.java | 27 ++ .../src/main/webapp/WEB-INF/web.xml | 43 +++ .../ServletJakartaExporterWebXmlIT.java | 113 +++++++ .../src/test/resources/Dockerfile | 2 + .../src/test/resources/logback-test.xml | 14 + pom.xml | 4 - .../java/io/prometheus/client/Collector.java | 125 ++++++- .../prometheus/client/CollectorRegistry.java | 95 ++---- .../java/io/prometheus/client/Predicate.java | 8 + .../prometheus/client/SampleNameFilter.java | 242 ++++++++++++++ .../java/io/prometheus/client/Supplier.java | 8 + .../client/CollectorRegistryTest.java | 64 +--- .../client/SampleNameFilterTest.java | 304 ++++++++++++++++++ .../client/hotspot/BufferPoolsExports.java | 83 +++-- .../client/hotspot/ClassLoadingExports.java | 49 ++- .../hotspot/GarbageCollectorExports.java | 32 +- .../client/hotspot/MemoryPoolsExports.java | 294 ++++++++++------- .../client/hotspot/ThreadExports.java | 135 +++++--- .../client/exporter/HTTPServer.java | 221 +++++++++++-- .../exporter/SampleNameFilterSupplier.java | 26 ++ .../client/exporter/TestDaemonFlags.java | 2 +- .../client/exporter/TestHTTPServer.java | 165 ++++++---- .../java/io/prometheus/client/Adapter.java | 20 ++ .../client/exporter/MetricsServlet.java | 26 +- .../common/adapter/ServletConfigAdapter.java | 5 + .../servlet/common/exporter/Exporter.java | 52 ++- .../ServletConfigurationException.java | 4 + .../servlet/common/exporter/ExporterTest.java | 8 +- .../client/servlet/jakarta/Adapter.java | 20 ++ .../jakarta/exporter/MetricsServlet.java | 32 +- 35 files changed, 1898 insertions(+), 458 deletions(-) create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/pom.xml create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile create mode 100644 integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml create mode 100644 simpleclient/src/main/java/io/prometheus/client/Predicate.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java create mode 100644 simpleclient/src/main/java/io/prometheus/client/Supplier.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java create mode 100644 simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java create mode 100644 simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java diff --git a/README.md b/README.md index f62a6e90a..2aa8044a8 100644 --- a/README.md +++ b/README.md @@ -672,9 +672,14 @@ There are HTTPServer, Servlet, SpringBoot, and Vert.x integrations included in t The simplest of these is the HTTPServer: ```java -HTTPServer server = new HTTPServer(1234); +HTTPServer server = new HTTPServer.Builder() + .withPort(1234) + .build(); ``` +The `HTTPServer.Builder` supports configuration of a `SampleNameFilter` which can be used to +restrict the time series being exported by name. + To add Prometheus exposition to an existing HTTP server using servlets, see the `MetricsServlet`. It also serves as a simple example of how to write a custom endpoint. @@ -689,11 +694,14 @@ server.setHandler(context); context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics"); ``` +Like the HTTPServer, the `MetricsServlet` can be configured with a `SampleNameFilter` which can +be used to restrict the time series being exported by name. See `integration_tests/servlet_jakarta_exporter_webxml/` +for an example how to configure this in `web.xml`. + All HTTP exposition integrations support restricting which time series to return using `?name[]=` URL parameters. Due to implementation limitations, this may have false negatives. - ## Exporting to a Pushgateway The [Pushgateway](https://github.com/prometheus/pushgateway) diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index 7faa6a7de..b8618f9c1 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -30,7 +30,7 @@ - ${artifactId} + ${project.artifactId} org.apache.maven.plugins diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index eaac05f2f..186b5dbae 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -54,7 +54,7 @@ - ${artifactId} + ${project.artifactId} org.apache.maven.plugins diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index fa2609678..9a5d87099 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -26,6 +26,7 @@ exemplars_otel_agent example_application java_versions + servlet_jakarta_exporter_webxml diff --git a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml new file mode 100644 index 000000000..582c5b7da --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.11.1-SNAPSHOT + + + servlet_jakarta_exporter_webxml + Integration Test - Servlet Jakarta Exporter web.xml + war + + + 1.2.0 + + + + + io.prometheus + simpleclient + ${project.version} + + + io.prometheus + simpleclient_servlet_jakarta + ${project.version} + + + io.prometheus + simpleclient_hotspot + ${project.version} + + + com.squareup.okhttp3 + okhttp + 4.9.1 + + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + 1.1.2 + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + integration-test + integration-test + + integration-test + + + + verify + verify + + verify + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + + + + maven-war-plugin + 3.3.1 + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java b/integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java new file mode 100644 index 000000000..e5bc220df --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java @@ -0,0 +1,27 @@ +package io.prometheus.client.it.servlet.jakarta; + +import io.prometheus.client.hotspot.DefaultExports; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; + +public class ExampleServlet extends HttpServlet { + + @Override + public void init() { + DefaultExports.initialize(); + } + + @Override + protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { + resp.setStatus(200); + resp.setContentType("text/plain"); + Writer writer = new BufferedWriter(resp.getWriter()); + writer.write("Hello, world!\n"); + writer.close(); + } +} diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml b/integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..4cff3cde6 --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,43 @@ + + + + + example + io.prometheus.client.it.servlet.jakarta.ExampleServlet + + + + prometheus + io.prometheus.client.servlet.jakarta.filter.MetricsFilter + + metric-name + requests + + + + prometheus-exporter + io.prometheus.client.servlet.jakarta.exporter.MetricsServlet + + name-must-not-start-with + + jvm_threads_deadlocked + jvm_memory_pool + + + + + example + /* + + + prometheus-exporter + /metrics + + + prometheus + example + + \ No newline at end of file diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java b/integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java new file mode 100644 index 000000000..d560ae532 --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java @@ -0,0 +1,113 @@ +package io.prometheus.client.it.servlet.jakarta; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +public class ServletJakartaExporterWebXmlIT { + + private final OkHttpClient client = new OkHttpClient(); + + private static class DockerContainer extends GenericContainer { + DockerContainer() { + super(new ImageFromDockerfile("servlet-jakarta-exporter-webxml") + .withFileFromPath("servlet_jakarta_exporter_webxml.war", Paths.get("target/servlet_jakarta_exporter_webxml.war")) + .withFileFromClasspath("Dockerfile", "Dockerfile")); + } + } + + @Rule + public DockerContainer dockerContainer = new DockerContainer() + .withExposedPorts(8080) + .waitingFor(Wait.forLogMessage(".*oejs.Server:main: Started Server.*", 1)); + + @Test + public void testSampleNameFilter() throws IOException, InterruptedException { + callExampleServlet(); + List metrics = scrapeMetrics(); + assertContains(metrics, "requests_bucket"); + assertContains(metrics, "requests_count"); + assertContains(metrics, "requests_sum"); + assertContains(metrics, "requests_created"); + assertContains(metrics, "requests_status_total"); + assertContains(metrics, "requests_status_created"); + assertContains(metrics, "jvm_gc_collection_seconds_count"); + assertNotContains(metrics, "jvm_threads_deadlocked"); + assertNotContains(metrics, "jvm_memory_pool"); + + List filteredMetrics = scrapeMetricsWithNameFilter("requests_count", "requests_sum"); + assertNotContains(filteredMetrics, "requests_bucket"); + assertContains(filteredMetrics, "requests_count"); + assertContains(filteredMetrics, "requests_sum"); + assertNotContains(filteredMetrics, "requests_created"); + assertNotContains(filteredMetrics, "requests_status_total"); + assertNotContains(filteredMetrics, "requests_status_created"); + assertNotContains(filteredMetrics, "jvm_gc_collection_seconds_count"); + assertNotContains(filteredMetrics, "jvm_threads_deadlocked"); + assertNotContains(filteredMetrics, "jvm_memory_pool"); + } + + private void assertContains(List metrics, String prefix) { + for (String metric : metrics) { + if (metric.startsWith(prefix)) { + return; + } + } + Assert.fail("metric not found: " + prefix); + } + private void assertNotContains(List metrics, String prefix) { + for (String metric : metrics) { + if (metric.startsWith(prefix)) { + Assert.fail("unexpected metric found: " + metric); + } + } + } + private void callExampleServlet() throws IOException { + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/hello") + .build(); + try (Response response = client.newCall(request).execute()) { + Assert.assertEquals("Hello, world!\n", response.body().string()); + } + } + + private List scrapeMetrics() throws IOException { + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/metrics") + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .build(); + try (Response response = client.newCall(request).execute()) { + return Arrays.asList(response.body().string().split("\\n")); + } + } + + private List scrapeMetricsWithNameFilter(String... names) throws IOException { + StringBuilder param = new StringBuilder(); + boolean first = true; + for (String name : names) { + if (!first) { + param.append("&"); + } + param.append("name[]=").append(name); + first = false; + } + Request request = new Request.Builder() + .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/metrics?" + param) + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .build(); + try (Response response = client.newCall(request).execute()) { + return Arrays.asList(response.body().string().split("\\n")); + } + } +} \ No newline at end of file diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile b/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile new file mode 100644 index 000000000..abd1416db --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile @@ -0,0 +1,2 @@ +FROM jetty:11.0.6 +COPY servlet_jakarta_exporter_webxml.war /var/lib/jetty/webapps/ROOT.war diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml b/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2b4a05bde..08de32541 100644 --- a/pom.xml +++ b/pom.xml @@ -88,10 +88,6 @@ maven-install-plugin 2.4 - - maven-deploy-plugin - 2.7 - maven-resources-plugin 2.6 diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java index fd02a0c1a..3a69500dc 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Collector.java +++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java @@ -17,10 +17,48 @@ * @see Exposition formats. */ public abstract class Collector { + /** - * Return all of the metrics of this Collector. + * Return all metrics of this Collector. */ public abstract List collect(); + + /** + * Like {@link #collect()}, but the result should only contain {@code MetricFamilySamples} where + * {@code sampleNameFilter.test(name)} is {@code true} for at least one Sample name. + *

+ * The default implementation first collects all {@code MetricFamilySamples} and then discards the ones + * where {@code sampleNameFilter.test(name)} returns {@code false} for all names in + * {@link MetricFamilySamples#getNames()}. + * To improve performance, collector implementations should override this method to prevent + * {@code MetricFamilySamples} from being collected if they will be discarded anyways. + * See {@code ThreadExports} for an example. + *

+ * Note that the resulting List may contain {@code MetricFamilySamples} where some Sample names return + * {@code true} for {@code sampleNameFilter.test(name)} but some Sample names return {@code false}. + * This is ok, because before we produce the output format we will call + * {@link MetricFamilySamples#filter(Predicate)} to strip all Samples where {@code sampleNameFilter.test(name)} + * returns {@code false}. + * + * @param sampleNameFilter may be {@code null}, indicating that all metrics should be collected. + */ + public List collect(Predicate sampleNameFilter) { + List all = collect(); + if (sampleNameFilter == null) { + return all; + } + List remaining = new ArrayList(all.size()); + for (MetricFamilySamples mfs : all) { + for (String name : mfs.getNames()) { + if (sampleNameFilter.test(name)) { + remaining.add(mfs); + break; + } + } + } + return remaining; + } + public enum Type { UNKNOWN, // This is untyped in Prometheus text format. COUNTER, @@ -40,7 +78,11 @@ static public class MetricFamilySamples { public final String unit; public final Type type; public final String help; - public final List samples; + public final List samples; // this list is modified when samples are added/removed. + + public MetricFamilySamples(String name, Type type, String help, List samples) { + this(name, "", type, help, samples); + } public MetricFamilySamples(String name, String unit, Type type, String help, List samples) { if (!unit.isEmpty() && !name.endsWith("_" + unit)) { @@ -72,10 +114,83 @@ public MetricFamilySamples(String name, String unit, Type type, String help, Lis this.samples = mungedSamples; } - public MetricFamilySamples(String name, Type type, String help, List samples) { - this(name, "", type, help, samples); + /** + * @param sampleNameFilter may be {@code null} indicating that the result contains the complete list of samples. + * @return A new MetricFamilySamples containing only the Samples matching the {@code sampleNameFilter}, + * or {@code null} if no Sample matches. + */ + public MetricFamilySamples filter(Predicate sampleNameFilter) { + if (sampleNameFilter == null) { + return this; + } + List remainingSamples = new ArrayList(samples.size()); + for (Sample sample : samples) { + if (sampleNameFilter.test(sample.name)) { + remainingSamples.add(sample); + } + } + if (remainingSamples.isEmpty()) { + return null; + } + return new MetricFamilySamples(name, unit, type, help, remainingSamples); } + /** + * List of names that are reserved for Samples in these MetricsFamilySamples. + *

+ * This is used in two places: + *

    + *
  1. To check potential name collisions in {@link CollectorRegistry#register(Collector)}. + *
  2. To check if a collector may contain metrics matching the metric name filter + * in {@link Collector#collect(Predicate)}. + *
+ * Note that {@code getNames()} always includes the name without suffix, even though some + * metrics types (like Counter) will not have a Sample with that name. + * The reason is that the name without suffix is used in the metadata comments ({@code # TYPE}, {@code # UNIT}, + * {@code # HELP}), and as this name must be unique + * we include the name without suffix here as well. + */ + public String[] getNames() { + switch (type) { + case COUNTER: + return new String[]{ + name + "_total", + name + "_created", + name + }; + case SUMMARY: + return new String[]{ + name + "_count", + name + "_sum", + name + "_created", + name + }; + case HISTOGRAM: + return new String[]{ + name + "_count", + name + "_sum", + name + "_bucket", + name + "_created", + name + }; + case GAUGE_HISTOGRAM: + return new String[]{ + name + "_gcount", + name + "_gsum", + name + "_bucket", + name + }; + case INFO: + return new String[]{ + name + "_info", + name + }; + default: + return new String[]{name}; + } + } + + @Override public boolean equals(Object obj) { if (!(obj instanceof MetricFamilySamples)) { @@ -204,7 +319,7 @@ public interface Describable { * Usually custom collectors do not have to implement Describable. If * Describable is not implemented and the CollectorRegistry was created * with auto describe enabled (which is the case for the default registry) - * then {@link collect} will be called at registration time instead of + * then {@link #collect} will be called at registration time instead of * describe. If this could cause problems, either implement a proper * describe, or if that's not practical have describe return an empty * list. diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index 0d37cca27..47af5b136 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -117,38 +117,7 @@ private List collectorNames(Collector m) { List names = new ArrayList(); for (Collector.MetricFamilySamples family : mfs) { - switch (family.type) { - case COUNTER: - names.add(family.name + "_total"); - names.add(family.name + "_created"); - names.add(family.name); - break; - case SUMMARY: - names.add(family.name + "_count"); - names.add(family.name + "_sum"); - names.add(family.name + "_created"); - names.add(family.name); - break; - case HISTOGRAM: - names.add(family.name + "_count"); - names.add(family.name + "_sum"); - names.add(family.name + "_bucket"); - names.add(family.name + "_created"); - names.add(family.name); - break; - case GAUGE_HISTOGRAM: - names.add(family.name + "_gcount"); - names.add(family.name + "_gsum"); - names.add(family.name + "_bucket"); - names.add(family.name); - break; - case INFO: - names.add(family.name + "_info"); - names.add(family.name); - break; - default: - names.add(family.name); - } + names.addAll(Arrays.asList(family.getNames())); } return names; } @@ -168,7 +137,16 @@ public Enumeration metricFamilySamples() { * histogram, you must include the '_count', '_sum' and '_bucket' names. */ public Enumeration filteredMetricFamilySamples(Set includedNames) { - return new MetricFamilySamplesEnumeration(includedNames); + return new MetricFamilySamplesEnumeration(new SampleNameFilter.Builder().nameMustBeEqualTo(includedNames).build()); + } + + /** + * Enumeration of metrics where {@code sampleNameFilter.test(name)} returns {@code true} for each {@code name} in + * {@link Collector.MetricFamilySamples#getNames()}. + * @param sampleNameFilter may be {@code null}, indicating that the enumeration should contain all metrics. + */ + public Enumeration filteredMetricFamilySamples(Predicate sampleNameFilter) { + return new MetricFamilySamplesEnumeration(sampleNameFilter); } class MetricFamilySamplesEnumeration implements Enumeration { @@ -176,75 +154,56 @@ class MetricFamilySamplesEnumeration implements Enumeration collectorIter; private Iterator metricFamilySamples; private Collector.MetricFamilySamples next; - private Set includedNames; + private final Predicate sampleNameFilter; - MetricFamilySamplesEnumeration(Set includedNames) { - this.includedNames = includedNames; - collectorIter = includedCollectorIterator(includedNames); + MetricFamilySamplesEnumeration(Predicate sampleNameFilter) { + this.sampleNameFilter = sampleNameFilter; + this.collectorIter = filteredCollectorIterator(); findNextElement(); } - private Iterator includedCollectorIterator(Set includedNames) { - if (includedNames.isEmpty()) { + private Iterator filteredCollectorIterator() { + if (sampleNameFilter == null) { return collectors().iterator(); } else { HashSet collectors = new HashSet(); synchronized (namesCollectorsLock) { for (Map.Entry entry : namesToCollectors.entrySet()) { - if (includedNames.contains(entry.getKey())) { + // Note that namesToCollectors contains keys for all combinations of suffixes (_total, _info, etc.). + if (sampleNameFilter.test(entry.getKey())) { collectors.add(entry.getValue()); } } } - return collectors.iterator(); } } MetricFamilySamplesEnumeration() { - this(Collections.emptySet()); + this(null); } private void findNextElement() { next = null; while (metricFamilySamples != null && metricFamilySamples.hasNext()) { - next = filter(metricFamilySamples.next()); + next = metricFamilySamples.next().filter(sampleNameFilter); if (next != null) { return; } } - if (next == null) { - while (collectorIter.hasNext()) { - metricFamilySamples = collectorIter.next().collect().iterator(); - while (metricFamilySamples.hasNext()) { - next = filter(metricFamilySamples.next()); - if (next != null) { - return; - } + while (collectorIter.hasNext()) { + metricFamilySamples = collectorIter.next().collect(sampleNameFilter).iterator(); + while (metricFamilySamples.hasNext()) { + next = metricFamilySamples.next().filter(sampleNameFilter); + if (next != null) { + return; } } } } - private Collector.MetricFamilySamples filter(Collector.MetricFamilySamples next) { - if (includedNames.isEmpty()) { - return next; - } else { - Iterator it = next.samples.iterator(); - while (it.hasNext()) { - if (!includedNames.contains(it.next().name)) { - it.remove(); - } - } - if (next.samples.size() == 0) { - return null; - } - return next; - } - } - public Collector.MetricFamilySamples nextElement() { Collector.MetricFamilySamples current = next; if (current == null) { diff --git a/simpleclient/src/main/java/io/prometheus/client/Predicate.java b/simpleclient/src/main/java/io/prometheus/client/Predicate.java new file mode 100644 index 000000000..6cbd83038 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/Predicate.java @@ -0,0 +1,8 @@ +package io.prometheus.client; + +/** + * Replacement for Java 8's {@code java.util.function.Predicate} for compatibility with Java versions < 8. + */ +public interface Predicate { + boolean test(T t); +} \ No newline at end of file diff --git a/simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java b/simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java new file mode 100644 index 000000000..180dd56c4 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java @@ -0,0 +1,242 @@ +package io.prometheus.client; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import static java.util.Collections.unmodifiableCollection; + +/** + * Filter samples (i.e. time series) by name. + */ +public class SampleNameFilter implements Predicate { + + /** + * For convenience, a filter that allows all names. + */ + public static final Predicate ALLOW_ALL = new AllowAll(); + + private final Collection nameIsEqualTo; + private final Collection nameIsNotEqualTo; + private final Collection nameStartsWith; + private final Collection nameDoesNotStartWith; + + @Override + public boolean test(String sampleName) { + return matchesNameEqualTo(sampleName) + && !matchesNameNotEqualTo(sampleName) + && matchesNameStartsWith(sampleName) + && !matchesNameDoesNotStartWith(sampleName); + } + + /** + * Replacement for Java 8's {@code Predicate.and()} for compatibility with Java versions < 8. + */ + public Predicate and(final Predicate other) { + if (other == null) { + throw new NullPointerException(); + } + return new Predicate() { + @Override + public boolean test(String s) { + return SampleNameFilter.this.test(s) && other.test(s); + } + }; + } + + private boolean matchesNameEqualTo(String metricName) { + if (nameIsEqualTo.isEmpty()) { + return true; + } + return nameIsEqualTo.contains(metricName); + } + + private boolean matchesNameNotEqualTo(String metricName) { + if (nameIsNotEqualTo.isEmpty()) { + return false; + } + return nameIsNotEqualTo.contains(metricName); + } + + private boolean matchesNameStartsWith(String metricName) { + if (nameStartsWith.isEmpty()) { + return true; + } + for (String prefix : nameStartsWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + private boolean matchesNameDoesNotStartWith(String metricName) { + if (nameDoesNotStartWith.isEmpty()) { + return false; + } + for (String prefix : nameDoesNotStartWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + public static class Builder { + + private final Collection nameEqualTo = new ArrayList(); + private final Collection nameNotEqualTo = new ArrayList(); + private final Collection nameStartsWith = new ArrayList(); + private final Collection nameDoesNotStartWith = new ArrayList(); + + /** + * @see #nameMustBeEqualTo(Collection) + */ + public Builder nameMustBeEqualTo(String... names) { + return nameMustBeEqualTo(Arrays.asList(names)); + } + + /** + * Only samples with one of the {@code names} will be included. + *

+ * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) + * and not the metric name. For instance, to retrieve all samples from a histogram, you must include the + * '_count', '_sum' and '_bucket' names. + *

+ * This method should be used by HTTP exporters to implement the {@code ?name[]=} URL parameters. + * + * @param names empty means no restriction. + */ + public Builder nameMustBeEqualTo(Collection names) { + nameEqualTo.addAll(names); + return this; + } + + /** + * @see #nameMustNotBeEqualTo(Collection) + */ + public Builder nameMustNotBeEqualTo(String... names) { + return nameMustNotBeEqualTo(Arrays.asList(names)); + } + + /** + * All samples that are not in {@code names} will be excluded. + *

+ * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) + * and not the metric name. For instance, to exclude all samples from a histogram, you must exclude the + * '_count', '_sum' and '_bucket' names. + * + * @param names empty means no name will be excluded. + */ + public Builder nameMustNotBeEqualTo(Collection names) { + nameNotEqualTo.addAll(names); + return this; + } + + /** + * @see #nameMustStartWith(Collection) + */ + public Builder nameMustStartWith(String... prefixes) { + return nameMustStartWith(Arrays.asList(prefixes)); + } + + /** + * Only samples whose name starts with one of the {@code prefixes} will be included. + * @param prefixes empty means no restriction. + */ + public Builder nameMustStartWith(Collection prefixes) { + nameStartsWith.addAll(prefixes); + return this; + } + + /** + * @see #nameMustNotStartWith(Collection) + */ + public Builder nameMustNotStartWith(String... prefixes) { + return nameMustNotStartWith(Arrays.asList(prefixes)); + } + + /** + * Samples with names starting with one of the {@code prefixes} will be excluded. + * @param prefixes empty means no time series will be excluded. + */ + public Builder nameMustNotStartWith(Collection prefixes) { + nameDoesNotStartWith.addAll(prefixes); + return this; + } + + public SampleNameFilter build() { + return new SampleNameFilter(nameEqualTo, nameNotEqualTo, nameStartsWith, nameDoesNotStartWith); + } + } + + private SampleNameFilter(Collection nameIsEqualTo, Collection nameIsNotEqualTo, Collection nameStartsWith, Collection nameDoesNotStartWith) { + this.nameIsEqualTo = unmodifiableCollection(nameIsEqualTo); + this.nameIsNotEqualTo = unmodifiableCollection(nameIsNotEqualTo); + this.nameStartsWith = unmodifiableCollection(nameStartsWith); + this.nameDoesNotStartWith = unmodifiableCollection(nameDoesNotStartWith); + } + + private static class AllowAll implements Predicate { + + private AllowAll() { + } + + @Override + public boolean test(String s) { + return true; + } + } + + /** + * Helper method to deserialize a {@code delimiter}-separated list of Strings into a {@code List}. + *

+ * {@code delimiter} is one of {@code , ; \t \n}. + *

+ * This is implemented here so that exporters can provide a consistent configuration format for + * lists of allowed names. + */ + public static List stringToList(String s) { + List result = new ArrayList(); + if (s != null) { + StringTokenizer tokenizer = new StringTokenizer(s, ",; \t\n"); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken(); + token = token.trim(); + if (token.length() > 0) { + result.add(token); + } + } + } + return result; + } + + /** + * Helper method to compose a filter such that Sample names must + *

    + *
  • match the existing filter
  • + *
  • and be in the list of allowedNames
  • + *
+ * This should be used to implement the {@code names[]} query parameter in HTTP exporters. + * + * @param filter may be null, indicating that the resulting filter should just filter by {@code allowedNames}. + * @param allowedNames may be null or empty, indicating that {@code filter} is returned unmodified. + * @return a filter combining the exising {@code filter} and the {@code allowedNames}, or {@code null} + * if both parameters were {@code null}. + */ + public static Predicate restrictToNamesEqualTo(Predicate filter, Collection allowedNames) { + if (allowedNames != null && !allowedNames.isEmpty()) { + SampleNameFilter allowedNamesFilter = new SampleNameFilter.Builder() + .nameMustBeEqualTo(allowedNames) + .build(); + if (filter == null) { + return allowedNamesFilter; + } else { + return allowedNamesFilter.and(filter); + } + } + return filter; + } +} \ No newline at end of file diff --git a/simpleclient/src/main/java/io/prometheus/client/Supplier.java b/simpleclient/src/main/java/io/prometheus/client/Supplier.java new file mode 100644 index 000000000..3eb766ea0 --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/Supplier.java @@ -0,0 +1,8 @@ +package io.prometheus.client; + +/** + * Replacement for Java 8's {@code java.util.function.Supplier} for compatibility with Java versions < 8. + */ +public interface Supplier { + T get(); +} diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java index 4404f247a..b5f56790a 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java @@ -53,7 +53,7 @@ public void testClear() { assertEquals(0, mfs.size()); } - class EmptyCollector extends Collector { + static class EmptyCollector extends Collector { public List collect() { return new ArrayList(); } @@ -72,29 +72,6 @@ public void testMetricFamilySamples() { assertEquals(new HashSet(Arrays.asList("g", "c", "s")), names); } - @Test - public void testMetricFamilySamples_filterNames() { - Collector g = Gauge.build().name("g").help("h").register(registry); - Collector c = Counter.build().name("c").help("h").register(registry); - Collector s = Summary.build().name("s").help("h").register(registry); - Collector ec = new EmptyCollector().register(registry); - SkippedCollector sr = new SkippedCollector().register(registry); - PartiallyFilterCollector pfr = new PartiallyFilterCollector().register(registry); - HashSet metrics = new HashSet(); - HashSet series = new HashSet(); - for (Collector.MetricFamilySamples metricFamilySamples : Collections.list(registry.filteredMetricFamilySamples( - new HashSet(Arrays.asList("", "s_sum", "c_total", "part_filter_a", "part_filter_c"))))) { - metrics.add(metricFamilySamples.name); - for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) { - series.add(sample.name); - } - } - - assertEquals(1, sr.collectCallCount); - assertEquals(2, pfr.collectCallCount); - assertEquals(new HashSet(Arrays.asList("s", "c", "part_filter_a", "part_filter_c")), metrics); - assertEquals(new HashSet(Arrays.asList("s_sum", "c_total", "part_filter_a", "part_filter_c")), series); - } @Test public void testEmptyRegistryHasNoMoreElements() { @@ -139,7 +116,7 @@ public void testCanUnAndReregister() { registry.register(h); } - class MyCollector extends Collector { + static class MyCollector extends Collector { public List collect() { List mfs = new ArrayList(); mfs.add(new GaugeMetricFamily("g", "help", 42)); @@ -161,41 +138,4 @@ public void testAutoDescribeThrowsOnReregisteringCustomCollector() { new MyCollector().register(r); new MyCollector().register(r); } - - private static class SkippedCollector extends Collector implements Collector.Describable { - public int collectCallCount = 0; - - @Override - public List collect() { - collectCallCount++; - List mfs = new ArrayList(); - mfs.add(new GaugeMetricFamily("slow_gauge", "help", 123)); - return mfs; - } - - @Override - public List describe() { - return collect(); - } - } - - private static class PartiallyFilterCollector extends Collector implements Collector.Describable { - public int collectCallCount = 0; - - @Override - public List collect() { - collectCallCount++; - List mfs = new ArrayList(); - mfs.add(new GaugeMetricFamily("part_filter_a", "help", 123)); - mfs.add(new GaugeMetricFamily("part_filter_b", "help", 123)); - mfs.add(new GaugeMetricFamily("part_filter_c", "help", 123)); - return mfs; - } - - @Override - public List describe() { - return collect(); - } - } - } diff --git a/simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java b/simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java new file mode 100644 index 000000000..b2c9f157b --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java @@ -0,0 +1,304 @@ +package io.prometheus.client; + +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.HashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; + +public class SampleNameFilterTest { + + private CollectorRegistry registry; + + @Before + public void setUp() { + registry = new CollectorRegistry(true); + } + + @Test + public void testCounter() { + // It should not make any difference whether a counter is created as "my_counter" or as "my_counter_total". + // We test both ways here and expect the same output. + for (String suffix : new String[] { "", "_total"}) { + registry.clear(); + Counter counter1 = Counter.build() + .name("counter1" + suffix) + .help("test counter 1") + .labelNames("path") + .register(registry); + counter1.labels("/hello").inc(); + counter1.labels("/goodbye").inc(); + Counter counter2 = Counter.build() + .name("counter2" + suffix) + .help("test counter 2") + .register(registry); + counter2.inc(); + + SampleNameFilter filter = new SampleNameFilter.Builder().build(); + List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter1_total", 2); + assertSamplesInclude(mfsList, "counter1_created", 2); + assertSamplesInclude(mfsList, "counter2_total", 1); + assertSamplesInclude(mfsList, "counter2_created", 1); + assertTotalNumberOfSamples(mfsList, 6); + + filter = new SampleNameFilter.Builder().nameMustStartWith("counter1").build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter1_total", 2); + assertSamplesInclude(mfsList, "counter1_created", 2); + assertTotalNumberOfSamples(mfsList, 4); + + filter = new SampleNameFilter.Builder().nameMustNotStartWith("counter1").build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter2_total", 1); + assertSamplesInclude(mfsList, "counter2_created", 1); + assertTotalNumberOfSamples(mfsList, 2); + + filter = new SampleNameFilter.Builder() + .nameMustBeEqualTo("counter2_total") + .nameMustBeEqualTo("counter1_total") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter1_total", 2); + assertSamplesInclude(mfsList, "counter2_total", 1); + assertTotalNumberOfSamples(mfsList, 3); + + filter = new SampleNameFilter.Builder() + .nameMustStartWith("counter1") + .nameMustNotStartWith("counter1_created") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter1_total", 2); + assertTotalNumberOfSamples(mfsList, 2); + + // The following filter would be weird in practice, but let's test this anyways :) + filter = new SampleNameFilter.Builder() + .nameMustBeEqualTo("counter1_created") + .nameMustBeEqualTo("counter2_created") + .nameMustNotStartWith("counter1") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "counter2_created", 1); + assertTotalNumberOfSamples(mfsList, 1); + + // And finally one that should not match anything + filter = new SampleNameFilter.Builder() + .nameMustBeEqualTo("counter1_total") + .nameMustNotBeEqualTo("counter1_total") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertTotalNumberOfSamples(mfsList, 0); + + } + } + + @Test + public void testCustomCollector() { + Collector myCollector = new Collector() { + @Override + public List collect() { + List result = new ArrayList(); + + String name = "temperature_centigrade"; + List labelNames = Collections.singletonList("location"); + GaugeMetricFamily temperatureCentigrade = new GaugeMetricFamily(name, "temperature centigrade", labelNames); + temperatureCentigrade.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("outside"), 26.0)); + temperatureCentigrade.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("inside"), 22.0)); + result.add(temperatureCentigrade); + + name = "temperature_fahrenheit"; + GaugeMetricFamily temperatureFahrenheit = new GaugeMetricFamily(name, "temperature fahrenheit", labelNames); + temperatureFahrenheit.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("outside"), 78.8)); + temperatureFahrenheit.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("inside"), 71.6)); + result.add(temperatureFahrenheit); + + return result; + } + }; + registry.register(myCollector); + + SampleNameFilter filter = new SampleNameFilter.Builder() + .nameMustStartWith("temperature_centigrade") + .build(); + List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "temperature_centigrade", 2); + assertTotalNumberOfSamples(mfsList, 2); + + filter = new SampleNameFilter.Builder() + .nameMustNotStartWith("temperature_centigrade") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "temperature_fahrenheit", 2); + assertTotalNumberOfSamples(mfsList, 2); + + filter = new SampleNameFilter.Builder() + .nameMustNotStartWith("temperature") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertTotalNumberOfSamples(mfsList, 0); + + filter = new SampleNameFilter.Builder() + .nameMustBeEqualTo("temperature_centigrade") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "temperature_centigrade", 2); + assertTotalNumberOfSamples(mfsList, 2); + + filter = new SampleNameFilter.Builder() + .nameMustNotBeEqualTo("temperature_centigrade") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "temperature_fahrenheit", 2); + assertTotalNumberOfSamples(mfsList, 2); + + filter = new SampleNameFilter.Builder() + .nameMustStartWith("temperature_c") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "temperature_centigrade", 2); + assertTotalNumberOfSamples(mfsList, 2); + } + + @Test + public void testHistogram() { + Histogram histogram = Histogram.build() + .name("test_histogram") + .help("test histogram") + .create(); + histogram.observe(100); + histogram.observe(200); + registry.register(histogram); + + SampleNameFilter filter = new SampleNameFilter.Builder().build(); + List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "test_histogram_bucket", 15); + assertSamplesInclude(mfsList, "test_histogram_count", 1); + assertSamplesInclude(mfsList, "test_histogram_sum", 1); + assertSamplesInclude(mfsList, "test_histogram_created", 1); + assertTotalNumberOfSamples(mfsList, 18); + + filter = new SampleNameFilter.Builder() + .nameMustStartWith("test_histogram") + // nameMustStartWith() is for the names[] query parameter in HTTP exporters. + // If histogram_created is missing in the names[] list, it should not be exported + // even though includePrefixes matches histogram_created. + .nameMustBeEqualTo("test_histogram_bucket") + .nameMustBeEqualTo("test_histogram_count") + .nameMustBeEqualTo("test_histogram_sum") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "test_histogram_bucket", 15); + assertSamplesInclude(mfsList, "test_histogram_count", 1); + assertSamplesInclude(mfsList, "test_histogram_sum", 1); + assertTotalNumberOfSamples(mfsList, 17); + + filter = new SampleNameFilter.Builder() + .nameMustStartWith("test_histogram") + // histogram without buckets + .nameMustNotStartWith("test_histogram_bucket") + .build(); + mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); + assertSamplesInclude(mfsList, "test_histogram_count", 1); + assertSamplesInclude(mfsList, "test_histogram_sum", 1); + assertSamplesInclude(mfsList, "test_histogram_created", 1); + assertTotalNumberOfSamples(mfsList, 3); + } + + /** + * Before {@link SampleNameFilter} was introduced, the {@link CollectorRegistry#filteredMetricFamilySamples(Set)} + * method could be used to pass included names directly. That method still there for compatibility. + * This is the original test copied over from {@link CollectorRegistryTest}. + */ + @Test + public void testLegacyApi() { + Gauge.build().name("g").help("h").register(registry); + Counter.build().name("c").help("h").register(registry); + Summary.build().name("s").help("h").register(registry); + new EmptyCollector().register(registry); + SkippedCollector sr = new SkippedCollector().register(registry); + PartiallyFilterCollector pfr = new PartiallyFilterCollector().register(registry); + HashSet metrics = new HashSet(); + HashSet series = new HashSet(); + Set includedNames = new HashSet(Arrays.asList("", "s_sum", "c_total", "part_filter_a", "part_filter_c")); + List mfsList = Collections.list(registry.filteredMetricFamilySamples(includedNames)); + for (Collector.MetricFamilySamples metricFamilySamples : mfsList) { + metrics.add(metricFamilySamples.name); + for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) { + series.add(sample.name); + } + } + assertEquals(1, sr.collectCallCount); + assertEquals(2, pfr.collectCallCount); + assertEquals(new HashSet(Arrays.asList("s", "c", "part_filter_a", "part_filter_c")), metrics); + assertEquals(new HashSet(Arrays.asList("s_sum", "c_total", "part_filter_a", "part_filter_c")), series); + } + + private static class EmptyCollector extends Collector { + public List collect() { + return new ArrayList(); + } + } + + private static class SkippedCollector extends Collector implements Collector.Describable { + public int collectCallCount = 0; + + @Override + public List collect() { + collectCallCount++; + List mfs = new ArrayList(); + mfs.add(new GaugeMetricFamily("slow_gauge", "help", 123)); + return mfs; + } + + @Override + public List describe() { + return collect(); + } + } + + private static class PartiallyFilterCollector extends Collector implements Collector.Describable { + public int collectCallCount = 0; + + @Override + public List collect() { + collectCallCount++; + List mfs = new ArrayList(); + mfs.add(new GaugeMetricFamily("part_filter_a", "help", 123)); + mfs.add(new GaugeMetricFamily("part_filter_b", "help", 123)); + mfs.add(new GaugeMetricFamily("part_filter_c", "help", 123)); + return mfs; + } + + @Override + public List describe() { + return collect(); + } + } + + private void assertSamplesInclude(List mfsList, String name, int times) { + int count = 0; + for (Collector.MetricFamilySamples mfs : mfsList) { + for (Collector.MetricFamilySamples.Sample sample : mfs.samples) { + if (sample.name.equals(name)) { + count++; + } + } + } + Assert.assertEquals("Wrong number of samples for " + name, times, count); + } + + private void assertTotalNumberOfSamples(List mfsList, int n) { + int count = 0; + for (Collector.MetricFamilySamples mfs : mfsList) { + count += mfs.samples.size(); + } + Assert.assertEquals("Wrong total number of samples", n, count); + } +} \ No newline at end of file diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java index d456b5e7b..36d4290d6 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java @@ -2,6 +2,7 @@ import io.prometheus.client.Collector; import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.Predicate; import java.lang.management.ManagementFactory; import java.lang.reflect.InvocationTargetException; @@ -11,6 +12,8 @@ import java.util.List; import java.util.logging.Logger; +import static io.prometheus.client.SampleNameFilter.ALLOW_ALL; + /** * Exports metrics about JVM buffers. * @@ -19,6 +22,10 @@ */ public class BufferPoolsExports extends Collector { + private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes"; + private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes"; + private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers"; + private static final Logger LOGGER = Logger.getLogger(BufferPoolsExports.class.getName()); private final List bufferPoolMXBeans = new ArrayList(); @@ -65,37 +72,60 @@ private static List accessBufferPoolMXBeans(final Class bufferPoolMXB @Override public List collect() { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { List mfs = new ArrayList(); - GaugeMetricFamily used = new GaugeMetricFamily( - "jvm_buffer_pool_used_bytes", - "Used bytes of a given JVM buffer pool.", - Collections.singletonList("pool")); - mfs.add(used); - GaugeMetricFamily capacity = new GaugeMetricFamily( - "jvm_buffer_pool_capacity_bytes", - "Bytes capacity of a given JVM buffer pool.", - Collections.singletonList("pool")); - mfs.add(capacity); - GaugeMetricFamily buffers = new GaugeMetricFamily( - "jvm_buffer_pool_used_buffers", - "Used buffers of a given JVM buffer pool.", - Collections.singletonList("pool")); - mfs.add(buffers); + if (nameFilter == null) { + nameFilter = ALLOW_ALL; + } + GaugeMetricFamily used = null; + if (nameFilter.test(JVM_BUFFER_POOL_USED_BYTES)) { + used = new GaugeMetricFamily( + JVM_BUFFER_POOL_USED_BYTES, + "Used bytes of a given JVM buffer pool.", + Collections.singletonList("pool")); + mfs.add(used); + } + GaugeMetricFamily capacity = null; + if (nameFilter.test(JVM_BUFFER_POOL_CAPACITY_BYTES)) { + capacity = new GaugeMetricFamily( + JVM_BUFFER_POOL_CAPACITY_BYTES, + "Bytes capacity of a given JVM buffer pool.", + Collections.singletonList("pool")); + mfs.add(capacity); + } + GaugeMetricFamily buffers = null; + if (nameFilter.test(JVM_BUFFER_POOL_USED_BUFFERS)) { + buffers = new GaugeMetricFamily( + JVM_BUFFER_POOL_USED_BUFFERS, + "Used buffers of a given JVM buffer pool.", + Collections.singletonList("pool")); + mfs.add(buffers); + } for (final Object pool : bufferPoolMXBeans) { - used.addMetric( - Collections.singletonList(getName(pool)), - callLongMethond(getMemoryUsed,pool)); - capacity.addMetric( - Collections.singletonList(getName(pool)), - callLongMethond(getTotalCapacity,pool)); - buffers.addMetric( - Collections.singletonList(getName(pool)), - callLongMethond(getCount,pool)); + if (used != null) { + used.addMetric( + Collections.singletonList(getName(pool)), + callLongMethod(getMemoryUsed, pool)); + } + if (capacity != null) { + capacity.addMetric( + Collections.singletonList(getName(pool)), + callLongMethod(getTotalCapacity, pool)); + } + if (buffers != null) { + buffers.addMetric( + Collections.singletonList(getName(pool)), + callLongMethod(getCount, pool)); + } } return mfs; } - private long callLongMethond(final Method method, final Object pool) { + private long callLongMethod(final Method method, final Object pool) { try { return (Long)method.invoke(pool); } catch (IllegalAccessException e) { @@ -116,7 +146,4 @@ private String getName(final Object pool) { } return ""; } - - - } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java index feeffe11f..b23b14be5 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java @@ -3,12 +3,15 @@ import io.prometheus.client.Collector; import io.prometheus.client.CounterMetricFamily; import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.Predicate; import java.lang.management.ManagementFactory; import java.lang.management.ClassLoadingMXBean; import java.util.ArrayList; import java.util.List; +import static io.prometheus.client.SampleNameFilter.ALLOW_ALL; + /** * Exports metrics about JVM classloading. *

@@ -26,6 +29,11 @@ * */ public class ClassLoadingExports extends Collector { + + private static final String JVM_CLASSES_CURRENTLY_LOADED = "jvm_classes_currently_loaded"; + private static final String JVM_CLASSES_LOADED_TOTAL = "jvm_classes_loaded_total"; + private static final String JVM_CLASSES_UNLOADED_TOTAL = "jvm_classes_unloaded_total"; + private final ClassLoadingMXBean clBean; public ClassLoadingExports() { @@ -36,25 +44,36 @@ public ClassLoadingExports(ClassLoadingMXBean clBean) { this.clBean = clBean; } - void addClassLoadingMetrics(List sampleFamilies) { - sampleFamilies.add(new GaugeMetricFamily( - "jvm_classes_currently_loaded", - "The number of classes that are currently loaded in the JVM", - clBean.getLoadedClassCount())); - sampleFamilies.add(new CounterMetricFamily( - "jvm_classes_loaded_total", - "The total number of classes that have been loaded since the JVM has started execution", - clBean.getTotalLoadedClassCount())); - sampleFamilies.add(new CounterMetricFamily( - "jvm_classes_unloaded_total", - "The total number of classes that have been unloaded since the JVM has started execution", - clBean.getUnloadedClassCount())); + void addClassLoadingMetrics(List sampleFamilies, Predicate nameFilter) { + if (nameFilter.test(JVM_CLASSES_CURRENTLY_LOADED)) { + sampleFamilies.add(new GaugeMetricFamily( + JVM_CLASSES_CURRENTLY_LOADED, + "The number of classes that are currently loaded in the JVM", + clBean.getLoadedClassCount())); + } + if (nameFilter.test(JVM_CLASSES_LOADED_TOTAL)) { + sampleFamilies.add(new CounterMetricFamily( + JVM_CLASSES_LOADED_TOTAL, + "The total number of classes that have been loaded since the JVM has started execution", + clBean.getTotalLoadedClassCount())); + } + if (nameFilter.test(JVM_CLASSES_UNLOADED_TOTAL)) { + sampleFamilies.add(new CounterMetricFamily( + JVM_CLASSES_UNLOADED_TOTAL, + "The total number of classes that have been unloaded since the JVM has started execution", + clBean.getUnloadedClassCount())); + } } - + @Override public List collect() { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { List mfs = new ArrayList(); - addClassLoadingMetrics(mfs); + addClassLoadingMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter); return mfs; } } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java index ad0b1f029..8aa18c3e6 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java @@ -1,6 +1,7 @@ package io.prometheus.client.hotspot; import io.prometheus.client.Collector; +import io.prometheus.client.Predicate; import io.prometheus.client.SummaryMetricFamily; import java.lang.management.GarbageCollectorMXBean; @@ -25,6 +26,9 @@ * */ public class GarbageCollectorExports extends Collector { + + private static final String JVM_GC_COLLECTION_SECONDS = "jvm_gc_collection_seconds"; + private final List garbageCollectors; public GarbageCollectorExports() { @@ -35,19 +39,27 @@ public GarbageCollectorExports() { this.garbageCollectors = garbageCollectors; } + @Override public List collect() { - SummaryMetricFamily gcCollection = new SummaryMetricFamily( - "jvm_gc_collection_seconds", - "Time spent in a given JVM garbage collector in seconds.", - Collections.singletonList("gc")); - for (final GarbageCollectorMXBean gc : garbageCollectors) { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { + List mfs = new ArrayList(); + if (nameFilter == null || nameFilter.test(JVM_GC_COLLECTION_SECONDS)) { + SummaryMetricFamily gcCollection = new SummaryMetricFamily( + JVM_GC_COLLECTION_SECONDS, + "Time spent in a given JVM garbage collector in seconds.", + Collections.singletonList("gc")); + for (final GarbageCollectorMXBean gc : garbageCollectors) { gcCollection.addMetric( - Collections.singletonList(gc.getName()), - gc.getCollectionCount(), - gc.getCollectionTime() / MILLISECONDS_PER_SECOND); + Collections.singletonList(gc.getName()), + gc.getCollectionCount(), + gc.getCollectionTime() / MILLISECONDS_PER_SECOND); + } + mfs.add(gcCollection); } - List mfs = new ArrayList(); - mfs.add(gcCollection); return mfs; } } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index 0b37e72ba..4729fbe70 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -2,6 +2,7 @@ import io.prometheus.client.Collector; import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.Predicate; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; @@ -11,6 +12,8 @@ import java.util.Collections; import java.util.List; +import static io.prometheus.client.SampleNameFilter.ALLOW_ALL; + /** * Exports metrics about JVM memory areas. *

@@ -29,6 +32,26 @@ * */ public class MemoryPoolsExports extends Collector { + + private static final String JVM_MEMORY_OBJECTS_PENDING_FINALIZATION = "jvm_memory_objects_pending_finalization"; + private static final String JVM_MEMORY_BYTES_USED = "jvm_memory_bytes_used"; + private static final String JVM_MEMORY_BYTES_COMMITTED = "jvm_memory_bytes_committed"; + private static final String JVM_MEMORY_BYTES_MAX = "jvm_memory_bytes_max"; + private static final String JVM_MEMORY_BYTES_INIT = "jvm_memory_bytes_init"; + + // Note: The Prometheus naming convention is that units belong at the end of the metric name. + // For new metrics like jvm_memory_pool_collection_used_bytes we follow that convention. + // For old metrics like jvm_memory_pool_bytes_used we keep the names as they are to avoid a breaking change. + + private static final String JVM_MEMORY_POOL_BYTES_USED = "jvm_memory_pool_bytes_used"; + private static final String JVM_MEMORY_POOL_BYTES_COMMITTED = "jvm_memory_pool_bytes_committed"; + private static final String JVM_MEMORY_POOL_BYTES_MAX = "jvm_memory_pool_bytes_max"; + private static final String JVM_MEMORY_POOL_BYTES_INIT = "jvm_memory_pool_bytes_init"; + private static final String JVM_MEMORY_POOL_COLLECTION_USED_BYTES = "jvm_memory_pool_collection_used_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES = "jvm_memory_pool_collection_committed_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_MAX_BYTES = "jvm_memory_pool_collection_max_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_INIT_BYTES = "jvm_memory_pool_collection_init_bytes"; + private final MemoryMXBean memoryBean; private final List poolBeans; @@ -44,131 +67,174 @@ public MemoryPoolsExports(MemoryMXBean memoryBean, this.poolBeans = poolBeans; } - void addMemoryAreaMetrics(List sampleFamilies) { + void addMemoryAreaMetrics(List sampleFamilies, Predicate nameFilter) { MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage(); MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage(); - GaugeMetricFamily finalizer = new GaugeMetricFamily( - "jvm_memory_objects_pending_finalization", - "The number of objects waiting in the finalizer queue.", - memoryBean.getObjectPendingFinalizationCount()); - sampleFamilies.add(finalizer); - - GaugeMetricFamily used = new GaugeMetricFamily( - "jvm_memory_bytes_used", - "Used bytes of a given JVM memory area.", - Collections.singletonList("area")); - used.addMetric(Collections.singletonList("heap"), heapUsage.getUsed()); - used.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getUsed()); - sampleFamilies.add(used); - - GaugeMetricFamily committed = new GaugeMetricFamily( - "jvm_memory_bytes_committed", - "Committed (bytes) of a given JVM memory area.", - Collections.singletonList("area")); - committed.addMetric(Collections.singletonList("heap"), heapUsage.getCommitted()); - committed.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getCommitted()); - sampleFamilies.add(committed); - - GaugeMetricFamily max = new GaugeMetricFamily( - "jvm_memory_bytes_max", - "Max (bytes) of a given JVM memory area.", - Collections.singletonList("area")); - max.addMetric(Collections.singletonList("heap"), heapUsage.getMax()); - max.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getMax()); - sampleFamilies.add(max); - - GaugeMetricFamily init = new GaugeMetricFamily( - "jvm_memory_bytes_init", - "Initial bytes of a given JVM memory area.", - Collections.singletonList("area")); - init.addMetric(Collections.singletonList("heap"), heapUsage.getInit()); - init.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getInit()); - sampleFamilies.add(init); + if (nameFilter.test(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION)) { + GaugeMetricFamily finalizer = new GaugeMetricFamily( + JVM_MEMORY_OBJECTS_PENDING_FINALIZATION, + "The number of objects waiting in the finalizer queue.", + memoryBean.getObjectPendingFinalizationCount()); + sampleFamilies.add(finalizer); + } + + if (nameFilter.test(JVM_MEMORY_BYTES_USED)) { + GaugeMetricFamily used = new GaugeMetricFamily( + JVM_MEMORY_BYTES_USED, + "Used bytes of a given JVM memory area.", + Collections.singletonList("area")); + used.addMetric(Collections.singletonList("heap"), heapUsage.getUsed()); + used.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getUsed()); + sampleFamilies.add(used); + } + + if (nameFilter.test(JVM_MEMORY_POOL_BYTES_COMMITTED)) { + GaugeMetricFamily committed = new GaugeMetricFamily( + JVM_MEMORY_BYTES_COMMITTED, + "Committed (bytes) of a given JVM memory area.", + Collections.singletonList("area")); + committed.addMetric(Collections.singletonList("heap"), heapUsage.getCommitted()); + committed.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getCommitted()); + sampleFamilies.add(committed); + } + + if (nameFilter.test(JVM_MEMORY_BYTES_MAX)) { + GaugeMetricFamily max = new GaugeMetricFamily( + JVM_MEMORY_BYTES_MAX, + "Max (bytes) of a given JVM memory area.", + Collections.singletonList("area")); + max.addMetric(Collections.singletonList("heap"), heapUsage.getMax()); + max.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getMax()); + sampleFamilies.add(max); + } + + if (nameFilter.test(JVM_MEMORY_BYTES_INIT)) { + GaugeMetricFamily init = new GaugeMetricFamily( + JVM_MEMORY_BYTES_INIT, + "Initial bytes of a given JVM memory area.", + Collections.singletonList("area")); + init.addMetric(Collections.singletonList("heap"), heapUsage.getInit()); + init.addMetric(Collections.singletonList("nonheap"), nonHeapUsage.getInit()); + sampleFamilies.add(init); + } } - void addMemoryPoolMetrics(List sampleFamilies) { - - // Note: The Prometheus naming convention is that units belong at the end of the metric name. - // For new metrics like jvm_memory_pool_collection_used_bytes we follow that convention. - // For old metrics like jvm_memory_pool_bytes_used we keep the names as they are to avoid a breaking change. - - GaugeMetricFamily used = new GaugeMetricFamily( - "jvm_memory_pool_bytes_used", - "Used bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(used); - GaugeMetricFamily committed = new GaugeMetricFamily( - "jvm_memory_pool_bytes_committed", - "Committed bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(committed); - GaugeMetricFamily max = new GaugeMetricFamily( - "jvm_memory_pool_bytes_max", - "Max bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(max); - GaugeMetricFamily init = new GaugeMetricFamily( - "jvm_memory_pool_bytes_init", - "Initial bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(init); - GaugeMetricFamily collectionUsed = new GaugeMetricFamily( - "jvm_memory_pool_collection_used_bytes", - "Used bytes after last collection of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(collectionUsed); - GaugeMetricFamily collectionCommitted = new GaugeMetricFamily( - "jvm_memory_pool_collection_committed_bytes", - "Committed after last collection bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(collectionCommitted); - GaugeMetricFamily collectionMax = new GaugeMetricFamily( - "jvm_memory_pool_collection_max_bytes", - "Max bytes after last collection of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(collectionMax); - GaugeMetricFamily collectionInit = new GaugeMetricFamily( - "jvm_memory_pool_collection_init_bytes", - "Initial after last collection bytes of a given JVM memory pool.", - Collections.singletonList("pool")); - sampleFamilies.add(collectionInit); - for (final MemoryPoolMXBean pool : poolBeans) { - MemoryUsage poolUsage = pool.getUsage(); - used.addMetric( - Collections.singletonList(pool.getName()), - poolUsage.getUsed()); - committed.addMetric( - Collections.singletonList(pool.getName()), - poolUsage.getCommitted()); - max.addMetric( - Collections.singletonList(pool.getName()), - poolUsage.getMax()); - init.addMetric( - Collections.singletonList(pool.getName()), - poolUsage.getInit()); - MemoryUsage collectionPoolUsage = pool.getCollectionUsage(); - if (collectionPoolUsage != null) { - collectionUsed.addMetric( - Collections.singletonList(pool.getName()), - collectionPoolUsage.getUsed()); - collectionCommitted.addMetric( - Collections.singletonList(pool.getName()), - collectionPoolUsage.getCommitted()); - collectionMax.addMetric( - Collections.singletonList(pool.getName()), - collectionPoolUsage.getMax()); - collectionInit.addMetric( - Collections.singletonList(pool.getName()), - collectionPoolUsage.getInit()); + void addMemoryPoolMetrics(List sampleFamilies, Predicate nameFilter) { + + boolean anyPoolMetricPassesFilter = false; + + GaugeMetricFamily used = null; + if (nameFilter.test(JVM_MEMORY_POOL_BYTES_USED)) { + used = new GaugeMetricFamily( + JVM_MEMORY_POOL_BYTES_USED, + "Used bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(used); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily committed = null; + if (nameFilter.test(JVM_MEMORY_POOL_BYTES_COMMITTED)) { + committed = new GaugeMetricFamily( + JVM_MEMORY_POOL_BYTES_COMMITTED, + "Committed bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(committed); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily max = null; + if (nameFilter.test(JVM_MEMORY_POOL_BYTES_MAX)) { + max = new GaugeMetricFamily( + JVM_MEMORY_POOL_BYTES_MAX, + "Max bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(max); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily init = null; + if (nameFilter.test(JVM_MEMORY_POOL_BYTES_INIT)) { + init = new GaugeMetricFamily( + JVM_MEMORY_POOL_BYTES_INIT, + "Initial bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(init); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily collectionUsed = null; + if (nameFilter.test(JVM_MEMORY_POOL_COLLECTION_USED_BYTES)) { + collectionUsed = new GaugeMetricFamily( + JVM_MEMORY_POOL_COLLECTION_USED_BYTES, + "Used bytes after last collection of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionUsed); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily collectionCommitted = null; + if (nameFilter.test(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES)) { + collectionCommitted = new GaugeMetricFamily( + JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES, + "Committed after last collection bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionCommitted); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily collectionMax = null; + if (nameFilter.test(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES)) { + collectionMax = new GaugeMetricFamily( + JVM_MEMORY_POOL_COLLECTION_MAX_BYTES, + "Max bytes after last collection of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionMax); + anyPoolMetricPassesFilter = true; + } + GaugeMetricFamily collectionInit = null; + if (nameFilter.test(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES)) { + collectionInit = new GaugeMetricFamily( + JVM_MEMORY_POOL_COLLECTION_INIT_BYTES, + "Initial after last collection bytes of a given JVM memory pool.", + Collections.singletonList("pool")); + sampleFamilies.add(collectionInit); + anyPoolMetricPassesFilter = true; + } + if (anyPoolMetricPassesFilter) { + for (final MemoryPoolMXBean pool : poolBeans) { + MemoryUsage poolUsage = pool.getUsage(); + if (poolUsage != null) { + addPoolMetrics(used, committed, max, init, pool.getName(), poolUsage); + } + MemoryUsage collectionPoolUsage = pool.getCollectionUsage(); + if (collectionPoolUsage != null) { + addPoolMetrics(collectionUsed, collectionCommitted, collectionMax, collectionInit, pool.getName(), collectionPoolUsage); + } } } } + private void addPoolMetrics(GaugeMetricFamily used, GaugeMetricFamily committed, GaugeMetricFamily max, GaugeMetricFamily init, String poolName, MemoryUsage poolUsage) { + if (used != null) { + used.addMetric(Collections.singletonList(poolName), poolUsage.getUsed()); + } + if (committed != null) { + committed.addMetric(Collections.singletonList(poolName), poolUsage.getCommitted()); + } + if (max != null) { + max.addMetric(Collections.singletonList(poolName), poolUsage.getMax()); + } + if (init != null) { + init.addMetric(Collections.singletonList(poolName), poolUsage.getInit()); + } + } + + @Override public List collect() { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { List mfs = new ArrayList(); - addMemoryAreaMetrics(mfs); - addMemoryPoolMetrics(mfs); + addMemoryAreaMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter); + addMemoryPoolMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter); return mfs; } } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java index 55c90a654..c63db20d7 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java @@ -3,6 +3,8 @@ import io.prometheus.client.Collector; import io.prometheus.client.CounterMetricFamily; import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.SampleNameFilter; +import io.prometheus.client.Predicate; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; @@ -13,6 +15,8 @@ import java.util.List; import java.util.Map; +import static io.prometheus.client.SampleNameFilter.ALLOW_ALL; + /** * Exports metrics about JVM thread areas. *

@@ -31,6 +35,15 @@ * */ public class ThreadExports extends Collector { + + private static final String JVM_THREADS_CURRENT = "jvm_threads_current"; + private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon"; + private static final String JVM_THREADS_PEAK = "jvm_threads_peak"; + private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total"; + private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked"; + private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor"; + private static final String JVM_THREADS_STATE = "jvm_threads_state"; + private final ThreadMXBean threadBean; public ThreadExports() { @@ -41,56 +54,70 @@ public ThreadExports(ThreadMXBean threadBean) { this.threadBean = threadBean; } - void addThreadMetrics(List sampleFamilies) { - sampleFamilies.add( - new GaugeMetricFamily( - "jvm_threads_current", - "Current thread count of a JVM", - threadBean.getThreadCount())); - - sampleFamilies.add( - new GaugeMetricFamily( - "jvm_threads_daemon", - "Daemon thread count of a JVM", - threadBean.getDaemonThreadCount())); - - sampleFamilies.add( - new GaugeMetricFamily( - "jvm_threads_peak", - "Peak thread count of a JVM", - threadBean.getPeakThreadCount())); - - sampleFamilies.add( - new CounterMetricFamily( - "jvm_threads_started_total", - "Started thread count of a JVM", - threadBean.getTotalStartedThreadCount())); - - sampleFamilies.add( - new GaugeMetricFamily( - "jvm_threads_deadlocked", - "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers", - nullSafeArrayLength(threadBean.findDeadlockedThreads()))); - - sampleFamilies.add( - new GaugeMetricFamily( - "jvm_threads_deadlocked_monitor", - "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors", - nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))); - - GaugeMetricFamily threadStateFamily = new GaugeMetricFamily( - "jvm_threads_state", - "Current count of threads by state", - Collections.singletonList("state")); - - Map threadStateCounts = getThreadStateCountMap(); - for (Map.Entry entry : threadStateCounts.entrySet()) { - threadStateFamily.addMetric( - Collections.singletonList(entry.getKey().toString()), - entry.getValue() - ); + void addThreadMetrics(List sampleFamilies, Predicate nameFilter) { + if (nameFilter.test(JVM_THREADS_CURRENT)) { + sampleFamilies.add( + new GaugeMetricFamily( + JVM_THREADS_CURRENT, + "Current thread count of a JVM", + threadBean.getThreadCount())); + } + + if (nameFilter.test(JVM_THREADS_DAEMON)) { + sampleFamilies.add( + new GaugeMetricFamily( + JVM_THREADS_DAEMON, + "Daemon thread count of a JVM", + threadBean.getDaemonThreadCount())); + } + + if (nameFilter.test(JVM_THREADS_PEAK)) { + sampleFamilies.add( + new GaugeMetricFamily( + JVM_THREADS_PEAK, + "Peak thread count of a JVM", + threadBean.getPeakThreadCount())); + } + + if (nameFilter.test(JVM_THREADS_STARTED_TOTAL)) { + sampleFamilies.add( + new CounterMetricFamily( + JVM_THREADS_STARTED_TOTAL, + "Started thread count of a JVM", + threadBean.getTotalStartedThreadCount())); + } + + if (nameFilter.test(JVM_THREADS_DEADLOCKED)) { + sampleFamilies.add( + new GaugeMetricFamily( + JVM_THREADS_DEADLOCKED, + "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers", + nullSafeArrayLength(threadBean.findDeadlockedThreads()))); + } + + if (nameFilter.test(JVM_THREADS_DEADLOCKED_MONITOR)) { + sampleFamilies.add( + new GaugeMetricFamily( + JVM_THREADS_DEADLOCKED_MONITOR, + "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors", + nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))); + } + + if (nameFilter.test(JVM_THREADS_STATE)) { + GaugeMetricFamily threadStateFamily = new GaugeMetricFamily( + JVM_THREADS_STATE, + "Current count of threads by state", + Collections.singletonList("state")); + + Map threadStateCounts = getThreadStateCountMap(); + for (Map.Entry entry : threadStateCounts.entrySet()) { + threadStateFamily.addMetric( + Collections.singletonList(entry.getKey().toString()), + entry.getValue() + ); + } + sampleFamilies.add(threadStateFamily); } - sampleFamilies.add(threadStateFamily); } private Map getThreadStateCountMap() { @@ -118,9 +145,15 @@ private static double nullSafeArrayLength(long[] array) { return null == array ? 0 : array.length; } + @Override public List collect() { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { List mfs = new ArrayList(); - addThreadMetrics(mfs); + addThreadMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter); return mfs; } -} +} \ No newline at end of file diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index d6afdcd69..dbc031307 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -1,12 +1,17 @@ package io.prometheus.client.exporter; import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.SampleNameFilter; +import io.prometheus.client.Predicate; +import io.prometheus.client.Supplier; import io.prometheus.client.exporter.common.TextFormat; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URLDecoder; import java.nio.charset.Charset; @@ -35,7 +40,7 @@ * } * * */ -public class HTTPServer { +public class HTTPServer implements Closeable { static { if (!System.getProperties().containsKey("sun.net.httpserver.maxReqTime")) { @@ -61,10 +66,16 @@ protected ByteArrayOutputStream initialValue() public static class HTTPMetricHandler implements HttpHandler { private final CollectorRegistry registry; private final LocalByteArray response = new LocalByteArray(); + private final Supplier> sampleNameFilterSupplier; private final static String HEALTHY_RESPONSE = "Exporter is Healthy."; HTTPMetricHandler(CollectorRegistry registry) { - this.registry = registry; + this(registry, null); + } + + HTTPMetricHandler(CollectorRegistry registry, Supplier> sampleNameFilterSupplier) { + this.registry = registry; + this.sampleNameFilterSupplier = sampleNameFilterSupplier; } @Override @@ -80,8 +91,13 @@ public void handle(HttpExchange t) throws IOException { } else { String contentType = TextFormat.chooseContentType(t.getRequestHeaders().getFirst("Accept")); t.getResponseHeaders().set("Content-Type", contentType); - TextFormat.writeFormat(contentType, osw, - registry.filteredMetricFamilySamples(parseQuery(query))); + Predicate filter = sampleNameFilterSupplier == null ? null : sampleNameFilterSupplier.get(); + filter = SampleNameFilter.restrictToNamesEqualTo(filter, parseQuery(query)); + if (filter == null) { + TextFormat.writeFormat(contentType, osw, registry.metricFamilySamples()); + } else { + TextFormat.writeFormat(contentType, osw, registry.filteredMetricFamilySamples(filter)); + } } osw.close(); @@ -103,7 +119,6 @@ public void handle(HttpExchange t) throws IOException { } t.close(); } - } protected static boolean shouldUseCompression(HttpExchange exchange) { @@ -166,67 +181,216 @@ static ThreadFactory defaultThreadFactory(boolean daemon) { protected final ExecutorService executorService; /** - * Start a HTTP server serving Prometheus metrics from the given registry using the given {@link HttpServer}. + * We keep the original constructors of {@link HTTPServer} for compatibility, but new configuration + * parameters like {@code sampleNameFilter} must be configured using the Builder. + */ + public static class Builder { + + private int port = 0; + private String hostname = null; + private InetAddress inetAddress = null; + private InetSocketAddress inetSocketAddress = null; + private HttpServer httpServer = null; + private CollectorRegistry registry = CollectorRegistry.defaultRegistry; + private boolean daemon = false; + private Predicate sampleNameFilter; + private Supplier> sampleNameFilterSupplier; + + /** + * Port to bind to. Must not be called together with {@link #withInetSocketAddress(InetSocketAddress)} + * or {@link #withHttpServer(HttpServer)}. Default is 0, indicating that a random port will be selected. + */ + public Builder withPort(int port) { + this.port = port; + return this; + } + + /** + * Use this hostname to resolve the IP address to bind to. Must not be called together with + * {@link #withInetAddress(InetAddress)} or {@link #withInetSocketAddress(InetSocketAddress)} + * or {@link #withHttpServer(HttpServer)}. + * Default is empty, indicating that the HTTPServer binds to the wildcard address. + */ + public Builder withHostname(String hostname) { + this.hostname = hostname; + return this; + } + + /** + * Bind to this IP address. Must not be called together with {@link #withHostname(String)} or + * {@link #withInetSocketAddress(InetSocketAddress)} or {@link #withHttpServer(HttpServer)}. + * Default is empty, indicating that the HTTPServer binds to the wildcard address. + */ + public Builder withInetAddress(InetAddress address) { + this.inetAddress = address; + return this; + } + + /** + * Listen on this address. Must not be called together with {@link #withPort(int)}, + * {@link #withHostname(String)}, {@link #withInetAddress(InetAddress)}, or {@link #withHttpServer(HttpServer)}. + */ + public Builder withInetSocketAddress(InetSocketAddress address) { + this.inetSocketAddress = address; + return this; + } + + /** + * Use this httpServer. The {@code httpServer} is expected to already be bound to an address. + * Must not be called together with {@link #withPort(int)}, or {@link #withHostname(String)}, + * or {@link #withInetAddress(InetAddress)}, or {@link #withInetSocketAddress(InetSocketAddress)}. + */ + public Builder withHttpServer(HttpServer httpServer) { + this.httpServer = httpServer; + return this; + } + + /** + * By default, the {@link HTTPServer} uses non-daemon threads. Set this to {@code true} to + * run the {@link HTTPServer} with daemon threads. + */ + public Builder withDaemonThreads(boolean daemon) { + this.daemon = daemon; + return this; + } + + /** + * Optional: Only export time series where {@code sampleNameFilter.test(name)} returns true. + *

+ * Use this if the sampleNameFilter remains the same throughout the lifetime of the HTTPServer. + * If the sampleNameFilter changes during runtime, use {@link #withSampleNameFilterSupplier(Supplier)}. + */ + public Builder withSampleNameFilter(Predicate sampleNameFilter) { + this.sampleNameFilter = sampleNameFilter; + return this; + } + + /** + * Optional: Only export time series where {@code sampleNameFilter.test(name)} returns true. + *

+ * Use this if the sampleNameFilter may change during runtime, like for example if you have a + * hot reload mechanism for your filter config. + * If the sampleNameFilter remains the same throughout the lifetime of the HTTPServer, + * use {@link #withSampleNameFilter(Predicate)} instead. + */ + public Builder withSampleNameFilterSupplier(Supplier> sampleNameFilterSupplier) { + this.sampleNameFilterSupplier = sampleNameFilterSupplier; + return this; + } + + /** + * Optional: Default is {@link CollectorRegistry#defaultRegistry}. + */ + public Builder withRegistry(CollectorRegistry registry) { + this.registry = registry; + return this; + } + + public HTTPServer build() throws IOException { + if (sampleNameFilter != null) { + assertNull(sampleNameFilterSupplier, "cannot configure 'sampleNameFilter' and 'sampleNameFilterSupplier' at the same time"); + sampleNameFilterSupplier = SampleNameFilterSupplier.of(sampleNameFilter); + } + if (httpServer != null) { + assertZero(port, "cannot configure 'httpServer' and 'port' at the same time"); + assertNull(hostname, "cannot configure 'httpServer' and 'hostname' at the same time"); + assertNull(inetAddress, "cannot configure 'httpServer' and 'inetAddress' at the same time"); + assertNull(inetSocketAddress, "cannot configure 'httpServer' and 'inetSocketAddress' at the same time"); + return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier); + } else if (inetSocketAddress != null) { + assertZero(port, "cannot configure 'inetSocketAddress' and 'port' at the same time"); + assertNull(hostname, "cannot configure 'inetSocketAddress' and 'hostname' at the same time"); + assertNull(inetAddress, "cannot configure 'inetSocketAddress' and 'inetAddress' at the same time"); + } else if (inetAddress != null) { + assertNull(hostname, "cannot configure 'inetAddress' and 'hostname' at the same time"); + inetSocketAddress = new InetSocketAddress(inetAddress, port); + } else if (hostname != null) { + inetSocketAddress = new InetSocketAddress(hostname, port); + } else { + inetSocketAddress = new InetSocketAddress(port); + } + return new HTTPServer(HttpServer.create(inetSocketAddress, 3), registry, daemon, sampleNameFilterSupplier); + } + + private void assertNull(Object o, String msg) { + if (o != null) { + throw new IllegalStateException(msg); + } + } + + private void assertZero(int i, String msg) { + if (i != 0) { + throw new IllegalStateException(msg); + } + } + } + + /** + * Start an HTTP server serving Prometheus metrics from the given registry using the given {@link HttpServer}. * The {@code httpServer} is expected to already be bound to an address */ public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon) throws IOException { - if (httpServer.getAddress() == null) - throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); - - server = httpServer; - HttpHandler mHandler = new HTTPMetricHandler(registry); - server.createContext("/", mHandler); - server.createContext("/metrics", mHandler); - server.createContext("/-/healthy", mHandler); - executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); - server.setExecutor(executorService); - start(daemon); + this(httpServer, registry, daemon, null); } /** - * Start a HTTP server serving Prometheus metrics from the given registry. + * Start an HTTP server serving Prometheus metrics from the given registry. */ public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, boolean daemon) throws IOException { this(HttpServer.create(addr, 3), registry, daemon); } /** - * Start a HTTP server serving Prometheus metrics from the given registry using non-daemon threads. + * Start an HTTP server serving Prometheus metrics from the given registry using non-daemon threads. */ public HTTPServer(InetSocketAddress addr, CollectorRegistry registry) throws IOException { this(addr, registry, false); } /** - * Start a HTTP server serving the default Prometheus registry. + * Start an HTTP server serving the default Prometheus registry. */ public HTTPServer(int port, boolean daemon) throws IOException { this(new InetSocketAddress(port), CollectorRegistry.defaultRegistry, daemon); } /** - * Start a HTTP server serving the default Prometheus registry using non-daemon threads. + * Start an HTTP server serving the default Prometheus registry using non-daemon threads. */ public HTTPServer(int port) throws IOException { this(port, false); } /** - * Start a HTTP server serving the default Prometheus registry. + * Start an HTTP server serving the default Prometheus registry. */ public HTTPServer(String host, int port, boolean daemon) throws IOException { this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, daemon); } /** - * Start a HTTP server serving the default Prometheus registry using non-daemon threads. + * Start an HTTP server serving the default Prometheus registry using non-daemon threads. */ public HTTPServer(String host, int port) throws IOException { this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, false); } + private HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon, Supplier> sampleNameFilterSupplier) { + if (httpServer.getAddress() == null) + throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); + + server = httpServer; + HttpHandler mHandler = new HTTPMetricHandler(registry, sampleNameFilterSupplier); + server.createContext("/", mHandler); + server.createContext("/metrics", mHandler); + server.createContext("/-/healthy", mHandler); + executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); + server.setExecutor(executorService); + start(daemon); + } + /** - * Start a HTTP server by making sure that its background thread inherit proper daemon flag. + * Start an HTTP server by making sure that its background thread inherit proper daemon flag. */ private void start(boolean daemon) { if (daemon == Thread.currentThread().isDaemon()) { @@ -254,8 +418,17 @@ public void run() { /** * Stop the HTTP server. + * @deprecated renamed to close(), so that the HTTPServer can be used in try-with-resources. */ public void stop() { + close(); + } + + /** + * Stop the HTTPServer. + */ + @Override + public void close() { server.stop(0); executorService.shutdown(); // Free any (parked/idle) threads in pool } diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java new file mode 100644 index 000000000..68094ad81 --- /dev/null +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java @@ -0,0 +1,26 @@ +package io.prometheus.client.exporter; + +import io.prometheus.client.Predicate; +import io.prometheus.client.Supplier; + +/** + * For convenience, an implementation of a {@code Supplier>} that + * always returns the same sampleNameFilter. + */ +public class SampleNameFilterSupplier implements Supplier> { + + private final Predicate sampleNameFilter; + + public static SampleNameFilterSupplier of(Predicate sampleNameFilter) { + return new SampleNameFilterSupplier(sampleNameFilter); + } + + private SampleNameFilterSupplier(Predicate sampleNameFilter) { + this.sampleNameFilter = sampleNameFilter; + } + + @Override + public Predicate get() { + return sampleNameFilter; + } +} diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java index 80bca9d90..aaddd5e22 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java @@ -7,7 +7,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Java6Assertions.assertThat; public class TestDaemonFlags { diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index c9f6beed6..af99ccf1f 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -10,50 +10,42 @@ import java.util.Scanner; import java.util.zip.GZIPInputStream; -import org.junit.After; +import io.prometheus.client.SampleNameFilter; import org.junit.Before; import org.junit.Test; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Java6Assertions.assertThat; public class TestHTTPServer { - HTTPServer s; + CollectorRegistry registry; @Before public void init() throws IOException { - CollectorRegistry registry = new CollectorRegistry(); + registry = new CollectorRegistry(); Gauge.build("a", "a help").register(registry); Gauge.build("b", "a help").register(registry); Gauge.build("c", "a help").register(registry); - s = new HTTPServer(new InetSocketAddress(0), registry); - } - - @After - public void cleanup() { - s.stop(); } - - String request(String context, String suffix) throws IOException { + String request(HTTPServer s, String context, String suffix) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); connection.connect(); - Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; + Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); + return scanner.hasNext() ? scanner.next() : ""; } - String request(String suffix) throws IOException { - return request("/metrics", suffix); + String request(HTTPServer s, String suffix) throws IOException { + return request(s, "/metrics", suffix); } - String requestWithCompression(String suffix) throws IOException { - return requestWithCompression("/metrics", suffix); + String requestWithCompression(HTTPServer s, String suffix) throws IOException { + return requestWithCompression(s, "/metrics", suffix); } - String requestWithCompression(String context, String suffix) throws IOException { + String requestWithCompression(HTTPServer s, String context, String suffix) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); @@ -61,18 +53,18 @@ String requestWithCompression(String context, String suffix) throws IOException connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); connection.connect(); GZIPInputStream gzs = new GZIPInputStream(connection.getInputStream()); - Scanner s = new Scanner(gzs).useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; + Scanner scanner = new Scanner(gzs).useDelimiter("\\A"); + return scanner.hasNext() ? scanner.next() : ""; } - String requestWithAccept(String accept) throws IOException { + String requestWithAccept(HTTPServer s, String accept) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort(); URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Accept", accept); - Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; + Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); + return scanner.hasNext() ? scanner.next() : ""; } @Test(expected = IllegalArgumentException.class) @@ -84,67 +76,130 @@ public void testRefuseUsingUnbound() throws IOException { @Test public void testSimpleRequest() throws IOException { - String response = request(""); - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, ""); + assertThat(response).contains("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).contains("c 0.0"); + } finally { + s.close(); + } } @Test public void testBadParams() throws IOException { - String response = request("?x"); - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, "?x"); + assertThat(response).contains("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).contains("c 0.0"); + } finally { + s.close(); + } } @Test public void testSingleName() throws IOException { - String response = request("?name[]=a"); - assertThat(response).contains("a 0.0"); - assertThat(response).doesNotContain("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, "?name[]=a"); + assertThat(response).contains("a 0.0"); + assertThat(response).doesNotContain("b 0.0"); + assertThat(response).doesNotContain("c 0.0"); + } finally { + s.close(); + } } @Test public void testMultiName() throws IOException { - String response = request("?name[]=a&name[]=b"); - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, "?name[]=a&name[]=b"); + assertThat(response).contains("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).doesNotContain("c 0.0"); + } finally { + s.close(); + } + } + + @Test + public void testSampleNameFilter() throws IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withSampleNameFilter(new SampleNameFilter.Builder() + .nameMustNotStartWith("a") + .build()) + .build(); + try { + String response = request(s, "?name[]=a&name[]=b"); + assertThat(response).doesNotContain("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).doesNotContain("c 0.0"); + } finally { + s.close(); + } } @Test public void testDecoding() throws IOException { - String response = request("?n%61me[]=%61"); - assertThat(response).contains("a 0.0"); - assertThat(response).doesNotContain("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, "?n%61me[]=%61"); + assertThat(response).contains("a 0.0"); + assertThat(response).doesNotContain("b 0.0"); + assertThat(response).doesNotContain("c 0.0"); + } finally { + s.close(); + } } @Test public void testGzipCompression() throws IOException { - String response = requestWithCompression(""); - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = requestWithCompression(s, ""); + assertThat(response).contains("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).contains("c 0.0"); + } finally { + s.close(); + } } @Test public void testOpenMetrics() throws IOException { - String response = requestWithAccept("application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"); - assertThat(response).contains("# EOF"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = requestWithAccept(s, "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"); + assertThat(response).contains("# EOF"); + } finally { + s.close(); + } } @Test public void testHealth() throws IOException { - String response = request("/-/healthy", ""); - assertThat(response).contains("Exporter is Healthy"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = request(s, "/-/healthy", ""); + assertThat(response).contains("Exporter is Healthy"); + } finally { + s.close(); + } } @Test public void testHealthGzipCompression() throws IOException { - String response = requestWithCompression("/-/healthy", ""); - assertThat(response).contains("Exporter is Healthy"); + HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + try { + String response = requestWithCompression(s, "/-/healthy", ""); + assertThat(response).contains("Exporter is Healthy"); + } finally { + s.close(); + } } } diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java index 6c1f493a5..8433fd67d 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java @@ -3,8 +3,10 @@ import io.prometheus.client.servlet.common.adapter.FilterConfigAdapter; import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; +import io.prometheus.client.servlet.common.adapter.ServletConfigAdapter; import javax.servlet.FilterConfig; +import javax.servlet.ServletConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -89,6 +91,20 @@ public String getInitParameter(String name) { } } + private static class ServletConfigAdapterImpl implements ServletConfigAdapter { + + final ServletConfig delegate; + + private ServletConfigAdapterImpl(ServletConfig delegate) { + this.delegate = delegate; + } + + @Override + public String getInitParameter(String name) { + return delegate.getInitParameter(name); + } + } + public static HttpServletRequestAdapter wrap(HttpServletRequest req) { return new HttpServletRequestAdapterImpl(req); } @@ -100,4 +116,8 @@ public static HttpServletResponseAdapter wrap(HttpServletResponse resp) { public static FilterConfigAdapter wrap(FilterConfig filterConfig) { return new FilterConfigAdapterImpl(filterConfig); } + + public static ServletConfigAdapter wrap(ServletConfig servletConfig) { + return new ServletConfigAdapterImpl(servletConfig); + } } \ No newline at end of file diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java index 77560335b..76a6d5cee 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java @@ -1,8 +1,13 @@ package io.prometheus.client.exporter; +import io.prometheus.client.Adapter; import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Predicate; import io.prometheus.client.servlet.common.exporter.Exporter; +import io.prometheus.client.servlet.common.exporter.ServletConfigurationException; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -18,11 +23,28 @@ public class MetricsServlet extends HttpServlet { private final Exporter exporter; public MetricsServlet() { - exporter = new Exporter(); + this(CollectorRegistry.defaultRegistry, null); + } + + public MetricsServlet(Predicate sampleNameFilter) { + this(CollectorRegistry.defaultRegistry, sampleNameFilter); } public MetricsServlet(CollectorRegistry registry) { - exporter = new Exporter(registry); + this(registry, null); + } + + public MetricsServlet(CollectorRegistry registry, Predicate sampleNameFilter) { + exporter = new Exporter(registry, sampleNameFilter); + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + try { + exporter.init(Adapter.wrap(servletConfig)); + } catch (ServletConfigurationException e) { + throw new ServletException(e); + } } @Override diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java new file mode 100644 index 000000000..f63d60a5c --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java @@ -0,0 +1,5 @@ +package io.prometheus.client.servlet.common.adapter; + +public interface ServletConfigAdapter { + String getInitParameter(String name); +} diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java index 4797710b0..8a76dd218 100644 --- a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java @@ -1,9 +1,12 @@ package io.prometheus.client.servlet.common.exporter; import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.SampleNameFilter; +import io.prometheus.client.Predicate; import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; import io.prometheus.client.exporter.common.TextFormat; +import io.prometheus.client.servlet.common.adapter.ServletConfigAdapter; import java.io.BufferedWriter; import java.io.IOException; @@ -11,29 +14,53 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; /** * The MetricsServlet class exists to provide a simple way of exposing the metrics values. - * */ public class Exporter { - private CollectorRegistry registry; + public static final String NAME_MUST_BE_EQUAL_TO = "name-must-be-equal-to"; + public static final String NAME_MUST_NOT_BE_EQUAL_TO = "name-must-not-be-equal-to"; + public static final String NAME_MUST_START_WITH = "name-must-start-with"; + public static final String NAME_MUST_NOT_START_WITH = "name-must-not-start-with"; - /** - * Construct a MetricsServlet for the default registry. - */ - public Exporter() { - this(CollectorRegistry.defaultRegistry); - } + private CollectorRegistry registry; + private Predicate sampleNameFilter; /** * Construct a MetricsServlet for the given registry. * @param registry collector registry + * @param sampleNameFilter programmatically set a {@link SampleNameFilter}. + * If there are any filter options configured in {@code ServletConfig}, they will be merged + * so that samples need to pass both filters to be exported. + * sampleNameFilter may be {@code null} indicating that nothing should be filtered. */ - public Exporter(CollectorRegistry registry) { + public Exporter(CollectorRegistry registry, Predicate sampleNameFilter) { this.registry = registry; + this.sampleNameFilter = sampleNameFilter; + } + + public void init(ServletConfigAdapter servletConfig) throws ServletConfigurationException { + List allowedNames = SampleNameFilter.stringToList(servletConfig.getInitParameter(NAME_MUST_BE_EQUAL_TO)); + List excludedNames = SampleNameFilter.stringToList(servletConfig.getInitParameter(NAME_MUST_NOT_BE_EQUAL_TO)); + List allowedPrefixes = SampleNameFilter.stringToList(servletConfig.getInitParameter(NAME_MUST_START_WITH)); + List excludedPrefixes = SampleNameFilter.stringToList(servletConfig.getInitParameter(NAME_MUST_NOT_START_WITH)); + if (!allowedPrefixes.isEmpty() || !excludedPrefixes.isEmpty() || !allowedNames.isEmpty() || !excludedNames.isEmpty()) { + SampleNameFilter filter = new SampleNameFilter.Builder() + .nameMustBeEqualTo(allowedNames) + .nameMustNotBeEqualTo(excludedNames) + .nameMustStartWith(allowedPrefixes) + .nameMustNotStartWith(excludedPrefixes) + .build(); + if (this.sampleNameFilter != null) { + this.sampleNameFilter = filter.and(this.sampleNameFilter); + } else { + this.sampleNameFilter = filter; + } + } } public void doGet(final HttpServletRequestAdapter req, final HttpServletResponseAdapter resp) throws IOException { @@ -43,7 +70,12 @@ public void doGet(final HttpServletRequestAdapter req, final HttpServletResponse Writer writer = new BufferedWriter(resp.getWriter()); try { - TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(parse(req))); + Predicate filter = SampleNameFilter.restrictToNamesEqualTo(sampleNameFilter, parse(req)); + if (filter == null) { + TextFormat.writeFormat(contentType, writer, registry.metricFamilySamples()); + } else { + TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(filter)); + } writer.flush(); } finally { writer.close(); diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java new file mode 100644 index 000000000..4d99cbb25 --- /dev/null +++ b/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java @@ -0,0 +1,4 @@ +package io.prometheus.client.servlet.common.exporter; + +public class ServletConfigurationException extends Exception { +} diff --git a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java index ed10fb10f..3143a55d8 100644 --- a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java +++ b/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java @@ -89,7 +89,7 @@ public void testWriterFiltersBasedOnParameter() throws IOException { StringWriter responseBody = new StringWriter(); HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); - new Exporter(registry).doGet(req, resp); + new Exporter(registry, null).doGet(req, resp); assertThat(responseBody.toString()).contains("a 0.0"); assertThat(responseBody.toString()).contains("b 0.0"); @@ -110,7 +110,7 @@ public void close() { CollectorRegistry registry = new CollectorRegistry(); Gauge a = Gauge.build("a", "a help").register(registry); - new Exporter(registry).doGet(req, resp); + new Exporter(registry, null).doGet(req, resp); Assert.assertTrue(closed.get()); } @@ -133,7 +133,7 @@ public void close() { Gauge a = Gauge.build("a", "a help").register(registry); try { - new Exporter(registry).doGet(req, resp); + new Exporter(registry, null).doGet(req, resp); fail("Exception expected"); } catch (Exception e) { } @@ -150,7 +150,7 @@ public void testOpenMetricsNegotiated() throws IOException { StringWriter responseBody = new StringWriter(); HttpServletResponseAdapter resp = mockHttpServletResponse(new PrintWriter(responseBody)); - new Exporter(registry).doGet(req, resp); + new Exporter(registry, null).doGet(req, resp); assertThat(responseBody.toString()).contains("a 0.0"); assertThat(responseBody.toString()).contains("# EOF"); diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java index 3321a1582..4a4b8bb01 100644 --- a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java @@ -4,7 +4,9 @@ import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; import io.prometheus.client.servlet.common.adapter.HttpServletResponseAdapter; +import io.prometheus.client.servlet.common.adapter.ServletConfigAdapter; import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletConfig; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @@ -89,6 +91,20 @@ public String getInitParameter(String name) { } } + private static class ServletConfigAdapterImpl implements ServletConfigAdapter { + + final ServletConfig delegate; + + private ServletConfigAdapterImpl(ServletConfig delegate) { + this.delegate = delegate; + } + + @Override + public String getInitParameter(String name) { + return delegate.getInitParameter(name); + } + } + public static HttpServletRequestAdapter wrap(HttpServletRequest req) { return new HttpServletRequestAdapterImpl(req); } @@ -100,4 +116,8 @@ public static HttpServletResponseAdapter wrap(HttpServletResponse resp) { public static FilterConfigAdapter wrap(FilterConfig filterConfig) { return new FilterConfigAdapterImpl(filterConfig); } + + public static ServletConfigAdapter wrap(ServletConfig servletConfig) { + return new ServletConfigAdapterImpl(servletConfig); + } } \ No newline at end of file diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java index 749d835f9..bf8646af7 100644 --- a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java @@ -1,7 +1,12 @@ package io.prometheus.client.servlet.jakarta.exporter; +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Predicate; import io.prometheus.client.servlet.common.exporter.Exporter; +import io.prometheus.client.servlet.common.exporter.ServletConfigurationException; +import jakarta.servlet.ServletConfig; +import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -14,7 +19,32 @@ */ public class MetricsServlet extends HttpServlet { - private final Exporter exporter = new Exporter(); + private final Exporter exporter; + + public MetricsServlet() { + this(CollectorRegistry.defaultRegistry, null); + } + + public MetricsServlet(Predicate sampleNameFilter) { + this(CollectorRegistry.defaultRegistry, sampleNameFilter); + } + + public MetricsServlet(CollectorRegistry registry) { + this(registry, null); + } + + public MetricsServlet(CollectorRegistry registry, Predicate sampleNameFilter) { + exporter = new Exporter(registry, sampleNameFilter); + } + + @Override + public void init(ServletConfig servletConfig) throws ServletException { + try { + exporter.init(wrap(servletConfig)); + } catch (ServletConfigurationException e) { + throw new ServletException(e); + } + } @Override protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException { From c3306c4c522c6246d54f2d2504099c8163492944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 27 Aug 2021 19:41:41 +0200 Subject: [PATCH 090/980] Change packaging of simpleclient_tracer to bundle #678 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- {benchmark => benchmarks}/README.md | 0 {benchmark => benchmarks}/pom.xml | 1 - .../client/benchmark/CounterBenchmark.java | 0 .../client/benchmark/ExemplarsBenchmark.java | 0 .../client/benchmark/GaugeBenchmark.java | 0 .../client/benchmark/SummaryBenchmark.java | 0 pom.xml | 2 +- simpleclient/pom.xml | 1 - simpleclient_bom/pom.xml | 67 ++++++++++++------- simpleclient_caffeine/pom.xml | 1 - simpleclient_common/pom.xml | 1 - simpleclient_dropwizard/pom.xml | 1 - simpleclient_graphite_bridge/pom.xml | 1 - simpleclient_guava/pom.xml | 1 - simpleclient_hibernate/pom.xml | 1 - simpleclient_hotspot/pom.xml | 1 - simpleclient_httpserver/pom.xml | 1 - simpleclient_jetty/pom.xml | 1 + simpleclient_jetty_jdk8/pom.xml | 1 - simpleclient_log4j/pom.xml | 1 - simpleclient_log4j2/pom.xml | 1 - simpleclient_logback/pom.xml | 1 - simpleclient_pushgateway/pom.xml | 1 - simpleclient_servlet_common/pom.xml | 1 - simpleclient_servlet_jakarta/pom.xml | 1 - simpleclient_spring_boot/pom.xml | 1 - .../simpleclient_tracer_common/pom.xml | 2 + .../simpleclient_tracer_otel/pom.xml | 2 + .../simpleclient_tracer_otel_agent/pom.xml | 2 + simpleclient_vertx/pom.xml | 1 - 30 files changed, 49 insertions(+), 46 deletions(-) rename {benchmark => benchmarks}/README.md (100%) rename {benchmark => benchmarks}/pom.xml (99%) rename {benchmark => benchmarks}/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java (100%) rename {benchmark => benchmarks}/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java (100%) rename {benchmark => benchmarks}/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java (100%) rename {benchmark => benchmarks}/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java (100%) diff --git a/benchmark/README.md b/benchmarks/README.md similarity index 100% rename from benchmark/README.md rename to benchmarks/README.md diff --git a/benchmark/pom.xml b/benchmarks/pom.xml similarity index 99% rename from benchmark/pom.xml rename to benchmarks/pom.xml index a670245f2..d9e63a945 100644 --- a/benchmark/pom.xml +++ b/benchmarks/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus benchmarks Prometheus Java Client Benchmarks diff --git a/benchmark/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java similarity index 100% rename from benchmark/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java rename to benchmarks/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java diff --git a/benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java similarity index 100% rename from benchmark/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java rename to benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java diff --git a/benchmark/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java similarity index 100% rename from benchmark/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java rename to benchmarks/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java diff --git a/benchmark/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java similarity index 100% rename from benchmark/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java rename to benchmarks/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java diff --git a/pom.xml b/pom.xml index 08de32541..c5fccf51f 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ simpleclient_tracer simpleclient_vertx simpleclient_bom - benchmark + benchmarks integration_tests diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 6b603330e..7f076565d 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient bundle diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index a46892b02..39b85b176 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -29,97 +29,112 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + ${project.version} io.prometheus - simpleclient_common - 0.11.1-SNAPSHOT + simpleclient_caffeine + ${project.version} io.prometheus - simpleclient_caffeine - 0.11.1-SNAPSHOT + simpleclient_common + ${project.version} io.prometheus simpleclient_dropwizard - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_graphite_bridge - 0.11.1-SNAPSHOT + ${project.version} io.prometheus - simpleclient_hibernate - 0.11.1-SNAPSHOT + simpleclient_guava + ${project.version} io.prometheus - simpleclient_guava - 0.11.1-SNAPSHOT + simpleclient_hibernate + ${project.version} io.prometheus simpleclient_hotspot - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_httpserver - 0.11.1-SNAPSHOT + ${project.version} + + + io.prometheus + simpleclient_jetty + ${project.version} + + + io.prometheus + simpleclient_jetty_jdk8 + ${project.version} io.prometheus simpleclient_log4j - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_log4j2 - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_logback - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_pushgateway - 0.11.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_servlet - 0.11.1-SNAPSHOT + ${project.version} io.prometheus - simpleclient_spring_web - 0.11.1-SNAPSHOT + simpleclient_servlet_jakarta + ${project.version} io.prometheus simpleclient_spring_boot - 0.11.1-SNAPSHOT + ${project.version} io.prometheus - simpleclient_jetty - 0.11.1-SNAPSHOT + simpleclient_spring_web + ${project.version} io.prometheus - simpleclient_jetty_jdk8 - 0.11.1-SNAPSHOT + simpleclient_tracer_otel + ${project.version} + + + io.prometheus + simpleclient_tracer_otel_agent + ${project.version} io.prometheus simpleclient_vertx - 0.11.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index c1f8be0e6..3ffa32841 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_caffeine bundle diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index dcd8ffdd0..7a88a38cb 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_common bundle diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 018cefb6e..99525a42d 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_dropwizard bundle diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 79925e2f7..f50ec6c00 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_graphite_bridge bundle diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 2e166b999..3ba619f3f 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_guava bundle diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index fbdb97611..ea21d6017 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_hibernate bundle diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index ee1d61559..909b1ac4a 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_hotspot bundle diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 84235bb9b..0106b3ff7 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_httpserver bundle diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index c06936994..214a14409 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -9,6 +9,7 @@ simpleclient_jetty + bundle Prometheus Java Simpleclient Jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index d7ac3fac5..ed79e89ee 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_jetty_jdk8 bundle diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index f5f9f22cd..74ebd8833 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_log4j bundle diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 3ef4b77b7..e9f1eac13 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_log4j2 bundle diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 2298c7cc6..fd1b56036 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_logback bundle diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 3e2197471..87cf30046 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_pushgateway bundle diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index d5d203025..0c8c6f052 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_servlet_common bundle diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 69bf3424f..f35aa23d6 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_servlet_jakarta bundle diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 9e677b393..3a520d8a8 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -8,7 +8,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_spring_boot bundle diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 0f2042ca4..291749278 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -9,6 +9,8 @@ simpleclient_tracer_common + bundle + Prometheus Java Span Context Supplier - Common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 11d36bbf9..ed0acf3f3 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -9,6 +9,8 @@ simpleclient_tracer_otel + bundle + Prometheus Java Span Context Supplier - OpenTelemetry diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 67272ebff..edad73066 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -9,6 +9,8 @@ simpleclient_tracer_otel_agent + bundle + Prometheus Java Span Context Supplier - OpenTelemetry Agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index f4ae3a9a7..02f5b6a49 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -20,7 +20,6 @@ 0.11.1-SNAPSHOT - io.prometheus simpleclient_vertx bundle From 5655d1fa896a9799dce7830a50b8a05672f1b299 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 29 Aug 2021 16:57:24 -0400 Subject: [PATCH 091/980] Added HTTP authentication to HTTPServer (#682) Signed-off-by: Doug Hoard --- simpleclient_httpserver/pom.xml | 6 ++ .../client/exporter/HTTPServer.java | 38 +++++++-- .../client/exporter/TestHTTPServer.java | 85 +++++++++++++++++++ 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 0106b3ff7..475ab4fc4 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -56,5 +56,11 @@ 2.6.0 test + + javax.xml.bind + jaxb-api + 2.3.0 + test + diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index dbc031307..2086f572f 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -26,6 +26,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; @@ -195,6 +197,7 @@ public static class Builder { private boolean daemon = false; private Predicate sampleNameFilter; private Supplier> sampleNameFilterSupplier; + private Authenticator authenticator; /** * Port to bind to. Must not be called together with {@link #withInetSocketAddress(InetSocketAddress)} @@ -286,6 +289,18 @@ public Builder withRegistry(CollectorRegistry registry) { return this; } + /** + * Optional: {@link Authenticator} to use to support authentication. + */ + public Builder withAuthenticator(Authenticator authenticator) { + this.authenticator = authenticator; + return this; + } + + /** + * Build the HTTPServer + * @throws IOException + */ public HTTPServer build() throws IOException { if (sampleNameFilter != null) { assertNull(sampleNameFilterSupplier, "cannot configure 'sampleNameFilter' and 'sampleNameFilterSupplier' at the same time"); @@ -296,7 +311,7 @@ public HTTPServer build() throws IOException { assertNull(hostname, "cannot configure 'httpServer' and 'hostname' at the same time"); assertNull(inetAddress, "cannot configure 'httpServer' and 'inetAddress' at the same time"); assertNull(inetSocketAddress, "cannot configure 'httpServer' and 'inetSocketAddress' at the same time"); - return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier); + return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); } else if (inetSocketAddress != null) { assertZero(port, "cannot configure 'inetSocketAddress' and 'port' at the same time"); assertNull(hostname, "cannot configure 'inetSocketAddress' and 'hostname' at the same time"); @@ -309,7 +324,7 @@ public HTTPServer build() throws IOException { } else { inetSocketAddress = new InetSocketAddress(port); } - return new HTTPServer(HttpServer.create(inetSocketAddress, 3), registry, daemon, sampleNameFilterSupplier); + return new HTTPServer(HttpServer.create(inetSocketAddress, 3), registry, daemon, sampleNameFilterSupplier, authenticator); } private void assertNull(Object o, String msg) { @@ -330,7 +345,7 @@ private void assertZero(int i, String msg) { * The {@code httpServer} is expected to already be bound to an address */ public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon) throws IOException { - this(httpServer, registry, daemon, null); + this(httpServer, registry, daemon, null, null); } /** @@ -375,15 +390,24 @@ public HTTPServer(String host, int port) throws IOException { this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, false); } - private HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon, Supplier> sampleNameFilterSupplier) { + private HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon, Supplier> sampleNameFilterSupplier, Authenticator authenticator) { if (httpServer.getAddress() == null) throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); server = httpServer; HttpHandler mHandler = new HTTPMetricHandler(registry, sampleNameFilterSupplier); - server.createContext("/", mHandler); - server.createContext("/metrics", mHandler); - server.createContext("/-/healthy", mHandler); + HttpContext mContext = server.createContext("/", mHandler); + if (authenticator != null) { + mContext.setAuthenticator(authenticator); + } + mContext = server.createContext("/metrics", mHandler); + if (authenticator != null) { + mContext.setAuthenticator(authenticator); + } + mContext = server.createContext("/-/healthy", mHandler); + if (authenticator != null) { + mContext.setAuthenticator(authenticator); + } executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); server.setExecutor(executorService); start(daemon); diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index af99ccf1f..f0dfe874a 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -1,9 +1,12 @@ package io.prometheus.client.exporter; +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.BasicAuthenticator; import com.sun.net.httpserver.HttpServer; import io.prometheus.client.Gauge; import io.prometheus.client.CollectorRegistry; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.URL; import java.net.URLConnection; @@ -11,9 +14,12 @@ import java.util.zip.GZIPInputStream; import io.prometheus.client.SampleNameFilter; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import javax.xml.bind.DatatypeConverter; + import static org.assertj.core.api.Java6Assertions.assertThat; public class TestHTTPServer { @@ -67,6 +73,39 @@ String requestWithAccept(HTTPServer s, String accept) throws IOException { return scanner.hasNext() ? scanner.next() : ""; } + String requestWithCredentials(HTTPServer httpServer, String context, String suffix, String user, String password) throws IOException { + String url = "http://localhost:" + httpServer.server.getAddress().getPort() + context + suffix; + URLConnection connection = new URL(url).openConnection(); + connection.setDoOutput(true); + if (user != null && password != null) { + connection.setRequestProperty("Authorization", encodeCredentials(user, password)); + } + connection.connect(); + Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } + + String encodeCredentials(String user, String password) { + // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, + try { + byte[] credentialsBytes = (user + ":" + password).getBytes("UTF-8"); + String encoded = DatatypeConverter.printBase64Binary(credentialsBytes); + encoded = String.format("Basic %s", encoded); + return encoded; + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e); + } + } + + Authenticator createAuthenticator(String realm, final String validUsername, final String validPassword) { + return new BasicAuthenticator(realm) { + @Override + public boolean checkCredentials(String username, String password) { + return validUsername.equals(username) && validPassword.equals(password); + } + }; + } + @Test(expected = IllegalArgumentException.class) public void testRefuseUsingUnbound() throws IOException { CollectorRegistry registry = new CollectorRegistry(); @@ -202,4 +241,50 @@ public void testHealthGzipCompression() throws IOException { s.close(); } } + + @Test + public void testBasicAuthSuccess() throws IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withAuthenticator(createAuthenticator("/", "user", "secret")) + .build(); + try { + String response = requestWithCredentials(s, "/metrics","?name[]=a&name[]=b", "user", "secret"); + assertThat(response).contains("a 0.0"); + } finally { + s.close(); + } + } + + @Test + public void testBasicAuthCredentialsMissing() throws IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withAuthenticator(createAuthenticator("/", "user", "secret")) + .build(); + try { + request(s, "/metrics", "?name[]=a&name[]=b"); + Assert.fail("expected IOException with HTTP 401"); + } catch (IOException e) { + Assert.assertTrue(e.getMessage().contains("401")); + } finally { + s.close(); + } + } + + @Test + public void testBasicAuthWrongCredentials() throws IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withAuthenticator(createAuthenticator("/", "user", "wrong")) + .build(); + try { + request(s, "/metrics", "?name[]=a&name[]=b"); + Assert.fail("expected IOException with HTTP 401"); + } catch (IOException e) { + Assert.assertTrue(e.getMessage().contains("401")); + } finally { + s.close(); + } + } } From 41572055033003fb95bd730ae1b033aa02381d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 29 Aug 2021 23:10:17 +0200 Subject: [PATCH 092/980] [maven-release-plugin] prepare release parent-0.12.0 --- benchmarks/pom.xml | 2 +- integration_tests/example_application/pom.xml | 2 +- integration_tests/exemplars_otel/pom.xml | 2 +- integration_tests/exemplars_otel_agent/pom.xml | 2 +- integration_tests/java_versions/pom.xml | 2 +- integration_tests/pom.xml | 2 +- integration_tests/servlet_jakarta_exporter_webxml/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 34 files changed, 67 insertions(+), 67 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index d9e63a945..27c6d0e83 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 benchmarks diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index b8618f9c1..2c54eead7 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.1-SNAPSHOT + 0.12.0 example_application diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index 186b5dbae..cc044b8b0 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.1-SNAPSHOT + 0.12.0 exemplars_otel diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/exemplars_otel_agent/pom.xml index 80ee9f089..6afc5f344 100644 --- a/integration_tests/exemplars_otel_agent/pom.xml +++ b/integration_tests/exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.1-SNAPSHOT + 0.12.0 exemplars_otel_agent diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/java_versions/pom.xml index 0bb95d83e..f562b7e8d 100644 --- a/integration_tests/java_versions/pom.xml +++ b/integration_tests/java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.1-SNAPSHOT + 0.12.0 java_versions diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 9a5d87099..ceeab30ad 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 integration_tests diff --git a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml index 582c5b7da..dc5b3d244 100644 --- a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.11.1-SNAPSHOT + 0.12.0 servlet_jakarta_exporter_webxml diff --git a/pom.xml b/pom.xml index c5fccf51f..52236c00f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.12.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 7f076565d..2f937c82a 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 39b85b176..823f6a706 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 3ffa32841..425069902 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 7a88a38cb..9d1bb6834 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 99525a42d..f9f97842d 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index f50ec6c00..2d8a48267 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 3ba619f3f..e3b6827ad 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index ea21d6017..19cd069cc 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 909b1ac4a..411b62aef 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_servlet - 0.11.1-SNAPSHOT + 0.12.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 475ab4fc4..dbee1a444 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 214a14409..aaf97a982 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index ed79e89ee..429f8c5e0 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 74ebd8833..5abba3b73 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index e9f1eac13..476d487b6 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index fd1b56036..12371952e 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 87cf30046..dbae93fdb 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index bf610b7ab..4888cd68a 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_servlet_common - 0.11.1-SNAPSHOT + 0.12.0 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 0c8c6f052..c9976c079 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index f35aa23d6..6664ca870 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_servlet_common - 0.11.1-SNAPSHOT + 0.12.0 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 3a520d8a8..91b7ae8c9 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_spring_web - 0.11.1-SNAPSHOT + 0.12.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 6de55c30b..68692334a 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index d15ff824d..34baf33ab 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 291749278..70fb3535e 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index ed0acf3f3..8dc83315a 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index edad73066..d92fc347f 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 02f5b6a49..bdf2fdb50 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.11.1-SNAPSHOT + 0.12.0 simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.11.1-SNAPSHOT + 0.12.0 io.prometheus simpleclient_common - 0.11.1-SNAPSHOT + 0.12.0 io.vertx From d72ad8bd642b98ab9953aea0d91c7bde4d50c587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 29 Aug 2021 23:10:21 +0200 Subject: [PATCH 093/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/example_application/pom.xml | 2 +- integration_tests/exemplars_otel/pom.xml | 2 +- integration_tests/exemplars_otel_agent/pom.xml | 2 +- integration_tests/java_versions/pom.xml | 2 +- integration_tests/pom.xml | 2 +- integration_tests/servlet_jakarta_exporter_webxml/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 34 files changed, 67 insertions(+), 67 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 27c6d0e83..9be936b63 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT benchmarks diff --git a/integration_tests/example_application/pom.xml b/integration_tests/example_application/pom.xml index 2c54eead7..ea92e06d5 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/example_application/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.0 + 0.12.1-SNAPSHOT example_application diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/exemplars_otel/pom.xml index cc044b8b0..dfea6ebf6 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/exemplars_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.0 + 0.12.1-SNAPSHOT exemplars_otel diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/exemplars_otel_agent/pom.xml index 6afc5f344..e1cecf937 100644 --- a/integration_tests/exemplars_otel_agent/pom.xml +++ b/integration_tests/exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.0 + 0.12.1-SNAPSHOT exemplars_otel_agent diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/java_versions/pom.xml index f562b7e8d..cbeba947f 100644 --- a/integration_tests/java_versions/pom.xml +++ b/integration_tests/java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.0 + 0.12.1-SNAPSHOT java_versions diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index ceeab30ad..1f3d5d8ae 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT integration_tests diff --git a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml index dc5b3d244..e53b175c5 100644 --- a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.0 + 0.12.1-SNAPSHOT servlet_jakarta_exporter_webxml diff --git a/pom.xml b/pom.xml index 52236c00f..bf8cf6250 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.12.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 2f937c82a..aa9e7a7d6 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 823f6a706..e7a77053c 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 425069902..4360f754f 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 9d1bb6834..c1b2a345c 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index f9f97842d..8468a86fa 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 2d8a48267..42123acb3 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index e3b6827ad..c2578193c 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 19cd069cc..8d4fea0f5 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 411b62aef..a6d69f1c1 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.12.0 + 0.12.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index dbee1a444..c086eb3ff 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index aaf97a982..ef40fec43 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 429f8c5e0..61fda81c4 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 5abba3b73..c12ff421c 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 476d487b6..44768169e 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 12371952e..12c72e5da 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index dbae93fdb..0f126991b 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 4888cd68a..bdbe41a9c 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.12.0 + 0.12.1-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index c9976c079..5d5b75e40 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 6664ca870..2e9b25a21 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.12.0 + 0.12.1-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 91b7ae8c9..e357e461c 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.12.0 + 0.12.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 68692334a..91b0045d8 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 34baf33ab..b79adf6cf 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 70fb3535e..54ce04625 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 8dc83315a..b5284cc4d 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index d92fc347f..7ee3f5009 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index bdf2fdb50..974e4fc26 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.12.0 + 0.12.1-SNAPSHOT simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.12.0 + 0.12.1-SNAPSHOT io.prometheus simpleclient_common - 0.12.0 + 0.12.1-SNAPSHOT io.vertx From f56cd15baddcbbb1154ea62fa244666493bf510b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 29 Aug 2021 23:52:51 +0200 Subject: [PATCH 094/980] Update documentation for rel 0.12.0 --- OTEL_EXEMPLARS.md | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OTEL_EXEMPLARS.md b/OTEL_EXEMPLARS.md index 779f2d4d3..487866362 100644 --- a/OTEL_EXEMPLARS.md +++ b/OTEL_EXEMPLARS.md @@ -53,7 +53,7 @@ you can exclude the corresponding dependencies in your `pom.xml`: io.prometheus simpleclient - 0.11.0 + 0.12.0 diff --git a/README.md b/README.md index 2aa8044a8..87f5c696b 100644 --- a/README.md +++ b/README.md @@ -46,25 +46,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.11.0 + 0.12.0 io.prometheus simpleclient_hotspot - 0.11.0 + 0.12.0 io.prometheus simpleclient_httpserver - 0.11.0 + 0.12.0 io.prometheus simpleclient_pushgateway - 0.11.0 + 0.12.0 ``` From 445177676fb20d66147be1b0dc1209568f97d6b8 Mon Sep 17 00:00:00 2001 From: Matthew Dolan Date: Sat, 11 Sep 2021 14:54:23 -0500 Subject: [PATCH 095/980] Add an InstrumentedAppender constructor that allows passing a CollectorRegistry (#690) * Add the InstrumentedAppender constructor that allows passing a CollectorRegistry Signed-off-by: Matthew Dolan * address comment: fix tests Signed-off-by: Matthew Dolan --- .../client/logback/InstrumentedAppender.java | 58 +++++++++++-------- .../logback/InstrumentedAppenderTest.java | 41 +++++++++---- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java b/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java index 2865bb471..092f52dc3 100644 --- a/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java +++ b/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java @@ -3,38 +3,46 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.UnsynchronizedAppenderBase; +import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Counter; public class InstrumentedAppender extends UnsynchronizedAppenderBase { - public static final String COUNTER_NAME = "logback_appender_total"; - private static final Counter COUNTER; - private static final Counter.Child TRACE_LABEL; - private static final Counter.Child DEBUG_LABEL; - private static final Counter.Child INFO_LABEL; - private static final Counter.Child WARN_LABEL; - private static final Counter.Child ERROR_LABEL; - - static { - COUNTER = Counter.build().name(COUNTER_NAME) - .help("Logback log statements at various log levels") - .labelNames("level") - .register(); - - TRACE_LABEL = COUNTER.labels("trace"); - DEBUG_LABEL = COUNTER.labels("debug"); - INFO_LABEL = COUNTER.labels("info"); - WARN_LABEL = COUNTER.labels("warn"); - ERROR_LABEL = COUNTER.labels("error"); - } + private static final Counter defaultCounter = Counter.build().name(COUNTER_NAME) + .help("Logback log statements at various log levels") + .labelNames("level") + .register(); + private final Counter.Child traceCounter; + private final Counter.Child debugCounter; + private final Counter.Child infoCounter; + private final Counter.Child warnCounter; + private final Counter.Child errorCounter; /** * Create a new instrumented appender using the default registry. */ public InstrumentedAppender() { + this(defaultCounter); } + /** + * Create a new instrumented appender using the supplied registry. + */ + public InstrumentedAppender(CollectorRegistry registry) { + this(Counter.build().name(COUNTER_NAME) + .help("Logback log statements at various log levels") + .labelNames("level") + .register(registry)); + } + + private InstrumentedAppender(Counter counter) { + this.traceCounter = counter.labels("trace"); + this.debugCounter = counter.labels("debug"); + this.infoCounter = counter.labels("info"); + this.warnCounter = counter.labels("warn"); + this.errorCounter = counter.labels("error"); + } @Override public void start() { @@ -45,19 +53,19 @@ public void start() { protected void append(ILoggingEvent event) { switch (event.getLevel().toInt()) { case Level.TRACE_INT: - TRACE_LABEL.inc(); + this.traceCounter.inc(); break; case Level.DEBUG_INT: - DEBUG_LABEL.inc(); + this.debugCounter.inc(); break; case Level.INFO_INT: - INFO_LABEL.inc(); + this.infoCounter.inc(); break; case Level.WARN_INT: - WARN_LABEL.inc(); + this.warnCounter.inc(); break; case Level.ERROR_INT: - ERROR_LABEL.inc(); + this.errorCounter.inc(); break; default: break; diff --git a/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java b/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java index b9b853710..af3bd1610 100644 --- a/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java +++ b/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java @@ -12,15 +12,21 @@ import org.junit.Test; public class InstrumentedAppenderTest { - + private CollectorRegistry registry; private InstrumentedAppender appender; + private InstrumentedAppender defaultAppender; private ILoggingEvent event; @Before public void setUp() throws Exception { - appender = new InstrumentedAppender(); + registry = new CollectorRegistry(); + + appender = new InstrumentedAppender(registry); appender.start(); - + + defaultAppender = new InstrumentedAppender(); + defaultAppender.start(); + event = mock(ILoggingEvent.class); } @@ -29,8 +35,10 @@ public void metersTraceEvents() throws Exception { when(event.getLevel()).thenReturn(Level.TRACE); appender.doAppend(event); - assertEquals(1, getLogLevelCount("trace")); + + defaultAppender.doAppend(event); + assertEquals(1, getDefaultLogLevelCount("trace")); } @Test @@ -38,8 +46,10 @@ public void metersDebugEvents() throws Exception { when(event.getLevel()).thenReturn(Level.DEBUG); appender.doAppend(event); - assertEquals(1, getLogLevelCount("debug")); + + defaultAppender.doAppend(event); + assertEquals(1, getDefaultLogLevelCount("debug")); } @Test @@ -47,8 +57,10 @@ public void metersInfoEvents() throws Exception { when(event.getLevel()).thenReturn(Level.INFO); appender.doAppend(event); - assertEquals(1, getLogLevelCount("info")); + + defaultAppender.doAppend(event); + assertEquals(1, getDefaultLogLevelCount("info")); } @Test @@ -56,8 +68,10 @@ public void metersWarnEvents() throws Exception { when(event.getLevel()).thenReturn(Level.WARN); appender.doAppend(event); - assertEquals(1, getLogLevelCount("warn")); + + defaultAppender.doAppend(event); + assertEquals(1, getDefaultLogLevelCount("warn")); } @Test @@ -65,12 +79,19 @@ public void metersErrorEvents() throws Exception { when(event.getLevel()).thenReturn(Level.ERROR); appender.doAppend(event); - assertEquals(1, getLogLevelCount("error")); + + defaultAppender.doAppend(event); + assertEquals(1, getDefaultLogLevelCount("error")); } private int getLogLevelCount(String level) { - return CollectorRegistry.defaultRegistry.getSampleValue(COUNTER_NAME, - new String[]{"level"}, new String[]{level}).intValue(); + return registry.getSampleValue(COUNTER_NAME, new String[]{"level"}, new String[]{level}).intValue(); + } + + private int getDefaultLogLevelCount(String level) { + return CollectorRegistry.defaultRegistry + .getSampleValue(COUNTER_NAME, new String[]{"level"}, new String[]{level}) + .intValue(); } } From a125fc3ace5d501b45b155c16f7e0f8481cae257 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sat, 11 Sep 2021 18:04:12 -0400 Subject: [PATCH 096/980] Added code to correctly handle HEAD request (#688) * Added code to correctly handle HEAD request Signed-off-by: Doug Hoard * Refactored solution and associated test code Signed-off-by: Doug Hoard --- .../client/exporter/HTTPServer.java | 10 ++- .../client/exporter/TestHTTPServer.java | 73 +++++++++++++------ 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index 2086f572f..3a2768615 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -83,7 +83,6 @@ public static class HTTPMetricHandler implements HttpHandler { @Override public void handle(HttpExchange t) throws IOException { String query = t.getRequestURI().getRawQuery(); - String contextPath = t.getHttpContext().getPath(); ByteArrayOutputStream response = this.response.get(); response.reset(); @@ -114,9 +113,12 @@ public void handle(HttpExchange t) throws IOException { os.close(); } } else { - t.getResponseHeaders().set("Content-Length", - String.valueOf(response.size())); - t.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.size()); + long contentLength = response.size(); + t.getResponseHeaders().set("Content-Length", String.valueOf(contentLength)); + if (t.getRequestMethod().equals("HEAD")) { + contentLength = -1; + } + t.sendResponseHeaders(HttpURLConnection.HTTP_OK, contentLength); response.writeTo(t.getResponseBody()); } t.close(); diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index f0dfe874a..164cbfca9 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -7,6 +7,7 @@ import io.prometheus.client.CollectorRegistry; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.net.URLConnection; @@ -34,24 +35,29 @@ public void init() throws IOException { Gauge.build("c", "a help").register(registry); } - String request(HTTPServer s, String context, String suffix) throws IOException { + Response request(String requestMethod, HTTPServer s, String context, String suffix) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); + ((HttpURLConnection)connection).setRequestMethod(requestMethod); connection.setDoOutput(true); connection.connect(); Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return scanner.hasNext() ? scanner.next() : ""; + return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); } - String request(HTTPServer s, String suffix) throws IOException { + Response request(HTTPServer s, String context, String suffix) throws IOException { + return request("GET", s, context, suffix); + } + + Response request(HTTPServer s, String suffix) throws IOException { return request(s, "/metrics", suffix); } - String requestWithCompression(HTTPServer s, String suffix) throws IOException { + Response requestWithCompression(HTTPServer s, String suffix) throws IOException { return requestWithCompression(s, "/metrics", suffix); } - String requestWithCompression(HTTPServer s, String context, String suffix) throws IOException { + Response requestWithCompression(HTTPServer s, String context, String suffix) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); @@ -60,20 +66,20 @@ String requestWithCompression(HTTPServer s, String context, String suffix) throw connection.connect(); GZIPInputStream gzs = new GZIPInputStream(connection.getInputStream()); Scanner scanner = new Scanner(gzs).useDelimiter("\\A"); - return scanner.hasNext() ? scanner.next() : ""; + return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); } - String requestWithAccept(HTTPServer s, String accept) throws IOException { + Response requestWithAccept(HTTPServer s, String accept) throws IOException { String url = "http://localhost:" + s.server.getAddress().getPort(); URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Accept", accept); Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return scanner.hasNext() ? scanner.next() : ""; + return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); } - String requestWithCredentials(HTTPServer httpServer, String context, String suffix, String user, String password) throws IOException { + Response requestWithCredentials(HTTPServer httpServer, String context, String suffix, String user, String password) throws IOException { String url = "http://localhost:" + httpServer.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); @@ -82,7 +88,7 @@ String requestWithCredentials(HTTPServer httpServer, String context, String suff } connection.connect(); Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; + return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); } String encodeCredentials(String user, String password) { @@ -117,7 +123,7 @@ public void testRefuseUsingUnbound() throws IOException { public void testSimpleRequest() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, ""); + String response = request(s, "").body; assertThat(response).contains("a 0.0"); assertThat(response).contains("b 0.0"); assertThat(response).contains("c 0.0"); @@ -130,7 +136,7 @@ public void testSimpleRequest() throws IOException { public void testBadParams() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, "?x"); + String response = request(s, "?x").body; assertThat(response).contains("a 0.0"); assertThat(response).contains("b 0.0"); assertThat(response).contains("c 0.0"); @@ -143,7 +149,7 @@ public void testBadParams() throws IOException { public void testSingleName() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, "?name[]=a"); + String response = request(s, "?name[]=a").body; assertThat(response).contains("a 0.0"); assertThat(response).doesNotContain("b 0.0"); assertThat(response).doesNotContain("c 0.0"); @@ -156,7 +162,7 @@ public void testSingleName() throws IOException { public void testMultiName() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, "?name[]=a&name[]=b"); + String response = request(s, "?name[]=a&name[]=b").body; assertThat(response).contains("a 0.0"); assertThat(response).contains("b 0.0"); assertThat(response).doesNotContain("c 0.0"); @@ -174,7 +180,7 @@ public void testSampleNameFilter() throws IOException { .build()) .build(); try { - String response = request(s, "?name[]=a&name[]=b"); + String response = request(s, "?name[]=a&name[]=b").body; assertThat(response).doesNotContain("a 0.0"); assertThat(response).contains("b 0.0"); assertThat(response).doesNotContain("c 0.0"); @@ -187,7 +193,7 @@ public void testSampleNameFilter() throws IOException { public void testDecoding() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, "?n%61me[]=%61"); + String response = request(s, "?n%61me[]=%61").body; assertThat(response).contains("a 0.0"); assertThat(response).doesNotContain("b 0.0"); assertThat(response).doesNotContain("c 0.0"); @@ -200,7 +206,7 @@ public void testDecoding() throws IOException { public void testGzipCompression() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = requestWithCompression(s, ""); + String response = requestWithCompression(s, "").body; assertThat(response).contains("a 0.0"); assertThat(response).contains("b 0.0"); assertThat(response).contains("c 0.0"); @@ -213,7 +219,7 @@ public void testGzipCompression() throws IOException { public void testOpenMetrics() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = requestWithAccept(s, "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"); + String response = requestWithAccept(s, "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1").body; assertThat(response).contains("# EOF"); } finally { s.close(); @@ -224,7 +230,7 @@ public void testOpenMetrics() throws IOException { public void testHealth() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = request(s, "/-/healthy", ""); + String response = request(s, "/-/healthy", "").body; assertThat(response).contains("Exporter is Healthy"); } finally { s.close(); @@ -235,7 +241,7 @@ public void testHealth() throws IOException { public void testHealthGzipCompression() throws IOException { HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); try { - String response = requestWithCompression(s, "/-/healthy", ""); + String response = requestWithCompression(s, "/-/healthy", "").body; assertThat(response).contains("Exporter is Healthy"); } finally { s.close(); @@ -249,7 +255,7 @@ public void testBasicAuthSuccess() throws IOException { .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); try { - String response = requestWithCredentials(s, "/metrics","?name[]=a&name[]=b", "user", "secret"); + String response = requestWithCredentials(s, "/metrics","?name[]=a&name[]=b", "user", "secret").body; assertThat(response).contains("a 0.0"); } finally { s.close(); @@ -287,4 +293,29 @@ public void testBasicAuthWrongCredentials() throws IOException { s.close(); } } + + @Test + public void testHEADRequest() throws IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .build(); + try { + Response response = request("HEAD", s, "/metrics", "?name[]=a&name[]=b"); + Assert.assertTrue(response.contentLength == 74); + Assert.assertTrue("".equals(response.body)); + } finally { + s.close(); + } + } + + class Response { + + public long contentLength; + public String body; + + public Response(long contentLength, String body) { + this.contentLength = contentLength; + this.body = body; + } + } } From 7a29af04821cd51592c45ce4682c3132372f4c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 Sep 2021 10:12:28 +0200 Subject: [PATCH 097/980] Add Java 17 compatibility test --- .../test/java/io/prometheus/client/smoketest/JavaVersionsIT.java | 1 + 1 file changed, 1 insertion(+) diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java index b9d3da3f5..ee8701186 100644 --- a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java +++ b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java @@ -39,6 +39,7 @@ public static String[] images() { // HotSpot "openjdk:8-jre", "openjdk:11-jre", + "openjdk:17", "ticketfly/java:6", "adoptopenjdk/openjdk16:ubi-minimal-jre", From 3ff7064bd9d474a924d68530249ec72b7c47ded5 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 10 Oct 2021 15:42:12 -0400 Subject: [PATCH 098/980] Changed adoptopenjdk/openjdk11-openj9 to adoptopenjdk/openjdk11-openj9:alpine (#709) Signed-off-by: Doug Hoard --- .../java/io/prometheus/client/smoketest/JavaVersionsIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java index ee8701186..51acb677e 100644 --- a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java +++ b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java @@ -45,7 +45,7 @@ public static String[] images() { // OpenJ9 "ibmjava:8-jre", - "adoptopenjdk/openjdk11-openj9", + "adoptopenjdk/openjdk11-openj9:alpine", }; } From f2536bf2383f2e1393310ab51c25cdcabdfead13 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 24 Oct 2021 06:29:51 -0400 Subject: [PATCH 099/980] Added azul/zulu-openjdk:6 for integration tests (#711) Signed-off-by: Doug Hoard --- .../test/java/io/prometheus/client/smoketest/JavaVersionsIT.java | 1 + 1 file changed, 1 insertion(+) diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java index 51acb677e..2d67ecb8c 100644 --- a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java +++ b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java @@ -42,6 +42,7 @@ public static String[] images() { "openjdk:17", "ticketfly/java:6", "adoptopenjdk/openjdk16:ubi-minimal-jre", + "azul/zulu-openjdk:6", // OpenJ9 "ibmjava:8-jre", From cfecd0d267cbf3ab2b505533897ed32c1284bc8b Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 9 Nov 2021 00:01:36 +0000 Subject: [PATCH 100/980] Update common Prometheus files Signed-off-by: prombot --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a49761689..ceede17f8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,4 +17,4 @@ jobs: - ~/.m2 key: maven-dependencies-{{ checksum "pom.xml" }} orbs: - prometheus: prometheus/prometheus@0.11.0 + prometheus: prometheus/prometheus@0.14.0 From 48c18e5f189b8950111a7c2e0ada7f03fbfb68ad Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Mon, 29 Nov 2021 15:30:35 -0500 Subject: [PATCH 101/980] Make HTTPMetricHandler constructors public (#722) Signed-off-by: Doug Hoard --- .../client/exporter/HTTPServer.java | 4 +-- .../client/exporter/TestHTTPServer.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index 3a2768615..b3badf470 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -71,11 +71,11 @@ public static class HTTPMetricHandler implements HttpHandler { private final Supplier> sampleNameFilterSupplier; private final static String HEALTHY_RESPONSE = "Exporter is Healthy."; - HTTPMetricHandler(CollectorRegistry registry) { + public HTTPMetricHandler(CollectorRegistry registry) { this(registry, null); } - HTTPMetricHandler(CollectorRegistry registry, Supplier> sampleNameFilterSupplier) { + public HTTPMetricHandler(CollectorRegistry registry, Supplier> sampleNameFilterSupplier) { this.registry = registry; this.sampleNameFilterSupplier = sampleNameFilterSupplier; } diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index 164cbfca9..7945a997d 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -91,6 +91,15 @@ Response requestWithCredentials(HTTPServer httpServer, String context, String su return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); } + Response request(HttpServer httpServer, String context, String suffix) throws IOException { + String url = "http://localhost:" + httpServer.getAddress().getPort() + context + suffix; + URLConnection connection = new URL(url).openConnection(); + connection.setDoOutput(true); + connection.connect(); + Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); + return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); + } + String encodeCredentials(String user, String password) { // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, try { @@ -308,6 +317,23 @@ public void testHEADRequest() throws IOException { } } + @Test + public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOException { + InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 0); + HttpServer httpServer = HttpServer.create(inetSocketAddress, 0); + httpServer.createContext("/metrics", new HTTPServer.HTTPMetricHandler(registry)); + httpServer.start(); + + try { + String response = request(httpServer, "/metrics", null).body; + assertThat(response).contains("a 0.0"); + assertThat(response).contains("b 0.0"); + assertThat(response).contains("c 0.0"); + } finally { + httpServer.stop(0); + } + } + class Response { public long contentLength; From 65ca8bd19382c4f35f7f8d10e2cc462faf3adf3c Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 5 Dec 2021 18:05:20 -0500 Subject: [PATCH 102/980] Refactored code to delegate Base64 encoding to either java.util.Base64 or javax.xml.bind.DatatypeConverter depending on the running JVM version. (#698) Signed-off-by: Doug Hoard --- simpleclient_pushgateway/pom.xml | 1 + .../io/prometheus/client/exporter/Base64.java | 48 +++++++++++++++++++ .../BasicAuthHttpConnectionFactory.java | 3 +- .../client/exporter/PushGateway.java | 4 +- 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 0f126991b..d3d8d4d25 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -48,6 +48,7 @@ javax.xml.bind jaxb-api 2.3.0 + provided diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java new file mode 100644 index 000000000..b2cbb88c7 --- /dev/null +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java @@ -0,0 +1,48 @@ +package io.prometheus.client.exporter; + +import javax.xml.bind.DatatypeConverter; + +/** + * This class delegates to either javax.xml.bind.DatatypeConverter (for Java < 8) or java.util.Base64 (Java 8+) + * to perform Base64 encoding of a String. + * + * This code requires Java 8+ for compilation. + */ +public class Base64 { + + private static final boolean HAS_JAVA_UTIL_BASE64 = hasJavaUtilBase64(); + + private static boolean hasJavaUtilBase64() { + try { + Class.forName("java.util.Base64"); + // Java 8+ + return true; + } catch (Throwable t) { + // Java < 8 + return false; + } + } + + private Base64() {} + + /** + * Encodes a byte[] to a String using Base64. + * + * Passing a null argument will cause a NullPointerException to be thrown. + * + * @param src + * @return String in Base64 encoding + */ + @SuppressWarnings("all") + public static String encodeToString(byte[] src) { + if (src == null) { + throw new NullPointerException(); + } + + if (HAS_JAVA_UTIL_BASE64) { + return java.util.Base64.getEncoder().encodeToString(src); + } else { + return DatatypeConverter.printBase64Binary(src); + } + } +} diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java index e903896c8..ead505b1f 100644 --- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; -import javax.xml.bind.DatatypeConverter; public class BasicAuthHttpConnectionFactory implements HttpConnectionFactory { private final HttpConnectionFactory originConnectionFactory; @@ -28,7 +27,7 @@ public HttpURLConnection create(String url) throws IOException { private String encode(String user, String password) { try { byte[] credentialsBytes = (user + ":" + password).getBytes("UTF-8"); - String encoded = DatatypeConverter.printBase64Binary(credentialsBytes); + String encoded = Base64.encodeToString(credentialsBytes); return String.format("Basic %s", encoded); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java index 88857fa84..1ab56b6a6 100644 --- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java @@ -13,10 +13,8 @@ import java.net.URL; import java.net.URLEncoder; import java.net.UnknownHostException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; -import javax.xml.bind.DatatypeConverter; import io.prometheus.client.Collector; import io.prometheus.client.CollectorRegistry; @@ -272,7 +270,7 @@ void doRequest(CollectorRegistry registry, String job, Map group private static String base64url(String v) { // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, try { - return DatatypeConverter.printBase64Binary(v.getBytes("UTF-8")).replace("+", "-").replace("/", "_"); + return Base64.encodeToString(v.getBytes("UTF-8")).replace("+", "-").replace("/", "_"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // Unreachable. } From 8456b73a0a9238b8d7c35f72e2d9ae4baea81027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 8 Dec 2021 17:23:37 +0100 Subject: [PATCH 103/980] Refactor integration tests; Add PushGateway test --- OTEL_EXEMPLARS.md | 6 +- .../it/exemplars_otel/ExemplarsOtelIT.java | 103 ------------- .../src/test/resources/Dockerfile | 5 - .../src/test/resources/Dockerfile | 10 -- .../{java_versions => it_common}/pom.xml | 30 ++-- .../client/it/common/Downloader.java | 37 +++++ .../client/it/common/LogConsumer.java | 36 +++++ .../prometheus/client/it/common/Scraper.java | 61 ++++++++ .../prometheus/client/it/common/Version.java | 16 ++ .../prometheus/client/it/common/Volume.java | 100 +++++++++++++ .../test/resources/project_version.properties | 2 + .../pom.xml | 33 ++--- .../ExampleSpringBootApp.java} | 24 ++- .../src/main/resources/application.properties | 0 .../ExemplarsOpenTelemetryAgentIT.java} | 95 +++++++----- .../src/test/resources/logback-test.xml | 0 .../pom.xml | 33 ++--- .../exemplars_otel/ExampleApplication.java} | 5 +- .../ExemplarsOpenTelemetrySdkIT.java | 140 ++++++++++++++++++ .../src/test/resources/logback-test.xml | 0 .../pom.xml | 45 +++++- .../it/java_versions/ExampleApplication.java} | 4 +- .../it/java_versions/JavaVersionsIT.java | 87 +++++++++++ .../src/test/resources/logback-test.xml | 0 integration_tests/it_pushgateway/pom.xml | 98 ++++++++++++ .../it/pushgateway/ExampleBatchJob.java | 36 +++++ .../client/it/pushgateway/PushGatewayIT.java | 97 ++++++++++++ .../src/test/resources/logback-test.xml | 0 .../src/test/resources/web-config.yml | 5 + .../pom.xml | 20 +-- .../it/servlet/jakarta/ExampleServlet.java | 0 .../src/main/webapp/WEB-INF/web.xml | 0 .../ServletJakartaExporterWebXmlIT.java | 2 +- .../src/test/resources/Dockerfile | 0 .../src/test/resources/logback-test.xml | 14 ++ .../client/smoketest/JavaVersionsIT.java | 116 --------------- integration_tests/pom.xml | 33 ++++- 37 files changed, 926 insertions(+), 367 deletions(-) delete mode 100644 integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java delete mode 100644 integration_tests/exemplars_otel/src/test/resources/Dockerfile delete mode 100644 integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile rename integration_tests/{java_versions => it_common}/pom.xml (69%) create mode 100644 integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java create mode 100644 integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java create mode 100644 integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java create mode 100644 integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java create mode 100644 integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java create mode 100644 integration_tests/it_common/src/test/resources/project_version.properties rename integration_tests/{exemplars_otel_agent => it_exemplars_otel_agent}/pom.xml (81%) rename integration_tests/{exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java => it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java} (81%) rename integration_tests/{exemplars_otel_agent => it_exemplars_otel_agent}/src/main/resources/application.properties (100%) rename integration_tests/{exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java => it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java} (77%) rename integration_tests/{exemplars_otel => it_exemplars_otel_agent}/src/test/resources/logback-test.xml (100%) rename integration_tests/{exemplars_otel => it_exemplars_otel_sdk}/pom.xml (80%) rename integration_tests/{exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java => it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java} (96%) create mode 100644 integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java rename integration_tests/{exemplars_otel_agent => it_exemplars_otel_sdk}/src/test/resources/logback-test.xml (100%) rename integration_tests/{example_application => it_java_versions}/pom.xml (55%) rename integration_tests/{example_application/src/main/java/io/prometheus/client/smoketest/Server.java => it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java} (88%) create mode 100644 integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java rename integration_tests/{java_versions => it_java_versions}/src/test/resources/logback-test.xml (100%) create mode 100644 integration_tests/it_pushgateway/pom.xml create mode 100644 integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java create mode 100644 integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java rename integration_tests/{servlet_jakarta_exporter_webxml => it_pushgateway}/src/test/resources/logback-test.xml (100%) create mode 100644 integration_tests/it_pushgateway/src/test/resources/web-config.yml rename integration_tests/{servlet_jakarta_exporter_webxml => it_servlet_jakarta_exporter_webxml}/pom.xml (84%) rename integration_tests/{servlet_jakarta_exporter_webxml => it_servlet_jakarta_exporter_webxml}/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java (100%) rename integration_tests/{servlet_jakarta_exporter_webxml => it_servlet_jakarta_exporter_webxml}/src/main/webapp/WEB-INF/web.xml (100%) rename integration_tests/{servlet_jakarta_exporter_webxml => it_servlet_jakarta_exporter_webxml}/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java (98%) rename integration_tests/{servlet_jakarta_exporter_webxml => it_servlet_jakarta_exporter_webxml}/src/test/resources/Dockerfile (100%) create mode 100644 integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml delete mode 100644 integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java diff --git a/OTEL_EXEMPLARS.md b/OTEL_EXEMPLARS.md index 487866362..ea7377251 100644 --- a/OTEL_EXEMPLARS.md +++ b/OTEL_EXEMPLARS.md @@ -8,9 +8,9 @@ If you want to see this in action, you can run the example from the `ExemplarsCl ``` ./mvnw package -cd integration_tests/exemplars_otel_agent/target/ +cd integration_tests/it_exemplars_otel_agent/target/ curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.2.0/opentelemetry-javaagent-all.jar -java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent-all.jar -jar ./sample-rest-application.jar +java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent-all.jar -jar ./example-spring-boot-app.jar ``` Now you have a Spring REST service running on [http://localhost:8080/hello](http://localhost:8080/hello) that is instrumented with the OpenTelemetry Java agent. @@ -55,7 +55,7 @@ you can exclude the corresponding dependencies in your `pom.xml`: simpleclient 0.12.0 - + io.prometheus simpleclient_tracer_otel diff --git a/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java b/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java deleted file mode 100644 index 3a34445e5..000000000 --- a/integration_tests/exemplars_otel/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOtelIT.java +++ /dev/null @@ -1,103 +0,0 @@ -package io.prometheus.client.it.exemplars_otel; - -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.junit.Assert; -import org.junit.Test; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.images.builder.ImageFromDockerfile; - -import java.io.IOException; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; - -/** - * This is just a smoke test, as completeness is already tested with exemplars_otel_agent - */ -public class ExemplarsOtelIT { - - private final String cmd = "java -cp \"/app/exemplars_otel.jar:/app/lib/*\" io.prometheus.client.it.exemplars_otel.Server"; - private final OkHttpClient client = new OkHttpClient(); - - private static class DockerContainer extends GenericContainer { - DockerContainer() { - super(new ImageFromDockerfile("exemplars-otel-test") - .withFileFromPath("exemplars_otel.jar", Paths.get("target/exemplars_otel.jar")) - .withFileFromPath("dependency", Paths.get("target/dependency")) - .withFileFromClasspath("Dockerfile", "Dockerfile")); - } - } - - @Test - public void testGoodCase() throws IOException { - runTest(":", true); - } - - @Test - public void testOtelAgentMissing() throws IOException { - runTest("rm /app/lib/simpleclient_tracer_otel_agent-*", true); - } - - @Test - public void testOtelMissing() throws IOException { - runTest("rm /app/lib/simpleclient_tracer_otel-*", false); - } - - @Test - public void testOtelAllMissing() throws IOException { - runTest("rm /app/lib/simpleclient_tracer_otel*", false); - } - - @Test - public void testTracerCommonMissing() throws IOException { - runTest("rm /app/lib/simpleclient_tracer_common-*", false); - } - - @Test - public void testAllMissing() throws IOException { - runTest("rm /app/lib/simpleclient_tracer*", false); - } - - private void runTest(String rmCmd, boolean exemplarsExpected) throws IOException { - try (DockerContainer container = new DockerContainer() - .withExposedPorts(9000) - .withCommand("/bin/bash", "-c", rmCmd + " ; " + cmd)) { - container.start(); - List metrics = scrapeMetrics(container); - boolean testTotalWithExemplarFound = false; - boolean testTotalWithoutExemplarFound = false; - for (String metric : metrics) { - System.out.println(metric); - if (metric.matches("^test_total 1\\.0 # \\{span_id=\"[0-9a-f]+\",trace_id=\"[0-9a-f]+\"} 1.0 [0-9.]+$")) { - testTotalWithExemplarFound = true; - } - if (metric.matches("^test_total 1\\.0$")) { - testTotalWithoutExemplarFound = true; - } - } - if (exemplarsExpected) { - Assert.assertTrue("test_total metric with exemplars expected", testTotalWithExemplarFound); - Assert.assertFalse("test_total without exemplar should not be there", testTotalWithoutExemplarFound); - } else { - Assert.assertFalse("test_total metric with exemplar should not be there", testTotalWithExemplarFound); - Assert.assertTrue("test_total without exemplar expected", testTotalWithoutExemplarFound); - } - } - } - - private List scrapeMetrics(DockerContainer dockerContainer) throws IOException { - Request request = new Request.Builder() - .url("http://localhost:" + dockerContainer.getMappedPort(9000) + "/metrics") - .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") - .build(); - try (Response response = client.newCall(request).execute()) { - String body = response.body().string(); - System.out.println("body:---"); - System.out.println(body); - System.out.println("---"); - return Arrays.asList(body.split("\\n")); - } - } -} diff --git a/integration_tests/exemplars_otel/src/test/resources/Dockerfile b/integration_tests/exemplars_otel/src/test/resources/Dockerfile deleted file mode 100644 index b15745aab..000000000 --- a/integration_tests/exemplars_otel/src/test/resources/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM openjdk:11-jre -RUN mkdir -p /app/ -COPY dependency /app/lib -COPY exemplars_otel.jar /app/ -CMD java -cp "/app/exemplars_otel.jar:/app/lib/*" io.prometheus.client.it.exemplars_otel.Server \ No newline at end of file diff --git a/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile b/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile deleted file mode 100644 index ec91f5fb0..000000000 --- a/integration_tests/exemplars_otel_agent/src/test/resources/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM openjdk:11-jre -RUN mkdir -p /app/ -ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.2.0/opentelemetry-javaagent-all.jar /app/ -COPY sample-rest-application.jar /app/ -CMD java \ - -Dotel.traces.exporter=logging \ - -Dotel.metrics.exporter=none \ - -javaagent:/app/opentelemetry-javaagent-all.jar \ - -jar \ - /app/sample-rest-application.jar diff --git a/integration_tests/java_versions/pom.xml b/integration_tests/it_common/pom.xml similarity index 69% rename from integration_tests/java_versions/pom.xml rename to integration_tests/it_common/pom.xml index cbeba947f..f475803d1 100644 --- a/integration_tests/java_versions/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -8,8 +8,8 @@ 0.12.1-SNAPSHOT - java_versions - Integration Test - Java Versions Smoke Test + it_common + Integration Tests - Common Utilities @@ -17,21 +17,20 @@ testcontainers test - - ch.qos.logback - logback-classic - 1.2.3 - test - com.squareup.okhttp3 okhttp - 4.9.1 test + + + src/test/resources + true + + org.apache.maven.plugins @@ -43,20 +42,11 @@ org.apache.maven.plugins - maven-failsafe-plugin + maven-jar-plugin - integration-test - integration-test - - integration-test - - - - verify - verify - verify + test-jar diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java new file mode 100644 index 000000000..7c82eb3dc --- /dev/null +++ b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java @@ -0,0 +1,37 @@ +package io.prometheus.client.it.common; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +import java.io.*; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class Downloader { + + /** + * Download a file from an HTTP URL and store it in the target/ directory. + */ + public static void downloadToTarget(String url, String fileName) throws IOException, URISyntaxException { + Path destination = Paths.get(Downloader.class.getResource("/").toURI()).getParent().resolve(fileName); + if (Files.exists(destination)) { + return; // only download once + } + System.out.println("Downloading " + url); + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder().url(url).build(); + Response response = client.newCall(request).execute(); + InputStream responseBody = response.body().byteStream(); + OutputStream output = new FileOutputStream(destination.toFile()); + byte[] data = new byte[1024]; + int count; + while ((count = responseBody.read(data)) != -1) { + output.write(data, 0, count); + } + output.close(); + responseBody.close(); + } +} diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java new file mode 100644 index 000000000..d60e53979 --- /dev/null +++ b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java @@ -0,0 +1,36 @@ +package io.prometheus.client.it.common; + +import org.testcontainers.containers.output.OutputFrame; + +import java.util.function.Consumer; + +/** + * Print Docker logs from TestContainers to stdout or stderr. + */ +public class LogConsumer implements Consumer { + + private final String prefix; + + private LogConsumer(String prefix) { + this.prefix = prefix; + } + + public static LogConsumer withPrefix(String prefix) { + return new LogConsumer(prefix); + } + + @Override + public void accept(OutputFrame outputFrame) { + switch (outputFrame.getType()) { + case STDOUT: + System.out.print(prefix + " - " + outputFrame.getUtf8String()); + break; + case END: + System.out.println(prefix + " - END"); + break; + default: // STDERR or unexpected + System.err.print(prefix + " - " + outputFrame.getUtf8String()); + break; + } + } +} diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java new file mode 100644 index 000000000..fc5bd0613 --- /dev/null +++ b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java @@ -0,0 +1,61 @@ +package io.prometheus.client.it.common; + +import okhttp3.Credentials; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.junit.Assert; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * Scrape metrics via HTTP + */ +public class Scraper { + + /** + * Scrape metrics from url without authentication. + */ + public static List scrape(String url, long timeoutMillis) { + return scrape(url, null, null, timeoutMillis); + } + + /** + * Scrape metrics from url with HTTP basic authentication. + */ + public static List scrape(String url, String user, String password, long timeoutMillis) { + OkHttpClient client = new OkHttpClient(); + long start = System.currentTimeMillis(); + Exception exception = null; + while (System.currentTimeMillis() - start < timeoutMillis) { + try { + Request.Builder requestBuilder = new Request.Builder() + .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") + .url(url); + if (user != null && password != null) { + requestBuilder.header("Authorization", Credentials.basic(user, password)); + } + Request request = requestBuilder.build(); + try (Response response = client.newCall(request).execute()) { + if (response.code() != 200) { + throw new IOException("Received HTTP Status " + response.code() + ": " + response.body().string()); + } + return Arrays.asList(response.body().string().split("\\n")); + } + } catch (Exception e) { + exception = e; + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { + } + } + } + if (exception != null) { + exception.printStackTrace(); + } + Assert.fail("timeout while getting metrics from " + url); + return null; // will not happen + } +} diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java new file mode 100644 index 000000000..2323090e1 --- /dev/null +++ b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java @@ -0,0 +1,16 @@ +package io.prometheus.client.it.common; + +import java.io.IOException; +import java.util.Properties; + +/** + * Utility to get the project version, like 0.12.1-SNAPSHOT + */ +public class Version { + + public static String loadProjectVersion() throws IOException { + Properties properties = new Properties(); + properties.load(Volume.class.getResourceAsStream("/project_version.properties")); + return properties.getProperty("project.version"); + } +} diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java new file mode 100644 index 000000000..24bb0ae3a --- /dev/null +++ b/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java @@ -0,0 +1,100 @@ +package io.prometheus.client.it.common; + +import org.junit.Assert; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.function.Predicate; + +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + +/** + * Temporary directory in ./target/ to be mounted as a volume in Docker containers. + */ +public class Volume { + + private final Path tmpDir; // will be created in the ./target/ directory + + private Volume(Path tmpDir) { + this.tmpDir = tmpDir; + } + + public static Volume create(String prefix) throws IOException, URISyntaxException { + Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent(); + Assert.assertEquals("failed to locate target/ directory", "target", targetDir.getFileName().toString()); + return new Volume(Files.createTempDirectory(targetDir, prefix + "-")); + } + + /** + * Copy a file or directory from ./target/ into the tmpDir + */ + public Volume copyFromTargetDirectory(String name) throws IOException { + Path src = tmpDir.getParent().resolve(name); + if (Files.isRegularFile(src)) { + Files.copy(src, tmpDir.resolve(src.getFileName()), REPLACE_EXISTING); + } else if (Files.isDirectory(src)) { + Path dest = tmpDir.resolve(src.getFileName()); + Files.createDirectories(dest); + Files.walkFileTree(src, new SimpleFileVisitor() { + + // create parent directories + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + Files.createDirectories(dest.resolve(src.relativize(dir))); + return FileVisitResult.CONTINUE; + } + + // copy file + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.copy(file, dest.resolve(src.relativize(file)), REPLACE_EXISTING); + return FileVisitResult.CONTINUE; + } + }); + } else { + Assert.fail(name + ": No such file or directory"); + } + return this; + } + + /** + * Remove files in tmpDir if they match the predicate. + */ + public void rm(Predicate predicate) throws IOException { + Files.walkFileTree(tmpDir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (predicate.test(file)) { + Files.delete(file); + } + return FileVisitResult.CONTINUE; + } + }); + } + + public String getHostPath() { + return tmpDir.toString(); + } + + /** + * Recursively remove tmpDir and its contents. + */ + public void remove() throws IOException { + if (!deleteRecursively(tmpDir.toFile())) { + throw new IOException(tmpDir + ": Failed to remove temporary test directory."); + } + } + + private boolean deleteRecursively(File file) { + File[] allContents = file.listFiles(); + if (allContents != null) { + for (File child : allContents) { + deleteRecursively(child); + } + } + return file.delete(); + } +} diff --git a/integration_tests/it_common/src/test/resources/project_version.properties b/integration_tests/it_common/src/test/resources/project_version.properties new file mode 100644 index 000000000..4eafa7259 --- /dev/null +++ b/integration_tests/it_common/src/test/resources/project_version.properties @@ -0,0 +1,2 @@ +# ${project.version} will be replaced by Maven at built time when this file is copied to the target/ directory. +project.version=${project.version} \ No newline at end of file diff --git a/integration_tests/exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml similarity index 81% rename from integration_tests/exemplars_otel_agent/pom.xml rename to integration_tests/it_exemplars_otel_agent/pom.xml index e1cecf937..6ef3acf5a 100644 --- a/integration_tests/exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -8,8 +8,8 @@ 0.12.1-SNAPSHOT - exemplars_otel_agent - Integration Test - Exemplars with the OpenTelemetry Agent + it_exemplars_otel_agent + Integration Tests - Exemplars with the OpenTelemetry Agent @@ -31,7 +31,7 @@ com.squareup.okhttp3 okhttp - 4.9.1 + compile io.prometheus @@ -56,11 +56,20 @@ ch.qos.logback logback-classic + 1.2.3 + test + + + io.prometheus + it_common + test-jar + ${project.version} + test - sample-rest-application + example-spring-boot-app org.springframework.boot @@ -84,22 +93,6 @@ org.apache.maven.plugins maven-failsafe-plugin - - - integration-test - integration-test - - integration-test - - - - verify - verify - - verify - - - diff --git a/integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java b/integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java similarity index 81% rename from integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java rename to integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java index dc01c4c58..d03d8f79c 100644 --- a/integration_tests/exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/SampleRestApplication.java +++ b/integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java @@ -18,31 +18,44 @@ import java.io.IOException; +/** + * The OpenTelemetry agent supports Spring Boot out-of-the-box. + * We use this Spring Boot example to test whether + * OpenTelemetry Traces created by the OpenTelemetry agent + * will be picked up as Exemplars by the Prometheus client_java library. + */ @SpringBootApplication @RestController -public class SampleRestApplication { +public class ExampleSpringBootApp { private double durationOuterMs = 0.5; private double durationInnerMs = 0.3; private final OkHttpClient client = new OkHttpClient(); + // Counter should have Exemplars when the OpenTelemetry agent is attached. private final Counter requestCounter = Counter.build() .name("requests_total") .help("Total number of requests.") .labelNames("path") .register(); + + // Gauges don't have Exemplars. private final Gauge lastRequestTimestamp = Gauge.build() .name("last_request_timestamp") .help("unix time of the last request") .labelNames("path") .register(); + + // Histogram should have Exemplars when the OpenTelemetry agent is attached. private final Histogram requestDurationHistogram = Histogram.build() .name("request_duration_histogram") .help("Request duration in seconds") .labelNames("path") .buckets(0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009) .register(); + + // Summaries don't have Exemplars private final Summary requestDurationSummary = Summary.build() .name("request_duration_summary") .help("Request duration in seconds") @@ -53,9 +66,13 @@ public class SampleRestApplication { public static void main(String[] args) { DefaultExports.initialize(); - SpringApplication.run(SampleRestApplication.class, args); + SpringApplication.run(ExampleSpringBootApp.class, args); } + /** + * GET /hello will trigger a GET request to /god-of-fire. + * That way, we get a nice distributed trace for the OpenTelemetry agent. + */ @GetMapping("/hello") public String hello() throws IOException { String path = "/hello"; @@ -89,6 +106,9 @@ public String godOfFire() { return "Prometheus"; } + /** + * Expose Prometheus metrics. + */ @Bean public ServletRegistrationBean metricsServlet() { ServletRegistrationBean bean = new ServletRegistrationBean<>(new MetricsServlet(), "/metrics"); diff --git a/integration_tests/exemplars_otel_agent/src/main/resources/application.properties b/integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties similarity index 100% rename from integration_tests/exemplars_otel_agent/src/main/resources/application.properties rename to integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties diff --git a/integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java similarity index 77% rename from integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java rename to integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java index 24b41171c..094f04fb6 100644 --- a/integration_tests/exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsClientJavaIT.java +++ b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java @@ -1,53 +1,83 @@ package io.prometheus.client.it.exemplars_otel_agent; +import io.prometheus.client.it.common.*; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import org.junit.After; import org.junit.Assert; -import org.junit.Rule; +import org.junit.Before; import org.junit.Test; +import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.images.builder.ImageFromDockerfile; import java.io.IOException; -import java.nio.file.Paths; -import java.util.Arrays; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class ExemplarsClientJavaIT { +/** + * Test if traces from the OpenTelemetry agent are picked up as Exemplars. + */ +public class ExemplarsOpenTelemetryAgentIT { - private final OkHttpClient client = new OkHttpClient(); + private final String image = "openjdk:11-jre"; + private final String otelAgentVersion = "1.2.0"; + private final Volume volume; + private final GenericContainer javaContainer; - private static class DockerContainer extends GenericContainer { - DockerContainer() { - super(new ImageFromDockerfile("exemplars-otel-agent-test") - .withFileFromPath("sample-rest-application.jar", Paths.get("target/sample-rest-application.jar")) - .withFileFromClasspath("Dockerfile", "Dockerfile")); - } + public ExemplarsOpenTelemetryAgentIT() throws IOException, URISyntaxException { + String appJar = "example-spring-boot-app.jar"; + String agentJar = "opentelemetry-javaagent-all.jar"; + String agentDownloadUrl = "https://github.com/open-telemetry/opentelemetry-java-instrumentation/" + + "releases/download/v" + otelAgentVersion + "/" + agentJar; + Downloader.downloadToTarget(agentDownloadUrl, agentJar); + this.volume = Volume.create("exemplars-otel-agent-test") + .copyFromTargetDirectory(appJar) + .copyFromTargetDirectory(agentJar); + String[] cmd = new String[] { + "java", + "-Dotel.traces.exporter=logging", + "-Dotel.metrics.exporter=none", + "-javaagent:/app/" + agentJar, + "-jar", + "/app/" + appJar + }; + System.out.println("Volume directory: " + volume.getHostPath()); + System.out.println("Command: " + String.join(" ", cmd)); + System.out.println("Docker image: " + image); + javaContainer = new GenericContainer<>(image) + .withFileSystemBind(volume.getHostPath(), "/app", BindMode.READ_ONLY) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(image)) + .withExposedPorts(8080) + .withCommand(cmd); + } + + @Before + public void setUp() { + javaContainer.start(); } - @Rule - public DockerContainer dockerContainer = new DockerContainer() - .withExposedPorts(8080) - .waitingFor(Wait.forLogMessage(".* Started .*", 1)); + @After + public void tearDown() throws IOException { + javaContainer.stop(); + volume.remove(); + } @Test - public void testExemplars() throws IOException { - Request request = new Request.Builder() - .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/hello") - .build(); + public void testExemplars() throws IOException, URISyntaxException { + String metricsUrl = "http://localhost:" + javaContainer.getMappedPort(8080) + "/metrics"; // --------------------------------------------------- // first request // --------------------------------------------------- - execute(request); - List metrics = scrapeMetrics(); + callHelloWorldEndpoint(); + List metrics = Scraper.scrape(metricsUrl, 10_000); SpanContext outer = getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/hello", "le", "0.001"); SpanContext inner = getSpanContext(metrics, "request_duration_histogram_bucket", "path", "/god-of-fire", "le", "0.001"); Assert.assertEquals(outer.traceId, inner.traceId); @@ -91,9 +121,9 @@ public void testExemplars() throws IOException { // --------------------------------------------------- for (int i=0; i<10; i++) { - execute(request); + callHelloWorldEndpoint(); } - metrics = scrapeMetrics(); + metrics = Scraper.scrape(metricsUrl, 10_000); Map outers = new HashMap<>(); Map inners = new HashMap<>(); for (String bucket : new String[]{"0.001", "0.002", "0.003", "0.004", "0.005", "0.006", "0.007", "0.008", "0.009", "+Inf"}) { @@ -171,7 +201,10 @@ private void assertNoExemplar(List responseBody, String metricName, Stri Assert.fail(prefix + " metric not found"); } - private void execute(Request request) throws IOException { + private void callHelloWorldEndpoint() throws IOException { + String helloUrl = "http://localhost:" + javaContainer.getMappedPort(8080) + "/hello"; + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder().url(helloUrl).build(); try (Response response = client.newCall(request).execute()) { Assert.assertEquals("Hello, Prometheus!\n", response.body().string()); } @@ -187,16 +220,6 @@ private SpanContext(String spanId, String traceId) { } } - private List scrapeMetrics() throws IOException { - Request request = new Request.Builder() - .url("http://localhost:" + dockerContainer.getMappedPort(8080) + "/metrics") - .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") - .build(); - try (Response response = client.newCall(request).execute()) { - return Arrays.asList(response.body().string().split("\\n")); - } - } - private SpanContext getSpanContext(List responseBody, String metricName, String... labels) { String prefix = makeFullMetricName(metricName, labels); Pattern pattern = Pattern.compile(".*span_id=\"([0-9a-f]+)\",trace_id=\"([0-9a-f]+).*"); diff --git a/integration_tests/exemplars_otel/src/test/resources/logback-test.xml b/integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/exemplars_otel/src/test/resources/logback-test.xml rename to integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml diff --git a/integration_tests/exemplars_otel/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml similarity index 80% rename from integration_tests/exemplars_otel/pom.xml rename to integration_tests/it_exemplars_otel_sdk/pom.xml index dfea6ebf6..9407528a2 100644 --- a/integration_tests/exemplars_otel/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -8,8 +8,8 @@ 0.12.1-SNAPSHOT - exemplars_otel - Integration Test - Exemplars with OpenTelemetry + it_exemplars_otel_sdk + Integration Tests - Exemplars with OpenTelemetry 1.2.0 @@ -36,10 +36,17 @@ simpleclient_httpserver ${project.version} + + io.prometheus + it_common + test-jar + ${project.version} + test + com.squareup.okhttp3 okhttp - 4.9.1 + test org.testcontainers @@ -49,12 +56,12 @@ ch.qos.logback logback-classic - 1.1.2 + test - ${project.artifactId} + example-open-telemetry-app org.apache.maven.plugins @@ -67,22 +74,6 @@ org.apache.maven.plugins maven-failsafe-plugin - - - integration-test - integration-test - - integration-test - - - - verify - verify - - verify - - - org.apache.maven.plugins diff --git a/integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java b/integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java similarity index 96% rename from integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java rename to integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java index c6329a97d..290ac2625 100644 --- a/integration_tests/exemplars_otel/src/main/java/io/prometheus/client/it/exemplars_otel/Server.java +++ b/integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java @@ -8,7 +8,10 @@ import java.io.IOException; -public class Server { +/** + * Example application using the OpenTelemetry SDK. + */ +public class ExampleApplication { public static void main(String[] args) throws IOException, InterruptedException { Counter counter = Counter.build() diff --git a/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java b/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java new file mode 100644 index 000000000..3f2f89b76 --- /dev/null +++ b/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java @@ -0,0 +1,140 @@ +package io.prometheus.client.it.exemplars_otel; + +import io.prometheus.client.it.common.LogConsumer; +import io.prometheus.client.it.common.Scraper; +import io.prometheus.client.it.common.Volume; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; + +/** + * Test if traces from the OpenTelemetry SDK are picked up as Exemplars. + *

+ * In addition, we make sure that missing OpenTelemetry dependencies do not cause client_java to crash the application. + **/ +public class ExemplarsOpenTelemetrySdkIT { + + private Volume volume; + private GenericContainer javaContainer; + + private final String appJar = "example-open-telemetry-app.jar"; + private final String image = "openjdk:11-jre"; + private final String[] cmd = new String[] {"java", "-cp", appJar + ":dependency/*", ExampleApplication.class.getName()}; + + @Before + public void setUp() throws IOException, URISyntaxException { + volume = Volume.create("exemplars-otel-sdk-test") + .copyFromTargetDirectory(appJar) + .copyFromTargetDirectory("dependency"); + javaContainer = new GenericContainer<>(image) + .withFileSystemBind(volume.getHostPath(), "/app", BindMode.READ_ONLY) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(image)) + .withExposedPorts(9000) + .withCommand(cmd); + System.out.println("Java image: " + image); + System.out.println("Temp dir: " + volume.getHostPath()); + System.out.println("cmd: " + String.join(" ", cmd)); + } + + @After + public void tearDown() throws IOException { + javaContainer.stop(); + volume.remove(); + } + + public void removeDependency(String prefix) throws IOException, URISyntaxException { + volume.rm(path -> path.getFileName().toString().startsWith(prefix)); + } + + /** + * All dependencies present -> Exemplars should be found. + */ + @Test + public void testGoodCase() throws IOException { + startContainerAndValidateMetrics(true); + } + + /** + * The dependency simpleclient_tracer_otel_agent is for getting the trace context from the OpenTelemetry Java agent. + * As we are getting the trace context from the OpenTelemetry SDK and not from the agent, Exemplars should work. + *

+ * We test this because if a user excludes simpleclient_tracer_otel_agent from the transitive dependencies for some reason + * we don't want client_java to break. + */ + @Test + public void testOtelAgentMissing() throws IOException, URISyntaxException { + removeDependency("simpleclient_tracer_otel_agent-"); + startContainerAndValidateMetrics(true); + } + + /** + * The dependency simpleclient_tracer_otel is for getting the trace context from the OpenTelemetry SDK. + * If this dependency is missing, Exemplars will be missing, but metrics should still work. + *

+ * We test this because users may exclude simpleclient_tracer_otel as a way to disable OpenTelemetry Exemplars. + */ + @Test + public void testOtelSdkMissing() throws IOException, URISyntaxException { + removeDependency("simpleclient_tracer_otel-"); + startContainerAndValidateMetrics(false); + } + + /** + * This will remove both, simpleclient_tracer_otel_agent and simpleclient_tracer_otel. + * The expected result is that Exemplars are missing, but metrics still work. + */ + @Test + public void testOtelAllMissing() throws IOException, URISyntaxException { + removeDependency("simpleclient_tracer_otel"); + startContainerAndValidateMetrics(false); + } + + /** + * Without simpleclient_tracer_common, Exemplars will be missing but metrics should still work. + */ + @Test + public void testTracerCommonMissing() throws IOException, URISyntaxException { + removeDependency("simpleclient_tracer_common-"); + startContainerAndValidateMetrics(false); + } + + /** + * If a user excludes all simpleclient_tracer dependencies, Exemplars will be missing but metrics should still work. + */ + @Test + public void testAllMissing() throws IOException, URISyntaxException { + removeDependency("simpleclient_tracer"); + startContainerAndValidateMetrics(false); + } + + private void startContainerAndValidateMetrics(boolean exemplarsExpected) throws IOException { + javaContainer.start(); + List metrics = Scraper.scrape("http://localhost:" + javaContainer.getMappedPort(9000) + "/metrics", 10_000); + boolean testTotalWithExemplarFound = false; + boolean testTotalWithoutExemplarFound = false; + for (String metric : metrics) { + System.out.println(metric); + if (metric.matches("^test_total 1\\.0 # \\{span_id=\"[0-9a-f]+\",trace_id=\"[0-9a-f]+\"} 1.0 [0-9.]+$")) { + testTotalWithExemplarFound = true; + } + if (metric.matches("^test_total 1\\.0$")) { + testTotalWithoutExemplarFound = true; + } + } + if (exemplarsExpected) { + Assert.assertTrue("test_total metric with exemplars expected", testTotalWithExemplarFound); + Assert.assertFalse("test_total without exemplar should not be there", testTotalWithoutExemplarFound); + } else { + Assert.assertFalse("test_total metric with exemplar should not be there", testTotalWithExemplarFound); + Assert.assertTrue("test_total without exemplar expected", testTotalWithoutExemplarFound); + } + } +} diff --git a/integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml b/integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/exemplars_otel_agent/src/test/resources/logback-test.xml rename to integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml diff --git a/integration_tests/example_application/pom.xml b/integration_tests/it_java_versions/pom.xml similarity index 55% rename from integration_tests/example_application/pom.xml rename to integration_tests/it_java_versions/pom.xml index ea92e06d5..6a26e6505 100644 --- a/integration_tests/example_application/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -8,8 +8,8 @@ 0.12.1-SNAPSHOT - example_application - Integration Test - Example Application + it_java_versions + Integration Tests - Java Versions @@ -27,10 +27,31 @@ simpleclient_httpserver ${project.version} + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + test + + + io.prometheus + it_common + test-jar + ${project.version} + test + + + com.squareup.okhttp3 + okhttp + test + - ${project.artifactId} org.apache.maven.plugins @@ -44,13 +65,29 @@ - io.prometheus.client.smoketest.Server + io.prometheus.client.it.java_versions.ExampleApplication + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + diff --git a/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java b/integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java similarity index 88% rename from integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java rename to integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java index 1a5f481f0..395cfb04f 100644 --- a/integration_tests/example_application/src/main/java/io/prometheus/client/smoketest/Server.java +++ b/integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java @@ -1,4 +1,4 @@ -package io.prometheus.client.smoketest; +package io.prometheus.client.it.java_versions; import io.prometheus.client.Counter; import io.prometheus.client.exporter.HTTPServer; @@ -9,7 +9,7 @@ /** * Simple example application that compiles with Java 6. */ -public class Server { +public class ExampleApplication { public static void main(String[] args) throws IOException, InterruptedException { DefaultExports.initialize(); diff --git a/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java b/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java new file mode 100644 index 000000000..bba186947 --- /dev/null +++ b/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java @@ -0,0 +1,87 @@ +package io.prometheus.client.it.java_versions; + +import io.prometheus.client.it.common.LogConsumer; +import io.prometheus.client.it.common.Scraper; +import io.prometheus.client.it.common.Version; +import io.prometheus.client.it.common.Volume; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.List; + +/** + * Smoke test with different Java versions. + */ +@RunWith(Parameterized.class) +public class JavaVersionsIT { + + private final Volume exampleApplicationDir; + private final GenericContainer javaContainer; + + @Parameterized.Parameters(name="{0}") + public static String[] images() { + return new String[] { + + // HotSpot + "openjdk:8-jre", + "openjdk:11-jre", + "openjdk:17", + "ticketfly/java:6", + "adoptopenjdk/openjdk16:ubi-minimal-jre", + "azul/zulu-openjdk:6", + + // OpenJ9 + "ibmjava:8-jre", + "adoptopenjdk/openjdk11-openj9:alpine", + }; + } + + public JavaVersionsIT(String image) throws IOException, URISyntaxException { + String exampleApplicationJar = "it_java_versions-" + Version.loadProjectVersion() + ".jar"; + exampleApplicationDir = Volume.create("it-java-versions") + .copyFromTargetDirectory(exampleApplicationJar); + javaContainer = new GenericContainer<>(image) + .withFileSystemBind(exampleApplicationDir.getHostPath(), "/app", BindMode.READ_ONLY) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(image)) + .withExposedPorts(9000) + .withCommand("/bin/sh", "-c", "java -version && java -jar " + exampleApplicationJar); + } + + private final List exampleMetrics = Arrays.asList( + "test_total{path=\"/hello-world\"}", + "jvm_memory_bytes_used{area=\"heap\"}" + ); + + @Before + public void setUp() { + javaContainer.start(); + } + + @After + public void tearDown() throws IOException { + javaContainer.stop(); + exampleApplicationDir.remove(); + } + + @Test + public void testExampleMetrics() { + List metrics = Scraper.scrape("http://localhost:" + javaContainer.getMappedPort(9000) + "/metrics", 10_000); + for (String metric : exampleMetrics) { + Assert.assertTrue(metric + " not found", metrics.stream() + .filter(m -> m.startsWith(metric + " ")) + .peek(System.out::println) + .findAny() + .isPresent()); + } + } +} diff --git a/integration_tests/java_versions/src/test/resources/logback-test.xml b/integration_tests/it_java_versions/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/java_versions/src/test/resources/logback-test.xml rename to integration_tests/it_java_versions/src/test/resources/logback-test.xml diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml new file mode 100644 index 000000000..18bb856f8 --- /dev/null +++ b/integration_tests/it_pushgateway/pom.xml @@ -0,0 +1,98 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.12.1-SNAPSHOT + + + it_pushgateway + Integration Tests - Pushgateway + + + + io.prometheus + simpleclient + ${project.version} + + + io.prometheus + simpleclient_pushgateway + ${project.version} + + + org.testcontainers + testcontainers + test + + + com.squareup.okhttp3 + okhttp + 4.9.1 + test + + + ch.qos.logback + logback-classic + 1.2.0 + test + + + io.prometheus + it_common + test-jar + ${project.version} + test + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.client.it.pushgateway.ExampleBatchJob + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java b/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java new file mode 100644 index 000000000..10ab09368 --- /dev/null +++ b/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java @@ -0,0 +1,36 @@ +package io.prometheus.client.it.pushgateway; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Gauge; +import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory; +import io.prometheus.client.exporter.PushGateway; + +public class ExampleBatchJob { + + // The following is copy-and-paste from README.md + // except that we added basic authentication to test the BasicAuthHttpConnectionFactory with different Java versions. + public static void main(String[] args) throws Exception { + if (args.length != 3) { + System.err.println("Usage: batch-job.jar

"); + System.exit(-1); + } + CollectorRegistry registry = new CollectorRegistry(); + Gauge duration = Gauge.build() + .name("my_batch_job_duration_seconds") + .help("Duration of my batch job in seconds.") + .register(registry); + Gauge.Timer durationTimer = duration.startTimer(); + try { + Gauge lastSuccess = Gauge.build() + .name("my_batch_job_last_success") + .help("Last time my batch job succeeded, in unixtime.") + .register(registry); + lastSuccess.setToCurrentTime(); + } finally { + durationTimer.setDuration(); + PushGateway pg = new PushGateway(args[0]); + pg.setConnectionFactory(new BasicAuthHttpConnectionFactory(args[1], args[2])); + pg.pushAdd(registry, "my_batch_job"); + } + } +} diff --git a/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java b/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java new file mode 100644 index 000000000..7aba0cc19 --- /dev/null +++ b/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java @@ -0,0 +1,97 @@ +package io.prometheus.client.it.pushgateway; + +import io.prometheus.client.it.common.LogConsumer; +import io.prometheus.client.it.common.Scraper; +import io.prometheus.client.it.common.Version; +import io.prometheus.client.it.common.Volume; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.Container; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.containers.output.OutputFrame; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.utility.MountableFile; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; + +@RunWith(Parameterized.class) +public class PushGatewayIT { + + private final String batchJobJar; + private final Volume batchJobDir; + private final GenericContainer javaContainer; + private final GenericContainer pushGatewayContainer; + + @Parameterized.Parameters(name = "{0}") + public static String[] images() { + return new String[] { + "azul/zulu-openjdk:6", + "openjdk:7", + "ibmjava:8-jre", + "openjdk:11-slim", + "openjdk:17" + }; + } + + public PushGatewayIT(String image) throws IOException, URISyntaxException { + batchJobJar = "it_pushgateway-" + Version.loadProjectVersion() + ".jar"; + batchJobDir = Volume.create("it-pushgateway-batch-job") + .copyFromTargetDirectory(batchJobJar); + Network network = Network.newNetwork(); + pushGatewayContainer = new GenericContainer<>("prom/pushgateway") + .withCopyFileToContainer(MountableFile.forClasspathResource("web-config.yml", 0644), "/") + .withNetwork(network) + .withNetworkAliases("pushgateway") + .withLogConsumer(LogConsumer.withPrefix("prom/pushgateway")) + .withCommand("--web.config.file=/web-config.yml") + .withExposedPorts(9091); + javaContainer = new GenericContainer<>(image) + .withFileSystemBind(batchJobDir.getHostPath(), "/app", BindMode.READ_ONLY) + .withNetwork(network) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(image)) + .withCommand("sleep", "30"); + } + + @Before + public void setUp() { + pushGatewayContainer.start(); + javaContainer.start(); + } + + @After + public void tearDown() throws IOException { + javaContainer.stop(); + pushGatewayContainer.stop(); + batchJobDir.remove(); + } + + @Test + public void testPushGateway() throws IOException, InterruptedException { + String user = "testUser"; + String password = "testPwd"; + Container.ExecResult r = javaContainer.execInContainer("java", "-jar", batchJobJar, "pushgateway:9091", user, password); + System.err.println(r.getStderr()); + System.out.println(r.getStdout()); + List metrics = Scraper.scrape("http://localhost:" + pushGatewayContainer.getMappedPort(9091) + "/metrics", user, password, 10_000); + assertContains(metrics, "my_batch_job_duration_seconds"); + assertContains(metrics, "my_batch_job_last_success"); + } + + private void assertContains(List metrics, String metric) { + for (String line : metrics) { + if (line.startsWith(metric + " ") || line.startsWith(metric + "{")) { + return; + } + } + Assert.fail(metric + " not found"); + } +} diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml b/integration_tests/it_pushgateway/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml rename to integration_tests/it_pushgateway/src/test/resources/logback-test.xml diff --git a/integration_tests/it_pushgateway/src/test/resources/web-config.yml b/integration_tests/it_pushgateway/src/test/resources/web-config.yml new file mode 100644 index 000000000..dc39fac85 --- /dev/null +++ b/integration_tests/it_pushgateway/src/test/resources/web-config.yml @@ -0,0 +1,5 @@ +# Usernames and passwords required to connect. +# Passwords are hashed with bcrypt: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md#about-bcrypt. +basic_auth_users: + # testUser: testPwd + testUser: $2y$10$r/SV/hDe3E3ISKsrZIwVJe40vrCo5N8e22WbxDCThMIhaYdUgCBwe \ No newline at end of file diff --git a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml similarity index 84% rename from integration_tests/servlet_jakarta_exporter_webxml/pom.xml rename to integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index e53b175c5..6dd4ac829 100644 --- a/integration_tests/servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -8,8 +8,8 @@ 0.12.1-SNAPSHOT - servlet_jakarta_exporter_webxml - Integration Test - Servlet Jakarta Exporter web.xml + it_servlet_jakarta_exporter_webxml + Integration Tests - Servlet Jakarta Exporter web.xml war @@ -69,22 +69,6 @@ org.apache.maven.plugins maven-failsafe-plugin - - - integration-test - integration-test - - integration-test - - - - verify - verify - - verify - - - org.apache.maven.plugins diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java b/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java similarity index 100% rename from integration_tests/servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java rename to integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from integration_tests/servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml rename to integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java b/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java similarity index 98% rename from integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java rename to integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java index d560ae532..b1fc03589 100644 --- a/integration_tests/servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java @@ -22,7 +22,7 @@ public class ServletJakartaExporterWebXmlIT { private static class DockerContainer extends GenericContainer { DockerContainer() { super(new ImageFromDockerfile("servlet-jakarta-exporter-webxml") - .withFileFromPath("servlet_jakarta_exporter_webxml.war", Paths.get("target/servlet_jakarta_exporter_webxml.war")) + .withFileFromPath("servlet_jakarta_exporter_webxml.war", Paths.get("target/it_servlet_jakarta_exporter_webxml.war")) .withFileFromClasspath("Dockerfile", "Dockerfile")); } } diff --git a/integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile b/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile similarity index 100% rename from integration_tests/servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile rename to integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java b/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java deleted file mode 100644 index 2d67ecb8c..000000000 --- a/integration_tests/java_versions/src/test/java/io/prometheus/client/smoketest/JavaVersionsIT.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.prometheus.client.smoketest; - -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.images.builder.ImageFromDockerfile; - -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * Smoke test with different Java versions. - */ -@RunWith(Parameterized.class) -public class JavaVersionsIT { - - private final int port = 9000; - private final OkHttpClient client = new OkHttpClient(); - - @Rule - public JavaContainer javaContainer; - - public JavaVersionsIT(String baseImage) { - javaContainer = new JavaContainer(baseImage).withExposedPorts(port); - } - - @Parameterized.Parameters(name="{0}") - public static String[] images() { - return new String[] { - - // HotSpot - "openjdk:8-jre", - "openjdk:11-jre", - "openjdk:17", - "ticketfly/java:6", - "adoptopenjdk/openjdk16:ubi-minimal-jre", - "azul/zulu-openjdk:6", - - // OpenJ9 - "ibmjava:8-jre", - "adoptopenjdk/openjdk11-openj9:alpine", - }; - } - - private final List exampleMetrics = Arrays.asList( - "test_total{path=\"/hello-world\"}", - "jvm_memory_bytes_used{area=\"heap\"}" - ); - - @Test - public void testExampleMetrics() { - List metrics = scrapeMetrics(TimeUnit.SECONDS.toMillis(10)); - System.out.println(javaContainer.getLogs()); - for (String metric : exampleMetrics) { - Assert.assertTrue(metric + " not found", metrics.stream() - .filter(m -> m.startsWith(metric + " ")) - .peek(System.out::println) - .findAny() - .isPresent()); - } - } - - private static class JavaContainer extends GenericContainer { - JavaContainer(String baseImage) { - super(new ImageFromDockerfile("prometheus-client-java-example-application") - .withDockerfileFromBuilder(builder -> - builder - .from(baseImage) - .run("mkdir /app") - .workDir("/app") - .copy("example_application.jar", "/app/") - .cmd("java -version && java -jar example_application.jar") - .build()) - .withFileFromPath("example_application.jar", - Paths.get("../example_application/target/example_application.jar"))); - } - } - - private List scrapeMetrics(long timeoutMillis) { - long start = System.currentTimeMillis(); - Exception exception = null; - String host = javaContainer.getHost(); - Integer mappedPort = javaContainer.getMappedPort(port); - String metricsUrl = "http://" + host + ":" + mappedPort + "/metrics"; - while (System.currentTimeMillis() - start < timeoutMillis) { - try { - Request request = new Request.Builder() - .header("Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8") - .url(metricsUrl) - .build(); - try (Response response = client.newCall(request).execute()) { - return Arrays.asList(response.body().string().split("\\n")); - } - } catch (Exception e) { - exception = e; - try { - Thread.sleep(100); - } catch (InterruptedException ignored) { - } - } - } - if (exception != null) { - exception.printStackTrace(); - } - Assert.fail("Timeout while getting metrics from " + metricsUrl + " (orig port: " + port + ")"); - return null; // will not happen - } -} diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 1f3d5d8ae..7f2ca58c6 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -22,11 +22,12 @@ - exemplars_otel - exemplars_otel_agent - example_application - java_versions - servlet_jakarta_exporter_webxml + it_exemplars_otel_sdk + it_exemplars_otel_agent + it_java_versions + it_servlet_jakarta_exporter_webxml + it_common + it_pushgateway @@ -35,6 +36,16 @@ org.apache.maven.plugins maven-failsafe-plugin + + + integration-test + integration-test + + integration-test + verify + + + @@ -47,6 +58,18 @@ 1.15.2 test + + com.squareup.okhttp3 + okhttp + 4.9.3 + test + + + ch.qos.logback + logback-classic + 1.1.2 + test + From c7337638a00e65fc1c538da81db7d27da0ff575c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 Dec 2021 23:37:08 +0100 Subject: [PATCH 104/980] Bump logback-classic from 1.1.2 to 1.2.0 in /integration_tests (#724) Bumps logback-classic from 1.1.2 to 1.2.0. --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 6ef3acf5a..3a964b88c 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -56,7 +56,7 @@ ch.qos.logback logback-classic - 1.2.3 + 1.2.0 test diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 6dd4ac829..55f093065 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -45,7 +45,7 @@ ch.qos.logback logback-classic - 1.1.2 + 1.2.0 jakarta.servlet diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 7f2ca58c6..1c1922927 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -67,7 +67,7 @@ ch.qos.logback logback-classic - 1.1.2 + 1.2.0 test From a472ca5e93dfedc8ec9106bc8e2818b95f4f61e9 Mon Sep 17 00:00:00 2001 From: Yakir Gibraltar Date: Mon, 13 Dec 2021 00:39:50 +0200 Subject: [PATCH 105/980] log4j version upgrade for CVE-2021-44228 (#726) Fixes #725 Signed-off-by: Yakir Gibraltar Co-authored-by: Yakir Gibraltar --- simpleclient_log4j2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 44768169e..aa5dac930 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -41,7 +41,7 @@ org.apache.logging.log4j log4j-core - 2.1 + 2.15.0 From 0b0bff19594eef579f87b9beca348557f78f3000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 12 Dec 2021 23:47:18 +0100 Subject: [PATCH 106/980] Add integration test for log4j2 --- README.md | 2 + integration_tests/it_log4j2/pom.xml | 121 ++++++++++++++++++ .../client/it/log4j2/ExampleApplication.java | 25 ++++ .../it_log4j2/src/main/resources/log4j2.xml | 15 +++ .../prometheus/client/it/log4j2/Log4j2IT.java | 73 +++++++++++ .../src/test/resources/logback-test.xml | 14 ++ integration_tests/pom.xml | 1 + simpleclient_log4j2/pom.xml | 1 + 8 files changed, 252 insertions(+) create mode 100644 integration_tests/it_log4j2/pom.xml create mode 100644 integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java create mode 100644 integration_tests/it_log4j2/src/main/resources/log4j2.xml create mode 100644 integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java create mode 100644 integration_tests/it_log4j2/src/test/resources/logback-test.xml diff --git a/README.md b/README.md index 87f5c696b..f6fe7a172 100644 --- a/README.md +++ b/README.md @@ -479,6 +479,8 @@ To register the log4j2 collector at root level: ``` +See `./integration_tests/it_log4j2/` for a log4j2 example. + ### Caches To register the Guava cache collector, be certain to add `recordStats()` when building diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml new file mode 100644 index 000000000..b37e0cca5 --- /dev/null +++ b/integration_tests/it_log4j2/pom.xml @@ -0,0 +1,121 @@ + + + 4.0.0 + + + io.prometheus + integration_tests + 0.12.1-SNAPSHOT + + + it_log4j2 + Integration Tests - log4j2 + + + 2.15.0 + + + + + + + io.prometheus + simpleclient + ${project.version} + + + io.prometheus + simpleclient_log4j2 + ${project.version} + + + io.prometheus + simpleclient_httpserver + ${project.version} + + + org.apache.logging.log4j + log4j-api + ${log4j2.version} + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + org.testcontainers + testcontainers + test + + + ch.qos.logback + logback-classic + test + + + io.prometheus + it_common + test-jar + ${project.version} + test + + + com.squareup.okhttp3 + okhttp + test + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.client.it.log4j2.ExampleApplication + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + 1.6 + 1.6 + + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + diff --git a/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java b/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java new file mode 100644 index 000000000..d922c02cd --- /dev/null +++ b/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java @@ -0,0 +1,25 @@ +package io.prometheus.client.it.log4j2; + +import io.prometheus.client.exporter.HTTPServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; + +/** + * Simple example application using simpleclient_log4j2. + */ +public class ExampleApplication { + + private static final Logger logger = LogManager.getLogger(ExampleApplication.class); + + public static void main(String[] args) throws IOException, InterruptedException { + + logger.debug("some debug message"); + logger.debug("another debug message"); + logger.warn("this is a warning"); + + new HTTPServer(9000); + Thread.currentThread().join(); // sleep forever + } +} diff --git a/integration_tests/it_log4j2/src/main/resources/log4j2.xml b/integration_tests/it_log4j2/src/main/resources/log4j2.xml new file mode 100644 index 000000000..b3dc3eb6c --- /dev/null +++ b/integration_tests/it_log4j2/src/main/resources/log4j2.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java b/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java new file mode 100644 index 000000000..d92ba8870 --- /dev/null +++ b/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java @@ -0,0 +1,73 @@ +package io.prometheus.client.it.log4j2; + +import io.prometheus.client.it.common.LogConsumer; +import io.prometheus.client.it.common.Scraper; +import io.prometheus.client.it.common.Version; +import io.prometheus.client.it.common.Volume; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.List; + +/** + * Test simpleclient_log4j2. + */ +public class Log4j2IT { + + private final String image = "openjdk:8-jre"; + // This test is green with a Java 6 image, but you need to downgrade the log4j version in pom.xml. + // private final String image = "azul/zulu-openjdk:6"; + private final Volume volume; + private final GenericContainer javaContainer; + + public Log4j2IT() throws IOException, URISyntaxException { + String exampleApplicationJar = "it_log4j2-" + Version.loadProjectVersion() + ".jar"; + volume = Volume.create("it-log4j2") + .copyFromTargetDirectory(exampleApplicationJar); + String[] cmd = new String[]{"java", "-jar", exampleApplicationJar}; + javaContainer = new GenericContainer<>(image) + .withFileSystemBind(volume.getHostPath(), "/app", BindMode.READ_ONLY) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(image)) + .withExposedPorts(9000) + .withCommand(cmd); + System.out.println("Volume directory: " + volume.getHostPath()); + System.out.println("Command: " + String.join(" ", cmd)); + System.out.println("Docker image: " + image); + } + + @Before + public void setUp() { + javaContainer.start(); + } + + @After + public void tearDown() throws IOException { + javaContainer.stop(); + volume.remove(); + } + + @Test + public void testLog4j2Metrics() { + List metrics = Scraper.scrape("http://localhost:" + javaContainer.getMappedPort(9000) + "/metrics", 10_000); + for (String expectedMetric : new String[]{ + "log4j2_appender_total{level=\"trace\"} 0.0", + "log4j2_appender_total{level=\"debug\"} 2.0", + "log4j2_appender_total{level=\"info\"} 0.0", + "log4j2_appender_total{level=\"warn\"} 1.0", + "log4j2_appender_total{level=\"error\"} 0.0", + "log4j2_appender_total{level=\"fatal\"} 0.0" + }) { + Assert.assertTrue(expectedMetric + " not found", metrics.contains(expectedMetric)); + } + } +} diff --git a/integration_tests/it_log4j2/src/test/resources/logback-test.xml b/integration_tests/it_log4j2/src/test/resources/logback-test.xml new file mode 100644 index 000000000..1b7a25aa0 --- /dev/null +++ b/integration_tests/it_log4j2/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 1c1922927..0ca2fa5ad 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -28,6 +28,7 @@ it_servlet_jakarta_exporter_webxml it_common it_pushgateway + it_log4j2 diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index aa5dac930..931884e0e 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -42,6 +42,7 @@ org.apache.logging.log4j log4j-core 2.15.0 + provided From a79608a2325167956a39d47047c47cceea5cc869 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 13 Dec 2021 13:37:10 +0100 Subject: [PATCH 107/980] Bump client versions (#727) Update guava and jetty to fix security warnings. Signed-off-by: SuperQ --- simpleclient_guava/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index c2578193c..a0bbf3d4b 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -41,7 +41,7 @@ com.google.guava guava - 18.0 + 31.0.1-jre diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 61fda81c4..5a1b7a851 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -52,12 +52,12 @@ org.eclipse.jetty jetty-server - 9.4.4.v20170414 + 9.4.44.v20210927 org.eclipse.jetty jetty-servlet - 9.4.4.v20170414 + 9.4.44.v20210927 From fb5fb3f60735be8eedf4ae48b4c27078cd185cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 13 Dec 2021 22:37:06 +0100 Subject: [PATCH 108/980] Fix javadoc --- .../src/main/java/io/prometheus/client/exporter/Base64.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java index b2cbb88c7..9191f8142 100644 --- a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java +++ b/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java @@ -3,7 +3,7 @@ import javax.xml.bind.DatatypeConverter; /** - * This class delegates to either javax.xml.bind.DatatypeConverter (for Java < 8) or java.util.Base64 (Java 8+) + * This class delegates to either javax.xml.bind.DatatypeConverter (for Java < 8) or java.util.Base64 (Java 8+) * to perform Base64 encoding of a String. * * This code requires Java 8+ for compilation. @@ -30,7 +30,7 @@ private Base64() {} * * Passing a null argument will cause a NullPointerException to be thrown. * - * @param src + * @param src string to be encoded * @return String in Base64 encoding */ @SuppressWarnings("all") From d38217d0bd038091d7f4de9e443a3eb3432ad6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 13 Dec 2021 22:39:45 +0100 Subject: [PATCH 109/980] [maven-release-plugin] prepare release parent-0.13.0 --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 5 ++--- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 70 insertions(+), 71 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 9be936b63..de7680d30 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index f475803d1..42c04fe58 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 3a964b88c..c8330a7cb 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 9407528a2..a02a1d25e 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 6a26e6505..27a99745b 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index b37e0cca5..f1e3223dc 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 18bb856f8..1c15022b1 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 55f093065..0b1dbc0c1 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.12.1-SNAPSHOT + 0.13.0 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 0ca2fa5ad..3d0c7a585 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 integration_tests diff --git a/pom.xml b/pom.xml index bf8cf6250..0240d7378 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.13.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index aa9e7a7d6..32045faab 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index e7a77053c..05c01107f 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 4360f754f..1ce136c5e 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index c1b2a345c..b5396e5d9 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 8468a86fa..a78cdbca9 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 42123acb3..701e59e4e 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index a0bbf3d4b..433a2ffd8 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 8d4fea0f5..32f354ff1 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index a6d69f1c1..f59e30495 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_servlet - 0.12.1-SNAPSHOT + 0.13.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index c086eb3ff..6a9e2014a 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index ef40fec43..1adf64548 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 5a1b7a851..ae92c39ab 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index c12ff421c..2546bea49 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 931884e0e..9d48b8d0a 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 12c72e5da..f553936de 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index d3d8d4d25..1e01de8dd 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index bdbe41a9c..07e9e6aae 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_servlet_common - 0.12.1-SNAPSHOT + 0.13.0 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 5d5b75e40..70fd2de08 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 2e9b25a21..647f28216 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_servlet_common - 0.12.1-SNAPSHOT + 0.13.0 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index e357e461c..974d29537 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_spring_web - 0.12.1-SNAPSHOT + 0.13.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 91b0045d8..0d3bb1bf2 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index b79adf6cf..49944f164 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 54ce04625..bd7a689ce 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index b5284cc4d..5b0676c5a 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 7ee3f5009..cb1025f84 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 974e4fc26..5badff9b9 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.12.1-SNAPSHOT + 0.13.0 simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.12.1-SNAPSHOT + 0.13.0 io.prometheus simpleclient_common - 0.12.1-SNAPSHOT + 0.13.0 io.vertx From 837bb6db47d00db4443bb2aa843c875f8f5579eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 13 Dec 2021 22:39:49 +0100 Subject: [PATCH 110/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index de7680d30..53eba4924 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 42c04fe58..3ceecad05 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index c8330a7cb..acedc82ae 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index a02a1d25e..b0dcfdad8 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 27a99745b..a41e51de7 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index f1e3223dc..e1608dd38 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 1c15022b1..b24dbf17a 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 0b1dbc0c1..55e19e183 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.0 + 0.13.1-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 3d0c7a585..6306ef056 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index 0240d7378..36b2b12fb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.13.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 32045faab..ec7dd3b19 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 05c01107f..0af05208c 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 1ce136c5e..3832a4ec5 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index b5396e5d9..cc0ab6572 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index a78cdbca9..fc9f9f9dd 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 701e59e4e..a7aee0100 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 433a2ffd8..b3acac8c4 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 32f354ff1..8c3a75dd1 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index f59e30495..19bf13766 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.13.0 + 0.13.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 6a9e2014a..c30271d38 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 1adf64548..b5b4419e3 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index ae92c39ab..6d4fe0ac0 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 2546bea49..24d84511b 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 9d48b8d0a..edf5cb1d0 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index f553936de..0804ac40f 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 1e01de8dd..b1c14fa97 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 07e9e6aae..a4a6ff1e8 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.13.0 + 0.13.1-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 70fd2de08..989757165 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 647f28216..77ca5ae6a 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.13.0 + 0.13.1-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 974d29537..af3c4c871 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.13.0 + 0.13.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 0d3bb1bf2..2c3124984 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 49944f164..eed17af45 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index bd7a689ce..dde061327 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 5b0676c5a..fd7380bea 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index cb1025f84..0a6e1f93b 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 5badff9b9..d0ef5a541 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.13.0 + 0.13.1-SNAPSHOT simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.13.0 + 0.13.1-SNAPSHOT io.prometheus simpleclient_common - 0.13.0 + 0.13.1-SNAPSHOT io.vertx From ab82f6f8e7710988c2bdfc978a326ec4b580b48a Mon Sep 17 00:00:00 2001 From: PrometheusBot Date: Wed, 15 Dec 2021 09:39:45 +0100 Subject: [PATCH 111/980] Update common Prometheus files (#730) Signed-off-by: prombot --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ceede17f8..bc7849e68 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,4 +17,4 @@ jobs: - ~/.m2 key: maven-dependencies-{{ checksum "pom.xml" }} orbs: - prometheus: prometheus/prometheus@0.14.0 + prometheus: prometheus/prometheus@0.15.0 From ffb141640e33f79983c22f689f1b86939a0398f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 17 Dec 2021 19:38:43 +0100 Subject: [PATCH 112/980] Bump log4j2 version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- integration_tests/it_log4j2/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index e1608dd38..3896a9a16 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -12,7 +12,7 @@ Integration Tests - log4j2 - 2.15.0 + 2.16.0 diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index edf5cb1d0..52d8ff4cc 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -41,7 +41,7 @@ org.apache.logging.log4j log4j-core - 2.15.0 + 2.16.0 provided From d30ddee5655a18f2b296b5f6380113fe76eb751d Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Tue, 14 Dec 2021 12:59:39 -0500 Subject: [PATCH 113/980] Added cleaner SSL support to HTTPServer Signed-off-by: Doug Hoard --- .../client/exporter/HTTPServer.java | 24 +- .../client/exporter/TestHTTPServer.java | 281 ++++++++++++++++-- .../src/test/resources/keystore.pkcs12 | Bin 0 -> 2735 bytes 3 files changed, 277 insertions(+), 28 deletions(-) create mode 100644 simpleclient_httpserver/src/test/resources/keystore.pkcs12 diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index b3badf470..f56bc8860 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -1,5 +1,7 @@ package io.prometheus.client.exporter; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.SampleNameFilter; import io.prometheus.client.Predicate; @@ -200,6 +202,7 @@ public static class Builder { private Predicate sampleNameFilter; private Supplier> sampleNameFilterSupplier; private Authenticator authenticator; + private HttpsConfigurator httpsConfigurator; /** * Port to bind to. Must not be called together with {@link #withInetSocketAddress(InetSocketAddress)} @@ -299,6 +302,14 @@ public Builder withAuthenticator(Authenticator authenticator) { return this; } + /** + * Optional: {@link HttpsConfigurator} to use to support TLS/SSL + */ + public Builder withHttpsConfigurator(HttpsConfigurator configurator) { + this.httpsConfigurator = configurator; + return this; + } + /** * Build the HTTPServer * @throws IOException @@ -308,11 +319,13 @@ public HTTPServer build() throws IOException { assertNull(sampleNameFilterSupplier, "cannot configure 'sampleNameFilter' and 'sampleNameFilterSupplier' at the same time"); sampleNameFilterSupplier = SampleNameFilterSupplier.of(sampleNameFilter); } + if (httpServer != null) { assertZero(port, "cannot configure 'httpServer' and 'port' at the same time"); assertNull(hostname, "cannot configure 'httpServer' and 'hostname' at the same time"); assertNull(inetAddress, "cannot configure 'httpServer' and 'inetAddress' at the same time"); assertNull(inetSocketAddress, "cannot configure 'httpServer' and 'inetSocketAddress' at the same time"); + assertNull(httpsConfigurator, "cannot configure 'httpServer' and 'httpsConfigurator' at the same time"); return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); } else if (inetSocketAddress != null) { assertZero(port, "cannot configure 'inetSocketAddress' and 'port' at the same time"); @@ -326,7 +339,16 @@ public HTTPServer build() throws IOException { } else { inetSocketAddress = new InetSocketAddress(port); } - return new HTTPServer(HttpServer.create(inetSocketAddress, 3), registry, daemon, sampleNameFilterSupplier, authenticator); + + HttpServer httpServer = null; + if (httpsConfigurator != null) { + httpServer = HttpsServer.create(inetSocketAddress, 3); + ((HttpsServer)httpServer).setHttpsConfigurator(httpsConfigurator); + } else { + httpServer = HttpServer.create(inetSocketAddress, 3); + } + + return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); } private void assertNull(Object o, String msg) { diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index 7945a997d..37721d214 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -3,22 +3,40 @@ import com.sun.net.httpserver.Authenticator; import com.sun.net.httpserver.BasicAuthenticator; import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; import io.prometheus.client.Gauge; import io.prometheus.client.CollectorRegistry; + +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.URL; import java.net.URLConnection; -import java.util.Scanner; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Scanner;; import java.util.zip.GZIPInputStream; import io.prometheus.client.SampleNameFilter; import org.junit.Assert; import org.junit.Before; -import org.junit.Test; - +import org.junit.Test;; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import javax.xml.bind.DatatypeConverter; import static org.assertj.core.api.Java6Assertions.assertThat; @@ -27,6 +45,68 @@ public class TestHTTPServer { CollectorRegistry registry; + private final static SSLContext SSL_CONTEXT; + + private final static HttpsConfigurator HTTPS_CONFIGURATOR; + + // Code put in a static block due to possible Exceptions + static { + try { + SSL_CONTEXT = createSSLContext( + "SSL", + "PKCS12", + "./src/test/resources/keystore.pkcs12", + "changeit"); + } catch (GeneralSecurityException e) { + throw new RuntimeException("Exception creating SSL_CONTEXT", e); + } catch (IOException e) { + throw new RuntimeException("Exception creating SSL_CONTEXT", e); + } + + HTTPS_CONFIGURATOR = createHttpsConfigurator(SSL_CONTEXT); + } + + private final static TrustManager[] TRUST_MANAGERS = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + private final static HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + final static Authenticator createAuthenticator(String realm, final String validUsername, final String validPassword) { + return new BasicAuthenticator(realm) { + @Override + public boolean checkCredentials(String username, String password) { + return validUsername.equals(username) && validPassword.equals(password); + } + }; + } + + class Response { + + public long contentLength; + public String body; + + public Response(long contentLength, String body) { + this.contentLength = contentLength; + this.body = body; + } + } + @Before public void init() throws IOException { registry = new CollectorRegistry(); @@ -79,18 +159,39 @@ Response requestWithAccept(HTTPServer s, String accept) throws IOException { return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); } - Response requestWithCredentials(HTTPServer httpServer, String context, String suffix, String user, String password) throws IOException { + Response requestWithCredentials(HTTPServer httpServer, String context, String suffix, String username, String password) throws IOException { String url = "http://localhost:" + httpServer.server.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); connection.setDoOutput(true); - if (user != null && password != null) { - connection.setRequestProperty("Authorization", encodeCredentials(user, password)); + if (username != null && password != null) { + connection.setRequestProperty("Authorization", encodeCredentials(username, password)); } connection.connect(); Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); } + Response requestWithSSL(String requestMethod, String username, String password, HTTPServer s, String context, String suffix) throws GeneralSecurityException, IOException { + String url = "https://localhost:" + s.server.getAddress().getPort() + context + suffix; + + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, TRUST_MANAGERS, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + HttpsURLConnection.setDefaultHostnameVerifier(HOSTNAME_VERIFIER); + + URLConnection connection = new URL(url).openConnection(); + ((HttpURLConnection)connection).setRequestMethod(requestMethod); + + if (username != null && password != null) { + connection.setRequestProperty("Authorization", encodeCredentials(username, password)); + } + + connection.setDoOutput(true); + connection.connect(); + Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); + return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); + } + Response request(HttpServer httpServer, String context, String suffix) throws IOException { String url = "http://localhost:" + httpServer.getAddress().getPort() + context + suffix; URLConnection connection = new URL(url).openConnection(); @@ -100,32 +201,21 @@ Response request(HttpServer httpServer, String context, String suffix) throws IO return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); } - String encodeCredentials(String user, String password) { + String encodeCredentials(String username, String password) { // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, try { - byte[] credentialsBytes = (user + ":" + password).getBytes("UTF-8"); - String encoded = DatatypeConverter.printBase64Binary(credentialsBytes); - encoded = String.format("Basic %s", encoded); - return encoded; + byte[] credentialsBytes = (username + ":" + password).getBytes("UTF-8"); + return "Basic " + DatatypeConverter.printBase64Binary(credentialsBytes); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } } - Authenticator createAuthenticator(String realm, final String validUsername, final String validPassword) { - return new BasicAuthenticator(realm) { - @Override - public boolean checkCredentials(String username, String password) { - return validUsername.equals(username) && validPassword.equals(password); - } - }; - } - @Test(expected = IllegalArgumentException.class) public void testRefuseUsingUnbound() throws IOException { CollectorRegistry registry = new CollectorRegistry(); HTTPServer s = new HTTPServer(HttpServer.create(), registry, true); - s.stop(); + s.close(); } @Test @@ -310,6 +400,8 @@ public void testHEADRequest() throws IOException { .build(); try { Response response = request("HEAD", s, "/metrics", "?name[]=a&name[]=b"); + + Assert.assertNotNull(response); Assert.assertTrue(response.contentLength == 74); Assert.assertTrue("".equals(response.body)); } finally { @@ -318,6 +410,24 @@ public void testHEADRequest() throws IOException { } @Test + public void testHEADRequestWithSSL() throws GeneralSecurityException, IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withHttpsConfigurator(HTTPS_CONFIGURATOR) + .build(); + + try { + Response response = requestWithSSL( + "HEAD", null, null, s, "/metrics", "?name[]=a&name[]=b"); + + Assert.assertNotNull(response); + Assert.assertTrue(response.contentLength == 74); + Assert.assertTrue("".equals(response.body)); + } finally { + s.close(); + } + } + public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOException { InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 0); HttpServer httpServer = HttpServer.create(inetSocketAddress, 0); @@ -334,14 +444,131 @@ public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOExceptio } } - class Response { + @Test + public void testHEADRequestWithSSLAndBasicAuthSuccess() throws GeneralSecurityException, IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withHttpsConfigurator(HTTPS_CONFIGURATOR) + .withAuthenticator(createAuthenticator("/", "user", "secret")) + .build(); - public long contentLength; - public String body; + try { + Response response = requestWithSSL( + "HEAD", "user", "secret", s, "/metrics", "?name[]=a&name[]=b"); - public Response(long contentLength, String body) { - this.contentLength = contentLength; - this.body = body; + Assert.assertNotNull(response); + Assert.assertTrue(response.contentLength == 74); + Assert.assertTrue("".equals(response.body)); + } finally { + s.close(); } } + + @Test + public void testHEADRequestWithSSLAndBasicAuthCredentialsMissing() throws GeneralSecurityException, IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withHttpsConfigurator(HTTPS_CONFIGURATOR) + .withAuthenticator(createAuthenticator("/", "user", "secret")) + .build(); + + try { + Response response = requestWithSSL("HEAD", null, null, s, "/metrics", "?name[]=a&name[]=b"); + Assert.fail("expected IOException with HTTP 401"); + } catch (IOException e) { + Assert.assertTrue(e.getMessage().contains("401")); + } finally { + s.close(); + } + } + + @Test + public void testHEADRequestWithSSLAndBasicAuthWrongCredentials() throws GeneralSecurityException, IOException { + HTTPServer s = new HTTPServer.Builder() + .withRegistry(registry) + .withHttpsConfigurator(HTTPS_CONFIGURATOR) + .withAuthenticator(createAuthenticator("/", "user", "secret")) + .build(); + + try { + Response response = requestWithSSL("HEAD", "user", "wrong", s, "/metrics", "?name[]=a&name[]=b"); + Assert.fail("expected IOException with HTTP 401"); + } catch (IOException e) { + Assert.assertTrue(e.getMessage().contains("401")); + } finally { + s.close(); + } + } + /** + * Create an SSLContext + * + * @param sslContextType + * @param keyStoreType + * @param keyStorePath + * @param keyStorePassword + * @return SSLContext + * @throws GeneralSecurityException + * @throws IOException + */ + public static SSLContext createSSLContext(String sslContextType, String keyStoreType, String keyStorePath, String keyStorePassword) + throws GeneralSecurityException, IOException { + SSLContext sslContext = null; + FileInputStream fileInputStream = null; + + try { + File file = new File(keyStorePath); + + if ((file.exists() == false) || (file.isFile() == false) || (file.canRead() == false)) { + throw new IllegalArgumentException("cannot read 'keyStorePath', path = [" + file.getAbsolutePath() + "]"); + } + + fileInputStream = new FileInputStream(keyStorePath); + + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(fileInputStream, keyStorePassword.toCharArray()); + + KeyManagerFactory keyManagerFactor = KeyManagerFactory.getInstance("SunX509"); + keyManagerFactor.init(keyStore, keyStorePassword.toCharArray()); + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); + trustManagerFactory.init(keyStore); + + sslContext = SSLContext.getInstance(sslContextType); + sslContext.init(keyManagerFactor.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + } finally { + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + // IGNORE + } + } + } + + return sslContext; + } + + /** + * + * @param sslContext + * @return HttpsConfigurator + */ + private static HttpsConfigurator createHttpsConfigurator(SSLContext sslContext) { + return new HttpsConfigurator(sslContext) { + @Override + public void configure(HttpsParameters params) { + try { + SSLContext c = getSSLContext(); + SSLEngine engine = c.createSSLEngine(); + params.setNeedClientAuth(false); + params.setCipherSuites(engine.getEnabledCipherSuites()); + params.setProtocols(engine.getEnabledProtocols()); + SSLParameters sslParameters = c.getSupportedSSLParameters(); + params.setSSLParameters(sslParameters); + } catch (Exception e) { + throw new RuntimeException("Exception creating HttpsConfigurator", e); + } + } + }; + } } diff --git a/simpleclient_httpserver/src/test/resources/keystore.pkcs12 b/simpleclient_httpserver/src/test/resources/keystore.pkcs12 new file mode 100644 index 0000000000000000000000000000000000000000..4e635ac82d941565f32321e720aead0c1fde9fb9 GIT binary patch literal 2735 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 Date: Sat, 18 Dec 2021 17:36:30 +0100 Subject: [PATCH 114/980] [maven-release-plugin] prepare release parent-0.14.0 --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 53eba4924..46b4ee50f 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 3ceecad05..1e26fcf78 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index acedc82ae..331cb42d7 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index b0dcfdad8..e390a87d3 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index a41e51de7..9cab0efd8 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 3896a9a16..582eae754 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index b24dbf17a..d6738afad 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 55e19e183..fa9b9bbac 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.13.1-SNAPSHOT + 0.14.0 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 6306ef056..ab3a7c83c 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 integration_tests diff --git a/pom.xml b/pom.xml index 36b2b12fb..c82bb849b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.14.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index ec7dd3b19..b6cd89f33 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 0af05208c..b1cfb538d 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 3832a4ec5..6187f7465 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index cc0ab6572..7c62a5e91 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index fc9f9f9dd..d682e3027 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index a7aee0100..00fa16a72 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index b3acac8c4..0d4a5114b 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 8c3a75dd1..b1daaecb2 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 19bf13766..8e940ece7 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_servlet - 0.13.1-SNAPSHOT + 0.14.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index c30271d38..76dbcb4ab 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index b5b4419e3..c32c28c97 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 6d4fe0ac0..8bf1b770c 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 24d84511b..d1c8768ba 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 52d8ff4cc..097331d85 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 0804ac40f..82bac49e0 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index b1c14fa97..cee3b7abb 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index a4a6ff1e8..c75471daf 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_servlet_common - 0.13.1-SNAPSHOT + 0.14.0 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 989757165..db3c75310 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 77ca5ae6a..252db32ad 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_servlet_common - 0.13.1-SNAPSHOT + 0.14.0 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index af3c4c871..86a65c007 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_spring_web - 0.13.1-SNAPSHOT + 0.14.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 2c3124984..a5ed181f2 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index eed17af45..f5498bd56 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index dde061327..d111d196f 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index fd7380bea..6e402515e 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 0a6e1f93b..d2e0e8f43 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index d0ef5a541..85c71a41c 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.13.1-SNAPSHOT + 0.14.0 simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.13.1-SNAPSHOT + 0.14.0 io.prometheus simpleclient_common - 0.13.1-SNAPSHOT + 0.14.0 io.vertx From 3af6571922a9d9cbf7918d4b2b07137c31ddfd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 18 Dec 2021 17:36:34 +0100 Subject: [PATCH 115/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 46b4ee50f..2ba7f597f 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 1e26fcf78..67e27fa14 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 331cb42d7..f92b12ad9 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index e390a87d3..ecbd1897a 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 9cab0efd8..d436fe305 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 582eae754..3995ccb5d 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index d6738afad..7029b084a 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index fa9b9bbac..92983c6a6 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.0 + 0.14.1-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index ab3a7c83c..5bd56acb2 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index c82bb849b..46b7ec239 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.14.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index b6cd89f33..f0a73de00 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index b1cfb538d..f26c5eea5 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 6187f7465..ee6a0e5b6 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 7c62a5e91..c064c86ac 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index d682e3027..35b81162e 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 00fa16a72..dd4f2844b 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 0d4a5114b..91870c835 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index b1daaecb2..de8126870 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 8e940ece7..2ef9e921d 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.14.0 + 0.14.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 76dbcb4ab..81cce91df 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index c32c28c97..6faf8ab7f 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 8bf1b770c..47a07da4e 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index d1c8768ba..42b0b083f 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 097331d85..6452f89a9 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 82bac49e0..f5771b6d6 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index cee3b7abb..34228ec06 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index c75471daf..096cd8cfd 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.14.0 + 0.14.1-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index db3c75310..a4a1993a3 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 252db32ad..d5fcc9b96 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.14.0 + 0.14.1-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 86a65c007..573502baa 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.14.0 + 0.14.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index a5ed181f2..faa6b09ba 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index f5498bd56..2b6edf184 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index d111d196f..4bbb6dc51 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 6e402515e..5eac50646 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index d2e0e8f43..d111f4444 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 85c71a41c..61ace5e06 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.14.0 + 0.14.1-SNAPSHOT simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.14.0 + 0.14.1-SNAPSHOT io.prometheus simpleclient_common - 0.14.0 + 0.14.1-SNAPSHOT io.vertx From 715aaa30d9b2eaff25021a5033b48318990b4713 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 19 Dec 2021 00:00:34 -0500 Subject: [PATCH 116/980] Added missing @Test annotation Signed-off-by: Doug Hoard --- .../test/java/io/prometheus/client/exporter/TestHTTPServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index 37721d214..bb8f7fa13 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -428,6 +428,7 @@ public void testHEADRequestWithSSL() throws GeneralSecurityException, IOExceptio } } + @Test public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOException { InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 0); HttpServer httpServer = HttpServer.create(inetSocketAddress, 0); From c7ed85ce1e99a50a6c8040919385e9ab257af5f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 18 Dec 2021 18:40:46 +0000 Subject: [PATCH 117/980] Bump log4j-core from 2.16.0 to 2.17.0 in /integration_tests/it_log4j2 Bumps log4j-core from 2.16.0 to 2.17.0. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- integration_tests/it_log4j2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 3995ccb5d..6d92149ee 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -12,7 +12,7 @@ Integration Tests - log4j2 - 2.16.0 + 2.17.0 From c867d8e61556ef1a91c18b697220c0284cb7fce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 19 Dec 2021 12:26:38 +0100 Subject: [PATCH 118/980] Bump log4j2 version --- simpleclient_log4j2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 6452f89a9..db22d49b6 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -41,7 +41,7 @@ org.apache.logging.log4j log4j-core - 2.16.0 + 2.17.0 provided From 39e40da662569d33cd86f007906310befd90d73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 19 Dec 2021 12:32:26 +0100 Subject: [PATCH 119/980] [maven-release-plugin] prepare release parent-0.14.1 --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 2ba7f597f..76a61bae3 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 67e27fa14..bebfe330e 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index f92b12ad9..69a4f6d3d 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index ecbd1897a..adebc1d9d 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index d436fe305..43e7f5853 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 6d92149ee..8b792d908 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 7029b084a..a64f0efff 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 92983c6a6..bb9a40da1 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1-SNAPSHOT + 0.14.1 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 5bd56acb2..280040fb3 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 integration_tests diff --git a/pom.xml b/pom.xml index 46b7ec239..85d3c4ea3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.14.1 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index f0a73de00..3cc8b7845 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index f26c5eea5..c8bf490fb 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index ee6a0e5b6..f273ec83b 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index c064c86ac..6fdd64144 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 35b81162e..9993b45a8 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index dd4f2844b..4f28d5aca 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 91870c835..75bde610e 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index de8126870..c4f4fd704 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 2ef9e921d..2e7543df1 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_servlet - 0.14.1-SNAPSHOT + 0.14.1 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 81cce91df..86fb104d2 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 6faf8ab7f..abf8cc29b 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 47a07da4e..c9a1313e3 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 42b0b083f..eda703aa7 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index db22d49b6..4d2e64dab 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index f5771b6d6..c245328a7 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 34228ec06..ba10fb802 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 096cd8cfd..8deb19ac3 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_servlet_common - 0.14.1-SNAPSHOT + 0.14.1 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index a4a1993a3..debb21ac4 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index d5fcc9b96..1707a0b51 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_servlet_common - 0.14.1-SNAPSHOT + 0.14.1 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 573502baa..7a340dbb5 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_spring_web - 0.14.1-SNAPSHOT + 0.14.1 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index faa6b09ba..a8bfe77c7 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 2b6edf184..14d573067 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 4bbb6dc51..bf4498212 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 5eac50646..335213475 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index d111f4444..82284541d 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 61ace5e06..ca298114c 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.14.1-SNAPSHOT + 0.14.1 simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.14.1-SNAPSHOT + 0.14.1 io.prometheus simpleclient_common - 0.14.1-SNAPSHOT + 0.14.1 io.vertx From 5ecd18946efc9e09a0dc7dad0e5408b17096dcba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 19 Dec 2021 12:32:30 +0100 Subject: [PATCH 120/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 76a61bae3..e027baf8d 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index bebfe330e..b17d40a01 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 69a4f6d3d..54dde3145 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index adebc1d9d..e4b647be8 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 43e7f5853..ff580e088 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 8b792d908..c173c6e91 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index a64f0efff..ea2f0b6eb 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index bb9a40da1..922e2634a 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.1 + 0.14.2-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 280040fb3..9464364c2 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index 85d3c4ea3..6ed5c83c5 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.14.1 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 3cc8b7845..d1a751f5e 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index c8bf490fb..2655d46da 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index f273ec83b..319e31276 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 6fdd64144..8b6265d99 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 9993b45a8..8a88bf39d 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 4f28d5aca..4a6ffeb42 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 75bde610e..a629ab7d3 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index c4f4fd704..cd898375c 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 2e7543df1..9abcdb150 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_servlet - 0.14.1 + 0.14.2-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 86fb104d2..3600fcdea 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index abf8cc29b..89de47899 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index c9a1313e3..0bd645483 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index eda703aa7..c6d2d525e 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 4d2e64dab..28cc59b8c 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index c245328a7..8f3a26c99 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index ba10fb802..55345ddea 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 8deb19ac3..a6686bdc2 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.14.1 + 0.14.2-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index debb21ac4..d287f5d56 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 1707a0b51..e4c67306d 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.14.1 + 0.14.2-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 7a340dbb5..47d76fa8c 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_spring_web - 0.14.1 + 0.14.2-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index a8bfe77c7..f88b8618c 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 14d573067..941d2073f 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index bf4498212..c46853511 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 335213475..0084319a2 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 82284541d..c9d6a593f 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index ca298114c..ec6b34eff 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.14.1 + 0.14.2-SNAPSHOT simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.14.1 + 0.14.2-SNAPSHOT io.prometheus simpleclient_common - 0.14.1 + 0.14.2-SNAPSHOT io.vertx From ce3f5d9736ed59421630a8367f6ae21def47e8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 21 Dec 2021 16:18:51 +0100 Subject: [PATCH 121/980] Make project easier to work with in the Intellij IDE --- integration_tests/it_java_versions/pom.xml | 32 ++++++++++++++++++++-- integration_tests/it_log4j2/pom.xml | 32 ++++++++++++++++++++-- integration_tests/it_pushgateway/pom.xml | 32 ++++++++++++++++++++-- pom.xml | 4 +-- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index ff580e088..e62ad864a 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -78,8 +78,6 @@ 1.6 1.6 - - 1.8 1.8 @@ -91,6 +89,36 @@ + + + + + + intellij + + false + + + + + idea.maven.embedder.version + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + The Apache Software License, Version 2.0 diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index c173c6e91..67f9c5c1f 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -97,8 +97,6 @@ 1.6 1.6 - - 1.8 1.8 @@ -110,6 +108,36 @@ + + + + + + intellij + + false + + + + + idea.maven.embedder.version + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + The Apache Software License, Version 2.0 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index ea2f0b6eb..3a1dacbcb 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -75,8 +75,6 @@ 1.6 1.6 - - 1.8 1.8 @@ -88,6 +86,36 @@ + + + + + + intellij + + false + + + + + idea.maven.embedder.version + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + The Apache Software License, Version 2.0 diff --git a/pom.xml b/pom.xml index 6ed5c83c5..56f08c4c0 100644 --- a/pom.xml +++ b/pom.xml @@ -173,8 +173,8 @@ - maven-release-plugin org.apache.maven.plugins + maven-release-plugin true false @@ -183,8 +183,8 @@ - maven-deploy-plugin org.apache.maven.plugins + maven-deploy-plugin org.apache.felix From fd931c1c6a88bab379fbc91cf3c933dd71dc19a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 21 Dec 2021 16:30:15 +0100 Subject: [PATCH 122/980] Fix MetricsServlet initialization (#739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../main/java/io/prometheus/client/exporter/MetricsServlet.java | 1 + .../client/servlet/jakarta/exporter/MetricsServlet.java | 1 + 2 files changed, 2 insertions(+) diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java index 76a6d5cee..3cd6af877 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java @@ -41,6 +41,7 @@ public MetricsServlet(CollectorRegistry registry, Predicate sampleNameFi @Override public void init(ServletConfig servletConfig) throws ServletException { try { + super.init(servletConfig); exporter.init(Adapter.wrap(servletConfig)); } catch (ServletConfigurationException e) { throw new ServletException(e); diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java index bf8646af7..4617ebd48 100644 --- a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java @@ -40,6 +40,7 @@ public MetricsServlet(CollectorRegistry registry, Predicate sampleNameFi @Override public void init(ServletConfig servletConfig) throws ServletException { try { + super.init(servletConfig); exporter.init(wrap(servletConfig)); } catch (ServletConfigurationException e) { throw new ServletException(e); From ec6def41378f4a408f781a13669e2caf82aa6bf3 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 19 Dec 2021 17:11:15 -0500 Subject: [PATCH 123/980] Changes to HTTPServer and HTTPMetricHandler to resolve getting Content-Length=0 when Transfer-Encoding=chunked. Refactored test classes for easier/cleaner testing. Signed-off-by: Doug Hoard --- .../client/exporter/HTTPServer.java | 4 +- .../client/exporter/HttpRequest.java | 244 ++++++++++ .../client/exporter/HttpResponse.java | 109 +++++ .../client/exporter/TestHTTPServer.java | 456 +++++++++--------- 4 files changed, 577 insertions(+), 236 deletions(-) create mode 100644 simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java create mode 100644 simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index f56bc8860..834c32480 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -116,7 +116,9 @@ public void handle(HttpExchange t) throws IOException { } } else { long contentLength = response.size(); - t.getResponseHeaders().set("Content-Length", String.valueOf(contentLength)); + if (contentLength > 0) { + t.getResponseHeaders().set("Content-Length", String.valueOf(contentLength)); + } if (t.getRequestMethod().equals("HEAD")) { contentLength = -1; } diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java new file mode 100644 index 000000000..5b7865de4 --- /dev/null +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java @@ -0,0 +1,244 @@ +package io.prometheus.client.exporter; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.xml.bind.DatatypeConverter; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; + +/** + * Class to perform HTTP testing + */ +public class HttpRequest { + + enum METHOD { GET, HEAD } + + private final Configuration configuration; + + /** + * Constructor + * + * @param configuration configuration + */ + private HttpRequest(Configuration configuration) { + this.configuration = configuration; + } + + /** + * Method to execute an HTTP request + * + * @return HttpResponse + * @throws IOException + */ + public HttpResponse execute() throws IOException { + if (configuration.url.toLowerCase().startsWith("https://") && (configuration.trustManagers != null)) { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, configuration.trustManagers, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + } catch (GeneralSecurityException e) { + throw new IOException(e); + } + + if (configuration.hostnameVerifier != null) { + HttpsURLConnection.setDefaultHostnameVerifier(configuration.hostnameVerifier); + } + } + + URLConnection urlConnection = new URL(configuration.url).openConnection(); + ((HttpURLConnection) urlConnection).setRequestMethod(configuration.method.toString()); + + Set>> entries = configuration.headers.entrySet(); + for (Map.Entry> entry : entries) { + for (String value : entry.getValue()) { + urlConnection.addRequestProperty(entry.getKey(), value); + } + } + + urlConnection.setUseCaches(false); + urlConnection.setDoInput(true); + urlConnection.setDoOutput(true); + urlConnection.connect(); + + Scanner scanner = new Scanner(urlConnection.getInputStream(), "UTF-8").useDelimiter("\\A"); + + return new HttpResponse( + ((HttpURLConnection) urlConnection).getResponseCode(), + urlConnection.getHeaderFields(), + urlConnection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); + } + + /** + * Class to build an HttpRequest + */ + static class Builder { + + private final Configuration configuration; + + /** + * Constructor + */ + public Builder() { + configuration = new Configuration(); + } + + /** + * Method to set the HTTP request method + * + * @param method + * @return Builder + */ + public Builder withMethod(METHOD method) { + configuration.method = method; + return this; + } + + /** + * Method to set the HTTP request URL + * + * @param url + * @return Builder + */ + public Builder withURL(String url) { + configuration.url = url; + return this; + } + + /** + * Method to add an HTTP request header + * + * @param name + * @param value + * @return Builder + */ + public Builder withHeader(String name, String value) { + configuration.addHeader(name, value); + return this; + } + + /** + * Method to set the HTTP request "Authorization" header + * + * @param username + * @param password + * @return Builder + */ + public Builder withAuthorization(String username, String password) { + configuration.setHeader("Authorization", encodeCredentials(username, password)); + return this; + } + + /** + * Method to set the HTTP request trust managers when using an SSL URL + * + * @param trustManagers + * @return Builder + */ + public Builder withTrustManagers(TrustManager[] trustManagers) { + configuration.trustManagers = trustManagers; + return this; + } + + /** + * Method to set the HTTP request hostname verifier when using an SSL URL + * + * @param hostnameVerifier + * @return Builder + */ + public Builder withHostnameVerifier(HostnameVerifier hostnameVerifier) { + configuration.hostnameVerifier = hostnameVerifier; + return this; + } + + /** + * Method to build the HttpRequest + * + * @return HttpRequest + */ + public HttpRequest build() { + return new HttpRequest(configuration); + } + } + + /** + * Class used for Builder configuration + */ + private static class Configuration { + + public METHOD method; + public String url; + public Map> headers; + public TrustManager[] trustManagers; + public HostnameVerifier hostnameVerifier; + + /** + * Constructor + */ + Configuration() { + method = METHOD.GET; + headers = new HashMap>(); + } + + /** + * Method to add (append) an HTTP request header + * + * @param name + * @param value + * @return Configuration + */ + void addHeader(String name, String value) { + name = name.toLowerCase(); + List values = headers.get(name); + if (values == null) { + values = new LinkedList(); + headers.put(name, values); + } + + values.add(value); + } + + /** + * Method to set (overwrite) an HTTP request header, removing all previous header values + * + * @param name + * @param value + * @return Configuration + */ + void setHeader(String name, String value) { + List values = new LinkedList(); + values.add(value); + headers.put(name, values); + } + } + + /** + * Method to encode "Authorization" credentials + * + * @param username + * @param password + * @return String + */ + private final static String encodeCredentials(String username, String password) { + // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, + try { + byte[] credentialsBytes = (username + ":" + password).getBytes("UTF-8"); + return "Basic " + DatatypeConverter.printBase64Binary(credentialsBytes); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java new file mode 100644 index 000000000..9ad49be41 --- /dev/null +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java @@ -0,0 +1,109 @@ +package io.prometheus.client.exporter; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Class to perform HTTP testing + */ +class HttpResponse { + + private int responseCode; + private Map> headers; + private long contentLength = -1; + private String body; + + /** + * Constructor + * + * @param responseCode + * @param headers + * @param contentLength + * @param body + */ + HttpResponse(int responseCode, Map> headers, long contentLength, String body) throws IOException { + this.responseCode = responseCode; + this.body = body; + this.contentLength = contentLength; + this.headers = new HashMap>(); + + Set>> headerSet = headers.entrySet(); + for (String header : headers.keySet()) { + if (header != null) { + List values = headers.get(header); + this.headers.put(header.toLowerCase(), values); + } + } + + if (getHeader("content-length") != null && getHeader("transfer-encoding") != null) { + throw new IOException("Invalid HTTP response, should only contain Connect-Length or Transfer-Encoding"); + } + } + + /** + * Method to get the HTTP response code + * + * @return int + */ + public int getResponseCode() { + return this.responseCode; + } + + /** + * Method to get a list of HTTP response headers values + * + * @param name + * @return List + */ + public List getHeaderList(String name) { + return headers.get(name.toLowerCase()); + } + + /** + * Method to get the first HTTP response header value + * + * @param name + * @return String + */ + public String getHeader(String name) { + String value = null; + + List valueList = getHeaderList(name); + if (valueList != null && (valueList.size() >= 0)) { + value = valueList.get(0); + } + + return value; + } + + /** + * Method to get the first HTTP response header value as a Long. + * Returns null of the header doesn't exist + * + * @param name + * @return Long + */ + public Long getHeaderAsLong(String name) { + String value = getHeader(name); + if (value != null) { + try { + return Long.valueOf(value); + } catch (Exception e) { + } + } + + return null; + } + + /** + * Method to get the HTTP response body + * + * @return String + */ + public String getBody() { + return body; + } +} diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index bb8f7fa13..cf7f6aef4 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -5,30 +5,14 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsParameters; -import io.prometheus.client.Gauge; import io.prometheus.client.CollectorRegistry; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.InetSocketAddress; -import java.net.URL; -import java.net.URLConnection; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.cert.X509Certificate; -import java.util.Scanner;; -import java.util.zip.GZIPInputStream; - +import io.prometheus.client.Gauge; import io.prometheus.client.SampleNameFilter; import org.junit.Assert; import org.junit.Before; -import org.junit.Test;; +import org.junit.Test; import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; @@ -38,6 +22,14 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import javax.xml.bind.DatatypeConverter; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.InetSocketAddress; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; import static org.assertj.core.api.Java6Assertions.assertThat; @@ -66,45 +58,45 @@ public class TestHTTPServer { HTTPS_CONFIGURATOR = createHttpsConfigurator(SSL_CONTEXT); } - private final static TrustManager[] TRUST_MANAGERS = new TrustManager[]{ + /** + * TrustManager[] that trusts all certificates + */ + private final static TrustManager[] TRUST_ALL_CERTS_TRUST_MANAGERS = new TrustManager[]{ new X509TrustManager() { - public java.security.cert.X509Certificate[] getAcceptedIssuers() { + public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + public void checkClientTrusted(X509Certificate[] certs, String authType) { } - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; - private final static HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() { + /** + * HostnameVerifier that accepts any hostname + */ + private final static HostnameVerifier TRUST_ALL_HOSTS_HOSTNAME_VERIFIER = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; - final static Authenticator createAuthenticator(String realm, final String validUsername, final String validPassword) { - return new BasicAuthenticator(realm) { - @Override - public boolean checkCredentials(String username, String password) { - return validUsername.equals(username) && validPassword.equals(password); - } - }; + HttpRequest.Builder createHttpRequestBuilder(HTTPServer httpServer, String urlPath) { + return new HttpRequest.Builder().withURL("http://localhost:" + httpServer.getPort() + urlPath); } - class Response { - - public long contentLength; - public String body; + HttpRequest.Builder createHttpRequestBuilderWithSSL(HTTPServer httpServer, String urlPath) { + return new HttpRequest.Builder().withURL("https://localhost:" + httpServer.getPort() + urlPath) + .withTrustManagers(TRUST_ALL_CERTS_TRUST_MANAGERS) + .withHostnameVerifier(TRUST_ALL_HOSTS_HOSTNAME_VERIFIER); + } - public Response(long contentLength, String body) { - this.contentLength = contentLength; - this.body = body; - } + HttpRequest.Builder createHttpRequestBuilder(HttpServer httpServer, String urlPath) { + return new HttpRequest.Builder().withURL("http://localhost:" + httpServer.getAddress().getPort() + urlPath); } @Before @@ -115,316 +107,267 @@ public void init() throws IOException { Gauge.build("c", "a help").register(registry); } - Response request(String requestMethod, HTTPServer s, String context, String suffix) throws IOException { - String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; - URLConnection connection = new URL(url).openConnection(); - ((HttpURLConnection)connection).setRequestMethod(requestMethod); - connection.setDoOutput(true); - connection.connect(); - Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); - } - - Response request(HTTPServer s, String context, String suffix) throws IOException { - return request("GET", s, context, suffix); - } - - Response request(HTTPServer s, String suffix) throws IOException { - return request(s, "/metrics", suffix); - } - - Response requestWithCompression(HTTPServer s, String suffix) throws IOException { - return requestWithCompression(s, "/metrics", suffix); - } - - Response requestWithCompression(HTTPServer s, String context, String suffix) throws IOException { - String url = "http://localhost:" + s.server.getAddress().getPort() + context + suffix; - URLConnection connection = new URL(url).openConnection(); - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); - connection.connect(); - GZIPInputStream gzs = new GZIPInputStream(connection.getInputStream()); - Scanner scanner = new Scanner(gzs).useDelimiter("\\A"); - return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); - } - - Response requestWithAccept(HTTPServer s, String accept) throws IOException { - String url = "http://localhost:" + s.server.getAddress().getPort(); - URLConnection connection = new URL(url).openConnection(); - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setRequestProperty("Accept", accept); - Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); - } - - Response requestWithCredentials(HTTPServer httpServer, String context, String suffix, String username, String password) throws IOException { - String url = "http://localhost:" + httpServer.server.getAddress().getPort() + context + suffix; - URLConnection connection = new URL(url).openConnection(); - connection.setDoOutput(true); - if (username != null && password != null) { - connection.setRequestProperty("Authorization", encodeCredentials(username, password)); - } - connection.connect(); - Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); - } - - Response requestWithSSL(String requestMethod, String username, String password, HTTPServer s, String context, String suffix) throws GeneralSecurityException, IOException { - String url = "https://localhost:" + s.server.getAddress().getPort() + context + suffix; - - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, TRUST_MANAGERS, new java.security.SecureRandom()); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - HttpsURLConnection.setDefaultHostnameVerifier(HOSTNAME_VERIFIER); - - URLConnection connection = new URL(url).openConnection(); - ((HttpURLConnection)connection).setRequestMethod(requestMethod); - - if (username != null && password != null) { - connection.setRequestProperty("Authorization", encodeCredentials(username, password)); - } - - connection.setDoOutput(true); - connection.connect(); - Scanner scanner = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return new Response(connection.getContentLength(), scanner.hasNext() ? scanner.next() : ""); - } - - Response request(HttpServer httpServer, String context, String suffix) throws IOException { - String url = "http://localhost:" + httpServer.getAddress().getPort() + context + suffix; - URLConnection connection = new URL(url).openConnection(); - connection.setDoOutput(true); - connection.connect(); - Scanner s = new Scanner(connection.getInputStream(), "UTF-8").useDelimiter("\\A"); - return new Response(connection.getContentLength(), s.hasNext() ? s.next() : ""); - } - - String encodeCredentials(String username, String password) { - // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, - try { - byte[] credentialsBytes = (username + ":" + password).getBytes("UTF-8"); - return "Basic " + DatatypeConverter.printBase64Binary(credentialsBytes); - } catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(e); - } - } - @Test(expected = IllegalArgumentException.class) public void testRefuseUsingUnbound() throws IOException { CollectorRegistry registry = new CollectorRegistry(); - HTTPServer s = new HTTPServer(HttpServer.create(), registry, true); - s.close(); + HTTPServer httpServer = new HTTPServer(HttpServer.create(), registry, true); + httpServer.close(); } @Test public void testSimpleRequest() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "").body; - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testBadParams() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "?x").body; - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics?x").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testSingleName() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "?name[]=a").body; - assertThat(response).contains("a 0.0"); - assertThat(response).doesNotContain("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics?name[]=a").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).doesNotContain("b 0.0"); + assertThat(body).doesNotContain("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testMultiName() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "?name[]=a&name[]=b").body; - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).doesNotContain("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testSampleNameFilter() throws IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() + .withRegistry(registry) + .withSampleNameFilter(new SampleNameFilter.Builder() + .nameMustNotStartWith("a") + .build()) + .build(); + + try { + String body = createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b").build().execute().getBody(); + assertThat(body).doesNotContain("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).doesNotContain("c 0.0"); + } finally { + httpServer.close(); + } + } + + @Test + public void testSampleNameFilterEmptyBody() throws IOException { + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withSampleNameFilter(new SampleNameFilter.Builder() .nameMustNotStartWith("a") + .nameMustNotStartWith("b") .build()) .build(); + try { - String response = request(s, "?name[]=a&name[]=b").body; - assertThat(response).doesNotContain("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + HttpResponse httpResponse = createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b").build().execute(); + assertThat(httpResponse.getBody()).isEmpty(); } finally { - s.close(); + httpServer.close(); } } @Test public void testDecoding() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "?n%61me[]=%61").body; - assertThat(response).contains("a 0.0"); - assertThat(response).doesNotContain("b 0.0"); - assertThat(response).doesNotContain("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics?n%61me[]=%61").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).doesNotContain("b 0.0"); + assertThat(body).doesNotContain("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testGzipCompression() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = requestWithCompression(s, "").body; - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics") + .withHeader("Accept", "gzip") + .withHeader("Accept", "deflate") + .build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testOpenMetrics() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = requestWithAccept(s, "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1").body; - assertThat(response).contains("# EOF"); + String body = createHttpRequestBuilder(httpServer, "/metrics") + .withHeader("Accept", "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1") + .build().execute().getBody(); + assertThat(body).contains("# EOF"); } finally { - s.close(); + httpServer.close(); } } @Test public void testHealth() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = request(s, "/-/healthy", "").body; - assertThat(response).contains("Exporter is Healthy"); + String body = createHttpRequestBuilder(httpServer, "/-/healthy").build().execute().getBody(); + assertThat(body).contains("Exporter is Healthy"); } finally { - s.close(); + httpServer.close(); } } @Test public void testHealthGzipCompression() throws IOException { - HTTPServer s = new HTTPServer(new InetSocketAddress(0), registry); + HTTPServer httpServer = new HTTPServer(new InetSocketAddress(0), registry); + try { - String response = requestWithCompression(s, "/-/healthy", "").body; - assertThat(response).contains("Exporter is Healthy"); + String body = createHttpRequestBuilder(httpServer, "/-/healthy") + .withHeader("Accept", "gzip") + .withHeader("Accept", "deflate") + .build().execute().getBody(); + assertThat(body).contains("Exporter is Healthy"); } finally { - s.close(); + httpServer.close(); } } @Test public void testBasicAuthSuccess() throws IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); + try { - String response = requestWithCredentials(s, "/metrics","?name[]=a&name[]=b", "user", "secret").body; - assertThat(response).contains("a 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b") + .withAuthorization("user", "secret") + .build().execute().getBody(); + assertThat(body).contains("a 0.0"); } finally { - s.close(); + httpServer.close(); } } @Test public void testBasicAuthCredentialsMissing() throws IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); + try { - request(s, "/metrics", "?name[]=a&name[]=b"); + createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b").build().execute().getBody(); Assert.fail("expected IOException with HTTP 401"); } catch (IOException e) { Assert.assertTrue(e.getMessage().contains("401")); } finally { - s.close(); + httpServer.close(); } } @Test public void testBasicAuthWrongCredentials() throws IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) - .withAuthenticator(createAuthenticator("/", "user", "wrong")) + .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); + try { - request(s, "/metrics", "?name[]=a&name[]=b"); + createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b") + .withAuthorization("user", "wrong") + .build().execute().getBody(); Assert.fail("expected IOException with HTTP 401"); } catch (IOException e) { Assert.assertTrue(e.getMessage().contains("401")); } finally { - s.close(); + httpServer.close(); } } @Test public void testHEADRequest() throws IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .build(); - try { - Response response = request("HEAD", s, "/metrics", "?name[]=a&name[]=b"); - Assert.assertNotNull(response); - Assert.assertTrue(response.contentLength == 74); - Assert.assertTrue("".equals(response.body)); + try { + HttpResponse httpResponse = createHttpRequestBuilder(httpServer, "/metrics?name[]=a&name[]=b") + .withMethod(HttpRequest.METHOD.HEAD) + .build().execute(); + Assert.assertNotNull(httpResponse); + Assert.assertNotNull(httpResponse.getHeaderAsLong("content-length")); + Assert.assertTrue(httpResponse.getHeaderAsLong("content-length") == 74); + assertThat(httpResponse.getBody()).isEmpty(); } finally { - s.close(); + httpServer.close(); } } @Test public void testHEADRequestWithSSL() throws GeneralSecurityException, IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withHttpsConfigurator(HTTPS_CONFIGURATOR) .build(); try { - Response response = requestWithSSL( - "HEAD", null, null, s, "/metrics", "?name[]=a&name[]=b"); - - Assert.assertNotNull(response); - Assert.assertTrue(response.contentLength == 74); - Assert.assertTrue("".equals(response.body)); + HttpResponse httpResponse = createHttpRequestBuilderWithSSL(httpServer, "/metrics?name[]=a&name[]=b") + .withMethod(HttpRequest.METHOD.HEAD) + .build().execute(); + Assert.assertNotNull(httpResponse); + Assert.assertNotNull(httpResponse.getHeaderAsLong("content-length")); + Assert.assertTrue(httpResponse.getHeaderAsLong("content-length") == 74); + assertThat(httpResponse.getBody()).isEmpty(); } finally { - s.close(); + httpServer.close(); } } @@ -436,10 +379,10 @@ public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOExceptio httpServer.start(); try { - String response = request(httpServer, "/metrics", null).body; - assertThat(response).contains("a 0.0"); - assertThat(response).contains("b 0.0"); - assertThat(response).contains("c 0.0"); + String body = createHttpRequestBuilder(httpServer, "/metrics").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); } finally { httpServer.stop(0); } @@ -447,59 +390,84 @@ public void testSimpleRequestHttpServerWithHTTPMetricHandler() throws IOExceptio @Test public void testHEADRequestWithSSLAndBasicAuthSuccess() throws GeneralSecurityException, IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withHttpsConfigurator(HTTPS_CONFIGURATOR) .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); try { - Response response = requestWithSSL( - "HEAD", "user", "secret", s, "/metrics", "?name[]=a&name[]=b"); - - Assert.assertNotNull(response); - Assert.assertTrue(response.contentLength == 74); - Assert.assertTrue("".equals(response.body)); + HttpResponse httpResponse = createHttpRequestBuilderWithSSL(httpServer, "/metrics?name[]=a&name[]=b") + .withMethod(HttpRequest.METHOD.HEAD) + .withAuthorization("user", "secret") + .build().execute(); + Assert.assertNotNull(httpResponse); + Assert.assertNotNull(httpResponse.getHeaderAsLong("content-length")); + Assert.assertTrue(httpResponse.getHeaderAsLong("content-length") == 74); + assertThat(httpResponse.getBody()).isEmpty(); } finally { - s.close(); + httpServer.close(); } } @Test public void testHEADRequestWithSSLAndBasicAuthCredentialsMissing() throws GeneralSecurityException, IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withHttpsConfigurator(HTTPS_CONFIGURATOR) .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); try { - Response response = requestWithSSL("HEAD", null, null, s, "/metrics", "?name[]=a&name[]=b"); + createHttpRequestBuilderWithSSL(httpServer, "/metrics?name[]=a&name[]=b") + .withMethod(HttpRequest.METHOD.HEAD) + .build().execute(); Assert.fail("expected IOException with HTTP 401"); } catch (IOException e) { Assert.assertTrue(e.getMessage().contains("401")); } finally { - s.close(); + httpServer.close(); } } @Test public void testHEADRequestWithSSLAndBasicAuthWrongCredentials() throws GeneralSecurityException, IOException { - HTTPServer s = new HTTPServer.Builder() + HTTPServer httpServer = new HTTPServer.Builder() .withRegistry(registry) .withHttpsConfigurator(HTTPS_CONFIGURATOR) .withAuthenticator(createAuthenticator("/", "user", "secret")) .build(); try { - Response response = requestWithSSL("HEAD", "user", "wrong", s, "/metrics", "?name[]=a&name[]=b"); + createHttpRequestBuilderWithSSL(httpServer, "/metrics?name[]=a&name[]=b") + .withMethod(HttpRequest.METHOD.HEAD) + .withAuthorization("user", "wrong") + .build().execute(); Assert.fail("expected IOException with HTTP 401"); } catch (IOException e) { Assert.assertTrue(e.getMessage().contains("401")); } finally { - s.close(); + httpServer.close(); } } + + /** + * Encodes authorization credentials + * + * @param username + * @param password + * @return String + */ + private final static String encodeCredentials(String username, String password) { + // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, + try { + byte[] credentialsBytes = (username + ":" + password).getBytes("UTF-8"); + return "Basic " + DatatypeConverter.printBase64Binary(credentialsBytes); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e); + } + } + /** * Create an SSLContext * @@ -511,7 +479,7 @@ public void testHEADRequestWithSSLAndBasicAuthWrongCredentials() throws GeneralS * @throws GeneralSecurityException * @throws IOException */ - public static SSLContext createSSLContext(String sslContextType, String keyStoreType, String keyStorePath, String keyStorePassword) + private final static SSLContext createSSLContext(String sslContextType, String keyStoreType, String keyStorePath, String keyStorePassword) throws GeneralSecurityException, IOException { SSLContext sslContext = null; FileInputStream fileInputStream = null; @@ -550,7 +518,25 @@ public static SSLContext createSSLContext(String sslContextType, String keyStore } /** + * Creates an Authenticator * + * @param realm + * @param validUsername + * @param validPassword + * @return Authenticator + */ + private final static Authenticator createAuthenticator(String realm, final String validUsername, final String validPassword) { + return new BasicAuthenticator(realm) { + @Override + public boolean checkCredentials(String username, String password) { + return validUsername.equals(username) && validPassword.equals(password); + } + }; + } + + /** + * Creates an HttpsConfiguration + * * @param sslContext * @return HttpsConfigurator */ From 61b3da7aa50c02e43685380b367c791c75ee4b8c Mon Sep 17 00:00:00 2001 From: Harold Dost Date: Wed, 22 Dec 2021 23:37:10 +0100 Subject: [PATCH 124/980] Patch for a number of CVEs Affecting Vert.x Web Patches for: * https://www.cve.org/CVERecord?id=CVE-2018-12537 * https://www.cve.org/CVERecord?id=CVE-2018-12540 * https://www.cve.org/CVERecord?id=CVE-2018-12541 * https://www.cve.org/CVERecord?id=CVE-2018-12542 Skips over: * https://www.cve.org/CVERecord?id=CVE-2018-12544 * https://www.cve.org/CVERecord?id=CVE-2019-17640 * https://www.cve.org/CVERecord?id=CVE-2020-35217 Also add a version for Vert.x 4 Fixes #705 Signed-off-by: Harold Dost --- pom.xml | 1 + simpleclient_vertx/pom.xml | 6 +- simpleclient_vertx4/pom.xml | 82 +++++++++++++++++ .../client/vertx/MetricsHandler.java | 91 +++++++++++++++++++ .../client/vertx/ExampleExporter.java | 33 +++++++ .../client/vertx/MetricsHandlerTest.java | 89 ++++++++++++++++++ 6 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 simpleclient_vertx4/pom.xml create mode 100644 simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java create mode 100644 simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java create mode 100644 simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java diff --git a/pom.xml b/pom.xml index 56f08c4c0..c21bc60aa 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,7 @@ simpleclient_jetty_jdk8 simpleclient_tracer simpleclient_vertx + simpleclient_vertx4 simpleclient_bom benchmarks integration_tests diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index ec6b34eff..41fa70f01 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -23,9 +23,9 @@ simpleclient_vertx bundle - Prometheus Java Simpleclient Vert.x + Prometheus Java Simpleclient Vert.x 3 - Vert.x Web Handler exporter for the simpleclient. + Vert.x 3 Web Handler exporter for the simpleclient. @@ -62,7 +62,7 @@ io.vertx vertx-web - 3.3.2 + 3.9.12 provided diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml new file mode 100644 index 000000000..3d41f8a08 --- /dev/null +++ b/simpleclient_vertx4/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + io.prometheus + parent + 0.14.2-SNAPSHOT + + + simpleclient_vertx4 + bundle + + Prometheus Java Simpleclient Vert.x 4 + + Vert.x 4 Web Handler exporter for the simpleclient. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + pmlopes + Paulo Lopes + paulo@mlopes.net + + + + + UTF-8 + + + + + io.prometheus + simpleclient + 0.14.2-SNAPSHOT + + + io.prometheus + simpleclient_common + 0.14.2-SNAPSHOT + + + io.vertx + vertx-web + 4.2.3 + provided + + + + junit + junit + 4.13.2 + test + + + org.assertj + assertj-core + 2.6.0 + test + + + diff --git a/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java b/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java new file mode 100644 index 000000000..5f1cbfafd --- /dev/null +++ b/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java @@ -0,0 +1,91 @@ +package io.prometheus.client.vertx; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.exporter.common.TextFormat; +import io.vertx.core.Handler; +import io.vertx.core.buffer.Buffer; +import io.vertx.core.http.HttpServerRequest; +import io.vertx.ext.web.RoutingContext; + +import java.io.IOException; +import java.io.Writer; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Metrics Handler for Vert.x Web. + *

+ * This handler will allow the usage of Prometheus Client Java API with + * Vert.x applications and expose a API compatible handler for the collector. + *

+ * Usage: + *

+ * router.route("/metrics").handler(new MetricsHandler()); + */ +public class MetricsHandler implements Handler { + + /** + * Wrap a Vert.x Buffer as a Writer so it can be used with + * TextFormat writer + */ + private static class BufferWriter extends Writer { + + private final Buffer buffer = Buffer.buffer(); + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + buffer.appendString(new String(cbuf, off, len)); + } + + @Override + public void flush() throws IOException { + // NO-OP + } + + @Override + public void close() throws IOException { + // NO-OP + } + + Buffer getBuffer() { + return buffer; + } + } + + private CollectorRegistry registry; + + /** + * Construct a MetricsHandler for the default registry. + */ + public MetricsHandler() { + this(CollectorRegistry.defaultRegistry); + } + + /** + * Construct a MetricsHandler for the given registry. + */ + public MetricsHandler(CollectorRegistry registry) { + this.registry = registry; + } + + @Override + public void handle(RoutingContext ctx) { + try { + final BufferWriter writer = new BufferWriter(); + String contentType = TextFormat.chooseContentType(ctx.request().headers().get("Accept")); + + TextFormat.writeFormat(contentType, writer, registry.filteredMetricFamilySamples(parse(ctx.request()))); + ctx.response() + .setStatusCode(200) + .putHeader("Content-Type", contentType) + .end(writer.getBuffer()); + } catch (IOException e) { + ctx.fail(e); + } + } + + private Set parse(HttpServerRequest request) { + return new HashSet(request.params().getAll("name[]")); + } +} diff --git a/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java b/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java new file mode 100644 index 000000000..d39f23a17 --- /dev/null +++ b/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java @@ -0,0 +1,33 @@ +package io.prometheus.client.vertx; + +import io.prometheus.client.Counter; +import io.prometheus.client.Gauge; +import io.prometheus.client.Histogram; +import io.prometheus.client.Summary; +import io.prometheus.client.vertx.MetricsHandler; +import io.vertx.core.Vertx; +import io.vertx.ext.web.Router; + +public class ExampleExporter { + + static final Gauge g = Gauge.build().name("gauge").help("blah").register(); + static final Counter c = Counter.build().name("counter").help("meh").register(); + static final Summary s = Summary.build().name("summary").help("meh").register(); + static final Histogram h = Histogram.build().name("histogram").help("meh").register(); + static final Gauge l = Gauge.build().name("labels").help("blah").labelNames("l").register(); + + public static void main(String[] args) throws Exception { + final Vertx vertx = Vertx.vertx(); + final Router router = Router.router(vertx); + + router.route("/metrics").handler(new MetricsHandler()); + + vertx.createHttpServer().requestHandler(router).listen(1234); + + g.set(1); + c.inc(2); + s.observe(3); + h.observe(4); + l.labels("foo").inc(5); + } +} diff --git a/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java b/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java new file mode 100644 index 000000000..6e71b55c6 --- /dev/null +++ b/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java @@ -0,0 +1,89 @@ +package io.prometheus.client.vertx; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Gauge; +import io.vertx.core.Vertx; +import io.vertx.ext.web.Router; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URL; +import java.util.Scanner; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MetricsHandlerTest { + + private static Vertx vertx; + private static Integer port; + private static CollectorRegistry registry; + + @BeforeClass + public static void setUp() throws Throwable { + Semaphore s = new Semaphore(1); + + + vertx = Vertx.vertx(); + final Vertx vertx = Vertx.vertx(); + final Router router = Router.router(vertx); + + registry = new CollectorRegistry(); + router.route("/metrics").handler(new MetricsHandler(registry)); + + router.route("/test").handler(routingContext -> { + routingContext.response().putHeader("content-type", "text").end("Hello World!"); + }); + + ServerSocket socket = new ServerSocket(0); + port = socket.getLocalPort(); + socket.close(); + + s.acquire(); + vertx.createHttpServer().requestHandler(router).listen(port, + event -> s.release() + ); + + s.tryAcquire(10, TimeUnit.SECONDS); + + Gauge.build("a", "a help").register(registry); + Gauge.build("b", "b help").register(registry); + Gauge.build("c", "c help").register(registry); + } + + @AfterClass + public static void tearDown() { + vertx.close(); + } + + @Test + public void metricsRequest_shouldReturnMetrics() throws IOException { + String out = makeRequest("/metrics"); + + assertThat(out).contains("a 0.0"); + assertThat(out).contains("b 0.0"); + assertThat(out).contains("c 0.0"); + } + + @Test + public void metricsRequest_shouldAllowFilteringMetrics() throws IOException { + String out = makeRequest("/metrics?name[]=b&name[]=c"); + + assertThat(out).doesNotContain("a 0.0"); + assertThat(out).contains("b 0.0"); + assertThat(out).contains("c 0.0"); + } + + + private String makeRequest(String url) throws IOException { + Scanner scanner = new Scanner(new URL("http://localhost:" + port + url).openStream(), "UTF-8") + .useDelimiter("\\A"); + String out = scanner.next(); + scanner.close(); + return out; + } +} From 276785d453eb3e3327f8390c64c3dfb95bee9c14 Mon Sep 17 00:00:00 2001 From: Shoothzj Date: Tue, 4 Jan 2022 16:52:03 +0800 Subject: [PATCH 125/980] Bump log4j version to 2.17.1 to solve CVE-2021-44832 Signed-off-by: Shoothzj --- integration_tests/it_log4j2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 67f9c5c1f..138d2d6a4 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -12,7 +12,7 @@ Integration Tests - log4j2 - 2.17.0 + 2.17.1 From c83877ab01539a34f172d72405db0f1b9b29cc60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 4 Jan 2022 23:20:44 +0100 Subject: [PATCH 126/980] Bump log4j to 2.17.1 --- simpleclient_log4j2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 28cc59b8c..78a4f06ea 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -41,7 +41,7 @@ org.apache.logging.log4j log4j-core - 2.17.0 + 2.17.1 provided From 787eef37843e3ea0972d064eb567d0639a8aba5f Mon Sep 17 00:00:00 2001 From: Jens Date: Tue, 18 Jan 2022 22:24:29 +0100 Subject: [PATCH 127/980] Improve CKMSQuantiles and address memory leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CKMSQuantiles is copied from an implementation of 2012, where it states that a ‘HACK’ was done, admitting a space leak. This leak has been noticed several times (#422, #550, #654). By correctly applying the algorithm from the paper we fix the leak. I have added unit-tests to show that the behaviour is correct. I have also added a Benchmark in the benchmark module showing the difference with the old and current implementation. According to my benchmarks, is in the new implementation a `get` of a quantile that has ‘seen’ 1 million elements 440 times faster. Inserting 1 million elements is 3.5 times faster. While going through the CKMS paper and the Java implementation I have added remarks and snippets from the paper, to clarify why certain choices are made. Signed-off-by: Jens Fix assertion in HistogramTest Median of 1..11 = 6 Signed-off-by: Jens Address PR remarks Signed-off-by: Jens --- benchmarks/pom.xml | 4 +- .../client/CKMSQuantileBenchmark.java | 108 ++++++ simpleclient/pom.xml | 6 + .../io/prometheus/client/CKMSQuantiles.java | 358 +++++++++++++----- .../prometheus/client/CKMSQuantilesTest.java | 196 ++++++++++ .../client/exporter/common/ExemplarTest.java | 12 +- 6 files changed, 576 insertions(+), 108 deletions(-) create mode 100644 benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java create mode 100644 simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index e027baf8d..4194ddf4e 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -27,12 +27,12 @@ org.openjdk.jmh jmh-core - 1.3.2 + 1.34 org.openjdk.jmh jmh-generator-annprocess - 1.3.2 + 1.34 javax.annotation diff --git a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java new file mode 100644 index 000000000..0f36212b5 --- /dev/null +++ b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java @@ -0,0 +1,108 @@ +package io.prometheus.client; + +import io.prometheus.client.CKMSQuantiles.Quantile; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class CKMSQuantileBenchmark { + + @State(Scope.Benchmark) + public static class EmptyBenchmarkState { + @Param({"10000", "100000", "1000000"}) + public int value; + + CKMSQuantiles ckmsQuantiles; + + List quantiles; + Random rand = new Random(0); + + long[] shuffle; + + @Setup(Level.Trial) + public void setup() { + quantiles = new ArrayList(); + quantiles.add(new Quantile(0.50, 0.050)); + quantiles.add(new Quantile(0.90, 0.010)); + quantiles.add(new Quantile(0.95, 0.005)); + quantiles.add(new Quantile(0.99, 0.001)); + + + shuffle = new long[value]; + for (int i = 0; i < shuffle.length; i++) { + shuffle[i] = i; + } + Collections.shuffle(Arrays.asList(shuffle), rand); + + } + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void ckmsQuantileInsertBenchmark(Blackhole blackhole, EmptyBenchmarkState state) { + CKMSQuantiles q = new CKMSQuantiles(state.quantiles.toArray(new Quantile[]{})); + for (long l : state.shuffle) { + q.insert(l); + } + } + + @State(Scope.Benchmark) + public static class PrefilledBenchmarkState { + public int value = 1000000; + + CKMSQuantiles ckmsQuantiles; + + List quantiles; + Random rand = new Random(0); + + long[] shuffle; + + @Setup(Level.Trial) + public void setup() { + quantiles = new ArrayList(); + quantiles.add(new Quantile(0.50, 0.050)); + quantiles.add(new Quantile(0.90, 0.010)); + quantiles.add(new Quantile(0.95, 0.005)); + quantiles.add(new Quantile(0.99, 0.001)); + + + shuffle = new long[value]; + for (int i = 0; i < shuffle.length; i++) { + shuffle[i] = i; + } + Collections.shuffle(Arrays.asList(shuffle), rand); + ckmsQuantiles = new CKMSQuantiles(quantiles.toArray(new Quantile[]{})); + for (long l : shuffle) { + ckmsQuantiles.insert(l); + } + + } + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void ckmsQuantileGetBenchmark(Blackhole blackhole, PrefilledBenchmarkState state) { + blackhole.consume(state.ckmsQuantiles.get(0.95)); + } + + public static void main(String[] args) throws RunnerException { + + Options opt = new OptionsBuilder() + .include(CKMSQuantileBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .threads(1) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index d1a751f5e..b2d8f9ac7 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -54,5 +54,11 @@ 4.13.2 test + + org.apache.commons + commons-math3 + 3.2 + test + diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index 1ffb65382..7fe6cff3b 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -2,6 +2,7 @@ // Copied from https://raw.githubusercontent.com/Netflix/ocelli/master/ocelli-core/src/main/java/netflix/ocelli/stats/CKMSQuantiles.java // Revision d0357b8bf5c17a173ce94d6b26823775b3f999f6 from Jan 21, 2015. +// Which was copied from https://github.com/umbrant/QuantileEstimation/blob/34ea6889570827a79b3f8294812d9390af23b734/src/main/java/com/umbrant/quantile/QuantileEstimationCKMS.java // // This is the original code except for the following modifications: // @@ -35,129 +36,202 @@ * Implementation of the Cormode, Korn, Muthukrishnan, and Srivastava algorithm * for streaming calculation of targeted high-percentile epsilon-approximate * quantiles. - * + *

* This is a generalization of the earlier work by Greenwald and Khanna (GK), * which essentially allows different error bounds on the targeted quantiles, * which allows for far more efficient calculation of high-percentiles. - * - * + *

+ *

* See: Cormode, Korn, Muthukrishnan, and Srivastava * "Effective Computation of Biased Quantiles over Data Streams" in ICDE 2005 - * + *

* Greenwald and Khanna, * "Space-efficient online computation of quantile summaries" in SIGMOD 2001 - * + *

+ *

+ * The Approximate Quantiles Algorithm looks like this (Figure 1) + *

+ * Main()
+ *    foreach item v do
+ *      Insert(v);
+ *      if (Compress Condition()) then
+ *          Compress();
+ *
+ * Insert(v):
+ *    r_0:=0;
+ *    for i:=1 to s do
+ *        ri := ri−1 + gi−1;
+ *        if (v < vi) break;
+ *        add (v,1,f(ri,n)−1) to S before vi;
+ *    n++;
+ *
+ * Compress():
+ *    for i := (s−1) downto 1 do
+ *        if (gi + gi+1 + ∆i+1 ≤ f(ri, n)) then
+ *            merge ti and ti+1;
+ *
+ * Output(φ):
+ *    r0:=0;
+ *    for i := 1 to s do
+ *        ri:=ri−1+gi−1;
+ *        if(ri +gi +∆i >φn+f(φn,n)/2)
+ *            print(vi−1); break;
+ * 
*/ -class CKMSQuantiles { +final class CKMSQuantiles { /** * Total number of items in stream. + * Increases on every insertBatch(). */ private int count = 0; /** - * Used for tracking incremental compression. + * Current list of sampled items, maintained in sorted order with error + * bounds. + *

+ * Note: Any algorithm that guarantees to find biased + * quantiles φ with error at most φεn in rank must store + * Ω(1 min{klog1/φ,log(εn)}) items. + *

+ */ + final LinkedList samples; + + /** + * Used for compress condition. + * This is a different index than the bufferCount, + * because flushing is also done on `quantile.get()`, + * but we need to compress, regardless of reaching the bufferCount, to limit space usage. */ private int compressIdx = 0; /** - * Current list of sampled items, maintained in sorted order with error - * bounds. + * The amount of values observed when to compress. */ - protected LinkedList sample; + private final int insertThreshold; /** * Buffers incoming items to be inserted in batch. */ - private double[] buffer = new double[500]; + private final double[] buffer; - private int bufferCount = 0; + /** + * Tracks the current index of the buffer. Increases on insert(). + */ + private int bufferIdx = 0; /** * Array of Quantiles that we care about, along with desired error. */ - private final Quantile quantiles[]; + private final Quantile[] quantiles; - public CKMSQuantiles(Quantile[] quantiles) { - this.quantiles = quantiles; - this.sample = new LinkedList(); + /** + * Set up the CKMS Quantiles. Can have 0 or more targeted quantiles defined. + * @param quantiles The targeted quantiles, can be empty. + */ + CKMSQuantiles(Quantile[] quantiles) { + // hard-coded epsilon of 0.1% to determine the batch size, and default epsilon in case of empty quantiles + double pointOnePercent = 0.001; + if (quantiles.length == 0) { // we need at least one for this algorithm to work + this.quantiles = new Quantile[1]; + this.quantiles[0] = new Quantile(0.5, pointOnePercent / 2); + } else { + this.quantiles = quantiles; + } + + // section 5.1 Methods - Batch. + // This is hardcoded to 500, which corresponds to an epsilon of 0.1%. + this.insertThreshold = 500; + + // create a buffer with size equal to threshold + this.buffer = new double[insertThreshold]; + + // Initialize empty items + this.samples = new LinkedList(); } /** * Add a new value from the stream. - * - * @param value + * + * @param value the observed value */ public void insert(double value) { - buffer[bufferCount] = value; - bufferCount++; + buffer[bufferIdx] = value; + bufferIdx++; + + if (bufferIdx == buffer.length) { + insertBatch(); // this is the batch insert variation + } - if (bufferCount == buffer.length) { - insertBatch(); + // The Compress_Condition() + compressIdx = (compressIdx + 1) % insertThreshold; + if (compressIdx == 0) { compress(); } } /** * Get the estimated value at the specified quantile. - * - * @param q - * Queried quantile, e.g. 0.50 or 0.99. + * + * @param q Queried quantile, e.g. 0.50 or 0.99. * @return Estimated value at that quantile. */ public double get(double q) { - // clear the buffer + // clear the buffer. in case of low value insertions, the samples can become stale. + // On every get, make sure we get the latest values in. insertBatch(); - compress(); - if (sample.size() == 0) { + if (samples.size() == 0) { return Double.NaN; } - int rankMin = 0; - int desired = (int) (q * count); + // Straightforward implementation of Output(q). + // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j + int currentRank = 0; + double desired = q * count; - ListIterator it = sample.listIterator(); + ListIterator it = samples.listIterator(); Item prev, cur; cur = it.next(); while (it.hasNext()) { prev = cur; cur = it.next(); - rankMin += prev.g; + currentRank += prev.g; - if (rankMin + cur.g + cur.delta > desired + if (currentRank + cur.g + cur.delta > desired + (allowableError(desired) / 2)) { return prev.value; } } // edge case of wanting max value - return sample.getLast().value; + return samples.getLast().value; } /** * Specifies the allowable error for this rank, depending on which quantiles * are being targeted. - * + *

* This is the f(r_i, n) function from the CKMS paper. It's basically how * wide the range of this rank can be. - * - * @param rank - * the index in the list of samples + *

+ * Define invariant function f (ri , n) as + * (i) f_j(r_i,n) = 2ε_j r_i / φ_j for φ_j n ≤ r_i ≤ n; + * (ii) f_j(r_i,n) = 2ε_j(n−r_i) / (1−φ_j) for 0 ≤ r_i ≤ φ_j n + *

+ * and take f(ri,n) = max{min_j ⌊f_j(r_i,n)⌋,1}. + * As before we ensure that for all i, g_i + ∆_i ≤ f(r_i, n). + * + * @param rank the index in the list of samples */ - private double allowableError(int rank) { - // NOTE: according to CKMS, this should be count, not size, but this - // leads - // to error larger than the error bounds. Leaving it like this is - // essentially a HACK, and blows up memory, but does "work". - // int size = count; - int size = sample.size(); - double minError = size + 1; + private double allowableError(double rank /* r_i */) { + int n = count; + double minError = count; for (Quantile q : quantiles) { double error; - if (rank <= q.quantile * size) { - error = q.u * (size - rank); + if (rank <= q.quantile * n) { + error = q.u * (n - rank); } else { error = q.v * rank; } @@ -165,103 +239,155 @@ private double allowableError(int rank) { minError = error; } } - - return minError; + return Math.max(minError, 1); } - private boolean insertBatch() { - if (bufferCount == 0) { - return false; + /** + * To insert a new item, v, we find i such that vi < v ≤ vi+1, + * we compute ri and insert the tuple (v,g=1,∆=f(ri,n)−1). + * + * We also ensure that min and max are kept exactly, so when v < v1, + * we insert the tuple (v,g = 1,∆ = 0) before v1. Similarly, when v > vs, + * we insert (v,g = 1,∆ = 0) after vs. + */ + private void insertBatch() { + if (bufferIdx == 0) { + return; } + // Has to be sorted: O(buffer) + // Since the buffer is treated as a circular buffer, we sort till the bufferIdx to prevent insertion of duplicate / already inserted values. + Arrays.sort(buffer, 0, bufferIdx); - Arrays.sort(buffer, 0, bufferCount); - - // Base case: no samples + // Base case: no samples yet int start = 0; - if (sample.size() == 0) { - Item newItem = new Item(buffer[0], 1, 0); - sample.add(newItem); + if (samples.size() == 0) { + Item newItem = new Item(buffer[0], 0); + samples.add(newItem); start++; count++; } - ListIterator it = sample.listIterator(); + // To insert a new item, v, we find i such that vi < v ≤ vi+1, + ListIterator it = samples.listIterator(); Item item = it.next(); - for (int i = start; i < bufferCount; i++) { + // Keep track of the current rank by adding the g of each item. See also discussion in https://issues.apache.org/jira/browse/HBASE-14324 + // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j + int currentRank = item.g; + + for (int i = start; i < bufferIdx; i++) { + // item to be inserted double v = buffer[i]; - while (it.nextIndex() < sample.size() && item.value < v) { + // find the item in the samples that is bigger than our v. + while (it.hasNext() && item.value < v) { item = it.next(); + currentRank += item.g; } // If we found that bigger item, back up so we insert ourselves // before it if (item.value > v) { + currentRank -= item.g; it.previous(); } // We use different indexes for the edge comparisons, because of the - // above - // if statement that adjusts the iterator + // above if statement that adjusts the iterator int delta; - if (it.previousIndex() == 0 || it.nextIndex() == sample.size()) { + if (it.previousIndex() == 0 || it.nextIndex() == samples.size()) { delta = 0; - } - else { - delta = ((int) Math.floor(allowableError(it.nextIndex()))) - 1; + } else { + delta = ((int) Math.floor(allowableError(currentRank))) - 1; } - Item newItem = new Item(v, 1, delta); + Item newItem = new Item(v, delta); it.add(newItem); count++; item = newItem; } - bufferCount = 0; - return true; + // reset buffered items to 0. + bufferIdx = 0; } /** * Try to remove extraneous items from the set of sampled items. This checks * if an item is unnecessary based on the desired error bounds, and merges * it with the adjacent item if it is. + *

+ * Compress. Periodically, the algorithm scans the data + * structure and merges adjacent nodes when this does not + * violate the invariant. That is, remove nodes (vi, gi, ∆i) + * and (vi+1 , gi+1 , ∆i+1 ), and replace with (vi+1 , (gi + + * gi+1 ), ∆i+1 ) provided that (gi + gi+1 + ∆i+1 ) ≤ f (ri , n). + * This also maintains the semantics of g and ∆ being the + * difference in rank between v_i and v_{i-1} , and the difference + * between the highest and lowest possible ranks of vi, respectively. */ private void compress() { - if (sample.size() < 2) { + // If there are 0,1, or 2 samples then there's nothing to compress. + if (samples.size() < 3) { return; } - ListIterator it = sample.listIterator(); - int removed = 0; + ListIterator it = samples.listIterator(); - Item prev = null; + Item prev; Item next = it.next(); + // Counter for the rank in the stream of all observed values. + // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j + int currentRank = next.g; + while (it.hasNext()) { prev = next; next = it.next(); - - if (prev.g + next.g + next.delta <= allowableError(it.previousIndex())) { + currentRank += next.g; + if (prev.g + next.g + next.delta <= allowableError(currentRank)) { next.g += prev.g; // Remove prev. it.remove() kills the last thing returned. - it.previous(); - it.previous(); - it.remove(); - // it.next() is now equal to next, skip it back forward again - it.next(); - removed++; + it.previous(); // brings pointer back to 'next' + it.previous(); // brings pointer back to 'prev' + it.remove(); // remove prev + // it.next() is now equal to next, + it.next(); // set pointer to 'next' } } } - private class Item { - public final double value; - public int g; - public final int delta; - - public Item(double value, int lower_delta, int delta) { + /** + * As in GK, the data structure at time n, S(n), consists + * of a sequence of s tuples ⟨ti = (vi, gi, ∆i)⟩, where each vi + * is a sampled item from the data stream and two additional + * values are kept: (1) g_i is the difference between the lowest + * possible rank of item i and the lowest possible rank of item + * i − 1; and (2) ∆_i is the difference between the greatest + * possible rank of item i and the lowest possible rank of item + * i. + */ + private static class Item { + /** + * vi + * is a sampled item from the data stream and two additional + * values are kept + */ + final double value; + /** + * g_i is the difference between the lowest + * possible rank of item i and the lowest possible rank of item + * i − 1. + * note: Always starts with 1, changes when merging Items. + */ + int g = 1; + /** + * ∆i is the difference between the greatest + * possible rank of item i and the lowest possible rank of item + * i. + */ + final int delta; + + Item(double value, int delta) { this.value = value; - this.g = lower_delta; this.delta = delta; } @@ -271,22 +397,54 @@ public String toString() { } } - public static class Quantile { - public final double quantile; - public final double error; - public final double u; - public final double v; + /** + * + */ + static class Quantile { + /** + * 0 < φ < 1 + */ + final double quantile; + /** + * Allowed error 0 < ε < 1 + */ + final double epsilon; + /** + * Helper value to calculate the targeted quantiles invariant as per Definition 5 (ii) + */ + final double u; + /** + * Helper value to calculate the targeted quantiles invariant as per Definition 5 (i) + */ + final double v; + + /** + * Targeted quantile: T = {(φ_j , ε_j )} + * Rather than requesting the same ε for all quantiles (the uniform case) + * or ε scaled by φ (the biased case), one might specify an arbitrary set + * of quantiles and the desired errors of ε for each in the form (φj , εj ). + * For example, input to the targeted quantiles problem might be {(0.5, 0.1), (0.2, 0.05), (0.9, 0.01)}, + * meaning that the median should be returned with 10% error, the 20th percentile with 5% error, + * and the 90th percentile with 1%. + * + * @param quantile the quantile between 0 and 1 + * @param epsilon the desired error for this quantile, between 0 and 1. + */ + Quantile(double quantile, double epsilon) { + if (quantile < 0 || quantile > 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); + if (epsilon < 0 || epsilon > 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); - public Quantile(double quantile, double error) { this.quantile = quantile; - this.error = error; - u = 2.0 * error / (1.0 - quantile); - v = 2.0 * error / quantile; + this.epsilon = epsilon; + // f_j(r_i,n) = 2ε_j(n−r_i) / (1−φ_j) for 0 ≤ r_i ≤ φ_j n + u = 2.0 * epsilon / (1.0 - quantile); + // f_j(r_i,n) = 2ε_j r_i / φ_j for φ_j n ≤ r_i ≤ n; + v = 2.0 * epsilon / quantile; } @Override public String toString() { - return String.format("Q{q=%.3f, eps=%.3f}", quantile, error); + return String.format("Q{q=%.3f, eps=%.3f}", quantile, epsilon); } } diff --git a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java new file mode 100644 index 000000000..63a281007 --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java @@ -0,0 +1,196 @@ +package io.prometheus.client; + +import io.prometheus.client.CKMSQuantiles.Quantile; +import org.apache.commons.math3.distribution.NormalDistribution; +import org.apache.commons.math3.random.JDKRandomGenerator; +import org.apache.commons.math3.random.RandomGenerator; +import org.junit.Test; + +import java.util.*; + +import static org.junit.Assert.*; + +public class CKMSQuantilesTest { + + @Test + public void testGetOnEmptyValues() { + List quantiles = new ArrayList(); + quantiles.add(new Quantile(0.50, 0.01)); + quantiles.add(new Quantile(0.90, 0.01)); + quantiles.add(new Quantile(0.95, 0.01)); + quantiles.add(new Quantile(0.99, 0.01)); + + CKMSQuantiles ckms = new CKMSQuantiles( + quantiles.toArray(new Quantile[]{})); + assertEquals(Double.NaN, ckms.get(0), 0); + } + + @Test + public void testGetWhenNoQuantilesAreDefined() { + CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); + assertEquals(Double.NaN, ckms.get(0), 0); + } + + @Test + public void testInsertWhenNoQuantilesAreDefined() { + CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); + ckms.insert(1.0); + ckms.insert(2.0); + ckms.insert(3.0); + assertEquals(1.0, ckms.get(0), 0); + assertEquals(2.0, ckms.get(0.5), 0); + assertEquals(3.0, ckms.get(1), 0); + } + + @Test + public void testCompressWhenBufferSize500Reached() { + CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); + List input = makeSequence(1, 499); + + for (double v : input) { + ckms.insert(v); + } + assertEquals("No compress should be triggered", 0, ckms.samples.size()); + + ckms.insert(500); + assertEquals(500, ckms.samples.size()); + } + + @Test + public void testGet() { + List quantiles = new ArrayList(); + quantiles.add(new Quantile(0.50, 0.01)); + quantiles.add(new Quantile(0.90, 0.01)); + quantiles.add(new Quantile(0.95, 0.01)); + quantiles.add(new Quantile(0.99, 0.01)); + + List input = makeSequence(1, 100); + CKMSQuantiles ckms = new CKMSQuantiles( + quantiles.toArray(new Quantile[]{})); + for (double v : input) { + ckms.insert(v); + } + assertEquals(10.0, ckms.get(0.1), 1); + assertEquals(50.0, ckms.get(0.5), 1); + assertEquals(90.0, ckms.get(0.9), 1); + assertEquals(95.0, ckms.get(0.95), 1); + assertEquals(99.0, ckms.get(0.99), 1); + } + + @Test + public void testGetWithAMillionElements() { + List quantiles = new ArrayList(); + quantiles.add(new Quantile(0.0, 0.01)); + quantiles.add(new Quantile(0.10, 0.01)); + quantiles.add(new Quantile(0.90, 0.001)); + quantiles.add(new Quantile(0.95, 0.02)); + quantiles.add(new Quantile(0.99, 0.001)); + + final int elemCount = 1000000; + double[] shuffle = new double[elemCount]; + for (int i = 0; i < shuffle.length; i++) { + shuffle[i] = i + 1; + } + Random rand = new Random(0); + + Collections.shuffle(Arrays.asList(shuffle), rand); + + CKMSQuantiles ckms = new CKMSQuantiles( + quantiles.toArray(new Quantile[]{})); + + for (double v : shuffle) { + ckms.insert(v); + } + // given the linear distribution, we set the delta equal to the εn value for this quantile + assertEquals(0.1 * elemCount, ckms.get(0.1), 0.01 * elemCount); + assertEquals(0.9 * elemCount, ckms.get(0.9), 0.001 * elemCount); + assertEquals(0.95 * elemCount, ckms.get(0.95), 0.02 * elemCount); + assertEquals(0.99 * elemCount, ckms.get(0.99), 0.001 * elemCount); + + assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000); + } + + + @Test + public void testGetGaussian() { + RandomGenerator rand = new JDKRandomGenerator(); + rand.setSeed(0); + + double mean = 0.0; + double stddev = 1.0; + NormalDistribution normalDistribution = new NormalDistribution(rand, mean, stddev, NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY); + + List quantiles = new ArrayList(); + quantiles.add(new Quantile(0.10, 0.001)); + quantiles.add(new Quantile(0.50, 0.01)); + quantiles.add(new Quantile(0.90, 0.001)); + quantiles.add(new Quantile(0.95, 0.001)); + quantiles.add(new Quantile(0.99, 0.001)); + + CKMSQuantiles ckms = new CKMSQuantiles( + quantiles.toArray(new Quantile[]{})); + + final int elemCount = 1000000; + double[] shuffle = normalDistribution.sample(elemCount); + + // insert a million samples + for (double v : shuffle) { + ckms.insert(v); + } + + // give the actual values for the quantiles we test + double p10 = normalDistribution.inverseCumulativeProbability(0.1); + double p90 = normalDistribution.inverseCumulativeProbability(0.9); + double p95 = normalDistribution.inverseCumulativeProbability(0.95); + double p99 = normalDistribution.inverseCumulativeProbability(0.99); + + //ε-approximate quantiles relaxes the requirement + //to finding an item with rank between (φ−ε)n and (φ+ε)n. + assertEquals(p10, ckms.get(0.1), errorBoundsNormalDistribution(0.1, 0.001, normalDistribution)); + assertEquals(mean, ckms.get(0.5), errorBoundsNormalDistribution(0.5, 0.01, normalDistribution)); + assertEquals(p90, ckms.get(0.9), errorBoundsNormalDistribution(0.9, 0.001, normalDistribution)); + assertEquals(p95, ckms.get(0.95), errorBoundsNormalDistribution(0.95, 0.001, normalDistribution)); + assertEquals(p99, ckms.get(0.99), errorBoundsNormalDistribution(0.99, 0.001, normalDistribution)); + + assertTrue("sample size should be below 1000", ckms.samples.size() < 1000); + } + + @Test + public void checkBounds() { + try { + new Quantile(-1, 0); + } catch (IllegalArgumentException e) { + assertEquals("Quantile must be between 0 and 1", e.getMessage()); + } catch (Exception e) { + fail("Wrong exception thrown" + e); + } + + try { + new Quantile(0.95, 2); + } catch (IllegalArgumentException e) { + assertEquals("Epsilon must be between 0 and 1", e.getMessage()); + } catch (Exception e) { + fail("Wrong exception thrown" + e); + } + } + + double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) { + //(φ+ε)n + double upperBound = nd.inverseCumulativeProbability(p + epsilon); + //(φ−ε)n + double lowerBound = nd.inverseCumulativeProbability(p - epsilon); + // subtract and divide by 2, assuming that the increase is linear in this small epsilon. + return Math.abs(upperBound - lowerBound) / 2; + } + + /** + * In Java 8 we could use IntStream + */ + List makeSequence(int begin, int end) { + List ret = new ArrayList(end - begin + 1); + for (int i = begin; i <= end; i++) { + ret.add((double) i); + } + return ret; + } +} diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java index 469446cda..2ab2821f9 100644 --- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java +++ b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java @@ -310,15 +310,15 @@ public void testSummaryNoLabels() throws IOException { .help("help") .quantile(0.5, 0.01) .register(registry); - for (int i=1; i<=11; i++) { // median is 5 + for (int i=1; i<=11; i++) { // median is 6 noLabelsDefaultExemplar.observe(i); } // Summaries don't have Exemplars according to the OpenMetrics spec. - assertOpenMetrics100Format("no_labels{quantile=\"0.5\"} 5.0\n"); + assertOpenMetrics100Format("no_labels{quantile=\"0.5\"} 6.0\n"); assertOpenMetrics100Format("no_labels_count 11.0\n"); assertOpenMetrics100Format("no_labels_sum 66.0\n"); - assert004Format("no_labels{quantile=\"0.5\",} 5.0\n"); + assert004Format("no_labels{quantile=\"0.5\",} 6.0\n"); assert004Format("no_labels_count 11.0\n"); assert004Format("no_labels_sum 66.0\n"); } @@ -331,15 +331,15 @@ public void testSummaryLabels() throws IOException { .labelNames("label") .quantile(0.5, 0.01) .register(registry); - for (int i=1; i<=11; i++) { // median is 5 + for (int i=1; i<=11; i++) { // median is 6 labelsNoExemplar.labels("test").observe(i); } // Summaries don't have Exemplars according to the OpenMetrics spec. - assertOpenMetrics100Format("labels{label=\"test\",quantile=\"0.5\"} 5.0\n"); + assertOpenMetrics100Format("labels{label=\"test\",quantile=\"0.5\"} 6.0\n"); assertOpenMetrics100Format("labels_count{label=\"test\"} 11.0\n"); assertOpenMetrics100Format("labels_sum{label=\"test\"} 66.0\n"); - assert004Format("labels{label=\"test\",quantile=\"0.5\",} 5.0\n"); + assert004Format("labels{label=\"test\",quantile=\"0.5\",} 6.0\n"); assert004Format("labels_count{label=\"test\",} 11.0\n"); assert004Format("labels_sum{label=\"test\",} 66.0\n"); } From fd9da3e7f756dc9c119108ebf6dbe88cda9a740c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 30 Jan 2022 21:38:06 +0100 Subject: [PATCH 128/980] CKMS Quantiles: Add tests, refactor, fix tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../io/prometheus/client/CKMSQuantiles.java | 463 ++++++------------ .../java/io/prometheus/client/Summary.java | 4 +- .../prometheus/client/CKMSQuantilesTest.java | 203 ++++---- 3 files changed, 256 insertions(+), 414 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index 7fe6cff3b..9f3a77bd0 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -1,16 +1,9 @@ package io.prometheus.client; -// Copied from https://raw.githubusercontent.com/Netflix/ocelli/master/ocelli-core/src/main/java/netflix/ocelli/stats/CKMSQuantiles.java +// The original implementation was copied from +// https://raw.githubusercontent.com/Netflix/ocelli/master/ocelli-core/src/main/java/netflix/ocelli/stats/CKMSQuantiles.java // Revision d0357b8bf5c17a173ce94d6b26823775b3f999f6 from Jan 21, 2015. -// Which was copied from https://github.com/umbrant/QuantileEstimation/blob/34ea6889570827a79b3f8294812d9390af23b734/src/main/java/com/umbrant/quantile/QuantileEstimationCKMS.java -// -// This is the original code except for the following modifications: -// -// - Changed the type of the observed values from int to double. -// - Removed the Quantiles interface and corresponding @Override annotations. -// - Changed the package name. -// - Make get() return NaN when no sample was observed. -// - Make class package private +// However, it has been heavily refactored in the meantime. /* Copyright 2012 Andrew Wang (andrew@umbrant.com) @@ -29,423 +22,263 @@ */ import java.util.Arrays; +import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** - * Implementation of the Cormode, Korn, Muthukrishnan, and Srivastava algorithm - * for streaming calculation of targeted high-percentile epsilon-approximate - * quantiles. - *

- * This is a generalization of the earlier work by Greenwald and Khanna (GK), - * which essentially allows different error bounds on the targeted quantiles, - * which allows for far more efficient calculation of high-percentiles. - *

- *

- * See: Cormode, Korn, Muthukrishnan, and Srivastava - * "Effective Computation of Biased Quantiles over Data Streams" in ICDE 2005 - *

- * Greenwald and Khanna, - * "Space-efficient online computation of quantile summaries" in SIGMOD 2001 - *

- *

- * The Approximate Quantiles Algorithm looks like this (Figure 1) - *

- * Main()
- *    foreach item v do
- *      Insert(v);
- *      if (Compress Condition()) then
- *          Compress();
+ * Algorithm solving the "Targeted Quantile Problem" as described in
+ * "Effective Computation of Biased Quantiles over Data Streams"
+ * by Cormode, Korn, Muthukrishnan, and Srivastava.
  *
- * Insert(v):
- *    r_0:=0;
- *    for i:=1 to s do
- *        ri := ri−1 + gi−1;
- *        if (v < vi) break;
- *        add (v,1,f(ri,n)−1) to S before vi;
- *    n++;
- *
- * Compress():
- *    for i := (s−1) downto 1 do
- *        if (gi + gi+1 + ∆i+1 ≤ f(ri, n)) then
- *            merge ti and ti+1;
- *
- * Output(φ):
- *    r0:=0;
- *    for i := 1 to s do
- *        ri:=ri−1+gi−1;
- *        if(ri +gi +∆i >φn+f(φn,n)/2)
- *            print(vi−1); break;
- * 
*/ final class CKMSQuantiles { - /** - * Total number of items in stream. - * Increases on every insertBatch(). - */ - private int count = 0; - /** - * Current list of sampled items, maintained in sorted order with error - * bounds. - *

- * Note: Any algorithm that guarantees to find biased - * quantiles φ with error at most φεn in rank must store - * Ω(1 min{klog1/φ,log(εn)}) items. - *

- */ - final LinkedList samples; + final Quantile[] quantiles; /** - * Used for compress condition. - * This is a different index than the bufferCount, - * because flushing is also done on `quantile.get()`, - * but we need to compress, regardless of reaching the bufferCount, to limit space usage. + * Total number of observations (not including those that are still in the buffer). */ - private int compressIdx = 0; + int n = 0; /** - * The amount of values observed when to compress. + * List of sampled observations, ordered by Sample.value. */ - private final int insertThreshold; + final LinkedList samples = new LinkedList(); /** - * Buffers incoming items to be inserted in batch. + * Compress is called every compressInterval inserts. + * Note that the buffer is flushed whenever get() is called, so we + * cannot just wait until the buffer is full before we call compress. */ - private final double[] buffer; + private final int compressInterval = 128; + private int insertsSinceLastCompress = 0; /** - * Tracks the current index of the buffer. Increases on insert(). + * Note that the buffer size could as well be less than the compressInterval. + * However, the buffer size should not be greater than the compressInterval, + * because the compressInterval is not respected in flush(), so if you want + * to compress more often than calling flush() that won't work. */ - private int bufferIdx = 0; + private final double[] buffer = new double[compressInterval]; + private int bufferPos = 0; - /** - * Array of Quantiles that we care about, along with desired error. - */ - private final Quantile[] quantiles; + public CKMSQuantiles(Quantile... quantiles) { + if (quantiles.length == 0) { + throw new IllegalArgumentException("quantiles cannot be empty"); + } + this.quantiles = quantiles; + } /** - * Set up the CKMS Quantiles. Can have 0 or more targeted quantiles defined. - * @param quantiles The targeted quantiles, can be empty. + * Add an observed value */ - CKMSQuantiles(Quantile[] quantiles) { - // hard-coded epsilon of 0.1% to determine the batch size, and default epsilon in case of empty quantiles - double pointOnePercent = 0.001; - if (quantiles.length == 0) { // we need at least one for this algorithm to work - this.quantiles = new Quantile[1]; - this.quantiles[0] = new Quantile(0.5, pointOnePercent / 2); - } else { - this.quantiles = quantiles; - } + public void insert(double value) { + buffer[bufferPos++] = value; - // section 5.1 Methods - Batch. - // This is hardcoded to 500, which corresponds to an epsilon of 0.1%. - this.insertThreshold = 500; + if (bufferPos == buffer.length) { + flush(); + } - // create a buffer with size equal to threshold - this.buffer = new double[insertThreshold]; + if (++insertsSinceLastCompress == compressInterval) { + compress(); + insertsSinceLastCompress = 0; + } + } - // Initialize empty items - this.samples = new LinkedList(); + private void flush() { + Arrays.sort(buffer, 0, bufferPos); + insertBatch(buffer, bufferPos); + bufferPos = 0; } /** - * Add a new value from the stream. - * - * @param value the observed value + * Inserts the elements from index 0 to index toIndex from the sortedBuffer. */ - public void insert(double value) { - buffer[bufferIdx] = value; - bufferIdx++; - - if (bufferIdx == buffer.length) { - insertBatch(); // this is the batch insert variation + void insertBatch(double[] sortedBuffer, int toIndex) { + if (toIndex == 0) { + return; } + ListIterator iterator = samples.listIterator(); + int i = 0; // position in buffer + int r = 0; // sum of g's left of the current sample + while (iterator.hasNext() && i < toIndex) { + Sample item = iterator.next(); + while (i < toIndex) { + if (sortedBuffer[i] > item.value) { + break; + } + insertBefore(iterator, sortedBuffer[i], r); + r++; // new item with g=1 was inserted before, so increment r + i++; + n++; + } + r += item.g; + } + while (i < toIndex) { + samples.add(new Sample(sortedBuffer[i], 0)); + i++; + n++; + } + } - // The Compress_Condition() - compressIdx = (compressIdx + 1) % insertThreshold; - if (compressIdx == 0) { - compress(); + private void insertBefore(ListIterator iterator, double value, int r) { + if (!iterator.hasPrevious()) { + samples.addFirst(new Sample(value, 0)); + } else { + iterator.previous(); + iterator.add(new Sample(value, f(r) - 1)); + iterator.next(); } } /** * Get the estimated value at the specified quantile. - * - * @param q Queried quantile, e.g. 0.50 or 0.99. - * @return Estimated value at that quantile. */ public double get(double q) { - // clear the buffer. in case of low value insertions, the samples can become stale. - // On every get, make sure we get the latest values in. - insertBatch(); + flush(); if (samples.size() == 0) { return Double.NaN; } - // Straightforward implementation of Output(q). - // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j - int currentRank = 0; - double desired = q * count; - - ListIterator it = samples.listIterator(); - Item prev, cur; - cur = it.next(); - while (it.hasNext()) { - prev = cur; - cur = it.next(); - - currentRank += prev.g; - - if (currentRank + cur.g + cur.delta > desired - + (allowableError(desired) / 2)) { - return prev.value; + int r = 0; // sum of g's left of the current sample + int desiredRank = (int) Math.ceil(q * n); + + ListIterator iterator = samples.listIterator(); + while (iterator.hasNext()) { + Sample sample = iterator.next(); + if (r + sample.g + sample.delta > desiredRank + f(desiredRank) / 2) { + iterator.previous(); // roll back the item.next() above + if (iterator.hasPrevious()) { + Sample result = iterator.previous(); + return result.value; + } else { + return sample.value; + } } + r += sample.g; } - - // edge case of wanting max value return samples.getLast().value; } /** - * Specifies the allowable error for this rank, depending on which quantiles - * are being targeted. - *

- * This is the f(r_i, n) function from the CKMS paper. It's basically how - * wide the range of this rank can be. - *

- * Define invariant function f (ri , n) as - * (i) f_j(r_i,n) = 2ε_j r_i / φ_j for φ_j n ≤ r_i ≤ n; - * (ii) f_j(r_i,n) = 2ε_j(n−r_i) / (1−φ_j) for 0 ≤ r_i ≤ φ_j n - *

- * and take f(ri,n) = max{min_j ⌊f_j(r_i,n)⌋,1}. - * As before we ensure that for all i, g_i + ∆_i ≤ f(r_i, n). - * - * @param rank the index in the list of samples + * Error function, as in definition 5 of the paper. */ - private double allowableError(double rank /* r_i */) { - int n = count; - double minError = count; - + int f(int r) { + int minResult = Integer.MAX_VALUE; for (Quantile q : quantiles) { - double error; - if (rank <= q.quantile * n) { - error = q.u * (n - rank); + int result; + // We had a numerical error here with the following example: + // quantile = 0.95, epsilon = 0.01, (n-r) = 30. + // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. + // To avoid running into these types of error we add 0.00000000001 before rounding down. + if (r >= q.quantile * n) { + result = (int) Math.floor(q.v * r + 0.00000000001); } else { - error = q.v * rank; + result = (int) Math.floor(q.u * (n - r) + 0.00000000001); } - if (error < minError) { - minError = error; + if (result < minResult) { + minResult = result; } } - return Math.max(minError, 1); + return Math.max(minResult, 1); } /** - * To insert a new item, v, we find i such that vi < v ≤ vi+1, - * we compute ri and insert the tuple (v,g=1,∆=f(ri,n)−1). - * - * We also ensure that min and max are kept exactly, so when v < v1, - * we insert the tuple (v,g = 1,∆ = 0) before v1. Similarly, when v > vs, - * we insert (v,g = 1,∆ = 0) after vs. + * Merge pairs of consecutive samples if this doesn't violate the error function. */ - private void insertBatch() { - if (bufferIdx == 0) { + void compress() { + if (samples.size() < 3) { return; } - // Has to be sorted: O(buffer) - // Since the buffer is treated as a circular buffer, we sort till the bufferIdx to prevent insertion of duplicate / already inserted values. - Arrays.sort(buffer, 0, bufferIdx); - - // Base case: no samples yet - int start = 0; - if (samples.size() == 0) { - Item newItem = new Item(buffer[0], 0); - samples.add(newItem); - start++; - count++; - } - - // To insert a new item, v, we find i such that vi < v ≤ vi+1, - ListIterator it = samples.listIterator(); - Item item = it.next(); - - // Keep track of the current rank by adding the g of each item. See also discussion in https://issues.apache.org/jira/browse/HBASE-14324 - // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j - int currentRank = item.g; - - for (int i = start; i < bufferIdx; i++) { - // item to be inserted - double v = buffer[i]; - // find the item in the samples that is bigger than our v. - while (it.hasNext() && item.value < v) { - item = it.next(); - currentRank += item.g; + Iterator descendingIterator = samples.descendingIterator(); + int r = n; // n is equal to the sum of the g's of all samples + + Sample right; + Sample left = descendingIterator.next(); + r -= left.g; + + while (descendingIterator.hasNext()) { + right = left; + left = descendingIterator.next(); + r = r - left.g; + if (left == samples.getFirst()) { + // The min sample must never be merged. + break; } - - // If we found that bigger item, back up so we insert ourselves - // before it - if (item.value > v) { - currentRank -= item.g; - it.previous(); - } - - // We use different indexes for the edge comparisons, because of the - // above if statement that adjusts the iterator - int delta; - if (it.previousIndex() == 0 || it.nextIndex() == samples.size()) { - delta = 0; - } else { - delta = ((int) Math.floor(allowableError(currentRank))) - 1; + if (left.g + right.g + right.delta < f(r)) { + right.g += left.g; + descendingIterator.remove(); + left = right; } - - Item newItem = new Item(v, delta); - it.add(newItem); - count++; - item = newItem; } - - // reset buffered items to 0. - bufferIdx = 0; } - /** - * Try to remove extraneous items from the set of sampled items. This checks - * if an item is unnecessary based on the desired error bounds, and merges - * it with the adjacent item if it is. - *

- * Compress. Periodically, the algorithm scans the data - * structure and merges adjacent nodes when this does not - * violate the invariant. That is, remove nodes (vi, gi, ∆i) - * and (vi+1 , gi+1 , ∆i+1 ), and replace with (vi+1 , (gi + - * gi+1 ), ∆i+1 ) provided that (gi + gi+1 + ∆i+1 ) ≤ f (ri , n). - * This also maintains the semantics of g and ∆ being the - * difference in rank between v_i and v_{i-1} , and the difference - * between the highest and lowest possible ranks of vi, respectively. - */ - private void compress() { - // If there are 0,1, or 2 samples then there's nothing to compress. - if (samples.size() < 3) { - return; - } - - ListIterator it = samples.listIterator(); - - Item prev; - Item next = it.next(); - - // Counter for the rank in the stream of all observed values. - // Paper Section 3.1 on true rank: let r_i = Sum_{j=1}^{i−1} g_j - int currentRank = next.g; - - while (it.hasNext()) { - prev = next; - next = it.next(); - currentRank += next.g; - if (prev.g + next.g + next.delta <= allowableError(currentRank)) { - next.g += prev.g; - // Remove prev. it.remove() kills the last thing returned. - it.previous(); // brings pointer back to 'next' - it.previous(); // brings pointer back to 'prev' - it.remove(); // remove prev - // it.next() is now equal to next, - it.next(); // set pointer to 'next' - } - } - } + static class Sample { - /** - * As in GK, the data structure at time n, S(n), consists - * of a sequence of s tuples ⟨ti = (vi, gi, ∆i)⟩, where each vi - * is a sampled item from the data stream and two additional - * values are kept: (1) g_i is the difference between the lowest - * possible rank of item i and the lowest possible rank of item - * i − 1; and (2) ∆_i is the difference between the greatest - * possible rank of item i and the lowest possible rank of item - * i. - */ - private static class Item { /** - * vi - * is a sampled item from the data stream and two additional - * values are kept + * Observed value. */ final double value; + /** - * g_i is the difference between the lowest - * possible rank of item i and the lowest possible rank of item - * i − 1. - * note: Always starts with 1, changes when merging Items. + * Difference between the lowest possible rank of this sample and its predecessor. + * This always starts with 1, but will be updated when compress() merges Samples. */ int g = 1; + /** - * ∆i is the difference between the greatest - * possible rank of item i and the lowest possible rank of item - * i. + * Difference between the greatest possible rank of this sample and the lowest possible rank of this sample. */ final int delta; - Item(double value, int delta) { + Sample(double value, int delta) { this.value = value; this.delta = delta; } @Override public String toString() { - return String.format("I{val=%.3f, g=%d, del=%d}", value, g, delta); + return String.format("Sample{val=%.3f, g=%d, delta=%d}", value, g, delta); } } - /** - * - */ static class Quantile { + /** - * 0 < φ < 1 + * Quantile. Must be between 0 and 1. */ final double quantile; + /** - * Allowed error 0 < ε < 1 + * Allowed error. Must be between 0 and 1. */ final double epsilon; + /** - * Helper value to calculate the targeted quantiles invariant as per Definition 5 (ii) + * Helper used in the error function f(), see definition 5 in the paper. */ final double u; + /** - * Helper value to calculate the targeted quantiles invariant as per Definition 5 (i) + * Helper used in the error function f(), see definition 5 in the paper. */ final double v; - /** - * Targeted quantile: T = {(φ_j , ε_j )} - * Rather than requesting the same ε for all quantiles (the uniform case) - * or ε scaled by φ (the biased case), one might specify an arbitrary set - * of quantiles and the desired errors of ε for each in the form (φj , εj ). - * For example, input to the targeted quantiles problem might be {(0.5, 0.1), (0.2, 0.05), (0.9, 0.01)}, - * meaning that the median should be returned with 10% error, the 20th percentile with 5% error, - * and the 90th percentile with 1%. - * - * @param quantile the quantile between 0 and 1 - * @param epsilon the desired error for this quantile, between 0 and 1. - */ Quantile(double quantile, double epsilon) { - if (quantile < 0 || quantile > 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); - if (epsilon < 0 || epsilon > 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); + if (quantile <= 0 || quantile >= 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); + if (epsilon <= 0 || epsilon >= 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); this.quantile = quantile; this.epsilon = epsilon; - // f_j(r_i,n) = 2ε_j(n−r_i) / (1−φ_j) for 0 ≤ r_i ≤ φ_j n u = 2.0 * epsilon / (1.0 - quantile); - // f_j(r_i,n) = 2ε_j r_i / φ_j for φ_j n ≤ r_i ≤ n; v = 2.0 * epsilon / quantile; } @Override public String toString() { - return String.format("Q{q=%.3f, eps=%.3f}", quantile, epsilon); + return String.format("Quantile{q=%.3f, epsilon=%.3f}", quantile, epsilon); } } - } diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index 34b123ba0..886358cd9 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -99,10 +99,10 @@ public static class Builder extends SimpleCollector.Builder { private int ageBuckets = 5; public Builder quantile(double quantile, double error) { - if (quantile < 0.0 || quantile > 1.0) { + if (quantile <= 0.0 || quantile >= 1.0) { throw new IllegalArgumentException("Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); } - if (error < 0.0 || error > 1.0) { + if (error <= 0.0 || error >= 1.0) { throw new IllegalArgumentException("Error " + error + " invalid: Expected number between 0.0 and 1.0."); } quantiles.add(new Quantile(quantile, error)); diff --git a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java index 63a281007..ca71018b4 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java @@ -12,105 +12,79 @@ public class CKMSQuantilesTest { - @Test - public void testGetOnEmptyValues() { - List quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.01)); - quantiles.add(new Quantile(0.90, 0.01)); - quantiles.add(new Quantile(0.95, 0.01)); - quantiles.add(new Quantile(0.99, 0.01)); - - CKMSQuantiles ckms = new CKMSQuantiles( - quantiles.toArray(new Quantile[]{})); - assertEquals(Double.NaN, ckms.get(0), 0); - } + private final Quantile q50 = new Quantile(0.5, 0.01); + private final Quantile q95 = new Quantile(0.95, 0.005); + private final Quantile q99 = new Quantile(0.99, 0.001); @Test - public void testGetWhenNoQuantilesAreDefined() { - CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); - assertEquals(Double.NaN, ckms.get(0), 0); - } - - @Test - public void testInsertWhenNoQuantilesAreDefined() { - CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); - ckms.insert(1.0); - ckms.insert(2.0); - ckms.insert(3.0); - assertEquals(1.0, ckms.get(0), 0); - assertEquals(2.0, ckms.get(0.5), 0); - assertEquals(3.0, ckms.get(1), 0); + public void testGetOnEmptyValues() { + CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99); + assertTrue(Double.isNaN(ckms.get(q95.quantile))); } @Test - public void testCompressWhenBufferSize500Reached() { - CKMSQuantiles ckms = new CKMSQuantiles(new Quantile[]{}); - List input = makeSequence(1, 499); - - for (double v : input) { - ckms.insert(v); + public void testGet() { + Random random = new Random(0); + CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99); + List input = shuffledValues(100, random); + for (double value : input) { + ckms.insert(value); } - assertEquals("No compress should be triggered", 0, ckms.samples.size()); - - ckms.insert(500); - assertEquals(500, ckms.samples.size()); + validateResults(ckms); } @Test - public void testGet() { - List quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.01)); - quantiles.add(new Quantile(0.90, 0.01)); - quantiles.add(new Quantile(0.95, 0.01)); - quantiles.add(new Quantile(0.99, 0.01)); + public void testBatchInsert() { + Random random = new Random(0); + testInsertBatch(1, 1, 100, random); + testInsertBatch(1, 10, 100, random); + testInsertBatch(2, 10, 100, random); + testInsertBatch(2, 110, 100, random); // compress never called, because compress interval > number of inserts + testInsertBatch(3, 10, 100, random); + testInsertBatch(10, 10, 100, random); + testInsertBatch(128, 128, 1, random); + testInsertBatch(128, 128, 1000, random); + testInsertBatch(128, 128, 10*1000, random); + testInsertBatch(128, 128, 100*1000, random); + testInsertBatch(128, 128, 1000*1000, random); + } - List input = makeSequence(1, 100); - CKMSQuantiles ckms = new CKMSQuantiles( - quantiles.toArray(new Quantile[]{})); - for (double v : input) { - ckms.insert(v); + private void testInsertBatch(int batchSize, int compressInterval, int totalNumber, Random random) { + System.out.println("testInsertBatch(batchSize=" + batchSize + ", compressInterval=" + compressInterval + ", totalNumber=" + totalNumber + ")"); + CKMSQuantiles ckms = new CKMSQuantiles(q50, q95); + int insertsSinceCompress = 0; + List input = shuffledValues(totalNumber, random); + for (int i=0; i= compressInterval) { + ckms.compress(); + validateSamples(ckms); // after each compress the samples should still be valid + insertsSinceCompress=0; + } } - assertEquals(10.0, ckms.get(0.1), 1); - assertEquals(50.0, ckms.get(0.5), 1); - assertEquals(90.0, ckms.get(0.9), 1); - assertEquals(95.0, ckms.get(0.95), 1); - assertEquals(99.0, ckms.get(0.99), 1); + validateResults(ckms); } @Test public void testGetWithAMillionElements() { - List quantiles = new ArrayList(); - quantiles.add(new Quantile(0.0, 0.01)); - quantiles.add(new Quantile(0.10, 0.01)); - quantiles.add(new Quantile(0.90, 0.001)); - quantiles.add(new Quantile(0.95, 0.02)); - quantiles.add(new Quantile(0.99, 0.001)); - - final int elemCount = 1000000; - double[] shuffle = new double[elemCount]; - for (int i = 0; i < shuffle.length; i++) { - shuffle[i] = i + 1; - } - Random rand = new Random(0); - - Collections.shuffle(Arrays.asList(shuffle), rand); - - CKMSQuantiles ckms = new CKMSQuantiles( - quantiles.toArray(new Quantile[]{})); - - for (double v : shuffle) { + Random random = new Random(0); + List input = shuffledValues(1000*1000, random); + CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99); + for (double v : input) { ckms.insert(v); } - // given the linear distribution, we set the delta equal to the εn value for this quantile - assertEquals(0.1 * elemCount, ckms.get(0.1), 0.01 * elemCount); - assertEquals(0.9 * elemCount, ckms.get(0.9), 0.001 * elemCount); - assertEquals(0.95 * elemCount, ckms.get(0.95), 0.02 * elemCount); - assertEquals(0.99 * elemCount, ckms.get(0.99), 0.001 * elemCount); - + validateResults(ckms); assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000); } - @Test public void testGetGaussian() { RandomGenerator rand = new JDKRandomGenerator(); @@ -127,10 +101,9 @@ public void testGetGaussian() { quantiles.add(new Quantile(0.95, 0.001)); quantiles.add(new Quantile(0.99, 0.001)); - CKMSQuantiles ckms = new CKMSQuantiles( - quantiles.toArray(new Quantile[]{})); + CKMSQuantiles ckms = new CKMSQuantiles(quantiles.toArray(new Quantile[]{})); - final int elemCount = 1000000; + final int elemCount = 1000*1000; double[] shuffle = normalDistribution.sample(elemCount); // insert a million samples @@ -155,8 +128,17 @@ public void testGetGaussian() { assertTrue("sample size should be below 1000", ckms.samples.size() < 1000); } + double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) { + //(φ+ε)n + double upperBound = nd.inverseCumulativeProbability(p + epsilon); + //(φ−ε)n + double lowerBound = nd.inverseCumulativeProbability(p - epsilon); + // subtract and divide by 2, assuming that the increase is linear in this small epsilon. + return Math.abs(upperBound - lowerBound) / 2; + } + @Test - public void checkBounds() { + public void testIllegalArgumentException() { try { new Quantile(-1, 0); } catch (IllegalArgumentException e) { @@ -164,7 +146,6 @@ public void checkBounds() { } catch (Exception e) { fail("Wrong exception thrown" + e); } - try { new Quantile(0.95, 2); } catch (IllegalArgumentException e) { @@ -174,23 +155,51 @@ public void checkBounds() { } } - double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) { - //(φ+ε)n - double upperBound = nd.inverseCumulativeProbability(p + epsilon); - //(φ−ε)n - double lowerBound = nd.inverseCumulativeProbability(p - epsilon); - // subtract and divide by 2, assuming that the increase is linear in this small epsilon. - return Math.abs(upperBound - lowerBound) / 2; + private List shuffledValues(int n, Random random) { + List result = new ArrayList(n); + for (int i=0; i makeSequence(int begin, int end) { - List ret = new ArrayList(end - begin + 1); - for (int i = begin; i <= end; i++) { - ret.add((double) i); + private void validateSamples(CKMSQuantiles ckms) { + double prev = -1.0; + int r = 0; // sum of all g's left of the current sample + for (CKMSQuantiles.Sample sample : ckms.samples) { + String msg = "invalid sample " + sample + ": count=" + ckms.n + " r=" + r + " f(r)=" + ckms.f(r); + assertTrue(msg, sample.g + sample.delta <= ckms.f(r)); + assertTrue("Samples not ordered. Keep in mind that insertBatch() takes a sorted array as parameter.", prev <= sample.value); + prev = sample.value; + r += sample.g; } - return ret; + assertEquals("the sum of all g's must be the total number of observations", r, ckms.n); } + + /** + * The values that we insert in these tests are always the numbers from 1 to n, in random order. + * So we can trivially calculate the range of acceptable results for each quantile. + * We check if the value returned by get() is within the range of acceptable results. + */ + private void validateResults(CKMSQuantiles ckms) { + for (Quantile q : ckms.quantiles) { + double actual = ckms.get(q.quantile); + double lowerBound = Math.floor(ckms.n * (q.quantile - 2 * q.epsilon)); + double upperBound = Math.ceil(ckms.n * (q.quantile + 2 * q.epsilon)); + boolean ok = actual >= lowerBound && actual <= upperBound; + if (!ok) { + for (CKMSQuantiles.Sample sample : ckms.samples) { + System.err.println(sample); + } + } + String errorMessage = q + ": " + actual + " not in [" + lowerBound + ", " + upperBound + "], n=" + ckms.n + ", " + q.quantile + "*" + ckms.n + "=" + (q.quantile*ckms.n); + assertTrue(errorMessage, ok); + } + } + + } From f9a117126157019af5248be6588dd442e3c6dd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 3 Feb 2022 14:32:28 +0100 Subject: [PATCH 129/980] Summaries: Allow 0.0 and 1.0 quantiles and update documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- README.md | 85 ++++++---- .../io/prometheus/client/CKMSQuantiles.java | 19 ++- .../java/io/prometheus/client/Summary.java | 131 +++++++++------ .../prometheus/client/CKMSQuantilesTest.java | 149 +++++++++++++++++- 4 files changed, 296 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index f6fe7a172..841183eca 100644 --- a/README.md +++ b/README.md @@ -130,57 +130,86 @@ when using this approach ensure the value you are reporting accounts for concurr ### Summary -Summaries track the size and number of events. +Summaries and Histograms can both be used to monitor latencies (or other things like request sizes). + +An overview of when to use Summaries and when to use Histograms can be found on [https://prometheus.io/docs/practices/histograms](https://prometheus.io/docs/practices/histograms). + +The following example shows how to measure latencies and request sizes: ```java class YourClass { - static final Summary receivedBytes = Summary.build() - .name("requests_size_bytes").help("Request size in bytes.").register(); - static final Summary requestLatency = Summary.build() - .name("requests_latency_seconds").help("Request latency in seconds.").register(); - void processRequest(Request req) { + private static final Summary requestLatency = Summary.build() + .name("requests_latency_seconds") + .help("request latency in seconds") + .register(); + + private static final Summary receivedBytes = Summary.build() + .name("requests_size_bytes") + .help("request size in bytes") + .register(); + + public void processRequest(Request req) { Summary.Timer requestTimer = requestLatency.startTimer(); try { // Your code here. } finally { - receivedBytes.observe(req.size()); requestTimer.observeDuration(); + receivedBytes.observe(req.size()); } } } ``` -There are utilities for timing code and support for [quantiles](https://prometheus.io/docs/practices/histograms/#quantiles). -Essentially quantiles aren't aggregatable and add some client overhead for the calculation. +The `Summary` class provides different utility methods for observing values, like `observe(double)`, `startTimer(); timer.observeDuration()`, `time(Callable)`, etc. + +By default, `Summary` metrics provide the `count` and the `sum`. For example, if you measure latencies of a REST service, the `count` will tell you how often the REST service was called, and the `sum` will tell you the total aggregated response time. You can calculate the average response time using a Prometheus query dividing `sum / count`. + +In addition to `count` and `sum`, you can configure a Summary to provide quantiles: ```java -class YourClass { - static final Summary requestLatency = Summary.build() - .quantile(0.5, 0.05) // Add 50th percentile (= median) with 5% tolerated error - .quantile(0.9, 0.01) // Add 90th percentile with 1% tolerated error - .name("requests_latency_seconds").help("Request latency in seconds.").register(); +Summary requestLatency = Summary.build() + .name("requests_latency_seconds") + .help("Request latency in seconds.") + .quantile(0.5, 0.01) // 0.5 quantile (median) with 0.01 allowed error + .quantile(0.95, 0.005) // 0.95 quantile with 0.005 allowed error + // ... + .register(); +``` - void processRequest(Request req) { - requestLatency.time(new Runnable() { - public abstract void run() { - // Your code here. - } - }); +As an example, a `0.95` quantile of `120ms` tells you that `95%` of the calls were faster than `120ms`, and `5%` of the calls were slower than `120ms`. +Tracking exact quantiles require a large amount of memory, because all observations need to be stored in a sorted list. Therefore, we allow an error to significantly reduce memory usage. - // Or the Java 8 lambda equivalent - requestLatency.time(() -> { - // Your code here. - }); - } -} +In the example, the allowed error of `0.005` means that you will not get the exact `0.95` quantile, but anything between the `0.945` quantile and the `0.955` quantile. + +Experiments show that the `Summary` typically needs to keep less than 100 samples to provide that precision, even if you have hundreds of millions of observations. + +There are a few special cases: + +* You can set an allowed error of `0`, but then the `Summary` will keep all observations in memory. +* You can track the minimum value with `.quantile(0, 0)`. This special case will not use additional memory even though the allowed error is `0`. +* You can track the maximum value with `.quantile(1, 0)`. This special case will not use additional memory even though the allowed error is `0`. + +Typically, you don't want to have a `Summary` representing the entire runtime of the application, but you want to look at a reasonable time interval. `Summary` metrics implement a configurable sliding time window: + +```java +Summary requestLatency = Summary.build() + .name("requests_latency_seconds") + .help("Request latency in seconds.") + .maxAgeSeconds(10 * 60) + .ageBuckets(5) + // ... + .register(); ``` +The default is a time window of 10 minutes and 5 age buckets, i.e. the time window is 10 minutes wide, and * we slide it forward every 2 minutes. + ### Histogram -Histograms track the size and number of events in buckets. -This allows for aggregatable calculation of quantiles. +Like Summaries, Histograms can be used to monitor latencies (or other things like request sizes). + +An overview of when to use Summaries and when to use Histograms can be found on [https://prometheus.io/docs/practices/histograms](https://prometheus.io/docs/practices/histograms). ```java class YourClass { diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index 9f3a77bd0..ff75d6f4d 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -142,6 +142,14 @@ public double get(double q) { return Double.NaN; } + if (q == 0.0) { + return samples.getFirst().value; + } + + if (q == 1.0) { + return samples.getLast().value; + } + int r = 0; // sum of g's left of the current sample int desiredRank = (int) Math.ceil(q * n); @@ -168,6 +176,9 @@ public double get(double q) { int f(int r) { int minResult = Integer.MAX_VALUE; for (Quantile q : quantiles) { + if (q.quantile == 0 || q.quantile == 1) { + continue; + } int result; // We had a numerical error here with the following example: // quantile = 0.95, epsilon = 0.01, (n-r) = 30. @@ -267,13 +278,13 @@ static class Quantile { final double v; Quantile(double quantile, double epsilon) { - if (quantile <= 0 || quantile >= 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); - if (epsilon <= 0 || epsilon >= 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); + if (quantile < 0.0 || quantile > 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); + if (epsilon < 0.0 || epsilon > 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); this.quantile = quantile; this.epsilon = epsilon; - u = 2.0 * epsilon / (1.0 - quantile); - v = 2.0 * epsilon / quantile; + u = 2.0 * epsilon / (1.0 - quantile); // if quantile == 1 this will be Double.NaN + v = 2.0 * epsilon / quantile; // if quantile == 0 this will be Double.NaN } @Override diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index 886358cd9..e60f33da1 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -13,70 +13,91 @@ import java.util.concurrent.TimeUnit; /** - * Summary metric, to track the size of events. + * {@link Summary} metrics and {@link Histogram} metrics can both be used to monitor latencies (or other things like request sizes). *

- * Example of uses for Summaries include: - *

    - *
  • Response latency
  • - *
  • Request size
  • - *
- * + * An overview of when to use Summaries and when to use Histograms can be found on https://prometheus.io/docs/practices/histograms. *

- * Example Summaries: + * The following example shows how to measure latencies and request sizes: + * *

- * {@code
- *   class YourClass {
- *     static final Summary receivedBytes = Summary.build()
- *         .name("requests_size_bytes").help("Request size in bytes.").register();
- *     static final Summary requestLatency = Summary.build()
- *         .name("requests_latency_seconds").help("Request latency in seconds.").register();
+ * class YourClass {
  *
- *     void processRequest(Request req) {
- *        Summary.Timer requestTimer = requestLatency.startTimer();
- *        try {
- *          // Your code here.
- *        } finally {
- *          receivedBytes.observe(req.size());
- *          requestTimer.observeDuration();
- *        }
- *     }
+ *   private static final Summary requestLatency = Summary.build()
+ *       .name("requests_latency_seconds")
+ *       .help("request latency in seconds")
+ *       .register();
+ *
+ *   private static final Summary receivedBytes = Summary.build()
+ *       .name("requests_size_bytes")
+ *       .help("request size in bytes")
+ *       .register();
  *
- *     // Or if using Java 8 and lambdas.
- *     void processRequestLambda(Request req) {
+ *   public void processRequest(Request req) {
+ *     Summary.Timer requestTimer = requestLatency.startTimer();
+ *     try {
+ *       // Your code here.
+ *     } finally {
+ *       requestTimer.observeDuration();
  *       receivedBytes.observe(req.size());
- *       requestLatency.time(() -> {
- *         // Your code here.
- *       });
  *     }
- * }
+ *   }
  * }
  * 
- * This would allow you to track request rate, average latency and average request size. * + * The {@link Summary} class provides different utility methods for observing values, like {@link #observe(double)}, + * {@link #startTimer()} and {@link Timer#observeDuration()}, {@link #time(Callable)}, etc. *

- * How to add custom quantiles: + * By default, {@link Summary} metrics provide the count and the sum. For example, if you measure + * latencies of a REST service, the count will tell you how often the REST service was called, + * and the sum will tell you the total aggregated response time. + * You can calculate the average response time using a Prometheus query dividing sum / count. + *

+ * In addition to count and sum, you can configure a Summary to provide quantiles: + * *

- * {@code
- *     static final Summary myMetric = Summary.build()
- *             .quantile(0.5, 0.05)   // Add 50th percentile (= median) with 5% tolerated error
- *             .quantile(0.9, 0.01)   // Add 90th percentile with 1% tolerated error
- *             .quantile(0.99, 0.001) // Add 99th percentile with 0.1% tolerated error
- *             .name("requests_size_bytes")
- *             .help("Request size in bytes.")
- *             .register();
- * }
+ * Summary requestLatency = Summary.build()
+ *     .name("requests_latency_seconds")
+ *     .help("Request latency in seconds.")
+ *     .quantile(0.5, 0.01)    // 0.5 quantile (median) with 0.01 allowed error
+ *     .quantile(0.95, 0.005)  // 0.95 quantile with 0.005 allowed error
+ *     // ...
+ *     .register();
  * 
* - * The quantiles are calculated over a sliding window of time. There are two options to configure this time window: + * As an example, a 0.95 quantile of 120ms tells you that 95% of the calls were faster than 120ms, and 5% of the calls were slower than 120ms. + *

+ * Tracking exact quantiles require a large amount of memory, because all observations need to be stored in a sorted list. Therefore, we allow an error to significantly reduce memory usage. + *

+ * In the example, the allowed error of 0.005 means that you will not get the exact 0.95 quantile, but anything between the 0.945 quantile and the 0.955 quantile. + *

+ * Experiments show that the {@link Summary} typically needs to keep less than 100 samples to provide that precision, even if you have hundreds of millions of observations. + *

+ * There are a few special cases: + * *

    - *
  • maxAgeSeconds(long): Set the duration of the time window is, i.e. how long observations are kept before they are discarded. - * Default is 10 minutes. - *
  • ageBuckets(int): Set the number of buckets used to implement the sliding time window. If your time window is 10 minutes, and you have ageBuckets=5, - * buckets will be switched every 2 minutes. The value is a trade-off between resources (memory and cpu for maintaining the bucket) - * and how smooth the time window is moved. Default value is 5. + *
  • You can set an allowed error of 0, but then the {@link Summary} will keep all observations in memory.
  • + *
  • You can track the minimum value with .quantile(0.0, 0.0). + * This special case will not use additional memory even though the allowed error is 0.
  • + *
  • You can track the maximum value with .quantile(1.0, 0.0). + * This special case will not use additional memory even though the allowed error is 0.
  • *
* - * See https://prometheus.io/docs/practices/histograms/ for more info on quantiles. + * Typically, you don't want to have a {@link Summary} representing the entire runtime of the application, + * but you want to look at a reasonable time interval. {@link Summary} metrics implement a configurable sliding + * time window: + * + *
+ * Summary requestLatency = Summary.build()
+ *     .name("requests_latency_seconds")
+ *     .help("Request latency in seconds.")
+ *     .maxAgeSeconds(10 * 60)
+ *     .ageBuckets(5)
+ *     // ...
+ *     .register();
+ * 
+ * + * The default is a time window of 10 minutes and 5 age buckets, i.e. the time window is 10 minutes wide, and + * we slide it forward every 2 minutes. */ public class Summary extends SimpleCollector implements Counter.Describable { @@ -98,17 +119,25 @@ public static class Builder extends SimpleCollector.Builder { private long maxAgeSeconds = TimeUnit.MINUTES.toSeconds(10); private int ageBuckets = 5; + /** + * The class JavaDoc for {@link Summary} has more information on {@link #quantile(double, double)}. + * @see Summary + */ public Builder quantile(double quantile, double error) { - if (quantile <= 0.0 || quantile >= 1.0) { + if (quantile < 0.0 || quantile > 1.0) { throw new IllegalArgumentException("Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); } - if (error <= 0.0 || error >= 1.0) { + if (error < 0.0 || error > 1.0) { throw new IllegalArgumentException("Error " + error + " invalid: Expected number between 0.0 and 1.0."); } quantiles.add(new Quantile(quantile, error)); return this; } + /** + * The class JavaDoc for {@link Summary} has more information on {@link #maxAgeSeconds(long)} + * @see Summary + */ public Builder maxAgeSeconds(long maxAgeSeconds) { if (maxAgeSeconds <= 0) { throw new IllegalArgumentException("maxAgeSeconds cannot be " + maxAgeSeconds); @@ -117,6 +146,10 @@ public Builder maxAgeSeconds(long maxAgeSeconds) { return this; } + /** + * The class JavaDoc for {@link Summary} has more information on {@link #ageBuckets(int)} + * @see Summary + */ public Builder ageBuckets(int ageBuckets) { if (ageBuckets <= 0) { throw new IllegalArgumentException("ageBuckets cannot be " + ageBuckets); diff --git a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java index ca71018b4..f00371fec 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java @@ -12,9 +12,11 @@ public class CKMSQuantilesTest { + private final Quantile qMin = new Quantile(0.0, 0.00); private final Quantile q50 = new Quantile(0.5, 0.01); private final Quantile q95 = new Quantile(0.95, 0.005); private final Quantile q99 = new Quantile(0.99, 0.001); + private final Quantile qMax = new Quantile(1.0, 0.00); @Test public void testGetOnEmptyValues() { @@ -35,7 +37,7 @@ public void testGet() { @Test public void testBatchInsert() { - Random random = new Random(0); + Random random = new Random(1); testInsertBatch(1, 1, 100, random); testInsertBatch(1, 10, 100, random); testInsertBatch(2, 10, 100, random); @@ -75,7 +77,7 @@ private void testInsertBatch(int batchSize, int compressInterval, int totalNumbe @Test public void testGetWithAMillionElements() { - Random random = new Random(0); + Random random = new Random(2); List input = shuffledValues(1000*1000, random); CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99); for (double v : input) { @@ -85,6 +87,132 @@ public void testGetWithAMillionElements() { assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000); } + @Test + public void testMin() { + Random random = new Random(3); + List input = shuffledValues(1000, random); + CKMSQuantiles ckms = new CKMSQuantiles(qMin); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + ckms.compress(); + assertEquals(2, ckms.samples.size()); + } + + @Test + public void testMax() { + Random random = new Random(4); + List input = shuffledValues(1000, random); + CKMSQuantiles ckms = new CKMSQuantiles(qMax); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + ckms.compress(); + assertEquals(2, ckms.samples.size()); + } + + @Test + public void testMinMax() { + Random random = new Random(5); + List input = shuffledValues(1000, random); + CKMSQuantiles ckms = new CKMSQuantiles(qMin, qMax); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + ckms.compress(); + assertEquals(2, ckms.samples.size()); + } + + @Test + public void testMinAndOthers() { + Random random = new Random(6); + List input = shuffledValues(1000, random); + CKMSQuantiles ckms = new CKMSQuantiles(q95, qMin); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + } + + @Test + public void testMaxAndOthers() { + Random random = new Random(7); + List input = shuffledValues(10000, random); + CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, qMax); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + } + + @Test + public void testMinMaxAndOthers() { + Random random = new Random(8); + List input = shuffledValues(10000, random); + CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, q95, q99, qMax); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + } + + @Test + public void testExactQuantile() { + Random random = new Random(9); + List input = shuffledValues(10000, random); + CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 0)); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + // With epsilon == 0 we need to keep all inputs in samples. + assertEquals(input.size(), ckms.samples.size()); + } + + @Test + public void testExactAndOthers() { + Random random = new Random(10); + List input = shuffledValues(10000, random); + CKMSQuantiles ckms = new CKMSQuantiles(q50, new Quantile(0.95, 0), q99); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + // With epsilon == 0 we need to keep all inputs in samples. + assertEquals(input.size(), ckms.samples.size()); + } + + @Test + public void testExactAndMin() { + Random random = new Random(11); + List input = shuffledValues(10000, random); + CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, new Quantile(0.95, 0)); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + // With epsilon == 0 we need to keep all inputs in samples. + assertEquals(input.size(), ckms.samples.size()); + } + + @Test + public void testMaxEpsilon() { + Random random = new Random(12); + List input = shuffledValues(10000, random); + // epsilon == 1 basically gives you random results, but it should still not throw an exception. + CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 1)); + for (double v : input) { + ckms.insert(v); + } + validateResults(ckms); + } + @Test public void testGetGaussian() { RandomGenerator rand = new JDKRandomGenerator(); @@ -188,8 +316,17 @@ private void validateSamples(CKMSQuantiles ckms) { private void validateResults(CKMSQuantiles ckms) { for (Quantile q : ckms.quantiles) { double actual = ckms.get(q.quantile); - double lowerBound = Math.floor(ckms.n * (q.quantile - 2 * q.epsilon)); - double upperBound = Math.ceil(ckms.n * (q.quantile + 2 * q.epsilon)); + double lowerBound, upperBound; + if (q.quantile == 0) { + lowerBound = 1; + upperBound = 1; + } else if (q.quantile == 1) { + lowerBound = ckms.n; + upperBound = ckms.n; + } else { + lowerBound = Math.floor(ckms.n * (q.quantile - 2 * q.epsilon)); + upperBound = Math.ceil(ckms.n * (q.quantile + 2 * q.epsilon)); + } boolean ok = actual >= lowerBound && actual <= upperBound; if (!ok) { for (CKMSQuantiles.Sample sample : ckms.samples) { @@ -200,6 +337,4 @@ private void validateResults(CKMSQuantiles ckms) { assertTrue(errorMessage, ok); } } - - -} +} \ No newline at end of file From 579694315f59906caffa3acff0891f6105a88314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Feb 2022 21:54:23 +0100 Subject: [PATCH 130/980] Bump vertx-web from 3.3.2 to 3.5.4 in /simpleclient_vertx (#758) Bumps vertx-web from 3.3.2 to 3.5.4. --- updated-dependencies: - dependency-name: io.vertx:vertx-web dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- simpleclient_vertx/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index ec6b34eff..61c9a12b7 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -62,7 +62,7 @@ io.vertx vertx-web - 3.3.2 + 3.5.4 provided From b56849c28ddaaada434c1e5facfa09504b1e2da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 3 Feb 2022 22:09:22 +0100 Subject: [PATCH 131/980] simpleclient_log4j: make log4j dependency provided MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- simpleclient_log4j/pom.xml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index c6d2d525e..209797050 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -39,11 +39,17 @@ 0.14.2-SNAPSHOT - log4j - log4j - 1.2.17 + org.apache.logging.log4j + log4j-core + 2.17.1 + provided + + + org.apache.logging.log4j + log4j-1.2-api + 2.17.1 + provided - junit @@ -55,7 +61,7 @@ org.mockito mockito-core - 2.28.2 + 4.3.1 test From a3954b03512376050f3609ae9fa462fda7fb427a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 4 Feb 2022 12:26:13 +0100 Subject: [PATCH 132/980] Dependency version bumps (#761) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump dependency versions Signed-off-by: Fabian Stäber * simpleclient_dropwizard: make dependency provided Signed-off-by: Fabian Stäber --- benchmarks/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 4 ++-- integration_tests/it_pushgateway/pom.xml | 4 ++-- .../it_servlet_jakarta_exporter_webxml/pom.xml | 4 ++-- integration_tests/pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 6 +++--- simpleclient_dropwizard/pom.xml | 5 +++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 4 ++-- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 6 +++--- simpleclient_spring_boot/pom.xml | 10 +++++----- simpleclient_spring_web/pom.xml | 12 ++++++------ simpleclient_vertx/pom.xml | 2 +- 23 files changed, 49 insertions(+), 48 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 4194ddf4e..d07a1dde3 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -37,7 +37,7 @@ javax.annotation javax.annotation-api - 1.3.1 + 1.3.2 io.prometheus diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 54dde3145..91347bb60 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -16,7 +16,7 @@ org.springframework.boot spring-boot-dependencies - 2.4.4 + 2.6.3 pom import @@ -56,7 +56,7 @@ ch.qos.logback logback-classic - 1.2.0 + 1.2.10 test diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 3a1dacbcb..b58191247 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -30,13 +30,13 @@ com.squareup.okhttp3 okhttp - 4.9.1 + 4.9.3 test ch.qos.logback logback-classic - 1.2.0 + 1.2.10 test diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 922e2634a..cbfb8214e 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -35,7 +35,7 @@ com.squareup.okhttp3 okhttp - 4.9.1 + 4.9.3 org.testcontainers @@ -45,7 +45,7 @@ ch.qos.logback logback-classic - 1.2.0 + 1.2.10 jakarta.servlet diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 9464364c2..98ca9d6c0 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -56,7 +56,7 @@ org.testcontainers testcontainers - 1.15.2 + 1.16.3 test @@ -68,7 +68,7 @@ ch.qos.logback logback-classic - 1.2.0 + 1.2.10 test diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index b2d8f9ac7..6f6af4b2e 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -57,7 +57,7 @@ org.apache.commons commons-math3 - 3.2 + 3.6.1 test diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 319e31276..a1d5e8f11 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -41,7 +41,7 @@ com.github.ben-manes.caffeine caffeine - 2.7.0 + 2.9.3 @@ -55,13 +55,13 @@ org.mockito mockito-core - 2.28.2 + 4.3.1 test org.assertj assertj-core - 2.6.0 + 3.22.0 test diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 8a88bf39d..8efebfee2 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -39,7 +39,8 @@ io.dropwizard.metrics metrics-core - 3.1.2 + 4.2.8 + provided @@ -51,7 +52,7 @@ org.assertj assertj-core - 2.9.1 + 3.22.0 test diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index a629ab7d3..14e526ab4 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -55,13 +55,13 @@ org.mockito mockito-core - 2.28.2 + 4.3.1 test org.assertj assertj-core - 2.6.0 + 3.22.0 test diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index cd898375c..c9908d937 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -44,7 +44,7 @@ org.hibernate hibernate-core - 5.2.0.Final + 5.6.5.Final provided @@ -58,7 +58,7 @@ org.mockito mockito-core - 2.18.0 + 4.3.1 test diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 9abcdb150..18099475e 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -62,7 +62,7 @@ org.eclipse.jetty jetty-servlet - 8.1.7.v20120910 + 8.2.0.v20160908 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 3600fcdea..34b644534 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -53,13 +53,13 @@ org.assertj assertj-core - 2.6.0 + 3.22.0 test javax.xml.bind jaxb-api - 2.3.0 + 2.4.0-b180830.0359 test diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 89de47899..e23440ef8 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -60,7 +60,7 @@ org.hamcrest hamcrest-all - 1.1 + 1.3 test diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 0bd645483..f4e3e4794 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -69,7 +69,7 @@ org.hamcrest hamcrest-all - 1.1 + 1.3 test diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 78a4f06ea..1d4826f65 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -55,7 +55,7 @@ org.mockito mockito-core - 2.28.2 + 4.3.1 test diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 8f3a26c99..c673eac79 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -41,7 +41,7 @@ ch.qos.logback logback-classic - 1.2.0 + 1.2.10 @@ -55,7 +55,7 @@ org.mockito mockito-core - 2.28.2 + 4.3.1 test diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 55345ddea..49af6da84 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -47,7 +47,7 @@ javax.xml.bind jaxb-api - 2.3.0 + 2.4.0-b180830.0359 provided diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index a6686bdc2..98c1c0fd2 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -55,7 +55,7 @@ javax.servlet javax.servlet-api - 3.0.1 + 3.1.0 provided @@ -68,19 +68,19 @@ org.assertj assertj-core - 2.6.0 + 3.22.0 test org.eclipse.jetty jetty-servlet - 8.1.7.v20120910 + 8.2.0.v20160908 test org.mockito mockito-core - 2.28.2 + 4.3.1 test diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index d287f5d56..632431d3c 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -57,7 +57,7 @@ org.assertj assertj-core - 2.6.0 + 3.22.0 test diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index e4c67306d..c38aca4f5 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -68,19 +68,19 @@ org.assertj assertj-core - 2.6.0 + 3.22.0 test org.eclipse.jetty jetty-servlet - 11.0.2 + 11.0.7 test org.mockito mockito-core - 2.28.2 + 4.3.1 test diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 47d76fa8c..1e54216e0 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -66,17 +66,17 @@ org.springframework.boot spring-boot-actuator - 1.5.4.RELEASE + 1.5.22.RELEASE org.springframework.boot spring-boot-starter-aop - 1.5.4.RELEASE + 1.5.22.RELEASE org.apache.commons commons-lang3 - 3.4 + 3.12.0 @@ -95,13 +95,13 @@ org.springframework.boot spring-boot-starter-test - 1.5.4.RELEASE + 1.5.22.RELEASE test org.springframework.boot spring-boot-starter-web - 1.5.4.RELEASE + 1.5.22.RELEASE test diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index f88b8618c..462fa94e3 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -61,27 +61,27 @@ org.springframework spring-web - 4.3.9.RELEASE + 4.3.30.RELEASE org.springframework spring-aop - 4.3.9.RELEASE + 4.3.30.RELEASE org.springframework spring-context - 4.3.9.RELEASE + 4.3.30.RELEASE org.aspectj aspectjweaver - 1.8.6 + 1.9.7 org.apache.commons commons-lang3 - 3.4 + 3.12.0 @@ -94,7 +94,7 @@ org.springframework spring-test - 4.2.3.RELEASE + 4.3.30.RELEASE test diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 61c9a12b7..fe0320026 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -75,7 +75,7 @@ org.assertj assertj-core - 2.6.0 + 3.22.0 test From 3568b2477c60dcde4d9380b666ad60a33d0f4208 Mon Sep 17 00:00:00 2001 From: Jens Date: Thu, 3 Feb 2022 22:59:24 +0100 Subject: [PATCH 133/980] Remove call to Math.floor in f() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we can be sure that the result is always positive, rounding down is faster than using Math.floor while getting the same result. ``` Benchmark Mode Cnt Score Error Units CKMSQuantileBenchmark.ckmsQuantileF avgt 4 37,188 ± 6,681 ns/op CKMSQuantileBenchmark.ckmsQuantileF avgt 4 20,500 ± 1,054 ns/op <= Without floor() ``` Signed-off-by: Jens --- .../client/CKMSQuantileBenchmark.java | 88 ++++++++++++------- .../io/prometheus/client/CKMSQuantiles.java | 4 +- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java index 0f36212b5..21c9bc0ce 100644 --- a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java @@ -8,7 +8,10 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; import java.util.concurrent.TimeUnit; public class CKMSQuantileBenchmark { @@ -18,79 +21,102 @@ public static class EmptyBenchmarkState { @Param({"10000", "100000", "1000000"}) public int value; - CKMSQuantiles ckmsQuantiles; - List quantiles; Random rand = new Random(0); - long[] shuffle; + List shuffle; + + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); @Setup(Level.Trial) public void setup() { quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.050)); - quantiles.add(new Quantile(0.90, 0.010)); - quantiles.add(new Quantile(0.95, 0.005)); - quantiles.add(new Quantile(0.99, 0.001)); - - - shuffle = new long[value]; - for (int i = 0; i < shuffle.length; i++) { - shuffle[i] = i; + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); } - Collections.shuffle(Arrays.asList(shuffle), rand); - + Collections.shuffle(shuffle, rand); } } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.MILLISECONDS) - public void ckmsQuantileInsertBenchmark(Blackhole blackhole, EmptyBenchmarkState state) { + public void ckmsQuantileInsertBenchmark(EmptyBenchmarkState state) { CKMSQuantiles q = new CKMSQuantiles(state.quantiles.toArray(new Quantile[]{})); - for (long l : state.shuffle) { + for (Double l : state.shuffle) { q.insert(l); } } + /** prefilled benchmark, means that we already have a filled and compressed samples available */ @State(Scope.Benchmark) public static class PrefilledBenchmarkState { - public int value = 1000000; + @Param({"10000", "100000", "1000000"}) + public int value; + CKMSQuantiles ckmsQuantiles; List quantiles; Random rand = new Random(0); - long[] shuffle; + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); + List shuffle; + + int rank = (int) (value * q95.quantile); + @Setup(Level.Trial) public void setup() { quantiles = new ArrayList(); - quantiles.add(new Quantile(0.50, 0.050)); - quantiles.add(new Quantile(0.90, 0.010)); - quantiles.add(new Quantile(0.95, 0.005)); - quantiles.add(new Quantile(0.99, 0.001)); + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); + } + Collections.shuffle(shuffle, rand); - shuffle = new long[value]; - for (int i = 0; i < shuffle.length; i++) { - shuffle[i] = i; - } - Collections.shuffle(Arrays.asList(shuffle), rand); ckmsQuantiles = new CKMSQuantiles(quantiles.toArray(new Quantile[]{})); - for (long l : shuffle) { + for (Double l : shuffle) { ckmsQuantiles.insert(l); } - + System.out.println("Sample size is: " + ckmsQuantiles.samples.size()); } + } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void ckmsQuantileGetBenchmark(Blackhole blackhole, PrefilledBenchmarkState state) { - blackhole.consume(state.ckmsQuantiles.get(0.95)); + blackhole.consume(state.ckmsQuantiles.get(state.q90.quantile)); + } + + /** + * benchmark for the f method. + */ + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void ckmsQuantileF(Blackhole blackhole, PrefilledBenchmarkState state) { + blackhole.consume(state.ckmsQuantiles.f(state.rank)); } public static void main(String[] args) throws RunnerException { diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index ff75d6f4d..4d7d0f8bd 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -185,9 +185,9 @@ int f(int r) { // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. // To avoid running into these types of error we add 0.00000000001 before rounding down. if (r >= q.quantile * n) { - result = (int) Math.floor(q.v * r + 0.00000000001); + result = (int) (q.v * r + 0.00000000001); } else { - result = (int) Math.floor(q.u * (n - r) + 0.00000000001); + result = (int) (q.u * (n - r) + 0.00000000001); } if (result < minResult) { minResult = result; From c70a2e25e07dc30083641f7ee64ea0f242b069f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 5 Feb 2022 18:55:36 +0100 Subject: [PATCH 134/980] Bump OpenTelemetry version --- OTEL_EXEMPLARS.md | 4 ++-- .../exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java | 4 ++-- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OTEL_EXEMPLARS.md b/OTEL_EXEMPLARS.md index ea7377251..1034d52be 100644 --- a/OTEL_EXEMPLARS.md +++ b/OTEL_EXEMPLARS.md @@ -9,8 +9,8 @@ If you want to see this in action, you can run the example from the `ExemplarsCl ``` ./mvnw package cd integration_tests/it_exemplars_otel_agent/target/ -curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.2.0/opentelemetry-javaagent-all.jar -java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent-all.jar -jar ./example-spring-boot-app.jar +curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.10.1/opentelemetry-javaagent.jar +java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent.jar -jar ./example-spring-boot-app.jar ``` Now you have a Spring REST service running on [http://localhost:8080/hello](http://localhost:8080/hello) that is instrumented with the OpenTelemetry Java agent. diff --git a/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java index 094f04fb6..7736f3595 100644 --- a/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java +++ b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java @@ -25,13 +25,13 @@ public class ExemplarsOpenTelemetryAgentIT { private final String image = "openjdk:11-jre"; - private final String otelAgentVersion = "1.2.0"; + private final String otelAgentVersion = "1.10.1"; private final Volume volume; private final GenericContainer javaContainer; public ExemplarsOpenTelemetryAgentIT() throws IOException, URISyntaxException { String appJar = "example-spring-boot-app.jar"; - String agentJar = "opentelemetry-javaagent-all.jar"; + String agentJar = "opentelemetry-javaagent.jar"; String agentDownloadUrl = "https://github.com/open-telemetry/opentelemetry-java-instrumentation/" + "releases/download/v" + otelAgentVersion + "/" + agentJar; Downloader.downloadToTarget(agentDownloadUrl, agentJar); diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index e4b647be8..aae7a515d 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -12,7 +12,7 @@ Integration Tests - Exemplars with OpenTelemetry - 1.2.0 + 1.10.1 diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 941d2073f..918bfcb32 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -18,7 +18,7 @@ io.opentelemetry opentelemetry-api - 1.0.1 + 1.10.1 From c205ef3edbb31da0808fa526e19b1025fad7f30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 5 Feb 2022 22:54:37 +0100 Subject: [PATCH 135/980] Fix JavaDoc warnings --- README.md | 2 +- .../io/prometheus/client/SimpleCollector.java | 2 +- .../main/java/io/prometheus/client/Summary.java | 16 ++++++++-------- .../client/jetty/JettyStatisticsCollector.java | 5 ++--- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 841183eca..cc160e338 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ when using this approach ensure the value you are reporting accounts for concurr ### Summary -Summaries and Histograms can both be used to monitor latencies (or other things like request sizes). +Summaries and Histograms can both be used to monitor distributions, like latencies or request sizes. An overview of when to use Summaries and when to use Histograms can be found on [https://prometheus.io/docs/practices/histograms](https://prometheus.io/docs/practices/histograms). diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java index ec321ba0a..5c5bf7c37 100644 --- a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java +++ b/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java @@ -11,7 +11,7 @@ *

* This class handles common initialization and label logic for the standard metrics. * You should never subclass this class. - *

+ * *

Initialization

* After calling build() on a subclass, {@link Builder#name(String) name}, * {@link SimpleCollector.Builder#help(String) help}, diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index e60f33da1..8836cbe7d 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit; /** - * {@link Summary} metrics and {@link Histogram} metrics can both be used to monitor latencies (or other things like request sizes). + * {@link Summary} metrics and {@link Histogram} metrics can both be used to monitor distributions like latencies or request sizes. *

* An overview of when to use Summaries and when to use Histograms can be found on https://prometheus.io/docs/practices/histograms. *

@@ -47,12 +47,12 @@ * The {@link Summary} class provides different utility methods for observing values, like {@link #observe(double)}, * {@link #startTimer()} and {@link Timer#observeDuration()}, {@link #time(Callable)}, etc. *

- * By default, {@link Summary} metrics provide the count and the sum. For example, if you measure - * latencies of a REST service, the count will tell you how often the REST service was called, - * and the sum will tell you the total aggregated response time. - * You can calculate the average response time using a Prometheus query dividing sum / count. + * By default, {@link Summary} metrics provide the {@code count} and the {@code sum}. For example, if you measure + * latencies of a REST service, the {@code count} will tell you how often the REST service was called, + * and the {@code sum} will tell you the total aggregated response time. + * You can calculate the average response time using a Prometheus query dividing {@code sum / count}. *

- * In addition to count and sum, you can configure a Summary to provide quantiles: + * In addition to {@code count} and {@code sum}, you can configure a Summary to provide quantiles: * *

  * Summary requestLatency = Summary.build()
@@ -76,9 +76,9 @@
  *
  * 
    *
  • You can set an allowed error of 0, but then the {@link Summary} will keep all observations in memory.
  • - *
  • You can track the minimum value with .quantile(0.0, 0.0). + *
  • You can track the minimum value with {@code .quantile(0.0, 0.0)}. * This special case will not use additional memory even though the allowed error is 0.
  • - *
  • You can track the maximum value with .quantile(1.0, 0.0). + *
  • You can track the maximum value with {@code .quantile(1.0, 0.0)}. * This special case will not use additional memory even though the allowed error is 0.
  • *
* diff --git a/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java b/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java index 8907ba151..7dddb00aa 100644 --- a/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java +++ b/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java @@ -9,8 +9,7 @@ /** * Collect metrics from jetty's org.eclipse.jetty.server.handler.StatisticsHandler. - *

- *

{@code
+ * 
  * Server server = new Server(8080);
  *
  * ServletContextHandler context = new ServletContextHandler();
@@ -29,7 +28,7 @@
  * server.setHandler(handlers);
  *
  * server.start();
- * }
+ *
*/ public class JettyStatisticsCollector extends Collector { private final StatisticsHandler statisticsHandler; From eb70395cd8db09bd61ae3755caf91d0687f54d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 5 Feb 2022 23:05:53 +0100 Subject: [PATCH 136/980] [maven-release-plugin] prepare release parent-0.15.0 --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index d07a1dde3..529230342 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index b17d40a01..6b1d963e6 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 91347bb60..9b97e1964 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index aae7a515d..91e06ab20 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index e62ad864a..1eb360b22 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 138d2d6a4..99ef82e4c 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index b58191247..77144f52a 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index cbfb8214e..23eba5bf0 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.14.2-SNAPSHOT + 0.15.0 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 98ca9d6c0..022c47b7c 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 integration_tests diff --git a/pom.xml b/pom.xml index 56f08c4c0..dde08f750 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.15.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 6f6af4b2e..5ee3f2f83 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 2655d46da..ca5673832 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index a1d5e8f11..5b07408f1 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 8b6265d99..42b8c73b1 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 8efebfee2..8493ffe83 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 4a6ffeb42..99c20fda0 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 14e526ab4..bf424cc99 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index c9908d937..5284e6aee 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 18099475e..772317d85 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_servlet - 0.14.2-SNAPSHOT + 0.15.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 34b644534..aa2219401 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index e23440ef8..257661eef 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index f4e3e4794..fc956bba7 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 209797050..1bf5a7ae9 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 org.apache.logging.log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 1d4826f65..fa251960d 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index c673eac79..e965cee5d 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 49af6da84..f52a88ee9 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 98c1c0fd2..930033855 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_servlet_common - 0.14.2-SNAPSHOT + 0.15.0 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 632431d3c..5ee4ccbf0 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index c38aca4f5..40ffcd67c 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_servlet_common - 0.14.2-SNAPSHOT + 0.15.0 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 1e54216e0..27a1f07d1 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_spring_web - 0.14.2-SNAPSHOT + 0.15.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 462fa94e3..0bd3581ca 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 918bfcb32..8fa70c1c0 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index c46853511..ce46022c0 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 0084319a2..f03e96baf 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index c9d6a593f..6559706e2 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index fe0320026..1304c2577 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.14.2-SNAPSHOT + 0.15.0 simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.14.2-SNAPSHOT + 0.15.0 io.prometheus simpleclient_common - 0.14.2-SNAPSHOT + 0.15.0 io.vertx From fa3c747129d1195624b722b11fdf0947c68e356e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 5 Feb 2022 23:05:57 +0100 Subject: [PATCH 137/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 6 +++--- 36 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 529230342..e008615ae 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 6b1d963e6..05bc4a886 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 9b97e1964..2ac1266d7 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 91e06ab20..aa9096d94 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 1eb360b22..3d3c86f75 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 99ef82e4c..15f296931 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 77144f52a..f199d5601 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 23eba5bf0..072b567c9 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.0 + 0.15.1-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 022c47b7c..eeacb74b8 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index dde08f750..1e4fb9d8b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.15.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 5ee3f2f83..c0067869a 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index ca5673832..d79c63d0b 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 5b07408f1..90005fa7c 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 42b8c73b1..fac75ceef 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 8493ffe83..b05def52f 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 99c20fda0..a5858ed20 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index bf424cc99..e4d7be62b 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 5284e6aee..585b71eba 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 772317d85..d079df396 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.15.0 + 0.15.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index aa2219401..e0d2ba6d9 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 257661eef..4ccae9591 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index fc956bba7..310d2d198 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 1bf5a7ae9..dfaec19d4 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index fa251960d..1006522c8 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index e965cee5d..6642ec681 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index f52a88ee9..4971eb0ab 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 930033855..9aab58f58 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.15.0 + 0.15.1-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 5ee4ccbf0..15578ea90 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 40ffcd67c..766cfd7f1 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.15.0 + 0.15.1-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 27a1f07d1..7c69ce2b2 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.15.0 + 0.15.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 0bd3581ca..f0ff5280b 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 8fa70c1c0..dd646182e 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index ce46022c0..acc02c7ce 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index f03e96baf..f60633366 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 6559706e2..9ed206650 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 1304c2577..31619a4b3 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.15.0 + 0.15.1-SNAPSHOT simpleclient_vertx @@ -52,12 +52,12 @@ io.prometheus simpleclient - 0.15.0 + 0.15.1-SNAPSHOT io.prometheus simpleclient_common - 0.15.0 + 0.15.1-SNAPSHOT io.vertx From c16d4ae26630686f56b4b8d898e94bba7f8e8229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 6 Feb 2022 00:04:31 +0100 Subject: [PATCH 138/980] Update client_java version in README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cc160e338..b6dd47033 100644 --- a/README.md +++ b/README.md @@ -46,25 +46,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.12.0 + 0.15.0 io.prometheus simpleclient_hotspot - 0.12.0 + 0.15.0 io.prometheus simpleclient_httpserver - 0.12.0 + 0.15.0 io.prometheus simpleclient_pushgateway - 0.12.0 + 0.15.0 ``` From 95872fc77cd55f88de9ee377e07fbc4aa2410ff7 Mon Sep 17 00:00:00 2001 From: Jens Date: Sat, 5 Feb 2022 21:49:47 +0100 Subject: [PATCH 139/980] Extract upperbound calculation The upperbound is constant for a given quantile. By calculating this once we save O(iterator size * quantiles size) calculations of this constant. Signed-off-by: Jens --- .../main/java/io/prometheus/client/CKMSQuantileBenchmark.java | 4 ++++ .../src/main/java/io/prometheus/client/CKMSQuantiles.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java index 21c9bc0ce..530810481 100644 --- a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java @@ -97,6 +97,10 @@ public void setup() { for (Double l : shuffle) { ckmsQuantiles.insert(l); } + // make sure we inserted all 'hanging' samples (count % 128) + ckmsQuantiles.get(0); + // compress everything so we have a similar samples size regardless of n. + ckmsQuantiles.compress(); System.out.println("Sample size is: " + ckmsQuantiles.samples.size()); } diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java index 4d7d0f8bd..78126efc8 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java +++ b/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java @@ -152,11 +152,12 @@ public double get(double q) { int r = 0; // sum of g's left of the current sample int desiredRank = (int) Math.ceil(q * n); + int upperBound = desiredRank + f(desiredRank) / 2; ListIterator iterator = samples.listIterator(); while (iterator.hasNext()) { Sample sample = iterator.next(); - if (r + sample.g + sample.delta > desiredRank + f(desiredRank) / 2) { + if (r + sample.g + sample.delta > upperBound) { iterator.previous(); // roll back the item.next() above if (iterator.hasPrevious()) { Sample result = iterator.previous(); From 2f4b01bb0893d3bead6164239bc9c3cd822acf0a Mon Sep 17 00:00:00 2001 From: Fredrik Svensson Date: Thu, 10 Mar 2022 09:38:29 +0100 Subject: [PATCH 140/980] Fix conditional for jvm_memory_bytes_committed Signed-off-by: Fredrik Svensson --- .../java/io/prometheus/client/hotspot/MemoryPoolsExports.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java index 4729fbe70..978fdc972 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java @@ -89,7 +89,7 @@ void addMemoryAreaMetrics(List sampleFamilies, Predicate Date: Mon, 14 Mar 2022 19:50:31 +0000 Subject: [PATCH 141/980] Update common Prometheus files Signed-off-by: prombot --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bc7849e68..b7b9e2afe 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,4 +17,4 @@ jobs: - ~/.m2 key: maven-dependencies-{{ checksum "pom.xml" }} orbs: - prometheus: prometheus/prometheus@0.15.0 + prometheus: prometheus/prometheus@0.16.0 From 756b5ebcda6d9b5b5c9f66ac565cd459153ff3b4 Mon Sep 17 00:00:00 2001 From: Fabrice Scellos Date: Wed, 16 Feb 2022 18:50:01 +0100 Subject: [PATCH 142/980] Adding TraceSampling to Examplar Sampler - Signed-off-by: Fabrice Scellos Signed-off-by: Fabrice Scellos --- .gitignore | 4 ++ .../client/benchmark/ExemplarsBenchmark.java | 5 ++ .../exemplars/DefaultExemplarSampler.java | 5 +- .../exemplars/DefaultExemplarSamplerTest.java | 52 ++++++++++++++++--- .../tracer/common/SpanContextSupplier.java | 7 +++ .../OpenTelemetrySpanContextSupplier.java | 5 ++ ...OpenTelemetryAgentSpanContextSupplier.java | 5 ++ 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index cec774d92..14ec2f863 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ simpleclient_pushgateway/mockserver.log simpleclient_pushgateway/mockserver_request.log nb-configuration.xml dependency-reduced-pom.xml + +**/.classpath +**.project +**/.settings/ diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java index 2c2acc29c..7d033afcd 100644 --- a/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java @@ -76,5 +76,10 @@ public String getTraceId() { public String getSpanId() { return "span-id"; } + + @Override + public boolean isSampled() { + return true; + } } } diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java index 759055cb9..40b7e3209 100644 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java +++ b/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java @@ -41,8 +41,9 @@ public Exemplar sample(double value, double bucketFrom, double bucketTo, Exempla private Exemplar doSample(double value, Exemplar previous) { long timestampMs = clock.currentTimeMillis(); - if (previous == null || previous.getTimestampMs() == null - || timestampMs - previous.getTimestampMs() > minRetentionIntervalMs) { + if ((previous == null || previous.getTimestampMs() == null + || timestampMs - previous.getTimestampMs() > minRetentionIntervalMs) + && spanContextSupplier.isSampled()) { String spanId = spanContextSupplier.getSpanId(); String traceId = spanContextSupplier.getTraceId(); if (traceId != null && spanId != null) { diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java index 8936e6e5f..2cc982f20 100644 --- a/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java @@ -1,15 +1,16 @@ package io.prometheus.client.exemplars; -import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import static java.lang.Double.NEGATIVE_INFINITY; +import static java.lang.Double.POSITIVE_INFINITY; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import static java.lang.Double.NEGATIVE_INFINITY; -import static java.lang.Double.POSITIVE_INFINITY; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; public class DefaultExemplarSamplerTest { @@ -20,6 +21,7 @@ public class DefaultExemplarSamplerTest { final AtomicReference spanId = new AtomicReference(); final AtomicLong timestamp = new AtomicLong(); DefaultExemplarSampler defaultSampler; + DefaultExemplarSampler defaultSamplerWithNoSample; final SpanContextSupplier testContext = new SpanContextSupplier() { @Override @@ -31,7 +33,30 @@ public String getTraceId() { public String getSpanId() { return spanId.get(); } - }; + + @Override + public boolean isSampled() { + return true; + } + }; + + final SpanContextSupplier testContextNoSample = new SpanContextSupplier() { + + @Override + public String getTraceId() { + return traceId.get(); + } + + @Override + public String getSpanId() { + return spanId.get(); + } + + @Override + public boolean isSampled() { + return false; + } + }; final DefaultExemplarSampler.Clock testClock = new DefaultExemplarSampler.Clock() { @Override @@ -46,6 +71,7 @@ public void setUp() { spanId.set("span-1"); timestamp.set(System.currentTimeMillis()); defaultSampler = new DefaultExemplarSampler(testContext, testClock); + defaultSamplerWithNoSample = new DefaultExemplarSampler(testContextNoSample, testClock); } @Test @@ -68,6 +94,18 @@ public void testCounter() { Assert.assertNull(sampler.sample(4.0, null)); } + @Test + public void testCounterWithNoSample() { + CounterExemplarSampler sampler = defaultSamplerWithNoSample; + Assert.assertEquals(null, sampler.sample(2.0, null)); + } + + @Test + public void testHistogramWithNoSample() { + HistogramExemplarSampler sampler = defaultSamplerWithNoSample; + Assert.assertEquals(null, sampler.sample(2.0, NEGATIVE_INFINITY, POSITIVE_INFINITY, null)); + } + @Test public void testHistogram() { HistogramExemplarSampler sampler = defaultSampler; diff --git a/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java index ce068323e..583021a45 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java +++ b/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java @@ -11,4 +11,11 @@ public interface SpanContextSupplier { * @return the current span id, or {@code null} if this call is not happening within a span context. */ String getSpanId(); + + /** + * @return the state of the current Span. If this value is false a component before in the chain take the decision to not record it. Subsequent calling service have + * to respect this value in order not to have partial TraceID with only some Span in it. This value is important to be sure to choose a recorded Trace in Examplar + * sampling process + */ + boolean isSampled(); } \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java index 1d298e522..8226fe1d8 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java +++ b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java @@ -36,4 +36,9 @@ public String getSpanId() { String spanId = Span.current().getSpanContext().getSpanId(); return SpanId.isValid(spanId) ? spanId : null; } + + @Override + public boolean isSampled() { + return Span.current().getSpanContext().isSampled(); + } } diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java index dca7c8488..b8b0db197 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java @@ -41,4 +41,9 @@ public String getSpanId() { String spanId = Span.current().getSpanContext().getSpanId(); return SpanId.isValid(spanId) ? spanId : null; } + + @Override + public boolean isSampled() { + return Span.current().getSpanContext().isSampled(); + } } From 4edf91118760f06e7b9ba12937b18850de343972 Mon Sep 17 00:00:00 2001 From: Fabrice Scellos Date: Wed, 16 Feb 2022 19:27:00 +0100 Subject: [PATCH 143/980] Fix IT test as they use a fix version 0.12.0 and not the current project one for some components Signed-off-by: Fabrice Scellos --- integration_tests/it_exemplars_otel_agent/pom.xml | 15 +++++++++++++++ .../ExemplarsOpenTelemetryAgentIT.java | 1 + 2 files changed, 16 insertions(+) diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 2ac1266d7..00a86e9e8 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -37,6 +37,21 @@ io.prometheus simpleclient ${project.version} + + + io.prometheus + simpleclient_tracer_common + ${project.version} + + + io.prometheus + simpleclient_tracer_otel + ${project.version} + + + io.prometheus + simpleclient_tracer_otel_agent + ${project.version} io.prometheus diff --git a/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java index 7736f3595..9dc36f6e9 100644 --- a/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java +++ b/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java @@ -42,6 +42,7 @@ public ExemplarsOpenTelemetryAgentIT() throws IOException, URISyntaxException { "java", "-Dotel.traces.exporter=logging", "-Dotel.metrics.exporter=none", + "-Dotel.traces.sampler=always_on", "-javaagent:/app/" + agentJar, "-jar", "/app/" + appJar From ca6145fdf8ad01093f09d1168fd683a1c6c64e59 Mon Sep 17 00:00:00 2001 From: Fabrice Scellos Date: Thu, 17 Mar 2022 08:45:55 +0100 Subject: [PATCH 144/980] Taking account of Fabian's propositions Signed-off-by: Fabrice Scellos --- .../it_exemplars_otel_agent/pom.xml | 27 +++++----------- simpleclient_bom/pom.xml | 5 +++ .../OpenTelemetrySpanContextSupplier.java | 31 ++++++++++--------- ...OpenTelemetryAgentSpanContextSupplier.java | 1 + 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 00a86e9e8..a7928612a 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -20,6 +20,13 @@ pom import + + io.prometheus + simpleclient_bom + ${project.version} + pom + import + @@ -33,26 +40,6 @@ okhttp compile - - io.prometheus - simpleclient - ${project.version} - - - io.prometheus - simpleclient_tracer_common - ${project.version} - - - io.prometheus - simpleclient_tracer_otel - ${project.version} - - - io.prometheus - simpleclient_tracer_otel_agent - ${project.version} - io.prometheus simpleclient_hotspot diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index d79c63d0b..2e8edbe44 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -71,6 +71,11 @@ simpleclient_httpserver ${project.version} + + io.prometheus + simpleclient_tracer_common + ${project.version} + io.prometheus simpleclient_jetty diff --git a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java index 8226fe1d8..0ae3ce1ce 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java +++ b/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java @@ -7,7 +7,7 @@ public class OpenTelemetrySpanContextSupplier implements SpanContextSupplier { - public static boolean isAvailable() { + public static boolean isAvailable() { try { if ("inactive".equalsIgnoreCase(System.getProperties().getProperty("io.prometheus.otelExemplars"))) { return false; @@ -15,6 +15,7 @@ public static boolean isAvailable() { OpenTelemetrySpanContextSupplier test = new OpenTelemetrySpanContextSupplier(); test.getSpanId(); test.getTraceId(); + test.isSampled(); return true; } catch (LinkageError ignored) { // NoClassDefFoundError: @@ -25,20 +26,20 @@ public static boolean isAvailable() { } } - @Override - public String getTraceId() { - String traceId = Span.current().getSpanContext().getTraceId(); - return TraceId.isValid(traceId) ? traceId : null; - } + @Override + public String getTraceId() { + String traceId = Span.current().getSpanContext().getTraceId(); + return TraceId.isValid(traceId) ? traceId : null; + } - @Override - public String getSpanId() { - String spanId = Span.current().getSpanContext().getSpanId(); - return SpanId.isValid(spanId) ? spanId : null; - } + @Override + public String getSpanId() { + String spanId = Span.current().getSpanContext().getSpanId(); + return SpanId.isValid(spanId) ? spanId : null; + } - @Override - public boolean isSampled() { - return Span.current().getSpanContext().isSampled(); - } + @Override + public boolean isSampled() { + return Span.current().getSpanContext().isSampled(); + } } diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java index b8b0db197..3a5b418b2 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java @@ -20,6 +20,7 @@ public static boolean isAvailable() { OpenTelemetryAgentSpanContextSupplier test = new OpenTelemetryAgentSpanContextSupplier(); test.getSpanId(); test.getTraceId(); + test.isSampled(); return true; } catch (LinkageError ignored) { // NoClassDefFoundError: From 989cbd1f4f249d84dbdf4b9e91b9676cc64022b6 Mon Sep 17 00:00:00 2001 From: Flavio Brasil Date: Tue, 26 Apr 2022 15:14:45 -0400 Subject: [PATCH 145/980] optimize Collector.sanitizeMetricName Signed-off-by: Flavio Brasil --- .../SanitizeMetricNameBenchmark.java | 53 +++++++++++++++++++ .../java/io/prometheus/client/Collector.java | 20 ++++--- .../io/prometheus/client/CollectorTest.java | 26 +++++++++ 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java b/benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java new file mode 100644 index 000000000..d89e676e5 --- /dev/null +++ b/benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java @@ -0,0 +1,53 @@ +package io.prometheus.client.benchmark; + +import com.codahale.metrics.MetricRegistry; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +import io.prometheus.client.Collector; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +@State(Scope.Benchmark) +public class SanitizeMetricNameBenchmark { + + @Benchmark + @BenchmarkMode({ Mode.AverageTime }) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void sanitizeSanitizedName() { + Collector.sanitizeMetricName("good_name"); + } + + @Benchmark + @BenchmarkMode({ Mode.AverageTime }) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void sanitizeNonSanitizedName() { + Collector.sanitizeMetricName("9not_good_name!"); + } + + public static void main(String[] args) throws RunnerException { + + Options opt = new OptionsBuilder() + .include(SanitizeMetricNameBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .measurementTime(TimeValue.seconds(1)) + .warmupTime(TimeValue.seconds(1)) + .threads(4) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java index 3a69500dc..6f84e1840 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Collector.java +++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java @@ -352,16 +352,24 @@ protected static void checkMetricName(String name) { } } - private static final Pattern SANITIZE_PREFIX_PATTERN = Pattern.compile("^[^a-zA-Z_:]"); - private static final Pattern SANITIZE_BODY_PATTERN = Pattern.compile("[^a-zA-Z0-9_:]"); - /** * Sanitize metric name */ public static String sanitizeMetricName(String metricName) { - return SANITIZE_BODY_PATTERN.matcher( - SANITIZE_PREFIX_PATTERN.matcher(metricName).replaceFirst("_") - ).replaceAll("_"); + int length = metricName.length(); + char[] sanitized = new char[length]; + for(int i = 0; i < length; i++) { + char ch = metricName.charAt(i); + if(ch == ':' || + (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (i > 0 && ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } + } + return new String(sanitized); } /** diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java index dbf611322..73603a37c 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java @@ -9,6 +9,32 @@ import static org.junit.Assert.*; public class CollectorTest { + + @Test + public void sanitizeMetricPrefix() throws Exception { + assertEquals("afoo", Collector.sanitizeMetricName("afoo")); + assertEquals("zfoo", Collector.sanitizeMetricName("zfoo")); + assertEquals("Afoo", Collector.sanitizeMetricName("Afoo")); + assertEquals("Zfoo", Collector.sanitizeMetricName("Zfoo")); + assertEquals(":foo", Collector.sanitizeMetricName(":foo")); + + assertEquals("_foo", Collector.sanitizeMetricName("0foo")); + assertEquals("_foo", Collector.sanitizeMetricName("5foo")); + assertEquals("_foo", Collector.sanitizeMetricName("9foo")); + assertEquals("_foo", Collector.sanitizeMetricName("/foo")); + assertEquals("_foo", Collector.sanitizeMetricName("*foo")); + } + + @Test + public void sanitizeMetricBody() throws Exception { + assertEquals("aamzAMZ059", Collector.sanitizeMetricName("aamzAMZ059")); + assertEquals("aaMzAmZ009", Collector.sanitizeMetricName("aaMzAmZ009")); + assertEquals("aZmA950aMz", Collector.sanitizeMetricName("aZmA950aMz")); + assertEquals("aZ9mA0a5Mz", Collector.sanitizeMetricName("aZ9mA0a5Mz")); + assertEquals("aZ9mA_0a5Mz", Collector.sanitizeMetricName("aZ9mA*0a5Mz")); + assertEquals("aZ9mA_0a5Mz", Collector.sanitizeMetricName("aZ9mA&0a5Mz")); + } + @Test public void sanitizeMetricName() throws Exception { assertEquals("_hoge", Collector.sanitizeMetricName("0hoge")); From 1f859efca54b679e5c22dedc1a194b837c2c63d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 4 May 2022 12:07:16 +0200 Subject: [PATCH 146/980] Bump dependency versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- benchmarks/pom.xml | 4 +- .../it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../pom.xml | 2 +- integration_tests/pom.xml | 4 +- pom.xml | 25 +++++++---- simpleclient_caffeine/pom.xml | 4 +- simpleclient_dropwizard/pom.xml | 4 +- simpleclient_guava/pom.xml | 4 +- simpleclient_hibernate/pom.xml | 4 +- simpleclient_hotspot/pom.xml | 4 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_log4j/pom.xml | 6 +-- simpleclient_log4j2/pom.xml | 4 +- simpleclient_logback/pom.xml | 4 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 4 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 4 +- version-rules.xml | 41 +++++++++++++++++++ 24 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 version-rules.xml diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index e008615ae..affc22fef 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -27,12 +27,12 @@ org.openjdk.jmh jmh-core - 1.34 + 1.35 org.openjdk.jmh jmh-generator-annprocess - 1.34 + 1.35 javax.annotation diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index a7928612a..5a1df5886 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -58,7 +58,7 @@ ch.qos.logback logback-classic - 1.2.10 + 1.2.11 test diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 15f296931..5349f32b8 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -12,7 +12,7 @@ Integration Tests - log4j2 - 2.17.1 + 2.17.2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index f199d5601..cc8402e52 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -36,7 +36,7 @@ ch.qos.logback logback-classic - 1.2.10 + 1.2.11 test diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 072b567c9..d23323a07 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -45,7 +45,7 @@ ch.qos.logback logback-classic - 1.2.10 + 1.2.11 jakarta.servlet diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index eeacb74b8..9dc769a0e 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -56,7 +56,7 @@ org.testcontainers testcontainers - 1.16.3 + 1.17.0 test @@ -68,7 +68,7 @@ ch.qos.logback logback-classic - 1.2.10 + 1.2.11 test diff --git a/pom.xml b/pom.xml index 1e07543e4..5be64aec3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + pom 4.0.0 @@ -177,10 +178,10 @@ org.apache.maven.plugins maven-release-plugin - true - false - release - deploy + true + false + release + deploy @@ -225,6 +226,14 @@ 1.6 + + org.codehaus.mojo + versions-maven-plugin + 2.10.0 + + file://${session.executionRootDirectory}/version-rules.xml + + @@ -280,9 +289,9 @@ attach-sources - - jar-no-fork - + + jar-no-fork + diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 90005fa7c..b70305f13 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -41,7 +41,7 @@ com.github.ben-manes.caffeine caffeine - 2.9.3 + 3.0.0 @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index b05def52f..9151402f2 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -39,7 +39,7 @@ io.dropwizard.metrics metrics-core - 4.2.8 + 4.2.9 provided @@ -58,7 +58,7 @@ org.mockito mockito-core - 2.28.2 + 3.0.0 test diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index e4d7be62b..4a12db7b5 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -41,7 +41,7 @@ com.google.guava guava - 31.0.1-jre + 31.1-jre @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 585b71eba..285f43045 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -44,7 +44,7 @@ org.hibernate hibernate-core - 5.6.5.Final + 5.6.6.Final provided @@ -58,7 +58,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index d079df396..f6a0a7c26 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -55,14 +55,14 @@ org.mockito mockito-core - 2.28.2 + 3.0.0 test org.eclipse.jetty jetty-servlet - 8.2.0.v20160908 + 9.4.44.v20210927 test diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 4ccae9591..1b0c20352 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -17,7 +17,7 @@ - 9.4.41.v20210516 + 9.4.44.v20210927 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index dfaec19d4..5c04800ed 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -41,13 +41,13 @@ org.apache.logging.log4j log4j-core - 2.17.1 + 2.17.2 provided org.apache.logging.log4j log4j-1.2-api - 2.17.1 + 2.17.2 provided @@ -61,7 +61,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 1006522c8..076d153c9 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -41,7 +41,7 @@ org.apache.logging.log4j log4j-core - 2.17.1 + 2.17.2 provided @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 6642ec681..839481067 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -41,7 +41,7 @@ ch.qos.logback logback-classic - 1.2.10 + 1.2.11 @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 4971eb0ab..32ef40494 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -60,7 +60,7 @@ org.mock-server mockserver-netty - 3.9.17 + 3.10.0 test diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 9aab58f58..8b600176e 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -55,7 +55,7 @@ javax.servlet javax.servlet-api - 3.1.0 + 4.0.0 provided @@ -80,7 +80,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 766cfd7f1..a03c64259 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -80,7 +80,7 @@ org.mockito mockito-core - 4.3.1 + 4.4.0 test diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index f0ff5280b..1881434e4 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -76,7 +76,7 @@ org.aspectj aspectjweaver - 1.9.7 + 1.9.8 org.apache.commons diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index dd646182e..f01215007 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -18,7 +18,7 @@ io.opentelemetry opentelemetry-api - 1.10.1 + 1.11.0 diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 22b56a8ac..0e0382441 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -62,7 +62,7 @@ io.vertx vertx-web - 3.9.12 + 3.9.13 provided diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index f8939e184..027a8ab0a 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -62,7 +62,7 @@ io.vertx vertx-web - 4.2.3 + 4.2.4 provided @@ -75,7 +75,7 @@ org.assertj assertj-core - 2.6.0 + 2.7.0 test diff --git a/version-rules.xml b/version-rules.xml new file mode 100644 index 000000000..567d9b200 --- /dev/null +++ b/version-rules.xml @@ -0,0 +1,41 @@ + + + + + .*-RC\d + .*\.RC\d + .*alpha.* + .*\.M\d + + + + + .*-b\d\d + + + + + .*-android + + + + + 2\..* + + + + + + [^8].* + + + + + + [^4].* + + + + \ No newline at end of file From c61d2eb1eaa3ac8fde8412da576eef26b5955a74 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Tue, 3 May 2022 17:04:24 -0400 Subject: [PATCH 147/980] Added code to HTTPServer.Builder to use ExecutorService Signed-off-by: Doug Hoard --- .../client/exporter/HTTPServer.java | 33 ++++++++++--- .../client/exporter/TestHTTPServer.java | 49 +++++++++++++++++++ 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index 834c32480..b7188a95c 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -199,6 +199,7 @@ public static class Builder { private InetAddress inetAddress = null; private InetSocketAddress inetSocketAddress = null; private HttpServer httpServer = null; + private ExecutorService executorService = null; private CollectorRegistry registry = CollectorRegistry.defaultRegistry; private boolean daemon = false; private Predicate sampleNameFilter; @@ -248,13 +249,26 @@ public Builder withInetSocketAddress(InetSocketAddress address) { /** * Use this httpServer. The {@code httpServer} is expected to already be bound to an address. * Must not be called together with {@link #withPort(int)}, or {@link #withHostname(String)}, - * or {@link #withInetAddress(InetAddress)}, or {@link #withInetSocketAddress(InetSocketAddress)}. + * or {@link #withInetAddress(InetAddress)}, or {@link #withInetSocketAddress(InetSocketAddress)}, + * or {@link #withExecutorService(ExecutorService)}. */ public Builder withHttpServer(HttpServer httpServer) { this.httpServer = httpServer; return this; } + /** + * Optional: ExecutorService used by the {@code httpServer}. + * Must not be called together with the {@link #withHttpServer(HttpServer)}. + * + * @param executorService + * @return + */ + public Builder withExecutorService(ExecutorService executorService) { + this.executorService = executorService; + return this; + } + /** * By default, the {@link HTTPServer} uses non-daemon threads. Set this to {@code true} to * run the {@link HTTPServer} with daemon threads. @@ -323,12 +337,13 @@ public HTTPServer build() throws IOException { } if (httpServer != null) { + assertNull(executorService, "cannot configure 'httpServer' and `executorService'"); assertZero(port, "cannot configure 'httpServer' and 'port' at the same time"); assertNull(hostname, "cannot configure 'httpServer' and 'hostname' at the same time"); assertNull(inetAddress, "cannot configure 'httpServer' and 'inetAddress' at the same time"); assertNull(inetSocketAddress, "cannot configure 'httpServer' and 'inetSocketAddress' at the same time"); assertNull(httpsConfigurator, "cannot configure 'httpServer' and 'httpsConfigurator' at the same time"); - return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); + return new HTTPServer(executorService, httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); } else if (inetSocketAddress != null) { assertZero(port, "cannot configure 'inetSocketAddress' and 'port' at the same time"); assertNull(hostname, "cannot configure 'inetSocketAddress' and 'hostname' at the same time"); @@ -350,7 +365,7 @@ public HTTPServer build() throws IOException { httpServer = HttpServer.create(inetSocketAddress, 3); } - return new HTTPServer(httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); + return new HTTPServer(executorService, httpServer, registry, daemon, sampleNameFilterSupplier, authenticator); } private void assertNull(Object o, String msg) { @@ -371,7 +386,7 @@ private void assertZero(int i, String msg) { * The {@code httpServer} is expected to already be bound to an address */ public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon) throws IOException { - this(httpServer, registry, daemon, null, null); + this(null, httpServer, registry, daemon, null, null); } /** @@ -416,7 +431,7 @@ public HTTPServer(String host, int port) throws IOException { this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, false); } - private HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon, Supplier> sampleNameFilterSupplier, Authenticator authenticator) { + private HTTPServer(ExecutorService executorService, HttpServer httpServer, CollectorRegistry registry, boolean daemon, Supplier> sampleNameFilterSupplier, Authenticator authenticator) { if (httpServer.getAddress() == null) throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); @@ -434,8 +449,12 @@ private HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean da if (authenticator != null) { mContext.setAuthenticator(authenticator); } - executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); - server.setExecutor(executorService); + if (executorService != null) { + this.executorService = executorService; + } else { + this.executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); + } + server.setExecutor(this.executorService); start(daemon); } diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index cf7f6aef4..2b18f4e82 100644 --- a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -30,6 +30,8 @@ import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.X509Certificate; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static org.assertj.core.api.Java6Assertions.assertThat; @@ -451,6 +453,53 @@ public void testHEADRequestWithSSLAndBasicAuthWrongCredentials() throws GeneralS } } + @Test + public void testExecutorService() throws IOException { + ExecutorService executorService = Executors.newFixedThreadPool(20); + + HTTPServer httpServer = new HTTPServer.Builder() + .withExecutorService(executorService) + .withRegistry(registry) + .build(); + + Assert.assertEquals(httpServer.executorService, executorService); + + try { + String body = createHttpRequestBuilder(httpServer, "/metrics").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); + } finally { + httpServer.close(); + } + } + + @Test(expected = IllegalStateException.class) + public void testExecutorServiceWithHttpServer() throws IOException { + InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 0); + + HttpServer externalHttpServer = HttpServer.create(inetSocketAddress, 0); + externalHttpServer.createContext("/metrics", new HTTPServer.HTTPMetricHandler(registry)); + externalHttpServer.start(); + + ExecutorService executorService = Executors.newFixedThreadPool(20); + + HTTPServer httpServer = new HTTPServer.Builder() + .withExecutorService(executorService) + .withHttpServer(externalHttpServer) + .withRegistry(registry) + .build(); + + try { + String body = createHttpRequestBuilder(httpServer, "/metrics").build().execute().getBody(); + assertThat(body).contains("a 0.0"); + assertThat(body).contains("b 0.0"); + assertThat(body).contains("c 0.0"); + } finally { + httpServer.close(); + } + } + /** * Encodes authorization credentials * From 1a2489fa6f30c3c0b5bcfd54c9912b267915d645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 4 May 2022 14:25:57 +0200 Subject: [PATCH 148/980] Add maintainer documentation --- MAINTAINER_NOTES.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 MAINTAINER_NOTES.md diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md new file mode 100644 index 000000000..e176bcd67 --- /dev/null +++ b/MAINTAINER_NOTES.md @@ -0,0 +1,9 @@ +# Maintainer Notes + +## Update Dependency Versions + +Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/index.html). Rules are configured in [version-rules.xml](version-rules.xml). + +``` +./mvnw versions:use-next-releases +``` From 4ce41e17c90022b2c307a3c51df5b3a917b80bed Mon Sep 17 00:00:00 2001 From: prombot Date: Tue, 3 May 2022 19:50:26 +0000 Subject: [PATCH 149/980] Update common Prometheus files Signed-off-by: prombot --- CODE_OF_CONDUCT.md | 4 ++-- SECURITY.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9a1aff412..d325872bd 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,3 @@ -## Prometheus Community Code of Conduct +# Prometheus Community Code of Conduct -Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). +Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/SECURITY.md b/SECURITY.md index 67741f015..fed02d85c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -3,4 +3,4 @@ The Prometheus security policy, including how to report vulnerabilities, can be found here: -https://prometheus.io/docs/operating/security/ + From 2f31b96666ce705e18d7216771f18c83f0dce0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 19 May 2022 23:30:03 +0200 Subject: [PATCH 150/980] Reduce number of core threads in HTTPServer to one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../prometheus/client/exporter/HTTPServer.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index b7188a95c..ffb591ab8 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -1,10 +1,15 @@ package io.prometheus.client.exporter; +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.SampleNameFilter; import io.prometheus.client.Predicate; +import io.prometheus.client.SampleNameFilter; import io.prometheus.client.Supplier; import io.prometheus.client.exporter.common.TextFormat; @@ -25,15 +30,10 @@ import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - /** * Expose Prometheus metrics using a plain Java HttpServer. *

@@ -452,7 +452,9 @@ private HTTPServer(ExecutorService executorService, HttpServer httpServer, Colle if (executorService != null) { this.executorService = executorService; } else { - this.executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); + ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); + executor.setCorePoolSize(1); + this.executorService = executor; } server.setExecutor(this.executorService); start(daemon); From 2be241cc3efeefd46c8bd7a6f403f3079a18e7e2 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Wed, 18 May 2022 07:21:31 -0400 Subject: [PATCH 151/980] Added defensive code for scenario where thread id <= 0 Signed-off-by: Doug Hoard --- .../client/hotspot/ThreadExports.java | 39 +++++-- .../client/hotspot/ThreadExportsTest.java | 100 +++++++++++++++++- 2 files changed, 128 insertions(+), 11 deletions(-) diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java index c63db20d7..42442b879 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java @@ -3,13 +3,13 @@ import io.prometheus.client.Collector; import io.prometheus.client.CounterMetricFamily; import io.prometheus.client.GaugeMetricFamily; -import io.prometheus.client.SampleNameFilter; import io.prometheus.client.Predicate; import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -36,13 +36,16 @@ */ public class ThreadExports extends Collector { + public static final String UNKNOWN = "UNKNOWN"; + + public static final String JVM_THREADS_STATE = "jvm_threads_state"; + private static final String JVM_THREADS_CURRENT = "jvm_threads_current"; private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon"; private static final String JVM_THREADS_PEAK = "jvm_threads_peak"; private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total"; private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked"; private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor"; - private static final String JVM_THREADS_STATE = "jvm_threads_state"; private final ThreadMXBean threadBean; @@ -109,10 +112,10 @@ void addThreadMetrics(List sampleFamilies, Predicate threadStateCounts = getThreadStateCountMap(); - for (Map.Entry entry : threadStateCounts.entrySet()) { + Map threadStateCounts = getThreadStateCountMap(); + for (Map.Entry entry : threadStateCounts.entrySet()) { threadStateFamily.addMetric( - Collections.singletonList(entry.getKey().toString()), + Collections.singletonList(entry.getKey()), entry.getValue() ); } @@ -120,24 +123,40 @@ void addThreadMetrics(List sampleFamilies, Predicate getThreadStateCountMap() { + private Map getThreadStateCountMap() { + long[] threadIds = threadBean.getAllThreadIds(); + + // Code to remove any thread id values <= 0 + int writePos = 0; + for (int i = 0; i < threadIds.length; i++) { + if (threadIds[i] > 0) { + threadIds[writePos++] = threadIds[i]; + } + } + + int numberOfInvalidThreadIds = threadIds.length - writePos; + threadIds = Arrays.copyOf(threadIds, writePos); + // Get thread information without computing any stack traces - ThreadInfo[] allThreads = threadBean.getThreadInfo(threadBean.getAllThreadIds(), 0); + ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0); // Initialize the map with all thread states - HashMap threadCounts = new HashMap(); + HashMap threadCounts = new HashMap(); for (Thread.State state : Thread.State.values()) { - threadCounts.put(state, 0); + threadCounts.put(state.name(), 0); } // Collect the actual thread counts for (ThreadInfo curThread : allThreads) { if (curThread != null) { Thread.State threadState = curThread.getThreadState(); - threadCounts.put(threadState, threadCounts.get(threadState) + 1); + threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1); } } + // Add the thread count for invalid thread ids + threadCounts.put(UNKNOWN, numberOfInvalidThreadIds); + return threadCounts; } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java index 9bd6c7f45..1fb2ac714 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java @@ -1,5 +1,6 @@ package io.prometheus.client.hotspot; +import io.prometheus.client.Collector.MetricFamilySamples; import io.prometheus.client.CollectorRegistry; import org.junit.Before; import org.junit.Test; @@ -7,7 +8,10 @@ import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; -import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; @@ -97,4 +101,98 @@ public void testThreadPools() { "jvm_threads_state", STATE_LABEL, STATE_TERMINATED_LABEL), .0000001); } + + @Test + public void testInvalidThreadIds() { + ThreadExports threadExports = new ThreadExports(); + + // Number of threads to create with invalid thread ids + int numberOfInvalidThreadIds = 2; + + // Get the current thread state counts + Map expectedThreadStateCountMap = new HashMap(); + List metricFamilySamplesList = threadExports.collect(); + for (MetricFamilySamples metricFamilySamples : metricFamilySamplesList) { + if (ThreadExports.JVM_THREADS_STATE.equals(metricFamilySamples.name)) { + for (MetricFamilySamples.Sample sample : metricFamilySamples.samples) { + expectedThreadStateCountMap.put(ThreadExports.JVM_THREADS_STATE + "-" + sample.labelValues.get(0), sample.value); + } + } + } + + // Add numberOfInvalidThreadIds to the expected UNKNOWN thread state count + expectedThreadStateCountMap.put( + ThreadExports.JVM_THREADS_STATE + "-" + ThreadExports.UNKNOWN, + expectedThreadStateCountMap.get( + ThreadExports.JVM_THREADS_STATE + "-" + ThreadExports.UNKNOWN) + numberOfInvalidThreadIds); + + final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + + try { + // Create and start threads with invalid thread ids (id=0, id=-1, etc.) + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + new TestThread(-i, new TestRunnable(countDownLatch)).start(); + } + + // Get the current thread state counts + Map actualThreadStateCountMap = new HashMap(); + metricFamilySamplesList = threadExports.collect(); + for (MetricFamilySamples metricFamilySamples : metricFamilySamplesList) { + if (ThreadExports.JVM_THREADS_STATE.equals(metricFamilySamples.name)) { + for (MetricFamilySamples.Sample sample : metricFamilySamples.samples) { + actualThreadStateCountMap.put(ThreadExports.JVM_THREADS_STATE + "-" + sample.labelValues.get(0), sample.value); + } + } + } + + // Assert that we have the same number of thread states + assertEquals(expectedThreadStateCountMap.size(), actualThreadStateCountMap.size()); + + // Check each thread state count + for (String threadState : expectedThreadStateCountMap.keySet()) { + double expectedThreadStateCount = expectedThreadStateCountMap.get(threadState); + double actualThreadStateCount = actualThreadStateCountMap.get(threadState); + + // Assert the expected and actual thread count states are equal + assertEquals(expectedThreadStateCount, actualThreadStateCount, 0.0); + } + } finally { + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + countDownLatch.countDown(); + } + } + } + + private class TestThread extends Thread { + + private long id; + + public TestThread(long id, Runnable runnable) { + super(runnable); + setDaemon(true); + this.id = id; + } + + public long getId() { + return this.id; + } + } + + private class TestRunnable implements Runnable { + + private CountDownLatch countDownLatch; + + public TestRunnable(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + // DO NOTHING + } + } + } } From 7c9fc397c21ebc9119f40131f075e1b2ed7b3079 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 5 Jun 2022 21:18:35 -0400 Subject: [PATCH 152/980] Fixed HttpServletResponseAdapterImpl setStatus method to call correct delegate method Signed-off-by: Doug Hoard --- .../main/java/io/prometheus/client/servlet/jakarta/Adapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java index 4a4b8bb01..780b235e3 100644 --- a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java +++ b/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java @@ -58,7 +58,7 @@ private static class HttpServletResponseAdapterImpl implements HttpServletRespon @Override public void setStatus(int httpStatusCode) { - delegate.setBufferSize(httpStatusCode); + delegate.setStatus(httpStatusCode); } @Override From e517786de891a3e35070d4d4ef1bac195a959391 Mon Sep 17 00:00:00 2001 From: Antoine DESSAIGNE Date: Wed, 1 Jun 2022 16:25:08 +0200 Subject: [PATCH 153/980] Mark opentelemtry-api as optional to make it an optional dependency in OSGi. Signed-off-by: Antoine DESSAIGNE --- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 1 + simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index f60633366..d054beba6 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -23,6 +23,7 @@ io.opentelemetry opentelemetry-api provided + true diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 9ed206650..7d443e50b 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -23,6 +23,7 @@ io.opentelemetry opentelemetry-api provided + true From 75baa060b650ae5d8b5e59efc5c81ca276cc73eb Mon Sep 17 00:00:00 2001 From: adessaigne Date: Tue, 14 Jun 2022 13:41:01 +0200 Subject: [PATCH 154/980] Move servlet adapters to an internal package to avoid duplicating classes when building OSGi bundles (#789) * Move servlet adapters to an internal package to avoid duplicating classes when building OSGi bundles Signed-off-by: Antoine DESSAIGNE * Fix typo in Adapter preventing it to work properly Signed-off-by: Antoine DESSAIGNE --- .../java/io/prometheus/client/exporter/MetricsServlet.java | 4 ++-- .../main/java/io/prometheus/client/filter/MetricsFilter.java | 2 +- .../java/io/prometheus/client/{ => internal}/Adapter.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename simpleclient_servlet/src/main/java/io/prometheus/client/{ => internal}/Adapter.java (97%) diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java index 3cd6af877..f30050d8e 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java @@ -1,6 +1,6 @@ package io.prometheus.client.exporter; -import io.prometheus.client.Adapter; +import io.prometheus.client.internal.Adapter; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Predicate; import io.prometheus.client.servlet.common.exporter.Exporter; @@ -13,7 +13,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import static io.prometheus.client.Adapter.wrap; +import static io.prometheus.client.internal.Adapter.wrap; /** * The MetricsServlet class provides a simple way of exposing the metrics values. diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java index 21d5b3343..c2775fcff 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java @@ -1,6 +1,6 @@ package io.prometheus.client.filter; -import io.prometheus.client.Adapter; +import io.prometheus.client.internal.Adapter; import io.prometheus.client.servlet.common.filter.Filter; import io.prometheus.client.servlet.common.filter.FilterConfigurationException; diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java b/simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java similarity index 97% rename from simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java rename to simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java index 8433fd67d..853980ae5 100644 --- a/simpleclient_servlet/src/main/java/io/prometheus/client/Adapter.java +++ b/simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java @@ -1,4 +1,4 @@ -package io.prometheus.client; +package io.prometheus.client.internal; import io.prometheus.client.servlet.common.adapter.FilterConfigAdapter; import io.prometheus.client.servlet.common.adapter.HttpServletRequestAdapter; @@ -58,7 +58,7 @@ private static class HttpServletResponseAdapterImpl implements HttpServletRespon @Override public void setStatus(int httpStatusCode) { - delegate.setBufferSize(httpStatusCode); + delegate.setStatus(httpStatusCode); } @Override From 6730f3e32199d6bf0e963b306ff69ef08ac5b178 Mon Sep 17 00:00:00 2001 From: Gabi Davar Date: Wed, 15 Jun 2022 10:42:58 +0200 Subject: [PATCH 155/980] Support `_created` time series suppression (#791) * Support PROMETHEUS_DISABLE_CREATED_SERIES env var to suppress `_created` time series Signed-off-by: Gabi Davar * switched to use a static variable. test tweaks. Signed-off-by: Gabi Davar * docs Signed-off-by: Gabi Davar * let's be truer. Signed-off-by: Gabi Davar * Revert GetNames() redundant change. Signed-off-by: Gabi Davar * make final, drop test for now Signed-off-by: Gabi Davar * remove the extra deps too. Signed-off-by: Gabi Davar * Add a brand new and shiny class Signed-off-by: Gabi Davar --- README.md | 7 ++++++ .../java/io/prometheus/client/Collector.java | 3 +-- .../java/io/prometheus/client/Counter.java | 4 +++- .../io/prometheus/client/Environment.java | 23 +++++++++++++++++++ .../java/io/prometheus/client/Histogram.java | 4 +++- .../java/io/prometheus/client/Summary.java | 4 +++- .../io/prometheus/client/HistogramTest.java | 4 ++-- 7 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 simpleclient/src/main/java/io/prometheus/client/Environment.java diff --git a/README.md b/README.md index b6dd47033..9fbafedcd 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,13 @@ There are canonical examples defined in the class definition Javadoc of the clie Documentation can be found at the [Java Client Github Project Page](http://prometheus.github.io/client_java). +### Disabling `_created` metrics + +By default, counters, histograms, and summaries export an additional series +suffixed with `_created` and a value of the unix timestamp for when the metric +was created. If this information is not helpful, it can be disabled by setting +the environment variable `PROMETHEUS_DISABLE_CREATED_SERIES=true`. + ## Instrumenting Four types of metrics are offered: Counter, Gauge, Summary and Histogram. diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/simpleclient/src/main/java/io/prometheus/client/Collector.java index 6f84e1840..99801fddc 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Collector.java +++ b/simpleclient/src/main/java/io/prometheus/client/Collector.java @@ -3,8 +3,7 @@ import io.prometheus.client.exemplars.Exemplar; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import java.util.regex.Pattern; /** diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/simpleclient/src/main/java/io/prometheus/client/Counter.java index 51f0a24a2..015ac4301 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Counter.java +++ b/simpleclient/src/main/java/io/prometheus/client/Counter.java @@ -355,7 +355,9 @@ public List collect() { List samples = new ArrayList(children.size()); for(Map.Entry, Child> c: children.entrySet()) { samples.add(new MetricFamilySamples.Sample(fullname + "_total", labelNames, c.getKey(), c.getValue().get(), c.getValue().getExemplar())); - samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0)); + if (Environment.includeCreatedSeries()) { + samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), c.getValue().created() / 1000.0)); + } } return familySamplesList(Type.COUNTER, samples); } diff --git a/simpleclient/src/main/java/io/prometheus/client/Environment.java b/simpleclient/src/main/java/io/prometheus/client/Environment.java new file mode 100644 index 000000000..bc6393bcf --- /dev/null +++ b/simpleclient/src/main/java/io/prometheus/client/Environment.java @@ -0,0 +1,23 @@ +package io.prometheus.client; + +import java.util.Arrays; +import java.util.List; + +class Environment { + + private static final String DISABLE_CREATED_SERIES = "PROMETHEUS_DISABLE_CREATED_SERIES"; + private static final List DISABLE_CREATED_SERIES_TRUE = Arrays.asList("true", "1", "t"); + private static final boolean includeCreatedSeries = !isTrue(DISABLE_CREATED_SERIES); + + static boolean includeCreatedSeries() { + return includeCreatedSeries; + } + + private static boolean isTrue(String envVarName) { + String stringValue = System.getenv(envVarName); + if (stringValue != null) { + return DISABLE_CREATED_SERIES_TRUE.contains(stringValue.toLowerCase()); + } + return false; + } +} diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index e0491579e..c97da1213 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -574,7 +574,9 @@ public List collect() { } samples.add(new MetricFamilySamples.Sample(fullname + "_count", labelNames, c.getKey(), v.buckets[buckets.length-1])); samples.add(new MetricFamilySamples.Sample(fullname + "_sum", labelNames, c.getKey(), v.sum)); - samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0)); + if (Environment.includeCreatedSeries()) { + samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0)); + } } return familySamplesList(Type.HISTOGRAM, samples); diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/simpleclient/src/main/java/io/prometheus/client/Summary.java index 8836cbe7d..6d1fb947a 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Summary.java +++ b/simpleclient/src/main/java/io/prometheus/client/Summary.java @@ -404,7 +404,9 @@ public List collect() { } samples.add(new MetricFamilySamples.Sample(fullname + "_count", labelNames, c.getKey(), v.count)); samples.add(new MetricFamilySamples.Sample(fullname + "_sum", labelNames, c.getKey(), v.sum)); - samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0)); + if (Environment.includeCreatedSeries()) { + samples.add(new MetricFamilySamples.Sample(fullname + "_created", labelNames, c.getKey(), v.created / 1000.0)); + } } return familySamplesList(Type.SUMMARY, samples); diff --git a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java index 3fe884509..11c838d10 100644 --- a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java @@ -299,7 +299,7 @@ private void assertExemplar(Histogram histogram, double value, String... labels) } if (lowerBound < value && value <= upperBound) { Assert.assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", bucket.exemplar); - Assert.assertEquals(value, bucket.exemplar.getValue(), 0.001); + Assert.assertEquals(value, bucket.exemplar.getValue(), 0.01); Assert.assertEquals(labels.length/2, bucket.exemplar.getNumberOfLabels()); for (int i=0; i Date: Wed, 15 Jun 2022 11:58:20 +0200 Subject: [PATCH 156/980] Fix Describable returning an empty list (#785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Describable returning an empty list Signed-off-by: Fabian Stäber * Fix implementation and add test Signed-off-by: Fabian Stäber --- .../prometheus/client/CollectorRegistry.java | 15 ++++-- .../client/EmptyDescribableTest.java | 47 +++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index 47af5b136..63234ff35 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -168,10 +168,17 @@ private Iterator filteredCollectorIterator() { } else { HashSet collectors = new HashSet(); synchronized (namesCollectorsLock) { - for (Map.Entry entry : namesToCollectors.entrySet()) { - // Note that namesToCollectors contains keys for all combinations of suffixes (_total, _info, etc.). - if (sampleNameFilter.test(entry.getKey())) { - collectors.add(entry.getValue()); + for (Map.Entry> entry : collectorsToNames.entrySet()) { + List names = entry.getValue(); + if (names.isEmpty()) { + collectors.add(entry.getKey()); + } else { + for (String name : names) { + if (sampleNameFilter.test(name)) { + collectors.add(entry.getKey()); + break; + } + } } } } diff --git a/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java b/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java new file mode 100644 index 000000000..bdff0dac1 --- /dev/null +++ b/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java @@ -0,0 +1,47 @@ +package io.prometheus.client; + +import org.junit.Test; + +import java.util.*; + +import static org.junit.Assert.assertEquals; + +public class EmptyDescribableTest { + + static class TestCollector extends Collector implements Collector.Describable { + + private final List describeResult; + + TestCollector(List describeResult) { + this.describeResult = describeResult; + } + + @Override + public List collect() { + List labelNames = Arrays.asList("label1", "label2"); + List labelValues1 = Arrays.asList("a", "b"); + List labelValues2 = Arrays.asList("c", "d"); + List samples = new ArrayList(2); + samples.add(new MetricFamilySamples.Sample("my_metric", labelNames, labelValues1, 1.0)); + samples.add(new MetricFamilySamples.Sample("my_metric", labelNames, labelValues2, 2.0)); + MetricFamilySamples mfs = new MetricFamilySamples("my_metric", "", Type.UNKNOWN, "help text", samples); + return Collections.singletonList(mfs); + } + + @Override + public List describe() { + return describeResult; + } + } + + @Test + public void testEmptyDescribe() { + CollectorRegistry registry = new CollectorRegistry(); + TestCollector collector = new TestCollector(new ArrayList()); + collector.register(registry); + Set includedNames = new HashSet(Collections.singletonList("my_metric")); + List mfs = Collections.list(registry.filteredMetricFamilySamples(includedNames)); + assertEquals(1, mfs.size()); + assertEquals(2, mfs.get(0).samples.size()); + } +} From 5e65821c49c89fa723f81233ac7e3eb888cf61cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 Jun 2022 14:53:25 +0200 Subject: [PATCH 157/980] Bump dependency versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- MAINTAINER_NOTES.md | 2 +- benchmarks/version-rules.xml | 6 +++ integration_tests/it_common/version-rules.xml | 6 +++ .../it_exemplars_otel_agent/version-rules.xml | 11 ++++ .../it_exemplars_otel_sdk/version-rules.xml | 6 +++ .../it_java_versions/version-rules.xml | 6 +++ integration_tests/it_log4j2/version-rules.xml | 6 +++ integration_tests/it_pushgateway/pom.xml | 2 +- .../it_pushgateway/version-rules.xml | 11 ++++ .../pom.xml | 4 +- .../version-rules.xml | 11 ++++ integration_tests/pom.xml | 4 +- integration_tests/version-rules.xml | 11 ++++ pom.xml | 2 +- simpleclient/version-rules.xml | 6 +++ simpleclient_caffeine/pom.xml | 6 +-- simpleclient_caffeine/version-rules.xml | 6 +++ simpleclient_common/version-rules.xml | 6 +++ simpleclient_dropwizard/pom.xml | 50 ++++++++++++++++++- .../dropwizard/DropwizardExportsTest.java | 36 ++++++------- simpleclient_dropwizard/version-rules.xml | 6 +++ .../version-rules.xml | 6 +++ simpleclient_guava/pom.xml | 4 +- simpleclient_guava/version-rules.xml | 6 +++ simpleclient_hibernate/pom.xml | 4 +- simpleclient_hibernate/version-rules.xml | 6 +++ simpleclient_hotspot/pom.xml | 49 +++++++++++++++++- .../hotspot/MemoryAllocationExportsTest.java | 4 +- simpleclient_hotspot/version-rules.xml | 12 +++++ simpleclient_httpserver/pom.xml | 2 +- simpleclient_httpserver/version-rules.xml | 6 +++ simpleclient_jetty/version-rules.xml | 6 +++ simpleclient_jetty_jdk8/pom.xml | 4 +- simpleclient_jetty_jdk8/version-rules.xml | 6 +++ simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j/version-rules.xml | 6 +++ simpleclient_log4j2/pom.xml | 2 +- simpleclient_log4j2/version-rules.xml | 6 +++ simpleclient_logback/pom.xml | 2 +- simpleclient_logback/version-rules.xml | 11 ++++ simpleclient_pushgateway/pom.xml | 8 ++- .../exporter/BasicAuthPushGatewayTest.java | 4 +- .../client/exporter/PushGatewayTest.java | 6 +-- simpleclient_pushgateway/version-rules.xml | 6 +++ simpleclient_servlet/pom.xml | 6 +-- simpleclient_servlet/version-rules.xml | 12 +++++ simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_common/version-rules.xml | 6 +++ simpleclient_servlet_jakarta/pom.xml | 8 +-- .../version-rules.xml | 6 +++ simpleclient_spring_boot/version-rules.xml | 11 ++++ simpleclient_spring_web/pom.xml | 2 +- simpleclient_spring_web/version-rules.xml | 12 +++++ simpleclient_tracer/pom.xml | 2 +- .../version-rules.xml | 6 +++ .../version-rules.xml | 6 +++ .../version-rules.xml | 6 +++ simpleclient_tracer/version-rules.xml | 6 +++ simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx/version-rules.xml | 12 +++++ simpleclient_vertx4/pom.xml | 4 +- simpleclient_vertx4/version-rules.xml | 6 +++ version-rules.xml | 37 +------------- 63 files changed, 425 insertions(+), 99 deletions(-) create mode 100644 benchmarks/version-rules.xml create mode 100644 integration_tests/it_common/version-rules.xml create mode 100644 integration_tests/it_exemplars_otel_agent/version-rules.xml create mode 100644 integration_tests/it_exemplars_otel_sdk/version-rules.xml create mode 100644 integration_tests/it_java_versions/version-rules.xml create mode 100644 integration_tests/it_log4j2/version-rules.xml create mode 100644 integration_tests/it_pushgateway/version-rules.xml create mode 100644 integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml create mode 100644 integration_tests/version-rules.xml create mode 100644 simpleclient/version-rules.xml create mode 100644 simpleclient_caffeine/version-rules.xml create mode 100644 simpleclient_common/version-rules.xml create mode 100644 simpleclient_dropwizard/version-rules.xml create mode 100644 simpleclient_graphite_bridge/version-rules.xml create mode 100644 simpleclient_guava/version-rules.xml create mode 100644 simpleclient_hibernate/version-rules.xml create mode 100644 simpleclient_hotspot/version-rules.xml create mode 100644 simpleclient_httpserver/version-rules.xml create mode 100644 simpleclient_jetty/version-rules.xml create mode 100644 simpleclient_jetty_jdk8/version-rules.xml create mode 100644 simpleclient_log4j/version-rules.xml create mode 100644 simpleclient_log4j2/version-rules.xml create mode 100644 simpleclient_logback/version-rules.xml create mode 100644 simpleclient_pushgateway/version-rules.xml create mode 100644 simpleclient_servlet/version-rules.xml create mode 100644 simpleclient_servlet_common/version-rules.xml create mode 100644 simpleclient_servlet_jakarta/version-rules.xml create mode 100644 simpleclient_spring_boot/version-rules.xml create mode 100644 simpleclient_spring_web/version-rules.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_common/version-rules.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml create mode 100644 simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml create mode 100644 simpleclient_tracer/version-rules.xml create mode 100644 simpleclient_vertx/version-rules.xml create mode 100644 simpleclient_vertx4/version-rules.xml diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md index e176bcd67..b9d67e146 100644 --- a/MAINTAINER_NOTES.md +++ b/MAINTAINER_NOTES.md @@ -5,5 +5,5 @@ Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/index.html). Rules are configured in [version-rules.xml](version-rules.xml). ``` -./mvnw versions:use-next-releases +./mvnw versions:use-latest-releases ``` diff --git a/benchmarks/version-rules.xml b/benchmarks/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/benchmarks/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/integration_tests/it_common/version-rules.xml b/integration_tests/it_common/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/integration_tests/it_common/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/integration_tests/it_exemplars_otel_agent/version-rules.xml b/integration_tests/it_exemplars_otel_agent/version-rules.xml new file mode 100644 index 000000000..fcb275534 --- /dev/null +++ b/integration_tests/it_exemplars_otel_agent/version-rules.xml @@ -0,0 +1,11 @@ + + + + + .*alpha.* + + + + diff --git a/integration_tests/it_exemplars_otel_sdk/version-rules.xml b/integration_tests/it_exemplars_otel_sdk/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/integration_tests/it_exemplars_otel_sdk/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/integration_tests/it_java_versions/version-rules.xml b/integration_tests/it_java_versions/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/integration_tests/it_java_versions/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/integration_tests/it_log4j2/version-rules.xml b/integration_tests/it_log4j2/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/integration_tests/it_log4j2/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index cc8402e52..f76d3dd0b 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -30,7 +30,7 @@ com.squareup.okhttp3 okhttp - 4.9.3 + 4.10.0 test diff --git a/integration_tests/it_pushgateway/version-rules.xml b/integration_tests/it_pushgateway/version-rules.xml new file mode 100644 index 000000000..fcb275534 --- /dev/null +++ b/integration_tests/it_pushgateway/version-rules.xml @@ -0,0 +1,11 @@ + + + + + .*alpha.* + + + + diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index d23323a07..414309367 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -35,7 +35,7 @@ com.squareup.okhttp3 okhttp - 4.9.3 + 4.10.0 org.testcontainers @@ -50,7 +50,7 @@ jakarta.servlet jakarta.servlet-api - 5.0.0 + 6.0.0 provided diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml new file mode 100644 index 000000000..fcb275534 --- /dev/null +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml @@ -0,0 +1,11 @@ + + + + + .*alpha.* + + + + diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 9dc769a0e..b981961ed 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -56,13 +56,13 @@ org.testcontainers testcontainers - 1.17.0 + 1.17.2 test com.squareup.okhttp3 okhttp - 4.9.3 + 4.10.0 test diff --git a/integration_tests/version-rules.xml b/integration_tests/version-rules.xml new file mode 100644 index 000000000..fcb275534 --- /dev/null +++ b/integration_tests/version-rules.xml @@ -0,0 +1,11 @@ + + + + + .*alpha.* + + + + diff --git a/pom.xml b/pom.xml index 5be64aec3..eb1afa2fe 100644 --- a/pom.xml +++ b/pom.xml @@ -231,7 +231,7 @@ versions-maven-plugin 2.10.0 - file://${session.executionRootDirectory}/version-rules.xml + file://${project.basedir}/version-rules.xml diff --git a/simpleclient/version-rules.xml b/simpleclient/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index b70305f13..4ad454941 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -41,7 +41,7 @@ com.github.ben-manes.caffeine caffeine - 3.0.0 + 3.1.1 @@ -55,13 +55,13 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test org.assertj assertj-core - 3.22.0 + 3.23.1 test diff --git a/simpleclient_caffeine/version-rules.xml b/simpleclient_caffeine/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_caffeine/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_common/version-rules.xml b/simpleclient_common/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_common/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 9151402f2..3cf721aa3 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -52,14 +52,60 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test org.mockito mockito-core - 3.0.0 + 4.6.1 test + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + 1.8 + 1.8 + + + + + + + + + + + intellij + + false + + + + + idea.maven.embedder.version + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java index 409dfaa51..33a031b54 100644 --- a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java +++ b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyDouble; -import static org.mockito.ArgumentMatchers.anyListOf; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -119,7 +119,7 @@ public String getValue() { metricRegistry.register("invalid_gauge", invalidGauge); assertEquals(null, registry.getSampleValue("invalid_gauge")); - Mockito.verifyZeroInteractions(sampleBuilder); + Mockito.verifyNoInteractions(sampleBuilder); } @Test @@ -132,7 +132,7 @@ public String getValue() { }; metricRegistry.register("invalid_gauge", invalidGauge); assertEquals(null, registry.getSampleValue("invalid_gauge")); - Mockito.verifyZeroInteractions(sampleBuilder); + Mockito.verifyNoInteractions(sampleBuilder); } void assertRegistryContainsMetrics(String... metrics) { @@ -190,19 +190,19 @@ public void testTimer() throws IOException, InterruptedException { @Test public void testThatMetricHelpUsesOriginalDropwizardName() { - Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedTimer1", Collections.emptyList(), Collections.emptyList(), 1234)); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedCounter1", Collections.emptyList(), Collections.emptyList(), 1234)); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedMeter1_total", Collections.emptyList(), Collections.emptyList(), 1234)); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedHistogram1", Collections.emptyList(), Collections.emptyList(), 1234)); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedGauge1", Collections.emptyList(), Collections.emptyList(), 1234)); metricRegistry.timer("my.application.namedTimer1"); @@ -248,43 +248,43 @@ public void testThatMetricHelpUsesOriginalDropwizardName() { @Test public void testThatMetricsMappedToSameNameAreGroupedInSameFamily() { final Collector.MetricFamilySamples.Sample namedTimerSample1 = new Collector.MetricFamilySamples.Sample("my_application_namedTimer", Collections.emptyList(), Collections.emptyList(), 1234); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedTimerSample1); final Collector.MetricFamilySamples.Sample namedTimerSample2 = new Collector.MetricFamilySamples.Sample("my_application_namedTimer", Collections.emptyList(), Collections.emptyList(), 1235); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer2"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer2"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedTimerSample2); final Collector.MetricFamilySamples.Sample namedCounter1 = new Collector.MetricFamilySamples.Sample("my_application_namedCounter", Collections.emptyList(), Collections.emptyList(), 1234); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedCounter1); final Collector.MetricFamilySamples.Sample namedCounter2 = new Collector.MetricFamilySamples.Sample("my_application_namedCounter", Collections.emptyList(), Collections.emptyList(), 1235); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter2"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter2"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedCounter2); final Collector.MetricFamilySamples.Sample namedMeter1 = new Collector.MetricFamilySamples.Sample("my_application_namedMeter_total", Collections.emptyList(), Collections.emptyList(), 1234); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedMeter1); final Collector.MetricFamilySamples.Sample namedMeter2 = new Collector.MetricFamilySamples.Sample("my_application_namedMeter_total", Collections.emptyList(), Collections.emptyList(), 1235); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter2"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter2"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedMeter2); final Collector.MetricFamilySamples.Sample namedHistogram1 = new Collector.MetricFamilySamples.Sample("my_application_namedHistogram", Collections.emptyList(), Collections.emptyList(), 1234); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedHistogram1); final Collector.MetricFamilySamples.Sample namedHistogram2 = new Collector.MetricFamilySamples.Sample("my_application_namedHistogram", Collections.emptyList(), Collections.emptyList(), 1235); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram2"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram2"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedHistogram2); final Collector.MetricFamilySamples.Sample namedGauge1 = new Collector.MetricFamilySamples.Sample("my_application_namedGauge", Collections.emptyList(), Collections.emptyList(), 1234); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedGauge1); final Collector.MetricFamilySamples.Sample namedGauge2 = new Collector.MetricFamilySamples.Sample("my_application_namedGauge", Collections.emptyList(), Collections.emptyList(), 1235); - Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge2"), anyString(), anyListOf(String.class), anyListOf(String.class), anyDouble())) + Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge2"), anyString(), anyList(), anyList(), anyDouble())) .thenReturn(namedGauge2); metricRegistry.timer("my.application.namedTimer1"); diff --git a/simpleclient_dropwizard/version-rules.xml b/simpleclient_dropwizard/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_dropwizard/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_graphite_bridge/version-rules.xml b/simpleclient_graphite_bridge/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_graphite_bridge/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 4a12db7b5..daa10c98c 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -55,13 +55,13 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test org.assertj assertj-core - 3.22.0 + 3.23.1 test diff --git a/simpleclient_guava/version-rules.xml b/simpleclient_guava/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_guava/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 285f43045..f1e697c6d 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -44,7 +44,7 @@ org.hibernate hibernate-core - 5.6.6.Final + 6.1.0.Final provided @@ -58,7 +58,7 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_hibernate/version-rules.xml b/simpleclient_hibernate/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_hibernate/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index f6a0a7c26..1d6be8bfa 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -55,15 +55,60 @@ org.mockito mockito-core - 3.0.0 + 4.6.1 test org.eclipse.jetty jetty-servlet - 9.4.44.v20210927 + 9.4.46.v20220331 test + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + 1.8 + 1.8 + + + + + + + + + + + intellij + + false + + + + + idea.maven.embedder.version + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java index 367b86333..d92f0572d 100644 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java @@ -62,7 +62,7 @@ protected List getGarbageCollectorMXBeans() { } }; - Mockito.verify((NotificationEmitter) notificationEmitterMXBean).addNotificationListener(Mockito.any(MemoryAllocationExports.AllocationCountingNotificationListener.class), Mockito.isNull(NotificationFilter.class), Mockito.isNull()); - Mockito.verifyZeroInteractions(notNotificationEmitterMXBean); + Mockito.verify((NotificationEmitter) notificationEmitterMXBean).addNotificationListener(Mockito.any(MemoryAllocationExports.AllocationCountingNotificationListener.class), Mockito.isNull(), Mockito.isNull()); + Mockito.verifyNoInteractions(notNotificationEmitterMXBean); } } diff --git a/simpleclient_hotspot/version-rules.xml b/simpleclient_hotspot/version-rules.xml new file mode 100644 index 000000000..904c3c3a1 --- /dev/null +++ b/simpleclient_hotspot/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^9].* + + + + diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index e0d2ba6d9..af0de64c9 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -53,7 +53,7 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test diff --git a/simpleclient_httpserver/version-rules.xml b/simpleclient_httpserver/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_httpserver/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_jetty/version-rules.xml b/simpleclient_jetty/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_jetty/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 310d2d198..73f968ca5 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -52,12 +52,12 @@ org.eclipse.jetty jetty-server - 9.4.44.v20210927 + 11.0.9 org.eclipse.jetty jetty-servlet - 9.4.44.v20210927 + 11.0.9 diff --git a/simpleclient_jetty_jdk8/version-rules.xml b/simpleclient_jetty_jdk8/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_jetty_jdk8/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 5c04800ed..be01b4558 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -61,7 +61,7 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_log4j/version-rules.xml b/simpleclient_log4j/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_log4j/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 076d153c9..443fdef39 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_log4j2/version-rules.xml b/simpleclient_log4j2/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_log4j2/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 839481067..5fa7490d8 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -55,7 +55,7 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_logback/version-rules.xml b/simpleclient_logback/version-rules.xml new file mode 100644 index 000000000..fcb275534 --- /dev/null +++ b/simpleclient_logback/version-rules.xml @@ -0,0 +1,11 @@ + + + + + .*alpha.* + + + + diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 32ef40494..269eaeb78 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -60,8 +60,14 @@ org.mock-server mockserver-netty - 3.10.0 + 5.13.2 test + + org.mock-server + mockserver-junit-rule-no-dependencies + 5.13.2 + test + diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java index 10f9188b5..1d5bfd774 100644 --- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java +++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.mockserver.client.server.MockServerClient; +import org.mockserver.client.MockServerClient; import org.mockserver.junit.MockServerRule; public class BasicAuthPushGatewayTest { @@ -28,7 +28,7 @@ public class BasicAuthPushGatewayTest { public void setUp() { registry = new CollectorRegistry(); gauge = Gauge.build().name("g").help("help").create(); - pushGateway = new PushGateway("localhost:" + mockServerRule.getHttpPort()); + pushGateway = new PushGateway("localhost:" + mockServerRule.getPort()); pushGateway.setConnectionFactory(new BasicAuthHttpConnectionFactory("testUser", "testPwd")); } diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java index 874595b18..ced492b8c 100644 --- a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java +++ b/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockserver.junit.MockServerRule; -import org.mockserver.client.server.MockServerClient; +import org.mockserver.client.MockServerClient; public class PushGatewayTest { @@ -37,7 +37,7 @@ public class PushGatewayTest { public void setUp() { registry = new CollectorRegistry(); gauge = (Gauge) Gauge.build().name("g").help("help").create(); - pg = new PushGateway("localhost:" + mockServerRule.getHttpPort()); + pg = new PushGateway("localhost:" + mockServerRule.getPort()); groupingKey = new TreeMap(); groupingKey.put("l", "v"); } @@ -86,7 +86,7 @@ public void testNon202ResponseThrows() throws IOException { thrown.expect(IOException.class); thrown.expectMessage( "Response code from http://localhost:" - + mockServerRule.getHttpPort() + + mockServerRule.getPort() + "/metrics/job/j was 500"); pg.push(registry, "j"); } diff --git a/simpleclient_pushgateway/version-rules.xml b/simpleclient_pushgateway/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_pushgateway/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 8b600176e..50ff4f9e6 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -55,7 +55,7 @@ javax.servlet javax.servlet-api - 4.0.0 + 4.0.1 provided @@ -68,7 +68,7 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test @@ -80,7 +80,7 @@ org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_servlet/version-rules.xml b/simpleclient_servlet/version-rules.xml new file mode 100644 index 000000000..318e865f5 --- /dev/null +++ b/simpleclient_servlet/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^8].* + + + + diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 15578ea90..c51cd19c0 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -57,7 +57,7 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test diff --git a/simpleclient_servlet_common/version-rules.xml b/simpleclient_servlet_common/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_servlet_common/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index a03c64259..99198ce30 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -55,7 +55,7 @@ jakarta.servlet jakarta.servlet-api - 5.0.0 + 6.0.0 provided @@ -68,19 +68,19 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test org.eclipse.jetty jetty-servlet - 11.0.7 + 11.0.9 test org.mockito mockito-core - 4.4.0 + 4.6.1 test diff --git a/simpleclient_servlet_jakarta/version-rules.xml b/simpleclient_servlet_jakarta/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_servlet_jakarta/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_spring_boot/version-rules.xml b/simpleclient_spring_boot/version-rules.xml new file mode 100644 index 000000000..f1b170b69 --- /dev/null +++ b/simpleclient_spring_boot/version-rules.xml @@ -0,0 +1,11 @@ + + + + + 2\..* + + + + diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 1881434e4..5ffb65e39 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -76,7 +76,7 @@ org.aspectj aspectjweaver - 1.9.8 + 1.9.9.1 org.apache.commons diff --git a/simpleclient_spring_web/version-rules.xml b/simpleclient_spring_web/version-rules.xml new file mode 100644 index 000000000..75c79360f --- /dev/null +++ b/simpleclient_spring_web/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^4].* + + + + diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index f01215007..1c7e02969 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -18,7 +18,7 @@ io.opentelemetry opentelemetry-api - 1.11.0 + 1.15.0 diff --git a/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_tracer/version-rules.xml b/simpleclient_tracer/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_tracer/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 0e0382441..f352cb951 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -75,7 +75,7 @@ org.assertj assertj-core - 3.22.0 + 3.23.1 test diff --git a/simpleclient_vertx/version-rules.xml b/simpleclient_vertx/version-rules.xml new file mode 100644 index 000000000..582c4ce11 --- /dev/null +++ b/simpleclient_vertx/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^3].* + + + + diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 027a8ab0a..a7aeca9e7 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -62,7 +62,7 @@ io.vertx vertx-web - 4.2.4 + 4.3.1 provided @@ -75,7 +75,7 @@ org.assertj assertj-core - 2.7.0 + 3.23.1 test diff --git a/simpleclient_vertx4/version-rules.xml b/simpleclient_vertx4/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/simpleclient_vertx4/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/version-rules.xml b/version-rules.xml index 567d9b200..5c6d39593 100644 --- a/version-rules.xml +++ b/version-rules.xml @@ -2,40 +2,5 @@ xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd"> - - - .*-RC\d - .*\.RC\d - .*alpha.* - .*\.M\d - - - - - .*-b\d\d - - - - - .*-android - - - - - 2\..* - - - - - - [^8].* - - - - - - [^4].* - - - \ No newline at end of file + From 6ac453dfaead46516ab81ad6e0083f45d5d1cdff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 Jun 2022 23:08:57 +0200 Subject: [PATCH 158/980] Update maintainer notes --- MAINTAINER_NOTES.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md index b9d67e146..1ffa525e5 100644 --- a/MAINTAINER_NOTES.md +++ b/MAINTAINER_NOTES.md @@ -7,3 +7,14 @@ Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/i ``` ./mvnw versions:use-latest-releases ``` + +## Release + +``` +./mvnw release:prepare -DreleaseVersion=0.16.0 -DdevelopmentVersion=0.16.1-SNAPSHOT +./mvnw release:perform -DreleaseVersion=0.16.0 -DdevelopmentVersion=0.16.1-SNAPSHOT +``` + +`release:prepare` does Github tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org). + +After that, manually verify the uploaded artifacts on [https://oss.sonatype.org/#stagingRepositories](https://oss.sonatype.org/#stagingRepositories), click `Close` to trigger Sonatype's verification, and then `Release`. From ed0d7ae3b57a3986f6531d1a37db031a331227e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 Jun 2022 23:11:45 +0200 Subject: [PATCH 159/980] [maven-release-plugin] prepare release parent-0.16.0 --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 7 +++---- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 37 files changed, 69 insertions(+), 70 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index affc22fef..3b6d0c457 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 05bc4a886..94e6360d9 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 5a1df5886..2a3dfe322 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index aa9096d94..05e21f117 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 3d3c86f75..d9dfe665a 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 5349f32b8..a7df8bb72 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index f76d3dd0b..9cdc429e2 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 414309367..5842a4a0a 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.15.1-SNAPSHOT + 0.16.0 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index b981961ed..b9885aeff 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 integration_tests diff --git a/pom.xml b/pom.xml index eb1afa2fe..f6116cc42 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + pom 4.0.0 io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 Prometheus Java Suite http://github.com/prometheus/client_java @@ -26,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + parent-0.16.0 diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index c0067869a..9c00b10b9 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 2e8edbe44..df1ea609e 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 4ad454941..b81ee2e4b 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index fac75ceef..c22b74822 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 3cf721aa3..10c758354 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index a5858ed20..eb77dfce5 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index daa10c98c..e7032b202 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index f1e697c6d..19a43778d 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 1d6be8bfa..bfecff6ed 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_servlet - 0.15.1-SNAPSHOT + 0.16.0 test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index af0de64c9..d6a9bfb1a 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 1b0c20352..0c8af2b7d 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 73f968ca5..5660e1640 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index be01b4558..d4210f6ed 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 org.apache.logging.log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 443fdef39..2892f58c9 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 5fa7490d8..bb8b235f9 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 269eaeb78..ccd9344c7 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 50ff4f9e6..11735dd34 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_servlet_common - 0.15.1-SNAPSHOT + 0.16.0 javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index c51cd19c0..c2d161c39 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 99198ce30..c0ae45c70 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_servlet_common - 0.15.1-SNAPSHOT + 0.16.0 jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index 7c69ce2b2..e7afb3d32 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_spring_web - 0.15.1-SNAPSHOT + 0.16.0 org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 5ffb65e39..a8a0c1349 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.15.1-SNAPSHOT + 0.16.0 io.prometheus simpleclient_common - 0.15.1-SNAPSHOT + 0.16.0 org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 1c7e02969..15641424b 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index acc02c7ce..688535c3b 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index d054beba6..d51d30e63 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 7d443e50b..f52e67243 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index f352cb951..d764d82e9 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index a7aeca9e7..4f58d2c80 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.15.1-SNAPSHOT + 0.16.0 simpleclient_vertx4 From 46b1e41626e0bf76ec8ebd8d0eeb555c92487257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 Jun 2022 23:11:49 +0200 Subject: [PATCH 160/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 4 ++-- simpleclient_common/pom.xml | 4 ++-- simpleclient_dropwizard/pom.xml | 4 ++-- simpleclient_graphite_bridge/pom.xml | 4 ++-- simpleclient_guava/pom.xml | 4 ++-- simpleclient_hibernate/pom.xml | 4 ++-- simpleclient_hotspot/pom.xml | 6 +++--- simpleclient_httpserver/pom.xml | 6 +++--- simpleclient_jetty/pom.xml | 4 ++-- simpleclient_jetty_jdk8/pom.xml | 4 ++-- simpleclient_log4j/pom.xml | 4 ++-- simpleclient_log4j2/pom.xml | 4 ++-- simpleclient_logback/pom.xml | 4 ++-- simpleclient_pushgateway/pom.xml | 6 +++--- simpleclient_servlet/pom.xml | 8 ++++---- simpleclient_servlet_common/pom.xml | 6 +++--- simpleclient_servlet_jakarta/pom.xml | 8 ++++---- simpleclient_spring_boot/pom.xml | 8 ++++---- simpleclient_spring_web/pom.xml | 6 +++--- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 37 files changed, 68 insertions(+), 68 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 3b6d0c457..f14128b41 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT benchmarks diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 94e6360d9..ff8e7ea09 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 2a3dfe322..5ec4b0727 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 05e21f117..e8eff08c1 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index d9dfe665a..a4f7d1cfe 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index a7df8bb72..e01be3b73 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 9cdc429e2..25784a7cf 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 5842a4a0a..5201ce2ce 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.0 + 0.16.1-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index b9885aeff..80932482a 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index f6116cc42..ee3c20583 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - parent-0.16.0 + HEAD diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 9c00b10b9..9e1a70c49 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index df1ea609e..47c8852a9 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index b81ee2e4b..9fa1e392b 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index c22b74822..1be246531 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 10c758354..eb0789354 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.dropwizard.metrics diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index eb77dfce5..41ca436fc 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index e7032b202..528fe0259 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 19a43778d..84553ed9e 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index bfecff6ed..bec6faa07 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_servlet - 0.16.0 + 0.16.1-SNAPSHOT test diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index d6a9bfb1a..5b3da856b 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 0c8af2b7d..2dc1c2b53 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 5660e1640..2e9d54435 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_jetty_jdk8 @@ -47,7 +47,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index d4210f6ed..0f1b50dcf 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 2892f58c9..5b0ff589a 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index bb8b235f9..953a322c2 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index ccd9344c7..3163135b2 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 11735dd34..e599bfb01 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.16.0 + 0.16.1-SNAPSHOT javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index c2d161c39..fac7cbbf8 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index c0ae45c70..3a9d4ac83 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_servlet_common - 0.16.0 + 0.16.1-SNAPSHOT jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index e7afb3d32..eb5dc6888 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_spring_web - 0.16.0 + 0.16.1-SNAPSHOT org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index a8a0c1349..c6562947e 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.16.0 + 0.16.1-SNAPSHOT io.prometheus simpleclient_common - 0.16.0 + 0.16.1-SNAPSHOT org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 15641424b..59e0c35e2 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 688535c3b..c1f2ee7a5 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index d51d30e63..f8274fb82 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index f52e67243..b29b27008 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index d764d82e9..d29591571 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 4f58d2c80..750b4bf88 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -17,7 +17,7 @@ io.prometheus parent - 0.16.0 + 0.16.1-SNAPSHOT simpleclient_vertx4 From b529294987dd75f8046e48e91c3d2780f27002dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 Jun 2022 00:15:37 +0200 Subject: [PATCH 161/980] Update docs for release 0.16.0 --- MAINTAINER_NOTES.md | 2 ++ README.md | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md index 1ffa525e5..593603a3a 100644 --- a/MAINTAINER_NOTES.md +++ b/MAINTAINER_NOTES.md @@ -18,3 +18,5 @@ Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/i `release:prepare` does Github tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org). After that, manually verify the uploaded artifacts on [https://oss.sonatype.org/#stagingRepositories](https://oss.sonatype.org/#stagingRepositories), click `Close` to trigger Sonatype's verification, and then `Release`. + +Note: We release only the parent module and the modules starting with simpleclient. Currently, we manually remove the benchmark and integration test modules. Todo: Instead of manually removing these modules, we should reconfigure the build to make sure that these modules aren't released. diff --git a/README.md b/README.md index 9fbafedcd..f619acd0e 100644 --- a/README.md +++ b/README.md @@ -46,25 +46,25 @@ version can be found on in the maven repository for io.prometheus simpleclient - 0.15.0 + 0.16.0 io.prometheus simpleclient_hotspot - 0.15.0 + 0.16.0 io.prometheus simpleclient_httpserver - 0.15.0 + 0.16.0 io.prometheus simpleclient_pushgateway - 0.15.0 + 0.16.0 ``` From 4ddd60c3d161272c6a9434c5f1ac519eab964fb9 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Thu, 30 Jun 2022 12:01:31 -0400 Subject: [PATCH 162/980] Fixed code to correctly unregister a Collector that is not registered (#795) Signed-off-by: Doug Hoard --- .../main/java/io/prometheus/client/CollectorRegistry.java | 6 ++++-- .../java/io/prometheus/client/CollectorRegistryTest.java | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index 63234ff35..e2ebd10e0 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -80,8 +80,10 @@ private void assertNoDuplicateNames(Collector m, List names) { public void unregister(Collector m) { synchronized (namesCollectorsLock) { List names = collectorsToNames.remove(m); - for (String name : names) { - namesToCollectors.remove(name); + if (names != null) { + for (String name : names) { + namesToCollectors.remove(name); + } } } } diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java index b5f56790a..59b3e7f52 100644 --- a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java +++ b/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java @@ -42,6 +42,11 @@ public void testUnregister() { assertEquals("c", mfs.get(0).name); } + @Test + public void testUnregisterNonRegistered() { + registry.unregister(new MyCollector()); + } + @Test public void testClear() { Collector g = Gauge.build().name("g").help("h").register(registry); From f3bfba1f324a22d42ce60852ac07a972e97fbaf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Jul 2022 22:05:22 +0200 Subject: [PATCH 163/980] Bump jetty-server in /simpleclient_jetty (#800) Bumps [jetty-server](https://github.com/eclipse/jetty.project) from 9.4.44.v20210927 to 10.0.10. - [Release notes](https://github.com/eclipse/jetty.project/releases) - [Commits](https://github.com/eclipse/jetty.project/compare/jetty-9.4.44.v20210927...jetty-10.0.10) --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- simpleclient_jetty/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 2dc1c2b53..a6280f7f5 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -17,7 +17,7 @@ - 9.4.44.v20210927 + 10.0.10 From cb0c862ca52231e6369ef4d9e1ef5b9178e763e6 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 10 Jul 2022 05:29:16 -0400 Subject: [PATCH 164/980] Added CompilationMXBean compilation time metric (#798) Signed-off-by: Doug Hoard --- .../prometheus/client/CollectorRegistry.java | 18 +++++ .../client/hotspot/CompilationExports.java | 66 +++++++++++++++++++ .../client/hotspot/DefaultExports.java | 11 ++-- .../hotspot/CompilationExportsTest.java | 59 +++++++++++++++++ 4 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java create mode 100644 simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java index e2ebd10e0..6487f18f8 100644 --- a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java +++ b/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java @@ -254,4 +254,22 @@ public Double getSampleValue(String name, String[] labelNames, String[] labelVal return null; } + /** + * Returns the given value, or null if it doesn't exist. + *

+ * This is inefficient, and intended only for use in unittests. + */ + public Double getSampleValue(String name, String[] labelNames, String[] labelValues, Predicate sampleNameFilter) { + for (Collector.MetricFamilySamples metricFamilySamples : Collections.list(filteredMetricFamilySamples(sampleNameFilter))) { + for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) { + if (sample.name.equals(name) + && Arrays.equals(sample.labelNames.toArray(), labelNames) + && Arrays.equals(sample.labelValues.toArray(), labelValues)) { + return sample.value; + } + } + } + return null; + } + } diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java new file mode 100644 index 000000000..50c00c8b0 --- /dev/null +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java @@ -0,0 +1,66 @@ +package io.prometheus.client.hotspot; + +import io.prometheus.client.Collector; +import io.prometheus.client.CounterMetricFamily; +import io.prometheus.client.GaugeMetricFamily; +import io.prometheus.client.Predicate; + +import java.lang.management.ManagementFactory; +import java.lang.management.CompilationMXBean; +import java.util.ArrayList; +import java.util.List; + +import static io.prometheus.client.SampleNameFilter.ALLOW_ALL; + +/** + * Exports metrics about JVM compilation. + *

+ * Example usage: + *

+ * {@code
+ *   new CompilationExports().register();
+ * }
+ * 
+ * Example metrics being exported: + *
+ *   jvm_compilation_time_ms_total{} 123432
+ * 
+ */ +public class CompilationExports extends Collector { + + private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL = "jvm_compilation_time_seconds_total"; + + private final CompilationMXBean compilationMXBean; + + public CompilationExports() { + this(ManagementFactory.getCompilationMXBean()); + } + + public CompilationExports(CompilationMXBean compilationMXBean) { + this.compilationMXBean = compilationMXBean; + } + + void addCompilationMetrics(List sampleFamilies, Predicate nameFilter) { + // Sanity check in the scenario that a JVM doesn't implement compilation time monitoring + if (compilationMXBean != null && compilationMXBean.isCompilationTimeMonitoringSupported()) { + if (nameFilter.test(JVM_COMPILATION_TIME_SECONDS_TOTAL)) { + sampleFamilies.add(new CounterMetricFamily( + JVM_COMPILATION_TIME_SECONDS_TOTAL, + "The total time in seconds taken for HotSpot class compilation", + compilationMXBean.getTotalCompilationTime() / MILLISECONDS_PER_SECOND)); + } + } + } + + @Override + public List collect() { + return collect(null); + } + + @Override + public List collect(Predicate nameFilter) { + List mfs = new ArrayList(1); + addCompilationMetrics(mfs, nameFilter == null ? ALLOW_ALL : nameFilter); + return mfs; + } +} \ No newline at end of file diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java index 79cd6ed5e..b1d626d61 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java @@ -16,6 +16,7 @@ *
*/ public class DefaultExports { + private static boolean initialized = false; /** @@ -34,14 +35,14 @@ public static synchronized void initialize() { * Register the default Hotspot collectors with the given registry. */ public static void register(CollectorRegistry registry) { - new StandardExports().register(registry); - new MemoryPoolsExports().register(registry); - new MemoryAllocationExports().register(registry); new BufferPoolsExports().register(registry); + new ClassLoadingExports().register(registry); + new CompilationExports().register(registry); new GarbageCollectorExports().register(registry); + new MemoryAllocationExports().register(registry); + new MemoryPoolsExports().register(registry); + new StandardExports().register(registry); new ThreadExports().register(registry); - new ClassLoadingExports().register(registry); new VersionInfoExports().register(registry); } - } diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java new file mode 100644 index 000000000..600217ba0 --- /dev/null +++ b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java @@ -0,0 +1,59 @@ +package io.prometheus.client.hotspot; + +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.SampleNameFilter; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.lang.management.CompilationMXBean; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +public class CompilationExportsTest { + + private CompilationMXBean mockCompilationsBean = Mockito.mock(CompilationMXBean.class); + private CollectorRegistry registry = new CollectorRegistry(); + private CompilationExports collectorUnderTest; + + private static final String[] EMPTY_LABEL = new String[0]; + + @Before + public void setUp() { + when(mockCompilationsBean.getTotalCompilationTime()).thenReturn(10000l); + when(mockCompilationsBean.isCompilationTimeMonitoringSupported()).thenReturn(true); + collectorUnderTest = new CompilationExports(mockCompilationsBean).register(registry); + } + + @Test + public void testCompilationExports() { + assertEquals( + 10.0, + registry.getSampleValue( + "jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL), + .0000001); + } + + @Test + public void testCompilationExportsWithFilter() { + assertEquals( + 10.0, + registry.getSampleValue( + "jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL, SampleNameFilter.ALLOW_ALL), + .0000001); + } + + @Test + public void testCompilationExportsFiltered() { + SampleNameFilter sampleNameFilter = + new SampleNameFilter.Builder() + .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") + .build(); + + assertNull( + registry.getSampleValue( + "jvm_compilation_time_seconds_total", EMPTY_LABEL, EMPTY_LABEL, sampleNameFilter)); + } +} From 149c0c06d9ac9020ec9240844f3fcb0da03909b6 Mon Sep 17 00:00:00 2001 From: Arthur S <36887373+arixmkii@users.noreply.github.com> Date: Tue, 19 Jul 2022 14:21:23 +0300 Subject: [PATCH 165/980] SubstrateVM awareness (#802) * SubstrateVM awareness Signed-off-by: Arthur Sengileyev * SubstrateVM awareness (via system properties check) Signed-off-by: Arthur Sengileyev --- .../client/hotspot/NativeImageChecker.java | 13 +++++ .../client/hotspot/ThreadExports.java | 56 ++++++++++--------- 2 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java new file mode 100644 index 000000000..3d5367964 --- /dev/null +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java @@ -0,0 +1,13 @@ +package io.prometheus.client.hotspot; + +/** + * Contains utilities to check if we are running inside or building for native image. Default behavior is to check + * if specific for graalvm runtime property is present. For additional optimizations it is possible to do add + * "--initialize-at-build-time=io.prometheus.client.hotspot.NativeImageChecker" to graalvm native image build command and + * the native image will be identified during build time. + */ +public final class NativeImageChecker { + static final boolean isGraalVmNativeImage = System.getProperty("org.graalvm.nativeimage.imagecode") != null; + + private NativeImageChecker() {} +} diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java index 42442b879..d74300cf5 100644 --- a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java +++ b/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java @@ -90,36 +90,38 @@ void addThreadMetrics(List sampleFamilies, Predicate threadStateCounts = getThreadStateCountMap(); - for (Map.Entry entry : threadStateCounts.entrySet()) { - threadStateFamily.addMetric( - Collections.singletonList(entry.getKey()), - entry.getValue() - ); + if (nameFilter.test(JVM_THREADS_STATE)) { + GaugeMetricFamily threadStateFamily = new GaugeMetricFamily( + JVM_THREADS_STATE, + "Current count of threads by state", + Collections.singletonList("state")); + + Map threadStateCounts = getThreadStateCountMap(); + for (Map.Entry entry : threadStateCounts.entrySet()) { + threadStateFamily.addMetric( + Collections.singletonList(entry.getKey()), + entry.getValue() + ); + } + sampleFamilies.add(threadStateFamily); } - sampleFamilies.add(threadStateFamily); } } From 1966186deaaa83aec496d88ff604a90795bad688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Jul 2022 15:46:14 +0200 Subject: [PATCH 166/980] Fix HTTPServer's default ExecutorService --- .../main/java/io/prometheus/client/exporter/HTTPServer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java index ffb591ab8..166f0350b 100644 --- a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java +++ b/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java @@ -31,6 +31,7 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPOutputStream; @@ -452,8 +453,8 @@ private HTTPServer(ExecutorService executorService, HttpServer httpServer, Colle if (executorService != null) { this.executorService = executorService; } else { - ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon)); - executor.setCorePoolSize(1); + ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(NamedDaemonThreadFactory.defaultThreadFactory(daemon)); + executor.setKeepAliveTime(2, TimeUnit.MINUTES); this.executorService = executor; } server.setExecutor(this.executorService); From c28b901225e35e7c1df0eacae8b58fdfbb390162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 22 Sep 2022 22:59:09 +0200 Subject: [PATCH 167/980] Fix rounding errors when creating histogram buckets --- .../java/io/prometheus/client/Histogram.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/simpleclient/src/main/java/io/prometheus/client/Histogram.java index c97da1213..c29dd4bcf 100644 --- a/simpleclient/src/main/java/io/prometheus/client/Histogram.java +++ b/simpleclient/src/main/java/io/prometheus/client/Histogram.java @@ -5,6 +5,7 @@ import io.prometheus.client.exemplars.HistogramExemplarSampler; import java.io.Closeable; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -128,8 +129,23 @@ public Builder buckets(double... buckets) { */ public Builder linearBuckets(double start, double width, int count) { buckets = new double[count]; + // Why BigDecimal? + // Because if you call linearBuckets(0.1, 0.1, 10) without BigDecimal you'll see annoying buckets like these: + // http_request_duration_seconds_bucket{le="0.1",} 10.0 + // http_request_duration_seconds_bucket{le="0.2",} 35.0 + // http_request_duration_seconds_bucket{le="0.30000000000000004",} 56.0 + // http_request_duration_seconds_bucket{le="0.4",} 63.0 + // http_request_duration_seconds_bucket{le="0.5",} 74.0 + // http_request_duration_seconds_bucket{le="0.6",} 101.0 + // http_request_duration_seconds_bucket{le="0.7000000000000001",} 134.0 + // http_request_duration_seconds_bucket{le="0.8",} 149.0 + // http_request_duration_seconds_bucket{le="0.9",} 156.0 + // http_request_duration_seconds_bucket{le="1.0",} 159.0 + // http_request_duration_seconds_bucket{le="+Inf",} 159.0 + BigDecimal s = new BigDecimal(Double.toString(start)); + BigDecimal w = new BigDecimal(Double.toString(width)); for (int i = 0; i < count; i++) { - buckets[i] = start + i * width; + buckets[i] = s.add(w.multiply(new BigDecimal(i))).doubleValue(); } return this; } From e11713f7c62f08a73bb987b7ecdfbd70c6b5e72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 9 Dec 2022 17:35:24 +0100 Subject: [PATCH 168/980] Fix integration test failure #826 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- integration_tests/it_exemplars_otel_agent/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 5ec4b0727..da8d0c378 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -76,6 +76,7 @@ org.springframework.boot spring-boot-maven-plugin + 2.7.6 From 7cf0cc9dc58981198be106a27333653bed7bf688 Mon Sep 17 00:00:00 2001 From: tt0suzy Date: Sun, 11 Dec 2022 14:38:03 -0600 Subject: [PATCH 169/980] fixed flaky test (#829) * fixed flaky test * change single labels back to HashMap --- .../samplebuilder/CustomMappingSampleBuilderTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java index b906fbbf6..c4af8f93e 100644 --- a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java +++ b/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java @@ -6,6 +6,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -81,7 +82,7 @@ public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() { @Test public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { - final Map labels = new HashMap(); + final Map labels = new LinkedHashMap(); labels.put("service", "${0}"); labels.put("status", "${1}"); final MapperConfig mapperConfig = new MapperConfig( @@ -106,7 +107,7 @@ public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { @Test public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() { - final Map labels = new HashMap(); + final Map labels = new LinkedHashMap(); labels.put("service", "${0}_${1}"); labels.put("status", "s_${1}"); final MapperConfig mapperConfig = new MapperConfig( @@ -131,7 +132,7 @@ public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample @Test public void test_WHEN_MetricNameSuffixRequested_THEN_ShouldReturnCorrectSample() { - final Map labels = new HashMap(); + final Map labels = new LinkedHashMap(); labels.put("service", "${0}"); labels.put("status", "s_${1}"); final MapperConfig mapperConfig = new MapperConfig( @@ -156,7 +157,7 @@ public void test_WHEN_MetricNameSuffixRequested_THEN_ShouldReturnCorrectSample() @Test public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() { - final Map labels = new HashMap(); + final Map labels = new LinkedHashMap(); labels.put("service", "${0}"); labels.put("status", "s_${1}"); final MapperConfig mapperConfig = new MapperConfig( From be8ae3bdcd84f411f825f2a86921608774e95616 Mon Sep 17 00:00:00 2001 From: Hendrik Ebbers Date: Fri, 23 Dec 2022 16:18:05 +0100 Subject: [PATCH 170/980] minimal information about the build of the project (#830) Signed-off-by: Hendrik Ebbers Signed-off-by: Hendrik Ebbers --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f619acd0e..0e9a2ef90 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Table of Contents * [Using](#using) * [Assets](#assets) * [Javadocs](#javadocs) + * [Building](#building) * [Instrumenting](#instrumenting) * [Counter](#counter) * [Gauge](#gauge) @@ -81,6 +82,10 @@ suffixed with `_created` and a value of the unix timestamp for when the metric was created. If this information is not helpful, it can be disabled by setting the environment variable `PROMETHEUS_DISABLE_CREATED_SERIES=true`. +## Building + +Building the repository needs Java <= 11 (The project the project still supports Java 6 and Java 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installqation is needed. To build the repository just call `./mvnw verify`. + ## Instrumenting Four types of metrics are offered: Counter, Gauge, Summary and Histogram. From 248ac4b036a3d61af4aba4e8e9a4d425cbee8b62 Mon Sep 17 00:00:00 2001 From: javaxiaomangren Date: Wed, 7 Dec 2022 14:08:52 +0800 Subject: [PATCH 171/980] update org.eclipse.jetty:jetty-server 11.0.9 to 11.0.10 --- simpleclient_jetty_jdk8/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 2e9d54435..38199d315 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -52,7 +52,7 @@ org.eclipse.jetty jetty-server - 11.0.9 + 11.0.10 org.eclipse.jetty From 91b7d18d9c354d019301bc1c5161d9be04b669da Mon Sep 17 00:00:00 2001 From: liukun4515 Date: Mon, 26 Dec 2022 14:33:27 +0800 Subject: [PATCH 172/980] fix bug for tag Signed-off-by: liukun4515 --- .../src/main/java/io/prometheus/client/bridge/Graphite.java | 2 +- .../src/test/java/io/prometheus/client/bridge/GraphiteTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java b/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java index 5e292800c..09cda1b04 100644 --- a/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java +++ b/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java @@ -61,7 +61,7 @@ public void push(CollectorRegistry registry) throws IOException { writer.write(m.replaceAll("_")); for (int i = 0; i < sample.labelNames.size(); ++i) { m.reset(sample.labelValues.get(i)); - writer.write("." + sample.labelNames.get(i) + "." + m.replaceAll("_")); + writer.write(";" + sample.labelNames.get(i) + "=" + m.replaceAll("_")); } writer.write(" " + sample.value + " " + now + "\n"); } diff --git a/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java b/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java index dbe6099ef..d0f00bc49 100644 --- a/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java +++ b/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java @@ -50,7 +50,7 @@ public void run() { // Check result. String[] parts = result.toString().split(" "); assertEquals(3, parts.length); - assertEquals("labels.l.fo_o", parts[0]); + assertEquals("labels;l=fo_o", parts[0]); assertEquals("1.0", parts[1]); Integer.parseInt(parts[2]); // This shouldn't throw an exception. } From 9ba0c2a9376986b6b47e031e04b277e9a93c9431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 11 Jan 2023 15:41:11 +0100 Subject: [PATCH 173/980] Fix Java version description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e9a2ef90..30560c5e5 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ the environment variable `PROMETHEUS_DISABLE_CREATED_SERIES=true`. ## Building -Building the repository needs Java <= 11 (The project the project still supports Java 6 and Java 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installqation is needed. To build the repository just call `./mvnw verify`. +Building the repository needs Java 11 (The project the project still supports Java 6 and Java versions > 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installqation is needed. To build the repository just call `./mvnw verify`. ## Instrumenting From da243e272d80d58d4b8bbf5c63d4aec4feaed51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 22 Mar 2023 15:54:30 +0100 Subject: [PATCH 174/980] Add Doug Hoard as maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- MAINTAINERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index e3deed2ca..c79384366 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,2 +1,3 @@ * Fabian Stäber @fstab +* Doug Hoard @dhoard * Tom Wilkie @tomwilkie From db2304d042a8f9373504b167efcfbbea13a9e1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 31 May 2023 10:17:30 +0200 Subject: [PATCH 175/980] Update CircleCI build image --- .circleci/config.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b7b9e2afe..91ddc1e5c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,13 +3,19 @@ machine: true jobs: build: machine: - image: ubuntu-2004:202010-01 + image: ubuntu-2204:2023.04.2 working_directory: ~/circleci-java steps: + - run: + name: Install OpenJDK 11 + command: | + sudo apt-get update && sudo apt-get install openjdk-11-jdk + sudo update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java + sudo update-alternatives --set javac /usr/lib/jvm/java-11-openjdk-amd64/bin/javac + java -version - checkout - restore_cache: key: maven-dependencies-{{ checksum "pom.xml" }} - - run: java -version - run: ./mvnw clean install - run: ./mvnw javadoc:jar - save_cache: From 98967b8367216f4107ad5621f260ed895c930262 Mon Sep 17 00:00:00 2001 From: CianShev <47430248+CianShev@users.noreply.github.com> Date: Thu, 6 Jul 2023 10:43:40 +0100 Subject: [PATCH 176/980] Update README.md Fixed small spelling error in README.md Signed-off-by: CianShev <47430248+CianShev@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30560c5e5..b8655dea7 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ the environment variable `PROMETHEUS_DISABLE_CREATED_SERIES=true`. ## Building -Building the repository needs Java 11 (The project the project still supports Java 6 and Java versions > 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installqation is needed. To build the repository just call `./mvnw verify`. +Building the repository needs Java 11 (The project the project still supports Java 6 and Java versions > 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installation is needed. To build the repository just call `./mvnw verify`. ## Instrumenting From 27fe3b733165230c4f5ae6f9bbf3242b095b8ad7 Mon Sep 17 00:00:00 2001 From: dhoard Date: Sat, 5 Aug 2023 19:03:17 -0400 Subject: [PATCH 177/980] Changed to remove use of inefficient String method Signed-off-by: dhoard --- .../prometheus/client/exporter/common/TextFormat.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java index db2de3a5b..58c0ebfa9 100644 --- a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java +++ b/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java @@ -137,8 +137,9 @@ public static void write004(Writer writer, Enumeration Date: Thu, 11 May 2023 16:13:08 +0200 Subject: [PATCH 178/980] Prometheus Metrics 1.0.x - Initial Commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .circleci/config.yml | 1 + benchmarks/pom.xml | 4 +- examples/pom.xml | 39 + examples/tomcat-servlet-example/pom.xml | 76 + .../tomcat_servlet/HelloWorldServlet.java | 47 + .../metrics/examples/tomcat_servlet/Main.java | 34 + integration_tests/it_common/pom.xml | 10 +- .../it_exemplars_otel_agent/pom.xml | 10 +- .../it_exemplars_otel_sdk/pom.xml | 10 +- .../ExemplarsOpenTelemetrySdkIT.java | 6 +- integration_tests/it_java_versions/pom.xml | 42 +- .../it/java_versions/JavaVersionsIT.java | 4 +- integration_tests/it_log4j2/pom.xml | 45 +- .../prometheus/client/it/log4j2/Log4j2IT.java | 2 - integration_tests/it_pushgateway/pom.xml | 42 +- .../client/it/pushgateway/PushGatewayIT.java | 5 +- .../pom.xml | 10 +- integration_tests/pom.xml | 4 +- pom.xml | 23 +- prometheus-metrics-config/pom.xml | 45 + .../metrics/config/ExemplarsProperties.java | 114 + .../config/ExporterFilterProperties.java | 117 + .../config/ExporterHttpServerProperties.java | 50 + .../metrics/config/ExporterProperties.java | 78 + .../metrics/config/MetricsProperties.java | 432 + .../metrics/config/PrometheusProperties.java | 79 + .../config/PrometheusPropertiesException.java | 12 + .../config/PrometheusPropertiesLoader.java | 105 + .../io/prometheus/metrics/config/Util.java | 112 + .../config/PrometheusPropertiesTest.java | 29 + .../resources/emptyUpperBounds.properties | 1 + .../src/test/resources/prometheus.properties | 20 + prometheus-metrics-config/version-rules.xml | 6 + prometheus-metrics-core/pom.xml | 67 + .../core/datapoints/CounterDataPoint.java | 88 + .../metrics/core/datapoints/DataPoint.java | 4 + .../datapoints/DistributionDataPoint.java | 36 + .../core/datapoints/GaugeDataPoint.java | 80 + .../core/datapoints/StateSetDataPoint.java | 33 + .../metrics/core/datapoints/Timer.java | 40 + .../metrics/core/datapoints/TimerApi.java | 74 + .../core/exemplars/ExemplarSampler.java | 326 + .../core/exemplars/ExemplarSamplerConfig.java | 135 + .../metrics/core/metrics/Buffer.java | 84 + .../metrics/core/metrics/CKMSQuantiles.java | 296 + .../metrics/core/metrics/CallbackMetric.java | 42 + .../metrics/core/metrics/Counter.java | 252 + .../core/metrics/CounterWithCallback.java | 101 + .../metrics/core/metrics/Gauge.java | 213 + .../core/metrics/GaugeWithCallback.java | 86 + .../metrics/core/metrics/Histogram.java | 926 + .../prometheus/metrics/core/metrics/Info.java | 132 + .../metrics/core/metrics/Metric.java | 68 + .../core/metrics/MetricWithFixedMetadata.java | 90 + .../metrics/core/metrics/SlidingWindow.java | 74 + .../metrics/core/metrics/StateSet.java | 194 + .../metrics/core/metrics/StatefulMetric.java | 158 + .../metrics/core/metrics/Summary.java | 355 + .../core/metrics/SummaryWithCallback.java | 93 + .../metrics/core/util/Scheduler.java | 37 + .../ExemplarSamplerConfigTestUtil.java | 30 + .../core/exemplars/ExemplarSamplerTest.java | 234 + .../metrics/core/metrics/CounterTest.java | 300 + .../metrics/core/metrics/GaugeTest.java | 222 + .../metrics/core/metrics/HistogramTest.java | 1306 ++ .../metrics/core/metrics/InfoTest.java | 23 + .../metrics/core/metrics/StateSetTest.java | 75 + .../core/metrics/StatefulMetricTest.java | 36 + .../metrics/core/metrics/TestUtil.java | 13 + .../metrics/core/metrics/TodoTest.java | 17 + prometheus-metrics-core/version-rules.xml | 6 + .../pom.xml | 54 + .../jakarta/PrometheusMetricsServlet.java | 89 + .../version-rules.xml | 12 + .../generate-protobuf.sh | 16 + prometheus-metrics-exposition-formats/pom.xml | 85 + .../com_google_protobuf_3_21_7/Metrics.java | 14221 ++++++++++++++++ .../ExpositionFormatWriter.java | 12 + .../expositionformats/ExpositionFormats.java | 53 + .../OpenMetricsTextFormatWriter.java | 341 + .../PrometheusProtobufWriter.java | 368 + .../PrometheusTextFormatWriter.java | 347 + .../expositionformats/ProtobufUtil.java | 13 + .../expositionformats/TextFormatUtil.java | 80 + .../src/main/protobuf/metrics.proto | 144 + .../ExpositionFormatsTest.java | 1471 ++ .../version-rules.xml | 6 + prometheus-metrics-model/pom.xml | 45 + .../metrics/model/registry/Collector.java | 42 + .../model/registry/MetricNameFilter.java | 196 + .../model/registry/MultiCollector.java | 44 + .../model/registry/PrometheusRegistry.java | 95 + .../snapshots/ClassicHistogramBucket.java | 42 + .../snapshots/ClassicHistogramBuckets.java | 223 + .../model/snapshots/CounterSnapshot.java | 148 + .../model/snapshots/DataPointSnapshot.java | 82 + .../DistributionDataPointSnapshot.java | 89 + .../metrics/model/snapshots/Exemplar.java | 129 + .../metrics/model/snapshots/Exemplars.java | 128 + .../model/snapshots/GaugeSnapshot.java | 134 + .../model/snapshots/HistogramSnapshot.java | 397 + .../metrics/model/snapshots/InfoSnapshot.java | 104 + .../metrics/model/snapshots/Label.java | 28 + .../metrics/model/snapshots/Labels.java | 364 + .../model/snapshots/MetricMetadata.java | 168 + .../model/snapshots/MetricSnapshot.java | 82 + .../model/snapshots/MetricSnapshots.java | 98 + .../snapshots/NativeHistogramBucket.java | 26 + .../snapshots/NativeHistogramBuckets.java | 159 + .../metrics/model/snapshots/Quantile.java | 34 + .../metrics/model/snapshots/Quantiles.java | 85 + .../model/snapshots/StateSetSnapshot.java | 225 + .../model/snapshots/SummarySnapshot.java | 136 + .../metrics/model/snapshots/Unit.java | 47 + .../model/snapshots/UnknownSnapshot.java | 135 + .../ClassicHistogramBucketsTest.java | 104 + .../model/snapshots/CounterSnapshotTest.java | 108 + .../metrics/model/snapshots/ExemplarTest.java | 78 + .../model/snapshots/ExemplarsTest.java | 42 + .../model/snapshots/GaugeSnapshotTest.java | 106 + .../snapshots/HistogramSnapshotTest.java | 269 + .../model/snapshots/InfoSnapshotTest.java | 46 + .../metrics/model/snapshots/LabelsTest.java | 80 + .../model/snapshots/MetricMetadataTest.java | 55 + .../model/snapshots/MetricSnapshotTest.java | 37 + .../model/snapshots/MetricSnapshotsTest.java | 86 + .../snapshots/NativeHistogramBucketsTest.java | 65 + .../model/snapshots/QuantilesTest.java | 53 + .../model/snapshots/SnapshotTestUtil.java | 17 + .../model/snapshots/StateSetSnapshotTest.java | 145 + .../model/snapshots/SummarySnapshotTest.java | 105 + .../model/snapshots/UnknownSnapshotTest.java | 71 + prometheus-metrics-model/version-rules.xml | 6 + prometheus-metrics-tracer/pom.xml | 52 + .../prometheus-metrics-tracer-common/pom.xml | 34 + .../metrics/tracer/common/SpanContext.java | 26 + .../version-rules.xml | 6 + .../pom.xml | 52 + .../initializer/SpanContextSupplier.java | 45 + .../version-rules.xml | 6 + .../pom.xml | 78 + .../OpenTelemetryAgentSpanContext.java | 52 + .../version-rules.xml | 6 + .../prometheus-metrics-tracer-otel/pom.xml | 48 + .../tracer/otel/OpenTelemetrySpanContext.java | 47 + .../version-rules.xml | 6 + prometheus-metrics-tracer/version-rules.xml | 6 + protobuf-shaded/.gitignore | 1 + protobuf-shaded/README.md | 1 + protobuf-shaded/pom.xml | 160 + simpleclient/pom.xml | 4 +- simpleclient_bom/pom.xml | 4 +- simpleclient_caffeine/pom.xml | 6 +- simpleclient_common/pom.xml | 6 +- simpleclient_dropwizard/pom.xml | 51 +- simpleclient_graphite_bridge/pom.xml | 6 +- simpleclient_guava/pom.xml | 6 +- simpleclient_hibernate/pom.xml | 6 +- simpleclient_hotspot/pom.xml | 52 +- simpleclient_httpserver/pom.xml | 8 +- simpleclient_jetty/pom.xml | 6 +- simpleclient_jetty_jdk8/pom.xml | 19 +- simpleclient_log4j/pom.xml | 6 +- simpleclient_log4j2/pom.xml | 6 +- simpleclient_logback/pom.xml | 6 +- simpleclient_pushgateway/pom.xml | 8 +- simpleclient_servlet/pom.xml | 10 +- simpleclient_servlet_common/pom.xml | 8 +- simpleclient_servlet_jakarta/pom.xml | 10 +- simpleclient_spring_boot/pom.xml | 10 +- simpleclient_spring_web/pom.xml | 8 +- simpleclient_tracer/pom.xml | 4 +- .../simpleclient_tracer_common/pom.xml | 2 +- .../simpleclient_tracer_otel/pom.xml | 15 +- .../simpleclient_tracer_otel_agent/pom.xml | 10 +- simpleclient_vertx/pom.xml | 16 +- simpleclient_vertx4/pom.xml | 16 +- 177 files changed, 30756 insertions(+), 409 deletions(-) create mode 100644 examples/pom.xml create mode 100644 examples/tomcat-servlet-example/pom.xml create mode 100644 examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java create mode 100644 examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java create mode 100644 prometheus-metrics-config/pom.xml create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/resources/emptyUpperBounds.properties create mode 100644 prometheus-metrics-config/src/test/resources/prometheus.properties create mode 100644 prometheus-metrics-config/version-rules.xml create mode 100644 prometheus-metrics-core/pom.xml create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java create mode 100644 prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java create mode 100644 prometheus-metrics-core/version-rules.xml create mode 100644 prometheus-metrics-exporter-servlet-jakarta/pom.xml create mode 100644 prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java create mode 100644 prometheus-metrics-exporter-servlet-jakarta/version-rules.xml create mode 100755 prometheus-metrics-exposition-formats/generate-protobuf.sh create mode 100644 prometheus-metrics-exposition-formats/pom.xml create mode 100644 prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java create mode 100644 prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java create mode 100644 prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto create mode 100644 prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java create mode 100644 prometheus-metrics-exposition-formats/version-rules.xml create mode 100644 prometheus-metrics-model/pom.xml create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java create mode 100644 prometheus-metrics-model/version-rules.xml create mode 100644 prometheus-metrics-tracer/pom.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-common/version-rules.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/version-rules.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/version-rules.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java create mode 100644 prometheus-metrics-tracer/prometheus-metrics-tracer-otel/version-rules.xml create mode 100644 prometheus-metrics-tracer/version-rules.xml create mode 100644 protobuf-shaded/.gitignore create mode 100644 protobuf-shaded/README.md create mode 100644 protobuf-shaded/pom.xml diff --git a/.circleci/config.yml b/.circleci/config.yml index 91ddc1e5c..8e864014b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,6 +16,7 @@ jobs: - checkout - restore_cache: key: maven-dependencies-{{ checksum "pom.xml" }} + - run: cd protobuf-shaded && ../mvnw install && cd .. - run: ./mvnw clean install - run: ./mvnw javadoc:jar - save_cache: diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index f14128b41..db455570b 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT benchmarks diff --git a/examples/pom.xml b/examples/pom.xml new file mode 100644 index 000000000..fb53876ed --- /dev/null +++ b/examples/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + examples + pom + + Prometheus Metrics Examples + + Example projects for the Prometheus Metrics Library. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + tomcat-servlet-example + + + diff --git a/examples/tomcat-servlet-example/pom.xml b/examples/tomcat-servlet-example/pom.xml new file mode 100644 index 000000000..0688b6045 --- /dev/null +++ b/examples/tomcat-servlet-example/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.0.0-alpha-1-SNAPSHOT + + + tomcat-servlet-example + + Tomcat Servlet Example + + Prometheus Metrics Example using Embedded Tomcat and the Exporter Servlet + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-servlet-jakarta + ${project.version} + + + org.apache.tomcat.embed + tomcat-embed-core + 10.1.11 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.tomcat_servlet.Main + + + + + + + + + diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java new file mode 100644 index 000000000..97d4161ef --- /dev/null +++ b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -0,0 +1,47 @@ +package io.prometheus.metrics.examples.tomcat_servlet; + +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.model.snapshots.Unit; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.Random; + +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; + +public class HelloWorldServlet extends HttpServlet { + + private final Random random = new Random(0); + + private final Counter counter = Counter.newBuilder() + .withName("requests_total") + .withHelp("total number of requests") + .withLabelNames("http_status") + .register(); + + private final Histogram histogram = Histogram.newBuilder() + .withName("request_duration_seconds") + .withHelp("request duration in seconds") + .withUnit(Unit.SECONDS) + .withLabelNames("http_status") + .register(); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("Hello, World!"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + counter.withLabelValues("200").inc(); + histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + } + } +} diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java new file mode 100644 index 000000000..759b88cb9 --- /dev/null +++ b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java @@ -0,0 +1,34 @@ +package io.prometheus.metrics.examples.tomcat_servlet; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; + +import java.io.File; + +/** + * Simple example using embedded Tomcat an the {@link PrometheusMetricsServlet}. + */ +public class Main { + + public static void main(String[] args) throws LifecycleException { + + Tomcat tomcat = new Tomcat(); + tomcat.setPort(8080); + + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + + Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); + ctx.addServletMappingDecoded("/*", "hello"); + + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); + + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } +} diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index ff8e7ea09..44758744c 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_common @@ -32,14 +32,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - org.apache.maven.plugins maven-jar-plugin diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index da8d0c378..80a97e549 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_exemplars_otel_agent @@ -85,14 +85,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index e8eff08c1..90c99c155 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_exemplars_otel_sdk @@ -63,14 +63,6 @@ example-open-telemetry-app - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin diff --git a/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java b/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java index 3f2f89b76..3e6287a13 100644 --- a/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java +++ b/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java @@ -16,7 +16,7 @@ /** * Test if traces from the OpenTelemetry SDK are picked up as Exemplars. - *

+ *

* In addition, we make sure that missing OpenTelemetry dependencies do not cause client_java to crash the application. **/ public class ExemplarsOpenTelemetrySdkIT { @@ -65,7 +65,7 @@ public void testGoodCase() throws IOException { /** * The dependency simpleclient_tracer_otel_agent is for getting the trace context from the OpenTelemetry Java agent. * As we are getting the trace context from the OpenTelemetry SDK and not from the agent, Exemplars should work. - *

+ *

* We test this because if a user excludes simpleclient_tracer_otel_agent from the transitive dependencies for some reason * we don't want client_java to break. */ @@ -78,7 +78,7 @@ public void testOtelAgentMissing() throws IOException, URISyntaxException { /** * The dependency simpleclient_tracer_otel is for getting the trace context from the OpenTelemetry SDK. * If this dependency is missing, Exemplars will be missing, but metrics should still work. - *

+ *

* We test this because users may exclude simpleclient_tracer_otel as a way to disable OpenTelemetry Exemplars. */ @Test diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index a4f7d1cfe..64441aee0 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_java_versions @@ -72,16 +72,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin @@ -89,36 +79,6 @@ - - - - - - intellij - - false - - - - - idea.maven.embedder.version - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - The Apache Software License, Version 2.0 diff --git a/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java b/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java index bba186947..e854ed193 100644 --- a/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java +++ b/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java @@ -1,5 +1,6 @@ package io.prometheus.client.it.java_versions; +import com.github.dockerjava.api.model.Ulimit; import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Scraper; import io.prometheus.client.it.common.Version; @@ -35,9 +36,7 @@ public static String[] images() { "openjdk:8-jre", "openjdk:11-jre", "openjdk:17", - "ticketfly/java:6", "adoptopenjdk/openjdk16:ubi-minimal-jre", - "azul/zulu-openjdk:6", // OpenJ9 "ibmjava:8-jre", @@ -50,6 +49,7 @@ public JavaVersionsIT(String image) throws IOException, URISyntaxException { exampleApplicationDir = Volume.create("it-java-versions") .copyFromTargetDirectory(exampleApplicationJar); javaContainer = new GenericContainer<>(image) + .withCreateContainerCmdModifier(c -> c.getHostConfig().withUlimits(new Ulimit[]{new Ulimit("nofile", 65536L, 65536L)})) .withFileSystemBind(exampleApplicationDir.getHostPath(), "/app", BindMode.READ_ONLY) .withWorkingDirectory("/app") .withLogConsumer(LogConsumer.withPrefix(image)) diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index e01be3b73..3090704cd 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_log4j2 @@ -88,19 +88,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - - - - 1.6 - 1.6 - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin @@ -108,36 +95,6 @@ - - - - - - intellij - - false - - - - - idea.maven.embedder.version - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - The Apache Software License, Version 2.0 diff --git a/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java b/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java index d92ba8870..8272880ba 100644 --- a/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java +++ b/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java @@ -24,8 +24,6 @@ public class Log4j2IT { private final String image = "openjdk:8-jre"; - // This test is green with a Java 6 image, but you need to downgrade the log4j version in pom.xml. - // private final String image = "azul/zulu-openjdk:6"; private final Volume volume; private final GenericContainer javaContainer; diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 25784a7cf..aa17740a1 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_pushgateway @@ -69,16 +69,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin @@ -86,36 +76,6 @@ - - - - - - intellij - - false - - - - - idea.maven.embedder.version - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - The Apache Software License, Version 2.0 diff --git a/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java b/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java index 7aba0cc19..d0fb6dac3 100644 --- a/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java +++ b/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java @@ -1,5 +1,6 @@ package io.prometheus.client.it.pushgateway; +import com.github.dockerjava.api.model.Ulimit; import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Scraper; import io.prometheus.client.it.common.Version; @@ -33,8 +34,6 @@ public class PushGatewayIT { @Parameterized.Parameters(name = "{0}") public static String[] images() { return new String[] { - "azul/zulu-openjdk:6", - "openjdk:7", "ibmjava:8-jre", "openjdk:11-slim", "openjdk:17" @@ -47,6 +46,7 @@ public PushGatewayIT(String image) throws IOException, URISyntaxException { .copyFromTargetDirectory(batchJobJar); Network network = Network.newNetwork(); pushGatewayContainer = new GenericContainer<>("prom/pushgateway") + .withCreateContainerCmdModifier(c -> c.getHostConfig().withUlimits(new Ulimit[]{new Ulimit("nofile", 65536L, 65536L)})) .withCopyFileToContainer(MountableFile.forClasspathResource("web-config.yml", 0644), "/") .withNetwork(network) .withNetworkAliases("pushgateway") @@ -54,6 +54,7 @@ public PushGatewayIT(String image) throws IOException, URISyntaxException { .withCommand("--web.config.file=/web-config.yml") .withExposedPorts(9091); javaContainer = new GenericContainer<>(image) + .withCreateContainerCmdModifier(c -> c.getHostConfig().withUlimits(new Ulimit[]{new Ulimit("nofile", 65536L, 65536L)})) .withFileSystemBind(batchJobDir.getHostPath(), "/app", BindMode.READ_ONLY) .withNetwork(network) .withWorkingDirectory("/app") diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 5201ce2ce..487dba31d 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT it_servlet_jakarta_exporter_webxml @@ -58,14 +58,6 @@ ${project.artifactId} - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - org.apache.maven.plugins maven-failsafe-plugin diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 80932482a..05a56956f 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index ee3c20583..a1259a598 100644 --- a/pom.xml +++ b/pom.xml @@ -4,8 +4,8 @@ 4.0.0 io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT Prometheus Java Suite http://github.com/prometheus/client_java @@ -37,6 +37,17 @@ + + + + prometheus-metrics-core + prometheus-metrics-config + prometheus-metrics-model + prometheus-metrics-tracer + prometheus-metrics-exposition-formats + prometheus-metrics-exporter-servlet-jakarta + examples + simpleclient simpleclient_common simpleclient_caffeine @@ -54,7 +65,7 @@ simpleclient_servlet_common simpleclient_servlet_jakarta simpleclient_spring_web - simpleclient_spring_boot + simpleclient_jetty simpleclient_jetty_jdk8 simpleclient_tracer @@ -206,6 +217,7 @@ true 8 ${java.home}/bin/javadoc + src/main/java;src/main/generated @@ -218,11 +230,10 @@ - org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml new file mode 100644 index 000000000..5810c19b7 --- /dev/null +++ b/prometheus-metrics-config/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-config + bundle + + Prometheus Metrics Config + + Configuration for Prometheus metrics and exposition formats. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + + junit + junit + 4.13.2 + test + + + diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java new file mode 100644 index 000000000..7d996f6a5 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java @@ -0,0 +1,114 @@ +package io.prometheus.metrics.config; + +import java.util.Map; + +/** + * Properties starting with io.prometheus.exemplars + */ +public class ExemplarsProperties { + + private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds"; + private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds"; + private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds"; + + private final Integer minRetentionPeriodSeconds; + private final Integer maxRetentionPeriodSeconds; + private final Integer sampleIntervalMilliseconds; + + private ExemplarsProperties( + Integer minRetentionPeriodSeconds, + Integer maxRetentionPeriodSeconds, + Integer sampleIntervalMilliseconds) { + this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; + this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; + this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; + } + + /** + * Minimum time how long Exemplars are kept before they may be replaced by new Exemplars. + *

+ * Default see {@code ExemplarSamplerConfig.DEFAULT_MIN_RETENTION_PERIOD_SECONDS} + */ + public Integer getMinRetentionPeriodSeconds() { + return minRetentionPeriodSeconds; + } + + /** + * Maximum time how long Exemplars are kept before they are evicted. + *

+ * Default see {@code ExemplarSamplerConfig.DEFAULT_MAX_RETENTION_PERIOD_SECONDS} + */ + public Integer getMaxRetentionPeriodSeconds() { + return maxRetentionPeriodSeconds; + } + + /** + * Time between attempts to sample new Exemplars. This is a performance improvement for high-frequency + * applications, because with the sample interval we make sure that the exemplar sampler is not called + * for every single request. + *

+ * Default see {@code ExemplarSamplerConfig.DEFAULT_SAMPLE_INTERVAL_MILLISECONDS} + */ + public Integer getSampleIntervalMilliseconds() { + return sampleIntervalMilliseconds; + } + + /** + * Note that this will remove entries from {@code properties}. + * This is because we want to know if there are unused properties remaining after all properties have been loaded. + */ + static ExemplarsProperties load(String prefix, Map properties) throws PrometheusPropertiesException { + Integer minRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MIN_RETENTION_PERIOD_SECONDS, properties); + Integer maxRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MAX_RETENTION_PERIOD_SECONDS, properties); + Integer sampleIntervalMilliseconds = Util.loadInteger(prefix + "." + SAMPLE_INTERVAL_MILLISECONDS, properties); + + Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MIN_RETENTION_PERIOD_SECONDS); + Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MAX_RETENTION_PERIOD_SECONDS); + Util.assertValue(sampleIntervalMilliseconds, t -> t > 0, "Expecting value > 0.", prefix, SAMPLE_INTERVAL_MILLISECONDS); + + if (minRetentionPeriodSeconds != null && maxRetentionPeriodSeconds != null) { + if (minRetentionPeriodSeconds > maxRetentionPeriodSeconds) { + throw new PrometheusPropertiesException(prefix + "." + MIN_RETENTION_PERIOD_SECONDS + " must not be greater than " + prefix + "." + MAX_RETENTION_PERIOD_SECONDS + "."); + } + } + + return new ExemplarsProperties( + minRetentionPeriodSeconds, + maxRetentionPeriodSeconds, + sampleIntervalMilliseconds + ); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private Integer minRetentionPeriodSeconds; + private Integer maxRetentionPeriodSeconds; + private Integer sampleIntervalMilliseconds; + + private Builder() { + } + + public Builder withMinRetentionPeriodSeconds(int minRetentionPeriodSeconds) { + this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; + return this; + } + + public Builder withMaxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) { + this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; + return this; + } + + public Builder withSampleIntervalMilliseconds(int sampleIntervalMilliseconds) { + this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; + return this; + } + + public ExemplarsProperties builder() { + return new ExemplarsProperties(minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds); + } + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java new file mode 100644 index 000000000..250985329 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -0,0 +1,117 @@ +package io.prometheus.metrics.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Properties starting with io.prometheus.exporter.filter + */ +public class ExporterFilterProperties { + + public static final String NAME_MUST_BE_EQUAL_TO = "nameMustBeEqualTo"; + public static final String NAME_MUST_NOT_BE_EQUAL_TO = "nameMustNotBeEqualTo"; + public static final String NAME_MUST_START_WITH = "nameMustStartWith"; + public static final String NAME_MUST_NOT_START_WITH = "nameMustNotStartWith"; + + private final List allowedNames; + private final List excludedNames; + private final List allowedPrefixes; + private final List excludedPrefixes; + + private ExporterFilterProperties(List allowedNames, List excludedNames, List allowedPrefixes, List excludedPrefixes) { + this(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, ""); + } + + private ExporterFilterProperties(List allowedNames, List excludedNames, List allowedPrefixes, List excludedPrefixes, String prefix) { + this.allowedNames = allowedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedNames)); + this.excludedNames = excludedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedNames)); + this.allowedPrefixes = allowedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedPrefixes)); + this.excludedPrefixes = excludedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedPrefixes)); + validate(prefix); + } + + public List getAllowedNames() { + return allowedNames; + } + + public List getExcludedNames() { + return excludedNames; + } + + public List getAllowedPrefixes() { + return allowedPrefixes; + } + + public List getExcludedPrefixes() { + return excludedPrefixes; + } + + private void validate(String prefix) throws PrometheusPropertiesException { + } + + /** + * Note that this will remove entries from {@code properties}. + * This is because we want to know if there are unused properties remaining after all properties have been loaded. + */ + static ExporterFilterProperties load(String prefix, Map properties) throws PrometheusPropertiesException { + List allowedNames = Util.loadStringList(prefix + "." + NAME_MUST_BE_EQUAL_TO, properties); + List excludedNames = Util.loadStringList(prefix + "." + NAME_MUST_NOT_BE_EQUAL_TO, properties); + List allowedPrefixes = Util.loadStringList(prefix + "." + NAME_MUST_START_WITH, properties); + List excludedPrefixes = Util.loadStringList(prefix + "." + NAME_MUST_NOT_START_WITH, properties); + return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private List allowedNames; + private List excludedNames; + private List allowedPrefixes; + private List excludedPrefixes; + + private Builder() { + } + + /** + * Only allowed metric names will be exposed. + */ + public Builder withAllowedNames(String... allowedNames) { + this.allowedNames = Arrays.asList(allowedNames); + return this; + } + + /** + * Excluded metric names will not be exposed. + */ + public Builder withExcludedNames(String... excludedNames) { + this.excludedNames = Arrays.asList(excludedNames); + return this; + } + + /** + * Only metrics with a name starting with an allowed prefix will be exposed. + */ + public Builder withAllowedPrefixes(String... allowedPrefixes) { + this.allowedPrefixes = Arrays.asList(allowedPrefixes); + return this; + } + + /** + * Metrics with a name starting with an excluded prefix will not be exposed. + */ + public Builder withExcludedPrefixes(String... excludedPrefixes) { + this.excludedPrefixes = Arrays.asList(excludedPrefixes); + return this; + } + + public ExporterFilterProperties build() { + return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes); + } + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java new file mode 100644 index 000000000..8c9d7aa39 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java @@ -0,0 +1,50 @@ +package io.prometheus.metrics.config; + +import java.util.Map; + +/** + * Properties starting with io.prometheus.exporter.httpServer + */ +public class ExporterHttpServerProperties { + + // TODO: Not used yet, will be used when we port the simpleclient_httpserver module to the new data model. + + private static final String PORT = "port"; + private final Integer port; + + private ExporterHttpServerProperties(Integer port) { + this.port = port; + } + + public Integer getPort() { + return port; + } + + /** + * Note that this will remove entries from {@code properties}. + * This is because we want to know if there are unused properties remaining after all properties have been loaded. + */ + static ExporterHttpServerProperties load(String prefix, Map properties) throws PrometheusPropertiesException { + Integer port = Util.loadInteger(prefix + "." + PORT, properties); + Util.assertValue(port, t -> t > 0, "Expecting value > 0", prefix, PORT); + return new ExporterHttpServerProperties(port); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private Integer port; + + public Builder withPort(int port) { + this.port = port; + return this; + } + + public ExporterHttpServerProperties build() { + return new ExporterHttpServerProperties(port); + } + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java new file mode 100644 index 000000000..016d399f0 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -0,0 +1,78 @@ +package io.prometheus.metrics.config; + +import java.util.Map; + +/** + * Properties starting with io.prometheus.exporter + */ +public class ExporterProperties { + + private static final String INCLUDE_CREATED_TIMESTAMPS = "includeCreatedTimestamps"; + private static final String EXEMPLARS_ON_ALL_METRIC_TYPES = "exemplarsOnAllMetricTypes"; + + private final Boolean includeCreatedTimestamps; + private final Boolean exemplarsOnAllMetricTypes; + + private ExporterProperties(Boolean includeCreatedTimestamps, Boolean exemplarsOnAllMetricTypes) { + this.includeCreatedTimestamps = includeCreatedTimestamps; + this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; + } + + /** + * Include the {@code _created} timestamps in text format? Default is {@code false}. + */ + public boolean getIncludeCreatedTimestamps() { + return includeCreatedTimestamps != null && includeCreatedTimestamps; + } + + /** + * Allow Exemplars on all metric types in OpenMetrics format? + * Default is {@code false}, which means Exemplars will only be added for Counters and Histograms. + */ + public boolean getExemplarsOnAllMetricTypes() { + return exemplarsOnAllMetricTypes != null && exemplarsOnAllMetricTypes; + } + + /** + * Note that this will remove entries from {@code properties}. + * This is because we want to know if there are unused properties remaining after all properties have been loaded. + */ + static ExporterProperties load(String prefix, Map properties) throws PrometheusPropertiesException { + Boolean includeCreatedTimestamps = Util.loadBoolean(prefix + "." + INCLUDE_CREATED_TIMESTAMPS, properties); + Boolean exemplarsOnAllMetricTypes = Util.loadBoolean(prefix + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); + return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private Boolean includeCreatedTimestamps; + private Boolean exemplarsOnAllMetricTypes; + + private Builder() { + } + + /** + * See {@link #getIncludeCreatedTimestamps()} + */ + public Builder withIncludeCreatedTimestamps(boolean includeCreatedTimestamps) { + this.includeCreatedTimestamps = includeCreatedTimestamps; + return this; + } + + /** + * See {@link #getExemplarsOnAllMetricTypes()}. + */ + public Builder withExemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { + this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; + return this; + } + + public ExporterProperties build() { + return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); + } + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java new file mode 100644 index 000000000..10966b3c8 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java @@ -0,0 +1,432 @@ +package io.prometheus.metrics.config; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static java.util.Collections.unmodifiableList; + +/** + * Properties starting with io.prometheus.metrics + */ +public class MetricsProperties { + + private static final String EXEMPLARS_ENABLED = "exemplarsEnabled"; + private static final String HISTOGRAM_NATIVE_ONLY = "histogramNativeOnly"; + private static final String HISTOGRAM_CLASSIC_ONLY = "histogramClassicOnly"; + private static final String HISTOGRAM_CLASSIC_UPPER_BOUNDS = "histogramClassicUpperBounds"; + private static final String HISTOGRAM_NATIVE_INITIAL_SCHEMA = "histogramNativeInitialSchema"; + private static final String HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD = "histogramNativeMinZeroThreshold"; + private static final String HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD = "histogramNativeMaxZeroThreshold"; + private static final String HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS = "histogramNativeMaxNumberOfBuckets"; // 0 means unlimited number of buckets + private static final String HISTOGRAM_NATIVE_RESET_DURATION_SECONDS = "histogramNativeResetDurationSeconds"; // 0 means no reset + private static final String SUMMARY_QUANTILES = "summaryQuantiles"; + private static final String SUMMARY_QUANTILE_ERRORS = "summaryQuantileErrors"; + private static final String SUMMARY_MAX_AGE_SECONDS = "summaryMaxAgeSeconds"; + private static final String SUMMARY_NUMBER_OF_AGE_BUCKETS = "summaryNumberOfAgeBuckets"; + + private final Boolean exemplarsEnabled; + private final Boolean histogramNativeOnly; + private final Boolean histogramClassicOnly; + private final List histogramClassicUpperBounds; + private final Integer histogramNativeInitialSchema; + private final Double histogramNativeMinZeroThreshold; + private final Double histogramNativeMaxZeroThreshold; + private final Integer histogramNativeMaxNumberOfBuckets; + private final Long histogramNativeResetDurationSeconds; + private final List summaryQuantiles; + private final List summaryQuantileErrors; + private final Long summaryMaxAgeSeconds; + private final Integer summaryNumberOfAgeBuckets; + + public MetricsProperties( + Boolean exemplarsEnabled, + Boolean histogramNativeOnly, + Boolean histogramClassicOnly, + List histogramClassicUpperBounds, + Integer histogramNativeInitialSchema, + Double histogramNativeMinZeroThreshold, + Double histogramNativeMaxZeroThreshold, + Integer histogramNativeMaxNumberOfBuckets, + Long histogramNativeResetDurationSeconds, + List summaryQuantiles, + List summaryQuantileErrors, + Long summaryMaxAgeSeconds, + Integer summaryNumberOfAgeBuckets) { + this(exemplarsEnabled, + histogramNativeOnly, + histogramClassicOnly, + histogramClassicUpperBounds, + histogramNativeInitialSchema, + histogramNativeMinZeroThreshold, + histogramNativeMaxZeroThreshold, + histogramNativeMaxNumberOfBuckets, + histogramNativeResetDurationSeconds, + summaryQuantiles, + summaryQuantileErrors, + summaryMaxAgeSeconds, + summaryNumberOfAgeBuckets, + ""); + } + + private MetricsProperties( + Boolean exemplarsEnabled, + Boolean histogramNativeOnly, + Boolean histogramClassicOnly, + List histogramClassicUpperBounds, + Integer histogramNativeInitialSchema, + Double histogramNativeMinZeroThreshold, + Double histogramNativeMaxZeroThreshold, + Integer histogramNativeMaxNumberOfBuckets, + Long histogramNativeResetDurationSeconds, + List summaryQuantiles, + List summaryQuantileErrors, + Long summaryMaxAgeSeconds, + Integer summaryNumberOfAgeBuckets, + String configPropertyPrefix) { + this.exemplarsEnabled = exemplarsEnabled; + this.histogramNativeOnly = isHistogramNativeOnly(histogramClassicOnly, histogramNativeOnly); + this.histogramClassicOnly = isHistogramClassicOnly(histogramClassicOnly, histogramNativeOnly); + this.histogramClassicUpperBounds = histogramClassicUpperBounds == null ? null : unmodifiableList(new ArrayList<>(histogramClassicUpperBounds)); + this.histogramNativeInitialSchema = histogramNativeInitialSchema; + this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; + this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; + this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; + this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; + this.summaryQuantiles = summaryQuantiles == null ? null : unmodifiableList(new ArrayList<>(summaryQuantiles)); + this.summaryQuantileErrors = summaryQuantileErrors == null ? null : unmodifiableList(new ArrayList<>(summaryQuantileErrors)); + this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; + this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; + validate(configPropertyPrefix); + } + + + private Boolean isHistogramClassicOnly(Boolean histogramClassicOnly, Boolean histogramNativeOnly) { + if (histogramClassicOnly == null && histogramNativeOnly == null) { + return null; + } + if (histogramClassicOnly != null) { + return histogramClassicOnly; + } + return !histogramNativeOnly; + } + + private Boolean isHistogramNativeOnly(Boolean histogramClassicOnly, Boolean histogramNativeOnly) { + if (histogramClassicOnly == null && histogramNativeOnly == null) { + return null; + } + if (histogramNativeOnly != null) { + return histogramNativeOnly; + } + return !histogramClassicOnly; + } + + private void validate(String prefix) throws PrometheusPropertiesException { + Util.assertValue(histogramNativeInitialSchema, s -> s >= -4 && s <= 8, "Expecting number between -4 and +8.", prefix, HISTOGRAM_NATIVE_INITIAL_SCHEMA); + Util.assertValue(histogramNativeMinZeroThreshold, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD); + Util.assertValue(histogramNativeMaxZeroThreshold, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); + Util.assertValue(histogramNativeMaxNumberOfBuckets, n -> n >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS); + Util.assertValue(histogramNativeResetDurationSeconds, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_RESET_DURATION_SECONDS); + Util.assertValue(summaryMaxAgeSeconds, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_MAX_AGE_SECONDS); + Util.assertValue(summaryNumberOfAgeBuckets, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_NUMBER_OF_AGE_BUCKETS); + + if (Boolean.TRUE.equals(histogramNativeOnly) && Boolean.TRUE.equals(histogramClassicOnly)) { + throw new PrometheusPropertiesException(prefix + "." + HISTOGRAM_NATIVE_ONLY + " and " + prefix + "." + HISTOGRAM_CLASSIC_ONLY + " cannot both be true"); + } + + if (histogramNativeMinZeroThreshold != null && histogramNativeMaxZeroThreshold != null) { + if (histogramNativeMinZeroThreshold > histogramNativeMaxZeroThreshold) { + throw new PrometheusPropertiesException(prefix + "." + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD + " cannot be greater than " + prefix + "." + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); + } + } + + if (summaryQuantiles != null) { + for (double quantile : summaryQuantiles) { + if (quantile < 0 || quantile > 1) { + throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILES + ": Expecting 0.0 <= quantile <= 1.0"); + } + } + } + + if (summaryQuantileErrors != null) { + if (summaryQuantiles == null) { + throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": Can't configure " + SUMMARY_QUANTILE_ERRORS + " without configuring " + SUMMARY_QUANTILES); + } + if (summaryQuantileErrors.size() != summaryQuantiles.size()) { + throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": must have the same length as " + SUMMARY_QUANTILES); + } + for (double error : summaryQuantileErrors) { + if (error < 0 || error > 1) { + throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": Expecting 0.0 <= error <= 1.0"); + } + } + } + } + + /** + * This is the only configuration property that can be applied to all metric types. + * You can use it to turn Exemplar support off. Default is {@code true}. + */ + public Boolean getExemplarsEnabled() { + return exemplarsEnabled; + } + + /** + * See {@code Histogram.Builder.nativeOnly()} + */ + public Boolean getHistogramNativeOnly() { + return histogramNativeOnly; + } + + /** + * See {@code Histogram.Builder.classicOnly()} + */ + public Boolean getHistogramClassicOnly() { + return histogramClassicOnly; + } + + /** + * See {@code Histogram.Builder.withClassicBuckets()} + */ + public List getHistogramClassicUpperBounds() { + return histogramClassicUpperBounds; + } + + /** + * See {@code Histogram.Builder.withNativeInitialSchema()} + */ + public Integer getHistogramNativeInitialSchema() { + return histogramNativeInitialSchema; + } + + /** + * See {@code Histogram.Builder.withNativeMinZeroThreshold()} + */ + public Double getHistogramNativeMinZeroThreshold() { + return histogramNativeMinZeroThreshold; + } + + /** + * See {@code Histogram.Builder.withNativeMaxZeroThreshold()} + */ + public Double getHistogramNativeMaxZeroThreshold() { + return histogramNativeMaxZeroThreshold; + } + + /** + * See {@code Histogram.Builder.withNativeMaxNumberOfBuckets()} + */ + public Integer getHistogramNativeMaxNumberOfBuckets() { + return histogramNativeMaxNumberOfBuckets; + } + + /** + * See {@code Histogram.Builder.withNativeResetDuration()} + */ + public Long getHistogramNativeResetDurationSeconds() { + return histogramNativeResetDurationSeconds; + } + + /** + * See {@code Summary.Builder.withQuantile()} + */ + public List getSummaryQuantiles() { + return summaryQuantiles; + } + + /** + * See {@code Summary.Builder.withQuantile()} + *

+ * Returns {@code null} only if {@link #getSummaryQuantiles()} is also {@code null}. + * Returns an empty list if {@link #getSummaryQuantiles()} are specified without specifying errors. + * If the list is not empty, it has the same size as {@link #getSummaryQuantiles()}. + */ + public List getSummaryQuantileErrors() { + if (summaryQuantiles != null) { + if (summaryQuantileErrors == null) { + return Collections.emptyList(); + } + } + return summaryQuantileErrors; + } + + /** + * See {@code Summary.Builder.withMaxAgeSeconds()} + */ + public Long getSummaryMaxAgeSeconds() { + return summaryMaxAgeSeconds; + } + + /** + * See {@code Summary.Builder.withNumberOfAgeBuckets()} + */ + public Integer getSummaryNumberOfAgeBuckets() { + return summaryNumberOfAgeBuckets; + } + + /** + * Note that this will remove entries from {@code properties}. + * This is because we want to know if there are unused properties remaining after all properties have been loaded. + */ + static MetricsProperties load(String prefix, Map properties) throws PrometheusPropertiesException { + return new MetricsProperties( + Util.loadBoolean(prefix + "." + EXEMPLARS_ENABLED, properties), + Util.loadBoolean(prefix + "." + HISTOGRAM_NATIVE_ONLY, properties), + Util.loadBoolean(prefix + "." + HISTOGRAM_CLASSIC_ONLY, properties), + Util.loadDoubleList(prefix + "." + HISTOGRAM_CLASSIC_UPPER_BOUNDS, properties), + Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_INITIAL_SCHEMA, properties), + Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD, properties), + Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD, properties), + Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS, properties), + Util.loadLong(prefix + "." + HISTOGRAM_NATIVE_RESET_DURATION_SECONDS, properties), + Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILES, properties), + Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILE_ERRORS, properties), + Util.loadLong(prefix + "." + SUMMARY_MAX_AGE_SECONDS, properties), + Util.loadInteger(prefix + "." + SUMMARY_NUMBER_OF_AGE_BUCKETS, properties), + prefix); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private Boolean exemplarsEnabled; + private Boolean histogramNativeOnly; + private Boolean histogramClassicOnly; + private List histogramClassicUpperBounds; + private Integer histogramNativeInitialSchema; + private Double histogramNativeMinZeroThreshold; + private Double histogramNativeMaxZeroThreshold; + private Integer histogramNativeMaxNumberOfBuckets; + private Long histogramNativeResetDurationSeconds; + private List summaryQuantiles; + private List summaryQuantileErrors; + private Long summaryMaxAgeSeconds; + private Integer summaryNumberOfAgeBuckets; + + private Builder() { + } + + public MetricsProperties build() { + return new MetricsProperties(exemplarsEnabled, + histogramNativeOnly, + histogramClassicOnly, + histogramClassicUpperBounds, + histogramNativeInitialSchema, + histogramNativeMinZeroThreshold, + histogramNativeMaxZeroThreshold, + histogramNativeMaxNumberOfBuckets, + histogramNativeResetDurationSeconds, + summaryQuantiles, + summaryQuantileErrors, + summaryMaxAgeSeconds, + summaryNumberOfAgeBuckets); + } + + /** + * See {@link MetricsProperties#getExemplarsEnabled()} + */ + public Builder withExemplarsEnabled(Boolean exemplarsEnabled) { + this.exemplarsEnabled = exemplarsEnabled; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeOnly()} + */ + public Builder withHistogramNativeOnly(Boolean histogramNativeOnly) { + this.histogramNativeOnly = histogramNativeOnly; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramClassicOnly()} + */ + public Builder withHistogramClassicOnly(Boolean histogramClassicOnly) { + this.histogramClassicOnly = histogramClassicOnly; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramClassicUpperBounds()} + */ + public Builder withHistogramClassicUpperBounds(double... histogramClassicUpperBounds) { + this.histogramClassicUpperBounds = Util.toList(histogramClassicUpperBounds); + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeInitialSchema()} + */ + public Builder withHistogramNativeInitialSchema(Integer histogramNativeInitialSchema) { + this.histogramNativeInitialSchema = histogramNativeInitialSchema; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeMinZeroThreshold()} + */ + public Builder withHistogramNativeMinZeroThreshold(Double histogramNativeMinZeroThreshold) { + this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeMaxZeroThreshold()} + */ + public Builder withHistogramNativeMaxZeroThreshold(Double histogramNativeMaxZeroThreshold) { + this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeMaxNumberOfBuckets()} + */ + public Builder withHistogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxNumberOfBuckets) { + this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; + return this; + } + + /** + * See {@link MetricsProperties#getHistogramNativeResetDurationSeconds()} + */ + public Builder withHistogramNativeResetDurationSeconds(Long histogramNativeResetDurationSeconds) { + this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; + return this; + } + + /** + * See {@link MetricsProperties#getSummaryQuantiles()} + */ + public Builder withSummaryQuantiles(double... summaryQuantiles) { + this.summaryQuantiles = Util.toList(summaryQuantiles); + return this; + } + + /** + * See {@link MetricsProperties#getSummaryQuantileErrors()} + */ + public Builder withSummaryQuantileErrors(double... summaryQuantileErrors) { + this.summaryQuantileErrors = Util.toList(summaryQuantileErrors); + return this; + } + + /** + * See {@link MetricsProperties#getSummaryMaxAgeSeconds()} + */ + public Builder withSummaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { + this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; + return this; + } + + /** + * See {@link MetricsProperties#getSummaryNumberOfAgeBuckets()} + */ + public Builder withSummaryNumberOfAgeBuckets(Integer summaryNumberOfAgeBuckets) { + this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; + return this; + } + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java new file mode 100644 index 000000000..9341c5988 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java @@ -0,0 +1,79 @@ +package io.prometheus.metrics.config; + +import java.util.HashMap; +import java.util.Map; + +/** + * The Prometheus Java client library can be configured at runtime (e.g. using a properties file). + *

+ * This class represents the runtime configuration. + */ +public class PrometheusProperties { + + private static final PrometheusProperties instance = PrometheusPropertiesLoader.load(); + + private final MetricsProperties defaultMetricsProperties; + private final Map metricProperties = new HashMap<>(); + private final ExemplarsProperties exemplarProperties; + private final ExporterProperties exporterProperties; + private final ExporterFilterProperties exporterFilterProperties; + private final ExporterHttpServerProperties httpServerConfig; + + /** + * Get the properties instance. When called for the first time, {@code get()} loads the properties from the following locations: + *

    + *
  • {@code prometheus.properties} file found in the classpath.
  • + *
  • Properties file specified in the {@code PROMETHEUS_CONFIG} environment variable or the {@code prometheus.config} system property.
  • + *
  • Individual properties from system properties.
  • + *
+ */ + public static PrometheusProperties get() throws PrometheusPropertiesException { + return instance; + } + + public PrometheusProperties( + MetricsProperties defaultMetricsProperties, + Map metricProperties, + ExemplarsProperties exemplarProperties, + ExporterProperties exporterProperties, + ExporterFilterProperties exporterFilterProperties, + ExporterHttpServerProperties httpServerConfig) { + this.defaultMetricsProperties = defaultMetricsProperties; + this.metricProperties.putAll(metricProperties); + this.exemplarProperties = exemplarProperties; + this.exporterProperties = exporterProperties; + this.exporterFilterProperties = exporterFilterProperties; + this.httpServerConfig = httpServerConfig; + } + + /** + * The default metric properties apply for metrics where {@link #getMetricProperties(String)} is {@code null}. + */ + public MetricsProperties getDefaultMetricProperties() { + return defaultMetricsProperties; + } + + /** + * Properties specific for one metric. Should be merged with {@link #getDefaultMetricProperties()}. + * May return {@code null} if no metric-specific properties are configured for a metric name. + */ + public MetricsProperties getMetricProperties(String metricName) { + return metricProperties.get(metricName); + } + + public ExemplarsProperties getExemplarProperties() { + return exemplarProperties; + } + + public ExporterProperties getExporterProperties() { + return exporterProperties; + } + + public ExporterFilterProperties getExporterFilterProperties() { + return exporterFilterProperties; + } + + public ExporterHttpServerProperties getExporterHttpServerProperties() { + return httpServerConfig; + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java new file mode 100644 index 000000000..e41009ca2 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java @@ -0,0 +1,12 @@ +package io.prometheus.metrics.config; + +public class PrometheusPropertiesException extends RuntimeException { + + public PrometheusPropertiesException(String msg) { + super(msg); + } + + public PrometheusPropertiesException(String msg, Exception cause) { + super(msg, cause); + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java new file mode 100644 index 000000000..ba52372e5 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java @@ -0,0 +1,105 @@ +package io.prometheus.metrics.config; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * The Properties Loader is early stages. + *

+ * It would be great to implement a subset of + * Spring Boot's Externalized Configuration, + * like support for YAML, Properties, and env vars, or support for Spring's naming conventions for properties. + */ +public class PrometheusPropertiesLoader { + + /** + * See {@link PrometheusProperties#get()}. + */ + public static PrometheusProperties load() throws PrometheusPropertiesException { + Map properties = loadProperties(); + Map metricsConfigs = loadMetricsConfigs(properties); + MetricsProperties defaultMetricsProperties = MetricsProperties.load("io.prometheus.metrics", properties); + ExemplarsProperties exemplarConfig = ExemplarsProperties.load("io.prometheus.exemplars", properties); + ExporterProperties exporterProperties = ExporterProperties.load("io.prometheus.exporter", properties); + ExporterFilterProperties exporterFilterProperties = ExporterFilterProperties.load("io.prometheus.exporter.filter", properties); + ExporterHttpServerProperties exporterHttpServerProperties = ExporterHttpServerProperties.load("io.prometheus.exporter.httpServer", properties); + validateAllPropertiesProcessed(properties); + return new PrometheusProperties(defaultMetricsProperties, metricsConfigs, exemplarConfig, exporterProperties, exporterFilterProperties, exporterHttpServerProperties); + } + + // This will remove entries from properties when they are processed. + private static Map loadMetricsConfigs(Map properties) { + Map result = new HashMap<>(); + Pattern pattern = Pattern.compile("io\\.prometheus\\.metrics\\.([^.]+)\\."); + // Create a copy of the keySet() for iterating. We cannot iterate directly over keySet() + // because entries are removed when MetricsConfig.load(...) is called. + Set propertyNames = new HashSet<>(); + for (Object key : properties.keySet()) { + propertyNames.add(key.toString()); + } + for (String propertyName : propertyNames) { + Matcher matcher = pattern.matcher(propertyName); + if (matcher.find()) { + String metricName = matcher.group(1); + if (!result.containsKey(metricName)) { + result.put(metricName, MetricsProperties.load("io.prometheus.metrics." + metricName, properties)); + } + } + } + return result; + } + + // If there are properties left starting with io.prometheus it's likely a typo, + // because we didn't use that property. + // Throw a config error to let the user know that this property doesn't exist. + private static void validateAllPropertiesProcessed(Map properties) { + for (Object key : properties.keySet()) { + if (key.toString().startsWith("io.prometheus")) { + throw new PrometheusPropertiesException(key + ": Unknown property"); + } + } + } + + private static Map loadProperties() { + Map properties = new HashMap<>(); + properties.putAll(loadPropertiesFromClasspath()); + properties.putAll(loadPropertiesFromFile()); // overriding the entries from the classpath file + properties.putAll(System.getProperties()); // overriding the entries from the properties file + // TODO: Add environment variables like EXEMPLARS_ENABLED. + return properties; + } + + private static Properties loadPropertiesFromClasspath() { + Properties properties = new Properties(); + try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("prometheus.properties")) { + properties.load(stream); + } catch (Exception ignored) { + } + return properties; + } + + private static Properties loadPropertiesFromFile() throws PrometheusPropertiesException { + Properties properties = new Properties(); + String path = System.getProperty("prometheus.config"); + if (System.getenv("PROMETHEUS_CONFIG") != null) { + path = System.getenv("PROMETHEUS_CONFIG"); + } + if (path != null) { + try (InputStream stream = Files.newInputStream(Paths.get(path))) { + properties.load(stream); + } catch (IOException e) { + throw new PrometheusPropertiesException("Failed to read Prometheus properties from " + path + ": " + e.getMessage(), e); + } + } + return properties; + } +} diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java new file mode 100644 index 000000000..8f1357134 --- /dev/null +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java @@ -0,0 +1,112 @@ +package io.prometheus.metrics.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +class Util { + + private static String getProperty(String name, Map properties) { + Object object = properties.remove(name); + if (object != null) { + return object.toString(); + } + return null; + } + + static Boolean loadBoolean(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + if (!"true".equalsIgnoreCase(property) && !"false".equalsIgnoreCase(property)) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting 'true' or 'false'"); + } + return Boolean.parseBoolean(property); + } + return null; + } + + static List toList(double... values) { + if (values == null) { + return null; + } + List result = new ArrayList<>(values.length); + for (double value : values) { + result.add(value); + } + return result; + } + + static List loadStringList(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + return Arrays.asList(property.split("\\s*,\\s*")); + } + return null; + } + + static List loadDoubleList(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + String[] numbers = property.split("\\s*,\\s*"); + Double[] result = new Double[numbers.length]; + for (int i = 0; i < numbers.length; i++) { + try { + if ("+Inf".equals(numbers[i].trim())) { + result[i] = Double.POSITIVE_INFINITY; + } else { + result[i] = Double.parseDouble(numbers[i]); + } + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting comma separated list of double values"); + } + } + return Arrays.asList(result); + } + return null; + } + + static Integer loadInteger(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting integer value"); + } + } + return null; + } + + static Double loadDouble(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Double.parseDouble(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting double value"); + } + } + return null; + } + + static Long loadLong(String name, Map properties) throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Long.parseLong(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting long value"); + } + } + return null; + } + + static void assertValue(T number, Predicate predicate, String message, String prefix, String name) throws PrometheusPropertiesException { + if (number != null && !predicate.test(number)) { + String fullMessage = prefix == null ? name + ": " + message : prefix + "." + name + ": " + message; + throw new PrometheusPropertiesException(fullMessage); + } + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java new file mode 100644 index 000000000..45fec1be0 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java @@ -0,0 +1,29 @@ +package io.prometheus.metrics.config; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class PrometheusPropertiesTest { + + @Test + public void testPrometheusConfig() { + PrometheusProperties result = PrometheusProperties.get(); + Assert.assertEquals(11, result.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); + Assert.assertEquals(4, result.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size()); + } + + @Test + public void testEmptyUpperBounds() throws IOException { + Properties properties = new Properties(); + try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("emptyUpperBounds.properties")) { + properties.load(stream); + } + Assert.assertEquals(1, properties.size()); + MetricsProperties.load("io.prometheus.metrics", properties); + Assert.assertEquals(0, properties.size()); + } +} diff --git a/prometheus-metrics-config/src/test/resources/emptyUpperBounds.properties b/prometheus-metrics-config/src/test/resources/emptyUpperBounds.properties new file mode 100644 index 000000000..c019761ca --- /dev/null +++ b/prometheus-metrics-config/src/test/resources/emptyUpperBounds.properties @@ -0,0 +1 @@ +io.prometheus.metrics.histogramClassicUpperBounds =, diff --git a/prometheus-metrics-config/src/test/resources/prometheus.properties b/prometheus-metrics-config/src/test/resources/prometheus.properties new file mode 100644 index 000000000..56b3daeb3 --- /dev/null +++ b/prometheus-metrics-config/src/test/resources/prometheus.properties @@ -0,0 +1,20 @@ +io.prometheus.metrics.histogramClassicUpperBounds = .005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10 +io.prometheus.metrics.http_duration_seconds.histogramClassicUpperBounds = .005, .01, .015, .02 +io.prometheus.metrics.summaryQuantiles = 0.5, 0.95, 0.99 +io.prometheus.metrics.summaryQuantileErrors = 0.01, 0.01, 0.001 + +io.prometheus.metrics.exemplarsEnabled = true +io.prometheus.metrics.http_duration_seconds.exemplarsEnabled = true + +io.prometheus.exporter.includeCreatedTimestamps = false +io.prometheus.exporter.exemplarsOnAllMetricTypes = true +io.prometheus.exporter.filter.nameMustBeEqualTo = a, b, c + + +io.prometheus.exemplars.minRetentionPeriodSeconds = 30 +io.prometheus.exemplars.maxRetentionPeriodSeconds = 30 +io.prometheus.exemplars.sampleIntervalMilliseconds = 30 + +io.prometheus.exporter.httpServer.port = 9000 + +# io.prometheus.metrics.unusedLabelsRetentionTimeSeconds = 0 diff --git a/prometheus-metrics-config/version-rules.xml b/prometheus-metrics-config/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-config/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml new file mode 100644 index 000000000..06d350b69 --- /dev/null +++ b/prometheus-metrics-core/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-core + bundle + + Prometheus Metrics Core + + Core Prometheus metric types + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-model + ${project.version} + + + io.prometheus + prometheus-metrics-config + ${project.version} + + + io.prometheus + prometheus-metrics-tracer-initializer + ${project.version} + + + io.prometheus + prometheus-metrics-exposition-formats + ${project.version} + test + + + + + junit + junit + 4.13.2 + test + + + diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java new file mode 100644 index 000000000..c2f72c30e --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java @@ -0,0 +1,88 @@ +package io.prometheus.metrics.core.datapoints; + +import io.prometheus.metrics.model.snapshots.Labels; + +/** + * Represents a single counter data point, i.e. a single line for a counter metric in Prometheus text format. + *

+ * Example usage: + *

{@code
+ * Counter counter = Counter.newBuilder()
+ *     .withName("tasks_total")
+ *     .withLabelNames("status")
+ *     .register();
+ * CounterDataPoint newTasks = counter.withLabelValues("new");
+ * CounterDataPoint pendingTasks = counter.withLabelValues("pending");
+ * CounterDataPoint completedTasks = counter.withLabelValues("completed");
+ * }
+ *

+ * Using {@code DataPoint} directly improves performance. If you increment a counter like this: + *

{@code
+ * counter.withLabelValues("pending").inc();
+ * }
+ * the label value {@code "pending"} needs to be looked up every single time. + * Using the {@code CounterDataPoint} like this: + *
{@code
+ * CounterDataPoint pendingTasks = counter.withLabelValues("pending");
+ * pendingTasks.inc();
+ * }
+ * allows you to look up the label value only once, and then use the {@code CounterDataPoint} directly. + * This is a worthwhile performance improvement when instrumenting a performance-critical code path. + *

+ * If you have a counter without labels like this: + *

{@code
+ * Counter counterWithoutLabels = Counter.newBuilder()
+ *     .withName("events_total")
+ *     .register();
+ * }
+ * You can use it as a {@code CounterDataPoint} directly. So the following: + *
{@code
+ * CounterDataPoint counterData = counterWithoutLabels.withLabels();
+ * }
+ * is equivalent to + *
{@code
+ * CounterDataPoint counterData = counterWithoutLabels;
+ * }
+ */ +public interface CounterDataPoint extends DataPoint { + + /** + * Add one. + */ + default void inc() { + inc(1L); + } + + /** + * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + default void inc(long amount) { + inc((double) amount); + } + + /** + * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + void inc(double amount); + + /** + * Add one, and create a custom exemplar with the given labels. + */ + default void incWithExemplar(Labels labels) { + incWithExemplar(1.0, labels); + } + + /** + * Add {@code amount}, and create a custom exemplar with the given labels. + * Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + default void incWithExemplar(long amount, Labels labels) { + inc((double) amount); + } + + /** + * Add {@code amount}, and create a custom exemplar with the given labels. + * Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + void incWithExemplar(double amount, Labels labels); +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java new file mode 100644 index 000000000..8dd277d81 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java @@ -0,0 +1,4 @@ +package io.prometheus.metrics.core.datapoints; + +public interface DataPoint { +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java new file mode 100644 index 000000000..f08ccae9c --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java @@ -0,0 +1,36 @@ +package io.prometheus.metrics.core.datapoints; + +import io.prometheus.metrics.model.snapshots.Labels; + +/** + * Represents a single data point of a histogram or a summary metric. + *

+ * Single data point means identified label values like {@code {method="GET", path="/", status_code="200"}}, + * ignoring the {@code "le"} label for histograms or the {@code "quantile"} label for summaries. + *

+ * This interface is named DistributionDataPoint because both histograms and summaries are used to observe + * distributions, like latency distributions or distributions of request sizes. Therefore + * DistributionDataPoint is a good name for a common interface implemented by histogram data points + * and summary data points. + *

+ * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + */ +public interface DistributionDataPoint extends DataPoint, TimerApi { + + /** + * Observe {@code value}. + */ + void observe(double value); + + /** + * Observe {@code value}, and create a custom exemplar with the given labels. + */ + void observeWithExemplar(double value, Labels labels); + + /** + * {@inheritDoc} + */ + default Timer startTimer() { + return new Timer(this::observe); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java new file mode 100644 index 000000000..9daf01428 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java @@ -0,0 +1,80 @@ +package io.prometheus.metrics.core.datapoints; + +import io.prometheus.metrics.model.snapshots.Labels; + +/** + * Represents a single gauge data point, i.e. a single line for a gauge metric in Prometheus text format. + *

+ * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + */ +public interface GaugeDataPoint extends DataPoint, TimerApi { + + /** + * Add one. + */ + default void inc() { + inc(1.0); + } + + /** + * Add {@code amount}. + */ + void inc(double amount); + + /** + * Add one, and create a custom exemplar with the given labels. + */ + default void incWithExemplar(Labels labels) { + incWithExemplar(1.0, labels); + } + + /** + * Add {@code amount}, and create a custom exemplar with the given labels. + */ + void incWithExemplar(double amount, Labels labels); + + /** + * Subtract one. + */ + default void dec() { + inc(-1.0); + } + + /** + * Subtract {@code amount}. + */ + default void dec(double amount) { + inc(-amount); + } + + /** + * Subtract one, and create a custom exemplar with the given labels. + */ + default void decWithExemplar(Labels labels) { + incWithExemplar(-1.0, labels); + } + + /** + * Subtract {@code amount}, and create a custom exemplar with the given labels. + */ + default void decWithExemplar(double amount, Labels labels) { + incWithExemplar(-amount, labels); + } + + /** + * Set the gauge to {@code value}. + */ + void set(double value); + + /** + * Set the gauge to {@code value}, and create a custom exemplar with the given labels. + */ + void setWithExemplar(double value, Labels labels); + + /** + * {@inheritDoc} + */ + default Timer startTimer() { + return new Timer(this::set); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java new file mode 100644 index 000000000..73b7dfdb3 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java @@ -0,0 +1,33 @@ +package io.prometheus.metrics.core.datapoints; + +/** + * Represents a single StateSet data point. + *

+ * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + */ +public interface StateSetDataPoint extends DataPoint { + + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(String...)}. + */ + void setTrue(String state); + + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(String...)}. + */ + void setFalse(String state); + + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(Class>)}. + */ + default void setTrue(Enum state) { + setTrue(state.toString()); + } + + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(Class>)}. + */ + default void setFalse(Enum state) { + setFalse(state.toString()); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java new file mode 100644 index 000000000..fd6461869 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java @@ -0,0 +1,40 @@ +package io.prometheus.metrics.core.datapoints; + +import io.prometheus.metrics.model.snapshots.Unit; + +import java.io.Closeable; +import java.util.function.DoubleConsumer; + +/** + * Helper class for observing durations. + */ +public class Timer implements Closeable { + + private final DoubleConsumer observeFunction; + private final long startTimeNanos = System.nanoTime(); + + /** + * Constructor is package private. Use the {@link TimerApi} provided by the implementation of the {@link DataPoint}. + */ + Timer(DoubleConsumer observeFunction) { + this.observeFunction = observeFunction; + } + + /** + * Records the observed duration in seconds since this {@code Timer} instance was created. + * @return the observed duration in seconds. + */ + public double observeDuration() { + double elapsed = Unit.nanosToSeconds(System.nanoTime() - startTimeNanos); + observeFunction.accept(elapsed); + return elapsed; + } + + /** + * Same as {@link #observeDuration()}. + */ + @Override + public void close() { + observeDuration(); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java new file mode 100644 index 000000000..a38c8053b --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java @@ -0,0 +1,74 @@ +package io.prometheus.metrics.core.datapoints; + +import java.util.concurrent.Callable; +import java.util.function.Supplier; + +/** + * Convenience API for timing durations. + *

+ * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: + * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". + */ +public interface TimerApi { + + /** + * Start a {@code Timer}. Example: + *

{@code
+     * Histogram histogram = Histogram.newBuilder()
+     *         .withName("http_request_duration_seconds")
+     *         .withHelp("HTTP request service time in seconds")
+     *         .withUnit(SECONDS)
+     *         .withLabelNames("method", "path")
+     *         .register();
+     *
+     * try (Timer timer = histogram.withLabelValues("GET", "/").startTimer()) {
+     *     // duration of this code block will be observed.
+     * }
+     * }
+ * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: + * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". + */ + Timer startTimer(); + + /** + * Observe the duration of the {@code func} call. Example: + *
{@code
+     * Histogram histogram = Histogram.newBuilder()
+     *         .withName("request_duration_seconds")
+     *         .withHelp("HTTP request service time in seconds")
+     *         .withUnit(SECONDS)
+     *         .withLabelNames("method", "path")
+     *         .register();
+     *
+     * histogram2.withLabelValues("GET", "/").time(() -> {
+     *     // duration of this code block will be observed.
+     * });
+     * }
+ *

+ * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: + * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". + */ + default void time(Runnable func) { + try (Timer timer = startTimer()) { + func.run(); + } + } + + /** + * Like {@link #time(Runnable)}, but returns the return value of {@code func}. + */ + default T time(Supplier func) { + try (Timer timer = startTimer()) { + return func.get(); + } + } + + /** + * Like {@link #time(Supplier)}, but {@code func} may throw a checked {@code Exception}. + */ + default T timeChecked(Callable func) throws Exception { + try (Timer timer = startTimer()) { + return func.call(); + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java new file mode 100644 index 000000000..0c8275356 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -0,0 +1,326 @@ +package io.prometheus.metrics.core.exemplars; + +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.core.util.Scheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.LongSupplier; + +/** + * The ExemplarSampler selects Spans as exemplars. + *

+ * There are two types of Exemplars: Regular exemplars are sampled implicitly if a supported tracing + * library is detected. Custom exemplars are provided explicitly in code, for example if a developer + * wants to make sure an Exemplar is created for a specific code path. + *

+ * Spans will be marked as being an Exemplar by calling {@link SpanContext#markCurrentSpanAsExemplar()}. + * The tracer implementation should set a Span attribute to mark the current Span as an Exemplar. + * This attribute can be used by a trace sampling algorithm to make sure traces with Exemplars are sampled. + *

+ * The ExemplarSample is rate-limited, so only a small fraction of Spans will be marked as Exemplars in + * an application with a large number of requests. + *

+ * See {@link ExemplarSamplerConfig} for configuration options. + */ +public class ExemplarSampler { + + private final ExemplarSamplerConfig config; + private final Exemplar[] exemplars; + private final Exemplar[] customExemplars; // Separate from exemplars, because we don't want custom exemplars + // to be overwritten by automatic exemplar sampling. exemplars.lengt == customExemplars.length + private final AtomicBoolean acceptingNewExemplars = new AtomicBoolean(true); + private final AtomicBoolean acceptingNewCustomExemplars = new AtomicBoolean(true); + + public ExemplarSampler(ExemplarSamplerConfig config) { + this.config = config; + this.exemplars = new Exemplar[config.getNumberOfExemplars()]; + this.customExemplars = new Exemplar[exemplars.length]; + } + + public Exemplars collect() { + // this may run in parallel with observe() + long now = System.currentTimeMillis(); + List result = new ArrayList<>(exemplars.length); + for (int i = 0; i < customExemplars.length; i++) { + Exemplar exemplar = customExemplars[i]; + if (exemplar != null) { + if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + customExemplars[i] = null; + } else { + result.add(exemplar); + } + } + } + for (int i = 0; i < exemplars.length && result.size() < exemplars.length; i++) { + Exemplar exemplar = exemplars[i]; + if (exemplar != null) { + if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + exemplars[i] = null; + } else { + result.add(exemplar); + } + } + } + return Exemplars.of(result); + } + + public void reset() { + for (int i = 0; i < exemplars.length; i++) { + exemplars[i] = null; + customExemplars[i] = null; + } + } + + public void observe(double value) { + if (!acceptingNewExemplars.get()) { + return; // This is the hot path in a high-throughput application and should be as efficient as possible. + } + rateLimitedObserve(acceptingNewExemplars, value, exemplars, () -> doObserve(value)); + } + + public void observeWithExemplar(double value, Labels labels) { + if (!acceptingNewCustomExemplars.get()) { + return; // This is the hot path in a high-throughput application and should be as efficient as possible. + } + rateLimitedObserve(acceptingNewCustomExemplars, value, customExemplars, () -> doObserveWithExemplar(value, labels)); + } + + private long doObserve(double value) { + if (exemplars.length == 1) { + return doObserveSingleExemplar(value); + } else if (config.getHistogramClassicUpperBounds() != null) { + return doObserveWithUpperBounds(value); + } else { + return doObserveWithoutUpperBounds(value); + } + } + + private long doObserveSingleExemplar(double value) { + long now = System.currentTimeMillis(); + Exemplar current = exemplars[0]; + if (current == null || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateExemplar(0, value, now); + } + return 0; + } + + private long doObserveWithUpperBounds(double value) { + long now = System.currentTimeMillis(); + double[] upperBounds = config.getHistogramClassicUpperBounds(); + for (int i = 0; i < upperBounds.length; i++) { + if (value <= upperBounds[i]) { + Exemplar previous = exemplars[i]; + if (previous == null || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateExemplar(i, value, now); + } else { + return 0; + } + } + } + return 0; // will never happen, as upperBounds contains +Inf + } + + private long doObserveWithoutUpperBounds(double value) { + final long now = System.currentTimeMillis(); + Exemplar smallest = null; + int smallestIndex = -1; + Exemplar largest = null; + int largestIndex = -1; + int nullIndex = -1; + for (int i = exemplars.length - 1; i >= 0; i--) { + Exemplar exemplar = exemplars[i]; + if (exemplar == null) { + nullIndex = i; + } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + exemplars[i] = null; + nullIndex = i; + } else { + if (smallest == null || exemplar.getValue() < smallest.getValue()) { + smallest = exemplar; + smallestIndex = i; + } + if (largest == null || exemplar.getValue() > largest.getValue()) { + largest = exemplar; + largestIndex = i; + } + } + } + if (nullIndex >= 0) { + return updateExemplar(nullIndex, value, now); + } + if (now - smallest.getTimestampMillis() > config.getMinRetentionPeriodMillis() && value < smallest.getValue()) { + return updateExemplar(smallestIndex, value, now); + } + if (now - largest.getTimestampMillis() > config.getMinRetentionPeriodMillis() && value > largest.getValue()) { + return updateExemplar(largestIndex, value, now); + } + long oldestTimestamp = 0; + int oldestIndex = -1; + for (int i = 0; i < exemplars.length; i++) { + Exemplar exemplar = exemplars[i]; + if (exemplar != null && exemplar != smallest && exemplar != largest) { + if (oldestTimestamp == 0 || exemplar.getTimestampMillis() < oldestTimestamp) { + oldestTimestamp = exemplar.getTimestampMillis(); + oldestIndex = i; + } + } + } + if (oldestIndex != -1 && now - oldestTimestamp > config.getMinRetentionPeriodMillis()) { + return updateExemplar(oldestIndex, value, now); + } + return 0; + } + + // Returns the timestamp of the newly added Exemplar (which is System.currentTimeMillis()) + // or 0 if no Exemplar was added. + private long doObserveWithExemplar(double amount, Labels labels) { + if (customExemplars.length == 1) { + return doObserveSingleExemplar(amount, labels); + } else if (config.getHistogramClassicUpperBounds() != null) { + return doObserveWithExemplarWithUpperBounds(amount, labels); + } else { + return doObserveWithExemplarWithoutUpperBounds(amount, labels); + } + } + + private long doObserveSingleExemplar(double amount, Labels labels) { + long now = System.currentTimeMillis(); + Exemplar current = customExemplars[0]; + if (current == null || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(0, amount, labels, now); + } + return 0; + } + + private long doObserveWithExemplarWithUpperBounds(double value, Labels labels) { + long now = System.currentTimeMillis(); + double[] upperBounds = config.getHistogramClassicUpperBounds(); + for (int i = 0; i < upperBounds.length; i++) { + if (value <= upperBounds[i]) { + Exemplar previous = customExemplars[i]; + if (previous == null || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(i, value, labels, now); + } else { + return 0; + } + } + } + return 0; // will never happen, as upperBounds contains +Inf + } + + private long doObserveWithExemplarWithoutUpperBounds(double amount, Labels labels) { + final long now = System.currentTimeMillis(); + int nullPos = -1; + int oldestPos = -1; + Exemplar oldest = null; + for (int i = customExemplars.length - 1; i >= 0; i--) { + Exemplar exemplar = customExemplars[i]; + if (exemplar == null) { + nullPos = i; + } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + customExemplars[i] = null; + nullPos = i; + } else { + if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { + oldest = exemplar; + oldestPos = i; + } + } + } + if (nullPos != -1) { + return updateCustomExemplar(nullPos, amount, labels, now); + } else if (now - oldest.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(oldestPos, amount, labels, now); + } else { + return 0; + } + } + + /** + * Observing requires a system call to {@link System#currentTimeMillis()}, + * and it requires iterating over the existing exemplars to check if one of the existing + * exemplars can be replaced. + *

+ * To avoid performance issues, we rate limit observing exemplars to + * {@link ExemplarSamplerConfig#getSampleIntervalMillis()} milliseconds. + */ + private void rateLimitedObserve(AtomicBoolean accepting, double value, Exemplar[] exemplars, LongSupplier observeFunc) { + if (Double.isNaN(value)) { + return; + } + if (!accepting.compareAndSet(true, false)) { + return; + } + // observeFunc returns the current timestamp or 0 if no Exemplar was added. + long now = observeFunc.getAsLong(); + long sleepTime = now == 0 ? config.getSampleIntervalMillis() : durationUntilNextExemplarExpires(now); + Scheduler.schedule(() -> accepting.compareAndSet(false, true), sleepTime, TimeUnit.MILLISECONDS); + } + + private long durationUntilNextExemplarExpires(long now) { + long oldestTimestamp = now; + for (Exemplar exemplar : exemplars) { + if (exemplar == null) { + return config.getSampleIntervalMillis(); + } else if (exemplar.getTimestampMillis() < oldestTimestamp) { + oldestTimestamp = exemplar.getTimestampMillis(); + } + } + long oldestAge = now - oldestTimestamp; + if (oldestAge < config.getMinRetentionPeriodMillis()) { + return config.getMinRetentionPeriodMillis() - oldestAge; + } + return config.getSampleIntervalMillis(); + } + + private long updateCustomExemplar(int index, double value, Labels labels, long now) { + if (!labels.contains(Exemplar.TRACE_ID) && !labels.contains(Exemplar.SPAN_ID)) { + labels = labels.merge(doSampleExemplar()); + } + customExemplars[index] = Exemplar.newBuilder() + .withValue(value) + .withLabels(labels) + .withTimestampMillis(now) + .build(); + return now; + } + + private long updateExemplar(int index, double value, long now) { + Labels traceLabels = doSampleExemplar(); + if (!traceLabels.isEmpty()) { + exemplars[index] = Exemplar.newBuilder() + .withValue(value) + .withLabels(traceLabels) + .withTimestampMillis(now) + .build(); + return now; + } else { + return 0; + } + } + + private Labels doSampleExemplar() { + try { + SpanContext spanContext = SpanContextSupplier.getSpanContext(); + if (spanContext != null) { + if (spanContext.isCurrentSpanSampled()) { + String spanId = spanContext.getCurrentSpanId(); + String traceId = spanContext.getCurrentTraceId(); + if (spanId != null && traceId != null) { + spanContext.markCurrentSpanAsExemplar(); + return Labels.of(Exemplar.TRACE_ID, traceId, Exemplar.SPAN_ID, spanId); + } + } + } + } catch (NoClassDefFoundError ignored) { + } + return Labels.EMPTY; + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java new file mode 100644 index 000000000..9712f29df --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java @@ -0,0 +1,135 @@ +package io.prometheus.metrics.core.exemplars; + +import io.prometheus.metrics.config.ExemplarsProperties; +import io.prometheus.metrics.config.PrometheusProperties; + +import java.util.concurrent.TimeUnit; + +public class ExemplarSamplerConfig { + + /** + * See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} + */ + public static final int DEFAULT_MIN_RETENTION_PERIOD_SECONDS = 7; + + /** + * See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} + */ + public static final int DEFAULT_MAX_RETENTION_PERIOD_SECONDS = 70; + + /** + * See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} + */ + private static final int DEFAULT_SAMPLE_INTERVAL_MILLISECONDS = 90; + + private final long minRetentionPeriodMillis; + private final long maxRetentionPeriodMillis; + private final long sampleIntervalMillis; + private final double[] histogramClassicUpperBounds; // null unless it's a classic histogram + private final int numberOfExemplars; // if histogramClassicUpperBounds != null, then numberOfExemplars == histogramClassicUpperBounds.length + + /** + * Constructor for all metric types except classic histograms. + * + * @param properties See {@link PrometheusProperties#getExemplarProperties()}. + * @param numberOfExemplars Counters have 1 Exemplar, native histograms and summaries have 4 Exemplars by default. + * For classic histogram use {@link #ExemplarSamplerConfig(ExemplarsProperties, double[])}. + */ + public ExemplarSamplerConfig(ExemplarsProperties properties, int numberOfExemplars) { + this(properties, numberOfExemplars, null); + } + + /** + * Constructor for classic histogram metrics. + * + * @param properties See {@link PrometheusProperties#getExemplarProperties()}. + * @param histogramClassicUpperBounds the ExemplarSampler will provide one Exemplar per histogram bucket. + * Must be sorted, and must include the +Inf bucket. + */ + public ExemplarSamplerConfig(ExemplarsProperties properties, double[] histogramClassicUpperBounds) { + this(properties, histogramClassicUpperBounds.length, histogramClassicUpperBounds); + } + + private ExemplarSamplerConfig(ExemplarsProperties properties, int numberOfExemplars, double[] histogramClassicUpperBounds) { + this( + TimeUnit.SECONDS.toMillis(getOrDefault(properties.getMinRetentionPeriodSeconds(), DEFAULT_MIN_RETENTION_PERIOD_SECONDS)), + TimeUnit.SECONDS.toMillis(getOrDefault(properties.getMaxRetentionPeriodSeconds(), DEFAULT_MAX_RETENTION_PERIOD_SECONDS)), + getOrDefault(properties.getSampleIntervalMilliseconds(), DEFAULT_SAMPLE_INTERVAL_MILLISECONDS), + numberOfExemplars, + histogramClassicUpperBounds); + } + + ExemplarSamplerConfig(long minRetentionPeriodMillis, long maxRetentionPeriodMillis, long sampleIntervalMillis, int numberOfExemplars, double[] histogramClassicUpperBounds) { + this.minRetentionPeriodMillis = minRetentionPeriodMillis; + this.maxRetentionPeriodMillis = maxRetentionPeriodMillis; + this.sampleIntervalMillis = sampleIntervalMillis; + this.numberOfExemplars = numberOfExemplars; + this.histogramClassicUpperBounds = histogramClassicUpperBounds; + validate(); + } + + private void validate() { + if (minRetentionPeriodMillis <= 0) { + throw new IllegalArgumentException(minRetentionPeriodMillis + ": minRetentionPeriod must be > 0."); + } + if (maxRetentionPeriodMillis <= 0) { + throw new IllegalArgumentException(maxRetentionPeriodMillis + ": maxRetentionPeriod must be > 0."); + } + if (histogramClassicUpperBounds != null) { + if (histogramClassicUpperBounds.length == 0 || histogramClassicUpperBounds[histogramClassicUpperBounds.length - 1] != Double.POSITIVE_INFINITY) { + throw new IllegalArgumentException("histogramClassicUpperBounds must contain the +Inf bucket."); + } + if (histogramClassicUpperBounds.length != numberOfExemplars) { + throw new IllegalArgumentException("histogramClassicUpperBounds.length must be equal to numberOfExemplars."); + } + double bound = histogramClassicUpperBounds[0]; + for (int i = 1; i < histogramClassicUpperBounds.length; i++) { + if (bound >= histogramClassicUpperBounds[i]) { + throw new IllegalArgumentException("histogramClassicUpperBounds must be sorted and must not contain duplicates."); + } + } + } + if (numberOfExemplars <= 0) { + throw new IllegalArgumentException(numberOfExemplars + ": numberOfExemplars must be > 0."); + } + } + + private static T getOrDefault(T result, T defaultValue) { + return result != null ? result : defaultValue; + } + + /** + * May be {@code null}. + */ + public double[] getHistogramClassicUpperBounds() { + return histogramClassicUpperBounds; + } + + /** + * See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} + */ + public long getMinRetentionPeriodMillis() { + return minRetentionPeriodMillis; + } + + /** + * See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} + */ + public long getMaxRetentionPeriodMillis() { + return maxRetentionPeriodMillis; + } + + /** + * See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} + */ + public long getSampleIntervalMillis() { + return sampleIntervalMillis; + } + + /** + * Defaults: Counters have one Exemplar, native histograms and summaries have 4 Exemplars, classic histograms have one Exemplar per bucket. + */ + public int getNumberOfExemplars() { + return numberOfExemplars; + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java new file mode 100644 index 000000000..390a2bc2b --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -0,0 +1,84 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; + +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Metrics support concurrent write and scrape operations. + *

+ * This is implemented by switching to a Buffer when the scrape starts, + * and applying the values from the buffer after the scrape ends. + */ +class Buffer { + + private static final long signBit = 1L << 63; + private final AtomicLong observationCount = new AtomicLong(0); + private double[] observationBuffer = new double[0]; + private int bufferPos = 0; + private boolean reset = false; + private final Object appendLock = new Object(); + private final Object runLock = new Object(); + + boolean append(double value) { + long count = observationCount.incrementAndGet(); + if ((count & signBit) == 0) { + return false; // sign bit not set -> buffer not active. + } else { + doAppend(value); + return true; + } + } + + private void doAppend(double amount) { + synchronized (appendLock) { + if (bufferPos >= observationBuffer.length) { + observationBuffer = Arrays.copyOf(observationBuffer, observationBuffer.length + 128); + } + observationBuffer[bufferPos] = amount; + bufferPos++; + } + } + + /** + * Must be called by the runnable in the run() method. + */ + void reset() { + reset = true; + } + + T run(Function complete, Supplier runnable, Consumer observeFunction) { + double[] buffer; + int bufferSize; + T result; + synchronized (runLock) { + Long count = observationCount.getAndAdd(signBit); + while (!complete.apply(count)) { + Thread.yield(); + } + result = runnable.get(); + int expectedBufferSize; + if (reset) { + expectedBufferSize = (int) ((observationCount.getAndSet(0) & ~signBit) - count); + reset = false; + } else { + expectedBufferSize = (int) (observationCount.addAndGet(signBit) - count); + } + while (bufferPos != expectedBufferSize) { + Thread.yield(); + } + buffer = observationBuffer; + bufferSize = bufferPos; + observationBuffer = new double[0]; + bufferPos = 0; + } + for (int i = 0; i < bufferSize; i++) { + observeFunction.accept(buffer[i]); + } + return result; + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java new file mode 100644 index 000000000..22662c62e --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java @@ -0,0 +1,296 @@ +package io.prometheus.metrics.core.metrics; + +// The original implementation was copied from +// https://raw.githubusercontent.com/Netflix/ocelli/master/ocelli-core/src/main/java/netflix/ocelli/stats/CKMSQuantiles.java +// Revision d0357b8bf5c17a173ce94d6b26823775b3f999f6 from Jan 21, 2015. +// However, it has been heavily refactored in the meantime. + +/* + Copyright 2012 Andrew Wang (andrew@umbrant.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.ListIterator; + +/** + * Algorithm solving the "Targeted Quantile Problem" as described in + * "Effective Computation of Biased Quantiles over Data Streams" + * by Cormode, Korn, Muthukrishnan, and Srivastava. + * + */ +final class CKMSQuantiles { + + final Quantile[] quantiles; + + /** + * Total number of observations (not including those that are still in the buffer). + */ + int n = 0; + + /** + * List of sampled observations, ordered by Sample.value. + */ + final LinkedList samples = new LinkedList(); + + /** + * Compress is called every compressInterval inserts. + * Note that the buffer is flushed whenever get() is called, so we + * cannot just wait until the buffer is full before we call compress. + */ + private final int compressInterval = 128; + private int insertsSinceLastCompress = 0; + + /** + * Note that the buffer size could as well be less than the compressInterval. + * However, the buffer size should not be greater than the compressInterval, + * because the compressInterval is not respected in flush(), so if you want + * to compress more often than calling flush() that won't work. + */ + private final double[] buffer = new double[compressInterval]; + private int bufferPos = 0; + + public CKMSQuantiles(Quantile... quantiles) { + if (quantiles.length == 0) { + throw new IllegalArgumentException("quantiles cannot be empty"); + } + this.quantiles = quantiles; + } + + /** + * Add an observed value + */ + public void insert(double value) { + buffer[bufferPos++] = value; + + if (bufferPos == buffer.length) { + flush(); + } + + if (++insertsSinceLastCompress == compressInterval) { + compress(); + insertsSinceLastCompress = 0; + } + } + + private void flush() { + Arrays.sort(buffer, 0, bufferPos); + insertBatch(buffer, bufferPos); + bufferPos = 0; + } + + /** + * Inserts the elements from index 0 to index toIndex from the sortedBuffer. + */ + void insertBatch(double[] sortedBuffer, int toIndex) { + if (toIndex == 0) { + return; + } + ListIterator iterator = samples.listIterator(); + int i = 0; // position in buffer + int r = 0; // sum of g's left of the current sample + while (iterator.hasNext() && i < toIndex) { + Sample item = iterator.next(); + while (i < toIndex) { + if (sortedBuffer[i] > item.value) { + break; + } + insertBefore(iterator, sortedBuffer[i], r); + r++; // new item with g=1 was inserted before, so increment r + i++; + n++; + } + r += item.g; + } + while (i < toIndex) { + samples.add(new Sample(sortedBuffer[i], 0)); + i++; + n++; + } + } + + private void insertBefore(ListIterator iterator, double value, int r) { + if (!iterator.hasPrevious()) { + samples.addFirst(new Sample(value, 0)); + } else { + iterator.previous(); + iterator.add(new Sample(value, f(r) - 1)); + iterator.next(); + } + } + + /** + * Get the estimated value at the specified quantile. + */ + public double get(double q) { + flush(); + + if (samples.size() == 0) { + return Double.NaN; + } + + if (q == 0.0) { + return samples.getFirst().value; + } + + if (q == 1.0) { + return samples.getLast().value; + } + + int r = 0; // sum of g's left of the current sample + int desiredRank = (int) Math.ceil(q * n); + int upperBound = desiredRank + f(desiredRank) / 2; + + ListIterator iterator = samples.listIterator(); + while (iterator.hasNext()) { + Sample sample = iterator.next(); + if (r + sample.g + sample.delta > upperBound) { + iterator.previous(); // roll back the item.next() above + if (iterator.hasPrevious()) { + Sample result = iterator.previous(); + return result.value; + } else { + return sample.value; + } + } + r += sample.g; + } + return samples.getLast().value; + } + + /** + * Error function, as in definition 5 of the paper. + */ + int f(int r) { + int minResult = Integer.MAX_VALUE; + for (Quantile q : quantiles) { + if (q.quantile == 0 || q.quantile == 1) { + continue; + } + int result; + // We had a numerical error here with the following example: + // quantile = 0.95, epsilon = 0.01, (n-r) = 30. + // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. + // To avoid running into these types of error we add 0.00000000001 before rounding down. + if (r >= q.quantile * n) { + result = (int) (q.v * r + 0.00000000001); + } else { + result = (int) (q.u * (n - r) + 0.00000000001); + } + if (result < minResult) { + minResult = result; + } + } + return Math.max(minResult, 1); + } + + /** + * Merge pairs of consecutive samples if this doesn't violate the error function. + */ + void compress() { + if (samples.size() < 3) { + return; + } + Iterator descendingIterator = samples.descendingIterator(); + int r = n; // n is equal to the sum of the g's of all samples + + Sample right; + Sample left = descendingIterator.next(); + r -= left.g; + + while (descendingIterator.hasNext()) { + right = left; + left = descendingIterator.next(); + r = r - left.g; + if (left == samples.getFirst()) { + // The min sample must never be merged. + break; + } + if (left.g + right.g + right.delta < f(r)) { + right.g += left.g; + descendingIterator.remove(); + left = right; + } + } + } + + static class Sample { + + /** + * Observed value. + */ + final double value; + + /** + * Difference between the lowest possible rank of this sample and its predecessor. + * This always starts with 1, but will be updated when compress() merges Samples. + */ + int g = 1; + + /** + * Difference between the greatest possible rank of this sample and the lowest possible rank of this sample. + */ + final int delta; + + Sample(double value, int delta) { + this.value = value; + this.delta = delta; + } + + @Override + public String toString() { + return String.format("Sample{val=%.3f, g=%d, delta=%d}", value, g, delta); + } + } + + static class Quantile { + + /** + * Quantile. Must be between 0 and 1. + */ + final double quantile; + + /** + * Allowed error. Must be between 0 and 1. + */ + final double epsilon; + + /** + * Helper used in the error function f(), see definition 5 in the paper. + */ + final double u; + + /** + * Helper used in the error function f(), see definition 5 in the paper. + */ + final double v; + + Quantile(double quantile, double epsilon) { + if (quantile < 0.0 || quantile > 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); + if (epsilon < 0.0 || epsilon > 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); + + this.quantile = quantile; + this.epsilon = epsilon; + u = 2.0 * epsilon / (1.0 - quantile); // if quantile == 1 this will be Double.NaN + v = 2.0 * epsilon / quantile; // if quantile == 0 this will be Double.NaN + } + + @Override + public String toString() { + return String.format("Quantile{q=%.3f, epsilon=%.3f}", quantile, epsilon); + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java new file mode 100644 index 000000000..2d9eb0b54 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java @@ -0,0 +1,42 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.Labels; + +import java.util.List; + +/** + * There are two kinds of metrics: {@code StatefulMetric} and {@code CallbackMetric}. + *

+ * See JavaDoc on {@link StatefulMetric} for more info. + */ +abstract class CallbackMetric extends MetricWithFixedMetadata { + + protected CallbackMetric(Builder builder) { + super(builder); + } + + protected Labels makeLabels(String... labelValues) { + if (labelNames.length == 0) { + if (labelValues != null && labelValues.length > 0) { + throw new IllegalArgumentException("Cannot pass label values to a " + this.getClass().getSimpleName() + " that was created without label names."); + } + return constLabels; + } else { + if (labelValues == null) { + throw new IllegalArgumentException(this.getClass().getSimpleName() + " was created with label names, but the callback was called without label values."); + } + if (labelValues.length != labelNames.length) { + throw new IllegalArgumentException(this.getClass().getSimpleName() + " was created with " + labelNames.length + " label names, but the callback was called with " + labelValues.length + " label values."); + } + return constLabels.merge(Labels.of(labelNames, labelValues)); + } + } + + static abstract class Builder, M extends CallbackMetric> extends MetricWithFixedMetadata.Builder { + + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + super(illegalLabelNames, properties); + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java new file mode 100644 index 000000000..6b5301cc5 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -0,0 +1,252 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.datapoints.CounterDataPoint; +import io.prometheus.metrics.core.exemplars.ExemplarSampler; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Labels; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.concurrent.atomic.LongAdder; + +/** + * Counter metric. + *

+ * Example usage: + *

{@code
+ * Counter requestCount = Counter.newBuilder()
+ *     .withName("requests_total")
+ *     .withHelp("Total number of requests")
+ *     .withLabelNames("path", "status")
+ *     .register();
+ * requestCount.withLabelValues("/hello-world", "200").inc();
+ * requestCount.withLabelValues("/hello-world", "500").inc();
+ * }
+ */ +public class Counter extends StatefulMetric implements CounterDataPoint, Collector { + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Counter(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + if (exemplarsEnabled) { + exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); + } else { + exemplarSamplerConfig = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void inc(long amount) { + getNoLabels().inc(amount); + } + + /** + * {@inheritDoc} + */ + @Override + public void inc(double amount) { + getNoLabels().inc(amount); + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(long amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(double amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** + * {@inheritDoc} + */ + @Override + public CounterSnapshot collect() { + return (CounterSnapshot) super.collect(); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + @Override + protected DataPoint newDataPoint() { + if (isExemplarsEnabled()) { + return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); + } else { + return new DataPoint(null); + } + } + + @Override + protected CounterSnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new CounterSnapshot(getMetadata(), data); + } + + static String normalizeName(String name) { + if (name != null && name.endsWith("_total")) { + name = name.substring(0, name.length() - 6); + } + return name; + } + + class DataPoint implements CounterDataPoint { + + private final DoubleAdder doubleValue = new DoubleAdder(); + // LongAdder is 20% faster than DoubleAdder. So let's use the LongAdder for long observations, + // and DoubleAdder for double observations. If the user doesn't observe any double at all, + // we will be using the LongAdder and get the best performance. + private final LongAdder longValue = new LongAdder(); + private final long createdTimeMillis = System.currentTimeMillis(); + private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false + + private DataPoint(ExemplarSampler exemplarSampler) { + this.exemplarSampler = exemplarSampler; + } + + /** + * {@inheritDoc} + */ + @Override + public void inc(long amount) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observe(amount); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void inc(double amount) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observe(amount); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(long amount, Labels labels) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(amount, labels); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(double amount, Labels labels) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(amount, labels); + } + } + + private void validateAndAdd(long amount) { + if (amount < 0) { + throw new IllegalArgumentException("Negative increment " + amount + " is illegal for Counter metrics."); + } + longValue.add(amount); + } + + private void validateAndAdd(double amount) { + if (amount < 0) { + throw new IllegalArgumentException("Negative increment " + amount + " is illegal for Counter metrics."); + } + doubleValue.add(amount); + } + + private CounterSnapshot.CounterDataPointSnapshot collect(Labels labels) { + // Read the exemplar first. Otherwise, there is a race condition where you might + // see an Exemplar for a value that's not counted yet. + // If there are multiple Exemplars (by default it's just one), use the newest. + Exemplar latestExemplar = null; + if (exemplarSampler != null) { + for (Exemplar exemplar : exemplarSampler.collect()) { + if (latestExemplar == null || exemplar.getTimestampMillis() > latestExemplar.getTimestampMillis()) { + latestExemplar = exemplar; + } + } + } + return new CounterSnapshot.CounterDataPointSnapshot(longValue.sum() + doubleValue.sum(), labels, latestExemplar, createdTimeMillis); + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + private Builder(PrometheusProperties properties) { + super(Collections.emptyList(), properties); + } + + /** + * The {@code _total} suffix will automatically be appended if it's missing. + *
{@code
+         * Counter c1 = Counter.newBuilder()
+         *     .withName("events_total")
+         *     .build();
+         * Counter c2 = Counter.newBuilder()
+         *     .withName("events")
+         *     .build();
+         * }
+ * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. + *

+ * Throws an {@link IllegalArgumentException} if + * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * is {@code false}. + */ + @Override + public Builder withName(String name) { + return super.withName(normalizeName(name)); + } + + @Override + public Counter build() { + return new Counter(this, properties); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java new file mode 100644 index 000000000..c7446f4c1 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java @@ -0,0 +1,101 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +/** + * Example: + *

{@code
+ * ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
+ *
+ * CounterWithCallback.newBuilder()
+ *         .withName("classes_loaded_total")
+ *         .withHelp("The total number of classes that have been loaded since the JVM has started execution")
+ *         .withCallback(callback -> callback.call(classLoadingMXBean.getLoadedClassCount()))
+ *         .register();
+ * }
+ */ +public class CounterWithCallback extends CallbackMetric { + + @FunctionalInterface + public interface Callback { + void call(double value, String... labelValues); + } + + private final Consumer callback; + + private CounterWithCallback(Builder builder) { + super(builder); + this.callback = builder.callback; + if (callback == null) { + throw new IllegalArgumentException("callback cannot be null"); + } + } + + @Override + public CounterSnapshot collect() { + List dataPoints = new ArrayList<>(); + callback.accept((value, labelValues) -> { + dataPoints.add(new CounterSnapshot.CounterDataPointSnapshot(value, makeLabels(labelValues), null, 0L)); + }); + return new CounterSnapshot(getMetadata(), dataPoints); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties properties) { + return new Builder(properties); + } + + public static class Builder extends CallbackMetric.Builder { + + private Consumer callback; + + public Builder withCallback(Consumer callback) { + this.callback = callback; + return self(); + } + + private Builder(PrometheusProperties properties) { + super(Collections.emptyList(), properties); + } + + /** + * The {@code _total} suffix will automatically be appended if it's missing. + *
{@code
+         * CounterWithCallback c1 = CounterWithCallback.newBuilder()
+         *     .withName("events_total")
+         *     .build();
+         * CounterWithCallback c2 = CounterWithCallback.newBuilder()
+         *     .withName("events")
+         *     .build();
+         * }
+ * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. + *

+ * Throws an {@link IllegalArgumentException} if + * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * is {@code false}. + */ + @Override + public Builder withName(String name) { + return super.withName(Counter.normalizeName(name)); + } + + @Override + public CounterWithCallback build() { + return new CounterWithCallback(this); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java new file mode 100644 index 000000000..1b0edfeb1 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java @@ -0,0 +1,213 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.datapoints.GaugeDataPoint; +import io.prometheus.metrics.core.exemplars.ExemplarSampler; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Gauge metric. + *

+ * Example usage: + *

{@code
+ * Gauge currentActiveUsers = Gauge.newBuilder()
+ *     .withName("current_active_users")
+ *     .withHelp("Number of users that are currently active")
+ *     .withLabelNames("region")
+ *     .register();
+ *
+ * public void login(String region) {
+ *     currentActiveUsers.withLabelValues(region).inc();
+ *     // perform login
+ * }
+ *
+ * public void logout(String region) {
+ *     currentActiveUsers.withLabelValues(region).dec();
+ *     // perform logout
+ * }
+ * }
+ */ +public class Gauge extends StatefulMetric implements GaugeDataPoint { + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Gauge(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + if (exemplarsEnabled) { + exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); + } else { + exemplarSamplerConfig = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void inc(double amount) { + getNoLabels().inc(amount); + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(double amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** + * {@inheritDoc} + */ + @Override + public void set(double value) { + getNoLabels().set(value); + } + + /** + * {@inheritDoc} + */ + @Override + public void setWithExemplar(double value, Labels labels) { + getNoLabels().setWithExemplar(value, labels); + } + + /** + * {@inheritDoc} + */ + @Override + public GaugeSnapshot collect() { + return (GaugeSnapshot) super.collect(); + } + + @Override + protected GaugeSnapshot collect(List labels, List metricData) { + List dataPointSnapshots = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + dataPointSnapshots.add(metricData.get(i).collect(labels.get(i))); + } + return new GaugeSnapshot(getMetadata(), dataPointSnapshots); + } + + @Override + protected DataPoint newDataPoint() { + if (isExemplarsEnabled()) { + return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); + } else { + return new DataPoint(null); + } + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + class DataPoint implements GaugeDataPoint { + + private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false + + private DataPoint(ExemplarSampler exemplarSampler) { + this.exemplarSampler = exemplarSampler; + } + + private final AtomicLong value = new AtomicLong(Double.doubleToRawLongBits(0)); + + /** + * {@inheritDoc} + */ + @Override + public void inc(double amount) { + long next = value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); + if (isExemplarsEnabled()) { + exemplarSampler.observe(Double.longBitsToDouble(next)); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void incWithExemplar(double amount, Labels labels) { + long next = value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(Double.longBitsToDouble(next), labels); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void set(double value) { + this.value.set(Double.doubleToRawLongBits(value)); + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setWithExemplar(double value, Labels labels) { + this.value.set(Double.doubleToRawLongBits(value)); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } + } + + private GaugeSnapshot.GaugeDataPointSnapshot collect(Labels labels) { + // Read the exemplar first. Otherwise, there is a race condition where you might + // see an Exemplar for a value that's not represented in getValue() yet. + // If there are multiple Exemplars (by default it's just one), use the oldest + // so that we don't violate min age. + Exemplar oldest = null; + if (isExemplarsEnabled()) { + for (Exemplar exemplar : exemplarSampler.collect()) { + if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { + oldest = exemplar; + } + } + } + return new GaugeSnapshot.GaugeDataPointSnapshot(Double.longBitsToDouble(value.get()), labels, oldest); + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + private Builder(PrometheusProperties config) { + super(Collections.emptyList(), config); + } + + @Override + public Gauge build() { + return new Gauge(this, properties); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java new file mode 100644 index 000000000..7a1424d95 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java @@ -0,0 +1,86 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +/** + * Example: + *
{@code
+ * MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
+ *
+ * GaugeWithCallback.newBuilder()
+ *     .withName("jvm_memory_bytes_used")
+ *     .withHelp("Used bytes of a given JVM memory area.")
+ *     .withUnit(Unit.BYTES)
+ *     .withLabelNames("area")
+ *     .withCallback(callback -> {
+ *         callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap");
+ *         callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap");
+ *     })
+ *     .register();
+ * }
+ */ +public class GaugeWithCallback extends CallbackMetric { + + @FunctionalInterface + public interface Callback { + void call(double value, String... labelValues); + } + + private final Consumer callback; + + private GaugeWithCallback(Builder builder) { + super(builder); + this.callback = builder.callback; + if (callback == null) { + throw new IllegalArgumentException("callback cannot be null"); + } + } + + @Override + public GaugeSnapshot collect() { + List dataPoints = new ArrayList<>(); + callback.accept((value, labelValues) -> { + dataPoints.add(new GaugeSnapshot.GaugeDataPointSnapshot(value, makeLabels(labelValues), null, 0L)); + }); + return new GaugeSnapshot(getMetadata(), dataPoints); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties properties) { + return new Builder(properties); + } + + public static class Builder extends CallbackMetric.Builder { + + private Consumer callback; + + public Builder withCallback(Consumer callback) { + this.callback = callback; + return self(); + } + + private Builder(PrometheusProperties properties) { + super(Collections.emptyList(), properties); + } + + @Override + public GaugeWithCallback build() { + return new GaugeWithCallback(this); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java new file mode 100644 index 000000000..50f352e26 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -0,0 +1,926 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.ExemplarsProperties; +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.exemplars.ExemplarSampler; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; +import io.prometheus.metrics.core.util.Scheduler; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.concurrent.atomic.LongAdder; + +/** + * Histogram metric. Example usage: + *
{@code
+ * Histogram histogram = Histogram.newBuilder()
+ *         .withName("http_request_duration_seconds")
+ *         .withHelp("HTTP request service time in seconds")
+ *         .withUnit(SECONDS)
+ *         .withLabelNames("method", "path", "status_code")
+ *         .register();
+ *
+ * long start = System.nanoTime();
+ * // do something
+ * histogram.withLabelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
+ * }
+ * Prometheus supports two internal representations of histograms: + *
    + *
  1. Classic Histograms have a fixed number of buckets with fixed bucket boundaries.
  2. + *
  3. Native Histograms have an infinite number of buckets with a dynamic resolution. + * Prometheus native histograms are the same as OpenTelemetry's exponential histograms.
  4. + *
+ * By default, a histogram maintains both representations, i.e. the example above will maintain a classic + * histogram representation with Prometheus' default bucket boundaries as well as native histogram representation. + * Which representation is used depends on the exposition format, i.e. which content type the Prometheus server + * accepts when scraping. Exposition format "Text" exposes the classic histogram, exposition format "Protobuf" + * exposes both representations. This is great for migrating from classic histograms to native histograms. + *

+ * If you want the classic representation only, use {@link Histogram.Builder#classicOnly}. + * If you want the native representation only, use {@link Histogram.Builder#nativeOnly}. + */ +public class Histogram extends StatefulMetric implements DistributionDataPoint { + + // nativeSchema == CLASSIC_HISTOGRAM indicates that this is a classic histogram only. + private final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; + + // NATIVE_BOUNDS is used to look up the native bucket index depending on the current schema. + private static final double[][] NATIVE_BOUNDS; + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + // Upper bounds for the classic histogram buckets. Contains at least +Inf. + // An empty array indicates that this is a native histogram only. + private final double[] classicUpperBounds; + + // The schema defines the resolution of the native histogram. + // Schema is Prometheus terminology, in OpenTelemetry it's named "scale". + // The formula for the bucket boundaries at position "index" is: + // + // base := base = (2^(2^-scale)) + // lowerBound := base^(index-1) + // upperBound := base^(index) + // + // Note that this is off-by-one compared to OpenTelemetry. + // + // Example: With schema 0 the bucket boundaries are ... 1/16, 1/8, 1/4, 1/2, 1, 2, 4, 8, 16, ... + // Each increment in schema doubles the number of buckets. + // + // The initialNativeSchema is the schema we start with. The histogram will automatically scale down + // if the number of native histogram buckets exceeds nativeMaxBuckets. + private final int nativeInitialSchema; // integer in [-4, 8] + + // Native histogram buckets get smaller and smaller the closer they get to zero. + // To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all + // values in [-zeroThreshold, +zeroThreshold] to be equal to zero. + // + // The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if + // the number of native histogram buckets exceeds nativeMaxBuckets. + private final double nativeMinZeroThreshold; + private final double nativeMaxZeroThreshold; + + // When the number of native histogram buckets becomes larger than nativeMaxBuckets, + // an attempt is made to reduce the number of buckets: + // (1) Reset if the last reset is longer than the reset duration ago + // (2) Increase the zero bucket width if it's smaller than nativeMaxZeroThreshold + // (3) Decrease the nativeSchema, i.e. merge pairs of neighboring buckets into one + private final int nativeMaxBuckets; + + // If the number of native histogram buckets exceeds nativeMaxBuckets, + // the histogram may reset (all values set to zero) after nativeResetDurationSeconds is expired. + private final long nativeResetDurationSeconds; // 0 indicates no reset + + private Histogram(Histogram.Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + nativeInitialSchema = getConfigProperty(properties, props -> { + if (Boolean.TRUE.equals(props.getHistogramClassicOnly())) { + return CLASSIC_HISTOGRAM; + } else { + return props.getHistogramNativeInitialSchema(); + } + }); + classicUpperBounds = getConfigProperty(properties, props -> { + if (Boolean.TRUE.equals(props.getHistogramNativeOnly())) { + return new double[]{}; + } else if (props.getHistogramClassicUpperBounds() != null) { + SortedSet upperBounds = new TreeSet<>(props.getHistogramClassicUpperBounds()); + upperBounds.add(Double.POSITIVE_INFINITY); + double[] result = new double[upperBounds.size()]; + int i = 0; + for (double upperBound : upperBounds) { + result[i++] = upperBound; + } + return result; + } else { + return null; + } + }); + double max = getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxZeroThreshold); + double min = getConfigProperty(properties, MetricsProperties::getHistogramNativeMinZeroThreshold); + nativeMaxZeroThreshold = max == builder.DEFAULT_NATIVE_MAX_ZERO_THRESHOLD && min > max ? min : max; + nativeMinZeroThreshold = Math.min(min, nativeMaxZeroThreshold); + nativeMaxBuckets = getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxNumberOfBuckets); + nativeResetDurationSeconds = getConfigProperty(properties, MetricsProperties::getHistogramNativeResetDurationSeconds); + ExemplarsProperties exemplarsProperties = prometheusProperties.getExemplarProperties(); + exemplarSamplerConfig = classicUpperBounds.length == 0 ? + new ExemplarSamplerConfig(exemplarsProperties, 4) : + new ExemplarSamplerConfig(exemplarsProperties, classicUpperBounds); + } + + /** + * {@inheritDoc} + */ + @Override + public void observe(double amount) { + getNoLabels().observe(amount); + } + + /** + * {@inheritDoc} + */ + @Override + public void observeWithExemplar(double amount, Labels labels) { + getNoLabels().observeWithExemplar(amount, labels); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + public class DataPoint implements DistributionDataPoint { + private final LongAdder[] classicBuckets; + private final ConcurrentHashMap nativeBucketsForPositiveValues = new ConcurrentHashMap<>(); + private final ConcurrentHashMap nativeBucketsForNegativeValues = new ConcurrentHashMap<>(); + private final LongAdder nativeZeroCount = new LongAdder(); + private final LongAdder count = new LongAdder(); + private final DoubleAdder sum = new DoubleAdder(); + private volatile int nativeSchema = nativeInitialSchema; // integer in [-4, 8] or CLASSIC_HISTOGRAM + private volatile double nativeZeroThreshold = Histogram.this.nativeMinZeroThreshold; + private volatile long createdTimeMillis = System.currentTimeMillis(); + private final Buffer buffer = new Buffer(); + private volatile boolean resetDurationExpired = false; + private final ExemplarSampler exemplarSampler; + + private DataPoint() { + if (exemplarsEnabled) { + exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); + } else { + exemplarSampler = null; + } + classicBuckets = new LongAdder[classicUpperBounds.length]; + for (int i = 0; i < classicUpperBounds.length; i++) { + classicBuckets[i] = new LongAdder(); + } + maybeScheduleNextReset(); + } + + /** + * {@inheritDoc} + */ + @Override + public void observe(double value) { + if (Double.isNaN(value)) { + // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. + return; + } + if (!buffer.append(value)) { + doObserve(value, false); + } + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void observeWithExemplar(double value, Labels labels) { + if (Double.isNaN(value)) { + // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. + return; + } + if (!buffer.append(value)) { + doObserve(value, false); + } + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } + } + + private void doObserve(double value, boolean fromBuffer) { + // classicUpperBounds is an empty array if this is a native histogram only. + for (int i = 0; i < classicUpperBounds.length; ++i) { + // The last bucket is +Inf, so we always increment. + if (value <= classicUpperBounds[i]) { + classicBuckets[i].add(1); + break; + } + } + boolean nativeBucketCreated = false; + if (Histogram.this.nativeInitialSchema != CLASSIC_HISTOGRAM) { + if (value > nativeZeroThreshold) { + nativeBucketCreated = addToNativeBucket(value, nativeBucketsForPositiveValues); + } else if (value < -nativeZeroThreshold) { + nativeBucketCreated = addToNativeBucket(-value, nativeBucketsForNegativeValues); + } else { + nativeZeroCount.add(1); + } + } + sum.add(value); + count.increment(); // must be the last step, because count is used to signal that the operation is complete. + if (!fromBuffer) { + // maybeResetOrScaleDown will switch to the buffer, + // which won't work if we are currently still processing observations from the buffer. + // The reason is that before switching to the buffer we wait for all pending observations to be counted. + // If we do this while still applying observations from the buffer, the pending observations from + // the buffer will never be counted, and the buffer.run() method will wait forever. + maybeResetOrScaleDown(value, nativeBucketCreated); + } + } + + private HistogramSnapshot.HistogramDataPointSnapshot collect(Labels labels) { + Exemplars exemplars = exemplarSampler != null ? exemplarSampler.collect() : Exemplars.EMPTY; + return buffer.run( + expectedCount -> count.sum() == expectedCount, + () -> { + if (classicUpperBounds.length == 0) { + // native only + return new HistogramSnapshot.HistogramDataPointSnapshot( + nativeSchema, + nativeZeroCount.sum(), + nativeZeroThreshold, + toBucketList(nativeBucketsForPositiveValues), + toBucketList(nativeBucketsForNegativeValues), + sum.sum(), + labels, + exemplars, + createdTimeMillis); + } else if (Histogram.this.nativeInitialSchema == CLASSIC_HISTOGRAM) { + // classic only + return new HistogramSnapshot.HistogramDataPointSnapshot( + ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), + sum.sum(), + labels, + exemplars, + createdTimeMillis); + } else { + // hybrid: classic and native + return new HistogramSnapshot.HistogramDataPointSnapshot( + ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), + nativeSchema, + nativeZeroCount.sum(), + nativeZeroThreshold, + toBucketList(nativeBucketsForPositiveValues), + toBucketList(nativeBucketsForNegativeValues), + sum.sum(), + labels, + exemplars, + createdTimeMillis); + } + }, + v -> doObserve(v, true) + ); + } + + private boolean addToNativeBucket(double value, ConcurrentHashMap buckets) { + boolean newBucketCreated = false; + int bucketIndex; + if (Double.isInfinite(value)) { + bucketIndex = findBucketIndex(Double.MAX_VALUE) + 1; + } else { + bucketIndex = findBucketIndex(value); + } + LongAdder bucketCount = buckets.get(bucketIndex); + if (bucketCount == null) { + LongAdder newBucketCount = new LongAdder(); + LongAdder existingBucketCount = buckets.putIfAbsent(bucketIndex, newBucketCount); + if (existingBucketCount == null) { + newBucketCreated = true; + bucketCount = newBucketCount; + } else { + bucketCount = existingBucketCount; + } + } + bucketCount.increment(); + return newBucketCreated; + } + + private int findBucketIndex(double value) { + // Preconditions: + // Double.isNan(value) is false; + // Double.isInfinite(value) is false; + // value > 0 + // --- + // The following is a naive implementation of C's frexp() function. + // Performance can be improved by using the internal Bit representation of floating point numbers. + // More info on the Bit representation of floating point numbers: + // https://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number + // Result: value == frac * 2^exp where frac in [0.5, 1). + double frac = value; + int exp = 0; + while (frac < 0.5) { + frac *= 2.0; + exp--; + } + while (frac >= 1.0) { + frac /= 2.0; + exp++; + } + // end of frexp() + + if (nativeSchema >= 1) { + return findIndex(NATIVE_BOUNDS[nativeSchema - 1], frac) + (exp - 1) * NATIVE_BOUNDS[nativeSchema - 1].length; + } else { + int bucketIndex = exp; + if (frac == 0.5) { + bucketIndex--; + } + int offset = (1 << -nativeSchema) - 1; + bucketIndex = (bucketIndex + offset) >> -nativeSchema; + return bucketIndex; + } + } + + private int findIndex(double[] bounds, double frac) { + // The following is the equivalent of golang's sort.SearchFloat64s(bounds, frac) + // See https://pkg.go.dev/sort#SearchFloat64s + int first = 0; + int last = bounds.length - 1; + while (first <= last) { + int mid = (first + last) / 2; + if (bounds[mid] == frac) { + return mid; + } else if (bounds[mid] < frac) { + first = mid + 1; + } else { + last = mid - 1; + } + } + return last + 1; + } + + /** + * Makes sure that the number of native buckets does not exceed nativeMaxBuckets. + *

    + *
  • If the histogram has already been scaled down (nativeSchema < initialSchema) + * reset after resetIntervalExpired to get back to the original schema.
  • + *
  • If a new bucket was created and we now exceed nativeMaxBuckets + * run maybeScaleDown() to scale down
  • + *
+ */ + private void maybeResetOrScaleDown(double value, boolean nativeBucketCreated) { + AtomicBoolean wasReset = new AtomicBoolean(false); + if (resetDurationExpired && nativeSchema < nativeInitialSchema) { + // If nativeSchema < initialNativeSchema the histogram has been scaled down. + // So if resetDurationExpired we will reset it to restore the original native schema. + buffer.run(expectedCount -> count.sum() == expectedCount, + () -> { + if (maybeReset()) { + wasReset.set(true); + } + return null; + }, + v -> doObserve(v, true)); + } else if (nativeBucketCreated) { + // If a new bucket was created we need to check if nativeMaxBuckets is exceeded + // and scale down if so. + maybeScaleDown(wasReset); + } + if (wasReset.get()) { + // We just discarded the newly observed value. Observe it again. + if (!buffer.append(value)) { + doObserve(value, true); + } + } + } + + private void maybeScaleDown(AtomicBoolean wasReset) { + if (nativeMaxBuckets == 0 || nativeSchema == -4) { + return; + } + int numberOfBuckets = nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); + if (numberOfBuckets <= nativeMaxBuckets) { + return; + } + buffer.run( + expectedCount -> count.sum() == expectedCount, + () -> { + // Now we are in the synchronized block while new observations go into the buffer. + // Check again if we need to limit the bucket size, because another thread might + // have limited it in the meantime. + int nBuckets = nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); + if (nBuckets <= nativeMaxBuckets || nativeSchema == -4) { + return null; + } + if (maybeReset()) { + wasReset.set(true); + return null; + } + if (maybeWidenZeroBucket()) { + return null; + } + doubleBucketWidth(); + return null; + }, + v -> doObserve(v, true) + ); + } + + // maybeReset is called in the synchronized block while new observations go into the buffer. + private boolean maybeReset() { + if (!resetDurationExpired) { + return false; + } + resetDurationExpired = false; + buffer.reset(); + nativeBucketsForPositiveValues.clear(); + nativeBucketsForNegativeValues.clear(); + nativeZeroCount.reset(); + count.reset(); + sum.reset(); + for (int i = 0; i < classicBuckets.length; i++) { + classicBuckets[i].reset(); + } + nativeZeroThreshold = nativeMinZeroThreshold; + nativeSchema = Histogram.this.nativeInitialSchema; + createdTimeMillis = System.currentTimeMillis(); + if (exemplarSampler != null) { + exemplarSampler.reset(); + } + maybeScheduleNextReset(); + return true; + } + + // maybeWidenZeroBucket is called in the synchronized block while new observations go into the buffer. + private boolean maybeWidenZeroBucket() { + if (nativeZeroThreshold >= nativeMaxZeroThreshold) { + return false; + } + int smallestIndex = findSmallestIndex(nativeBucketsForPositiveValues); + int smallestNegativeIndex = findSmallestIndex(nativeBucketsForNegativeValues); + if (smallestNegativeIndex < smallestIndex) { + smallestIndex = smallestNegativeIndex; + } + if (smallestIndex == Integer.MAX_VALUE) { + return false; + } + double newZeroThreshold = nativeBucketIndexToUpperBound(nativeSchema, smallestIndex); + if (newZeroThreshold > nativeMaxZeroThreshold) { + return false; + } + mergeWithZeroBucket(smallestIndex, nativeBucketsForPositiveValues); + mergeWithZeroBucket(smallestIndex, nativeBucketsForNegativeValues); + nativeZeroThreshold = newZeroThreshold; + return true; + } + + private void mergeWithZeroBucket(int index, Map buckets) { + LongAdder count = buckets.remove(index); + if (count != null) { + nativeZeroCount.add(count.sum()); + } + } + + private double nativeBucketIndexToUpperBound(int schema, int index) { + double result = calcUpperBound(schema, index); + if (Double.isInfinite(result)) { + // The last bucket boundary should always be MAX_VALUE, so that the +Inf bucket counts only + // actual +Inf observations. + // However, MAX_VALUE is not a natural bucket boundary, so we introduce MAX_VALUE + // as an artificial boundary before +Inf. + double previousBucketBoundary = calcUpperBound(schema, index - 1); + if (Double.isFinite(previousBucketBoundary) && previousBucketBoundary < Double.MAX_VALUE) { + return Double.MAX_VALUE; + } + } + return result; + } + + private double calcUpperBound(int schema, int index) { + // The actual formula is: + // --- + // base := 2^(2^-schema); + // upperBound := base^index; + // --- + // The following implementation reduces the numerical error for index > 0. + // It's not very efficient. We should refactor and use an algorithm as in client_golang's getLe() + double factor = 1.0; + while (index > 0) { + if (index % 2 == 0) { + index /= 2; + schema -= 1; + } else { + index -= 1; + factor *= Math.pow(2, Math.pow(2, -schema)); + } + } + return factor * Math.pow(2, index * Math.pow(2, -schema)); + } + + private int findSmallestIndex(Map nativeBuckets) { + int result = Integer.MAX_VALUE; + for (int key : nativeBuckets.keySet()) { + if (key < result) { + result = key; + } + } + return result; + } + + // doubleBucketWidth is called in the synchronized block while new observations go into the buffer. + private void doubleBucketWidth() { + doubleBucketWidth(nativeBucketsForPositiveValues); + doubleBucketWidth(nativeBucketsForNegativeValues); + nativeSchema--; + } + + private void doubleBucketWidth(Map buckets) { + int[] keys = new int[buckets.size()]; + long[] values = new long[keys.length]; + int i = 0; + for (Map.Entry entry : buckets.entrySet()) { + keys[i] = entry.getKey(); + values[i] = entry.getValue().sum(); + i++; + } + buckets.clear(); + for (i = 0; i < keys.length; i++) { + int index = (keys[i] + 1) / 2; + LongAdder count = buckets.get(index); + if (count == null) { + count = new LongAdder(); + buckets.put(index, count); + } + count.add(values[i]); + } + } + + private NativeHistogramBuckets toBucketList(ConcurrentHashMap map) { + int[] bucketIndexes = new int[map.size()]; + long[] counts = new long[map.size()]; + int i = 0; + for (Map.Entry entry : map.entrySet()) { + bucketIndexes[i] = entry.getKey(); + counts[i] = entry.getValue().sum(); + i++; + } + return NativeHistogramBuckets.of(bucketIndexes, counts); + } + + private void maybeScheduleNextReset() { + if (nativeResetDurationSeconds > 0) { + Scheduler.schedule(() -> resetDurationExpired = true, nativeResetDurationSeconds, TimeUnit.SECONDS); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public HistogramSnapshot collect() { + return (HistogramSnapshot) super.collect(); + } + + @Override + protected HistogramSnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new HistogramSnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + static { + // See bounds in client_golang's histogram implementation. + NATIVE_BOUNDS = new double[8][]; + for (int schema = 1; schema <= 8; schema++) { + NATIVE_BOUNDS[schema - 1] = new double[1 << schema]; + NATIVE_BOUNDS[schema - 1][0] = 0.5; + // https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto#L501 + double base = Math.pow(2, Math.pow(2, -schema)); + for (int i = 1; i < NATIVE_BOUNDS[schema - 1].length; i++) { + if (i % 2 == 0 && schema > 1) { + // Use previously calculated value for increased precision, see comment in client_golang's implementation. + NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 2][i / 2]; + } else { + NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 1][i - 1] * base; + } + } + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + public static final double[] DEFAULT_CLASSIC_UPPER_BOUNDS = new double[]{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}; + private final double DEFAULT_NATIVE_MIN_ZERO_THRESHOLD = Math.pow(2.0, -128); + private final double DEFAULT_NATIVE_MAX_ZERO_THRESHOLD = Math.pow(2.0, -128); + private final int DEFAULT_NATIVE_INITIAL_SCHEMA = 5; + private final int DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS = 160; + private final long DEFAULT_NATIVE_RESET_DURATION_SECONDS = 0; // 0 means no reset + + private Boolean nativeOnly; + private Boolean classicOnly; + private double[] classicUpperBounds; + private Integer nativeInitialSchema; + private Double nativeMaxZeroThreshold; + private Double nativeMinZeroThreshold; + private Integer nativeMaxNumberOfBuckets; + private Long nativeResetDurationSeconds; + + @Override + public Histogram build() { + return new Histogram(this, properties); + } + + @Override + protected MetricsProperties toProperties() { + return MetricsProperties.newBuilder() + .withExemplarsEnabled(exemplarsEnabled) + .withHistogramNativeOnly(nativeOnly) + .withHistogramClassicOnly(classicOnly) + .withHistogramClassicUpperBounds(classicUpperBounds) + .withHistogramNativeInitialSchema(nativeInitialSchema) + .withHistogramNativeMinZeroThreshold(nativeMinZeroThreshold) + .withHistogramNativeMaxZeroThreshold(nativeMaxZeroThreshold) + .withHistogramNativeMaxNumberOfBuckets(nativeMaxNumberOfBuckets) + .withHistogramNativeResetDurationSeconds(nativeResetDurationSeconds) + .build(); + } + + /** + * Default properties for histogram metrics. + */ + @Override + public MetricsProperties getDefaultProperties() { + return MetricsProperties.newBuilder() + .withExemplarsEnabled(true) + .withHistogramNativeOnly(false) + .withHistogramClassicOnly(false) + .withHistogramClassicUpperBounds(DEFAULT_CLASSIC_UPPER_BOUNDS) + .withHistogramNativeInitialSchema(DEFAULT_NATIVE_INITIAL_SCHEMA) + .withHistogramNativeMinZeroThreshold(DEFAULT_NATIVE_MIN_ZERO_THRESHOLD) + .withHistogramNativeMaxZeroThreshold(DEFAULT_NATIVE_MAX_ZERO_THRESHOLD) + .withHistogramNativeMaxNumberOfBuckets(DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS) + .withHistogramNativeResetDurationSeconds(DEFAULT_NATIVE_RESET_DURATION_SECONDS) + .build(); + } + + private Builder(PrometheusProperties config) { + super(Collections.singletonList("le"), config); + } + + /** + * Use the native histogram representation only, i.e. don't maintain classic histogram buckets. + * See {@link Histogram} for more info. + */ + public Builder nativeOnly() { + if (Boolean.TRUE.equals(classicOnly)) { + throw new IllegalArgumentException("Cannot call nativeOnly() after calling classicOnly()."); + } + nativeOnly = true; + return this; + } + + /** + * Use the classic histogram representation only, i.e. don't maintain native histogram buckets. + * See {@link Histogram} for more info. + */ + public Builder classicOnly() { + if (Boolean.TRUE.equals(nativeOnly)) { + throw new IllegalArgumentException("Cannot call classicOnly() after calling nativeOnly()."); + } + classicOnly = true; + return this; + } + + + /** + * Set the upper bounds for the classic histogram buckets. + * Default is {@link Builder#DEFAULT_CLASSIC_UPPER_BOUNDS}. + * If the +Inf bucket is missing it will be added. + * If upperBounds contains duplicates the duplicates will be removed. + */ + public Builder withClassicBuckets(double... upperBounds) { + this.classicUpperBounds = upperBounds; + for (double bound : upperBounds) { + if (Double.isNaN(bound)) { + throw new IllegalArgumentException("Cannot use NaN as upper bound for a histogram"); + } + } + return this; + } + + /** + * Create classic histogram buckets with linear bucket boundaries. + *

+ * Example: {@code withClassicLinearBuckets(1.0, 0.5, 10)} creates bucket boundaries + * {@code [[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5]}. + * + * @param start is the first bucket boundary + * @param width is the width of each bucket + * @param count is the total number of buckets, including start + */ + public Builder withClassicLinearBuckets(double start, double width, int count) { + this.classicUpperBounds = new double[count]; + // Use BigDecimal to avoid weird bucket boundaries like 0.7000000000000001. + BigDecimal s = new BigDecimal(Double.toString(start)); + BigDecimal w = new BigDecimal(Double.toString(width)); + for (int i = 0; i < count; i++) { + classicUpperBounds[i] = s.add(w.multiply(new BigDecimal(i))).doubleValue(); + } + return this; + } + + /** + * Create classic histogram bucxkets with exponential boundaries. + *

+ * Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket bounaries + * {@code [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]} + * + * @param start is the first bucket boundary + * @param factor growth factor + * @param count total number of buckets, including start + */ + public Builder withClassicExponentialBuckets(double start, double factor, int count) { + classicUpperBounds = new double[count]; + for (int i = 0; i < count; i++) { + classicUpperBounds[i] = start * Math.pow(factor, i); + } + return this; + } + + /** + * The schema is a number in [-4, 8] defining the resolution of the native histogram. + * Default is {@link Builder#DEFAULT_NATIVE_INITIAL_SCHEMA}. + *

+ * The higher the schema, the finer the resolution. + * Schema is Prometheus terminology. In OpenTelemetry it's called "scale". + *

+ * Note that the schema for a histogram may be automatically decreased at runtime if the number + * of native histogram buckets exceeds {@link #withNativeMaxNumberOfBuckets(int)}. + *

+ * The following table shows: + *

    + *
  • factor: The growth factor for bucket boundaries, i.e. next bucket boundary = growth factor * previous bucket boundary. + *
  • max quantile error: The maximum error for quantiles calculated using the Prometheus histogram_quantile() function, relative to the observed value, assuming harmonic mean. + *
+ * + * + * + * + * + * 99% + * + * + * 99% + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
schemafactormax quantile error
-465.536
-3256
-21688%
-1460%
0233%
11.4142...17%
21.1892...9%
31.1090...4%
41.0442...2%
51.0218...1%
61.0108...0.5%
71.0054...0.3%
81.0027...0.1%
+ */ + public Builder withNativeInitialSchema(int nativeSchema) { + if (nativeSchema < -4 || nativeSchema > 8) { + throw new IllegalArgumentException("Unsupported native histogram schema " + nativeSchema + ": expecting -4 <= schema <= 8."); + } + this.nativeInitialSchema = nativeSchema; + return this; + } + + /** + * Native histogram buckets get smaller and smaller the closer they get to zero. + * To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all + * values in [-zeroThreshold, +zeroThreshold] to be equal to zero. + *

+ * The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if + * the number of native histogram buckets exceeds nativeMaxBuckets. + *

+ * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. + */ + public Builder withNativeMaxZeroThreshold(double nativeMaxZeroThreshold) { + if (nativeMaxZeroThreshold < 0) { + throw new IllegalArgumentException("Illegal native max zero threshold " + nativeMaxZeroThreshold + ": must be >= 0"); + } + this.nativeMaxZeroThreshold = nativeMaxZeroThreshold; + return this; + } + + /** + * Native histogram buckets get smaller and smaller the closer they get to zero. + * To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all + * values in [-zeroThreshold, +zeroThreshold] to be equal to zero. + *

+ * The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if + * the number of native histogram buckets exceeds nativeMaxBuckets. + *

+ * Default is {@link Builder#DEFAULT_NATIVE_MIN_ZERO_THRESHOLD}. + */ + public Builder withNativeMinZeroThreshold(double nativeMinZeroThreshold) { + if (nativeMinZeroThreshold < 0) { + throw new IllegalArgumentException("Illegal native min zero threshold " + nativeMinZeroThreshold + ": must be >= 0"); + } + this.nativeMinZeroThreshold = nativeMinZeroThreshold; + return this; + } + + /** + * Limit the number of native buckets. + *

+ * If the number of native buckets exceeds the maximum, the {@link #withNativeInitialSchema(int)} is decreased, + * i.e. the resolution of the histogram is decreased to reduce the number of buckets. + *

+ * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. + */ + public Builder withNativeMaxNumberOfBuckets(int nativeMaxBuckets) { + this.nativeMaxNumberOfBuckets = nativeMaxBuckets; + return this; + } + + /** + * If the histogram needed to be scaled down because {@link #withNativeMaxNumberOfBuckets(int)} was exceeded, + * reset the histogram after a certain time interval to go back to the original {@link #withNativeInitialSchema(int)}. + *

+ * Reset means all values are set to zero. A good value might be 24h or 7d. + *

+ * Default is no reset. + */ + public Builder withNativeResetDuration(long duration, TimeUnit unit) { + // TODO: reset interval isn't tested yet + if (duration <= 0) { + throw new IllegalArgumentException(duration + ": value > 0 expected"); + } + nativeResetDurationSeconds = unit.toSeconds(duration); + return this; + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java new file mode 100644 index 000000000..9d6675dbb --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java @@ -0,0 +1,132 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Info metric. Example: + *

{@code
+ * Info info = Info.newBuilder()
+ *         .withName("java_runtime_info")
+ *         .withHelp("Java runtime info")
+ *         .withLabelNames("env", "version", "vendor", "runtime")
+ *         .register();
+ *
+ * String version = System.getProperty("java.runtime.version", "unknown");
+ * String vendor = System.getProperty("java.vm.vendor", "unknown");
+ * String runtime = System.getProperty("java.runtime.name", "unknown");
+ *
+ * info.infoLabelValues("prod", version, vendor, runtime);
+ * info.infoLabelValues("dev", version, vendor, runtime);
+ * }
+ */ +public class Info extends MetricWithFixedMetadata { + + private final List labels = new CopyOnWriteArrayList<>(); + + private Info(Builder builder) { + super(builder); + } + + /** + * Create an info data point with the given label values. + */ + public void infoLabelValues(String... labelValues) { + if (labelValues.length != labelNames.length) { + if (labelValues.length == 0) { + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call withLabelValues(...) when using it."); + } else { + throw new IllegalArgumentException("Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); + } + } + labels.add(Labels.of(labelNames, labelValues)); + } + + /** + * {@inheritDoc} + */ + @Override + public InfoSnapshot collect() { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(new InfoSnapshot.InfoDataPointSnapshot(labels.get(i).merge(constLabels))); + } + return new InfoSnapshot(getMetadata(), data); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends MetricWithFixedMetadata.Builder { + + private Builder(PrometheusProperties config) { + super(Collections.emptyList(), config); + } + + /** + * The {@code _info} suffix will automatically be appended if it's missing. + *
{@code
+         * Info info1 = Info.newBuilder()
+         *     .withName("runtime_info")
+         *     .build();
+         * Info info2 = Info.newBuilder()
+         *     .withName("runtime")
+         *     .build();
+         * }
+ * In the example above both {@code info1} and {@code info2} will be named {@code "runtime_info"} in Prometheus. + *

+ * Throws an {@link IllegalArgumentException} if + * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * is {@code false}. + */ + @Override + public Builder withName(String name) { + if (name != null && name.endsWith("_info")) { + name = name.substring(0, name.length() - 5); + } + return super.withName(name); + } + + /** + * Throws an {@link UnsupportedOperationException} because Info metrics cannot have a unit. + */ + @Override + public Builder withUnit(Unit unit) { + if (unit != null) { + throw new UnsupportedOperationException("Info metrics cannot have a unit."); + } + return this; + } + + private static String normalizeName(String name) { + if (name != null && name.endsWith("_info")) { + name = name.substring(0, name.length() - 5); + } + return name; + } + + @Override + public Info build() { + return new Info(withName(normalizeName(name))); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java new file mode 100644 index 000000000..81ff931ce --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java @@ -0,0 +1,68 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; + +import java.util.ArrayList; +import java.util.List; + +/** + * Common base class for all metrics. + */ +public abstract class Metric implements Collector { + + protected final Labels constLabels; + + protected Metric(Builder builder) { + this.constLabels = builder.constLabels; + } + + @Override + public abstract MetricSnapshot collect(); + + protected static abstract class Builder, M extends Metric> { + + protected final List illegalLabelNames; + protected final PrometheusProperties properties; + private Labels constLabels = Labels.EMPTY; + + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + this.illegalLabelNames = new ArrayList<>(illegalLabelNames); + this.properties = properties; + } + + // ConstLabels are only used rarely. In particular, do not use them to + // attach the same labels to all your metrics. Those use cases are + // better covered by target labels set by the scraping Prometheus + // server, or by one specific metric (e.g. a build_info or a + // machine_role metric). See also + // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels + public B withConstLabels(Labels constLabels) { + for (Label label : constLabels) { // NPE if constLabels is null + if (illegalLabelNames.contains(label.getName())) { + throw new IllegalArgumentException(label.getName() + ": illegal label name for this metric type"); + } + } + this.constLabels = constLabels; + return self(); + } + + public M register() { + return register(PrometheusRegistry.defaultRegistry); + } + + public M register(PrometheusRegistry registry) { + M metric = build(); + registry.register(metric); + return metric; + } + + public abstract M build(); + + protected abstract B self(); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java new file mode 100644 index 000000000..22b607654 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -0,0 +1,90 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.util.Arrays; +import java.util.List; + +/** + * Almost all metrics have fixed metadata, i.e. the metric name is known when the metric is created. + *

+ * An exception would be a metric that is a bridge to a 3rd party metric library, where the metric name + * has to be retrieved from the 3rd party metric library at scrape time. + */ +public abstract class MetricWithFixedMetadata extends Metric { + + private final MetricMetadata metadata; + protected final String[] labelNames; + + protected MetricWithFixedMetadata(Builder builder) { + super(builder); + this.metadata = new MetricMetadata(makeName(builder.name, builder.unit), builder.help, builder.unit); + this.labelNames = Arrays.copyOf(builder.labelNames, builder.labelNames.length); + } + + protected MetricMetadata getMetadata() { + return metadata; + } + + private String makeName(String name, Unit unit) { + if (unit != null) { + String suffix = "_" + unit; + if (!name.endsWith(suffix)) { + name = name + suffix; + } + } + return name; + } + + public static abstract class Builder, M extends MetricWithFixedMetadata> extends Metric.Builder { + + protected String name; + private Unit unit; + private String help; + private String[] labelNames = new String[0]; + + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + super(illegalLabelNames, properties); + } + + public B withName(String name) { + if (!MetricMetadata.isValidMetricName(name)) { + throw new IllegalArgumentException("'" + name + "': Illegal metric name."); + } + this.name = name; + return self(); + } + + public B withUnit(Unit unit) { + this.unit = unit; + return self(); + } + + public B withHelp(String help) { + this.help = help; + return self(); + } + + public B withLabelNames(String... labelNames) { + for (String labelName : labelNames) { + if (!Labels.isValidLabelName(labelName)) { + throw new IllegalArgumentException(labelName + ": illegal label name"); + } + if (illegalLabelNames.contains(labelName)) { + throw new IllegalArgumentException(labelName + ": illegal label name for this metric type"); + } + } + this.labelNames = labelNames; + return self(); + } + + @Override + public abstract M build(); + + @Override + protected abstract B self(); + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java new file mode 100644 index 000000000..b789e809c --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -0,0 +1,74 @@ +package io.prometheus.metrics.core.metrics; + +import java.lang.reflect.Array; +import java.util.concurrent.TimeUnit; +import java.util.function.ObjDoubleConsumer; +import java.util.function.Supplier; + +/** + * Maintains a ring buffer of T to implement a sliding time window. + *

+ * This is used to maintain a sliding window of {@link CKMSQuantiles} for {@link Summary} metrics. + *

+ * It is implemented in a generic way so that 3rd party libraries can use it for implementing sliding windows. + *

+ * TODO: The current implementation is {@code synchronized}. There is likely room for optimization. + */ +public class SlidingWindow { + + private final Supplier constructor; + private final ObjDoubleConsumer observeFunction; + private final T[] ringBuffer; + private int currentBucket; + private long lastRotateTimestampMillis; + private final long durationBetweenRotatesMillis; + + /** + * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of {@code T} + * are maintained and the sliding window moves to the next instance of T every 20 seconds. + * + * @param clazz type of T + * @param constructor for creating a new instance of T as the old one gets evicted + * @param observeFunction for observing a value (e.g. calling {@code t.observe(value)} + * @param maxAgeSeconds after this amount of time an instance of T gets evicted. + * @param ageBuckets number of age buckets. + */ + public SlidingWindow(Class clazz, Supplier constructor, ObjDoubleConsumer observeFunction, long maxAgeSeconds, int ageBuckets) { + this.constructor = constructor; + this.observeFunction = observeFunction; + this.ringBuffer = (T[]) Array.newInstance(clazz, ageBuckets); + for (int i = 0; i < ringBuffer.length; i++) { + this.ringBuffer[i] = constructor.get(); + } + this.currentBucket = 0; + this.lastRotateTimestampMillis = System.currentTimeMillis(); + this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets; + } + + /** + * Get the currently active instance of {@code T}. + */ + public synchronized T current() { + return rotate(); + } + + /** + * Observe a value. + */ + public synchronized void observe(double value) { + observeFunction.accept(rotate(), value); + } + + private T rotate() { + long timeSinceLastRotateMillis = System.currentTimeMillis() - lastRotateTimestampMillis; + while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { + ringBuffer[currentBucket] = constructor.get(); + if (++currentBucket >= ringBuffer.length) { + currentBucket = 0; + } + timeSinceLastRotateMillis -= durationBetweenRotatesMillis; + lastRotateTimestampMillis += durationBetweenRotatesMillis; + } + return ringBuffer[currentBucket]; + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java new file mode 100644 index 000000000..308c61be1 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -0,0 +1,194 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.core.datapoints.StateSetDataPoint; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +/** + * StateSet metric. Example: + *

{@code
+ * public enum Feature {
+ *
+ *     FEATURE_1("feature1"),
+ *     FEATURE_2("feature2");
+ *
+ *     private final String name;
+ *
+ *     Feature(String name) {
+ *         this.name = name;
+ *     }
+ *
+ *     @Override
+ *     public String toString() {
+ *         return name;
+ *     }
+ * }
+ *
+ * public static void main(String[] args) {
+ *
+ *     StateSet stateSet = StateSet.newBuilder()
+ *             .withName("feature_flags")
+ *             .withHelp("Feature flags")
+ *             .withLabelNames("env")
+ *             .withStates(Feature.class)
+ *             .register();
+ *
+ *     stateSet.withLabelValues("dev").setFalse(FEATURE_1);
+ *     stateSet.withLabelValues("dev").setTrue(FEATURE_2);
+ * }
+ * }
+ * The example above shows how to use a StateSet with an enum. + * You don't have to use enum, you can use regular strings as well. + */ +public class StateSet extends StatefulMetric implements StateSetDataPoint { + + private final boolean exemplarsEnabled; + private final String[] names; + + private StateSet(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + this.names = builder.names; // builder.names is already a validated copy + for (String name : names) { + if (this.getMetadata().getName().equals(name)) { + throw new IllegalArgumentException("Label name " + name + " is illegal (can't use the metric name as label name in state set metrics)"); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public StateSetSnapshot collect() { + return (StateSetSnapshot) super.collect(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setTrue(String state) { + getNoLabels().setTrue(state); + } + + /** + * {@inheritDoc} + */ + @Override + public void setFalse(String state) { + getNoLabels().setFalse(state); + } + + @Override + protected StateSetSnapshot collect(List labels, List metricDataList) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(new StateSetSnapshot.StateSetDataPointSnapshot(names, metricDataList.get(i).values, labels.get(i))); + } + return new StateSetSnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + class DataPoint implements StateSetDataPoint { + + private final boolean[] values = new boolean[names.length]; + + private DataPoint() { + } + + /** + * {@inheritDoc} + */ + @Override + public void setTrue(String state) { + set(state, true); + } + + /** + * {@inheritDoc} + */ + @Override + public void setFalse(String state) { + set(state, false); + } + + private void set(String name, boolean value) { + for (int i = 0; i < names.length; i++) { + if (names[i].equals(name)) { + values[i] = value; + return; + } + } + throw new IllegalArgumentException(name + ": unknown state"); + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + private String[] names; + + private Builder(PrometheusProperties config) { + super(Collections.emptyList(), config); + } + + /** + * Declare the states that should be represented by this StateSet. + */ + public Builder withStates(Class> enumClass) { + return withStates(Stream.of(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new)); + } + + /** + * Declare the states that should be represented by this StateSet. + */ + public Builder withStates(String... stateNames) { + if (stateNames.length == 0) { + throw new IllegalArgumentException("states cannot be empty"); + } + this.names = Stream.of(stateNames) + .distinct() + .sorted() + .toArray(String[]::new); + return this; + } + + @Override + public StateSet build() { + if (names == null) { + throw new IllegalStateException("State names are required when building a StateSet."); + } + return new StateSet(this, properties); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java new file mode 100644 index 000000000..591c16e6b --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -0,0 +1,158 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.core.datapoints.DataPoint; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + +/** + * There are two kinds of metrics: + *
    + *
  • A {@code StatefulMetric} actively maintains its current values, e.g. a stateful counter actively stores its current count.
  • + *
  • A {@code CallbackMetric} gets its values on demand when it is collected, e.g. a callback gauge representing the current heap size.
  • + *
+ * The OpenTelemetry terminology for stateful is synchronous and the OpenTelemetry terminology for callback is asynchronous. + * We are using our own terminology here because in Java synchronous and asynchronous usually refers to multi-threading, + * but this has nothing to do with multi-threading. + */ +abstract class StatefulMetric extends MetricWithFixedMetadata { + + /** + * Map label values to data points. + */ + private final ConcurrentHashMap, T> data = new ConcurrentHashMap<>(); + + /** + * Shortcut for data.get(Collections.emptyList()) + */ + private volatile T noLabels; + + protected StatefulMetric(Builder builder) { + super(builder); + } + + /** + * labels and metricData have the same size. labels.get(i) are the labels for metricData.get(i). + */ + protected abstract MetricSnapshot collect(List labels, List metricData); + + public MetricSnapshot collect() { + if (labelNames.length == 0 && data.size() == 0) { + // This is a metric without labels that has not been used yet. Initialize the data on the fly. + withLabelValues(); + } + List labels = new ArrayList<>(data.size()); + List metricData = new ArrayList<>(data.size()); + for (Map.Entry, T> entry : data.entrySet()) { + String[] labelValues = entry.getKey().toArray(new String[labelNames.length]); + labels.add(constLabels.merge(labelNames, labelValues)); + metricData.add(entry.getValue()); + } + return collect(labels, metricData); + } + + public D withLabelValues(String... labelValues) { + if (labelValues.length != labelNames.length) { + if (labelValues.length == 0) { + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call withLabelValues(...) when using it."); + } else { + throw new IllegalArgumentException("Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); + } + } + return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); + } + + // TODO: Remove automatically if label values have not been used in a while? + public void remove(String... labelValues) { + data.remove(Arrays.asList(labelValues)); + } + + protected abstract T newDataPoint(); + + protected T getNoLabels() { + if (noLabels == null) { + // Note that this will throw an IllegalArgumentException if labelNames is not empty. + noLabels = (T) withLabelValues(); + } + return noLabels; + } + + protected MetricsProperties[] getMetricProperties(Builder builder, PrometheusProperties prometheusProperties) { + String metricName = getMetadata().getName(); + if (prometheusProperties.getMetricProperties(metricName) != null) { + return new MetricsProperties[]{ + prometheusProperties.getMetricProperties(metricName), // highest precedence + builder.toProperties(), // second-highest precedence + prometheusProperties.getDefaultMetricProperties(), // third-highest precedence + builder.getDefaultProperties() // fallback + }; + } else { + return new MetricsProperties[]{ + builder.toProperties(), // highest precedence + prometheusProperties.getDefaultMetricProperties(), // second-highest precedence + builder.getDefaultProperties() // fallback + }; + } + } + + protected T getConfigProperty(MetricsProperties[] properties, Function getter) { + T result; + for (MetricsProperties props : properties) { + result = getter.apply(props); + if (result != null) { + return result; + } + } + throw new IllegalStateException("Missing default config. This is a bug in the Prometheus metrics core library."); + } + + protected abstract boolean isExemplarsEnabled(); + + static abstract class Builder, M extends StatefulMetric> extends MetricWithFixedMetadata.Builder { + + protected Boolean exemplarsEnabled; + + protected Builder(List illegalLabelNames, PrometheusProperties config) { + super(illegalLabelNames, config); + } + + public B withExemplars() { + this.exemplarsEnabled = TRUE; + return self(); + } + + public B withoutExemplars() { + this.exemplarsEnabled = FALSE; + return self(); + } + + /** + * Override if there are more properties than just exemplars enabled. + */ + protected MetricsProperties toProperties() { + return MetricsProperties.newBuilder() + .withExemplarsEnabled(exemplarsEnabled) + .build(); + } + + /** + * Override if there are more properties than just exemplars enabled. + */ + public MetricsProperties getDefaultProperties() { + return MetricsProperties.newBuilder() + .withExemplarsEnabled(true) + .build(); + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java new file mode 100644 index 000000000..d461162f1 --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java @@ -0,0 +1,355 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.MetricsProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.exemplars.ExemplarSampler; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.DoubleAdder; +import java.util.concurrent.atomic.LongAdder; + +/** + * Summary metric. Example: + *
{@code
+ * Summary summary = Summary.newBuilder()
+ *         .withName("http_request_duration_seconds_hi")
+ *         .withHelp("HTTP request service time in seconds")
+ *         .withUnit(SECONDS)
+ *         .withLabelNames("method", "path", "status_code")
+ *         .withQuantile(0.5, 0.01)
+ *         .withQuantile(0.95, 0.001)
+ *         .withQuantile(0.99, 0.001)
+ *         .register();
+ *
+ * long start = System.nanoTime();
+ * // process a request, duration will be observed
+ * summary.withLabelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
+ * }
+ * See {@link Summary.Builder} for configuration options. + */ +public class Summary extends StatefulMetric implements DistributionDataPoint { + + private final List quantiles; // May be empty, but cannot be null. + private final long maxAgeSeconds; + private final int ageBuckets; + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Summary(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + this.exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + this.quantiles = Collections.unmodifiableList(makeQuantiles(properties)); + this.maxAgeSeconds = getConfigProperty(properties, MetricsProperties::getSummaryMaxAgeSeconds); + this.ageBuckets = getConfigProperty(properties, MetricsProperties::getSummaryNumberOfAgeBuckets); + this.exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 4); + } + + private List makeQuantiles(MetricsProperties[] properties) { + List result = new ArrayList<>(); + List quantiles = getConfigProperty(properties, MetricsProperties::getSummaryQuantiles); + List quantileErrors = getConfigProperty(properties, MetricsProperties::getSummaryQuantileErrors); + if (quantiles != null) { + for (int i = 0; i < quantiles.size(); i++) { + if (quantileErrors.size() > 0) { + result.add(new CKMSQuantiles.Quantile(quantiles.get(i), quantileErrors.get(i))); + } else { + result.add(new CKMSQuantiles.Quantile(quantiles.get(i), Builder.defaultError(quantiles.get(i)))); + } + } + } + return result; + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + /** + * {@inheritDoc} + */ + @Override + public void observe(double amount) { + getNoLabels().observe(amount); + } + + /** + * {@inheritDoc} + */ + @Override + public void observeWithExemplar(double amount, Labels labels) { + getNoLabels().observeWithExemplar(amount, labels); + } + + /** + * {@inheritDoc} + */ + @Override + public SummarySnapshot collect() { + return (SummarySnapshot) super.collect(); + } + + @Override + protected SummarySnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new SummarySnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + + public class DataPoint implements DistributionDataPoint { + + private final LongAdder count = new LongAdder(); + private final DoubleAdder sum = new DoubleAdder(); + private final SlidingWindow quantileValues; + private final Buffer buffer = new Buffer(); + private final ExemplarSampler exemplarSampler; + + private final long createdTimeMillis = System.currentTimeMillis(); + + private DataPoint() { + if (quantiles.size() > 0) { + CKMSQuantiles.Quantile[] quantilesArray = quantiles.toArray(new CKMSQuantiles.Quantile[0]); + quantileValues = new SlidingWindow<>(CKMSQuantiles.class, () -> new CKMSQuantiles(quantilesArray), CKMSQuantiles::insert, maxAgeSeconds, ageBuckets); + } else { + quantileValues = null; + } + if (exemplarsEnabled) { + exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); + } else { + exemplarSampler = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public void observe(double value) { + if (Double.isNaN(value)) { + return; + } + if (!buffer.append(value)) { + doObserve(value); + } + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void observeWithExemplar(double value, Labels labels) { + if (Double.isNaN(value)) { + return; + } + if (!buffer.append(value)) { + doObserve(value); + } + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } + } + + private void doObserve(double amount) { + sum.add(amount); + if (quantileValues != null) { + quantileValues.observe(amount); + } + // count must be incremented last, because in collect() the count + // indicates the number of completed observations. + count.increment(); + } + + private SummarySnapshot.SummaryDataPointSnapshot collect(Labels labels) { + return buffer.run( + expectedCount -> count.sum() == expectedCount, + // TODO Exemplars (are hard-coded as empty in the line below) + () -> new SummarySnapshot.SummaryDataPointSnapshot(count.sum(), sum.sum(), makeQuantiles(), labels, Exemplars.EMPTY, createdTimeMillis), + this::doObserve + ); + } + + private List getQuantiles() { + return quantiles; + } + + private Quantiles makeQuantiles() { + Quantile[] quantiles = new Quantile[getQuantiles().size()]; + for (int i = 0; i < getQuantiles().size(); i++) { + CKMSQuantiles.Quantile quantile = getQuantiles().get(i); + quantiles[i] = new Quantile(quantile.quantile, quantileValues.current().get(quantile.quantile)); + } + return Quantiles.of(quantiles); + } + } + + public static Summary.Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Summary.Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + /** + * 5 minutes. See {@link #withMaxAgeSeconds(long)}. + */ + public static final long DEFAULT_MAX_AGE_SECONDS = TimeUnit.MINUTES.toSeconds(5); + + /** + * 5. See {@link #withNumberOfAgeBuckets(int)} + */ + public static final int DEFAULT_NUMBER_OF_AGE_BUCKETS = 5; + private final List quantiles = new ArrayList<>(); + private Long maxAgeSeconds; + private Integer ageBuckets; + + private Builder(PrometheusProperties properties) { + super(Collections.singletonList("quantile"), properties); + } + + private static double defaultError(double quantile) { + if (quantile <= 0.01 || quantile >= 0.99) { + return 0.001; + } else if (quantile <= 0.02 || quantile >= 0.98) { + return 0.005; + } else { + return 0.01; + } + } + + /** + * See {@link #withQuantile(double, double)}. + *

+ * Default errors are: + *

    + *
  • error = 0.001 if quantile <= 0.01 or quantile >= 0.99
  • + *
  • error = 0.005 if quantile <= 0.02 or quantile >= 0.98
  • + *
  • error = 0.01 else. + *
+ */ + public Builder withQuantile(double quantile) { + return withQuantile(quantile, defaultError(quantile)); + } + + /** + * Example: The following will track the 0.95 quantile: + *
{@code
+         * .withQuantile(0.95, 0.001)
+         * }
+ * The second argument is the acceptable error margin, i.e. with the code above the quantile + * will not be exactly the 0.95 quantile but something between 0.949 and 0.951. + *

+ * There are two special cases: + *

    + *
  • {@code .withQuantile(0.0, 0.0)} gives you the minimum observed value
  • + *
  • {@code .withQuantile(1.0, 0.0)} gives you the maximum observed value
  • + *
+ */ + public Builder withQuantile(double quantile, double error) { + if (quantile < 0.0 || quantile > 1.0) { + throw new IllegalArgumentException("Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); + } + if (error < 0.0 || error > 1.0) { + throw new IllegalArgumentException("Error " + error + " invalid: Expected number between 0.0 and 1.0."); + } + quantiles.add(new CKMSQuantiles.Quantile(quantile, error)); + return this; + } + + /** + * The quantiles are relative to a moving time window. + * {@code maxAgeSeconds} is the size of that time window. + * Default is {@link #DEFAULT_MAX_AGE_SECONDS}. + */ + public Builder withMaxAgeSeconds(long maxAgeSeconds) { + if (maxAgeSeconds <= 0) { + throw new IllegalArgumentException("maxAgeSeconds cannot be " + maxAgeSeconds); + } + this.maxAgeSeconds = maxAgeSeconds; + return this; + } + + /** + * The quantiles are relative to a moving time window. + * The {@code numberOfAgeBuckets} defines how smoothly the time window moves forward. + * For example, if the time window is 5 minutes and has 5 age buckets, + * then it is moving forward every minute by one minute. + * Default is {@link #DEFAULT_NUMBER_OF_AGE_BUCKETS}. + */ + public Builder withNumberOfAgeBuckets(int ageBuckets) { + if (ageBuckets <= 0) { + throw new IllegalArgumentException("ageBuckets cannot be " + ageBuckets); + } + this.ageBuckets = ageBuckets; + return this; + } + + @Override + protected MetricsProperties toProperties() { + double[] quantiles = null; + double[] quantileErrors = null; + if (!this.quantiles.isEmpty()) { + quantiles = new double[this.quantiles.size()]; + quantileErrors = new double[this.quantiles.size()]; + for (int i = 0; i < this.quantiles.size(); i++) { + quantiles[i] = this.quantiles.get(i).quantile; + quantileErrors[i] = this.quantiles.get(i).epsilon; + } + } + return MetricsProperties.newBuilder() + .withExemplarsEnabled(exemplarsEnabled) + .withSummaryQuantiles(quantiles) + .withSummaryQuantileErrors(quantileErrors) + .withSummaryNumberOfAgeBuckets(ageBuckets) + .withSummaryMaxAgeSeconds(maxAgeSeconds) + .build(); + } + + /** + * Default properties for summary metrics. + */ + @Override + public MetricsProperties getDefaultProperties() { + return MetricsProperties.newBuilder() + .withExemplarsEnabled(true) + .withSummaryQuantiles() + .withSummaryNumberOfAgeBuckets(DEFAULT_NUMBER_OF_AGE_BUCKETS) + .withSummaryMaxAgeSeconds(DEFAULT_MAX_AGE_SECONDS) + .build(); + } + + @Override + public Summary build() { + return new Summary(this, properties); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java new file mode 100644 index 000000000..c9bdcfdfe --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java @@ -0,0 +1,93 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +/** + * Example: + *
{@code
+ * double MILLISECONDS_PER_SECOND = 1E3;
+ *
+ * SummaryWithCallback.newBuilder()
+ *         .withName("jvm_gc_collection_seconds")
+ *         .withHelp("Time spent in a given JVM garbage collector in seconds.")
+ *         .withUnit(Unit.SECONDS)
+ *         .withLabelNames("gc")
+ *         .withCallback(callback -> {
+ *             for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
+ *                 callback.call(
+ *                         gc.getCollectionCount(),
+ *                         gc.getCollectionTime() / MILLISECONDS_PER_SECOND,
+ *                         Quantiles.EMPTY,
+ *                         gc.getName()
+ *                 );
+ *             }
+ *         })
+ *         .register();
+ * }
+ */ +public class SummaryWithCallback extends CallbackMetric { + + @FunctionalInterface + public interface Callback { + void call(long count, double sum, Quantiles quantiles, String... labelValues); + } + + private final Consumer callback; + + private SummaryWithCallback(Builder builder) { + super(builder); + this.callback = builder.callback; + if (callback == null) { + throw new IllegalArgumentException("callback cannot be null"); + } + } + + @Override + public SummarySnapshot collect() { + List dataPoints = new ArrayList<>(); + callback.accept((count, sum, quantiles, labelValues) -> { + dataPoints.add(new SummarySnapshot.SummaryDataPointSnapshot(count, sum, quantiles, makeLabels(labelValues), Exemplars.EMPTY, 0L)); + }); + return new SummarySnapshot(getMetadata(), dataPoints); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties properties) { + return new Builder(properties); + } + + public static class Builder extends CallbackMetric.Builder { + + private Consumer callback; + + public Builder withCallback(Consumer callback) { + this.callback = callback; + return self(); + } + + private Builder(PrometheusProperties properties) { + super(Collections.singletonList("quantile"), properties); + } + + @Override + public SummaryWithCallback build() { + return new SummaryWithCallback(this); + } + + @Override + protected Builder self() { + return this; + } + } +} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java new file mode 100644 index 000000000..22780819e --- /dev/null +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java @@ -0,0 +1,37 @@ +package io.prometheus.metrics.core.util; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +/** + * Used for scheduling maintenance tasks like purging outdated Exemplars or resetting native histograms. + */ +public class Scheduler { + + private static class DaemonThreadFactory implements ThreadFactory { + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable); + thread.setDaemon(true); + return thread; + } + } + + private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory()); + + public static ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return executor.schedule(command, delay, unit); + } + + /** + * For unit test. Wait until the executor Thread is running. + */ + public static void awaitInitialization() throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + Scheduler.schedule(latch::countDown, 0, TimeUnit.MILLISECONDS); + latch.await(); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java new file mode 100644 index 000000000..c20482e44 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java @@ -0,0 +1,30 @@ +package io.prometheus.metrics.core.exemplars; + +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; + +import java.lang.reflect.Field; + +public class ExemplarSamplerConfigTestUtil { + + private static ExemplarSamplerConfig getConfig(Object metric, String fieldName) throws NoSuchFieldException, IllegalAccessException { + Field configField = metric.getClass().getDeclaredField(fieldName); + configField.setAccessible(true); + return (ExemplarSamplerConfig) configField.get(metric); + } + + private static void setRetentionPeriod(ExemplarSamplerConfig config, String name, long value) throws IllegalAccessException, NoSuchFieldException { + Field field = config.getClass().getDeclaredField(name); + field.setAccessible(true); + field.set(config, value); + } + + public static void setMinRetentionPeriodMillis(Object metric, long value) throws NoSuchFieldException, IllegalAccessException { + ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig"); + setRetentionPeriod(config, "minRetentionPeriodMillis", value); + } + + public static void setSampleIntervalMillis(Object metric, long value) throws NoSuchFieldException, IllegalAccessException { + ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig"); + setRetentionPeriod(config, "sampleIntervalMillis", value); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java new file mode 100644 index 000000000..24882065e --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java @@ -0,0 +1,234 @@ +package io.prometheus.metrics.core.exemplars; + +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.core.util.Scheduler; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ExemplarSamplerTest { + + private final int tick = 10; // Time step in milliseconds. Make this larger if the test is flaky. + private final int sampleInterval = 10 * tick; // do not change this + private final int minAge = 50 * tick; // do not change this + private final int maxAge = 200 * tick; // do not change this + + private ExemplarSamplerConfig makeConfig(double... buckets) { + return new ExemplarSamplerConfig( + minAge, + maxAge, + sampleInterval, + buckets.length == 0 ? 4 : buckets.length, // number of exemplars + buckets.length == 0 ? null : buckets + ); + } + + + private static class SpanContext implements io.prometheus.metrics.tracer.common.SpanContext { + + int callCount = 0; + boolean isSampled = true; + boolean isExemplar = false; + + @Override + public String getCurrentTraceId() { + return "" + (callCount++); + } + + @Override + public String getCurrentSpanId() { + return "" + callCount; + } + + @Override + public boolean isCurrentSpanSampled() { + return isSampled; + } + + @Override + public void markCurrentSpanAsExemplar() { + isExemplar = true; + } + } + + @Test + public void testCustomExemplarsBuckets() throws Exception { + // TODO + } + + private io.prometheus.metrics.tracer.common.SpanContext origContext; + + @Before + public void setUp() { + origContext = SpanContextSupplier.getSpanContext(); + } + + @After + public void tearDown() { + SpanContextSupplier.setSpanContext(origContext); + } + + @Test + public void testIsSampled() throws Exception { + SpanContext context = new SpanContext(); + context.isSampled = false; + SpanContextSupplier.setSpanContext(context); + ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + Thread.sleep(tick); // t = 1 tick + sampler.observe(0.3); // no sampled, because isSampled() returns false + assertExemplars(sampler); // empty + } + + @Test + public void testDefaultConfigHasFourExemplars() throws Exception { + SpanContext context = new SpanContext(); + SpanContextSupplier.setSpanContext(context); + ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + Thread.sleep(tick); // t = 1 tick + sampler.observe(0.3); + Thread.sleep(sampleInterval + tick); // t = 12 tick + sampler.observe(0.8); + Thread.sleep(sampleInterval + tick); // t = 23 tick + sampler.observe(0.4); + Thread.sleep(sampleInterval + tick); // t = 34 tick + sampler.observe(0.6); + Thread.sleep(sampleInterval + tick); // t = 45 tick + sampler.observe(0.2); // not observed, we got 4 Exemplars already and non reached min age + assertExemplars(sampler, 0.3, 0.8, 0.4, 0.6); + print(sampler.collect()); + } + + @Test + public void testEmptyBuckets() throws Exception { + SpanContext context = new SpanContext(); + SpanContextSupplier.setSpanContext(context); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(Double.POSITIVE_INFINITY)); + Thread.sleep(tick); // t = 1 tick + sampler.observe(0.8); // observed in the +Inf bucket + Thread.sleep(sampleInterval + tick); // t = 12 tick + sampler.observe(0.5); // not observed, because +Inf is the only bucket + assertExemplars(sampler, 0.8); + print(sampler.collect()); + } + + @Test + public void testDefaultExemplarsBuckets() throws Exception { + SpanContext context = new SpanContext(); + SpanContextSupplier.setSpanContext(context); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(0.2, 0.4, 0.6, 0.8, 1.0, Double.POSITIVE_INFINITY)); + Scheduler.awaitInitialization(); + Thread.sleep(tick); // t = 1 tick + sampler.observe(0.3); + sampler.observe(0.5); // not observed, previous observation is less than sample interval ms ago + assertExemplars(sampler, 0.3); + Thread.sleep(sampleInterval + tick); // t = 12 ticks + sampler.observe(0.5); // observed + assertExemplars(sampler, 0.3, 0.5); + Thread.sleep(sampleInterval + tick); // t = 23 ticks + sampler.observe(0.4); // not observed, because 0.3 hasn't reached min age yet + assertExemplars(sampler, 0.3, 0.5); + Thread.sleep(sampleInterval + tick); // t = 34 ticks + sampler.observe(1.1); // observed + assertExemplars(sampler, 0.3, 0.5, 1.1); + Thread.sleep(20 * tick); // t = 54 ticks + assertExemplars(sampler, 0.3, 0.5, 1.1); + sampler.observe(0.4); // observed + assertExemplars(sampler, 0.4, 0.5, 1.1); + Thread.sleep(159 * tick); // t = 213 ticks + assertExemplars(sampler, 0.4, 1.1); // 0.5 evicted because it has reached max age + print(sampler.collect()); + } + + @Test + public void testCustomExemplarsNoBuckets() throws Exception { + // TODO + } + + @Test + public void testDefaultExemplarsNoBuckets() throws Exception { + SpanContext context = new SpanContext(); + SpanContextSupplier.setSpanContext(context); + ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + Scheduler.awaitInitialization(); + Thread.sleep(tick); // t = 1 tick + sampler.observe(1); // observed + assertExemplars(sampler, 1); + sampler.observe(2); // not observed, previous observation is less than sample interval ms ago + Thread.sleep(sampleInterval + tick); // t = 12 ticks + sampler.observe(3); // observed + assertExemplars(sampler, 1, 3); + Thread.sleep(2 * tick); // t = 14 ticks + sampler.observe(4); // not observed, previous observation is less than sample interval ms ago + Thread.sleep(sampleInterval + tick); // t = 25 ticks + sampler.observe(5); // observed + assertExemplars(sampler, 1, 3, 5); + Thread.sleep(sampleInterval + tick); // t = 36 ticks + sampler.observe(6); // observed + assertExemplars(sampler, 1, 3, 5, 6); + Thread.sleep(sampleInterval + tick); // t = 47 ticks + sampler.observe(7); // not observed, because no Exemplar has reached the minimum age yet + Thread.sleep(5 * tick); // t = 52 ticks + sampler.observe(2); // not observed. 1 is older than min age, but kept because it's the minimum + assertExemplars(sampler, 1, 3, 5, 6); + Thread.sleep(sampleInterval + tick); // t = 63 ticks + sampler.observe(2); // observed + assertExemplars(sampler, 1, 2, 5, 6); + Thread.sleep(27 * tick); // t = 90 ticks + sampler.observe(7); // observed, replaces 6 because 7 > 6 even though 5 is older + assertExemplars(sampler, 1, 2, 5, 7); + sampler.observe(8); // not observed, sample interval not done + assertExemplars(sampler, 1, 2, 5, 7); + Thread.sleep(sampleInterval + tick); // t = 101 ticks + sampler.observe(8); // observed + assertExemplars(sampler, 1, 2, 8, 7); + Thread.sleep(101 * tick); // t = 202 ticks + sampler.observe(5); // observed, replaces 1 because 1 reached the max age + assertExemplars(sampler, 5, 2, 8, 7); + print(sampler.collect()); + } + + private void assertExemplars(ExemplarSampler sampler, double... values) { + Exemplars exemplars = sampler.collect(); + Assert.assertEquals(values.length, exemplars.size()); + for (double value : values) { + boolean found = false; + for (Exemplar exemplar : exemplars) { + if (exemplar.getValue() == value) { + found = true; + break; + } + } + Assert.assertTrue(value + " not found", found); + } + } + + private void print(Exemplars exemplars) { + System.out.print("["); + boolean farst = true; + for (Exemplar exemplar : exemplars) { + if (!farst) { + System.out.print(","); + } + farst = false; + System.out.print(exemplar.getValue() + "{"); + boolean first = true; + for (Label label : exemplar.getLabels()) { + if (!first) { + System.out.print(","); + } + System.out.print(label.getName() + "=" + label.getValue()); + first = false; + } + if (!first) { + System.out.print(","); + } + System.out.print("age=" + (System.currentTimeMillis() - exemplar.getTimestampMillis())); + System.out.print("}"); + } + System.out.println("]"); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java new file mode 100644 index 000000000..0efa6ee4a --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -0,0 +1,300 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.Unit; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Iterator; + +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.rules.ExpectedException.none; + +public class CounterTest { + + Counter noLabels; + Counter labels; + private static final long exemplarSampleIntervalMillis = 10; + private static final long exemplarMinAgeMillis = 100; + SpanContext origSpanContext; + + @Rule + public final ExpectedException thrown = none(); + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException { + noLabels = Counter.newBuilder().withName("nolabels").build(); + labels = Counter.newBuilder().withName("labels") + .withHelp("help") + .withUnit(Unit.SECONDS) + .withLabelNames("l") + .build(); + origSpanContext = SpanContextSupplier.getSpanContext(); + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(noLabels, exemplarSampleIntervalMillis); + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(noLabels, exemplarMinAgeMillis); + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(labels, exemplarSampleIntervalMillis); + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(labels, exemplarMinAgeMillis); + } + + @After + public void tearDown() { + SpanContextSupplier.setSpanContext(origSpanContext); + } + + private CounterSnapshot.CounterDataPointSnapshot getData(Counter counter, String... labels) { + return counter.collect().getData().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(() -> new RuntimeException("counter with labels " + labels + " not found")); + } + + private double getValue(Counter counter, String... labels) { + return getData(counter, labels).getValue(); + } + + + private int getNumberOfLabels(Counter counter) { + return ((CounterSnapshot) counter.collect()).getData().size(); + } + + @Test + public void testIncrement() { + noLabels.inc(); + assertEquals(1.0, getValue(noLabels), .001); + noLabels.inc(2); + assertEquals(3.0, getValue(noLabels), .001); + noLabels.withLabelValues().inc(4); + assertEquals(7.0, getValue(noLabels), .001); + noLabels.withLabelValues().inc(); + assertEquals(8.0, getValue(noLabels), .001); + } + + @Test + public void testNegativeIncrementFails() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Negative increment -1 is illegal for Counter metrics."); + noLabels.inc(-1); + } + + @Test + public void testEmptyCountersHaveNoLabels() { + assertEquals(1, getNumberOfLabels(noLabels)); + assertEquals(0, getNumberOfLabels(labels)); + } + + @Test + public void testLabels() { + assertEquals(0, getNumberOfLabels(labels)); + labels.withLabelValues("a").inc(); + assertEquals(1, getNumberOfLabels(labels)); + assertEquals(1.0, getValue(labels, "l", "a"), .001); + labels.withLabelValues("b").inc(3); + assertEquals(2, getNumberOfLabels(labels)); + assertEquals(1.0, getValue(labels, "l", "a"), .001); + assertEquals(3.0, getValue(labels, "l", "b"), .001); + } + + @Test + public void testTotalStrippedFromName() { + Counter counter = Counter.newBuilder() + .withName("my_counter_total") + .withUnit(Unit.SECONDS) + .build(); + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); + assertEquals("name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData)); + + counter = Counter.newBuilder() + .withName("my_counter") + .build(); + protobufData = new PrometheusProtobufWriter().convert(counter.collect()); + assertEquals("name: \"my_counter_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData)); + } + + @Test + public void testSnapshotComplete() { + long before = System.currentTimeMillis(); + Counter counter = Counter.newBuilder() + .withName("test_seconds_total") + .withUnit(Unit.SECONDS) + .withHelp("help message") + .withConstLabels(Labels.of("const1name", "const1value", "const2name", "const2value")) + .withLabelNames("path", "status") + .build(); + counter.withLabelValues("/", "200").inc(2); + counter.withLabelValues("/", "500").inc(); + CounterSnapshot snapshot = (CounterSnapshot) counter.collect(); + Assert.assertEquals("test_seconds", snapshot.getMetadata().getName()); + Assert.assertEquals("seconds", snapshot.getMetadata().getUnit().toString()); + Assert.assertEquals("help message", snapshot.getMetadata().getHelp()); + Assert.assertEquals(2, snapshot.getData().size()); + Iterator iter = snapshot.getData().iterator(); + // data is ordered by labels, so 200 comes before 500 + CounterSnapshot.CounterDataPointSnapshot data = iter.next(); + Assert.assertEquals(Labels.of("const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"), data.getLabels()); + Assert.assertEquals(2, data.getValue(), 0.0001); + Assert.assertTrue(data.getCreatedTimestampMillis() >= before); + Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + // 500 + data = iter.next(); + Assert.assertEquals(Labels.of("const1name", "const1value", "const2name", "const2value", "path", "/", "status", "500"), data.getLabels()); + Assert.assertEquals(1, data.getValue(), 0.0001); + Assert.assertTrue(data.getCreatedTimestampMillis() >= before); + Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + } + + @Test + public void testIncWithExemplar() throws Exception { + noLabels.incWithExemplar(Labels.of("key", "value")); + assertExemplar(noLabels, 1.0, "key", "value"); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + noLabels.incWithExemplar(Labels.EMPTY); + assertExemplar(noLabels, 1.0); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + noLabels.incWithExemplar(3, Labels.of("key1", "value1", "key2", "value2")); + assertExemplar(noLabels, 3, "key1", "value1", "key2", "value2"); + } + + private void assertExemplar(Counter counter, double value, String... labels) { + Exemplar exemplar = getData(counter).getExemplar(); + Assert.assertEquals(value, exemplar.getValue(), 0.0001); + assertEquals(Labels.of(labels), exemplar.getLabels()); + } + + @Test + public void testExemplarSampler() throws Exception { + final Exemplar exemplar1 = Exemplar.newBuilder() + .withValue(2.0) + .withTraceId("abc") + .withSpanId("123") + .build(); + final Exemplar exemplar2 = Exemplar.newBuilder() + .withValue(1.0) + .withTraceId("def") + .withSpanId("456") + .build(); + final Exemplar exemplar3 = Exemplar.newBuilder() + .withValue(1.0) + .withTraceId("123") + .withSpanId("abc") + .build(); + final Exemplar customExemplar = Exemplar.newBuilder() + .withValue(1.0) + .withTraceId("bab") + .withSpanId("cdc") + .withLabels(Labels.of("test", "test")) + .build(); + SpanContext spanContext = new SpanContext() { + private int callNumber = 0; + + @Override + public String getCurrentTraceId() { + switch (callNumber) { + case 1: + return "abc"; + case 3: + return "def"; + case 4: + return "123"; + case 5: + return "bab"; + default: + throw new RuntimeException("unexpected call"); + } + } + + @Override + public String getCurrentSpanId() { + switch (callNumber) { + case 1: + return "123"; + case 3: + return "456"; + case 4: + return "abc"; + case 5: + return "cdc"; + default: + throw new RuntimeException("unexpected call"); + } + } + + @Override + public boolean isCurrentSpanSampled() { + callNumber++; + if (callNumber == 2) { + return false; + } + return true; + } + + @Override + public void markCurrentSpanAsExemplar() { + } + }; + Counter counter = Counter.newBuilder() + .withName("count_total") + .build(); + + SpanContextSupplier.setSpanContext(spanContext); + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(counter, exemplarMinAgeMillis); + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(counter, exemplarSampleIntervalMillis); + + counter.inc(2.0); + assertExemplarEquals(exemplar1, getData(counter).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + counter.inc(3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called + assertExemplarEquals(exemplar1, getData(counter).getExemplar()); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + counter.inc(2.0); // 2nd call: isSampled() returns false -> not sampled + assertExemplarEquals(exemplar1, getData(counter).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + counter.inc(1.0); // sampled + assertExemplarEquals(exemplar2, getData(counter).getExemplar()); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + counter.inc(1.0); // sampled + assertExemplarEquals(exemplar3, getData(counter).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + counter.incWithExemplar(Labels.of("test", "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached min age yet + assertExemplarEquals(customExemplar, getData(counter).getExemplar()); + } + + @Test + public void testExemplarSamplerDisabled() { + Counter counter = Counter.newBuilder() + //.withExemplarSampler((inc, prev) -> {throw new RuntimeException("unexpected call to exemplar sampler");}) + .withName("count_total") + .withoutExemplars() + .build(); + counter.incWithExemplar(3.0, Labels.of("a", "b")); + Assert.assertNull(getData(counter).getExemplar()); + counter.inc(2.0); + Assert.assertNull(getData(counter).getExemplar()); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java new file mode 100644 index 000000000..4c437281e --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java @@ -0,0 +1,222 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.core.datapoints.Timer; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; +import static org.junit.Assert.assertEquals; + +public class GaugeTest { + + private static final long exemplarSampleIntervalMillis = 10; + private static final long exemplarMinAgeMillis = 100; + + private Gauge noLabels, labels; + + private SpanContext origSpanContext; + + @Before + public void setUp() { + noLabels = Gauge.newBuilder().withName("nolabels").build(); + labels = Gauge.newBuilder().withName("labels").withLabelNames("l").build(); + origSpanContext = SpanContextSupplier.getSpanContext(); + } + + @After + public void tearDown() { + SpanContextSupplier.setSpanContext(origSpanContext); + } + + private GaugeSnapshot.GaugeDataPointSnapshot getData(Gauge gauge, String... labels) { + return ((GaugeSnapshot) gauge.collect()).getData().stream() + .filter(data -> data.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(RuntimeException::new); + } + + private double getValue(Gauge gauge, String... labels) { + return getData(gauge, labels).getValue(); + } + + @Test + public void testIncrement() { + noLabels.inc(); + assertEquals(1.0, getValue(noLabels), .001); + noLabels.inc(2); + assertEquals(3.0, getValue(noLabels), .001); + noLabels.inc(4); + assertEquals(7.0, getValue(noLabels), .001); + noLabels.inc(); + assertEquals(8.0, getValue(noLabels), .001); + } + + @Test + public void testDecrement() { + noLabels.dec(); + assertEquals(-1.0, getValue(noLabels), .001); + noLabels.dec(2); + assertEquals(-3.0, getValue(noLabels), .001); + noLabels.dec(4); + assertEquals(-7.0, getValue(noLabels), .001); + noLabels.dec(); + assertEquals(-8.0, getValue(noLabels), .001); + } + + @Test + public void testSet() { + noLabels.set(42); + assertEquals(42, getValue(noLabels), .001); + noLabels.set(7); + assertEquals(7.0, getValue(noLabels), .001); + } + + @Test + public void testTimer() throws InterruptedException { + try (Timer timer = noLabels.startTimer()) { + Thread.sleep(12); + } + assertEquals(0.012, getValue(noLabels), 0.005); // 5ms delta should be enough so this isn't flaky + } + + @Test + public void noLabelsDefaultZeroValue() { + assertEquals(0.0, getValue(noLabels), .001); + } + + @Test + public void testLabels() { + labels.withLabelValues("a").inc(); + labels.withLabelValues("b").inc(3); + assertEquals(1.0, getValue(labels, "l", "a"), .001); + assertEquals(3.0, getValue(labels, "l", "b"), .001); + } + + @Test + public void testExemplarSampler() throws Exception { + final Exemplar exemplar1 = Exemplar.newBuilder() + .withValue(2.0) + .withTraceId("abc") + .withSpanId("123") + .build(); + final Exemplar exemplar2 = Exemplar.newBuilder() + .withValue(6.5) + .withTraceId("def") + .withSpanId("456") + .build(); + final Exemplar exemplar3 = Exemplar.newBuilder() + .withValue(7.0) + .withTraceId("123") + .withSpanId("abc") + .build(); + final Exemplar customExemplar = Exemplar.newBuilder() + .withValue(8.0) + .withTraceId("bab") + .withSpanId("cdc") + .withLabels(Labels.of("test", "test")) + .build(); + SpanContext spanContext = new SpanContext() { + private int callNumber = 0; + + @Override + public String getCurrentTraceId() { + switch (callNumber) { + case 1: + return "abc"; + case 3: + return "def"; + case 4: + return "123"; + case 5: + return "bab"; + default: + throw new RuntimeException("unexpected call"); + } + } + + @Override + public String getCurrentSpanId() { + switch (callNumber) { + case 1: + return "123"; + case 3: + return "456"; + case 4: + return "abc"; + case 5: + return "cdc"; + default: + throw new RuntimeException("unexpected call"); + } + } + + @Override + public boolean isCurrentSpanSampled() { + callNumber++; + if (callNumber == 2) { + return false; + } + return true; + } + + @Override + public void markCurrentSpanAsExemplar() { + } + }; + Gauge gauge = Gauge.newBuilder() + .withName("my_gauge") + .build(); + + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(gauge, exemplarMinAgeMillis); + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(gauge, exemplarSampleIntervalMillis); + SpanContextSupplier.setSpanContext(spanContext); + + gauge.inc(2.0); + assertExemplarEquals(exemplar1, getData(gauge).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + gauge.inc(3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called + assertExemplarEquals(exemplar1, getData(gauge).getExemplar()); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + gauge.inc(2.0); // 2nd call: isSampled() returns false -> not sampled + assertExemplarEquals(exemplar1, getData(gauge).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + gauge.dec(0.5); // sampled + assertExemplarEquals(exemplar2, getData(gauge).getExemplar()); + + Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis); + + gauge.set(7.0); // sampled + assertExemplarEquals(exemplar3, getData(gauge).getExemplar()); + + Thread.sleep(2 * exemplarSampleIntervalMillis); + + gauge.incWithExemplar(Labels.of("test", "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached min age yet + assertExemplarEquals(customExemplar, getData(gauge).getExemplar()); + } + + @Test + public void testExemplarSamplerDisabled() { + Gauge gauge = Gauge.newBuilder() + .withName("test") + .withoutExemplars() + .build(); + gauge.setWithExemplar(3.0, Labels.of("a", "b")); + Assert.assertNull(getData(gauge).getExemplar()); + gauge.inc(2.0); + Assert.assertNull(getData(gauge).getExemplar()); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java new file mode 100644 index 000000000..393e2c876 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -0,0 +1,1306 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CompletionService; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; + +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class HistogramTest { + + private static final double RESET_DURATION_REACHED = -123.456; // just a random value indicating that we should simulate that the reset duration has been reached + + private SpanContext origSpanContext; + + @Before + public void setUp() { + origSpanContext = SpanContextSupplier.getSpanContext(); + } + + @After + public void tearDown() { + SpanContextSupplier.setSpanContext(origSpanContext); + } + + /** + * Mimic the tests in client_golang. + */ + private static class GolangTestCase { + final String name; + final String expected; + final Histogram histogram; + final double[] observations; + + private GolangTestCase(String name, String expected, Histogram histogram, double... observations) { + this.name = name; + this.expected = expected; + this.histogram = histogram; + this.observations = observations; + } + + private void run() throws NoSuchFieldException, IllegalAccessException { + System.out.println("Running " + name + "..."); + for (double observation : observations) { + if (observation == RESET_DURATION_REACHED) { + Field resetAllowed = Histogram.DataPoint.class.getDeclaredField("resetDurationExpired"); + resetAllowed.setAccessible(true); + resetAllowed.set(histogram.getNoLabels(), true); + } else { + histogram.observe(observation); + } + } + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(histogram.collect()); + String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; + assertEquals("test \"" + name + "\" failed", expectedWithMetadata, TextFormat.printer().shortDebugString(protobufData)); + } + } + + /** + * Test cases copied from histogram_test.go in client_golang. + */ + @Test + public void testGolangTests() throws NoSuchFieldException, IllegalAccessException { + GolangTestCase[] testCases = new GolangTestCase[]{ + new GolangTestCase("'no sparse buckets' from client_golang", + "sample_count: 3 " + + "sample_sum: 6.0 " + + "bucket { cumulative_count: 0 upper_bound: 0.005 } " + + "bucket { cumulative_count: 0 upper_bound: 0.01 } " + + "bucket { cumulative_count: 0 upper_bound: 0.025 } " + + "bucket { cumulative_count: 0 upper_bound: 0.05 } " + + "bucket { cumulative_count: 0 upper_bound: 0.1 } " + + "bucket { cumulative_count: 0 upper_bound: 0.25 } " + + "bucket { cumulative_count: 0 upper_bound: 0.5 } " + + "bucket { cumulative_count: 1 upper_bound: 1.0 } " + + "bucket { cumulative_count: 2 upper_bound: 2.5 } " + + "bucket { cumulative_count: 3 upper_bound: 5.0 } " + + "bucket { cumulative_count: 3 upper_bound: 10.0 } " + + "bucket { cumulative_count: 3 upper_bound: Infinity }", + Histogram.newBuilder() + .withName("test") + .classicOnly() + .build(), + 1.0, 2.0, 3.0), + new GolangTestCase("'factor 1.1 results in schema 3' from client_golang", + "sample_count: 4 " + + "sample_sum: 6.0 " + + "schema: 3 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 1 } " + + "positive_span { offset: 7 length: 1 } " + + "positive_span { offset: 4 length: 1 } " + + "positive_delta: 1 " + + "positive_delta: 0 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(3) + .withNativeMaxZeroThreshold(0) + .build(), + 0.0, 1.0, 2.0, 3.0), + new GolangTestCase("'factor 1.2 results in schema 2' from client_golang", + "sample_count: 6 " + + "sample_sum: 7.4 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, 1, 1.2, 1.4, 1.8, 2), + new GolangTestCase("'factor 4 results in schema -1' from client_golang", + "sample_count: 14 " + + "sample_sum: 63.2581251 " + + "schema: -1 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: -2 length: 6 } " + + "positive_delta: 2 " + + "positive_delta: 0 " + + "positive_delta: 0 " + + "positive_delta: 2 " + + "positive_delta: -1 " + + "positive_delta: -2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(-1) + .withNativeMaxZeroThreshold(0) + .build(), + 0.0156251, 0.0625, // Bucket -2: (0.015625, 0.0625) + 0.1, 0.25, // Bucket -1: (0.0625, 0.25] + 0.5, 1, // Bucket 0: (0.25, 1] + 1.5, 2, 3, 3.5, // Bucket 1: (1, 4] + 5, 6, 7, // Bucket 2: (4, 16] + 33.33 // Bucket 3: (16, 64] + ), + new GolangTestCase("'factor 17 results in schema -2' from client_golang", + "sample_count: 14 " + + "sample_sum: 63.2581251 " + + "schema: -2 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: -1 length: 4 } " + + "positive_delta: 2 " + + "positive_delta: 2 " + + "positive_delta: 3 " + + "positive_delta: -6", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(-2) + .withNativeMaxZeroThreshold(0) + .build(), + 0.0156251, 0.0625, // Bucket -1: (0.015625, 0.0625] + 0.1, 0.25, 0.5, 1, // Bucket 0: (0.0625, 1] + 1.5, 2, 3, 3.5, 5, 6, 7, // Bucket 1: (1, 16] + 33.33 // Bucket 2: (16, 256] + ), + new GolangTestCase("'negative buckets' from client_golang", + "sample_count: 6 " + + "sample_sum: -7.4 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 5 } " + + "negative_delta: 1 " + + "negative_delta: -1 " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, -1, -1.2, -1.4, -1.8, -2 + ), + new GolangTestCase("'negative and positive buckets' from client_golang", + "sample_count: 11 " + + "sample_sum: 0.0 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 5 } " + + "negative_delta: 1 " + + "negative_delta: -1 " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 2 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2 + ), + new GolangTestCase("'wide zero bucket' from client_golang", + "sample_count: 11 " + + "sample_sum: 0.0 " + + "schema: 2 " + + "zero_threshold: 1.4 " + + "zero_count: 7 " + + "negative_span { offset: 4 length: 1 } " + + "negative_delta: 2 " + + "positive_span { offset: 4 length: 1 } " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMinZeroThreshold(1.4) + .build(), + 0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2 + ), + /* + // See https://github.com/prometheus/client_golang/issues/1275 + new TestCase("'NaN observation' from client_golang", + "sample_count: 7 " + + "sample_sum: NaN " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .asNativeHistogram() + .withNativeSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, 1, 1.2, 1.4, 1.8, 2, Double.NaN + ), + */ + new GolangTestCase("'+Inf observation' from client_golang", + "sample_count: 7 " + + "sample_sum: Infinity " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_span { offset: 4092 length: 1 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2 " + + "positive_delta: -1", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, 1, 1.2, 1.4, 1.8, 2, Double.POSITIVE_INFINITY + ), + new GolangTestCase("'-Inf observation' from client_golang", + "sample_count: 7 " + + "sample_sum: -Infinity " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 4097 length: 1 } " + + "negative_delta: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .build(), + 0, 1, 1.2, 1.4, 1.8, 2, Double.NEGATIVE_INFINITY + ), + new GolangTestCase("'limited buckets but nothing triggered' from client_golang", + "sample_count: 6 " + + "sample_sum: 7.4 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: -1 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.2, 1.4, 1.8, 2 + ), + new GolangTestCase("'buckets limited by halving resolution' from client_golang", + "sample_count: 8 " + + "sample_sum: 11.5 " + + "schema: 1 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 0 length: 5 } " + + "positive_delta: 1 " + + "positive_delta: 2 " + + "positive_delta: -1 " + + "positive_delta: -2 " + + "positive_delta: 1", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3 + ), + new GolangTestCase("'buckets limited by widening the zero bucket' from client_golang", + "sample_count: 8 " + + "sample_sum: 11.5 " + + "schema: 2 " + + "zero_threshold: 1.0 " + + "zero_count: 2 " + + "positive_span { offset: 1 length: 7 } " + + "positive_delta: 1 " + + "positive_delta: 1 " + + "positive_delta: -2 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 0 " + + "positive_delta: 1", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3 + ), + new GolangTestCase("'buckets limited by widening the zero bucket twice' from client_golang", + "sample_count: 9 " + + "sample_sum: 15.5 " + + "schema: 2 " + + "zero_threshold: 1.189207115002721 " + + "zero_count: 3 " + + "positive_span { offset: 2 length: 7 } " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 2 " + + "positive_delta: -2 " + + "positive_delta: 0 " + + "positive_delta: 1 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4), + new GolangTestCase("'buckets limited by reset' from client_golang", + "sample_count: 2 " + + "sample_sum: 7.0 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: 7 length: 2 } " + + "positive_delta: 1 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMinZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, RESET_DURATION_REACHED, 3, 4), + new GolangTestCase("'limited buckets but nothing triggered, negative observations' from client_golang", + "sample_count: 6 " + + "sample_sum: -7.4 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 5 } " + + "negative_delta: 1 " + + "negative_delta: -1 " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 2", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, -1, -1.2, -1.4, -1.8, -2), + new GolangTestCase("'buckets limited by halving resolution, negative observations' from client_golang", + "sample_count: 8 " + + "sample_sum: -11.5 " + + "schema: 1 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 5 } " + + "negative_delta: 1 " + + "negative_delta: 2 " + + "negative_delta: -1 " + + "negative_delta: -2 " + + "negative_delta: 1", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3), + new GolangTestCase("'buckets limited by widening the zero bucket, negative observations' from client_golang", + "sample_count: 8 " + + "sample_sum: -11.5 " + + "schema: 2 " + + "zero_threshold: 1.0 " + + "zero_count: 2 " + + "negative_span { offset: 1 length: 7 } " + + "negative_delta: 1 " + + "negative_delta: 1 " + + "negative_delta: -2 " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 0 " + + "negative_delta: 1", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3), + new GolangTestCase("'buckets limited by widening the zero bucket twice, negative observations' from client_golang", + "sample_count: 9 " + + "sample_sum: -15.5 " + + "schema: 2 " + + "zero_threshold: 1.189207115002721 " + + "zero_count: 3 " + + "negative_span { offset: 2 length: 7 } " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 2 " + + "negative_delta: -2 " + + "negative_delta: 0 " + + "negative_delta: 1 " + + "negative_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4), + new GolangTestCase("'buckets limited by reset, negative observations' from client_golang", + "sample_count: 2 " + + "sample_sum: -7.0 " + + "schema: 2 " + + "zero_threshold: 2.9387358770557188E-39 " + + "zero_count: 0 " + + "negative_span { offset: 7 length: 2 } " + + "negative_delta: 1 " + + "negative_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, -1, -1.1, -1.2, -1.4, -1.8, -2, RESET_DURATION_REACHED, -3, -4), + new GolangTestCase("'buckets limited by halving resolution, then reset' from client_golang", + "sample_count: 2 " + + "sample_sum: 7.0 " + + "schema: 2 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: 7 length: 2 } " + + "positive_delta: 1 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(0) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4), + new GolangTestCase("'buckets limited by widening the zero bucket, then reset' from client_golang", + "sample_count: 2 " + + "sample_sum: 7.0 " + + "schema: 2 " + + "zero_threshold: 2.9387358770557188E-39 " + + "zero_count: 0 " + + "positive_span { offset: 7 length: 2 } " + + "positive_delta: 1 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(2) + .withNativeMaxZeroThreshold(1.2) + .withNativeMaxNumberOfBuckets(4) + .build(), + 0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4) + }; + for (GolangTestCase testCase : testCases) { + testCase.run(); + } + } + + /** + * Additional tests that are not part of client_golang's test suite. + */ + @Test + public void testAdditional() throws NoSuchFieldException, IllegalAccessException { + GolangTestCase[] testCases = new GolangTestCase[]{ + new GolangTestCase("observed values are exactly at bucket boundaries", + "sample_count: 3 " + + "sample_sum: 1.5 " + + "schema: 0 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: -1 length: 2 } " + + "positive_delta: 1 " + + "positive_delta: 0", + Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withNativeInitialSchema(0) + .withNativeMaxZeroThreshold(0) + .build(), + 0.0, 0.5, 1.0) + }; + for (GolangTestCase testCase : testCases) { + testCase.run(); + } + } + + /** + * Tests HistogramData.nativeBucketIndexToUpperBound(int, int). + *

+ * This test is ported from client_golang's TestGetLe(). + */ + @Test + public void testNativeBucketIndexToUpperBound() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + int[] indexes = new int[]{-1, 0, 1, 512, 513, -1, 0, 1, 1024, 1025, -1, 0, 1, 4096, 4097}; + int[] schemas = new int[]{-1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}; + double[] expectedUpperBounds = new double[]{0.25, 1, 4, Double.MAX_VALUE, Double.POSITIVE_INFINITY, + 0.5, 1, 2, Double.MAX_VALUE, Double.POSITIVE_INFINITY, + 0.8408964152537144, 1, 1.189207115002721, Double.MAX_VALUE, Double.POSITIVE_INFINITY}; + Method method = Histogram.DataPoint.class.getDeclaredMethod("nativeBucketIndexToUpperBound", int.class, int.class); + method.setAccessible(true); + for (int i = 0; i < indexes.length; i++) { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withNativeInitialSchema(schemas[i]) + .build(); + Histogram.DataPoint histogramData = histogram.newDataPoint(); + double result = (double) method.invoke(histogramData, schemas[i], indexes[i]); + Assert.assertEquals("index=" + indexes[i] + ", schema=" + schemas[i], expectedUpperBounds[i], result, 0.0000000000001); + } + } + + /** + * Test if lowerBound < value <= upperBound is true for the bucket index returned by findBucketIndex() + */ + @Test + public void testFindBucketIndex() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Random rand = new Random(); + Method findBucketIndex = Histogram.DataPoint.class.getDeclaredMethod("findBucketIndex", double.class); + Method nativeBucketIndexToUpperBound = Histogram.DataPoint.class.getDeclaredMethod("nativeBucketIndexToUpperBound", int.class, int.class); + findBucketIndex.setAccessible(true); + nativeBucketIndexToUpperBound.setAccessible(true); + for (int schema = -4; schema <= 8; schema++) { + Histogram histogram = Histogram.newBuilder() + .nativeOnly() + .withName("test") + .withNativeInitialSchema(schema) + .build(); + for (int i = 0; i < 10_000; i++) { + for (int zeros = -5; zeros <= 10; zeros++) { + double value = rand.nextDouble() * Math.pow(10, zeros); + int bucketIndex = (int) findBucketIndex.invoke(histogram.getNoLabels(), value); + double lowerBound = (double) nativeBucketIndexToUpperBound.invoke(histogram.getNoLabels(), schema, bucketIndex - 1); + double upperBound = (double) nativeBucketIndexToUpperBound.invoke(histogram.getNoLabels(), schema, bucketIndex); + Assert.assertTrue("Bucket index " + bucketIndex + " with schema " + schema + " has range [" + lowerBound + ", " + upperBound + "]. Value " + value + " is outside of that range.", lowerBound < value && upperBound >= value); + } + } + } + } + + @Test + public void testDefaults() throws IOException { + Histogram histogram = Histogram.newBuilder().withName("test").build(); + histogram.observe(0.5); + HistogramSnapshot snapshot = histogram.collect(); + String expectedNative = "" + + "name: \"test\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 1 " + + "sample_sum: 0.5 " + + // default native schema is 5 + "schema: 5 " + + // default zero threshold is 2^-128 + "zero_threshold: " + Math.pow(2.0, -128.0) + " " + + "zero_count: 0 " + + "positive_span { offset: -32 length: 1 } " + + "positive_delta: 1 " + + "} }"; + String expectedClassic = "" + + // default classic buckets + "# TYPE test histogram\n" + + "test_bucket{le=\"0.005\"} 0\n" + + "test_bucket{le=\"0.01\"} 0\n" + + "test_bucket{le=\"0.025\"} 0\n" + + "test_bucket{le=\"0.05\"} 0\n" + + "test_bucket{le=\"0.1\"} 0\n" + + "test_bucket{le=\"0.25\"} 0\n" + + "test_bucket{le=\"0.5\"} 1\n" + + "test_bucket{le=\"1.0\"} 1\n" + + "test_bucket{le=\"2.5\"} 1\n" + + "test_bucket{le=\"5.0\"} 1\n" + + "test_bucket{le=\"10.0\"} 1\n" + + "test_bucket{le=\"+Inf\"} 1\n" + + "test_count 1\n" + + "test_sum 0.5\n" + + "# EOF\n"; + + // protobuf + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); + Assert.assertEquals(expectedNative, TextFormat.printer().shortDebugString(protobufData)); + + // text + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expectedClassic, out.toString()); + } + + @Test + public void testExemplarsClassicHistogram() throws Exception { + SpanContext spanContext = new SpanContext() { + int callCount = 0; + + @Override + public String getCurrentTraceId() { + return "traceId-" + callCount; + } + + @Override + public String getCurrentSpanId() { + return "spanId-" + callCount; + } + + @Override + public boolean isCurrentSpanSampled() { + callCount++; + return true; + } + + @Override + public void markCurrentSpanAsExemplar() { + } + }; + Histogram histogram = Histogram.newBuilder() + .withName("test") + // The default number of Exemplars is 4. + // Use 5 buckets to verify that the exemplar sample is configured with the buckets. + .withClassicBuckets(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY) + .withLabelNames("path") + .build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + SpanContextSupplier.setSpanContext(spanContext); + + Exemplar ex1a = Exemplar.newBuilder() + .withValue(0.5) + .withSpanId("spanId-1") + .withTraceId("traceId-1") + .build(); + Exemplar ex1b = Exemplar.newBuilder() + .withValue(0.5) + .withSpanId("spanId-2") + .withTraceId("traceId-2") + .build(); + Exemplar ex2a = Exemplar.newBuilder() + .withValue(4.5) + .withSpanId("spanId-3") + .withTraceId("traceId-3") + .build(); + Exemplar ex2b = Exemplar.newBuilder() + .withValue(4.5) + .withSpanId("spanId-4") + .withTraceId("traceId-4") + .build(); + Exemplar ex3a = Exemplar.newBuilder() + .withValue(1.5) + .withSpanId("spanId-5") + .withTraceId("traceId-5") + .build(); + Exemplar ex3b = Exemplar.newBuilder() + .withValue(1.5) + .withSpanId("spanId-6") + .withTraceId("traceId-6") + .build(); + Exemplar ex4a = Exemplar.newBuilder() + .withValue(2.5) + .withSpanId("spanId-7") + .withTraceId("traceId-7") + .build(); + Exemplar ex4b = Exemplar.newBuilder() + .withValue(2.5) + .withSpanId("spanId-8") + .withTraceId("traceId-8") + .build(); + Exemplar ex5a = Exemplar.newBuilder() + .withValue(3.5) + .withSpanId("spanId-9") + .withTraceId("traceId-9") + .build(); + Exemplar ex5b = Exemplar.newBuilder() + .withValue(3.5) + .withSpanId("spanId-10") + .withTraceId("traceId-10") + .build(); + histogram.withLabelValues("/hello").observe(0.5); + histogram.withLabelValues("/world").observe(0.5); // different labels are tracked independently, i.e. we don't need to wait for sampleIntervalMillis + + HistogramSnapshot snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 2.0, "path", "/world")); + assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 3.0, "path", "/world")); + assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 4.0, "path", "/world")); + assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Thread.sleep(sampleIntervalMillis + 1); + histogram.withLabelValues("/hello").observe(4.5); + histogram.withLabelValues("/world").observe(4.5); + + snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 2.0, "path", "/world")); + assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 3.0, "path", "/world")); + assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 4.0, "path", "/world")); + assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Thread.sleep(sampleIntervalMillis + 1); + histogram.withLabelValues("/hello").observe(1.5); + histogram.withLabelValues("/world").observe(1.5); + Thread.sleep(sampleIntervalMillis + 1); + histogram.withLabelValues("/hello").observe(2.5); + histogram.withLabelValues("/world").observe(2.5); + Thread.sleep(sampleIntervalMillis + 1); + histogram.withLabelValues("/hello").observe(3.5); + histogram.withLabelValues("/world").observe(3.5); + + snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertExemplarEquals(ex3a, getExemplar(snapshot, 2.0, "path", "/hello")); + assertExemplarEquals(ex3b, getExemplar(snapshot, 2.0, "path", "/world")); + assertExemplarEquals(ex4a, getExemplar(snapshot, 3.0, "path", "/hello")); + assertExemplarEquals(ex4b, getExemplar(snapshot, 3.0, "path", "/world")); + assertExemplarEquals(ex5a, getExemplar(snapshot, 4.0, "path", "/hello")); + assertExemplarEquals(ex5b, getExemplar(snapshot, 4.0, "path", "/world")); + assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Exemplar custom = Exemplar.newBuilder() + .withValue(3.4) + .withLabels(Labels.of("key2", "value2", "key1", "value1", "trace_id", "traceId-11", "span_id", "spanId-11")) + .build(); + Thread.sleep(sampleIntervalMillis + 1); + histogram.withLabelValues("/hello").observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2")); + snapshot = histogram.collect(); + // custom exemplars have preference, so the automatic exemplar is replaced + assertExemplarEquals(custom, getExemplar(snapshot, 4.0, "path", "/hello")); + } + + private Exemplar getExemplar(HistogramSnapshot snapshot, double le, String... labels) { + HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findFirst() + .orElseThrow(() -> new RuntimeException("Labels not found")); + double lowerBound = Double.NEGATIVE_INFINITY; + for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { + if (bucket.getUpperBound() == le) { + break; + } else { + lowerBound = bucket.getUpperBound(); + } + } + return data.getExemplars().get(lowerBound, le); + } + + @Test + public void testCustomExemplarsClassicHistogram() throws InterruptedException, NoSuchFieldException, IllegalAccessException { + + // TODO: This was copied from the old simpleclient, can probably be refactored. + + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withExemplars() + .build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(histogram, 3 * sampleIntervalMillis); + + Labels labels = Labels.of("mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + histogram.observeWithExemplar(0.5, Labels.of("key", "value")); + assertExemplar(histogram, 0.5, "key", "value"); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.5, Labels.EMPTY); + assertExemplar(histogram, 0.5); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.5, labels); + assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + // default buckets are {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(2.0, Labels.of("key1", "value1", "key2", "value2")); + assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); + assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.4, Labels.EMPTY); // same bucket as 0.5 + assertExemplar(histogram, 0.4); + assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); + } + + private void assertExemplar(Histogram histogram, double value, String... labels) { + double lowerBound = Double.NEGATIVE_INFINITY; + double upperBound = Double.POSITIVE_INFINITY; + HistogramSnapshot snapshot = histogram.collect(); + HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream() + .filter(d -> d.getLabels().isEmpty()) + .findFirst() + .orElseThrow(() -> new RuntimeException("No data without labels found")); + for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { + if (bucket.getUpperBound() >= value) { + upperBound = bucket.getUpperBound(); + break; + } else { + lowerBound = bucket.getUpperBound(); + } + } + Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); + Assert.assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); + Assert.assertEquals(value, exemplar.getValue(), 0.0); + Assert.assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); + for (int i = 0; i < labels.length; i += 2) { + Assert.assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); + Assert.assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); + } + } + + + @Test + public void testExemplarsNativeHistogram() throws NoSuchFieldException, IllegalAccessException { + + SpanContext spanContext = new SpanContext() { + int callCount = 0; + + @Override + public String getCurrentTraceId() { + return "traceId-" + callCount; + } + + @Override + public String getCurrentSpanId() { + return "spanId-" + callCount; + } + + @Override + public boolean isCurrentSpanSampled() { + callCount++; + return true; + } + + @Override + public void markCurrentSpanAsExemplar() { + } + }; + Histogram histogram = Histogram.newBuilder() + .withName("test") + .nativeOnly() + .withLabelNames("path") + .build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + SpanContextSupplier.setSpanContext(spanContext); + + Exemplar ex1 = Exemplar.newBuilder() + .withValue(3.11) + .withSpanId("spanId-1") + .withTraceId("traceId-1") + .build(); + Exemplar ex2 = Exemplar.newBuilder() + .withValue(3.12) + .withSpanId("spanId-2") + .withTraceId("traceId-2") + .build(); + Exemplar ex3 = Exemplar.newBuilder() + .withValue(3.13) + .withSpanId("spanId-3") + .withTraceId("traceId-3") + .withLabels(Labels.of("key1", "value1", "key2", "value2")) + .build(); + + histogram.withLabelValues("/hello").observe(3.11); + histogram.withLabelValues("/world").observe(3.12); + assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); + assertEquals(1, getData(histogram, "path", "/world").getExemplars().size()); + assertExemplarEquals(ex2, getData(histogram, "path", "/world").getExemplars().iterator().next()); + + histogram.withLabelValues("/world").observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2")); + assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); + assertEquals(2, getData(histogram, "path", "/world").getExemplars().size()); + Exemplars exemplars = getData(histogram, "path", "/world").getExemplars(); + List exemplarList = new ArrayList<>(exemplars.size()); + for (Exemplar exemplar : exemplars) { + exemplarList.add(exemplar); + } + exemplarList.sort(Comparator.comparingDouble(Exemplar::getValue)); + assertEquals(2, exemplars.size()); + assertExemplarEquals(ex2, exemplarList.get(0)); + assertExemplarEquals(ex3, exemplarList.get(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelName() { + Histogram.newBuilder() + .withName("test") + .withLabelNames("label", "le"); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelNameConstLabels() { + Histogram.newBuilder() + .withName("test") + .withConstLabels(Labels.of("label1", "value1", "le", "0.3")); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelNamePrefix() { + Histogram.newBuilder() + .withName("test") + .withLabelNames("__hello"); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelNameDot() { + // The Prometheus team are investigating to allow dots in future Prometheus versions, but for now it's invalid. + // The reason is that you cannot use illegal label names in the Prometheus query language. + Histogram.newBuilder() + .withName("test") + .withLabelNames("http.status"); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalName() { + Histogram.newBuilder() + .withName("server.durations"); + } + + @Test(expected = IllegalArgumentException.class) + public void testNoName() { + Histogram.newBuilder().build(); + } + + @Test(expected = NullPointerException.class) + public void testNullName() { + Histogram.newBuilder() + .withName(null); + } + + @Test + public void testDuplicateClassicBuckets() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withClassicBuckets(0, 3, 17, 3, 21) + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testUnsortedBuckets() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withClassicBuckets(0.2, 0.1) + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testEmptyBuckets() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withClassicBuckets() + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testBucketsIncludePositiveInfinity() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withClassicBuckets(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY) + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testLinearBuckets() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withClassicLinearBuckets(0.1, 0.1, 10) + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testExponentialBuckets() { + Histogram histogram = Histogram.newBuilder() + .withClassicExponentialBuckets(2, 2.5, 3) + .withName("test") + .build(); + List upperBounds = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + assertEquals(Arrays.asList(2.0, 5.0, 12.5, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test(expected = RuntimeException.class) + public void testBucketsIncludeNaN() { + Histogram.newBuilder() + .withName("test") + .withClassicBuckets(0.01, 0.1, 1.0, Double.NaN); + } + + @Test + public void testNoLabelsDefaultZeroValue() { + Histogram noLabels = Histogram.newBuilder().withName("test").build(); + assertEquals(0.0, getBucket(noLabels, 0.005).getCount(), 0.0); + assertEquals(0, getData(noLabels).getCount()); + assertEquals(0.0, getData(noLabels).getSum(), 0.0); + } + + private ClassicHistogramBucket getBucket(Histogram histogram, double le, String... labels) { + return getData(histogram, labels).getClassicBuckets().stream() + .filter(b -> b.getUpperBound() == le) + .findAny() + .orElseThrow(() -> new RuntimeException("bucket with le=" + le + " not found.")); + } + + @Test + public void testObserve() { + Histogram noLabels = Histogram.newBuilder() + .withName("test") + .build(); + noLabels.observe(2); + assertEquals(1, getData(noLabels).getCount()); + assertEquals(2.0, getData(noLabels).getSum(), .0); + assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); + noLabels.observe(4); + assertEquals(2.0, getData(noLabels).getCount(), .0); + assertEquals(6.0, getData(noLabels).getSum(), .0); + assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 5).getCount(), .0); + assertEquals(0.0, getBucket(noLabels, 10).getCount(), .0); + assertEquals(0.0, getBucket(noLabels, Double.POSITIVE_INFINITY).getCount(), .0); + } + + @Test + // See https://github.com/prometheus/client_java/issues/646 + public void testNegativeAmount() { + Histogram histogram = Histogram.newBuilder() + .withName("histogram") + .withHelp("test histogram for negative values") + .withClassicBuckets(-10, -5, 0, 5, 10) + .build(); + double expectedCount = 0; + double expectedSum = 0; + for (int i = 10; i >= -11; i--) { + histogram.observe(i); + expectedCount++; + expectedSum += i; + assertEquals(expectedSum, getData(histogram).getSum(), .001); + assertEquals(expectedCount, getData(histogram).getCount(), .001); + } + List expectedBucketCounts = Arrays.asList(2L, 5L, 5L, 5L, 5L, 0L); // buckets -10, -5, 0, 5, 10, +Inf + List actualBucketCounts = getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getCount) + .collect(Collectors.toList()); + assertEquals(expectedBucketCounts, actualBucketCounts); + } + + @Test + public void testBoundaryConditions() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .build(); + histogram.observe(2.5); + assertEquals(0, getBucket(histogram, 1).getCount()); + assertEquals(1, getBucket(histogram, 2.5).getCount()); + + histogram.observe(Double.POSITIVE_INFINITY); + assertEquals(0, getBucket(histogram, 1).getCount()); + assertEquals(1, getBucket(histogram, 2.5).getCount()); + assertEquals(0, getBucket(histogram, 5).getCount()); + assertEquals(0, getBucket(histogram, 10).getCount()); + assertEquals(1, getBucket(histogram, Double.POSITIVE_INFINITY).getCount()); + } + + @Test + public void testObserveWithLabels() { + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withConstLabels(Labels.of("env", "prod")) + .withLabelNames("path", "status") + .build(); + histogram.withLabelValues("/hello", "200").observe(0.11); + histogram.withLabelValues("/hello", "200").observe(0.2); + histogram.withLabelValues("/hello", "500").observe(0.19); + HistogramSnapshot.HistogramDataPointSnapshot data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); + HistogramSnapshot.HistogramDataPointSnapshot data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); + assertEquals(2, data200.getCount()); + assertEquals(0.31, data200.getSum(), 0.0000001); + assertEquals(1, data500.getCount()); + assertEquals(0.19, data500.getSum(), 0.0000001); + histogram.withLabelValues("/hello", "200").observe(0.13); + data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); + data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); + assertEquals(3, data200.getCount()); + assertEquals(0.44, data200.getSum(), 0.0000001); + assertEquals(1, data500.getCount()); + assertEquals(0.19, data500.getSum(), 0.0000001); + } + + @Test + public void testObserveMultithreaded() throws InterruptedException, ExecutionException, TimeoutException { + // Hard to test concurrency, but let's run a couple of observations in parallel and assert none gets lost. + Histogram histogram = Histogram.newBuilder() + .withName("test") + .withLabelNames("status") + .build(); + int nThreads = 8; + DistributionDataPoint obs = histogram.withLabelValues("200"); + ExecutorService executor = Executors.newFixedThreadPool(nThreads); + CompletionService> completionService = new ExecutorCompletionService<>(executor); + CountDownLatch startSignal = new CountDownLatch(nThreads); + for (int t = 0; t < nThreads; t++) { + completionService.submit(() -> { + List snapshots = new ArrayList<>(); + startSignal.countDown(); + startSignal.await(); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 1000; j++) { + obs.observe(1.1); + } + snapshots.add(histogram.collect()); + } + return snapshots; + }); + } + long maxCount = 0; + for (int i = 0; i < nThreads; i++) { + Future> future = completionService.take(); + List snapshots = future.get(5, TimeUnit.SECONDS); + long count = 0; + for (HistogramSnapshot snapshot : snapshots) { + Assert.assertEquals(1, snapshot.getData().size()); + HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream().findFirst().orElseThrow(RuntimeException::new); + Assert.assertTrue(data.getCount() >= (count + 1000)); // 1000 own observations plus the ones from other threads + count = data.getCount(); + } + if (count > maxCount) { + maxCount = count; + } + } + Assert.assertEquals(nThreads * 10_000, maxCount); // the last collect() has seen all observations + Assert.assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); + executor.shutdown(); + Assert.assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); + } + + + private HistogramSnapshot.HistogramDataPointSnapshot getData(Histogram histogram, String... labels) { + return histogram.collect().getData().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java new file mode 100644 index 000000000..4cca37ef6 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -0,0 +1,23 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import org.junit.Assert; +import org.junit.Test; + +public class InfoTest { + + @Test + public void testIncrement() { + Info info = Info.newBuilder() + .withName("target_info") + .withLabelNames("key") + .build(); + info.infoLabelValues("value"); + InfoSnapshot snapshot = info.collect(); + Assert.assertEquals("target", snapshot.getMetadata().getName()); + Assert.assertEquals(1, snapshot.getData().size()); + InfoSnapshot.InfoDataPointSnapshot data = snapshot.getData().stream().findAny().orElseThrow(RuntimeException::new); + Assert.assertEquals(Labels.of("key", "value"), data.getLabels()); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java new file mode 100644 index 000000000..1babd430c --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java @@ -0,0 +1,75 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import org.junit.Assert; +import org.junit.Test; + +public class StateSetTest { + + enum MyFeatureFlag { + EXPERIMENTAL_FEATURE_1 { + @Override + public String toString() { + return "feature1"; + } + }, + + EXPERIMENTAL_FEATURE_2 { + @Override + public String toString() { + return "feature2"; + } + } + } + + @Test + public void testEnumStateSet() { + StateSet stateSet = StateSet.newBuilder() + .withName("feature_flags") + .withLabelNames("environment") + .withStates(MyFeatureFlag.class) + .build(); + stateSet.withLabelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); + stateSet.withLabelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); + StateSetSnapshot snapshot = stateSet.collect(); + Assert.assertEquals(2, snapshot.getData().size()); + Assert.assertEquals(2, getData(stateSet, "environment", "dev").size()); + Assert.assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); + Assert.assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); + Assert.assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); + Assert.assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); + Assert.assertEquals(2, getData(stateSet, "environment", "prod").size()); + Assert.assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); + Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(0)); + Assert.assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); + Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(1)); + } + + @Test + public void testDefaultFalse() { + StateSet stateSet = StateSet.newBuilder() + .withName("test") + .withStates("state1", "state2", "state3") + .build(); + Assert.assertEquals(3, getData(stateSet).size()); + Assert.assertEquals("state1", getData(stateSet).getName(0)); + Assert.assertFalse(getData(stateSet).isTrue(0)); + Assert.assertEquals("state2", getData(stateSet).getName(1)); + Assert.assertFalse(getData(stateSet).isTrue(1)); + Assert.assertEquals("state3", getData(stateSet).getName(2)); + Assert.assertFalse(getData(stateSet).isTrue(2)); + } + + private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) { + return stateSet.collect().getData().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(() -> new RuntimeException("stateset with labels " + labels + " not found")); + } + + @Test(expected = IllegalStateException.class) + public void testStatesCannotBeEmpty() { + StateSet.newBuilder().withName("invalid").build(); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java new file mode 100644 index 000000000..3b947e73e --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -0,0 +1,36 @@ +package io.prometheus.metrics.core.metrics; + +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.Map; + +public class StatefulMetricTest { + + @Test + public void testLabelRemoveWhileCollecting() throws Exception { + Counter counter = Counter.newBuilder().withName("test").withLabelNames("label1", "label2").build(); + Field data = counter.getClass().getSuperclass().getDeclaredField("data"); + data.setAccessible(true); + + counter.withLabelValues("a", "b").inc(1.0); + counter.withLabelValues("c", "d").inc(3.0); + counter.withLabelValues("e", "f").inc(7.0); + + // collect() iterates over data.entrySet(). + // remove() removes entries from data. + // Make sure iterating does not yield null while removing. + + int i = 0; + for (Map.Entry entry : ((Map) data.get(counter)).entrySet()) { + i++; + if (i == 2) { + counter.remove("c", "d"); + counter.remove("e", "f"); + } + Assert.assertNotNull(entry.getKey()); + Assert.assertNotNull(entry.getValue()); + } + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java new file mode 100644 index 000000000..489bcac33 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java @@ -0,0 +1,13 @@ +package io.prometheus.metrics.core.metrics; + +import io.prometheus.metrics.model.snapshots.Exemplar; +import org.junit.Assert; + +public class TestUtil { + + public static void assertExemplarEquals(Exemplar expected, Exemplar actual) { + // ignore timestamp + Assert.assertEquals(expected.getValue(), actual.getValue(), 0.00001); + Assert.assertEquals(expected.getLabels(), actual.getLabels()); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java new file mode 100644 index 000000000..996e199db --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java @@ -0,0 +1,17 @@ +package io.prometheus.metrics.core.metrics; + +public class TodoTest { + + // if a metric with labels is created but never used it has no data. + // The registry's collect() method should skip those metrics to avoid illegal protobuf or text format. + + // callback versions of metrics + + // build() called with name == null + + // call inc() without labels, but the metric was created with labels + + // call inc() with labels, but the metric was created without labels + + // for performance: Use return value of withLabels() directly +} diff --git a/prometheus-metrics-core/version-rules.xml b/prometheus-metrics-core/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-core/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml new file mode 100644 index 000000000..a6038dd91 --- /dev/null +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-exporter-servlet-jakarta + bundle + + Prometheus Metrics Exporter Servlet Jakarta + + Jakarta Servlet for exposing a Prometheus scrape endpoint. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-model + ${project.version} + + + io.prometheus + prometheus-metrics-exposition-formats + ${project.version} + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + provided + + + + diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java new file mode 100644 index 000000000..ef3656875 --- /dev/null +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java @@ -0,0 +1,89 @@ +package io.prometheus.metrics.exporter.servlet.jakarta; + +import io.prometheus.metrics.config.ExporterFilterProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.expositionformats.ExpositionFormatWriter; +import io.prometheus.metrics.expositionformats.ExpositionFormats; +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.function.Predicate; + +/** + * Initial example exporter so that we can try the new metrics library out. + *

+ * We'll add a Jakarta servlet, the built-in HTTPServer, etc. soon, and likely move common code into a common module. + */ +public class PrometheusMetricsServlet extends HttpServlet { + + private final PrometheusRegistry registry; + + private final ExpositionFormats expositionFormats; + private final Predicate nameFilter; + + public PrometheusMetricsServlet() { + this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); + } + + public PrometheusMetricsServlet(PrometheusRegistry registry) { + this(PrometheusProperties.get(), registry); + } + + public PrometheusMetricsServlet(PrometheusProperties config) { + this(config, PrometheusRegistry.defaultRegistry); + } + + public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) { + this.expositionFormats = ExpositionFormats.init(config.getExporterProperties()); + this.registry = registry; + this.nameFilter = makeNameFilter(config.getExporterFilterProperties()); + } + + private static Predicate makeNameFilter(ExporterFilterProperties props) { + if (props.getAllowedNames() == null && props.getExcludedNames() == null && props.getAllowedPrefixes() == null && props.getExcludedPrefixes() == null) { + return null; + } else { + return MetricNameFilter.newBuilder() + .nameMustBeEqualTo(props.getAllowedNames()) + .nameMustNotBeEqualTo(props.getExcludedNames()) + .nameMustStartWith(props.getAllowedPrefixes()) + .nameMustNotStartWith(props.getExcludedPrefixes()) + .build(); + } + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + Predicate filter = nameFilter; + String[] allowedNames = request.getParameterValues("name[]"); + if (allowedNames != null) { + filter = filter.and(MetricNameFilter.newBuilder().nameMustBeEqualTo(allowedNames).build()); + } + String debugParam = request.getParameter("debug"); + if (debugParam != null) { + switch (debugParam) { + case "openmetrics": + response.setContentType("text/plain"); + expositionFormats.getOpenMetricsTextFormatWriter().write(response.getOutputStream(), registry.scrape(filter)); + return; + case "text": + response.setContentType("text/plain"); + expositionFormats.getPrometheusTextFormatWriter().write(response.getOutputStream(), registry.scrape(filter)); + return; + case "prometheus-protobuf": + response.setContentType("text/plain"); + String debugString = expositionFormats.getPrometheusProtobufWriter().toDebugString(registry.scrape(filter)); + response.getWriter().write(debugString); + return; + } + } + String acceptHeader = request.getHeader("Accept"); + ExpositionFormatWriter writer = expositionFormats.findWriter(acceptHeader); + response.setContentType(writer.getContentType()); + writer.write(response.getOutputStream(), registry.scrape(filter)); + } +} diff --git a/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml b/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml new file mode 100644 index 000000000..318e865f5 --- /dev/null +++ b/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^8].* + + + + diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh new file mode 100755 index 000000000..e61d58055 --- /dev/null +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# We use the shaded protobuf JAR from the protobuf-shaded module. +# I could not figure out how to use a protoc Maven plugin to use the shaded module, so I ran this command to generate the sources manually. + +# The version string must be the same as in protobuf-shaded/pom.xml. +export PROTOBUF_VERSION_STRING="3_21_7" + +rm -rf src/main/protobuf/* +curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/prometheus/client/metrics.proto -o src/main/protobuf/metrics.proto +sed -i "s/java_package = \"io.prometheus.client\"/java_package = \"io.prometheus.metrics.expositionformats.generated.com_google_protobuf_${PROTOBUF_VERSION_STRING}\"/" src/main/protobuf/metrics.proto +rm -rf src/main/generated/* +protoc --java_out src/main/generated src/main/protobuf/metrics.proto +sed -i "s/com\\.google\\.protobuf/io.prometheus.com_google_protobuf_${PROTOBUF_VERSION_STRING}/g" "src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_${PROTOBUF_VERSION_STRING}/Metrics.java" diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml new file mode 100644 index 000000000..9de57e88c --- /dev/null +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-exposition-formats + bundle + + Prometheus Metrics Exposition Formats + + Prometheus exposition formats. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-model + ${project.version} + + + io.prometheus + prometheus-metrics-config + ${project.version} + + + io.prometheus + protobuf-shaded + ${project.version} + + + + + junit + junit + 4.13.2 + test + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + add-source + generate-sources + + add-source + + + + src/main/generated/ + + + + + + + + diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java new file mode 100644 index 000000000..94e92a1f3 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java @@ -0,0 +1,14221 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: src/main/protobuf/metrics.proto + +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7; + +public final class Metrics { + private Metrics() {} + public static void registerAllExtensions( + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistry registry) { + registerAllExtensions( + (io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite) registry); + } + /** + * Protobuf enum {@code io.prometheus.client.MetricType} + */ + public enum MetricType + implements io.prometheus.metrics.com_google_protobuf_3_21_7.ProtocolMessageEnum { + /** + *

+     * COUNTER must use the Metric field "counter".
+     * 
+ * + * COUNTER = 0; + */ + COUNTER(0), + /** + *
+     * GAUGE must use the Metric field "gauge".
+     * 
+ * + * GAUGE = 1; + */ + GAUGE(1), + /** + *
+     * SUMMARY must use the Metric field "summary".
+     * 
+ * + * SUMMARY = 2; + */ + SUMMARY(2), + /** + *
+     * UNTYPED must use the Metric field "untyped".
+     * 
+ * + * UNTYPED = 3; + */ + UNTYPED(3), + /** + *
+     * HISTOGRAM must use the Metric field "histogram".
+     * 
+ * + * HISTOGRAM = 4; + */ + HISTOGRAM(4), + /** + *
+     * GAUGE_HISTOGRAM must use the Metric field "histogram".
+     * 
+ * + * GAUGE_HISTOGRAM = 5; + */ + GAUGE_HISTOGRAM(5), + ; + + /** + *
+     * COUNTER must use the Metric field "counter".
+     * 
+ * + * COUNTER = 0; + */ + public static final int COUNTER_VALUE = 0; + /** + *
+     * GAUGE must use the Metric field "gauge".
+     * 
+ * + * GAUGE = 1; + */ + public static final int GAUGE_VALUE = 1; + /** + *
+     * SUMMARY must use the Metric field "summary".
+     * 
+ * + * SUMMARY = 2; + */ + public static final int SUMMARY_VALUE = 2; + /** + *
+     * UNTYPED must use the Metric field "untyped".
+     * 
+ * + * UNTYPED = 3; + */ + public static final int UNTYPED_VALUE = 3; + /** + *
+     * HISTOGRAM must use the Metric field "histogram".
+     * 
+ * + * HISTOGRAM = 4; + */ + public static final int HISTOGRAM_VALUE = 4; + /** + *
+     * GAUGE_HISTOGRAM must use the Metric field "histogram".
+     * 
+ * + * GAUGE_HISTOGRAM = 5; + */ + public static final int GAUGE_HISTOGRAM_VALUE = 5; + + + public final int getNumber() { + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static MetricType valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static MetricType forNumber(int value) { + switch (value) { + case 0: return COUNTER; + case 1: return GAUGE; + case 2: return SUMMARY; + case 3: return UNTYPED; + case 4: return HISTOGRAM; + case 5: return GAUGE_HISTOGRAM; + default: return null; + } + } + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap< + MetricType> internalValueMap = + new io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap() { + public MetricType findValueByNumber(int number) { + return MetricType.forNumber(number); + } + }; + + public final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.getDescriptor().getEnumTypes().get(0); + } + + private static final MetricType[] VALUES = values(); + + public static MetricType valueOf( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private MetricType(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:io.prometheus.client.MetricType) + } + + public interface LabelPairOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.LabelPair) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + boolean hasName(); + /** + * optional string name = 1; + * @return The name. + */ + java.lang.String getName(); + /** + * optional string name = 1; + * @return The bytes for name. + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes(); + + /** + * optional string value = 2; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional string value = 2; + * @return The value. + */ + java.lang.String getValue(); + /** + * optional string value = 2; + * @return The bytes for value. + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getValueBytes(); + } + /** + * Protobuf type {@code io.prometheus.client.LabelPair} + */ + public static final class LabelPair extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.LabelPair) + LabelPairOrBuilder { + private static final long serialVersionUID = 0L; + // Use LabelPair.newBuilder() to construct. + private LabelPair(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private LabelPair() { + name_ = ""; + value_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new LabelPair(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder.class); + } + + private int bitField0_; + public static final int NAME_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object name_ = ""; + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + @java.lang.Override + public boolean hasName() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional string name = 1; + * @return The name. + */ + @java.lang.Override + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * optional string name = 1; + * @return The bytes for name. + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + + public static final int VALUE_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile java.lang.Object value_ = ""; + /** + * optional string value = 2; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string value = 2; + * @return The value. + */ + @java.lang.Override + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } + } + /** + * optional string value = 2; + * @return The bytes for value. + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof java.lang.String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_); + } + if (((bitField0_ & 0x00000002) != 0)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, value_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, value_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair) obj; + + if (hasName() != other.hasName()) return false; + if (hasName()) { + if (!getName() + .equals(other.getName())) return false; + } + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (!getValue() + .equals(other.getValue())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasName()) { + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + } + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + getValue().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.LabelPair} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + name_ = ""; + value_ = ""; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.name_ = name_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()) return this; + if (other.hasName()) { + name_ = other.name_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (other.hasValue()) { + value_ = other.value_; + bitField0_ |= 0x00000002; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + name_ = input.readBytes(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + value_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional string name = 1; + * @return The name. + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + * @return The bytes for name. + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + /** + * optional string name = 1; + * @param value The name to set. + * @return This builder for chaining. + */ + public Builder setName( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional string name = 1; + * @return This builder for chaining. + */ + public Builder clearName() { + name_ = getDefaultInstance().getName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * optional string name = 1; + * @param value The bytes for name to set. + * @return This builder for chaining. + */ + public Builder setNameBytes( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) { + if (value == null) { throw new NullPointerException(); } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private java.lang.Object value_ = ""; + /** + * optional string value = 2; + * @return Whether the value field is set. + */ + public boolean hasValue() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string value = 2; + * @return The value. + */ + public java.lang.String getValue() { + java.lang.Object ref = value_; + if (!(ref instanceof java.lang.String)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + value_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string value = 2; + * @return The bytes for value. + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getValueBytes() { + java.lang.Object ref = value_; + if (ref instanceof String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + value_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + /** + * optional string value = 2; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + value_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional string value = 2; + * @return This builder for chaining. + */ + public Builder clearValue() { + value_ = getDefaultInstance().getValue(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + * optional string value = 2; + * @param value The bytes for value to set. + * @return This builder for chaining. + */ + public Builder setValueBytes( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) { + if (value == null) { throw new NullPointerException(); } + value_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.LabelPair) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public LabelPair parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GaugeOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Gauge) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional double value = 1; + * @return The value. + */ + double getValue(); + } + /** + * Protobuf type {@code io.prometheus.client.Gauge} + */ + public static final class Gauge extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Gauge) + GaugeOrBuilder { + private static final long serialVersionUID = 0L; + // Use Gauge.newBuilder() to construct. + private Gauge(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Gauge() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Gauge(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder.class); + } + + private int bitField0_; + public static final int VALUE_FIELD_NUMBER = 1; + private double value_ = 0D; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeDouble(1, value_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(1, value_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge) obj; + + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (java.lang.Double.doubleToLongBits(getValue()) + != java.lang.Double.doubleToLongBits( + other.getValue())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getValue())); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Gauge} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + value_ = 0D; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000001; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance()) return this; + if (other.hasValue()) { + setValue(other.getValue()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: { + value_ = input.readDouble(); + bitField0_ |= 0x00000001; + break; + } // case 9 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private double value_ ; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + /** + * optional double value = 1; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue(double value) { + + value_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional double value = 1; + * @return This builder for chaining. + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000001); + value_ = 0D; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Gauge) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Gauge parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CounterOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Counter) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional double value = 1; + * @return The value. + */ + double getValue(); + + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return Whether the exemplar field is set. + */ + boolean hasExemplar(); + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return The exemplar. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar(); + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + } + /** + * Protobuf type {@code io.prometheus.client.Counter} + */ + public static final class Counter extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Counter) + CounterOrBuilder { + private static final long serialVersionUID = 0L; + // Use Counter.newBuilder() to construct. + private Counter(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Counter() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Counter(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder.class); + } + + private int bitField0_; + public static final int VALUE_FIELD_NUMBER = 1; + private double value_ = 0D; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + + public static final int EXEMPLAR_FIELD_NUMBER = 2; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_; + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return Whether the exemplar field is set. + */ + @java.lang.Override + public boolean hasExemplar() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return The exemplar. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeDouble(1, value_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(2, getExemplar()); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(1, value_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(2, getExemplar()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter) obj; + + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (java.lang.Double.doubleToLongBits(getValue()) + != java.lang.Double.doubleToLongBits( + other.getValue())) return false; + } + if (hasExemplar() != other.hasExemplar()) return false; + if (hasExemplar()) { + if (!getExemplar() + .equals(other.getExemplar())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getValue())); + } + if (hasExemplar()) { + hash = (37 * hash) + EXEMPLAR_FIELD_NUMBER; + hash = (53 * hash) + getExemplar().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Counter} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getExemplarFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + value_ = 0D; + exemplar_ = null; + if (exemplarBuilder_ != null) { + exemplarBuilder_.dispose(); + exemplarBuilder_ = null; + } + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.exemplar_ = exemplarBuilder_ == null + ? exemplar_ + : exemplarBuilder_.build(); + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance()) return this; + if (other.hasValue()) { + setValue(other.getValue()); + } + if (other.hasExemplar()) { + mergeExemplar(other.getExemplar()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: { + value_ = input.readDouble(); + bitField0_ |= 0x00000001; + break; + } // case 9 + case 18: { + input.readMessage( + getExemplarFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000002; + break; + } // case 18 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private double value_ ; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + /** + * optional double value = 1; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue(double value) { + + value_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional double value = 1; + * @return This builder for chaining. + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000001); + value_ = 0D; + onChanged(); + return this; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_; + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return Whether the exemplar field is set. + */ + public boolean hasExemplar() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + * @return The exemplar. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() { + if (exemplarBuilder_ == null) { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } else { + return exemplarBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) { + if (exemplarBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + exemplar_ = value; + } else { + exemplarBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public Builder setExemplar( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder builderForValue) { + if (exemplarBuilder_ == null) { + exemplar_ = builderForValue.build(); + } else { + exemplarBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) { + if (exemplarBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + exemplar_ != null && + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) { + getExemplarBuilder().mergeFrom(value); + } else { + exemplar_ = value; + } + } else { + exemplarBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public Builder clearExemplar() { + bitField0_ = (bitField0_ & ~0x00000002); + exemplar_ = null; + if (exemplarBuilder_ != null) { + exemplarBuilder_.dispose(); + exemplarBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder getExemplarBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getExemplarFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + if (exemplarBuilder_ != null) { + return exemplarBuilder_.getMessageOrBuilder(); + } else { + return exemplar_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 2; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> + getExemplarFieldBuilder() { + if (exemplarBuilder_ == null) { + exemplarBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>( + getExemplar(), + getParentForChildren(), + isClean()); + exemplar_ = null; + } + return exemplarBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Counter) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Counter parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface QuantileOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Quantile) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional double quantile = 1; + * @return Whether the quantile field is set. + */ + boolean hasQuantile(); + /** + * optional double quantile = 1; + * @return The quantile. + */ + double getQuantile(); + + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional double value = 2; + * @return The value. + */ + double getValue(); + } + /** + * Protobuf type {@code io.prometheus.client.Quantile} + */ + public static final class Quantile extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Quantile) + QuantileOrBuilder { + private static final long serialVersionUID = 0L; + // Use Quantile.newBuilder() to construct. + private Quantile(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Quantile() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Quantile(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder.class); + } + + private int bitField0_; + public static final int QUANTILE_FIELD_NUMBER = 1; + private double quantile_ = 0D; + /** + * optional double quantile = 1; + * @return Whether the quantile field is set. + */ + @java.lang.Override + public boolean hasQuantile() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double quantile = 1; + * @return The quantile. + */ + @java.lang.Override + public double getQuantile() { + return quantile_; + } + + public static final int VALUE_FIELD_NUMBER = 2; + private double value_ = 0D; + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional double value = 2; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeDouble(1, quantile_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeDouble(2, value_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(1, quantile_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(2, value_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile) obj; + + if (hasQuantile() != other.hasQuantile()) return false; + if (hasQuantile()) { + if (java.lang.Double.doubleToLongBits(getQuantile()) + != java.lang.Double.doubleToLongBits( + other.getQuantile())) return false; + } + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (java.lang.Double.doubleToLongBits(getValue()) + != java.lang.Double.doubleToLongBits( + other.getValue())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasQuantile()) { + hash = (37 * hash) + QUANTILE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getQuantile())); + } + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getValue())); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Quantile} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + quantile_ = 0D; + value_ = 0D; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.quantile_ = quantile_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance()) return this; + if (other.hasQuantile()) { + setQuantile(other.getQuantile()); + } + if (other.hasValue()) { + setValue(other.getValue()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: { + quantile_ = input.readDouble(); + bitField0_ |= 0x00000001; + break; + } // case 9 + case 17: { + value_ = input.readDouble(); + bitField0_ |= 0x00000002; + break; + } // case 17 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private double quantile_ ; + /** + * optional double quantile = 1; + * @return Whether the quantile field is set. + */ + @java.lang.Override + public boolean hasQuantile() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double quantile = 1; + * @return The quantile. + */ + @java.lang.Override + public double getQuantile() { + return quantile_; + } + /** + * optional double quantile = 1; + * @param value The quantile to set. + * @return This builder for chaining. + */ + public Builder setQuantile(double value) { + + quantile_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional double quantile = 1; + * @return This builder for chaining. + */ + public Builder clearQuantile() { + bitField0_ = (bitField0_ & ~0x00000001); + quantile_ = 0D; + onChanged(); + return this; + } + + private double value_ ; + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional double value = 2; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + /** + * optional double value = 2; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue(double value) { + + value_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional double value = 2; + * @return This builder for chaining. + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000002); + value_ = 0D; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Quantile) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Quantile parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface SummaryOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Summary) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + boolean hasSampleCount(); + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + long getSampleCount(); + + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + boolean hasSampleSum(); + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + double getSampleSum(); + + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + java.util.List + getQuantileList(); + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index); + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + int getQuantileCount(); + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + java.util.List + getQuantileOrBuilderList(); + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder( + int index); + } + /** + * Protobuf type {@code io.prometheus.client.Summary} + */ + public static final class Summary extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Summary) + SummaryOrBuilder { + private static final long serialVersionUID = 0L; + // Use Summary.newBuilder() to construct. + private Summary(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Summary() { + quantile_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Summary(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder.class); + } + + private int bitField0_; + public static final int SAMPLE_COUNT_FIELD_NUMBER = 1; + private long sampleCount_ = 0L; + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + @java.lang.Override + public boolean hasSampleCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + @java.lang.Override + public long getSampleCount() { + return sampleCount_; + } + + public static final int SAMPLE_SUM_FIELD_NUMBER = 2; + private double sampleSum_ = 0D; + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + @java.lang.Override + public boolean hasSampleSum() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + @java.lang.Override + public double getSampleSum() { + return sampleSum_; + } + + public static final int QUANTILE_FIELD_NUMBER = 3; + @SuppressWarnings("serial") + private java.util.List quantile_; + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + @java.lang.Override + public java.util.List getQuantileList() { + return quantile_; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + @java.lang.Override + public java.util.List + getQuantileOrBuilderList() { + return quantile_; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + @java.lang.Override + public int getQuantileCount() { + return quantile_.size(); + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index) { + return quantile_.get(index); + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder( + int index) { + return quantile_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeUInt64(1, sampleCount_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeDouble(2, sampleSum_); + } + for (int i = 0; i < quantile_.size(); i++) { + output.writeMessage(3, quantile_.get(i)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeUInt64Size(1, sampleCount_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(2, sampleSum_); + } + for (int i = 0; i < quantile_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(3, quantile_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary) obj; + + if (hasSampleCount() != other.hasSampleCount()) return false; + if (hasSampleCount()) { + if (getSampleCount() + != other.getSampleCount()) return false; + } + if (hasSampleSum() != other.hasSampleSum()) return false; + if (hasSampleSum()) { + if (java.lang.Double.doubleToLongBits(getSampleSum()) + != java.lang.Double.doubleToLongBits( + other.getSampleSum())) return false; + } + if (!getQuantileList() + .equals(other.getQuantileList())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSampleCount()) { + hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + getSampleCount()); + } + if (hasSampleSum()) { + hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getSampleSum())); + } + if (getQuantileCount() > 0) { + hash = (37 * hash) + QUANTILE_FIELD_NUMBER; + hash = (53 * hash) + getQuantileList().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Summary} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + sampleCount_ = 0L; + sampleSum_ = 0D; + if (quantileBuilder_ == null) { + quantile_ = java.util.Collections.emptyList(); + } else { + quantile_ = null; + quantileBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result) { + if (quantileBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0)) { + quantile_ = java.util.Collections.unmodifiableList(quantile_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.quantile_ = quantile_; + } else { + result.quantile_ = quantileBuilder_.build(); + } + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.sampleCount_ = sampleCount_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.sampleSum_ = sampleSum_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance()) return this; + if (other.hasSampleCount()) { + setSampleCount(other.getSampleCount()); + } + if (other.hasSampleSum()) { + setSampleSum(other.getSampleSum()); + } + if (quantileBuilder_ == null) { + if (!other.quantile_.isEmpty()) { + if (quantile_.isEmpty()) { + quantile_ = other.quantile_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureQuantileIsMutable(); + quantile_.addAll(other.quantile_); + } + onChanged(); + } + } else { + if (!other.quantile_.isEmpty()) { + if (quantileBuilder_.isEmpty()) { + quantileBuilder_.dispose(); + quantileBuilder_ = null; + quantile_ = other.quantile_; + bitField0_ = (bitField0_ & ~0x00000004); + quantileBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getQuantileFieldBuilder() : null; + } else { + quantileBuilder_.addAllMessages(other.quantile_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + sampleCount_ = input.readUInt64(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 17: { + sampleSum_ = input.readDouble(); + bitField0_ |= 0x00000002; + break; + } // case 17 + case 26: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.PARSER, + extensionRegistry); + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + quantile_.add(m); + } else { + quantileBuilder_.addMessage(m); + } + break; + } // case 26 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private long sampleCount_ ; + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + @java.lang.Override + public boolean hasSampleCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + @java.lang.Override + public long getSampleCount() { + return sampleCount_; + } + /** + * optional uint64 sample_count = 1; + * @param value The sampleCount to set. + * @return This builder for chaining. + */ + public Builder setSampleCount(long value) { + + sampleCount_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional uint64 sample_count = 1; + * @return This builder for chaining. + */ + public Builder clearSampleCount() { + bitField0_ = (bitField0_ & ~0x00000001); + sampleCount_ = 0L; + onChanged(); + return this; + } + + private double sampleSum_ ; + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + @java.lang.Override + public boolean hasSampleSum() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + @java.lang.Override + public double getSampleSum() { + return sampleSum_; + } + /** + * optional double sample_sum = 2; + * @param value The sampleSum to set. + * @return This builder for chaining. + */ + public Builder setSampleSum(double value) { + + sampleSum_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional double sample_sum = 2; + * @return This builder for chaining. + */ + public Builder clearSampleSum() { + bitField0_ = (bitField0_ & ~0x00000002); + sampleSum_ = 0D; + onChanged(); + return this; + } + + private java.util.List quantile_ = + java.util.Collections.emptyList(); + private void ensureQuantileIsMutable() { + if (!((bitField0_ & 0x00000004) != 0)) { + quantile_ = new java.util.ArrayList(quantile_); + bitField0_ |= 0x00000004; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> quantileBuilder_; + + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public java.util.List getQuantileList() { + if (quantileBuilder_ == null) { + return java.util.Collections.unmodifiableList(quantile_); + } else { + return quantileBuilder_.getMessageList(); + } + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public int getQuantileCount() { + if (quantileBuilder_ == null) { + return quantile_.size(); + } else { + return quantileBuilder_.getCount(); + } + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index) { + if (quantileBuilder_ == null) { + return quantile_.get(index); + } else { + return quantileBuilder_.getMessage(index); + } + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder setQuantile( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) { + if (quantileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureQuantileIsMutable(); + quantile_.set(index, value); + onChanged(); + } else { + quantileBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder setQuantile( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) { + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + quantile_.set(index, builderForValue.build()); + onChanged(); + } else { + quantileBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) { + if (quantileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureQuantileIsMutable(); + quantile_.add(value); + onChanged(); + } else { + quantileBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder addQuantile( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) { + if (quantileBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureQuantileIsMutable(); + quantile_.add(index, value); + onChanged(); + } else { + quantileBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder addQuantile( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) { + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + quantile_.add(builderForValue.build()); + onChanged(); + } else { + quantileBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder addQuantile( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) { + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + quantile_.add(index, builderForValue.build()); + onChanged(); + } else { + quantileBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder addAllQuantile( + java.lang.Iterable values) { + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, quantile_); + onChanged(); + } else { + quantileBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder clearQuantile() { + if (quantileBuilder_ == null) { + quantile_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + } else { + quantileBuilder_.clear(); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public Builder removeQuantile(int index) { + if (quantileBuilder_ == null) { + ensureQuantileIsMutable(); + quantile_.remove(index); + onChanged(); + } else { + quantileBuilder_.remove(index); + } + return this; + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder getQuantileBuilder( + int index) { + return getQuantileFieldBuilder().getBuilder(index); + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder( + int index) { + if (quantileBuilder_ == null) { + return quantile_.get(index); } else { + return quantileBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public java.util.List + getQuantileOrBuilderList() { + if (quantileBuilder_ != null) { + return quantileBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(quantile_); + } + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder addQuantileBuilder() { + return getQuantileFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder addQuantileBuilder( + int index) { + return getQuantileFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.Quantile quantile = 3; + */ + public java.util.List + getQuantileBuilderList() { + return getQuantileFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> + getQuantileFieldBuilder() { + if (quantileBuilder_ == null) { + quantileBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder>( + quantile_, + ((bitField0_ & 0x00000004) != 0), + getParentForChildren(), + isClean()); + quantile_ = null; + } + return quantileBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Summary) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Summary parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface UntypedOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Untyped) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional double value = 1; + * @return The value. + */ + double getValue(); + } + /** + * Protobuf type {@code io.prometheus.client.Untyped} + */ + public static final class Untyped extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Untyped) + UntypedOrBuilder { + private static final long serialVersionUID = 0L; + // Use Untyped.newBuilder() to construct. + private Untyped(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Untyped() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Untyped(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder.class); + } + + private int bitField0_; + public static final int VALUE_FIELD_NUMBER = 1; + private double value_ = 0D; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeDouble(1, value_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(1, value_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped) obj; + + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (java.lang.Double.doubleToLongBits(getValue()) + != java.lang.Double.doubleToLongBits( + other.getValue())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getValue())); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Untyped} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + value_ = 0D; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000001; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance()) return this; + if (other.hasValue()) { + setValue(other.getValue()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 9: { + value_ = input.readDouble(); + bitField0_ |= 0x00000001; + break; + } // case 9 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private double value_ ; + /** + * optional double value = 1; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 1; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + /** + * optional double value = 1; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue(double value) { + + value_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional double value = 1; + * @return This builder for chaining. + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000001); + value_ = 0D; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Untyped) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Untyped parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface HistogramOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Histogram) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + boolean hasSampleCount(); + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + long getSampleCount(); + + /** + *
+     * Overrides sample_count if > 0.
+     * 
+ * + * optional double sample_count_float = 4; + * @return Whether the sampleCountFloat field is set. + */ + boolean hasSampleCountFloat(); + /** + *
+     * Overrides sample_count if > 0.
+     * 
+ * + * optional double sample_count_float = 4; + * @return The sampleCountFloat. + */ + double getSampleCountFloat(); + + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + boolean hasSampleSum(); + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + double getSampleSum(); + + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + java.util.List + getBucketList(); + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index); + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + int getBucketCount(); + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + java.util.List + getBucketOrBuilderList(); + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder( + int index); + + /** + *
+     * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+     * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+     * then each power of two is divided into 2^n logarithmic buckets.
+     * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+     * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+     * 
+ * + * optional sint32 schema = 5; + * @return Whether the schema field is set. + */ + boolean hasSchema(); + /** + *
+     * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+     * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+     * then each power of two is divided into 2^n logarithmic buckets.
+     * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+     * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+     * 
+ * + * optional sint32 schema = 5; + * @return The schema. + */ + int getSchema(); + + /** + *
+     * Breadth of the zero bucket.
+     * 
+ * + * optional double zero_threshold = 6; + * @return Whether the zeroThreshold field is set. + */ + boolean hasZeroThreshold(); + /** + *
+     * Breadth of the zero bucket.
+     * 
+ * + * optional double zero_threshold = 6; + * @return The zeroThreshold. + */ + double getZeroThreshold(); + + /** + *
+     * Count in zero bucket.
+     * 
+ * + * optional uint64 zero_count = 7; + * @return Whether the zeroCount field is set. + */ + boolean hasZeroCount(); + /** + *
+     * Count in zero bucket.
+     * 
+ * + * optional uint64 zero_count = 7; + * @return The zeroCount. + */ + long getZeroCount(); + + /** + *
+     * Overrides sb_zero_count if > 0.
+     * 
+ * + * optional double zero_count_float = 8; + * @return Whether the zeroCountFloat field is set. + */ + boolean hasZeroCountFloat(); + /** + *
+     * Overrides sb_zero_count if > 0.
+     * 
+ * + * optional double zero_count_float = 8; + * @return The zeroCountFloat. + */ + double getZeroCountFloat(); + + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + java.util.List + getNegativeSpanList(); + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index); + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + int getNegativeSpanCount(); + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + java.util.List + getNegativeSpanOrBuilderList(); + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder( + int index); + + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @return A list containing the negativeDelta. + */ + java.util.List getNegativeDeltaList(); + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @return The count of negativeDelta. + */ + int getNegativeDeltaCount(); + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @param index The index of the element to return. + * @return The negativeDelta at the given index. + */ + long getNegativeDelta(int index); + + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @return A list containing the negativeCount. + */ + java.util.List getNegativeCountList(); + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @return The count of negativeCount. + */ + int getNegativeCountCount(); + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @param index The index of the element to return. + * @return The negativeCount at the given index. + */ + double getNegativeCount(int index); + + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + java.util.List + getPositiveSpanList(); + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index); + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + int getPositiveSpanCount(); + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + java.util.List + getPositiveSpanOrBuilderList(); + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder( + int index); + + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @return A list containing the positiveDelta. + */ + java.util.List getPositiveDeltaList(); + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @return The count of positiveDelta. + */ + int getPositiveDeltaCount(); + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @param index The index of the element to return. + * @return The positiveDelta at the given index. + */ + long getPositiveDelta(int index); + + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @return A list containing the positiveCount. + */ + java.util.List getPositiveCountList(); + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @return The count of positiveCount. + */ + int getPositiveCountCount(); + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @param index The index of the element to return. + * @return The positiveCount at the given index. + */ + double getPositiveCount(int index); + } + /** + * Protobuf type {@code io.prometheus.client.Histogram} + */ + public static final class Histogram extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Histogram) + HistogramOrBuilder { + private static final long serialVersionUID = 0L; + // Use Histogram.newBuilder() to construct. + private Histogram(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Histogram() { + bucket_ = java.util.Collections.emptyList(); + negativeSpan_ = java.util.Collections.emptyList(); + negativeDelta_ = emptyLongList(); + negativeCount_ = emptyDoubleList(); + positiveSpan_ = java.util.Collections.emptyList(); + positiveDelta_ = emptyLongList(); + positiveCount_ = emptyDoubleList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Histogram(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder.class); + } + + private int bitField0_; + public static final int SAMPLE_COUNT_FIELD_NUMBER = 1; + private long sampleCount_ = 0L; + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + @java.lang.Override + public boolean hasSampleCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + @java.lang.Override + public long getSampleCount() { + return sampleCount_; + } + + public static final int SAMPLE_COUNT_FLOAT_FIELD_NUMBER = 4; + private double sampleCountFloat_ = 0D; + /** + *
+     * Overrides sample_count if > 0.
+     * 
+ * + * optional double sample_count_float = 4; + * @return Whether the sampleCountFloat field is set. + */ + @java.lang.Override + public boolean hasSampleCountFloat() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Overrides sample_count if > 0.
+     * 
+ * + * optional double sample_count_float = 4; + * @return The sampleCountFloat. + */ + @java.lang.Override + public double getSampleCountFloat() { + return sampleCountFloat_; + } + + public static final int SAMPLE_SUM_FIELD_NUMBER = 2; + private double sampleSum_ = 0D; + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + @java.lang.Override + public boolean hasSampleSum() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + @java.lang.Override + public double getSampleSum() { + return sampleSum_; + } + + public static final int BUCKET_FIELD_NUMBER = 3; + @SuppressWarnings("serial") + private java.util.List bucket_; + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + @java.lang.Override + public java.util.List getBucketList() { + return bucket_; + } + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + @java.lang.Override + public java.util.List + getBucketOrBuilderList() { + return bucket_; + } + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + @java.lang.Override + public int getBucketCount() { + return bucket_.size(); + } + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index) { + return bucket_.get(index); + } + /** + *
+     * Buckets for the conventional histogram.
+     * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder( + int index) { + return bucket_.get(index); + } + + public static final int SCHEMA_FIELD_NUMBER = 5; + private int schema_ = 0; + /** + *
+     * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+     * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+     * then each power of two is divided into 2^n logarithmic buckets.
+     * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+     * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+     * 
+ * + * optional sint32 schema = 5; + * @return Whether the schema field is set. + */ + @java.lang.Override + public boolean hasSchema() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + *
+     * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+     * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+     * then each power of two is divided into 2^n logarithmic buckets.
+     * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+     * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+     * 
+ * + * optional sint32 schema = 5; + * @return The schema. + */ + @java.lang.Override + public int getSchema() { + return schema_; + } + + public static final int ZERO_THRESHOLD_FIELD_NUMBER = 6; + private double zeroThreshold_ = 0D; + /** + *
+     * Breadth of the zero bucket.
+     * 
+ * + * optional double zero_threshold = 6; + * @return Whether the zeroThreshold field is set. + */ + @java.lang.Override + public boolean hasZeroThreshold() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + *
+     * Breadth of the zero bucket.
+     * 
+ * + * optional double zero_threshold = 6; + * @return The zeroThreshold. + */ + @java.lang.Override + public double getZeroThreshold() { + return zeroThreshold_; + } + + public static final int ZERO_COUNT_FIELD_NUMBER = 7; + private long zeroCount_ = 0L; + /** + *
+     * Count in zero bucket.
+     * 
+ * + * optional uint64 zero_count = 7; + * @return Whether the zeroCount field is set. + */ + @java.lang.Override + public boolean hasZeroCount() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + *
+     * Count in zero bucket.
+     * 
+ * + * optional uint64 zero_count = 7; + * @return The zeroCount. + */ + @java.lang.Override + public long getZeroCount() { + return zeroCount_; + } + + public static final int ZERO_COUNT_FLOAT_FIELD_NUMBER = 8; + private double zeroCountFloat_ = 0D; + /** + *
+     * Overrides sb_zero_count if > 0.
+     * 
+ * + * optional double zero_count_float = 8; + * @return Whether the zeroCountFloat field is set. + */ + @java.lang.Override + public boolean hasZeroCountFloat() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + *
+     * Overrides sb_zero_count if > 0.
+     * 
+ * + * optional double zero_count_float = 8; + * @return The zeroCountFloat. + */ + @java.lang.Override + public double getZeroCountFloat() { + return zeroCountFloat_; + } + + public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9; + @SuppressWarnings("serial") + private java.util.List negativeSpan_; + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + @java.lang.Override + public java.util.List getNegativeSpanList() { + return negativeSpan_; + } + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + @java.lang.Override + public java.util.List + getNegativeSpanOrBuilderList() { + return negativeSpan_; + } + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + @java.lang.Override + public int getNegativeSpanCount() { + return negativeSpan_.size(); + } + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index) { + return negativeSpan_.get(index); + } + /** + *
+     * Negative buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder( + int index) { + return negativeSpan_.get(index); + } + + public static final int NEGATIVE_DELTA_FIELD_NUMBER = 10; + @SuppressWarnings("serial") + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_; + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @return A list containing the negativeDelta. + */ + @java.lang.Override + public java.util.List + getNegativeDeltaList() { + return negativeDelta_; + } + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @return The count of negativeDelta. + */ + public int getNegativeDeltaCount() { + return negativeDelta_.size(); + } + /** + *
+     * Use either "negative_delta" or "negative_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 negative_delta = 10; + * @param index The index of the element to return. + * @return The negativeDelta at the given index. + */ + public long getNegativeDelta(int index) { + return negativeDelta_.getLong(index); + } + + public static final int NEGATIVE_COUNT_FIELD_NUMBER = 11; + @SuppressWarnings("serial") + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_; + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @return A list containing the negativeCount. + */ + @java.lang.Override + public java.util.List + getNegativeCountList() { + return negativeCount_; + } + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @return The count of negativeCount. + */ + public int getNegativeCountCount() { + return negativeCount_.size(); + } + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double negative_count = 11; + * @param index The index of the element to return. + * @return The negativeCount at the given index. + */ + public double getNegativeCount(int index) { + return negativeCount_.getDouble(index); + } + + public static final int POSITIVE_SPAN_FIELD_NUMBER = 12; + @SuppressWarnings("serial") + private java.util.List positiveSpan_; + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + @java.lang.Override + public java.util.List getPositiveSpanList() { + return positiveSpan_; + } + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + @java.lang.Override + public java.util.List + getPositiveSpanOrBuilderList() { + return positiveSpan_; + } + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + @java.lang.Override + public int getPositiveSpanCount() { + return positiveSpan_.size(); + } + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index) { + return positiveSpan_.get(index); + } + /** + *
+     * Positive buckets for the native histogram.
+     * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder( + int index) { + return positiveSpan_.get(index); + } + + public static final int POSITIVE_DELTA_FIELD_NUMBER = 13; + @SuppressWarnings("serial") + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_; + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @return A list containing the positiveDelta. + */ + @java.lang.Override + public java.util.List + getPositiveDeltaList() { + return positiveDelta_; + } + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @return The count of positiveDelta. + */ + public int getPositiveDeltaCount() { + return positiveDelta_.size(); + } + /** + *
+     * Use either "positive_delta" or "positive_count", the former for
+     * regular histograms with integer counts, the latter for float
+     * histograms.
+     * 
+ * + * repeated sint64 positive_delta = 13; + * @param index The index of the element to return. + * @return The positiveDelta at the given index. + */ + public long getPositiveDelta(int index) { + return positiveDelta_.getLong(index); + } + + public static final int POSITIVE_COUNT_FIELD_NUMBER = 14; + @SuppressWarnings("serial") + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_; + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @return A list containing the positiveCount. + */ + @java.lang.Override + public java.util.List + getPositiveCountList() { + return positiveCount_; + } + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @return The count of positiveCount. + */ + public int getPositiveCountCount() { + return positiveCount_.size(); + } + /** + *
+     * Absolute count of each bucket.
+     * 
+ * + * repeated double positive_count = 14; + * @param index The index of the element to return. + * @return The positiveCount at the given index. + */ + public double getPositiveCount(int index) { + return positiveCount_.getDouble(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeUInt64(1, sampleCount_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeDouble(2, sampleSum_); + } + for (int i = 0; i < bucket_.size(); i++) { + output.writeMessage(3, bucket_.get(i)); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeDouble(4, sampleCountFloat_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeSInt32(5, schema_); + } + if (((bitField0_ & 0x00000010) != 0)) { + output.writeDouble(6, zeroThreshold_); + } + if (((bitField0_ & 0x00000020) != 0)) { + output.writeUInt64(7, zeroCount_); + } + if (((bitField0_ & 0x00000040) != 0)) { + output.writeDouble(8, zeroCountFloat_); + } + for (int i = 0; i < negativeSpan_.size(); i++) { + output.writeMessage(9, negativeSpan_.get(i)); + } + for (int i = 0; i < negativeDelta_.size(); i++) { + output.writeSInt64(10, negativeDelta_.getLong(i)); + } + for (int i = 0; i < negativeCount_.size(); i++) { + output.writeDouble(11, negativeCount_.getDouble(i)); + } + for (int i = 0; i < positiveSpan_.size(); i++) { + output.writeMessage(12, positiveSpan_.get(i)); + } + for (int i = 0; i < positiveDelta_.size(); i++) { + output.writeSInt64(13, positiveDelta_.getLong(i)); + } + for (int i = 0; i < positiveCount_.size(); i++) { + output.writeDouble(14, positiveCount_.getDouble(i)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeUInt64Size(1, sampleCount_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(2, sampleSum_); + } + for (int i = 0; i < bucket_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(3, bucket_.get(i)); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(4, sampleCountFloat_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeSInt32Size(5, schema_); + } + if (((bitField0_ & 0x00000010) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(6, zeroThreshold_); + } + if (((bitField0_ & 0x00000020) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeUInt64Size(7, zeroCount_); + } + if (((bitField0_ & 0x00000040) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(8, zeroCountFloat_); + } + for (int i = 0; i < negativeSpan_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(9, negativeSpan_.get(i)); + } + { + int dataSize = 0; + for (int i = 0; i < negativeDelta_.size(); i++) { + dataSize += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeSInt64SizeNoTag(negativeDelta_.getLong(i)); + } + size += dataSize; + size += 1 * getNegativeDeltaList().size(); + } + { + int dataSize = 0; + dataSize = 8 * getNegativeCountList().size(); + size += dataSize; + size += 1 * getNegativeCountList().size(); + } + for (int i = 0; i < positiveSpan_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(12, positiveSpan_.get(i)); + } + { + int dataSize = 0; + for (int i = 0; i < positiveDelta_.size(); i++) { + dataSize += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeSInt64SizeNoTag(positiveDelta_.getLong(i)); + } + size += dataSize; + size += 1 * getPositiveDeltaList().size(); + } + { + int dataSize = 0; + dataSize = 8 * getPositiveCountList().size(); + size += dataSize; + size += 1 * getPositiveCountList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram) obj; + + if (hasSampleCount() != other.hasSampleCount()) return false; + if (hasSampleCount()) { + if (getSampleCount() + != other.getSampleCount()) return false; + } + if (hasSampleCountFloat() != other.hasSampleCountFloat()) return false; + if (hasSampleCountFloat()) { + if (java.lang.Double.doubleToLongBits(getSampleCountFloat()) + != java.lang.Double.doubleToLongBits( + other.getSampleCountFloat())) return false; + } + if (hasSampleSum() != other.hasSampleSum()) return false; + if (hasSampleSum()) { + if (java.lang.Double.doubleToLongBits(getSampleSum()) + != java.lang.Double.doubleToLongBits( + other.getSampleSum())) return false; + } + if (!getBucketList() + .equals(other.getBucketList())) return false; + if (hasSchema() != other.hasSchema()) return false; + if (hasSchema()) { + if (getSchema() + != other.getSchema()) return false; + } + if (hasZeroThreshold() != other.hasZeroThreshold()) return false; + if (hasZeroThreshold()) { + if (java.lang.Double.doubleToLongBits(getZeroThreshold()) + != java.lang.Double.doubleToLongBits( + other.getZeroThreshold())) return false; + } + if (hasZeroCount() != other.hasZeroCount()) return false; + if (hasZeroCount()) { + if (getZeroCount() + != other.getZeroCount()) return false; + } + if (hasZeroCountFloat() != other.hasZeroCountFloat()) return false; + if (hasZeroCountFloat()) { + if (java.lang.Double.doubleToLongBits(getZeroCountFloat()) + != java.lang.Double.doubleToLongBits( + other.getZeroCountFloat())) return false; + } + if (!getNegativeSpanList() + .equals(other.getNegativeSpanList())) return false; + if (!getNegativeDeltaList() + .equals(other.getNegativeDeltaList())) return false; + if (!getNegativeCountList() + .equals(other.getNegativeCountList())) return false; + if (!getPositiveSpanList() + .equals(other.getPositiveSpanList())) return false; + if (!getPositiveDeltaList() + .equals(other.getPositiveDeltaList())) return false; + if (!getPositiveCountList() + .equals(other.getPositiveCountList())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSampleCount()) { + hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + getSampleCount()); + } + if (hasSampleCountFloat()) { + hash = (37 * hash) + SAMPLE_COUNT_FLOAT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getSampleCountFloat())); + } + if (hasSampleSum()) { + hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getSampleSum())); + } + if (getBucketCount() > 0) { + hash = (37 * hash) + BUCKET_FIELD_NUMBER; + hash = (53 * hash) + getBucketList().hashCode(); + } + if (hasSchema()) { + hash = (37 * hash) + SCHEMA_FIELD_NUMBER; + hash = (53 * hash) + getSchema(); + } + if (hasZeroThreshold()) { + hash = (37 * hash) + ZERO_THRESHOLD_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getZeroThreshold())); + } + if (hasZeroCount()) { + hash = (37 * hash) + ZERO_COUNT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + getZeroCount()); + } + if (hasZeroCountFloat()) { + hash = (37 * hash) + ZERO_COUNT_FLOAT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getZeroCountFloat())); + } + if (getNegativeSpanCount() > 0) { + hash = (37 * hash) + NEGATIVE_SPAN_FIELD_NUMBER; + hash = (53 * hash) + getNegativeSpanList().hashCode(); + } + if (getNegativeDeltaCount() > 0) { + hash = (37 * hash) + NEGATIVE_DELTA_FIELD_NUMBER; + hash = (53 * hash) + getNegativeDeltaList().hashCode(); + } + if (getNegativeCountCount() > 0) { + hash = (37 * hash) + NEGATIVE_COUNT_FIELD_NUMBER; + hash = (53 * hash) + getNegativeCountList().hashCode(); + } + if (getPositiveSpanCount() > 0) { + hash = (37 * hash) + POSITIVE_SPAN_FIELD_NUMBER; + hash = (53 * hash) + getPositiveSpanList().hashCode(); + } + if (getPositiveDeltaCount() > 0) { + hash = (37 * hash) + POSITIVE_DELTA_FIELD_NUMBER; + hash = (53 * hash) + getPositiveDeltaList().hashCode(); + } + if (getPositiveCountCount() > 0) { + hash = (37 * hash) + POSITIVE_COUNT_FIELD_NUMBER; + hash = (53 * hash) + getPositiveCountList().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Histogram} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + sampleCount_ = 0L; + sampleCountFloat_ = 0D; + sampleSum_ = 0D; + if (bucketBuilder_ == null) { + bucket_ = java.util.Collections.emptyList(); + } else { + bucket_ = null; + bucketBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + schema_ = 0; + zeroThreshold_ = 0D; + zeroCount_ = 0L; + zeroCountFloat_ = 0D; + if (negativeSpanBuilder_ == null) { + negativeSpan_ = java.util.Collections.emptyList(); + } else { + negativeSpan_ = null; + negativeSpanBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000100); + negativeDelta_ = emptyLongList(); + negativeCount_ = emptyDoubleList(); + if (positiveSpanBuilder_ == null) { + positiveSpan_ = java.util.Collections.emptyList(); + } else { + positiveSpan_ = null; + positiveSpanBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000800); + positiveDelta_ = emptyLongList(); + positiveCount_ = emptyDoubleList(); + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result) { + if (bucketBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0)) { + bucket_ = java.util.Collections.unmodifiableList(bucket_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.bucket_ = bucket_; + } else { + result.bucket_ = bucketBuilder_.build(); + } + if (negativeSpanBuilder_ == null) { + if (((bitField0_ & 0x00000100) != 0)) { + negativeSpan_ = java.util.Collections.unmodifiableList(negativeSpan_); + bitField0_ = (bitField0_ & ~0x00000100); + } + result.negativeSpan_ = negativeSpan_; + } else { + result.negativeSpan_ = negativeSpanBuilder_.build(); + } + if (((bitField0_ & 0x00000200) != 0)) { + negativeDelta_.makeImmutable(); + bitField0_ = (bitField0_ & ~0x00000200); + } + result.negativeDelta_ = negativeDelta_; + if (((bitField0_ & 0x00000400) != 0)) { + negativeCount_.makeImmutable(); + bitField0_ = (bitField0_ & ~0x00000400); + } + result.negativeCount_ = negativeCount_; + if (positiveSpanBuilder_ == null) { + if (((bitField0_ & 0x00000800) != 0)) { + positiveSpan_ = java.util.Collections.unmodifiableList(positiveSpan_); + bitField0_ = (bitField0_ & ~0x00000800); + } + result.positiveSpan_ = positiveSpan_; + } else { + result.positiveSpan_ = positiveSpanBuilder_.build(); + } + if (((bitField0_ & 0x00001000) != 0)) { + positiveDelta_.makeImmutable(); + bitField0_ = (bitField0_ & ~0x00001000); + } + result.positiveDelta_ = positiveDelta_; + if (((bitField0_ & 0x00002000) != 0)) { + positiveCount_.makeImmutable(); + bitField0_ = (bitField0_ & ~0x00002000); + } + result.positiveCount_ = positiveCount_; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.sampleCount_ = sampleCount_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.sampleCountFloat_ = sampleCountFloat_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.sampleSum_ = sampleSum_; + to_bitField0_ |= 0x00000004; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.schema_ = schema_; + to_bitField0_ |= 0x00000008; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.zeroThreshold_ = zeroThreshold_; + to_bitField0_ |= 0x00000010; + } + if (((from_bitField0_ & 0x00000040) != 0)) { + result.zeroCount_ = zeroCount_; + to_bitField0_ |= 0x00000020; + } + if (((from_bitField0_ & 0x00000080) != 0)) { + result.zeroCountFloat_ = zeroCountFloat_; + to_bitField0_ |= 0x00000040; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance()) return this; + if (other.hasSampleCount()) { + setSampleCount(other.getSampleCount()); + } + if (other.hasSampleCountFloat()) { + setSampleCountFloat(other.getSampleCountFloat()); + } + if (other.hasSampleSum()) { + setSampleSum(other.getSampleSum()); + } + if (bucketBuilder_ == null) { + if (!other.bucket_.isEmpty()) { + if (bucket_.isEmpty()) { + bucket_ = other.bucket_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureBucketIsMutable(); + bucket_.addAll(other.bucket_); + } + onChanged(); + } + } else { + if (!other.bucket_.isEmpty()) { + if (bucketBuilder_.isEmpty()) { + bucketBuilder_.dispose(); + bucketBuilder_ = null; + bucket_ = other.bucket_; + bitField0_ = (bitField0_ & ~0x00000008); + bucketBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getBucketFieldBuilder() : null; + } else { + bucketBuilder_.addAllMessages(other.bucket_); + } + } + } + if (other.hasSchema()) { + setSchema(other.getSchema()); + } + if (other.hasZeroThreshold()) { + setZeroThreshold(other.getZeroThreshold()); + } + if (other.hasZeroCount()) { + setZeroCount(other.getZeroCount()); + } + if (other.hasZeroCountFloat()) { + setZeroCountFloat(other.getZeroCountFloat()); + } + if (negativeSpanBuilder_ == null) { + if (!other.negativeSpan_.isEmpty()) { + if (negativeSpan_.isEmpty()) { + negativeSpan_ = other.negativeSpan_; + bitField0_ = (bitField0_ & ~0x00000100); + } else { + ensureNegativeSpanIsMutable(); + negativeSpan_.addAll(other.negativeSpan_); + } + onChanged(); + } + } else { + if (!other.negativeSpan_.isEmpty()) { + if (negativeSpanBuilder_.isEmpty()) { + negativeSpanBuilder_.dispose(); + negativeSpanBuilder_ = null; + negativeSpan_ = other.negativeSpan_; + bitField0_ = (bitField0_ & ~0x00000100); + negativeSpanBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getNegativeSpanFieldBuilder() : null; + } else { + negativeSpanBuilder_.addAllMessages(other.negativeSpan_); + } + } + } + if (!other.negativeDelta_.isEmpty()) { + if (negativeDelta_.isEmpty()) { + negativeDelta_ = other.negativeDelta_; + bitField0_ = (bitField0_ & ~0x00000200); + } else { + ensureNegativeDeltaIsMutable(); + negativeDelta_.addAll(other.negativeDelta_); + } + onChanged(); + } + if (!other.negativeCount_.isEmpty()) { + if (negativeCount_.isEmpty()) { + negativeCount_ = other.negativeCount_; + bitField0_ = (bitField0_ & ~0x00000400); + } else { + ensureNegativeCountIsMutable(); + negativeCount_.addAll(other.negativeCount_); + } + onChanged(); + } + if (positiveSpanBuilder_ == null) { + if (!other.positiveSpan_.isEmpty()) { + if (positiveSpan_.isEmpty()) { + positiveSpan_ = other.positiveSpan_; + bitField0_ = (bitField0_ & ~0x00000800); + } else { + ensurePositiveSpanIsMutable(); + positiveSpan_.addAll(other.positiveSpan_); + } + onChanged(); + } + } else { + if (!other.positiveSpan_.isEmpty()) { + if (positiveSpanBuilder_.isEmpty()) { + positiveSpanBuilder_.dispose(); + positiveSpanBuilder_ = null; + positiveSpan_ = other.positiveSpan_; + bitField0_ = (bitField0_ & ~0x00000800); + positiveSpanBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getPositiveSpanFieldBuilder() : null; + } else { + positiveSpanBuilder_.addAllMessages(other.positiveSpan_); + } + } + } + if (!other.positiveDelta_.isEmpty()) { + if (positiveDelta_.isEmpty()) { + positiveDelta_ = other.positiveDelta_; + bitField0_ = (bitField0_ & ~0x00001000); + } else { + ensurePositiveDeltaIsMutable(); + positiveDelta_.addAll(other.positiveDelta_); + } + onChanged(); + } + if (!other.positiveCount_.isEmpty()) { + if (positiveCount_.isEmpty()) { + positiveCount_ = other.positiveCount_; + bitField0_ = (bitField0_ & ~0x00002000); + } else { + ensurePositiveCountIsMutable(); + positiveCount_.addAll(other.positiveCount_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + sampleCount_ = input.readUInt64(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 17: { + sampleSum_ = input.readDouble(); + bitField0_ |= 0x00000004; + break; + } // case 17 + case 26: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.PARSER, + extensionRegistry); + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + bucket_.add(m); + } else { + bucketBuilder_.addMessage(m); + } + break; + } // case 26 + case 33: { + sampleCountFloat_ = input.readDouble(); + bitField0_ |= 0x00000002; + break; + } // case 33 + case 40: { + schema_ = input.readSInt32(); + bitField0_ |= 0x00000010; + break; + } // case 40 + case 49: { + zeroThreshold_ = input.readDouble(); + bitField0_ |= 0x00000020; + break; + } // case 49 + case 56: { + zeroCount_ = input.readUInt64(); + bitField0_ |= 0x00000040; + break; + } // case 56 + case 65: { + zeroCountFloat_ = input.readDouble(); + bitField0_ |= 0x00000080; + break; + } // case 65 + case 74: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.PARSER, + extensionRegistry); + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + negativeSpan_.add(m); + } else { + negativeSpanBuilder_.addMessage(m); + } + break; + } // case 74 + case 80: { + long v = input.readSInt64(); + ensureNegativeDeltaIsMutable(); + negativeDelta_.addLong(v); + break; + } // case 80 + case 82: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + ensureNegativeDeltaIsMutable(); + while (input.getBytesUntilLimit() > 0) { + negativeDelta_.addLong(input.readSInt64()); + } + input.popLimit(limit); + break; + } // case 82 + case 89: { + double v = input.readDouble(); + ensureNegativeCountIsMutable(); + negativeCount_.addDouble(v); + break; + } // case 89 + case 90: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + ensureNegativeCountIsMutable(); + while (input.getBytesUntilLimit() > 0) { + negativeCount_.addDouble(input.readDouble()); + } + input.popLimit(limit); + break; + } // case 90 + case 98: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.PARSER, + extensionRegistry); + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + positiveSpan_.add(m); + } else { + positiveSpanBuilder_.addMessage(m); + } + break; + } // case 98 + case 104: { + long v = input.readSInt64(); + ensurePositiveDeltaIsMutable(); + positiveDelta_.addLong(v); + break; + } // case 104 + case 106: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + ensurePositiveDeltaIsMutable(); + while (input.getBytesUntilLimit() > 0) { + positiveDelta_.addLong(input.readSInt64()); + } + input.popLimit(limit); + break; + } // case 106 + case 113: { + double v = input.readDouble(); + ensurePositiveCountIsMutable(); + positiveCount_.addDouble(v); + break; + } // case 113 + case 114: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + ensurePositiveCountIsMutable(); + while (input.getBytesUntilLimit() > 0) { + positiveCount_.addDouble(input.readDouble()); + } + input.popLimit(limit); + break; + } // case 114 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private long sampleCount_ ; + /** + * optional uint64 sample_count = 1; + * @return Whether the sampleCount field is set. + */ + @java.lang.Override + public boolean hasSampleCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional uint64 sample_count = 1; + * @return The sampleCount. + */ + @java.lang.Override + public long getSampleCount() { + return sampleCount_; + } + /** + * optional uint64 sample_count = 1; + * @param value The sampleCount to set. + * @return This builder for chaining. + */ + public Builder setSampleCount(long value) { + + sampleCount_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional uint64 sample_count = 1; + * @return This builder for chaining. + */ + public Builder clearSampleCount() { + bitField0_ = (bitField0_ & ~0x00000001); + sampleCount_ = 0L; + onChanged(); + return this; + } + + private double sampleCountFloat_ ; + /** + *
+       * Overrides sample_count if > 0.
+       * 
+ * + * optional double sample_count_float = 4; + * @return Whether the sampleCountFloat field is set. + */ + @java.lang.Override + public boolean hasSampleCountFloat() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Overrides sample_count if > 0.
+       * 
+ * + * optional double sample_count_float = 4; + * @return The sampleCountFloat. + */ + @java.lang.Override + public double getSampleCountFloat() { + return sampleCountFloat_; + } + /** + *
+       * Overrides sample_count if > 0.
+       * 
+ * + * optional double sample_count_float = 4; + * @param value The sampleCountFloat to set. + * @return This builder for chaining. + */ + public Builder setSampleCountFloat(double value) { + + sampleCountFloat_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + *
+       * Overrides sample_count if > 0.
+       * 
+ * + * optional double sample_count_float = 4; + * @return This builder for chaining. + */ + public Builder clearSampleCountFloat() { + bitField0_ = (bitField0_ & ~0x00000002); + sampleCountFloat_ = 0D; + onChanged(); + return this; + } + + private double sampleSum_ ; + /** + * optional double sample_sum = 2; + * @return Whether the sampleSum field is set. + */ + @java.lang.Override + public boolean hasSampleSum() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional double sample_sum = 2; + * @return The sampleSum. + */ + @java.lang.Override + public double getSampleSum() { + return sampleSum_; + } + /** + * optional double sample_sum = 2; + * @param value The sampleSum to set. + * @return This builder for chaining. + */ + public Builder setSampleSum(double value) { + + sampleSum_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * optional double sample_sum = 2; + * @return This builder for chaining. + */ + public Builder clearSampleSum() { + bitField0_ = (bitField0_ & ~0x00000004); + sampleSum_ = 0D; + onChanged(); + return this; + } + + private java.util.List bucket_ = + java.util.Collections.emptyList(); + private void ensureBucketIsMutable() { + if (!((bitField0_ & 0x00000008) != 0)) { + bucket_ = new java.util.ArrayList(bucket_); + bitField0_ |= 0x00000008; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> bucketBuilder_; + + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public java.util.List getBucketList() { + if (bucketBuilder_ == null) { + return java.util.Collections.unmodifiableList(bucket_); + } else { + return bucketBuilder_.getMessageList(); + } + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public int getBucketCount() { + if (bucketBuilder_ == null) { + return bucket_.size(); + } else { + return bucketBuilder_.getCount(); + } + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index) { + if (bucketBuilder_ == null) { + return bucket_.get(index); + } else { + return bucketBuilder_.getMessage(index); + } + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder setBucket( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) { + if (bucketBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBucketIsMutable(); + bucket_.set(index, value); + onChanged(); + } else { + bucketBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder setBucket( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) { + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + bucket_.set(index, builderForValue.build()); + onChanged(); + } else { + bucketBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) { + if (bucketBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBucketIsMutable(); + bucket_.add(value); + onChanged(); + } else { + bucketBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder addBucket( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) { + if (bucketBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBucketIsMutable(); + bucket_.add(index, value); + onChanged(); + } else { + bucketBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder addBucket( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) { + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + bucket_.add(builderForValue.build()); + onChanged(); + } else { + bucketBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder addBucket( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) { + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + bucket_.add(index, builderForValue.build()); + onChanged(); + } else { + bucketBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder addAllBucket( + java.lang.Iterable values) { + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, bucket_); + onChanged(); + } else { + bucketBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder clearBucket() { + if (bucketBuilder_ == null) { + bucket_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + bucketBuilder_.clear(); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public Builder removeBucket(int index) { + if (bucketBuilder_ == null) { + ensureBucketIsMutable(); + bucket_.remove(index); + onChanged(); + } else { + bucketBuilder_.remove(index); + } + return this; + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder getBucketBuilder( + int index) { + return getBucketFieldBuilder().getBuilder(index); + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder( + int index) { + if (bucketBuilder_ == null) { + return bucket_.get(index); } else { + return bucketBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public java.util.List + getBucketOrBuilderList() { + if (bucketBuilder_ != null) { + return bucketBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(bucket_); + } + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder addBucketBuilder() { + return getBucketFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance()); + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder addBucketBuilder( + int index) { + return getBucketFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance()); + } + /** + *
+       * Buckets for the conventional histogram.
+       * 
+ * + * repeated .io.prometheus.client.Bucket bucket = 3; + */ + public java.util.List + getBucketBuilderList() { + return getBucketFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> + getBucketFieldBuilder() { + if (bucketBuilder_ == null) { + bucketBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder>( + bucket_, + ((bitField0_ & 0x00000008) != 0), + getParentForChildren(), + isClean()); + bucket_ = null; + } + return bucketBuilder_; + } + + private int schema_ ; + /** + *
+       * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+       * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+       * then each power of two is divided into 2^n logarithmic buckets.
+       * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+       * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+       * 
+ * + * optional sint32 schema = 5; + * @return Whether the schema field is set. + */ + @java.lang.Override + public boolean hasSchema() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + *
+       * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+       * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+       * then each power of two is divided into 2^n logarithmic buckets.
+       * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+       * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+       * 
+ * + * optional sint32 schema = 5; + * @return The schema. + */ + @java.lang.Override + public int getSchema() { + return schema_; + } + /** + *
+       * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+       * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+       * then each power of two is divided into 2^n logarithmic buckets.
+       * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+       * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+       * 
+ * + * optional sint32 schema = 5; + * @param value The schema to set. + * @return This builder for chaining. + */ + public Builder setSchema(int value) { + + schema_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + *
+       * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
+       * They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
+       * then each power of two is divided into 2^n logarithmic buckets.
+       * Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
+       * In the future, more bucket schemas may be added using numbers < -4 or > 8.
+       * 
+ * + * optional sint32 schema = 5; + * @return This builder for chaining. + */ + public Builder clearSchema() { + bitField0_ = (bitField0_ & ~0x00000010); + schema_ = 0; + onChanged(); + return this; + } + + private double zeroThreshold_ ; + /** + *
+       * Breadth of the zero bucket.
+       * 
+ * + * optional double zero_threshold = 6; + * @return Whether the zeroThreshold field is set. + */ + @java.lang.Override + public boolean hasZeroThreshold() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + *
+       * Breadth of the zero bucket.
+       * 
+ * + * optional double zero_threshold = 6; + * @return The zeroThreshold. + */ + @java.lang.Override + public double getZeroThreshold() { + return zeroThreshold_; + } + /** + *
+       * Breadth of the zero bucket.
+       * 
+ * + * optional double zero_threshold = 6; + * @param value The zeroThreshold to set. + * @return This builder for chaining. + */ + public Builder setZeroThreshold(double value) { + + zeroThreshold_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + *
+       * Breadth of the zero bucket.
+       * 
+ * + * optional double zero_threshold = 6; + * @return This builder for chaining. + */ + public Builder clearZeroThreshold() { + bitField0_ = (bitField0_ & ~0x00000020); + zeroThreshold_ = 0D; + onChanged(); + return this; + } + + private long zeroCount_ ; + /** + *
+       * Count in zero bucket.
+       * 
+ * + * optional uint64 zero_count = 7; + * @return Whether the zeroCount field is set. + */ + @java.lang.Override + public boolean hasZeroCount() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + *
+       * Count in zero bucket.
+       * 
+ * + * optional uint64 zero_count = 7; + * @return The zeroCount. + */ + @java.lang.Override + public long getZeroCount() { + return zeroCount_; + } + /** + *
+       * Count in zero bucket.
+       * 
+ * + * optional uint64 zero_count = 7; + * @param value The zeroCount to set. + * @return This builder for chaining. + */ + public Builder setZeroCount(long value) { + + zeroCount_ = value; + bitField0_ |= 0x00000040; + onChanged(); + return this; + } + /** + *
+       * Count in zero bucket.
+       * 
+ * + * optional uint64 zero_count = 7; + * @return This builder for chaining. + */ + public Builder clearZeroCount() { + bitField0_ = (bitField0_ & ~0x00000040); + zeroCount_ = 0L; + onChanged(); + return this; + } + + private double zeroCountFloat_ ; + /** + *
+       * Overrides sb_zero_count if > 0.
+       * 
+ * + * optional double zero_count_float = 8; + * @return Whether the zeroCountFloat field is set. + */ + @java.lang.Override + public boolean hasZeroCountFloat() { + return ((bitField0_ & 0x00000080) != 0); + } + /** + *
+       * Overrides sb_zero_count if > 0.
+       * 
+ * + * optional double zero_count_float = 8; + * @return The zeroCountFloat. + */ + @java.lang.Override + public double getZeroCountFloat() { + return zeroCountFloat_; + } + /** + *
+       * Overrides sb_zero_count if > 0.
+       * 
+ * + * optional double zero_count_float = 8; + * @param value The zeroCountFloat to set. + * @return This builder for chaining. + */ + public Builder setZeroCountFloat(double value) { + + zeroCountFloat_ = value; + bitField0_ |= 0x00000080; + onChanged(); + return this; + } + /** + *
+       * Overrides sb_zero_count if > 0.
+       * 
+ * + * optional double zero_count_float = 8; + * @return This builder for chaining. + */ + public Builder clearZeroCountFloat() { + bitField0_ = (bitField0_ & ~0x00000080); + zeroCountFloat_ = 0D; + onChanged(); + return this; + } + + private java.util.List negativeSpan_ = + java.util.Collections.emptyList(); + private void ensureNegativeSpanIsMutable() { + if (!((bitField0_ & 0x00000100) != 0)) { + negativeSpan_ = new java.util.ArrayList(negativeSpan_); + bitField0_ |= 0x00000100; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_; + + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public java.util.List getNegativeSpanList() { + if (negativeSpanBuilder_ == null) { + return java.util.Collections.unmodifiableList(negativeSpan_); + } else { + return negativeSpanBuilder_.getMessageList(); + } + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public int getNegativeSpanCount() { + if (negativeSpanBuilder_ == null) { + return negativeSpan_.size(); + } else { + return negativeSpanBuilder_.getCount(); + } + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index) { + if (negativeSpanBuilder_ == null) { + return negativeSpan_.get(index); + } else { + return negativeSpanBuilder_.getMessage(index); + } + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder setNegativeSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (negativeSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureNegativeSpanIsMutable(); + negativeSpan_.set(index, value); + onChanged(); + } else { + negativeSpanBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder setNegativeSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + negativeSpan_.set(index, builderForValue.build()); + onChanged(); + } else { + negativeSpanBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (negativeSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureNegativeSpanIsMutable(); + negativeSpan_.add(value); + onChanged(); + } else { + negativeSpanBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder addNegativeSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (negativeSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureNegativeSpanIsMutable(); + negativeSpan_.add(index, value); + onChanged(); + } else { + negativeSpanBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder addNegativeSpan( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + negativeSpan_.add(builderForValue.build()); + onChanged(); + } else { + negativeSpanBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder addNegativeSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + negativeSpan_.add(index, builderForValue.build()); + onChanged(); + } else { + negativeSpanBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder addAllNegativeSpan( + java.lang.Iterable values) { + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, negativeSpan_); + onChanged(); + } else { + negativeSpanBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder clearNegativeSpan() { + if (negativeSpanBuilder_ == null) { + negativeSpan_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000100); + onChanged(); + } else { + negativeSpanBuilder_.clear(); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public Builder removeNegativeSpan(int index) { + if (negativeSpanBuilder_ == null) { + ensureNegativeSpanIsMutable(); + negativeSpan_.remove(index); + onChanged(); + } else { + negativeSpanBuilder_.remove(index); + } + return this; + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder getNegativeSpanBuilder( + int index) { + return getNegativeSpanFieldBuilder().getBuilder(index); + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder( + int index) { + if (negativeSpanBuilder_ == null) { + return negativeSpan_.get(index); } else { + return negativeSpanBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public java.util.List + getNegativeSpanOrBuilderList() { + if (negativeSpanBuilder_ != null) { + return negativeSpanBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(negativeSpan_); + } + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addNegativeSpanBuilder() { + return getNegativeSpanFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()); + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addNegativeSpanBuilder( + int index) { + return getNegativeSpanFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()); + } + /** + *
+       * Negative buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan negative_span = 9; + */ + public java.util.List + getNegativeSpanBuilderList() { + return getNegativeSpanFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> + getNegativeSpanFieldBuilder() { + if (negativeSpanBuilder_ == null) { + negativeSpanBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>( + negativeSpan_, + ((bitField0_ & 0x00000100) != 0), + getParentForChildren(), + isClean()); + negativeSpan_ = null; + } + return negativeSpanBuilder_; + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_ = emptyLongList(); + private void ensureNegativeDeltaIsMutable() { + if (!((bitField0_ & 0x00000200) != 0)) { + negativeDelta_ = mutableCopy(negativeDelta_); + bitField0_ |= 0x00000200; + } + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @return A list containing the negativeDelta. + */ + public java.util.List + getNegativeDeltaList() { + return ((bitField0_ & 0x00000200) != 0) ? + java.util.Collections.unmodifiableList(negativeDelta_) : negativeDelta_; + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @return The count of negativeDelta. + */ + public int getNegativeDeltaCount() { + return negativeDelta_.size(); + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @param index The index of the element to return. + * @return The negativeDelta at the given index. + */ + public long getNegativeDelta(int index) { + return negativeDelta_.getLong(index); + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @param index The index to set the value at. + * @param value The negativeDelta to set. + * @return This builder for chaining. + */ + public Builder setNegativeDelta( + int index, long value) { + + ensureNegativeDeltaIsMutable(); + negativeDelta_.setLong(index, value); + onChanged(); + return this; + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @param value The negativeDelta to add. + * @return This builder for chaining. + */ + public Builder addNegativeDelta(long value) { + + ensureNegativeDeltaIsMutable(); + negativeDelta_.addLong(value); + onChanged(); + return this; + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @param values The negativeDelta to add. + * @return This builder for chaining. + */ + public Builder addAllNegativeDelta( + java.lang.Iterable values) { + ensureNegativeDeltaIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, negativeDelta_); + onChanged(); + return this; + } + /** + *
+       * Use either "negative_delta" or "negative_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 negative_delta = 10; + * @return This builder for chaining. + */ + public Builder clearNegativeDelta() { + negativeDelta_ = emptyLongList(); + bitField0_ = (bitField0_ & ~0x00000200); + onChanged(); + return this; + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_ = emptyDoubleList(); + private void ensureNegativeCountIsMutable() { + if (!((bitField0_ & 0x00000400) != 0)) { + negativeCount_ = mutableCopy(negativeCount_); + bitField0_ |= 0x00000400; + } + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @return A list containing the negativeCount. + */ + public java.util.List + getNegativeCountList() { + return ((bitField0_ & 0x00000400) != 0) ? + java.util.Collections.unmodifiableList(negativeCount_) : negativeCount_; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @return The count of negativeCount. + */ + public int getNegativeCountCount() { + return negativeCount_.size(); + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @param index The index of the element to return. + * @return The negativeCount at the given index. + */ + public double getNegativeCount(int index) { + return negativeCount_.getDouble(index); + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @param index The index to set the value at. + * @param value The negativeCount to set. + * @return This builder for chaining. + */ + public Builder setNegativeCount( + int index, double value) { + + ensureNegativeCountIsMutable(); + negativeCount_.setDouble(index, value); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @param value The negativeCount to add. + * @return This builder for chaining. + */ + public Builder addNegativeCount(double value) { + + ensureNegativeCountIsMutable(); + negativeCount_.addDouble(value); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @param values The negativeCount to add. + * @return This builder for chaining. + */ + public Builder addAllNegativeCount( + java.lang.Iterable values) { + ensureNegativeCountIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, negativeCount_); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double negative_count = 11; + * @return This builder for chaining. + */ + public Builder clearNegativeCount() { + negativeCount_ = emptyDoubleList(); + bitField0_ = (bitField0_ & ~0x00000400); + onChanged(); + return this; + } + + private java.util.List positiveSpan_ = + java.util.Collections.emptyList(); + private void ensurePositiveSpanIsMutable() { + if (!((bitField0_ & 0x00000800) != 0)) { + positiveSpan_ = new java.util.ArrayList(positiveSpan_); + bitField0_ |= 0x00000800; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_; + + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public java.util.List getPositiveSpanList() { + if (positiveSpanBuilder_ == null) { + return java.util.Collections.unmodifiableList(positiveSpan_); + } else { + return positiveSpanBuilder_.getMessageList(); + } + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public int getPositiveSpanCount() { + if (positiveSpanBuilder_ == null) { + return positiveSpan_.size(); + } else { + return positiveSpanBuilder_.getCount(); + } + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index) { + if (positiveSpanBuilder_ == null) { + return positiveSpan_.get(index); + } else { + return positiveSpanBuilder_.getMessage(index); + } + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder setPositiveSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (positiveSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePositiveSpanIsMutable(); + positiveSpan_.set(index, value); + onChanged(); + } else { + positiveSpanBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder setPositiveSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + positiveSpan_.set(index, builderForValue.build()); + onChanged(); + } else { + positiveSpanBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (positiveSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePositiveSpanIsMutable(); + positiveSpan_.add(value); + onChanged(); + } else { + positiveSpanBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder addPositiveSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) { + if (positiveSpanBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePositiveSpanIsMutable(); + positiveSpan_.add(index, value); + onChanged(); + } else { + positiveSpanBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder addPositiveSpan( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + positiveSpan_.add(builderForValue.build()); + onChanged(); + } else { + positiveSpanBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder addPositiveSpan( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) { + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + positiveSpan_.add(index, builderForValue.build()); + onChanged(); + } else { + positiveSpanBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder addAllPositiveSpan( + java.lang.Iterable values) { + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, positiveSpan_); + onChanged(); + } else { + positiveSpanBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder clearPositiveSpan() { + if (positiveSpanBuilder_ == null) { + positiveSpan_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000800); + onChanged(); + } else { + positiveSpanBuilder_.clear(); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public Builder removePositiveSpan(int index) { + if (positiveSpanBuilder_ == null) { + ensurePositiveSpanIsMutable(); + positiveSpan_.remove(index); + onChanged(); + } else { + positiveSpanBuilder_.remove(index); + } + return this; + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder getPositiveSpanBuilder( + int index) { + return getPositiveSpanFieldBuilder().getBuilder(index); + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder( + int index) { + if (positiveSpanBuilder_ == null) { + return positiveSpan_.get(index); } else { + return positiveSpanBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public java.util.List + getPositiveSpanOrBuilderList() { + if (positiveSpanBuilder_ != null) { + return positiveSpanBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(positiveSpan_); + } + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addPositiveSpanBuilder() { + return getPositiveSpanFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()); + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addPositiveSpanBuilder( + int index) { + return getPositiveSpanFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()); + } + /** + *
+       * Positive buckets for the native histogram.
+       * 
+ * + * repeated .io.prometheus.client.BucketSpan positive_span = 12; + */ + public java.util.List + getPositiveSpanBuilderList() { + return getPositiveSpanFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> + getPositiveSpanFieldBuilder() { + if (positiveSpanBuilder_ == null) { + positiveSpanBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>( + positiveSpan_, + ((bitField0_ & 0x00000800) != 0), + getParentForChildren(), + isClean()); + positiveSpan_ = null; + } + return positiveSpanBuilder_; + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_ = emptyLongList(); + private void ensurePositiveDeltaIsMutable() { + if (!((bitField0_ & 0x00001000) != 0)) { + positiveDelta_ = mutableCopy(positiveDelta_); + bitField0_ |= 0x00001000; + } + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @return A list containing the positiveDelta. + */ + public java.util.List + getPositiveDeltaList() { + return ((bitField0_ & 0x00001000) != 0) ? + java.util.Collections.unmodifiableList(positiveDelta_) : positiveDelta_; + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @return The count of positiveDelta. + */ + public int getPositiveDeltaCount() { + return positiveDelta_.size(); + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @param index The index of the element to return. + * @return The positiveDelta at the given index. + */ + public long getPositiveDelta(int index) { + return positiveDelta_.getLong(index); + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @param index The index to set the value at. + * @param value The positiveDelta to set. + * @return This builder for chaining. + */ + public Builder setPositiveDelta( + int index, long value) { + + ensurePositiveDeltaIsMutable(); + positiveDelta_.setLong(index, value); + onChanged(); + return this; + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @param value The positiveDelta to add. + * @return This builder for chaining. + */ + public Builder addPositiveDelta(long value) { + + ensurePositiveDeltaIsMutable(); + positiveDelta_.addLong(value); + onChanged(); + return this; + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @param values The positiveDelta to add. + * @return This builder for chaining. + */ + public Builder addAllPositiveDelta( + java.lang.Iterable values) { + ensurePositiveDeltaIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, positiveDelta_); + onChanged(); + return this; + } + /** + *
+       * Use either "positive_delta" or "positive_count", the former for
+       * regular histograms with integer counts, the latter for float
+       * histograms.
+       * 
+ * + * repeated sint64 positive_delta = 13; + * @return This builder for chaining. + */ + public Builder clearPositiveDelta() { + positiveDelta_ = emptyLongList(); + bitField0_ = (bitField0_ & ~0x00001000); + onChanged(); + return this; + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_ = emptyDoubleList(); + private void ensurePositiveCountIsMutable() { + if (!((bitField0_ & 0x00002000) != 0)) { + positiveCount_ = mutableCopy(positiveCount_); + bitField0_ |= 0x00002000; + } + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @return A list containing the positiveCount. + */ + public java.util.List + getPositiveCountList() { + return ((bitField0_ & 0x00002000) != 0) ? + java.util.Collections.unmodifiableList(positiveCount_) : positiveCount_; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @return The count of positiveCount. + */ + public int getPositiveCountCount() { + return positiveCount_.size(); + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @param index The index of the element to return. + * @return The positiveCount at the given index. + */ + public double getPositiveCount(int index) { + return positiveCount_.getDouble(index); + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @param index The index to set the value at. + * @param value The positiveCount to set. + * @return This builder for chaining. + */ + public Builder setPositiveCount( + int index, double value) { + + ensurePositiveCountIsMutable(); + positiveCount_.setDouble(index, value); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @param value The positiveCount to add. + * @return This builder for chaining. + */ + public Builder addPositiveCount(double value) { + + ensurePositiveCountIsMutable(); + positiveCount_.addDouble(value); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @param values The positiveCount to add. + * @return This builder for chaining. + */ + public Builder addAllPositiveCount( + java.lang.Iterable values) { + ensurePositiveCountIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, positiveCount_); + onChanged(); + return this; + } + /** + *
+       * Absolute count of each bucket.
+       * 
+ * + * repeated double positive_count = 14; + * @return This builder for chaining. + */ + public Builder clearPositiveCount() { + positiveCount_ = emptyDoubleList(); + bitField0_ = (bitField0_ & ~0x00002000); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Histogram) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Histogram parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BucketOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Bucket) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + *
+     * Cumulative in increasing order.
+     * 
+ * + * optional uint64 cumulative_count = 1; + * @return Whether the cumulativeCount field is set. + */ + boolean hasCumulativeCount(); + /** + *
+     * Cumulative in increasing order.
+     * 
+ * + * optional uint64 cumulative_count = 1; + * @return The cumulativeCount. + */ + long getCumulativeCount(); + + /** + *
+     * Overrides cumulative_count if > 0.
+     * 
+ * + * optional double cumulative_count_float = 4; + * @return Whether the cumulativeCountFloat field is set. + */ + boolean hasCumulativeCountFloat(); + /** + *
+     * Overrides cumulative_count if > 0.
+     * 
+ * + * optional double cumulative_count_float = 4; + * @return The cumulativeCountFloat. + */ + double getCumulativeCountFloat(); + + /** + *
+     * Inclusive.
+     * 
+ * + * optional double upper_bound = 2; + * @return Whether the upperBound field is set. + */ + boolean hasUpperBound(); + /** + *
+     * Inclusive.
+     * 
+ * + * optional double upper_bound = 2; + * @return The upperBound. + */ + double getUpperBound(); + + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return Whether the exemplar field is set. + */ + boolean hasExemplar(); + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return The exemplar. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar(); + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + } + /** + *
+   * A Bucket of a conventional histogram, each of which is treated as
+   * an individual counter-like time series by Prometheus.
+   * 
+ * + * Protobuf type {@code io.prometheus.client.Bucket} + */ + public static final class Bucket extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Bucket) + BucketOrBuilder { + private static final long serialVersionUID = 0L; + // Use Bucket.newBuilder() to construct. + private Bucket(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Bucket() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Bucket(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder.class); + } + + private int bitField0_; + public static final int CUMULATIVE_COUNT_FIELD_NUMBER = 1; + private long cumulativeCount_ = 0L; + /** + *
+     * Cumulative in increasing order.
+     * 
+ * + * optional uint64 cumulative_count = 1; + * @return Whether the cumulativeCount field is set. + */ + @java.lang.Override + public boolean hasCumulativeCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+     * Cumulative in increasing order.
+     * 
+ * + * optional uint64 cumulative_count = 1; + * @return The cumulativeCount. + */ + @java.lang.Override + public long getCumulativeCount() { + return cumulativeCount_; + } + + public static final int CUMULATIVE_COUNT_FLOAT_FIELD_NUMBER = 4; + private double cumulativeCountFloat_ = 0D; + /** + *
+     * Overrides cumulative_count if > 0.
+     * 
+ * + * optional double cumulative_count_float = 4; + * @return Whether the cumulativeCountFloat field is set. + */ + @java.lang.Override + public boolean hasCumulativeCountFloat() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Overrides cumulative_count if > 0.
+     * 
+ * + * optional double cumulative_count_float = 4; + * @return The cumulativeCountFloat. + */ + @java.lang.Override + public double getCumulativeCountFloat() { + return cumulativeCountFloat_; + } + + public static final int UPPER_BOUND_FIELD_NUMBER = 2; + private double upperBound_ = 0D; + /** + *
+     * Inclusive.
+     * 
+ * + * optional double upper_bound = 2; + * @return Whether the upperBound field is set. + */ + @java.lang.Override + public boolean hasUpperBound() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + *
+     * Inclusive.
+     * 
+ * + * optional double upper_bound = 2; + * @return The upperBound. + */ + @java.lang.Override + public double getUpperBound() { + return upperBound_; + } + + public static final int EXEMPLAR_FIELD_NUMBER = 3; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_; + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return Whether the exemplar field is set. + */ + @java.lang.Override + public boolean hasExemplar() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return The exemplar. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeUInt64(1, cumulativeCount_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeDouble(2, upperBound_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeMessage(3, getExemplar()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeDouble(4, cumulativeCountFloat_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeUInt64Size(1, cumulativeCount_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(2, upperBound_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(3, getExemplar()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(4, cumulativeCountFloat_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket) obj; + + if (hasCumulativeCount() != other.hasCumulativeCount()) return false; + if (hasCumulativeCount()) { + if (getCumulativeCount() + != other.getCumulativeCount()) return false; + } + if (hasCumulativeCountFloat() != other.hasCumulativeCountFloat()) return false; + if (hasCumulativeCountFloat()) { + if (java.lang.Double.doubleToLongBits(getCumulativeCountFloat()) + != java.lang.Double.doubleToLongBits( + other.getCumulativeCountFloat())) return false; + } + if (hasUpperBound() != other.hasUpperBound()) return false; + if (hasUpperBound()) { + if (java.lang.Double.doubleToLongBits(getUpperBound()) + != java.lang.Double.doubleToLongBits( + other.getUpperBound())) return false; + } + if (hasExemplar() != other.hasExemplar()) return false; + if (hasExemplar()) { + if (!getExemplar() + .equals(other.getExemplar())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasCumulativeCount()) { + hash = (37 * hash) + CUMULATIVE_COUNT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + getCumulativeCount()); + } + if (hasCumulativeCountFloat()) { + hash = (37 * hash) + CUMULATIVE_COUNT_FLOAT_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getCumulativeCountFloat())); + } + if (hasUpperBound()) { + hash = (37 * hash) + UPPER_BOUND_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getUpperBound())); + } + if (hasExemplar()) { + hash = (37 * hash) + EXEMPLAR_FIELD_NUMBER; + hash = (53 * hash) + getExemplar().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A Bucket of a conventional histogram, each of which is treated as
+     * an individual counter-like time series by Prometheus.
+     * 
+ * + * Protobuf type {@code io.prometheus.client.Bucket} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getExemplarFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + cumulativeCount_ = 0L; + cumulativeCountFloat_ = 0D; + upperBound_ = 0D; + exemplar_ = null; + if (exemplarBuilder_ != null) { + exemplarBuilder_.dispose(); + exemplarBuilder_ = null; + } + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.cumulativeCount_ = cumulativeCount_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.cumulativeCountFloat_ = cumulativeCountFloat_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.upperBound_ = upperBound_; + to_bitField0_ |= 0x00000004; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.exemplar_ = exemplarBuilder_ == null + ? exemplar_ + : exemplarBuilder_.build(); + to_bitField0_ |= 0x00000008; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance()) return this; + if (other.hasCumulativeCount()) { + setCumulativeCount(other.getCumulativeCount()); + } + if (other.hasCumulativeCountFloat()) { + setCumulativeCountFloat(other.getCumulativeCountFloat()); + } + if (other.hasUpperBound()) { + setUpperBound(other.getUpperBound()); + } + if (other.hasExemplar()) { + mergeExemplar(other.getExemplar()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + cumulativeCount_ = input.readUInt64(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 17: { + upperBound_ = input.readDouble(); + bitField0_ |= 0x00000004; + break; + } // case 17 + case 26: { + input.readMessage( + getExemplarFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000008; + break; + } // case 26 + case 33: { + cumulativeCountFloat_ = input.readDouble(); + bitField0_ |= 0x00000002; + break; + } // case 33 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private long cumulativeCount_ ; + /** + *
+       * Cumulative in increasing order.
+       * 
+ * + * optional uint64 cumulative_count = 1; + * @return Whether the cumulativeCount field is set. + */ + @java.lang.Override + public boolean hasCumulativeCount() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Cumulative in increasing order.
+       * 
+ * + * optional uint64 cumulative_count = 1; + * @return The cumulativeCount. + */ + @java.lang.Override + public long getCumulativeCount() { + return cumulativeCount_; + } + /** + *
+       * Cumulative in increasing order.
+       * 
+ * + * optional uint64 cumulative_count = 1; + * @param value The cumulativeCount to set. + * @return This builder for chaining. + */ + public Builder setCumulativeCount(long value) { + + cumulativeCount_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+       * Cumulative in increasing order.
+       * 
+ * + * optional uint64 cumulative_count = 1; + * @return This builder for chaining. + */ + public Builder clearCumulativeCount() { + bitField0_ = (bitField0_ & ~0x00000001); + cumulativeCount_ = 0L; + onChanged(); + return this; + } + + private double cumulativeCountFloat_ ; + /** + *
+       * Overrides cumulative_count if > 0.
+       * 
+ * + * optional double cumulative_count_float = 4; + * @return Whether the cumulativeCountFloat field is set. + */ + @java.lang.Override + public boolean hasCumulativeCountFloat() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Overrides cumulative_count if > 0.
+       * 
+ * + * optional double cumulative_count_float = 4; + * @return The cumulativeCountFloat. + */ + @java.lang.Override + public double getCumulativeCountFloat() { + return cumulativeCountFloat_; + } + /** + *
+       * Overrides cumulative_count if > 0.
+       * 
+ * + * optional double cumulative_count_float = 4; + * @param value The cumulativeCountFloat to set. + * @return This builder for chaining. + */ + public Builder setCumulativeCountFloat(double value) { + + cumulativeCountFloat_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + *
+       * Overrides cumulative_count if > 0.
+       * 
+ * + * optional double cumulative_count_float = 4; + * @return This builder for chaining. + */ + public Builder clearCumulativeCountFloat() { + bitField0_ = (bitField0_ & ~0x00000002); + cumulativeCountFloat_ = 0D; + onChanged(); + return this; + } + + private double upperBound_ ; + /** + *
+       * Inclusive.
+       * 
+ * + * optional double upper_bound = 2; + * @return Whether the upperBound field is set. + */ + @java.lang.Override + public boolean hasUpperBound() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + *
+       * Inclusive.
+       * 
+ * + * optional double upper_bound = 2; + * @return The upperBound. + */ + @java.lang.Override + public double getUpperBound() { + return upperBound_; + } + /** + *
+       * Inclusive.
+       * 
+ * + * optional double upper_bound = 2; + * @param value The upperBound to set. + * @return This builder for chaining. + */ + public Builder setUpperBound(double value) { + + upperBound_ = value; + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+       * Inclusive.
+       * 
+ * + * optional double upper_bound = 2; + * @return This builder for chaining. + */ + public Builder clearUpperBound() { + bitField0_ = (bitField0_ & ~0x00000004); + upperBound_ = 0D; + onChanged(); + return this; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_; + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return Whether the exemplar field is set. + */ + public boolean hasExemplar() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + * @return The exemplar. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() { + if (exemplarBuilder_ == null) { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } else { + return exemplarBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) { + if (exemplarBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + exemplar_ = value; + } else { + exemplarBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public Builder setExemplar( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder builderForValue) { + if (exemplarBuilder_ == null) { + exemplar_ = builderForValue.build(); + } else { + exemplarBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) { + if (exemplarBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0) && + exemplar_ != null && + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) { + getExemplarBuilder().mergeFrom(value); + } else { + exemplar_ = value; + } + } else { + exemplarBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public Builder clearExemplar() { + bitField0_ = (bitField0_ & ~0x00000008); + exemplar_ = null; + if (exemplarBuilder_ != null) { + exemplarBuilder_.dispose(); + exemplarBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder getExemplarBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getExemplarFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + if (exemplarBuilder_ != null) { + return exemplarBuilder_.getMessageOrBuilder(); + } else { + return exemplar_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_; + } + } + /** + * optional .io.prometheus.client.Exemplar exemplar = 3; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> + getExemplarFieldBuilder() { + if (exemplarBuilder_ == null) { + exemplarBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>( + getExemplar(), + getParentForChildren(), + isClean()); + exemplar_ = null; + } + return exemplarBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Bucket) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Bucket parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BucketSpanOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.BucketSpan) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + *
+     * Gap to previous span, or starting point for 1st span (which can be negative).
+     * 
+ * + * optional sint32 offset = 1; + * @return Whether the offset field is set. + */ + boolean hasOffset(); + /** + *
+     * Gap to previous span, or starting point for 1st span (which can be negative).
+     * 
+ * + * optional sint32 offset = 1; + * @return The offset. + */ + int getOffset(); + + /** + *
+     * Length of consecutive buckets.
+     * 
+ * + * optional uint32 length = 2; + * @return Whether the length field is set. + */ + boolean hasLength(); + /** + *
+     * Length of consecutive buckets.
+     * 
+ * + * optional uint32 length = 2; + * @return The length. + */ + int getLength(); + } + /** + *
+   * A BucketSpan defines a number of consecutive buckets in a native
+   * histogram with their offset. Logically, it would be more
+   * straightforward to include the bucket counts in the Span. However,
+   * the protobuf representation is more compact in the way the data is
+   * structured here (with all the buckets in a single array separate
+   * from the Spans).
+   * 
+ * + * Protobuf type {@code io.prometheus.client.BucketSpan} + */ + public static final class BucketSpan extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.BucketSpan) + BucketSpanOrBuilder { + private static final long serialVersionUID = 0L; + // Use BucketSpan.newBuilder() to construct. + private BucketSpan(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BucketSpan() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BucketSpan(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder.class); + } + + private int bitField0_; + public static final int OFFSET_FIELD_NUMBER = 1; + private int offset_ = 0; + /** + *
+     * Gap to previous span, or starting point for 1st span (which can be negative).
+     * 
+ * + * optional sint32 offset = 1; + * @return Whether the offset field is set. + */ + @java.lang.Override + public boolean hasOffset() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+     * Gap to previous span, or starting point for 1st span (which can be negative).
+     * 
+ * + * optional sint32 offset = 1; + * @return The offset. + */ + @java.lang.Override + public int getOffset() { + return offset_; + } + + public static final int LENGTH_FIELD_NUMBER = 2; + private int length_ = 0; + /** + *
+     * Length of consecutive buckets.
+     * 
+ * + * optional uint32 length = 2; + * @return Whether the length field is set. + */ + @java.lang.Override + public boolean hasLength() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * Length of consecutive buckets.
+     * 
+ * + * optional uint32 length = 2; + * @return The length. + */ + @java.lang.Override + public int getLength() { + return length_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeSInt32(1, offset_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeUInt32(2, length_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeSInt32Size(1, offset_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeUInt32Size(2, length_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan) obj; + + if (hasOffset() != other.hasOffset()) return false; + if (hasOffset()) { + if (getOffset() + != other.getOffset()) return false; + } + if (hasLength() != other.hasLength()) return false; + if (hasLength()) { + if (getLength() + != other.getLength()) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasOffset()) { + hash = (37 * hash) + OFFSET_FIELD_NUMBER; + hash = (53 * hash) + getOffset(); + } + if (hasLength()) { + hash = (37 * hash) + LENGTH_FIELD_NUMBER; + hash = (53 * hash) + getLength(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A BucketSpan defines a number of consecutive buckets in a native
+     * histogram with their offset. Logically, it would be more
+     * straightforward to include the bucket counts in the Span. However,
+     * the protobuf representation is more compact in the way the data is
+     * structured here (with all the buckets in a single array separate
+     * from the Spans).
+     * 
+ * + * Protobuf type {@code io.prometheus.client.BucketSpan} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + offset_ = 0; + length_ = 0; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan(this); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.offset_ = offset_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.length_ = length_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()) return this; + if (other.hasOffset()) { + setOffset(other.getOffset()); + } + if (other.hasLength()) { + setLength(other.getLength()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + offset_ = input.readSInt32(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 16: { + length_ = input.readUInt32(); + bitField0_ |= 0x00000002; + break; + } // case 16 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private int offset_ ; + /** + *
+       * Gap to previous span, or starting point for 1st span (which can be negative).
+       * 
+ * + * optional sint32 offset = 1; + * @return Whether the offset field is set. + */ + @java.lang.Override + public boolean hasOffset() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + *
+       * Gap to previous span, or starting point for 1st span (which can be negative).
+       * 
+ * + * optional sint32 offset = 1; + * @return The offset. + */ + @java.lang.Override + public int getOffset() { + return offset_; + } + /** + *
+       * Gap to previous span, or starting point for 1st span (which can be negative).
+       * 
+ * + * optional sint32 offset = 1; + * @param value The offset to set. + * @return This builder for chaining. + */ + public Builder setOffset(int value) { + + offset_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+       * Gap to previous span, or starting point for 1st span (which can be negative).
+       * 
+ * + * optional sint32 offset = 1; + * @return This builder for chaining. + */ + public Builder clearOffset() { + bitField0_ = (bitField0_ & ~0x00000001); + offset_ = 0; + onChanged(); + return this; + } + + private int length_ ; + /** + *
+       * Length of consecutive buckets.
+       * 
+ * + * optional uint32 length = 2; + * @return Whether the length field is set. + */ + @java.lang.Override + public boolean hasLength() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+       * Length of consecutive buckets.
+       * 
+ * + * optional uint32 length = 2; + * @return The length. + */ + @java.lang.Override + public int getLength() { + return length_; + } + /** + *
+       * Length of consecutive buckets.
+       * 
+ * + * optional uint32 length = 2; + * @param value The length to set. + * @return This builder for chaining. + */ + public Builder setLength(int value) { + + length_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + *
+       * Length of consecutive buckets.
+       * 
+ * + * optional uint32 length = 2; + * @return This builder for chaining. + */ + public Builder clearLength() { + bitField0_ = (bitField0_ & ~0x00000002); + length_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.BucketSpan) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public BucketSpan parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ExemplarOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Exemplar) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + java.util.List + getLabelList(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + int getLabelCount(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + java.util.List + getLabelOrBuilderList(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index); + + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + boolean hasValue(); + /** + * optional double value = 2; + * @return The value. + */ + double getValue(); + + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return Whether the timestamp field is set. + */ + boolean hasTimestamp(); + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return The timestamp. + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp(); + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder(); + } + /** + * Protobuf type {@code io.prometheus.client.Exemplar} + */ + public static final class Exemplar extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Exemplar) + ExemplarOrBuilder { + private static final long serialVersionUID = 0L; + // Use Exemplar.newBuilder() to construct. + private Exemplar(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Exemplar() { + label_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Exemplar(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder.class); + } + + private int bitField0_; + public static final int LABEL_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private java.util.List label_; + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public java.util.List getLabelList() { + return label_; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public java.util.List + getLabelOrBuilderList() { + return label_; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public int getLabelCount() { + return label_.size(); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) { + return label_.get(index); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index) { + return label_.get(index); + } + + public static final int VALUE_FIELD_NUMBER = 2; + private double value_ = 0D; + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional double value = 2; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + + public static final int TIMESTAMP_FIELD_NUMBER = 3; + private io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp timestamp_; + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return Whether the timestamp field is set. + */ + @java.lang.Override + public boolean hasTimestamp() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return The timestamp. + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp() { + return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_; + } + /** + *
+     * OpenMetrics-style.
+     * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() { + return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < label_.size(); i++) { + output.writeMessage(1, label_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeDouble(2, value_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(3, getTimestamp()); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < label_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(1, label_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeDoubleSize(2, value_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(3, getTimestamp()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar) obj; + + if (!getLabelList() + .equals(other.getLabelList())) return false; + if (hasValue() != other.hasValue()) return false; + if (hasValue()) { + if (java.lang.Double.doubleToLongBits(getValue()) + != java.lang.Double.doubleToLongBits( + other.getValue())) return false; + } + if (hasTimestamp() != other.hasTimestamp()) return false; + if (hasTimestamp()) { + if (!getTimestamp() + .equals(other.getTimestamp())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getLabelCount() > 0) { + hash = (37 * hash) + LABEL_FIELD_NUMBER; + hash = (53 * hash) + getLabelList().hashCode(); + } + if (hasValue()) { + hash = (37 * hash) + VALUE_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + java.lang.Double.doubleToLongBits(getValue())); + } + if (hasTimestamp()) { + hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER; + hash = (53 * hash) + getTimestamp().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Exemplar} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getLabelFieldBuilder(); + getTimestampFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + if (labelBuilder_ == null) { + label_ = java.util.Collections.emptyList(); + } else { + label_ = null; + labelBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + value_ = 0D; + timestamp_ = null; + if (timestampBuilder_ != null) { + timestampBuilder_.dispose(); + timestampBuilder_ = null; + } + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result) { + if (labelBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + label_ = java.util.Collections.unmodifiableList(label_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.label_ = label_; + } else { + result.label_ = labelBuilder_.build(); + } + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.value_ = value_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.timestamp_ = timestampBuilder_ == null + ? timestamp_ + : timestampBuilder_.build(); + to_bitField0_ |= 0x00000002; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) return this; + if (labelBuilder_ == null) { + if (!other.label_.isEmpty()) { + if (label_.isEmpty()) { + label_ = other.label_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureLabelIsMutable(); + label_.addAll(other.label_); + } + onChanged(); + } + } else { + if (!other.label_.isEmpty()) { + if (labelBuilder_.isEmpty()) { + labelBuilder_.dispose(); + labelBuilder_ = null; + label_ = other.label_; + bitField0_ = (bitField0_ & ~0x00000001); + labelBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getLabelFieldBuilder() : null; + } else { + labelBuilder_.addAllMessages(other.label_); + } + } + } + if (other.hasValue()) { + setValue(other.getValue()); + } + if (other.hasTimestamp()) { + mergeTimestamp(other.getTimestamp()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.PARSER, + extensionRegistry); + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(m); + } else { + labelBuilder_.addMessage(m); + } + break; + } // case 10 + case 17: { + value_ = input.readDouble(); + bitField0_ |= 0x00000002; + break; + } // case 17 + case 26: { + input.readMessage( + getTimestampFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.util.List label_ = + java.util.Collections.emptyList(); + private void ensureLabelIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + label_ = new java.util.ArrayList(label_); + bitField0_ |= 0x00000001; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_; + + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List getLabelList() { + if (labelBuilder_ == null) { + return java.util.Collections.unmodifiableList(label_); + } else { + return labelBuilder_.getMessageList(); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public int getLabelCount() { + if (labelBuilder_ == null) { + return label_.size(); + } else { + return labelBuilder_.getCount(); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) { + if (labelBuilder_ == null) { + return label_.get(index); + } else { + return labelBuilder_.getMessage(index); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder setLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.set(index, value); + onChanged(); + } else { + labelBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder setLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.set(index, builderForValue.build()); + onChanged(); + } else { + labelBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.add(value); + onChanged(); + } else { + labelBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.add(index, value); + onChanged(); + } else { + labelBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(builderForValue.build()); + onChanged(); + } else { + labelBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(index, builderForValue.build()); + onChanged(); + } else { + labelBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addAllLabel( + java.lang.Iterable values) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, label_); + onChanged(); + } else { + labelBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder clearLabel() { + if (labelBuilder_ == null) { + label_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + labelBuilder_.clear(); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder removeLabel(int index) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.remove(index); + onChanged(); + } else { + labelBuilder_.remove(index); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder getLabelBuilder( + int index) { + return getLabelFieldBuilder().getBuilder(index); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index) { + if (labelBuilder_ == null) { + return label_.get(index); } else { + return labelBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List + getLabelOrBuilderList() { + if (labelBuilder_ != null) { + return labelBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(label_); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder() { + return getLabelFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder( + int index) { + return getLabelFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List + getLabelBuilderList() { + return getLabelFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> + getLabelFieldBuilder() { + if (labelBuilder_ == null) { + labelBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>( + label_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + label_ = null; + } + return labelBuilder_; + } + + private double value_ ; + /** + * optional double value = 2; + * @return Whether the value field is set. + */ + @java.lang.Override + public boolean hasValue() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional double value = 2; + * @return The value. + */ + @java.lang.Override + public double getValue() { + return value_; + } + /** + * optional double value = 2; + * @param value The value to set. + * @return This builder for chaining. + */ + public Builder setValue(double value) { + + value_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional double value = 2; + * @return This builder for chaining. + */ + public Builder clearValue() { + bitField0_ = (bitField0_ & ~0x00000002); + value_ = 0D; + onChanged(); + return this; + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp timestamp_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder> timestampBuilder_; + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return Whether the timestamp field is set. + */ + public boolean hasTimestamp() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + * @return The timestamp. + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp() { + if (timestampBuilder_ == null) { + return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_; + } else { + return timestampBuilder_.getMessage(); + } + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public Builder setTimestamp(io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp value) { + if (timestampBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + timestamp_ = value; + } else { + timestampBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public Builder setTimestamp( + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) { + if (timestampBuilder_ == null) { + timestamp_ = builderForValue.build(); + } else { + timestampBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public Builder mergeTimestamp(io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp value) { + if (timestampBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + timestamp_ != null && + timestamp_ != io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) { + getTimestampBuilder().mergeFrom(value); + } else { + timestamp_ = value; + } + } else { + timestampBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public Builder clearTimestamp() { + bitField0_ = (bitField0_ & ~0x00000004); + timestamp_ = null; + if (timestampBuilder_ != null) { + timestampBuilder_.dispose(); + timestampBuilder_ = null; + } + onChanged(); + return this; + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder getTimestampBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getTimestampFieldBuilder().getBuilder(); + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() { + if (timestampBuilder_ != null) { + return timestampBuilder_.getMessageOrBuilder(); + } else { + return timestamp_ == null ? + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_; + } + } + /** + *
+       * OpenMetrics-style.
+       * 
+ * + * optional .google.protobuf.Timestamp timestamp = 3; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder> + getTimestampFieldBuilder() { + if (timestampBuilder_ == null) { + timestampBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder>( + getTimestamp(), + getParentForChildren(), + isClean()); + timestamp_ = null; + } + return timestampBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Exemplar) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Exemplar parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface MetricOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.Metric) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + java.util.List + getLabelList(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + int getLabelCount(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + java.util.List + getLabelOrBuilderList(); + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index); + + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return Whether the gauge field is set. + */ + boolean hasGauge(); + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return The gauge. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge(); + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder(); + + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return Whether the counter field is set. + */ + boolean hasCounter(); + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return The counter. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter(); + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder(); + + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return Whether the summary field is set. + */ + boolean hasSummary(); + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return The summary. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary(); + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder(); + + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return Whether the untyped field is set. + */ + boolean hasUntyped(); + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return The untyped. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped(); + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder(); + + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return Whether the histogram field is set. + */ + boolean hasHistogram(); + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return The histogram. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram(); + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder(); + + /** + * optional int64 timestamp_ms = 6; + * @return Whether the timestampMs field is set. + */ + boolean hasTimestampMs(); + /** + * optional int64 timestamp_ms = 6; + * @return The timestampMs. + */ + long getTimestampMs(); + } + /** + * Protobuf type {@code io.prometheus.client.Metric} + */ + public static final class Metric extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.Metric) + MetricOrBuilder { + private static final long serialVersionUID = 0L; + // Use Metric.newBuilder() to construct. + private Metric(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Metric() { + label_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Metric(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder.class); + } + + private int bitField0_; + public static final int LABEL_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private java.util.List label_; + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public java.util.List getLabelList() { + return label_; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public java.util.List + getLabelOrBuilderList() { + return label_; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public int getLabelCount() { + return label_.size(); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) { + return label_.get(index); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index) { + return label_.get(index); + } + + public static final int GAUGE_FIELD_NUMBER = 2; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge gauge_; + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return Whether the gauge field is set. + */ + @java.lang.Override + public boolean hasGauge() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return The gauge. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge() { + return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_; + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder() { + return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_; + } + + public static final int COUNTER_FIELD_NUMBER = 3; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter counter_; + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return Whether the counter field is set. + */ + @java.lang.Override + public boolean hasCounter() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return The counter. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter() { + return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_; + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder() { + return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_; + } + + public static final int SUMMARY_FIELD_NUMBER = 4; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary summary_; + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return Whether the summary field is set. + */ + @java.lang.Override + public boolean hasSummary() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return The summary. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary() { + return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_; + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder() { + return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_; + } + + public static final int UNTYPED_FIELD_NUMBER = 5; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped untyped_; + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return Whether the untyped field is set. + */ + @java.lang.Override + public boolean hasUntyped() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return The untyped. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped() { + return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_; + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder() { + return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_; + } + + public static final int HISTOGRAM_FIELD_NUMBER = 7; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram histogram_; + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return Whether the histogram field is set. + */ + @java.lang.Override + public boolean hasHistogram() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return The histogram. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram() { + return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_; + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder() { + return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_; + } + + public static final int TIMESTAMP_MS_FIELD_NUMBER = 6; + private long timestampMs_ = 0L; + /** + * optional int64 timestamp_ms = 6; + * @return Whether the timestampMs field is set. + */ + @java.lang.Override + public boolean hasTimestampMs() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * optional int64 timestamp_ms = 6; + * @return The timestampMs. + */ + @java.lang.Override + public long getTimestampMs() { + return timestampMs_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < label_.size(); i++) { + output.writeMessage(1, label_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(2, getGauge()); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeMessage(3, getCounter()); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeMessage(4, getSummary()); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeMessage(5, getUntyped()); + } + if (((bitField0_ & 0x00000020) != 0)) { + output.writeInt64(6, timestampMs_); + } + if (((bitField0_ & 0x00000010) != 0)) { + output.writeMessage(7, getHistogram()); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < label_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(1, label_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(2, getGauge()); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(3, getCounter()); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(4, getSummary()); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(5, getUntyped()); + } + if (((bitField0_ & 0x00000020) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeInt64Size(6, timestampMs_); + } + if (((bitField0_ & 0x00000010) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(7, getHistogram()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric) obj; + + if (!getLabelList() + .equals(other.getLabelList())) return false; + if (hasGauge() != other.hasGauge()) return false; + if (hasGauge()) { + if (!getGauge() + .equals(other.getGauge())) return false; + } + if (hasCounter() != other.hasCounter()) return false; + if (hasCounter()) { + if (!getCounter() + .equals(other.getCounter())) return false; + } + if (hasSummary() != other.hasSummary()) return false; + if (hasSummary()) { + if (!getSummary() + .equals(other.getSummary())) return false; + } + if (hasUntyped() != other.hasUntyped()) return false; + if (hasUntyped()) { + if (!getUntyped() + .equals(other.getUntyped())) return false; + } + if (hasHistogram() != other.hasHistogram()) return false; + if (hasHistogram()) { + if (!getHistogram() + .equals(other.getHistogram())) return false; + } + if (hasTimestampMs() != other.hasTimestampMs()) return false; + if (hasTimestampMs()) { + if (getTimestampMs() + != other.getTimestampMs()) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getLabelCount() > 0) { + hash = (37 * hash) + LABEL_FIELD_NUMBER; + hash = (53 * hash) + getLabelList().hashCode(); + } + if (hasGauge()) { + hash = (37 * hash) + GAUGE_FIELD_NUMBER; + hash = (53 * hash) + getGauge().hashCode(); + } + if (hasCounter()) { + hash = (37 * hash) + COUNTER_FIELD_NUMBER; + hash = (53 * hash) + getCounter().hashCode(); + } + if (hasSummary()) { + hash = (37 * hash) + SUMMARY_FIELD_NUMBER; + hash = (53 * hash) + getSummary().hashCode(); + } + if (hasUntyped()) { + hash = (37 * hash) + UNTYPED_FIELD_NUMBER; + hash = (53 * hash) + getUntyped().hashCode(); + } + if (hasHistogram()) { + hash = (37 * hash) + HISTOGRAM_FIELD_NUMBER; + hash = (53 * hash) + getHistogram().hashCode(); + } + if (hasTimestampMs()) { + hash = (37 * hash) + TIMESTAMP_MS_FIELD_NUMBER; + hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong( + getTimestampMs()); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.Metric} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getLabelFieldBuilder(); + getGaugeFieldBuilder(); + getCounterFieldBuilder(); + getSummaryFieldBuilder(); + getUntypedFieldBuilder(); + getHistogramFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + if (labelBuilder_ == null) { + label_ = java.util.Collections.emptyList(); + } else { + label_ = null; + labelBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + gauge_ = null; + if (gaugeBuilder_ != null) { + gaugeBuilder_.dispose(); + gaugeBuilder_ = null; + } + counter_ = null; + if (counterBuilder_ != null) { + counterBuilder_.dispose(); + counterBuilder_ = null; + } + summary_ = null; + if (summaryBuilder_ != null) { + summaryBuilder_.dispose(); + summaryBuilder_ = null; + } + untyped_ = null; + if (untypedBuilder_ != null) { + untypedBuilder_.dispose(); + untypedBuilder_ = null; + } + histogram_ = null; + if (histogramBuilder_ != null) { + histogramBuilder_.dispose(); + histogramBuilder_ = null; + } + timestampMs_ = 0L; + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result) { + if (labelBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + label_ = java.util.Collections.unmodifiableList(label_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.label_ = label_; + } else { + result.label_ = labelBuilder_.build(); + } + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.gauge_ = gaugeBuilder_ == null + ? gauge_ + : gaugeBuilder_.build(); + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.counter_ = counterBuilder_ == null + ? counter_ + : counterBuilder_.build(); + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.summary_ = summaryBuilder_ == null + ? summary_ + : summaryBuilder_.build(); + to_bitField0_ |= 0x00000004; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.untyped_ = untypedBuilder_ == null + ? untyped_ + : untypedBuilder_.build(); + to_bitField0_ |= 0x00000008; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.histogram_ = histogramBuilder_ == null + ? histogram_ + : histogramBuilder_.build(); + to_bitField0_ |= 0x00000010; + } + if (((from_bitField0_ & 0x00000040) != 0)) { + result.timestampMs_ = timestampMs_; + to_bitField0_ |= 0x00000020; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance()) return this; + if (labelBuilder_ == null) { + if (!other.label_.isEmpty()) { + if (label_.isEmpty()) { + label_ = other.label_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureLabelIsMutable(); + label_.addAll(other.label_); + } + onChanged(); + } + } else { + if (!other.label_.isEmpty()) { + if (labelBuilder_.isEmpty()) { + labelBuilder_.dispose(); + labelBuilder_ = null; + label_ = other.label_; + bitField0_ = (bitField0_ & ~0x00000001); + labelBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getLabelFieldBuilder() : null; + } else { + labelBuilder_.addAllMessages(other.label_); + } + } + } + if (other.hasGauge()) { + mergeGauge(other.getGauge()); + } + if (other.hasCounter()) { + mergeCounter(other.getCounter()); + } + if (other.hasSummary()) { + mergeSummary(other.getSummary()); + } + if (other.hasUntyped()) { + mergeUntyped(other.getUntyped()); + } + if (other.hasHistogram()) { + mergeHistogram(other.getHistogram()); + } + if (other.hasTimestampMs()) { + setTimestampMs(other.getTimestampMs()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.PARSER, + extensionRegistry); + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(m); + } else { + labelBuilder_.addMessage(m); + } + break; + } // case 10 + case 18: { + input.readMessage( + getGaugeFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + input.readMessage( + getCounterFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000004; + break; + } // case 26 + case 34: { + input.readMessage( + getSummaryFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000008; + break; + } // case 34 + case 42: { + input.readMessage( + getUntypedFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000010; + break; + } // case 42 + case 48: { + timestampMs_ = input.readInt64(); + bitField0_ |= 0x00000040; + break; + } // case 48 + case 58: { + input.readMessage( + getHistogramFieldBuilder().getBuilder(), + extensionRegistry); + bitField0_ |= 0x00000020; + break; + } // case 58 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.util.List label_ = + java.util.Collections.emptyList(); + private void ensureLabelIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + label_ = new java.util.ArrayList(label_); + bitField0_ |= 0x00000001; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_; + + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List getLabelList() { + if (labelBuilder_ == null) { + return java.util.Collections.unmodifiableList(label_); + } else { + return labelBuilder_.getMessageList(); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public int getLabelCount() { + if (labelBuilder_ == null) { + return label_.size(); + } else { + return labelBuilder_.getCount(); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) { + if (labelBuilder_ == null) { + return label_.get(index); + } else { + return labelBuilder_.getMessage(index); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder setLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.set(index, value); + onChanged(); + } else { + labelBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder setLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.set(index, builderForValue.build()); + onChanged(); + } else { + labelBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.add(value); + onChanged(); + } else { + labelBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) { + if (labelBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.add(index, value); + onChanged(); + } else { + labelBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(builderForValue.build()); + onChanged(); + } else { + labelBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addLabel( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.add(index, builderForValue.build()); + onChanged(); + } else { + labelBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder addAllLabel( + java.lang.Iterable values) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, label_); + onChanged(); + } else { + labelBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder clearLabel() { + if (labelBuilder_ == null) { + label_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + labelBuilder_.clear(); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public Builder removeLabel(int index) { + if (labelBuilder_ == null) { + ensureLabelIsMutable(); + label_.remove(index); + onChanged(); + } else { + labelBuilder_.remove(index); + } + return this; + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder getLabelBuilder( + int index) { + return getLabelFieldBuilder().getBuilder(index); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder( + int index) { + if (labelBuilder_ == null) { + return label_.get(index); } else { + return labelBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List + getLabelOrBuilderList() { + if (labelBuilder_ != null) { + return labelBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(label_); + } + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder() { + return getLabelFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder( + int index) { + return getLabelFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.LabelPair label = 1; + */ + public java.util.List + getLabelBuilderList() { + return getLabelFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> + getLabelFieldBuilder() { + if (labelBuilder_ == null) { + labelBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>( + label_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + label_ = null; + } + return labelBuilder_; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge gauge_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> gaugeBuilder_; + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return Whether the gauge field is set. + */ + public boolean hasGauge() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + * @return The gauge. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge() { + if (gaugeBuilder_ == null) { + return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_; + } else { + return gaugeBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge value) { + if (gaugeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + gauge_ = value; + } else { + gaugeBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public Builder setGauge( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder builderForValue) { + if (gaugeBuilder_ == null) { + gauge_ = builderForValue.build(); + } else { + gaugeBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge value) { + if (gaugeBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0) && + gauge_ != null && + gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance()) { + getGaugeBuilder().mergeFrom(value); + } else { + gauge_ = value; + } + } else { + gaugeBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public Builder clearGauge() { + bitField0_ = (bitField0_ & ~0x00000002); + gauge_ = null; + if (gaugeBuilder_ != null) { + gaugeBuilder_.dispose(); + gaugeBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder getGaugeBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getGaugeFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder() { + if (gaugeBuilder_ != null) { + return gaugeBuilder_.getMessageOrBuilder(); + } else { + return gauge_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_; + } + } + /** + * optional .io.prometheus.client.Gauge gauge = 2; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> + getGaugeFieldBuilder() { + if (gaugeBuilder_ == null) { + gaugeBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder>( + getGauge(), + getParentForChildren(), + isClean()); + gauge_ = null; + } + return gaugeBuilder_; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter counter_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> counterBuilder_; + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return Whether the counter field is set. + */ + public boolean hasCounter() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional .io.prometheus.client.Counter counter = 3; + * @return The counter. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter() { + if (counterBuilder_ == null) { + return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_; + } else { + return counterBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter value) { + if (counterBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + counter_ = value; + } else { + counterBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public Builder setCounter( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder builderForValue) { + if (counterBuilder_ == null) { + counter_ = builderForValue.build(); + } else { + counterBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter value) { + if (counterBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) && + counter_ != null && + counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance()) { + getCounterBuilder().mergeFrom(value); + } else { + counter_ = value; + } + } else { + counterBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public Builder clearCounter() { + bitField0_ = (bitField0_ & ~0x00000004); + counter_ = null; + if (counterBuilder_ != null) { + counterBuilder_.dispose(); + counterBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder getCounterBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getCounterFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder() { + if (counterBuilder_ != null) { + return counterBuilder_.getMessageOrBuilder(); + } else { + return counter_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_; + } + } + /** + * optional .io.prometheus.client.Counter counter = 3; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> + getCounterFieldBuilder() { + if (counterBuilder_ == null) { + counterBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder>( + getCounter(), + getParentForChildren(), + isClean()); + counter_ = null; + } + return counterBuilder_; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary summary_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> summaryBuilder_; + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return Whether the summary field is set. + */ + public boolean hasSummary() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .io.prometheus.client.Summary summary = 4; + * @return The summary. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary() { + if (summaryBuilder_ == null) { + return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_; + } else { + return summaryBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary value) { + if (summaryBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + summary_ = value; + } else { + summaryBuilder_.setMessage(value); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public Builder setSummary( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder builderForValue) { + if (summaryBuilder_ == null) { + summary_ = builderForValue.build(); + } else { + summaryBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary value) { + if (summaryBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0) && + summary_ != null && + summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance()) { + getSummaryBuilder().mergeFrom(value); + } else { + summary_ = value; + } + } else { + summaryBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public Builder clearSummary() { + bitField0_ = (bitField0_ & ~0x00000008); + summary_ = null; + if (summaryBuilder_ != null) { + summaryBuilder_.dispose(); + summaryBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder getSummaryBuilder() { + bitField0_ |= 0x00000008; + onChanged(); + return getSummaryFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder() { + if (summaryBuilder_ != null) { + return summaryBuilder_.getMessageOrBuilder(); + } else { + return summary_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_; + } + } + /** + * optional .io.prometheus.client.Summary summary = 4; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> + getSummaryFieldBuilder() { + if (summaryBuilder_ == null) { + summaryBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder>( + getSummary(), + getParentForChildren(), + isClean()); + summary_ = null; + } + return summaryBuilder_; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped untyped_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> untypedBuilder_; + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return Whether the untyped field is set. + */ + public boolean hasUntyped() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + * @return The untyped. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped() { + if (untypedBuilder_ == null) { + return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_; + } else { + return untypedBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped value) { + if (untypedBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + untyped_ = value; + } else { + untypedBuilder_.setMessage(value); + } + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public Builder setUntyped( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder builderForValue) { + if (untypedBuilder_ == null) { + untyped_ = builderForValue.build(); + } else { + untypedBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped value) { + if (untypedBuilder_ == null) { + if (((bitField0_ & 0x00000010) != 0) && + untyped_ != null && + untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance()) { + getUntypedBuilder().mergeFrom(value); + } else { + untyped_ = value; + } + } else { + untypedBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public Builder clearUntyped() { + bitField0_ = (bitField0_ & ~0x00000010); + untyped_ = null; + if (untypedBuilder_ != null) { + untypedBuilder_.dispose(); + untypedBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder getUntypedBuilder() { + bitField0_ |= 0x00000010; + onChanged(); + return getUntypedFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder() { + if (untypedBuilder_ != null) { + return untypedBuilder_.getMessageOrBuilder(); + } else { + return untyped_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_; + } + } + /** + * optional .io.prometheus.client.Untyped untyped = 5; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> + getUntypedFieldBuilder() { + if (untypedBuilder_ == null) { + untypedBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder>( + getUntyped(), + getParentForChildren(), + isClean()); + untyped_ = null; + } + return untypedBuilder_; + } + + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram histogram_; + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> histogramBuilder_; + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return Whether the histogram field is set. + */ + public boolean hasHistogram() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + * @return The histogram. + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram() { + if (histogramBuilder_ == null) { + return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_; + } else { + return histogramBuilder_.getMessage(); + } + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram value) { + if (histogramBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + histogram_ = value; + } else { + histogramBuilder_.setMessage(value); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public Builder setHistogram( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder builderForValue) { + if (histogramBuilder_ == null) { + histogram_ = builderForValue.build(); + } else { + histogramBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram value) { + if (histogramBuilder_ == null) { + if (((bitField0_ & 0x00000020) != 0) && + histogram_ != null && + histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance()) { + getHistogramBuilder().mergeFrom(value); + } else { + histogram_ = value; + } + } else { + histogramBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public Builder clearHistogram() { + bitField0_ = (bitField0_ & ~0x00000020); + histogram_ = null; + if (histogramBuilder_ != null) { + histogramBuilder_.dispose(); + histogramBuilder_ = null; + } + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder getHistogramBuilder() { + bitField0_ |= 0x00000020; + onChanged(); + return getHistogramFieldBuilder().getBuilder(); + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder() { + if (histogramBuilder_ != null) { + return histogramBuilder_.getMessageOrBuilder(); + } else { + return histogram_ == null ? + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_; + } + } + /** + * optional .io.prometheus.client.Histogram histogram = 7; + */ + private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> + getHistogramFieldBuilder() { + if (histogramBuilder_ == null) { + histogramBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder>( + getHistogram(), + getParentForChildren(), + isClean()); + histogram_ = null; + } + return histogramBuilder_; + } + + private long timestampMs_ ; + /** + * optional int64 timestamp_ms = 6; + * @return Whether the timestampMs field is set. + */ + @java.lang.Override + public boolean hasTimestampMs() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + * optional int64 timestamp_ms = 6; + * @return The timestampMs. + */ + @java.lang.Override + public long getTimestampMs() { + return timestampMs_; + } + /** + * optional int64 timestamp_ms = 6; + * @param value The timestampMs to set. + * @return This builder for chaining. + */ + public Builder setTimestampMs(long value) { + + timestampMs_ = value; + bitField0_ |= 0x00000040; + onChanged(); + return this; + } + /** + * optional int64 timestamp_ms = 6; + * @return This builder for chaining. + */ + public Builder clearTimestampMs() { + bitField0_ = (bitField0_ & ~0x00000040); + timestampMs_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.Metric) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public Metric parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface MetricFamilyOrBuilder extends + // @@protoc_insertion_point(interface_extends:io.prometheus.client.MetricFamily) + io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + boolean hasName(); + /** + * optional string name = 1; + * @return The name. + */ + java.lang.String getName(); + /** + * optional string name = 1; + * @return The bytes for name. + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes(); + + /** + * optional string help = 2; + * @return Whether the help field is set. + */ + boolean hasHelp(); + /** + * optional string help = 2; + * @return The help. + */ + java.lang.String getHelp(); + /** + * optional string help = 2; + * @return The bytes for help. + */ + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getHelpBytes(); + + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return Whether the type field is set. + */ + boolean hasType(); + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return The type. + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType(); + + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + java.util.List + getMetricList(); + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index); + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + int getMetricCount(); + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + java.util.List + getMetricOrBuilderList(); + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder( + int index); + } + /** + * Protobuf type {@code io.prometheus.client.MetricFamily} + */ + public static final class MetricFamily extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:io.prometheus.client.MetricFamily) + MetricFamilyOrBuilder { + private static final long serialVersionUID = 0L; + // Use MetricFamily.newBuilder() to construct. + private MetricFamily(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + super(builder); + } + private MetricFamily() { + name_ = ""; + help_ = ""; + type_ = 0; + metric_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new MetricFamily(); + } + + @java.lang.Override + public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.Builder.class); + } + + private int bitField0_; + public static final int NAME_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private volatile java.lang.Object name_ = ""; + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + @java.lang.Override + public boolean hasName() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional string name = 1; + * @return The name. + */ + @java.lang.Override + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } + } + /** + * optional string name = 1; + * @return The bytes for name. + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + + public static final int HELP_FIELD_NUMBER = 2; + @SuppressWarnings("serial") + private volatile java.lang.Object help_ = ""; + /** + * optional string help = 2; + * @return Whether the help field is set. + */ + @java.lang.Override + public boolean hasHelp() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string help = 2; + * @return The help. + */ + @java.lang.Override + public java.lang.String getHelp() { + java.lang.Object ref = help_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + help_ = s; + } + return s; + } + } + /** + * optional string help = 2; + * @return The bytes for help. + */ + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getHelpBytes() { + java.lang.Object ref = help_; + if (ref instanceof java.lang.String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + help_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + + public static final int TYPE_FIELD_NUMBER = 3; + private int type_ = 0; + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return The type. + */ + @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(type_); + return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.COUNTER : result; + } + + public static final int METRIC_FIELD_NUMBER = 4; + @SuppressWarnings("serial") + private java.util.List metric_; + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + @java.lang.Override + public java.util.List getMetricList() { + return metric_; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + @java.lang.Override + public java.util.List + getMetricOrBuilderList() { + return metric_; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + @java.lang.Override + public int getMetricCount() { + return metric_.size(); + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index) { + return metric_.get(index); + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder( + int index) { + return metric_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_); + } + if (((bitField0_ & 0x00000002) != 0)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, help_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeEnum(3, type_); + } + for (int i = 0; i < metric_.size(); i++) { + output.writeMessage(4, metric_.get(i)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, help_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeEnumSize(3, type_); + } + for (int i = 0; i < metric_.size(); i++) { + size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream + .computeMessageSize(4, metric_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily)) { + return super.equals(obj); + } + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily) obj; + + if (hasName() != other.hasName()) return false; + if (hasName()) { + if (!getName() + .equals(other.getName())) return false; + } + if (hasHelp() != other.hasHelp()) return false; + if (hasHelp()) { + if (!getHelp() + .equals(other.getHelp())) return false; + } + if (hasType() != other.hasType()) return false; + if (hasType()) { + if (type_ != other.type_) return false; + } + if (!getMetricList() + .equals(other.getMetricList())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasName()) { + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + } + if (hasHelp()) { + hash = (37 * hash) + HELP_FIELD_NUMBER; + hash = (53 * hash) + getHelp().hashCode(); + } + if (hasType()) { + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + type_; + } + if (getMetricCount() > 0) { + hash = (37 * hash) + METRIC_FIELD_NUMBER; + hash = (53 * hash) + getMetricList().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + java.nio.ByteBuffer data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + java.nio.ByteBuffer data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(byte[] data) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + byte[] data, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom( + java.io.InputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code io.prometheus.client.MetricFamily} + */ + public static final class Builder extends + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily) + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamilyOrBuilder { + public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptor() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor; + } + + @java.lang.Override + protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable + .ensureFieldAccessorsInitialized( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.Builder.class); + } + + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.newBuilder() + private Builder() { + + } + + private Builder( + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + name_ = ""; + help_ = ""; + type_ = 0; + if (metricBuilder_ == null) { + metric_ = java.util.Collections.emptyList(); + } else { + metric_ = null; + metricBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + getDescriptorForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.getDefaultInstance(); + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result) { + if (metricBuilder_ == null) { + if (((bitField0_ & 0x00000008) != 0)) { + metric_ = java.util.Collections.unmodifiableList(metric_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.metric_ = metric_; + } else { + result.metric_ = metricBuilder_.build(); + } + } + + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.name_ = name_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.help_ = help_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.type_ = type_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.getDefaultInstance()) return this; + if (other.hasName()) { + name_ = other.name_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (other.hasHelp()) { + help_ = other.help_; + bitField0_ |= 0x00000002; + onChanged(); + } + if (other.hasType()) { + setType(other.getType()); + } + if (metricBuilder_ == null) { + if (!other.metric_.isEmpty()) { + if (metric_.isEmpty()) { + metric_ = other.metric_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureMetricIsMutable(); + metric_.addAll(other.metric_); + } + onChanged(); + } + } else { + if (!other.metric_.isEmpty()) { + if (metricBuilder_.isEmpty()) { + metricBuilder_.dispose(); + metricBuilder_ = null; + metric_ = other.metric_; + bitField0_ = (bitField0_ & ~0x00000008); + metricBuilder_ = + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + getMetricFieldBuilder() : null; + } else { + metricBuilder_.addAllMessages(other.metric_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + name_ = input.readBytes(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + help_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 24: { + int tmpRaw = input.readEnum(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType tmpValue = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(tmpRaw); + if (tmpValue == null) { + mergeUnknownVarintField(3, tmpRaw); + } else { + type_ = tmpRaw; + bitField0_ |= 0x00000004; + } + break; + } // case 24 + case 34: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.PARSER, + extensionRegistry); + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + metric_.add(m); + } else { + metricBuilder_.addMessage(m); + } + break; + } // case 34 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.lang.Object name_ = ""; + /** + * optional string name = 1; + * @return Whether the name field is set. + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * optional string name = 1; + * @return The name. + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + name_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string name = 1; + * @return The bytes for name. + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + /** + * optional string name = 1; + * @param value The name to set. + * @return This builder for chaining. + */ + public Builder setName( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * optional string name = 1; + * @return This builder for chaining. + */ + public Builder clearName() { + name_ = getDefaultInstance().getName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * optional string name = 1; + * @param value The bytes for name to set. + * @return This builder for chaining. + */ + public Builder setNameBytes( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) { + if (value == null) { throw new NullPointerException(); } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private java.lang.Object help_ = ""; + /** + * optional string help = 2; + * @return Whether the help field is set. + */ + public boolean hasHelp() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional string help = 2; + * @return The help. + */ + public java.lang.String getHelp() { + java.lang.Object ref = help_; + if (!(ref instanceof java.lang.String)) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = + (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + help_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string help = 2; + * @return The bytes for help. + */ + public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString + getHelpBytes() { + java.lang.Object ref = help_; + if (ref instanceof String) { + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8( + (java.lang.String) ref); + help_ = b; + return b; + } else { + return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref; + } + } + /** + * optional string help = 2; + * @param value The help to set. + * @return This builder for chaining. + */ + public Builder setHelp( + java.lang.String value) { + if (value == null) { throw new NullPointerException(); } + help_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + * optional string help = 2; + * @return This builder for chaining. + */ + public Builder clearHelp() { + help_ = getDefaultInstance().getHelp(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + /** + * optional string help = 2; + * @param value The bytes for help to set. + * @return This builder for chaining. + */ + public Builder setHelpBytes( + io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) { + if (value == null) { throw new NullPointerException(); } + help_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + + private int type_ = 0; + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return The type. + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(type_); + return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.COUNTER : result; + } + /** + * optional .io.prometheus.client.MetricType type = 3; + * @param value The type to set. + * @return This builder for chaining. + */ + public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + type_ = value.getNumber(); + onChanged(); + return this; + } + /** + * optional .io.prometheus.client.MetricType type = 3; + * @return This builder for chaining. + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000004); + type_ = 0; + onChanged(); + return this; + } + + private java.util.List metric_ = + java.util.Collections.emptyList(); + private void ensureMetricIsMutable() { + if (!((bitField0_ & 0x00000008) != 0)) { + metric_ = new java.util.ArrayList(metric_); + bitField0_ |= 0x00000008; + } + } + + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> metricBuilder_; + + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public java.util.List getMetricList() { + if (metricBuilder_ == null) { + return java.util.Collections.unmodifiableList(metric_); + } else { + return metricBuilder_.getMessageList(); + } + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public int getMetricCount() { + if (metricBuilder_ == null) { + return metric_.size(); + } else { + return metricBuilder_.getCount(); + } + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index) { + if (metricBuilder_ == null) { + return metric_.get(index); + } else { + return metricBuilder_.getMessage(index); + } + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder setMetric( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) { + if (metricBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMetricIsMutable(); + metric_.set(index, value); + onChanged(); + } else { + metricBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder setMetric( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) { + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + metric_.set(index, builderForValue.build()); + onChanged(); + } else { + metricBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) { + if (metricBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMetricIsMutable(); + metric_.add(value); + onChanged(); + } else { + metricBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder addMetric( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) { + if (metricBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMetricIsMutable(); + metric_.add(index, value); + onChanged(); + } else { + metricBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder addMetric( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) { + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + metric_.add(builderForValue.build()); + onChanged(); + } else { + metricBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder addMetric( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) { + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + metric_.add(index, builderForValue.build()); + onChanged(); + } else { + metricBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder addAllMetric( + java.lang.Iterable values) { + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + values, metric_); + onChanged(); + } else { + metricBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder clearMetric() { + if (metricBuilder_ == null) { + metric_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + metricBuilder_.clear(); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public Builder removeMetric(int index) { + if (metricBuilder_ == null) { + ensureMetricIsMutable(); + metric_.remove(index); + onChanged(); + } else { + metricBuilder_.remove(index); + } + return this; + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder getMetricBuilder( + int index) { + return getMetricFieldBuilder().getBuilder(index); + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder( + int index) { + if (metricBuilder_ == null) { + return metric_.get(index); } else { + return metricBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public java.util.List + getMetricOrBuilderList() { + if (metricBuilder_ != null) { + return metricBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(metric_); + } + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder addMetricBuilder() { + return getMetricFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder addMetricBuilder( + int index) { + return getMetricFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance()); + } + /** + * repeated .io.prometheus.client.Metric metric = 4; + */ + public java.util.List + getMetricBuilderList() { + return getMetricFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> + getMetricFieldBuilder() { + if (metricBuilder_ == null) { + metricBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder>( + metric_, + ((bitField0_ & 0x00000008) != 0), + getParentForChildren(), + isClean()); + metric_ = null; + } + return metricBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:io.prometheus.client.MetricFamily) + } + + // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily) + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily(); + } + + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Override + public MetricFamily parsePartialFrom( + io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_LabelPair_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_LabelPair_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Gauge_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Gauge_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Counter_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Counter_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Quantile_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Quantile_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Summary_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Summary_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Untyped_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Untyped_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Histogram_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Histogram_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Bucket_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Bucket_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_BucketSpan_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Exemplar_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Exemplar_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_Metric_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_Metric_fieldAccessorTable; + private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + internal_static_io_prometheus_client_MetricFamily_descriptor; + private static final + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable; + + public static io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\037src/main/protobuf/metrics.proto\022\024io.pr" + + "ometheus.client\032\037google/protobuf/timesta" + + "mp.proto\"(\n\tLabelPair\022\014\n\004name\030\001 \001(\t\022\r\n\005v" + + "alue\030\002 \001(\t\"\026\n\005Gauge\022\r\n\005value\030\001 \001(\001\"J\n\007Co" + + "unter\022\r\n\005value\030\001 \001(\001\0220\n\010exemplar\030\002 \001(\0132\036" + + ".io.prometheus.client.Exemplar\"+\n\010Quanti" + + "le\022\020\n\010quantile\030\001 \001(\001\022\r\n\005value\030\002 \001(\001\"e\n\007S" + + "ummary\022\024\n\014sample_count\030\001 \001(\004\022\022\n\nsample_s" + + "um\030\002 \001(\001\0220\n\010quantile\030\003 \003(\0132\036.io.promethe" + + "us.client.Quantile\"\030\n\007Untyped\022\r\n\005value\030\001" + + " \001(\001\"\247\003\n\tHistogram\022\024\n\014sample_count\030\001 \001(\004" + + "\022\032\n\022sample_count_float\030\004 \001(\001\022\022\n\nsample_s" + + "um\030\002 \001(\001\022,\n\006bucket\030\003 \003(\0132\034.io.prometheus" + + ".client.Bucket\022\016\n\006schema\030\005 \001(\021\022\026\n\016zero_t" + + "hreshold\030\006 \001(\001\022\022\n\nzero_count\030\007 \001(\004\022\030\n\020ze" + + "ro_count_float\030\010 \001(\001\0227\n\rnegative_span\030\t " + + "\003(\0132 .io.prometheus.client.BucketSpan\022\026\n" + + "\016negative_delta\030\n \003(\022\022\026\n\016negative_count\030" + + "\013 \003(\001\0227\n\rpositive_span\030\014 \003(\0132 .io.promet" + + "heus.client.BucketSpan\022\026\n\016positive_delta" + + "\030\r \003(\022\022\026\n\016positive_count\030\016 \003(\001\"\211\001\n\006Bucke" + + "t\022\030\n\020cumulative_count\030\001 \001(\004\022\036\n\026cumulativ" + + "e_count_float\030\004 \001(\001\022\023\n\013upper_bound\030\002 \001(\001" + + "\0220\n\010exemplar\030\003 \001(\0132\036.io.prometheus.clien" + + "t.Exemplar\",\n\nBucketSpan\022\016\n\006offset\030\001 \001(\021" + + "\022\016\n\006length\030\002 \001(\r\"x\n\010Exemplar\022.\n\005label\030\001 " + + "\003(\0132\037.io.prometheus.client.LabelPair\022\r\n\005" + + "value\030\002 \001(\001\022-\n\ttimestamp\030\003 \001(\0132\032.google." + + "protobuf.Timestamp\"\276\002\n\006Metric\022.\n\005label\030\001" + + " \003(\0132\037.io.prometheus.client.LabelPair\022*\n" + + "\005gauge\030\002 \001(\0132\033.io.prometheus.client.Gaug" + + "e\022.\n\007counter\030\003 \001(\0132\035.io.prometheus.clien" + + "t.Counter\022.\n\007summary\030\004 \001(\0132\035.io.promethe" + + "us.client.Summary\022.\n\007untyped\030\005 \001(\0132\035.io." + + "prometheus.client.Untyped\0222\n\thistogram\030\007" + + " \001(\0132\037.io.prometheus.client.Histogram\022\024\n" + + "\014timestamp_ms\030\006 \001(\003\"\210\001\n\014MetricFamily\022\014\n\004" + + "name\030\001 \001(\t\022\014\n\004help\030\002 \001(\t\022.\n\004type\030\003 \001(\0162 " + + ".io.prometheus.client.MetricType\022,\n\006metr" + + "ic\030\004 \003(\0132\034.io.prometheus.client.Metric*b" + + "\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUGE\020\001\022\013\n\007" + + "SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n" + + "\017GAUGE_HISTOGRAM\020\005B\212\001\nLio.prometheus.met" + + "rics.expositionformats.generated.com_goo" + + "gle_protobuf_3_21_7Z:github.com/promethe" + + "us/client_model/go;io_prometheus_client" + }; + descriptor = io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor[] { + io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampProto.getDescriptor(), + }); + internal_static_io_prometheus_client_LabelPair_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_io_prometheus_client_LabelPair_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_LabelPair_descriptor, + new java.lang.String[] { "Name", "Value", }); + internal_static_io_prometheus_client_Gauge_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_io_prometheus_client_Gauge_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Gauge_descriptor, + new java.lang.String[] { "Value", }); + internal_static_io_prometheus_client_Counter_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_io_prometheus_client_Counter_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Counter_descriptor, + new java.lang.String[] { "Value", "Exemplar", }); + internal_static_io_prometheus_client_Quantile_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_io_prometheus_client_Quantile_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Quantile_descriptor, + new java.lang.String[] { "Quantile", "Value", }); + internal_static_io_prometheus_client_Summary_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_io_prometheus_client_Summary_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Summary_descriptor, + new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", }); + internal_static_io_prometheus_client_Untyped_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_io_prometheus_client_Untyped_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Untyped_descriptor, + new java.lang.String[] { "Value", }); + internal_static_io_prometheus_client_Histogram_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_io_prometheus_client_Histogram_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Histogram_descriptor, + new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", }); + internal_static_io_prometheus_client_Bucket_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_io_prometheus_client_Bucket_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Bucket_descriptor, + new java.lang.String[] { "CumulativeCount", "CumulativeCountFloat", "UpperBound", "Exemplar", }); + internal_static_io_prometheus_client_BucketSpan_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_BucketSpan_descriptor, + new java.lang.String[] { "Offset", "Length", }); + internal_static_io_prometheus_client_Exemplar_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_io_prometheus_client_Exemplar_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Exemplar_descriptor, + new java.lang.String[] { "Label", "Value", "Timestamp", }); + internal_static_io_prometheus_client_Metric_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_io_prometheus_client_Metric_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_Metric_descriptor, + new java.lang.String[] { "Label", "Gauge", "Counter", "Summary", "Untyped", "Histogram", "TimestampMs", }); + internal_static_io_prometheus_client_MetricFamily_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable = new + io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable( + internal_static_io_prometheus_client_MetricFamily_descriptor, + new java.lang.String[] { "Name", "Help", "Type", "Metric", }); + io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampProto.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java new file mode 100644 index 000000000..2d1ce9dcd --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java @@ -0,0 +1,12 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.MetricSnapshots; + +import java.io.IOException; +import java.io.OutputStream; + +public interface ExpositionFormatWriter { + boolean accepts(String acceptHeader); + void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException; + String getContentType(); +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java new file mode 100644 index 000000000..f913753cd --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java @@ -0,0 +1,53 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.config.ExporterProperties; +import io.prometheus.metrics.config.PrometheusProperties; + +public class ExpositionFormats { + + private final PrometheusProtobufWriter prometheusProtobufWriter; + private final PrometheusTextFormatWriter prometheusTextFormatWriter; + private final OpenMetricsTextFormatWriter openMetricsTextFormatWriter; + + private ExpositionFormats(PrometheusProtobufWriter prometheusProtobufWriter, + PrometheusTextFormatWriter prometheusTextFormatWriter, + OpenMetricsTextFormatWriter openMetricsTextFormatWriter) { + this.prometheusProtobufWriter = prometheusProtobufWriter; + this.prometheusTextFormatWriter = prometheusTextFormatWriter; + this.openMetricsTextFormatWriter = openMetricsTextFormatWriter; + } + + public static ExpositionFormats init() { + return init(PrometheusProperties.get().getExporterProperties()); + } + + public static ExpositionFormats init(ExporterProperties properties) { + return new ExpositionFormats( + new PrometheusProtobufWriter(), + new PrometheusTextFormatWriter(properties.getIncludeCreatedTimestamps()), + new OpenMetricsTextFormatWriter(properties.getIncludeCreatedTimestamps(), properties.getExemplarsOnAllMetricTypes()) + ); + } + + public ExpositionFormatWriter findWriter(String acceptHeader) { + if (prometheusProtobufWriter.accepts(acceptHeader)) { + return prometheusProtobufWriter; + } + if (openMetricsTextFormatWriter.accepts(acceptHeader)) { + return openMetricsTextFormatWriter; + } + return prometheusTextFormatWriter; + } + + public PrometheusProtobufWriter getPrometheusProtobufWriter() { + return prometheusProtobufWriter; + } + + public PrometheusTextFormatWriter getPrometheusTextFormatWriter() { + return prometheusTextFormatWriter; + } + + public OpenMetricsTextFormatWriter getOpenMetricsTextFormatWriter() { + return openMetricsTextFormatWriter; + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java new file mode 100644 index 000000000..0559ce0be --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -0,0 +1,341 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DistributionDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; + +/** + * Write the OpenMetrics text format as defined on https://openmetrics.io. + */ +public class OpenMetricsTextFormatWriter implements ExpositionFormatWriter { + + public static final String CONTENT_TYPE = "application/openmetrics-text; version=1.0.0; charset=utf-8"; + private final boolean createdTimestampsEnabled; + private final boolean exemplarsOnAllMetricTypesEnabled; + + /** + * @param createdTimestampsEnabled defines if {@code _created} timestamps should be included in the output or not. + */ + public OpenMetricsTextFormatWriter(boolean createdTimestampsEnabled, boolean exemplarsOnAllMetricTypesEnabled) { + this.createdTimestampsEnabled = createdTimestampsEnabled; + this.exemplarsOnAllMetricTypesEnabled = exemplarsOnAllMetricTypesEnabled; + } + + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } + return acceptHeader.contains("application/openmetrics-text"); + } + + @Override + public String getContentType() { + return CONTENT_TYPE; + } + + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getData().size() > 0) { + if (snapshot instanceof CounterSnapshot) { + writeCounter(writer, (CounterSnapshot) snapshot); + } else if (snapshot instanceof GaugeSnapshot) { + writeGauge(writer, (GaugeSnapshot) snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeHistogram(writer, (HistogramSnapshot) snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeSummary(writer, (SummarySnapshot) snapshot); + } else if (snapshot instanceof InfoSnapshot) { + writeInfo(writer, (InfoSnapshot) snapshot); + } else if (snapshot instanceof StateSetSnapshot) { + writeStateSet(writer, (StateSetSnapshot) snapshot); + } else if (snapshot instanceof UnknownSnapshot) { + writeUnknown(writer, (UnknownSnapshot) snapshot); + } + } + } + writer.write("# EOF\n"); + writer.flush(); + } + + private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "counter", metadata); + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), "_total", data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + writeCreated(writer, metadata, data); + } + } + + private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "gauge", metadata); + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + } + + private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + if (snapshot.isGaugeHistogram()) { + writeMetadata(writer, "gaugehistogram", metadata); + writeClassicHistogramBuckets(writer, metadata, "_gcount", "_gsum", snapshot.getData()); + } else { + writeMetadata(writer, "histogram", metadata); + writeClassicHistogramBuckets(writer, metadata, "_count", "_sum", snapshot.getData()); + } + } + + private void writeClassicHistogramBuckets(OutputStreamWriter writer, MetricMetadata metadata, String countSuffix, String sumSuffix, List dataList) throws IOException { + for (HistogramSnapshot.HistogramDataPointSnapshot data : dataList) { + ClassicHistogramBuckets buckets = getClassicBuckets(data); + Exemplars exemplars = data.getExemplars(); + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + writeNameAndLabels(writer, metadata.getName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); + writeLong(writer, cumulativeCount); + Exemplar exemplar; + if (i == 0) { + exemplar = exemplars.get(Double.NEGATIVE_INFINITY, buckets.getUpperBound(i)); + } else { + exemplar = exemplars.get(buckets.getUpperBound(i - 1), buckets.getUpperBound(i)); + } + writeScrapeTimestampAndExemplar(writer, data, exemplar); + } + if (data.hasCount() && data.hasSum()) { + // In OpenMetrics format, histogram _count and _sum are either both present or both absent. + // While Prometheus allows Exemplars for histogram's _count and _sum now, we don't + // use Exemplars here to be backwards compatible with previous behavior. + writeCountAndSum(writer, metadata, data, countSuffix, sumSuffix, Exemplars.EMPTY); + } + writeCreated(writer, metadata, data); + } + } + + private ClassicHistogramBuckets getClassicBuckets(HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.getClassicBuckets().isEmpty()) { + return ClassicHistogramBuckets.of( + new double[]{Double.POSITIVE_INFINITY}, + new long[]{data.getCount()} + ); + } else { + return data.getClassicBuckets(); + } + } + + private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getData()) { + if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { + continue; + } + if (!metadataWritten) { + writeMetadata(writer, "summary", metadata); + metadataWritten = true; + } + Exemplars exemplars = data.getExemplars(); + // Exemplars for summaries are new, and there's no best practice yet which Exemplars to choose for which + // time series. We select exemplars[0] for _count, exemplars[1] for _sum, and exemplars[2...] for the + // quantiles, all indexes modulo exemplars.length. + int exemplarIndex = 1; + for (Quantile quantile : data.getQuantiles()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels(), "quantile", quantile.getQuantile()); + writeDouble(writer, quantile.getValue()); + if (exemplars.size() > 0 && exemplarsOnAllMetricTypesEnabled) { + exemplarIndex = (exemplarIndex + 1) % exemplars.size(); + writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + // Unlike histograms, summaries can have only a count or only a sum according to OpenMetrics. + writeCountAndSum(writer, metadata, data, "_count", "_sum", exemplars); + writeCreated(writer, metadata, data); + } + } + + private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "info", metadata); + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), "_info", data.getLabels()); + writer.write("1"); + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + + private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "stateset", metadata); + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { + for (int i = 0; i < data.size(); i++) { + writer.write(metadata.getName()); + writer.write('{'); + for (int j = 0; j < data.getLabels().size(); j++) { + if (j > 0) { + writer.write(","); + } + writer.write(data.getLabels().getName(j)); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getLabels().getValue(j)); + writer.write("\""); + } + if (!data.getLabels().isEmpty()) { + writer.write(","); + } + writer.write(metadata.getName()); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getName(i)); + writer.write("\"} "); + if (data.isTrue(i)) { + writer.write("1"); + } else { + writer.write("0"); + } + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + } + + private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "unknown", metadata); + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + } + + private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata, DistributionDataPointSnapshot data, String countSuffix, String sumSuffix, Exemplars exemplars) throws IOException { + int exemplarIndex = 0; + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getName(), countSuffix, data.getLabels()); + writeLong(writer, data.getCount()); + if (exemplars.size() > 0) { + writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); + exemplarIndex = exemplarIndex + 1 % exemplars.size(); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getName(), sumSuffix, data.getLabels()); + writeDouble(writer, data.getSum()); + if (exemplars.size() > 0) { + writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } + } + } + + private void writeCreated(OutputStreamWriter writer, MetricMetadata metadata, DataPointSnapshot data) throws IOException { + if (createdTimestampsEnabled && data.hasCreatedTimestamp()) { + writeNameAndLabels(writer, metadata.getName(), "_created", data.getLabels()); + writeTimestamp(writer, data.getCreatedTimestampMillis()); + if (data.hasScrapeTimestamp()) { + writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); + } + writer.write('\n'); + } + } + + private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { + writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + } + + private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels, + String additionalLabelName, double additionalLabelValue) throws IOException { + writer.write(name); + if (suffix != null) { + writer.write(suffix); + } + if (!labels.isEmpty() || additionalLabelName != null) { + writeLabels(writer, labels, additionalLabelName, additionalLabelValue); + } + writer.write(' '); + } + + private void writeScrapeTimestampAndExemplar(OutputStreamWriter writer, DataPointSnapshot data, Exemplar exemplar) throws IOException { + if (data.hasScrapeTimestamp()) { + writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); + } + if (exemplar != null) { + writer.write(" # "); + writeLabels(writer, exemplar.getLabels(), null, 0); + writer.write(' '); + writeDouble(writer, exemplar.getValue()); + if (exemplar.hasTimestamp()) { + writer.write(' '); + writeTimestamp(writer, exemplar.getTimestampMillis()); + } + } + writer.write('\n'); + } + + private void writeMetadata(OutputStreamWriter writer, String typeName, MetricMetadata metadata) throws IOException { + writer.write("# TYPE "); + writer.write(metadata.getName()); + writer.write(' '); + writer.write(typeName); + writer.write('\n'); + if (metadata.getUnit() != null) { + writer.write("# UNIT "); + writer.write(metadata.getName()); + writer.write(' '); + writeEscapedLabelValue(writer, metadata.getUnit().toString()); + writer.write('\n'); + } + if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { + writer.write("# HELP "); + writer.write(metadata.getName()); + writer.write(' '); + writeEscapedLabelValue(writer, metadata.getHelp()); + writer.write('\n'); + } + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java new file mode 100644 index 000000000..d6de08114 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -0,0 +1,368 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; + +import java.io.IOException; +import java.io.OutputStream; + +import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; + +/** + * Write the Prometheus protobuf format as defined in + * github.com/prometheus/client_model. + *

+ * As of today, this is the only exposition format that supports native histograms. + */ +public class PrometheusProtobufWriter implements ExpositionFormatWriter { + + public static final String CONTENT_TYPE = "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"; + + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } else { + return acceptHeader.contains("application/vnd.google.protobuf") + && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); + } + } + + @Override + public String getContentType() { + return CONTENT_TYPE; + } + + public String toDebugString(MetricSnapshots metricSnapshots) { + StringBuilder stringBuilder = new StringBuilder(); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getData().size() > 0) { + stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); + } + } + return stringBuilder.toString(); + } + + @Override + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getData().size() > 0) { + convert(snapshot).writeDelimitedTo(out); + } + } + } + + public Metrics.MetricFamily convert(MetricSnapshot snapshot) { + Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder(); + if (snapshot instanceof CounterSnapshot) { + for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getData()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_total", Metrics.MetricType.COUNTER); + } else if (snapshot instanceof GaugeSnapshot) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getData()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); + } else if (snapshot instanceof HistogramSnapshot) { + HistogramSnapshot histogram = (HistogramSnapshot) snapshot; + for (HistogramSnapshot.HistogramDataPointSnapshot data : histogram.getData()) { + builder.addMetric(convert(data)); + } + Metrics.MetricType type = histogram.isGaugeHistogram() ? Metrics.MetricType.GAUGE_HISTOGRAM : Metrics.MetricType.HISTOGRAM; + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, type); + } else if (snapshot instanceof SummarySnapshot) { + for (SummarySnapshot.SummaryDataPointSnapshot data : ((SummarySnapshot) snapshot).getData()) { + if (data.hasCount() || data.hasSum() || data.getQuantiles().size() > 0) { + builder.addMetric(convert(data)); + } + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.SUMMARY); + } else if (snapshot instanceof InfoSnapshot) { + for (InfoSnapshot.InfoDataPointSnapshot data : ((InfoSnapshot) snapshot).getData()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_info", Metrics.MetricType.GAUGE); + } else if (snapshot instanceof StateSetSnapshot) { + for (StateSetSnapshot.StateSetDataPointSnapshot data : ((StateSetSnapshot) snapshot).getData()) { + for (int i = 0; i < data.size(); i++) { + builder.addMetric(convert(data, snapshot.getMetadata().getName(), i)); + } + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); + } else if (snapshot instanceof UnknownSnapshot) { + for (UnknownSnapshot.UnknownDataPointSnapshot data : ((UnknownSnapshot) snapshot).getData()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.UNTYPED); + } + return builder.build(); + } + + private void setMetadataUnlessEmpty(Metrics.MetricFamily.Builder builder, MetricMetadata metadata, String nameSuffix, Metrics.MetricType type) { + if (builder.getMetricCount() == 0) { + return; + } + if (nameSuffix == null) { + builder.setName(metadata.getName()); + } else { + builder.setName(metadata.getName() + nameSuffix); + } + if (metadata.getHelp() != null) { + builder.setHelp(metadata.getHelp()); + } + builder.setType(type); + } + + private Metrics.Metric.Builder convert(CounterDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Counter.Builder counterBuilder = Metrics.Counter.newBuilder(); + counterBuilder.setValue(data.getValue()); + if (data.getExemplar() != null) { + counterBuilder.setExemplar(convert(data.getExemplar())); + } + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setCounter(counterBuilder.build()); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(GaugeSnapshot.GaugeDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + gaugeBuilder.setValue(data.getValue()); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(HistogramSnapshot.HistogramDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Histogram.Builder histogramBuilder = Metrics.Histogram.newBuilder(); + if (data.hasNativeHistogramData()) { + histogramBuilder.setSchema(data.getNativeSchema()); + histogramBuilder.setZeroCount(data.getNativeZeroCount()); + histogramBuilder.setZeroThreshold(data.getNativeZeroThreshold()); + addBuckets(histogramBuilder, data.getNativeBucketsForPositiveValues(), +1); + addBuckets(histogramBuilder, data.getNativeBucketsForNegativeValues(), -1); + + // Add a single +Inf bucket for the exemplar. + // It is currently not possible to have more than one exemplar in a native histogram, + // see https://cloud-native.slack.com/archives/C02KR205UMU/p1688414381799849 + Exemplar exemplar = data.getExemplars().getLatest(); + if (exemplar != null) { + Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() + .setCumulativeCount(getNativeCount(data)) + .setUpperBound(Double.POSITIVE_INFINITY); + bucketBuilder.setExemplar(convert(exemplar)); + histogramBuilder.addBucket(bucketBuilder); + } + } else if (data.hasClassicHistogramData()) { + + // Once native histograms support multiple exemplars the above can be changed from "else if" to "if", + // so that we always add the complete classic buckets and exemplars. + + ClassicHistogramBuckets buckets = data.getClassicBuckets(); + double lowerBound = Double.NEGATIVE_INFINITY; + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + double upperBound = buckets.getUpperBound(i); + Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() + .setCumulativeCount(cumulativeCount) + .setUpperBound(upperBound); + Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); + if (exemplar != null) { + bucketBuilder.setExemplar(convert(exemplar)); + } + histogramBuilder.addBucket(bucketBuilder); + lowerBound = upperBound; + } + } + addLabels(metricBuilder, data.getLabels()); + setScrapeTimestamp(metricBuilder, data); + if (data.hasCount()) { + histogramBuilder.setSampleCount(data.getCount()); + } + if (data.hasSum()) { + histogramBuilder.setSampleSum(data.getSum()); + } + metricBuilder.setHistogram(histogramBuilder.build()); + return metricBuilder; + } + + private long getNativeCount(HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.hasCount()) { + return data.getCount(); + } else { + long count = data.getNativeZeroCount(); + for (int i = 0; i < data.getNativeBucketsForPositiveValues().size(); i++) { + count += data.getNativeBucketsForPositiveValues().getCount(i); + } + for (int i = 0; i < data.getNativeBucketsForNegativeValues().size(); i++) { + count += data.getNativeBucketsForNegativeValues().getCount(i); + } + return count; + } + } + + private void addBuckets(Metrics.Histogram.Builder histogramBuilder, NativeHistogramBuckets buckets, int sgn) { + if (buckets.size() > 0) { + Metrics.BucketSpan.Builder currentSpan = Metrics.BucketSpan.newBuilder(); + currentSpan.setOffset(buckets.getBucketIndex(0)); + currentSpan.setLength(0); + int previousIndex = currentSpan.getOffset(); + long previousCount = 0; + for (int i = 0; i < buckets.size(); i++) { + if (buckets.getBucketIndex(i) > previousIndex + 1) { + // If the gap between bucketIndex and previousIndex is just 1 or 2, + // we don't start a new span but continue the existing span and add 1 or 2 empty buckets. + if (buckets.getBucketIndex(i) <= previousIndex + 3) { + while (buckets.getBucketIndex(i) > previousIndex + 1) { + currentSpan.setLength(currentSpan.getLength() + 1); + previousIndex++; + if (sgn > 0) { + histogramBuilder.addPositiveDelta(-previousCount); + } else { + histogramBuilder.addNegativeDelta(-previousCount); + } + previousCount = 0; + } + } else { + if (sgn > 0) { + histogramBuilder.addPositiveSpan(currentSpan.build()); + } else { + histogramBuilder.addNegativeSpan(currentSpan.build()); + } + currentSpan = Metrics.BucketSpan.newBuilder(); + currentSpan.setOffset(buckets.getBucketIndex(i) - (previousIndex + 1)); + } + } + currentSpan.setLength(currentSpan.getLength() + 1); + previousIndex = buckets.getBucketIndex(i); + if (sgn > 0) { + histogramBuilder.addPositiveDelta(buckets.getCount(i) - previousCount); + } else { + histogramBuilder.addNegativeDelta(buckets.getCount(i) - previousCount); + } + previousCount = buckets.getCount(i); + } + if (sgn > 0) { + histogramBuilder.addPositiveSpan(currentSpan.build()); + } else { + histogramBuilder.addNegativeSpan(currentSpan.build()); + } + } + } + + private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder(); + if (data.hasCount()) { + summaryBuilder.setSampleCount(data.getCount()); + } + if (data.hasSum()) { + summaryBuilder.setSampleSum(data.getSum()); + } + Quantiles quantiles = data.getQuantiles(); + for (int i = 0; i < quantiles.size(); i++) { + summaryBuilder.addQuantile(Metrics.Quantile.newBuilder() + .setQuantile(quantiles.get(i).getQuantile()) + .setValue(quantiles.get(i).getValue()) + .build()); + } + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setSummary(summaryBuilder.build()); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + gaugeBuilder.setValue(1); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.addLabel(Metrics.LabelPair.newBuilder() + .setName(name) + .setValue(data.getName(i)) + .build()); + if (data.isTrue(i)) { + gaugeBuilder.setValue(1); + } else { + gaugeBuilder.setValue(0); + } + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Untyped.Builder untypedBuilder = Metrics.Untyped.newBuilder(); + untypedBuilder.setValue(data.getValue()); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setUntyped(untypedBuilder); + return metricBuilder; + } + + private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { + for (int i = 0; i < labels.size(); i++) { + metricBuilder.addLabel(Metrics.LabelPair.newBuilder() + .setName(labels.getName(i)) + .setValue(labels.getValue(i)) + .build()); + } + } + + private void addLabels(Metrics.Exemplar.Builder metricBuilder, Labels labels) { + for (int i = 0; i < labels.size(); i++) { + metricBuilder.addLabel(Metrics.LabelPair.newBuilder() + .setName(labels.getName(i)) + .setValue(labels.getValue(i)) + .build()); + } + } + + private Metrics.Exemplar.Builder convert(Exemplar exemplar) { + Metrics.Exemplar.Builder builder = Metrics.Exemplar.newBuilder(); + builder.setValue(exemplar.getValue()); + addLabels(builder, exemplar.getLabels()); + if (exemplar.hasTimestamp()) { + builder.setTimestamp(timestampFromMillis(exemplar.getTimestampMillis())); + } + return builder; + } + + private void setScrapeTimestamp(Metrics.Metric.Builder metricBuilder, DataPointSnapshot data) { + if (data.hasScrapeTimestamp()) { + metricBuilder.setTimestampMs(data.getScrapeTimestampMillis()); + } + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java new file mode 100644 index 000000000..a4499dd9d --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -0,0 +1,347 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; + +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; + +/** + * Write the Prometheus text format. This is the default if you view a Prometheus endpoint with your Web browser. + */ +public class PrometheusTextFormatWriter implements ExpositionFormatWriter { + + public static final String CONTENT_TYPE = "text/plain; version=0.0.4; charset=utf-8"; + + private final boolean writeCreatedTimestamps; + + public PrometheusTextFormatWriter(boolean writeCreatedTimestamps) { + this.writeCreatedTimestamps = writeCreatedTimestamps; + } + + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } else { + return acceptHeader.contains("text/plain"); + } + } + + @Override + public String getContentType() { + return CONTENT_TYPE; + } + + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + // See https://prometheus.io/docs/instrumenting/exposition_formats/ + // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and "summary". + OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getData().size() > 0) { + if (snapshot instanceof CounterSnapshot) { + writeCounter(writer, (CounterSnapshot) snapshot); + } else if (snapshot instanceof GaugeSnapshot) { + writeGauge(writer, (GaugeSnapshot) snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeHistogram(writer, (HistogramSnapshot) snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeSummary(writer, (SummarySnapshot) snapshot); + } else if (snapshot instanceof InfoSnapshot) { + writeInfo(writer, (InfoSnapshot) snapshot); + } else if (snapshot instanceof StateSetSnapshot) { + writeStateSet(writer, (StateSetSnapshot) snapshot); + } else if (snapshot instanceof UnknownSnapshot) { + writeUnknown(writer, (UnknownSnapshot) snapshot); + } + } + } + if (writeCreatedTimestamps) { + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getData().size() > 0) { + if (snapshot instanceof CounterSnapshot) { + writeCreated(writer, snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeCreated(writer, snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeCreated(writer, snapshot); + } + } + } + } + writer.flush(); + } + + public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (DataPointSnapshot data : snapshot.getData()) { + if (data.hasCreatedTimestamp()) { + if (!metadataWritten) { + writeMetadata(writer, "_created", "gauge", metadata); + metadataWritten = true; + } + writeNameAndLabels(writer, metadata.getName(), "_created", data.getLabels()); + writeTimestamp(writer, data.getCreatedTimestampMillis()); + writeScrapeTimestampAndNewline(writer, data); + } + } + + } + + private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { + if (snapshot.getData().size() > 0) { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "_total", "counter", metadata); + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), "_total", data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } + } + } + + private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "gauge", metadata); + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } + } + + private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "histogram", metadata); + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + ClassicHistogramBuckets buckets = getClassicBuckets(data); + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + writeNameAndLabels(writer, metadata.getName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); + writeLong(writer, cumulativeCount); + writeScrapeTimestampAndNewline(writer, data); + } + if (!snapshot.isGaugeHistogram()) { + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getName(), "_count", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); + } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getName(), "_sum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); + } + } + } + if (snapshot.isGaugeHistogram()) { + writeGaugeCountSum(writer, snapshot, metadata); + } + } + + private ClassicHistogramBuckets getClassicBuckets(HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.getClassicBuckets().isEmpty()) { + return ClassicHistogramBuckets.of( + new double[]{Double.POSITIVE_INFINITY}, + new long[]{data.getCount()} + ); + } else { + return data.getClassicBuckets(); + } + } + + private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot snapshot, MetricMetadata metadata) throws IOException { + // Prometheus text format does not support gaugehistogram's _gcount and _gsum. + // So we append _gcount and _gsum as gauge metrics. + boolean metadataWritten = false; + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + if (data.hasCount()) { + if (!metadataWritten) { + writeMetadata(writer, "_gcount", "gauge", metadata); + metadataWritten = true; + } + writeNameAndLabels(writer, metadata.getName(), "_gcount", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); + } + } + metadataWritten = false; + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + if (data.hasSum()) { + if (!metadataWritten) { + writeMetadata(writer, "_gsum", "gauge", metadata); + metadataWritten = true; + } + writeNameAndLabels(writer, metadata.getName(), "_gsum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); + } + } + } + + private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getData()) { + if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { + continue; + } + if (!metadataWritten) { + writeMetadata(writer, "", "summary", metadata); + metadataWritten = true; + } + for (Quantile quantile : data.getQuantiles()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels(), "quantile", quantile.getQuantile()); + writeDouble(writer, quantile.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getName(), "_count", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); + } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getName(), "_sum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); + } + } + } + + private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "_info", "gauge", metadata); + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), "_info", data.getLabels()); + writer.write("1"); + writeScrapeTimestampAndNewline(writer, data); + } + } + + private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "gauge", metadata); + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { + for (int i = 0; i < data.size(); i++) { + writer.write(metadata.getName()); + writer.write('{'); + for (int j = 0; j < data.getLabels().size(); j++) { + if (j > 0) { + writer.write(","); + } + writer.write(data.getLabels().getName(j)); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getLabels().getValue(j)); + writer.write("\""); + } + if (!data.getLabels().isEmpty()) { + writer.write(","); + } + writer.write(metadata.getName()); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getName(i)); + writer.write("\"} "); + if (data.isTrue(i)) { + writer.write("1"); + } else { + writer.write("0"); + } + writeScrapeTimestampAndNewline(writer, data); + } + } + } + + private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "untyped", metadata); + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { + writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } + } + + private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { + writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + } + + private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels, + String additionalLabelName, double additionalLabelValue) throws IOException { + writer.write(name); + if (suffix != null) { + writer.write(suffix); + } + if (!labels.isEmpty() || additionalLabelName != null) { + writeLabels(writer, labels, additionalLabelName, additionalLabelValue); + } + writer.write(' '); + } + + private void writeMetadata(OutputStreamWriter writer, String suffix, String typeString, MetricMetadata metadata) throws IOException { + if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { + writer.write("# HELP "); + writer.write(metadata.getName()); + if (suffix != null) { + writer.write(suffix); + } + writer.write(' '); + writeEscapedHelp(writer, metadata.getHelp()); + writer.write('\n'); + } + writer.write("# TYPE "); + writer.write(metadata.getName()); + if (suffix != null) { + writer.write(suffix); + } + writer.write(' '); + writer.write(typeString); + writer.write('\n'); + } + + private void writeEscapedHelp(Writer writer, String s) throws IOException { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\\': + writer.append("\\\\"); + break; + case '\n': + writer.append("\\n"); + break; + default: + writer.append(c); + } + } + } + + private void writeScrapeTimestampAndNewline(OutputStreamWriter writer, DataPointSnapshot data) throws IOException { + if (data.hasScrapeTimestamp()) { + writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); + } + writer.write('\n'); + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java new file mode 100644 index 000000000..fe496df8c --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java @@ -0,0 +1,13 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp; + +public class ProtobufUtil { + + static Timestamp timestampFromMillis(long timestampMillis) { + return Timestamp.newBuilder() + .setSeconds(timestampMillis / 1000L) + .setNanos((int) (timestampMillis % 1000L * 1000000L)) + .build(); + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java new file mode 100644 index 000000000..5bb15c312 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -0,0 +1,80 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.Labels; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; + +public class TextFormatUtil { + + static void writeLong(OutputStreamWriter writer, long value) throws IOException { + writer.append(Long.toString(value)); + } + + static void writeDouble(OutputStreamWriter writer, double d) throws IOException { + if (d == Double.POSITIVE_INFINITY) { + writer.write("+Inf"); + } else if (d == Double.NEGATIVE_INFINITY) { + writer.write("-Inf"); + } else { + writer.write(Double.toString(d)); + // FloatingDecimal.getBinaryToASCIIConverter(d).appendTo(writer); + } + } + + static void writeTimestamp(OutputStreamWriter writer, long timestampMs) throws IOException { + writer.write(Long.toString(timestampMs / 1000L)); + writer.write("."); + long ms = timestampMs % 1000; + if (ms < 100) { + writer.write("0"); + } + if (ms < 10) { + writer.write("0"); + } + writer.write(Long.toString(ms)); + } + + static void writeEscapedLabelValue(Writer writer, String s) throws IOException { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\\': + writer.append("\\\\"); + break; + case '\"': + writer.append("\\\""); + break; + case '\n': + writer.append("\\n"); + break; + default: + writer.append(c); + } + } + } + + static void writeLabels(OutputStreamWriter writer, Labels labels, String additionalLabelName, double additionalLabelValue) throws IOException { + writer.write('{'); + for (int i = 0; i < labels.size(); i++) { + if (i > 0) { + writer.write(","); + } + writer.write(labels.getName(i)); + writer.write("=\""); + writeEscapedLabelValue(writer, labels.getValue(i)); + writer.write("\""); + } + if (additionalLabelName != null) { + if (!labels.isEmpty()) { + writer.write(","); + } + writer.write(additionalLabelName); + writer.write("=\""); + writeDouble(writer, additionalLabelValue); + writer.write("\""); + } + writer.write('}'); + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto new file mode 100644 index 000000000..b351b6d5a --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto @@ -0,0 +1,144 @@ +// Copyright 2013 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package io.prometheus.client; +option java_package = "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7"; +option go_package = "github.com/prometheus/client_model/go;io_prometheus_client"; + +import "google/protobuf/timestamp.proto"; + +message LabelPair { + optional string name = 1; + optional string value = 2; +} + +enum MetricType { + // COUNTER must use the Metric field "counter". + COUNTER = 0; + // GAUGE must use the Metric field "gauge". + GAUGE = 1; + // SUMMARY must use the Metric field "summary". + SUMMARY = 2; + // UNTYPED must use the Metric field "untyped". + UNTYPED = 3; + // HISTOGRAM must use the Metric field "histogram". + HISTOGRAM = 4; + // GAUGE_HISTOGRAM must use the Metric field "histogram". + GAUGE_HISTOGRAM = 5; +} + +message Gauge { + optional double value = 1; +} + +message Counter { + optional double value = 1; + optional Exemplar exemplar = 2; +} + +message Quantile { + optional double quantile = 1; + optional double value = 2; +} + +message Summary { + optional uint64 sample_count = 1; + optional double sample_sum = 2; + repeated Quantile quantile = 3; +} + +message Untyped { + optional double value = 1; +} + +message Histogram { + optional uint64 sample_count = 1; + optional double sample_count_float = 4; // Overrides sample_count if > 0. + optional double sample_sum = 2; + // Buckets for the conventional histogram. + repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional. + + // Everything below here is for native histograms (also known as sparse histograms). + // Native histograms are an experimental feature without stability guarantees. + + // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8. + // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and + // then each power of two is divided into 2^n logarithmic buckets. + // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n). + // In the future, more bucket schemas may be added using numbers < -4 or > 8. + optional sint32 schema = 5; + optional double zero_threshold = 6; // Breadth of the zero bucket. + optional uint64 zero_count = 7; // Count in zero bucket. + optional double zero_count_float = 8; // Overrides sb_zero_count if > 0. + + // Negative buckets for the native histogram. + repeated BucketSpan negative_span = 9; + // Use either "negative_delta" or "negative_count", the former for + // regular histograms with integer counts, the latter for float + // histograms. + repeated sint64 negative_delta = 10; // Count delta of each bucket compared to previous one (or to zero for 1st bucket). + repeated double negative_count = 11; // Absolute count of each bucket. + + // Positive buckets for the native histogram. + repeated BucketSpan positive_span = 12; + // Use either "positive_delta" or "positive_count", the former for + // regular histograms with integer counts, the latter for float + // histograms. + repeated sint64 positive_delta = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket). + repeated double positive_count = 14; // Absolute count of each bucket. +} + +// A Bucket of a conventional histogram, each of which is treated as +// an individual counter-like time series by Prometheus. +message Bucket { + optional uint64 cumulative_count = 1; // Cumulative in increasing order. + optional double cumulative_count_float = 4; // Overrides cumulative_count if > 0. + optional double upper_bound = 2; // Inclusive. + optional Exemplar exemplar = 3; +} + +// A BucketSpan defines a number of consecutive buckets in a native +// histogram with their offset. Logically, it would be more +// straightforward to include the bucket counts in the Span. However, +// the protobuf representation is more compact in the way the data is +// structured here (with all the buckets in a single array separate +// from the Spans). +message BucketSpan { + optional sint32 offset = 1; // Gap to previous span, or starting point for 1st span (which can be negative). + optional uint32 length = 2; // Length of consecutive buckets. +} + +message Exemplar { + repeated LabelPair label = 1; + optional double value = 2; + optional google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style. +} + +message Metric { + repeated LabelPair label = 1; + optional Gauge gauge = 2; + optional Counter counter = 3; + optional Summary summary = 4; + optional Untyped untyped = 5; + optional Histogram histogram = 7; + optional int64 timestamp_ms = 6; +} + +message MetricFamily { + optional string name = 1; + optional string help = 2; + optional MetricType type = 3; + repeated Metric metric = 4; +} diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java new file mode 100644 index 000000000..233953e00 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -0,0 +1,1471 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ExpositionFormatsTest { + + private final String exemplar1String = "{env=\"prod\",span_id=\"12345\",trace_id=\"abcde\"} 1.7 1672850685.829"; + private final String exemplar2String = "{env=\"dev\",span_id=\"23456\",trace_id=\"bcdef\"} 2.4 1672850685.830"; + + private final String exemplar1protoString = "exemplar { " + + "label { name: \"env\" value: \"prod\" } " + + "label { name: \"span_id\" value: \"12345\" } " + + "label { name: \"trace_id\" value: \"abcde\" } " + + "value: 1.7 " + + "timestamp { seconds: 1672850685 nanos: 829000000 } }"; + + private final String exemplar2protoString = "exemplar { " + + "label { name: \"env\" value: \"dev\" } " + + "label { name: \"span_id\" value: \"23456\" } " + + "label { name: \"trace_id\" value: \"bcdef\" } " + + "value: 2.4 " + + "timestamp { seconds: 1672850685 nanos: 830000000 } }"; + + private final String createdTimestamp1s = "1672850385.800"; + private final long createdTimestamp1 = (long) (1000 * Double.parseDouble(createdTimestamp1s)); + private final String createdTimestamp2s = "1672850285.000"; + private final long createdTimestamp2 = (long) (1000 * Double.parseDouble(createdTimestamp2s)); + private final String scrapeTimestamp1s = "1672850685.829"; + private final long scrapeTimestamp1 = (long) (1000 * Double.parseDouble(scrapeTimestamp1s)); + private final String scrapeTimestamp2s = "1672850585.820"; + private final long scrapeTimestamp2 = (long) (1000 * Double.parseDouble(scrapeTimestamp2s)); + + private final Exemplar exemplar1 = Exemplar.newBuilder() + .withSpanId("12345") + .withTraceId("abcde") + .withLabels(Labels.of("env", "prod")) + .withValue(1.7) + .withTimestampMillis(1672850685829L) + .build(); + + private final Exemplar exemplar2 = Exemplar.newBuilder() + .withSpanId("23456") + .withTraceId("bcdef") + .withLabels(Labels.of("env", "dev")) + .withValue(2.4) + .withTimestampMillis(1672850685830L) + .build(); + + @Test + public void testCounterComplete() throws IOException { + String openMetricsText = "" + + "# TYPE service_time_seconds counter\n" + + "# UNIT service_time_seconds seconds\n" + + "# HELP service_time_seconds total time spent serving\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP service_time_seconds_total total time spent serving\n" + + "# TYPE service_time_seconds_total counter\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + "\n" + + "# HELP service_time_seconds_created total time spent serving\n" + + "# TYPE service_time_seconds_created gauge\n" + + "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; + String openMetricsTextWithoutCreated = "" + + "# TYPE service_time_seconds counter\n" + + "# UNIT service_time_seconds seconds\n" + + "# HELP service_time_seconds total time spent serving\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = "" + + "# HELP service_time_seconds_total total time spent serving\n" + + "# TYPE service_time_seconds_total counter\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"service_time_seconds_total\" " + + "help: \"total time spent serving\" " + + "type: COUNTER " + + "metric { " + + "label { name: \"path\" value: \"/hello\" } " + + "label { name: \"status\" value: \"200\" } " + + "counter { " + + "value: 0.8 " + + exemplar1protoString + " " + + "} " + + "timestamp_ms: 1672850685829 " + + "} " + + "metric { " + + "label { name: \"path\" value: \"/hello\" } " + + "label { name: \"status\" value: \"500\" } " + + "counter { " + + "value: 0.9 " + + exemplar2protoString + " " + + "} " + + "timestamp_ms: 1672850585820 " + + "}"; + //@formatter:on + + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("service_time_seconds") + .withHelp("total time spent serving") + .withUnit(Unit.SECONDS) + .addDataPoint(CounterDataPointSnapshot.newBuilder() + .withValue(0.8) + .withLabels(Labels.newBuilder() + .addLabel("path", "/hello") + .addLabel("status", "200") + .build()) + .withExemplar(exemplar1) + .withCreatedTimestampMillis(createdTimestamp1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .addDataPoint(CounterDataPointSnapshot.newBuilder() + .withValue(0.9) + .withLabels(Labels.newBuilder() + .addLabel("path", "/hello") + .addLabel("status", "500") + .build()) + .withExemplar(exemplar2) + .withCreatedTimestampMillis(createdTimestamp2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, counter); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } + + @Test + public void testCounterMinimal() throws IOException { + String openMetricsText = "" + + "# TYPE my_counter counter\n" + + "my_counter_total 1.1\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE my_counter_total counter\n" + + "my_counter_total 1.1\n"; + String prometheusProtobuf = "" + + "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("my_counter") + .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.1).build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertOpenMetricsTextWithoutCreated(openMetricsText, counter); + assertPrometheusTextWithoutCreated(prometheusText, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } + + @Test + public void testGaugeComplete() throws IOException { + String openMetricsText = "" + + "# TYPE disk_usage_ratio gauge\n" + + "# UNIT disk_usage_ratio ratio\n" + + "# HELP disk_usage_ratio percentage used\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP disk_usage_ratio percentage used\n" + + "# TYPE disk_usage_ratio gauge\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"disk_usage_ratio\" " + + "help: \"percentage used\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"device\" value: \"/dev/sda1\" } " + + "gauge { value: 0.2 } " + + "timestamp_ms: 1672850685829 " + + "} metric { " + + "label { name: \"device\" value: \"/dev/sda2\" } " + + "gauge { value: 0.7 } " + + "timestamp_ms: 1672850585820 " + + "}"; + //@formatter:on + GaugeSnapshot gauge = GaugeSnapshot.newBuilder() + .withName("disk_usage_ratio") + .withHelp("percentage used") + .withUnit(new Unit("ratio")) + .addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(0.7) + .withLabels(Labels.newBuilder() + .addLabel("device", "/dev/sda2") + .build()) + .withExemplar(exemplar2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(0.2) + .withLabels(Labels.newBuilder() + .addLabel("device", "/dev/sda1") + .build()) + .withExemplar(exemplar1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertPrometheusText(prometheusText, gauge); + assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); + assertPrometheusTextWithoutCreated(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } + + @Test + public void testGaugeMinimal() throws IOException { + String openMetricsText = "" + + "# TYPE temperature_centigrade gauge\n" + + "temperature_centigrade 22.3\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE temperature_centigrade gauge\n" + + "temperature_centigrade 22.3\n"; + String prometheusProtobuf = "" + + "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; + GaugeSnapshot gauge = GaugeSnapshot.newBuilder() + .withName("temperature_centigrade") + .addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(22.3) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertPrometheusText(prometheusText, gauge); + assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); + assertPrometheusTextWithoutCreated(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } + + @Test + public void testSummaryComplete() throws IOException { + String openMetricsText = "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP http_request_duration_seconds request duration\n" + + "# TYPE http_request_duration_seconds summary\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + + "# HELP http_request_duration_seconds_created request duration\n" + + "# TYPE http_request_duration_seconds_created gauge\n" + + "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; + String openMetricsTextWithoutCreated = "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = "" + + "# HELP http_request_duration_seconds request duration\n" + + "# TYPE http_request_duration_seconds summary\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"http_request_duration_seconds\" " + + "help: \"request duration\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "summary { " + + "sample_count: 3 " + + "sample_sum: 1.2 " + + "quantile { quantile: 0.5 value: 225.3 } " + + "quantile { quantile: 0.9 value: 240.7 } " + + "quantile { quantile: 0.95 value: 245.1 } " + + "} " + + "timestamp_ms: 1672850685829 " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "summary { " + + "sample_count: 7 " + + "sample_sum: 2.2 " + + "quantile { quantile: 0.5 value: 225.3 } " + + "quantile { quantile: 0.9 value: 240.7 } " + + "quantile { quantile: 0.95 value: 245.1 } " + + "} " + "" + + "timestamp_ms: 1672850585820 " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("http_request_duration_seconds") + .withHelp("request duration") + .withUnit(Unit.SECONDS) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withCount(7) + .withSum(2.2) + .withQuantiles(Quantiles.newBuilder() + .addQuantile(0.5, 225.3) + .addQuantile(0.9, 240.7) + .addQuantile(0.95, 245.1) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("status", "500") + .build()) + .withExemplars(Exemplars.of(exemplar2)) + .withCreatedTimestampMillis(createdTimestamp2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withCount(3) + .withSum(1.2) + .withQuantiles(Quantiles.newBuilder() + .addQuantile(0.5, 225.3) + .addQuantile(0.9, 240.7) + .addQuantile(0.95, 245.1) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("status", "200") + .build()) + .withExemplars(Exemplars.of(exemplar1)) + .withCreatedTimestampMillis(createdTimestamp1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, summary); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testSummaryWithoutQuantiles() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds summary\n" + + "# UNIT latency_seconds seconds\n" + + "# HELP latency_seconds latency\n" + + "latency_seconds_count 3\n" + + "latency_seconds_sum 1.2\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP latency_seconds latency\n" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count 3\n" + + "latency_seconds_sum 1.2\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "help: \"latency\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_count: 3 " + + "sample_sum: 1.2 " + + "} " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .withHelp("latency") + .withUnit(Unit.SECONDS) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withCount(3) + .withSum(1.2) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testSummaryNoCountAndSum() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds{quantile=\"0.95\"} 200.0\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds{quantile=\"0.95\"} 200.0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "quantile { quantile: 0.95 value: 200.0 } " + + "} " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withQuantiles(Quantiles.newBuilder().addQuantile(0.95, 200.0).build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testSummaryJustCount() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count 1\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count 1\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_count: 1 " + + "} " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withCount(1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testSummaryJustSum() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_sum 12.3\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_sum 12.3\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_sum: 12.3 " + + "} " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withSum(12.3) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testSummaryEmptyData() throws IOException { + // SummaryData can be present but empty (no count, no sum, no quantiles). + // This should be treated like no data is present. + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .withHelp("latency") + .withUnit(Unit.SECONDS) + .addDataPoint(SummaryDataPointSnapshot.newBuilder().build()) + .build(); + assertOpenMetricsText("# EOF\n", summary); + assertPrometheusText("", summary); + assertOpenMetricsTextWithoutCreated("# EOF\n", summary); + assertPrometheusTextWithoutCreated("", summary); + assertPrometheusProtobuf("", summary); + } + + @Test + public void testSummaryEmptyAndNonEmpty() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count{path=\"/v2\"} 2\n" + + "latency_seconds_sum{path=\"/v2\"} 10.7\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count{path=\"/v2\"} 2\n" + + "latency_seconds_sum{path=\"/v2\"} 10.7\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"path\" value: \"/v2\" } " + + "summary { " + + "sample_count: 2 " + + "sample_sum: 10.7 " + + "} " + + "}"; + //@formatter:on + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withLabels(Labels.of("path", "/v1")) + .build()) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withLabels(Labels.of("path", "/v2")) + .withCount(2) + .withSum(10.7) + .build()) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withLabels(Labels.of("path", "/v3")) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + + @Test + public void testClassicHistogramComplete() throws Exception { + String openMetricsText = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "# HELP response_size_bytes_created help\n" + + "# TYPE response_size_bytes_created gauge\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; + String openMetricsTextWithoutCreated = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"response_size_bytes\" " + + "help: \"help\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 3 " + + "sample_sum: 4.1 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: 2.2 " + + exemplar1protoString + " " + + "} bucket { " + + "cumulative_count: 3 " + + "upper_bound: Infinity " + + exemplar2protoString + " " + + "} " + + "} " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 5 " + + "sample_sum: 3.2 " + + "bucket { " + + "cumulative_count: 3 " + + "upper_bound: 0.0 " + + "} bucket { " + + "cumulative_count: 5 " + + "upper_bound: 2.2 " + + exemplar1protoString + " " + + "} bucket { " + + "cumulative_count: 5 " + + "upper_bound: Infinity " + + exemplar2protoString + " " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot histogram = HistogramSnapshot.newBuilder() + .withName("response_size_bytes") + .withHelp("help") + .withUnit(Unit.BYTES) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(3.2) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(0.0, 3) + .addBucket(2.2, 2) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build()) + .withLabels(Labels.of("status", "500")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(4.1) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(2.2, 2) + .addBucket(Double.POSITIVE_INFINITY, 1) + .build()) + .withLabels(Labels.of("status", "200")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, histogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } + + @Test + public void testClassicHistogramMinimal() throws Exception { + // In OpenMetrics a histogram can have a _count if and only if it has a _sum. + // In Prometheus format, a histogram can have a _count without a _sum. + String openMetricsText = "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"request_latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 2 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot histogram = HistogramSnapshot.newBuilder() + .withName("request_latency_seconds") + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 2) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); + assertPrometheusTextWithoutCreated(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } + + @Test + public void testClassicHistogramCountAndSum() throws Exception { + String openMetricsText = "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n" + + "request_latency_seconds_sum 3.2\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n" + + "request_latency_seconds_sum 3.2\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"request_latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 2 " + + "sample_sum: 3.2 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot histogram = HistogramSnapshot.newBuilder() + .withName("request_latency_seconds") + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(3.2) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 2) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); + assertPrometheusTextWithoutCreated(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } + + @Test + public void testClassicGaugeHistogramComplete() throws IOException { + String openMetricsText = "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "# TYPE cache_size_bytes histogram\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + "\n" + + "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gcount gauge\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + + "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gsum gauge\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + + "# HELP cache_size_bytes_created number of bytes in the cache\n" + + "# TYPE cache_size_bytes_created gauge\n" + + "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; + String openMetricsTextWithoutCreated = "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = "" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "# TYPE cache_size_bytes histogram\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + "\n" + + "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gcount gauge\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + + "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gsum gauge\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"cache_size_bytes\" " + + "help: \"number of bytes in the cache\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "label { name: \"db\" value: \"items\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 17.0 " + + "bucket { " + + "cumulative_count: 3 " + + "upper_bound: 2.0 " + + exemplar1protoString + " " + + "} bucket { " + + "cumulative_count: 4 " + + "upper_bound: Infinity " + + exemplar2protoString + " " + + "} " + + "} " + + "} metric { " + + "label { name: \"db\" value: \"options\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 18.0 " + + "bucket { " + + "cumulative_count: 4 " + + "upper_bound: 2.0 " + + exemplar1protoString + " " + + "} bucket { " + + "cumulative_count: 4 " + + "upper_bound: Infinity " + + exemplar2protoString + " " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() + .asGaugeHistogram() + .withName("cache_size_bytes") + .withHelp("number of bytes in the cache") + .withUnit(Unit.BYTES) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(17) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(2.0, 3) + .addBucket(Double.POSITIVE_INFINITY, 1) + .build()) + .withLabels(Labels.of("db", "items")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(18) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(2.0, 4) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build() + ) + .withLabels(Labels.of("db", "options")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } + + @Test + public void testClassicGaugeHistogramMinimal() throws IOException { + // In OpenMetrics a histogram can have a _count if and only if it has a _sum. + // In Prometheus format, a histogram can have a _count without a _sum. + String openMetricsText = "" + + "# TYPE queue_size_bytes gaugehistogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE queue_size_bytes histogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# TYPE queue_size_bytes_gcount gauge\n" + + "queue_size_bytes_gcount 130\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"queue_size_bytes\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 130 " + + "bucket { " + + "cumulative_count: 130 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() + .asGaugeHistogram() + .withName("queue_size_bytes") + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 130) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } + + @Test + public void testClassicGaugeHistogramCountAndSum() throws IOException { + String openMetricsText = "" + + "# TYPE queue_size_bytes gaugehistogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "queue_size_bytes_gcount 130\n" + + "queue_size_bytes_gsum 27000.0\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE queue_size_bytes histogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# TYPE queue_size_bytes_gcount gauge\n" + + "queue_size_bytes_gcount 130\n" + + "# TYPE queue_size_bytes_gsum gauge\n" + + "queue_size_bytes_gsum 27000.0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"queue_size_bytes\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 130 " + + "sample_sum: 27000.0 " + + "bucket { " + + "cumulative_count: 130 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() + .asGaugeHistogram() + .withName("queue_size_bytes") + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(27000) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 130) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } + + @Test + public void testNativeHistogramComplete() throws IOException { + String openMetricsText = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "# HELP response_size_bytes_created help\n" + + "# TYPE response_size_bytes_created gauge\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; + String openMetricsTextWithoutCreated = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"response_size_bytes\" " + + "help: \"help\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 2 " + + "sample_sum: 4.2 " + + "bucket { cumulative_count: 2 upper_bound: Infinity " + exemplar2protoString + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: 0 length: 1 } " + + "positive_delta: 2 " + + "} " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 55 " + // bucket counts + zero count + "sample_sum: 3.2 " + + "bucket { cumulative_count: 55 upper_bound: Infinity " + exemplar2protoString + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 1 } " + + "negative_span { offset: 9 length: 1 } " + + "negative_delta: 1 " + + "negative_delta: -1 " + // span with count 0 + "positive_span { offset: 2 length: 3 } " + // span with 3 buckets (indexes 2-4) + "positive_span { offset: 7 length: 1 } " + // span with 1 bucket (index 12) + "positive_span { offset: 9 length: 4 } " + // span with gap of size 1 (indexes 22-25) + "positive_span { offset: 6 length: 5 } " + // span with gap of size 2 (indexes 32-36) + "positive_span { offset: 4 length: 2 } " + // span with gap of size 3 part 1 (indexes 41-42) + "positive_span { offset: 3 length: 2 } " + // span with gap of size 3 part 2 (indexes 46-47) + "positive_delta: 3 " + // index 2, count 3 + "positive_delta: 2 " + // index 3, count 5 + "positive_delta: -1 " + // index 4, count 4 + "positive_delta: 2 " + // index 12, count 6 + "positive_delta: -4 " + // index 22, count 2 + "positive_delta: -2 " + // index 23, gap + "positive_delta: 1 " + // index 24, count 1 + "positive_delta: 2 " + // index 25, count 3 + "positive_delta: 1 " + // index 32, count 4 + "positive_delta: -1 " + // index 33, count 3 + "positive_delta: -3 " + // index 34, gap + "positive_delta: 0 " + // index 35, gap + "positive_delta: 7 " + // index 36, count 7 + "positive_delta: -4 " + // index 41, count 3 + "positive_delta: 6 " + // index 42, count 9 + "positive_delta: -7 " + // index 46, count 2 + "positive_delta: -1 " + // index 47, count 1 + "} " + + "}"; + //@formatter:on + HistogramSnapshot nativeHistogram = HistogramSnapshot.newBuilder() + .withName("response_size_bytes") + .withHelp("help") + .withUnit(Unit.BYTES) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(3.2) + .withNativeSchema(5) + .withNativeZeroCount(1) + .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + // span with 3 buckets + .addBucket(2, 3) + .addBucket(3, 5) + .addBucket(4, 4) + // span with just 1 bucket + .addBucket(12, 6) + // span with gap of size 1 + .addBucket(22, 2) + .addBucket(24, 1) + .addBucket(25, 3) + // span with gap of size 2 + .addBucket(32, 4) + .addBucket(33, 3) + .addBucket(36, 7) + // span with gap of size 3 + .addBucket(41, 3) + .addBucket(42, 9) + .addBucket(46, 2) + .addBucket(47, 1) + .build()) + .withNativeBucketsForNegativeValues(NativeHistogramBuckets.newBuilder() + .addBucket(0, 1) + .addBucket(10, 0) // bucket with count 0 + .build()) + .withLabels(Labels.of("status", "500")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(4.2) + .withNativeSchema(5) + .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + .addBucket(0, 2) + .build()) + .withLabels(Labels.of("status", "200")) + .withExemplars(Exemplars.of(exemplar1, exemplar2)) + .withCreatedTimestampMillis(createdTimestamp1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, nativeHistogram); + assertPrometheusText(prometheusText, nativeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, nativeHistogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, nativeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); + } + + @Test + public void testNativeHistogramMinimal() throws IOException { + String openMetricsText = "" + + "# TYPE latency_seconds histogram\n" + + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE latency_seconds histogram\n" + + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + + "latency_seconds_count 0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 0 " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "} " + + "}"; + //@formatter:on + HistogramSnapshot nativeHistogram = HistogramSnapshot.newBuilder() + .withName("latency_seconds") + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withNativeSchema(5) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, nativeHistogram); + assertPrometheusText(prometheusText, nativeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); + } + + // TODO: Gauge Native Histogram + + @Test + public void testInfo() throws IOException { + String openMetrics = "" + + "# TYPE version info\n" + + "# HELP version version information\n" + + "version_info{version=\"1.2.3\"} 1\n" + + "# EOF\n"; + String prometheus = "" + + "# HELP version_info version information\n" + + "# TYPE version_info gauge\n" + + "version_info{version=\"1.2.3\"} 1\n"; + InfoSnapshot info = InfoSnapshot.newBuilder() + .withName("version") + .withHelp("version information") + .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of("version", "1.2.3")) + .build()) + .build(); + assertOpenMetricsText(openMetrics, info); + assertPrometheusText(prometheus, info); + assertOpenMetricsTextWithoutCreated(openMetrics, info); + assertPrometheusTextWithoutCreated(prometheus, info); + } + + @Test + public void testStateSetComplete() throws IOException { + String openMetrics = "" + + "# TYPE state stateset\n" + + "# HELP state complete state set example\n" + + "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s + "\n" + + "state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" + + "state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" + + "state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String prometheus = "" + + "# HELP state complete state set example\n" + + "# TYPE state gauge\n" + + "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s + "\n" + + "state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" + + "state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" + + "state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n"; + StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() + .withName("state") + .withHelp("complete state set example") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("env", "prod")) + .addState("state1", false) + .addState("state2", true) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("env", "dev")) + .addState("state2", false) + .addState("state1", true) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetrics, stateSet); + assertPrometheusText(prometheus, stateSet); + assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); + assertPrometheusTextWithoutCreated(prometheus, stateSet); + } + + @Test + public void testStateSetMinimal() throws IOException { + String openMetrics = "" + + "# TYPE state stateset\n" + + "state{state=\"a\"} 1\n" + + "state{state=\"bb\"} 0\n" + + "# EOF\n"; + String prometheus = "" + + "# TYPE state gauge\n" + + "state{state=\"a\"} 1\n" + + "state{state=\"bb\"} 0\n"; + StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() + .withName("state") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("a", true) + .addState("bb", false) + .build()) + .build(); + assertOpenMetricsText(openMetrics, stateSet); + assertPrometheusText(prometheus, stateSet); + assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); + assertPrometheusTextWithoutCreated(prometheus, stateSet); + } + + @Test + public void testUnknownComplete() throws IOException { + String openMetrics = "" + + "# TYPE my_special_thing_bytes unknown\n" + + "# UNIT my_special_thing_bytes bytes\n" + + "# HELP my_special_thing_bytes help message\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "# EOF\n"; + String prometheus = "" + + "# HELP my_special_thing_bytes help message\n" + + "# TYPE my_special_thing_bytes untyped\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n"; + UnknownSnapshot unknown = UnknownSnapshot.newBuilder() + .withName("my_special_thing_bytes") + .withHelp("help message") + .withUnit(Unit.BYTES) + .addDataPoint(UnknownDataPointSnapshot.newBuilder() + .withValue(0.7) + .withLabels(Labels.of("env", "prod")) + .withExemplar(exemplar2) + .withScrapeTimestampMillis(scrapeTimestamp2) + .build()) + .addDataPoint(UnknownDataPointSnapshot.newBuilder() + .withValue(0.2) + .withLabels(Labels.of("env", "dev")) + .withExemplar(exemplar1) + .withScrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertPrometheusText(prometheus, unknown); + assertOpenMetricsTextWithoutCreated(openMetrics, unknown); + assertPrometheusTextWithoutCreated(prometheus, unknown); + } + + @Test + public void testUnknownMinimal() throws IOException { + String openMetrics = "" + + "# TYPE other unknown\n" + + "other 22.3\n" + + "# EOF\n"; + String prometheus = "" + + "# TYPE other untyped\n" + + "other 22.3\n"; + UnknownSnapshot unknown = UnknownSnapshot.newBuilder() + .withName("other") + .addDataPoint(UnknownDataPointSnapshot.newBuilder() + .withValue(22.3) + .build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertPrometheusText(prometheus, unknown); + assertOpenMetricsTextWithoutCreated(openMetrics, unknown); + assertPrometheusTextWithoutCreated(prometheus, unknown); + } + + @Test + public void testHelpEscape() throws IOException { + String openMetrics = "" + + "# TYPE test counter\n" + + "# HELP test Some text and \\n some \\\" escaping\n" + + "test_total 1.0\n" + + "# EOF\n"; + String prometheus = "" + + "# HELP test_total Some text and \\n some \" escaping\n" + + "# TYPE test_total counter\n" + + "test_total 1.0\n"; + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("test") + .withHelp("Some text and \n some \" escaping") // example from https://openMetrics.io + .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + assertOpenMetricsText(openMetrics, counter); + assertPrometheusText(prometheus, counter); + assertOpenMetricsTextWithoutCreated(openMetrics, counter); + assertPrometheusTextWithoutCreated(prometheus, counter); + } + + @Test + public void testLabelValueEscape() throws IOException { + String openMetrics = "" + + "# TYPE test counter\n" + + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n" + + "# EOF\n"; + String prometheus = "" + + "# TYPE test_total counter\n" + + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("test") + .addDataPoint(CounterDataPointSnapshot.newBuilder() + // example from https://openMetrics.io + .withLabels(Labels.of("a", "x", "b", "escaping\" example \n ")) + .withValue(1.0) + .build()) + .build(); + assertOpenMetricsText(openMetrics, counter); + assertPrometheusText(prometheus, counter); + } + + private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } + + private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } + + private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } + + private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } + + private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { + PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); + Metrics.MetricFamily protobufData = writer.convert(snapshot); + String actual = TextFormat.printer().shortDebugString(protobufData); + Assert.assertEquals(expected, actual); + } +} diff --git a/prometheus-metrics-exposition-formats/version-rules.xml b/prometheus-metrics-exposition-formats/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-exposition-formats/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml new file mode 100644 index 000000000..b1f06cc23 --- /dev/null +++ b/prometheus-metrics-model/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-model + bundle + + Prometheus Metrics Model + + Data model for read-only immutable Prometheus metrics snapshots. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + + junit + junit + 4.13.2 + test + + + 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 new file mode 100644 index 000000000..b0fba2db1 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java @@ -0,0 +1,42 @@ +package io.prometheus.metrics.model.registry; + +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; + +import java.util.List; +import java.util.function.Predicate; + +/** + * 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(); + + /** + * 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().getName())) { + return result; + } else { + return null; + } + } + + /** + * Override this and return {@code null} if a collector does not have a constant name (name may change between scrapes). + */ + default String getName() { + return collect().getMetadata().getName(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java new file mode 100644 index 000000000..e8e8c1621 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java @@ -0,0 +1,196 @@ +package io.prometheus.metrics.model.registry; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Predicate; + +import static java.util.Collections.unmodifiableCollection; + +/** + * Filter samples (i.e. time series) by name. + */ +public class MetricNameFilter implements Predicate { + + /** + * For convenience, a filter that allows all names. + */ + public static final Predicate ALLOW_ALL = name -> true; + + private final Collection nameIsEqualTo; + private final Collection nameIsNotEqualTo; + private final Collection nameStartsWith; + private final Collection nameDoesNotStartWith; + + private MetricNameFilter(Collection nameIsEqualTo, Collection nameIsNotEqualTo, Collection nameStartsWith, Collection nameDoesNotStartWith) { + this.nameIsEqualTo = unmodifiableCollection(new ArrayList<>(nameIsEqualTo)); + this.nameIsNotEqualTo = unmodifiableCollection(new ArrayList<>(nameIsNotEqualTo)); + this.nameStartsWith = unmodifiableCollection(new ArrayList<>(nameStartsWith)); + this.nameDoesNotStartWith = unmodifiableCollection(new ArrayList<>(nameDoesNotStartWith)); + } + + @Override + public boolean test(String sampleName) { + return matchesNameEqualTo(sampleName) + && !matchesNameNotEqualTo(sampleName) + && matchesNameStartsWith(sampleName) + && !matchesNameDoesNotStartWith(sampleName); + } + + private boolean matchesNameEqualTo(String metricName) { + if (nameIsEqualTo.isEmpty()) { + return true; + } + for (String name : nameIsEqualTo) { + // The following ignores suffixes like _total. + // "request_count" and "request_count_total" both match a metric named "request_count". + if (name.startsWith(metricName)) { + return true; + } + } + return false; + } + + private boolean matchesNameNotEqualTo(String metricName) { + if (nameIsNotEqualTo.isEmpty()) { + return false; + } + for (String name : nameIsNotEqualTo) { + // The following ignores suffixes like _total. + // "request_count" and "request_count_total" both match a metric named "request_count". + if (name.startsWith(metricName)) { + return true; + } + } + return false; + } + + private boolean matchesNameStartsWith(String metricName) { + if (nameStartsWith.isEmpty()) { + return true; + } + for (String prefix : nameStartsWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + private boolean matchesNameDoesNotStartWith(String metricName) { + if (nameDoesNotStartWith.isEmpty()) { + return false; + } + for (String prefix : nameDoesNotStartWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private final Collection nameEqualTo = new ArrayList<>(); + private final Collection nameNotEqualTo = new ArrayList<>(); + private final Collection nameStartsWith = new ArrayList<>(); + private final Collection nameDoesNotStartWith = new ArrayList<>(); + + private Builder() { + } + + /** + * @see #nameMustBeEqualTo(Collection) + */ + public Builder nameMustBeEqualTo(String... names) { + return nameMustBeEqualTo(Arrays.asList(names)); + } + + /** + * Only samples with one of the {@code names} will be included. + *

+ * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) + * and not the metric name. For instance, to retrieve all samples from a histogram, you must include the + * '_count', '_sum' and '_bucket' names. + *

+ * This method should be used by HTTP exporters to implement the {@code ?name[]=} URL parameters. + * + * @param names empty means no restriction. + */ + public Builder nameMustBeEqualTo(Collection names) { + if (names != null) { + nameEqualTo.addAll(names); + } + return this; + } + + /** + * @see #nameMustNotBeEqualTo(Collection) + */ + public Builder nameMustNotBeEqualTo(String... names) { + return nameMustNotBeEqualTo(Arrays.asList(names)); + } + + /** + * All samples that are not in {@code names} will be excluded. + *

+ * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) + * and not the metric name. For instance, to exclude all samples from a histogram, you must exclude the + * '_count', '_sum' and '_bucket' names. + * + * @param names empty means no name will be excluded. + */ + public Builder nameMustNotBeEqualTo(Collection names) { + if (names != null) { + nameNotEqualTo.addAll(names); + } + return this; + } + + /** + * @see #nameMustStartWith(Collection) + */ + public Builder nameMustStartWith(String... prefixes) { + return nameMustStartWith(Arrays.asList(prefixes)); + } + + /** + * Only samples whose name starts with one of the {@code prefixes} will be included. + * + * @param prefixes empty means no restriction. + */ + public Builder nameMustStartWith(Collection prefixes) { + if (prefixes != null) { + nameStartsWith.addAll(prefixes); + } + return this; + } + + /** + * @see #nameMustNotStartWith(Collection) + */ + public Builder nameMustNotStartWith(String... prefixes) { + return nameMustNotStartWith(Arrays.asList(prefixes)); + } + + /** + * Samples with names starting with one of the {@code prefixes} will be excluded. + * + * @param prefixes empty means no time series will be excluded. + */ + public Builder nameMustNotStartWith(Collection prefixes) { + if (prefixes != null) { + nameDoesNotStartWith.addAll(prefixes); + } + return this; + } + + public MetricNameFilter build() { + return new MetricNameFilter(nameEqualTo, nameNotEqualTo, nameStartsWith, nameDoesNotStartWith); + } + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java new file mode 100644 index 000000000..3fd56e493 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -0,0 +1,44 @@ +package io.prometheus.metrics.model.registry; + +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; + +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * Like {@link Collector}, but collecting multiple Snapshots at once. + */ +@FunctionalInterface +public interface MultiCollector { + + /** + * Called when the Prometheus server scrapes metrics. + */ + MetricSnapshots collect(); + + /** + * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} is {@code true}. + *

+ * Override this if there is a more efficient way than first collecting all snapshot and then discarding the excluded ones. + */ + default MetricSnapshots collect(Predicate includedNames) { + MetricSnapshots allSnapshots = collect(); + MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); + for (MetricSnapshot snapshot : allSnapshots) { + if (includedNames.test(snapshot.getMetadata().getName())) { + result.addMetricSnapshot(snapshot); + } + } + return result.build(); + } + + /** + * Override this and return an empty list if the MultiCollector does not return a constant list of names + * (names may be added / removed between scrapes). + */ + default List getNames() { + return collect().stream().map(snapshot -> snapshot.getMetadata().getName()).collect(Collectors.toList()); + } +} 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 new file mode 100644 index 000000000..858a1b37d --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java @@ -0,0 +1,95 @@ +package io.prometheus.metrics.model.registry; + +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; + +public class PrometheusRegistry { + + public static final PrometheusRegistry defaultRegistry = new PrometheusRegistry(); + + private final Set names = ConcurrentHashMap.newKeySet(); + private final List collectors = new CopyOnWriteArrayList<>(); + private final List multiCollectors = new CopyOnWriteArrayList<>(); + + public void register(Collector collector) { + String name = collector.getName(); + if (!names.add(name)) { + throw new IllegalStateException("Can't register " + name + " because that name is already registered."); + } + collectors.add(collector); + } + + public void register(MultiCollector collector) { + for (String name : collector.getNames()) { + if (!names.add(name)) { + throw new IllegalStateException("Can't register " + name + " because that name is already registered."); + } + } + multiCollectors.add(collector); + } + + public void unregister(Collector collector) { + collectors.remove(collector); + names.remove(collector.getName()); + } + + public void unregister(MultiCollector collector) { + multiCollectors.remove(collector); + for (String name : collector.getNames()) { + names.remove(name); + } + } + + public MetricSnapshots scrape() { + MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); + for (Collector collector : collectors) { + result.addMetricSnapshot(collector.collect()); + } + for (MultiCollector collector : multiCollectors) { + for (MetricSnapshot snapshot : collector.collect()) { + result.addMetricSnapshot(snapshot); + } + } + return result.build(); + } + + public MetricSnapshots scrape(Predicate includedNames) { + if (includedNames == null) { + return scrape(); + } + MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); + for (Collector collector : collectors) { + String name = collector.getName(); + if (name == null || includedNames.test(name)) { + MetricSnapshot snapshot = collector.collect(includedNames); + if (snapshot != null) { + result.addMetricSnapshot(snapshot); + } + } + } + for (MultiCollector collector : multiCollectors) { + List names = collector.getNames(); + boolean excluded = true; // the multi-collector is excluded unless at least one name matches + for (String name : names) { + if (includedNames.test(name)) { + excluded = false; + break; + } + } + if (!excluded) { + for (MetricSnapshot snapshot : collector.collect(includedNames)) { + if (snapshot != null) { + result.addMetricSnapshot(snapshot); + } + } + } + } + return result.build(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java new file mode 100644 index 000000000..6ca2f90ec --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java @@ -0,0 +1,42 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Helper class for iterating over {@link ClassicHistogramBuckets}. + * Note that the {@code count} is not cumulative. + */ +public class ClassicHistogramBucket implements Comparable { + + private final long count; // not cumulative + private final double upperBound; + + public ClassicHistogramBucket(double upperBound, long count) { + this.count = count; + this.upperBound = upperBound; + if (Double.isNaN(upperBound)) { + throw new IllegalArgumentException("Cannot use NaN as an upper bound for a histogram bucket"); + } + if (count < 0) { + throw new IllegalArgumentException(count + ": " + ClassicHistogramBuckets.class.getSimpleName() + " cannot have a negative count"); + } + } + + public long getCount() { + return count; + } + + public double getUpperBound() { + return upperBound; + } + + /** + * For sorting a list of buckets by upper bound. + */ + @Override + public int compareTo(ClassicHistogramBucket other) { + int result = Double.compare(upperBound, other.upperBound); + if (result != 0) { + return result; + } + return Long.compare(count, other.count); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java new file mode 100644 index 000000000..cd20eb4e8 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java @@ -0,0 +1,223 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +/** + * Immutable container for histogram buckets with fixed bucket boundaries. + * Note that the counts are not cumulative. + */ +public class ClassicHistogramBuckets implements Iterable { + + /** + * Used in native histograms to indicate that no classic histogram buckets are present. + */ + public static final ClassicHistogramBuckets EMPTY = new ClassicHistogramBuckets(new double[]{}, new long[]{}); + + private final double[] upperBounds; + private final long[] counts; // not cumulative + + private ClassicHistogramBuckets(double[] upperBounds, long[] counts) { + this.upperBounds = upperBounds; + this.counts = counts; + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, + * or use {@link ClassicHistogramBuckets#newBuilder()}. + *

+ * This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. + * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. + * An upper bound must not be {@link Double#NaN}. + * The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. + * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. + * For each count, {@link Number#longValue()} is called to get the value. + * Counts are not cumulative. Counts must not be negative. + */ + public static ClassicHistogramBuckets of(List upperBounds, List counts) { + double[] upperBoundsCopy = new double[upperBounds.size()]; + for (int i = 0; i < upperBounds.size(); i++) { + upperBoundsCopy[i] = upperBounds.get(i); + } + long[] countsCopy = new long[counts.size()]; + for (int i = 0; i < counts.size(); i++) { + countsCopy[i] = counts.get(i).longValue(); + } + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, + * or use {@link ClassicHistogramBuckets#newBuilder()}. + *

+ * This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. + * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. + * An upper bound must not be {@link Double#NaN}. + * The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. + * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. + * For each count, {@link Number#longValue()} is called to get the value. + * Counts are not cumulative. Counts must not be negative. + */ + public static ClassicHistogramBuckets of(double[] upperBounds, Number[] counts) { + double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); + long[] countsCopy = new long[counts.length]; + for (int i = 0; i < counts.length; i++) { + countsCopy[i] = counts[i].longValue(); + } + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, + * or use {@link ClassicHistogramBuckets#newBuilder()}. + *

+ * This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. + * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. + * An upper bound must not be {@link Double#NaN}. + * The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. + * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. + * Counts are not cumulative. Counts must not be negative. + */ + public static ClassicHistogramBuckets of(double[] upperBounds, long[] counts) { + double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); + long[] countsCopy = Arrays.copyOf(counts, counts.length); + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + private static void sortAndValidate(double[] upperBounds, long[] counts) { + if (upperBounds.length != counts.length) { + throw new IllegalArgumentException("upperBounds.length == " + upperBounds.length + " but counts.length == " + counts.length + ". Expected the same length."); + } + sort(upperBounds, counts); + validate(upperBounds, counts); + } + + private static void sort(double[] upperBounds, long[] counts) { + // Bubblesort. Should be efficient here as in most cases upperBounds is already sorted. + int n = upperBounds.length; + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (upperBounds[j] > upperBounds[j + 1]) { + swap(j, j + 1, upperBounds, counts); + } + } + } + } + + private static void swap(int i, int j, double[] upperBounds, long[] counts) { + double tmpDouble = upperBounds[j]; + upperBounds[j] = upperBounds[i]; + upperBounds[i] = tmpDouble; + long tmpLong = counts[j]; + counts[j] = counts[i]; + counts[i] = tmpLong; + } + + private static void validate(double[] upperBounds, long[] counts) { + // Preconditions: + // * upperBounds sorted + // * upperBounds and counts have the same length + if (upperBounds.length == 0) { + throw new IllegalArgumentException(ClassicHistogramBuckets.class.getSimpleName() + " cannot be empty. They must contain at least the +Inf bucket."); + } + if (upperBounds[upperBounds.length - 1] != Double.POSITIVE_INFINITY) { + throw new IllegalArgumentException(ClassicHistogramBuckets.class.getSimpleName() + " must contain the +Inf bucket."); + } + for (int i = 0; i < upperBounds.length; i++) { + if (Double.isNaN(upperBounds[i])) { + throw new IllegalArgumentException("Cannot use NaN as an upper bound in " + ClassicHistogramBuckets.class.getSimpleName()); + } + if (counts[i] < 0) { + throw new IllegalArgumentException("Counts in " + ClassicHistogramBuckets.class.getSimpleName() + " cannot be negative."); + } + if (i > 0) { + if (upperBounds[i - 1] == upperBounds[i]) { + throw new IllegalArgumentException("Duplicate upper bound " + upperBounds[i]); + } + } + } + } + + public int size() { + return upperBounds.length; + } + + public double getUpperBound(int i) { + return upperBounds[i]; + } + + /** + * The count is not cumulative. + */ + public long getCount(int i) { + return counts[i]; + } + + public boolean isEmpty() { + return this.upperBounds.length == 0; + } + + private List asList() { + List result = new ArrayList<>(size()); + for (int i = 0; i < upperBounds.length; i++) { + result.add(new ClassicHistogramBucket(upperBounds[i], counts[i])); + } + return Collections.unmodifiableList(result); + } + + @Override + public Iterator iterator() { + return asList().iterator(); + } + + public Stream stream() { + return asList().stream(); + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, + * or use {@code newBuilder()}. + */ + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private final List upperBounds = new ArrayList<>(); + private final List counts = new ArrayList<>(); + + private Builder() {} + + /** + * Must be called at least once for the {@link Double#POSITIVE_INFINITY} bucket. + */ + public Builder addBucket(double upperBound, long count) { + upperBounds.add(upperBound); + counts.add(count); + return this; + } + + /** + * Will throw an {@link IllegalArgumentException} if the {@link Double#POSITIVE_INFINITY} bucket is missing. + */ + public ClassicHistogramBuckets build() { + return ClassicHistogramBuckets.of(upperBounds, counts); + } + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java new file mode 100644 index 000000000..e994e9513 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -0,0 +1,148 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of a Counter. + */ +public class CounterSnapshot extends MetricSnapshot { + + /** + * To create a new {@link CounterSnapshot}, you can either call the constructor directly or use + * the builder with {@link CounterSnapshot#newBuilder()}. + * + * @param metadata the metric name in metadata must not include the {@code _total} suffix. + * See {@link MetricMetadata} for more naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public CounterSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getData() { + return (List) data; + } + + public static class CounterDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + + /** + * To create a new {@link CounterDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link CounterDataPointSnapshot#newBuilder()}. + * + * @param value the counter value. Must not be negative. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series + * (this specific set of labels) was created (or reset to zero). + * It's optional. Use {@code 0L} if there is no created timestamp. + */ + public CounterDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long createdTimestampMillis) { + this(value, labels, exemplar, createdTimestampMillis, 0); + } + + /** + * 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 CounterDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long createdTimestampMillis, long scrapeTimestampMillis) { + super(labels, createdTimestampMillis, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; + validate(); + } + + public double getValue() { + return value; + } + + /** + * May be {@code null}. + */ + public Exemplar getExemplar() { + return exemplar; + } + + protected void validate() { + if (value < 0.0) { + throw new IllegalArgumentException(value + ": counters cannot have a negative value"); + } + } + + public static class Builder extends DataPointSnapshot.Builder { + + private Exemplar exemplar = null; + private Double value = null; + private long createdTimestampMillis = 0L; + + private Builder() { + } + + /** + * Counter value. This is required. The value must not be negative. + */ + public Builder withValue(double value) { + this.value = value; + return this; + } + + public Builder withExemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } + + public Builder withCreatedTimestampMillis(long createdTimestampMillis) { + this.createdTimestampMillis = createdTimestampMillis; + return this; + } + + public CounterDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); + } + return new CounterDataPointSnapshot(value, labels, exemplar, createdTimestampMillis, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(CounterDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + public CounterSnapshot build() { + return new CounterSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java new file mode 100644 index 000000000..b4241e2e4 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java @@ -0,0 +1,82 @@ +package io.prometheus.metrics.model.snapshots; + +public abstract class DataPointSnapshot { + private final Labels labels; + private final long createdTimestampMillis; + private final long scrapeTimestampMillis; + + protected DataPointSnapshot(Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { + this.labels = labels; + this.createdTimestampMillis = createdTimestampMillis; + this.scrapeTimestampMillis = scrapeTimestampMillis; + validate(); + } + + private void validate() { + if (labels == null) { + throw new IllegalArgumentException("Labels cannot be null. Use Labels.EMPTY if there are no labels."); + } + if (createdTimestampMillis < 0) { + throw new IllegalArgumentException("Created timestamp cannot be negative. Use 0 if the metric doesn't have a created timestamp."); + } + if (scrapeTimestampMillis < 0) { + throw new IllegalArgumentException("Scrape timestamp cannot be negative. Use 0 to indicate that the Prometheus server should set the scrape timestamp."); + } + if (hasCreatedTimestamp() && hasScrapeTimestamp()) { + if (scrapeTimestampMillis < createdTimestampMillis) { + throw new IllegalArgumentException("The scrape timestamp cannot be before the created timestamp"); + } + } + } + + public Labels getLabels() { + return labels; + } + + public boolean hasScrapeTimestamp() { + return scrapeTimestampMillis != 0L; + } + + /** + * This will only return a reasonable value if {@link #hasScrapeTimestamp()} is true. + */ + public long getScrapeTimestampMillis() { + return scrapeTimestampMillis; + } + + public boolean hasCreatedTimestamp() { + return createdTimestampMillis != 0L; + } + + /** + * This will only return a reasonable value if {@link #hasCreatedTimestamp()} is true. + * Some metrics like Gauge don't have created timestamps. For these metrics {@link #hasCreatedTimestamp()} + * is always false. + */ + public long getCreatedTimestampMillis() { + return createdTimestampMillis; + } + + public static abstract class Builder> { + + protected Labels labels = Labels.EMPTY; + protected long scrapeTimestampMillis = 0L; + + public T withLabels(Labels labels) { + this.labels = labels; + return self(); + } + + /** + * In most cases you should not need to set a timestamp, because the timestamp of a Prometheus metric should + * usually be set by the Prometheus server during scraping. + * Exceptions include mirroring metrics with given timestamps from other metric sources. + */ + public T withScrapeTimestampMillis(long scrapeTimestampMillis) { + this.scrapeTimestampMillis = scrapeTimestampMillis; + return self(); + } + + protected abstract T self(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java new file mode 100644 index 000000000..5536f01e9 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java @@ -0,0 +1,89 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Common base class for histogram and summary data. + * Histograms and Summaries represent distributions, like a latency distribution or a distribution + * of request sizes in Bytes. + */ +public abstract class DistributionDataPointSnapshot extends DataPointSnapshot { + private final long count; // optional, negative value means no count. + private final double sum; // optional, Double.NaN means no sum. + private final Exemplars exemplars; // optional, Exemplars.EMPTY means no Exemplars. + + /** + * See JavaDoc of the child classes. + */ + protected DistributionDataPointSnapshot(long count, double sum, Exemplars exemplars, Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { + super(labels, createdTimestampMillis, scrapeTimestampMillis); + this.count = count; + this.sum = sum; + this.exemplars = exemplars == null ? Exemplars.EMPTY : exemplars; + validate(); + } + + private void validate() { + // If a histogram or summary observes negative values the sum could be negative. + // According to OpenMetrics sum should be omitted in that case, but we don't enforce this here. + } + + public boolean hasCount() { + return count >= 0; + } + + public boolean hasSum() { + return !Double.isNaN(sum); + } + + /** + * This will return garbage if {@link #hasCount()} is {@code false}. + */ + public long getCount() { + return count; + } + + /** + * This will return garbage if {@link #hasSum()} is {@code false}. + */ + public double getSum() { + return sum; + } + + /** + * May be {@link Exemplars#EMPTY}, but will never be {@code null}. + */ + public Exemplars getExemplars() { + return exemplars; + } + + static abstract class Builder> extends DataPointSnapshot.Builder { + + protected long count = -1; + protected double sum = Double.NaN; + protected long createdTimestampMillis = 0L; + protected Exemplars exemplars = Exemplars.EMPTY; + + /** + * Count can be explicitly set on summaries (this is a public method for summary metrics), + * and it is set implicitly on histograms (derived from the bucket counts). + */ + protected T withCount(long count) { + this.count = count; + return self(); + } + + public T withSum(double sum) { + this.sum = sum; + return self(); + } + + public T withExemplars(Exemplars exemplars) { + this.exemplars = exemplars; + return self(); + } + + public T withCreatedTimestampMillis(long createdTimestampMillis) { + this.createdTimestampMillis = createdTimestampMillis; + return self(); + } + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java new file mode 100644 index 000000000..c9865aac5 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java @@ -0,0 +1,129 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Immutable representation of an Exemplar. + */ +public class Exemplar { + + /** + * Label name for trace id. + */ + public static final String TRACE_ID = "trace_id"; + + /** + * Label name for span id. + */ + public static final String SPAN_ID = "span_id"; + + private final double value; + private final Labels labels; + private final long timestampMillis; + + /** + * To create a new {@link Exemplar}, you can either call the constructor directly + * or use the Builder with {@link Exemplar#newBuilder()}. + * + * @param value the observed value. This is required. + * @param labels in most cases the labels will contain the {@link #TRACE_ID} and {@link #SPAN_ID}. + * Must not be {@code null}. Use {@link Labels#EMPTY} if no labels are present. + * @param timestampMillis timestamp when the value was observed. Optional. Use 0L if not available. + */ + public Exemplar(double value, Labels labels, long timestampMillis) { + if (labels == null) { + throw new NullPointerException("Labels cannot be null. Use Labels.EMPTY."); + } + this.value = value; + this.labels = labels; + this.timestampMillis = timestampMillis; + } + + public double getValue() { + return value; + } + + /** + * In most cases labels will contain {@link #TRACE_ID} and {@link #SPAN_ID}, but this is not required. + * May be {@link Labels#EMPTY}, but may not be {@code null}. + */ + public Labels getLabels() { + return labels; + } + + public boolean hasTimestamp() { + return timestampMillis != 0L; + } + + /** + * Will return garbage if {@link #hasTimestamp()} is {@code false}. + */ + public long getTimestampMillis() { + return timestampMillis; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private Double value = null; + private Labels labels = Labels.EMPTY; + private String traceId = null; + private String spanId = null; + private long timestampMillis = 0L; + + private Builder() { + } + + public Builder withValue(double value) { + this.value = value; + return this; + } + + public Builder withTraceId(String traceId) { + this.traceId = traceId; + return this; + } + + public Builder withSpanId(String spanId) { + this.spanId = spanId; + return this; + } + + public Builder withLabels(Labels labels) { + if (labels == null) { + throw new NullPointerException(); + } + this.labels = labels; + return this; + } + + public Builder withTimestampMillis(long timestampMillis) { + this.timestampMillis = timestampMillis; + return this; + } + + /** + * @throws IllegalStateException if {@link #withValue(double)} wasn't called. + */ + public Exemplar build() { + if (value == null) { + throw new IllegalStateException("cannot build an Exemplar without a value"); + } + Labels allLabels; + if (traceId != null && spanId != null) { + allLabels = Labels.of(TRACE_ID, traceId, SPAN_ID, spanId); + } else if (traceId != null) { + allLabels = Labels.of(TRACE_ID, traceId); + } else if (spanId != null) { + allLabels = Labels.of(SPAN_ID, spanId); + } else { + allLabels = Labels.EMPTY; + } + if (!labels.isEmpty()) { + allLabels = allLabels.merge(labels); + } + return new Exemplar(value, allLabels, timestampMillis); + } + } +} 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 new file mode 100644 index 000000000..641d0e573 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java @@ -0,0 +1,128 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Immutable container for Exemplars. + *

+ * 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) { + this.exemplars = Collections.unmodifiableList(new ArrayList<>(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#newBuilder()}. + * + * @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#newBuilder()}. + * + * @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. + */ + public Exemplar get(double lowerBound, double upperBound) { + for (int i = 0; i < exemplars.size(); i++) { + Exemplar exemplar = exemplars.get(i); + double value = exemplar.getValue(); + if (value > lowerBound && value <= upperBound) { + return exemplar; + } + } + return null; + } + + /** + * 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 Builder() { + } + + public Builder addExemplar(Exemplar exemplar) { + exemplars.add(exemplar); + return this; + } + + public Builder addExemplars(List exemplars) { + this.exemplars.addAll(exemplars); + return this; + } + + public Exemplars build() { + return Exemplars.of(exemplars); + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java new file mode 100644 index 000000000..54c033d34 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java @@ -0,0 +1,134 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of a Gauge. + */ +public final class GaugeSnapshot extends MetricSnapshot { + + /** + * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use + * the builder with {@link GaugeSnapshot#newBuilder()}. + * + * @param metadata see {@link MetricMetadata} for naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public GaugeSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getData() { + return (List) data; + } + + public static final class GaugeDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + + /** + * To create a new {@link GaugeDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link GaugeDataPointSnapshot#newBuilder()}. + * + * @param value the gauge value. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. + */ + public GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { + this(value, labels, exemplar, 0); + } + + /** + * 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 GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; + } + + public double getValue() { + return value; + } + + /** + * May be {@code null}. + */ + public Exemplar getExemplar() { + return exemplar; + } + + public static class Builder extends DataPointSnapshot.Builder { + + private Exemplar exemplar = null; + private Double value = null; + + private Builder() { + } + + /** + * Gauge value. This is required. + */ + public Builder withValue(double value) { + this.value = value; + return this; + } + + /** + * Optional + */ + public Builder withExemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } + + public GaugeDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); + } + return new GaugeDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(GaugeDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + public GaugeSnapshot build() { + return new GaugeSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java new file mode 100644 index 000000000..860b291c7 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -0,0 +1,397 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of a Histogram. + */ +public final class HistogramSnapshot extends MetricSnapshot { + + private final boolean gaugeHistogram; + public static final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; + + /** + * To create a new {@link HistogramSnapshot}, you can either call the constructor directly or use + * the builder with {@link HistogramSnapshot#newBuilder()}. + * + * @param metadata see {@link MetricMetadata} for naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public HistogramSnapshot(MetricMetadata metadata, Collection data) { + this(false, metadata, data); + } + + /** + * Use this with the first parameter {@code true} to create a snapshot of a Gauge Histogram. + * The data model for Gauge Histograms is the same as for regular histograms, except that bucket values + * are semantically gauges and not counters. + * See openmetrics.io for more info on Gauge Histograms. + */ + public HistogramSnapshot(boolean isGaugeHistogram, MetricMetadata metadata, Collection data) { + super(metadata, data); + this.gaugeHistogram = isGaugeHistogram; + } + + public boolean isGaugeHistogram() { + return gaugeHistogram; + } + + @Override + public List getData() { + return (List) data; + } + + public static final class HistogramDataPointSnapshot extends DistributionDataPointSnapshot { + + // There are two types of histograms: Classic histograms and native histograms. + // Classic histograms have a fixed set of buckets. + // Native histograms have "infinitely many" buckets with exponentially growing boundaries. + // The OpenTelemetry terminology for native histogram is "exponential histogram". + // --- + // A histogram can be a classic histogram (indicated by nativeSchema == CLASSIC_HISTOGRAM), + // or a native histogram (indicated by classicBuckets == ClassicHistogramBuckets.EMPTY), + // or both. + // --- + // A histogram that is both classic and native is great for migrating from classic histograms + // to native histograms: Old Prometheus servers can still scrape the classic histogram, while + // new Prometheus servers can scrape the native histogram. + + private final ClassicHistogramBuckets classicBuckets; // May be ClassicHistogramBuckets.EMPTY for native histograms. + private final int nativeSchema; // Number in [-4, 8]. May be CLASSIC_HISTOGRAM for classic histograms. + private final long nativeZeroCount; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final double nativeZeroThreshold; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final NativeHistogramBuckets nativeBucketsForPositiveValues; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final NativeHistogramBuckets nativeBucketsForNegativeValues; // only used if nativeSchema != CLASSIC_HISTOGRAM + + /** + * Constructor for classic histograms (as opposed to native histograms). + *

+ * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link HistogramSnapshot#newBuilder()}. + * + * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. + * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series + * (this specific set of labels) was created (or reset to zero). + * It's optional. Use {@code 0L} if there is no created timestamp. + */ + public HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this(classicBuckets, CLASSIC_HISTOGRAM, 0, 0, NativeHistogramBuckets.EMPTY, NativeHistogramBuckets.EMPTY, sum, labels, exemplars, createdTimestampMillis, 0L); + } + + /** + * Constructor for native histograms (as opposed to classic histograms). + *

+ * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link HistogramSnapshot#newBuilder()}. + * + * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. + * @param nativeZeroCount number of observed zero values (zero is special because there is no + * histogram bucket for zero values). + * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as zero. + * This is to avoid creating a large number of buckets if observations fluctuate around zero. + * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. + * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. + * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series + * (this specific set of labels) was created (or reset to zero). + * It's optional. Use {@code 0L} if there is no created timestamp. + */ + public HistogramDataPointSnapshot( + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this(ClassicHistogramBuckets.EMPTY, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, 0L); + } + + /** + * Constructor for a histogram with both, classic and native data. + *

+ * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link HistogramSnapshot#newBuilder()}. + * + * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. + * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. + * @param nativeZeroCount number of observed zero values (zero is special because there is no + * histogram bucket for zero values). + * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as zero. + * This is to avoid creating a large number of buckets if observations fluctuate around zero. + * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. + * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. + * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series + * (this specific set of labels) was created (or reset to zero). + * It's optional. Use {@code 0L} if there is no created timestamp. + */ + public HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this(classicBuckets, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, 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 HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis, + long scrapeTimestampMillis) { + super(calculateCount(classicBuckets, nativeSchema, nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues), sum, exemplars, labels, createdTimestampMillis, scrapeTimestampMillis); + this.classicBuckets = classicBuckets; + this.nativeSchema = nativeSchema; + this.nativeZeroCount = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroCount; + this.nativeZeroThreshold = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroThreshold; + this.nativeBucketsForPositiveValues = nativeSchema == CLASSIC_HISTOGRAM ? NativeHistogramBuckets.EMPTY : nativeBucketsForPositiveValues; + this.nativeBucketsForNegativeValues = nativeSchema == CLASSIC_HISTOGRAM ? NativeHistogramBuckets.EMPTY : nativeBucketsForNegativeValues; + validate(); + } + + private static long calculateCount(ClassicHistogramBuckets classicBuckets, int nativeSchema, long nativeZeroCount, NativeHistogramBuckets nativeBucketsForPositiveValues, NativeHistogramBuckets nativeBucketsForNegativeValues) { + if (classicBuckets.isEmpty()) { + // This is a native histogram + return calculateNativeCount(nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); + } else if (nativeSchema == CLASSIC_HISTOGRAM) { + // This is a classic histogram + return calculateClassicCount(classicBuckets); + } else { + // This is both, a native and a classic histogram. Count should be the same for both. + long classicCount = calculateClassicCount(classicBuckets); + long nativeCount = calculateNativeCount(nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); + if (classicCount != nativeCount) { + throw new IllegalArgumentException("Inconsistent observation count: If a histogram has both classic and native data the observation count must be the same. Classic count is " + classicCount + " but native count is " + nativeCount + "."); + } + return classicCount; + } + } + + private static long calculateClassicCount(ClassicHistogramBuckets classicBuckets) { + long count = 0; + for (int i = 0; i < classicBuckets.size(); i++) { + count += classicBuckets.getCount(i); + } + return count; + } + + private static long calculateNativeCount(long nativeZeroCount, NativeHistogramBuckets nativeBucketsForPositiveValues, NativeHistogramBuckets nativeBucketsForNegativeValues) { + long count = nativeZeroCount; + for (int i = 0; i < nativeBucketsForNegativeValues.size(); i++) { + count += nativeBucketsForNegativeValues.getCount(i); + } + for (int i = 0; i < nativeBucketsForPositiveValues.size(); i++) { + count += nativeBucketsForPositiveValues.getCount(i); + } + return count; + } + + public boolean hasClassicHistogramData() { + return !classicBuckets.isEmpty(); + } + + public boolean hasNativeHistogramData() { + return nativeSchema != CLASSIC_HISTOGRAM; + } + + /** + * Will return garbage if {@link #hasClassicHistogramData()} is {@code false}. + */ + public ClassicHistogramBuckets getClassicBuckets() { + return classicBuckets; + } + + /** + * The schema defines the scale of the native histogram, i.g. the granularity of the buckets. + * Current supported values are -4 <= schema <= 8. + * See {@link NativeHistogramBuckets} for more info. + * This will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public int getNativeSchema() { + return nativeSchema; + } + + /** + * Number of observed zero values. + * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public long getNativeZeroCount() { + return nativeZeroCount; + } + + /** + * All observations in [-nativeZeroThreshold; +nativeZeroThreshold] are treated as zero. + * This is useful to avoid creation of a large number of buckets if observations fluctuate around zero. + * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public double getNativeZeroThreshold() { + return nativeZeroThreshold; + } + + /** + * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public NativeHistogramBuckets getNativeBucketsForPositiveValues() { + return nativeBucketsForPositiveValues; + } + + /** + * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public NativeHistogramBuckets getNativeBucketsForNegativeValues() { + return nativeBucketsForNegativeValues; + } + + private void validate() { + for (Label label : getLabels()) { + if (label.getName().equals("le")) { + throw new IllegalArgumentException("le is a reserved label name for histograms"); + } + } + if (nativeSchema == CLASSIC_HISTOGRAM && classicBuckets.isEmpty()) { + throw new IllegalArgumentException("Histogram buckets cannot be empty, must at least have the +Inf bucket."); + } + if (nativeSchema != CLASSIC_HISTOGRAM) { + if (nativeSchema < -4 || nativeSchema > 8) { + throw new IllegalArgumentException(nativeSchema + ": illegal schema. Expecting number in [-4, 8]."); + } + if (nativeZeroCount < 0) { + throw new IllegalArgumentException(nativeZeroCount + ": nativeZeroCount cannot be negative"); + } + if (Double.isNaN(nativeZeroThreshold) || nativeZeroThreshold < 0) { + throw new IllegalArgumentException(nativeZeroThreshold + ": illegal nativeZeroThreshold. Must be >= 0."); + } + } + } + + public static class Builder extends DistributionDataPointSnapshot.Builder { + + private ClassicHistogramBuckets classicHistogramBuckets = ClassicHistogramBuckets.EMPTY; + private int nativeSchema = CLASSIC_HISTOGRAM; + private long nativeZeroCount = 0; + private double nativeZeroThreshold = 0; + private NativeHistogramBuckets nativeBucketsForPositiveValues = NativeHistogramBuckets.EMPTY; + private NativeHistogramBuckets nativeBucketsForNegativeValues = NativeHistogramBuckets.EMPTY; + + private Builder() { + } + + @Override + protected Builder self() { + return this; + } + + public Builder withClassicHistogramBuckets(ClassicHistogramBuckets classicBuckets) { + this.classicHistogramBuckets = classicBuckets; + return this; + } + + public Builder withNativeSchema(int nativeSchema) { + this.nativeSchema = nativeSchema; + return this; + } + + public Builder withNativeZeroCount(long zeroCount) { + this.nativeZeroCount = zeroCount; + return this; + } + + public Builder withNativeZeroThreshold(double zeroThreshold) { + this.nativeZeroThreshold = zeroThreshold; + return this; + } + + public Builder withNativeBucketsForPositiveValues(NativeHistogramBuckets bucketsForPositiveValues) { + this.nativeBucketsForPositiveValues = bucketsForPositiveValues; + return this; + } + + public Builder withNativeBucketsForNegativeValues(NativeHistogramBuckets bucketsForNegativeValues) { + this.nativeBucketsForNegativeValues = bucketsForNegativeValues; + return this; + } + + public HistogramDataPointSnapshot build() { + if (nativeSchema == CLASSIC_HISTOGRAM && classicHistogramBuckets.isEmpty()) { + throw new IllegalArgumentException("One of nativeSchema and classicHistogramBuckets is required."); + } + return new HistogramDataPointSnapshot(classicHistogramBuckets, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + private boolean isGaugeHistogram = false; + + private Builder() { + } + + public Builder addDataPoint(HistogramDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + /** + * Create a Gauge Histogram. The data model for Gauge Histograms is the same as for regular histograms, + * except that bucket values are semantically gauges and not counters. + * See openmetrics.io for more info on Gauge Histograms. + */ + public Builder asGaugeHistogram() { + isGaugeHistogram = true; + return this; + } + + public HistogramSnapshot build() { + return new HistogramSnapshot(isGaugeHistogram, buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java new file mode 100644 index 000000000..b49e0d121 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -0,0 +1,104 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of an Info metric. + */ +public final class InfoSnapshot extends MetricSnapshot { + + /** + * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use + * the builder with {@link InfoSnapshot#newBuilder()}. + * + * @param metadata the metric name in metadata must not include the {@code _info} suffix. + * See {@link MetricMetadata} for more naming conventions. + * The metadata must not have a unit. + * @param data the constructor will create a sorted copy of the collection. + */ + public InfoSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + if (metadata.getName().endsWith("_info")) { + throw new IllegalArgumentException("The name of an info snapshot must not include the _info suffix"); + } + if (metadata.hasUnit()) { + throw new IllegalArgumentException("An Info metric cannot have a unit."); + } + } + + @Override + public List getData() { + return (List) data; + } + + public static class InfoDataPointSnapshot extends DataPointSnapshot { + + /** + * To create a new {@link InfoDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link InfoDataPointSnapshot#newBuilder()}. + * + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + */ + public InfoDataPointSnapshot(Labels labels) { + this(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 InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); + } + + public static class Builder extends DataPointSnapshot.Builder { + + public InfoDataPointSnapshot build() { + return new InfoDataPointSnapshot(labels, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(InfoDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + @Override + public Builder withUnit(Unit unit) { + throw new IllegalArgumentException("Info metric cannot have a unit."); + } + + public InfoSnapshot build() { + return new InfoSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java new file mode 100644 index 000000000..c31a8b1af --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java @@ -0,0 +1,28 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Utility for iterating over {@link Labels}. + */ +public final class Label implements Comparable

    + *
  • The name MUST NOT include the {@code _total} suffix for counter metrics or the + * {@code _info} suffix for info metrics. + * If in doubt, use {@link #sanitizeMetricName(String)} to remove the suffix.
  • + *
  • If name is {@code null}, a {@link NullPointerException} is thrown.
  • + *
  • If {@link #isValidMetricName(String) isValidMetricName(name)} is false, + * an {@link IllegalArgumentException} is thrown. + * Use {@link #sanitizeMetricName(String)} to convert arbitrary Strings to valid names.
  • + *
  • If unit != null, the name SHOULD contain the unit as a suffix. Example: + *
    +     *         new MetricMetadata("cache_size_bytes", "current size of the cache", Unit.BYTES);
    +     *         
    + * This is not enforced. No Exception will be thrown if the name does not have the unit as suffix.
  • + *
  • The name MUST NOT contain the {@code _total} or {@code _created} suffixes for counters, + * the {@code _count}, {@code _sum}, or {@code _created} suffixes for summaries, + * the {@code _count}, {@code _sum}, {@code _bucket}, or {@code _created} suffixes for classic histograms, + * the {@code _gcount}, {@code _gsum}, {@code _bucket} suffixes for classic gauge histograms, + * or the {@code _info} suffix for info metrics.
  • + *
+ * + * @param name must follow the naming conventions described above. + * @param help optional. May be {@code null}. + * @param unit optional. May be {@code null}. + */ + public MetricMetadata(String name, String help, Unit unit) { + this.name = name; + this.help = help; + this.unit = unit; + validate(); + } + + /** + * The name does not include the {@code _total} suffix for counter metrics + * or the {@code _info} suffix for Info metrics. + */ + public String getName() { + return name; + } + + public String getHelp() { + return help; + } + + public boolean hasUnit() { + return unit != null; + } + + public Unit getUnit() { + return unit; + } + + private void validate() { + if (name == null) { + throw new IllegalArgumentException("Missing required field: name is null"); + } + if (!isValidMetricName(name)) { + throw new IllegalArgumentException("'" + name + "': illegal metric name"); + } + } + + /** + * Test if a metric name is valid. Rules: + *
    + *
  • The name must match {@link #METRIC_NAME_RE}.
  • + *
  • The name MUST NOT end with one of the {@link #RESERVED_SUFFIXES}.
  • + *
+ * If a metric has a {@link Unit}, the metric name SHOULD end with the unit as a suffix (note that in + * OpenMetrics this is a MUST, but this library does not enforce Unit + * suffixes). + *

+ * Example: If you create a Counter for a processing time with {@link Unit#SECONDS}, the name should be + * {@code processing_time_seconds}. When exposed in OpenMetrics Text format, this will be represented as two + * values: {@code processing_time_seconds_total} for the counter value, and the optional + * {@code processing_time_seconds_created} timestamp. + *

+ * Use {@link #sanitizeMetricName(String)} to convert arbitrary Strings to valid metric names. + */ + public static boolean isValidMetricName(String name) { + for (String reservedSuffix : RESERVED_SUFFIXES) { + if (name.endsWith(reservedSuffix)) { + return false; + } + } + return METRIC_NAME_RE.matcher(name).matches(); + } + + /** + * Convert arbitrary metric names to valid Prometheus metric names. + */ + public static String sanitizeMetricName(String metricName) { + if (metricName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert an empty string into a valid metric name."); + } + int length = metricName.length(); + char[] sanitized = new char[length]; + for (int i = 0; i < length; i++) { + char ch = metricName.charAt(i); + if (ch == ':' || + (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (i > 0 && ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } + } + String sanitizedString = new String(sanitized); + boolean modified = true; + while (modified) { + modified = false; + for (String reservedSuffix : RESERVED_SUFFIXES) { + if (sanitizedString.equals(reservedSuffix)) { + // This is for the corner case when you call sanitizeMetricName("_total"). + // In that case the result will be "total". + return reservedSuffix.substring(1); + } + if (sanitizedString.endsWith(reservedSuffix)) { + sanitizedString = sanitizedString.substring(0, sanitizedString.length() - reservedSuffix.length()); + modified = true; + } + } + } + return sanitizedString; + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java new file mode 100644 index 000000000..5108c3bd0 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -0,0 +1,82 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Base class for metric snapshots. + */ +public abstract class MetricSnapshot { + + private final MetricMetadata metadata; + protected final List data; + + protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... data) { + this(metadata, Arrays.asList(data)); + } + + protected MetricSnapshot(MetricMetadata metadata, Collection data) { + this.metadata = metadata; + if (data == null) { + throw new NullPointerException(); + } + List dataCopy = new ArrayList<>(data); + dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); + this.data = Collections.unmodifiableList(dataCopy); + validateLabels(); + } + + public MetricMetadata getMetadata() { + return metadata; + } + + public abstract List getData(); + + protected void validateLabels() { + // Verify that labels are unique (the same set of names/values must not be used multiple times for the same metric). + for (int i = 0; i < data.size() - 1; i++) { + if (data.get(i).getLabels().equals(data.get(i + 1).getLabels())) { + throw new IllegalArgumentException("Duplicate labels in metric data: " + data.get(i).getLabels()); + } + } + // Should we verify that all entries in data have the same label names? + // No. They should have the same label names, but according to OpenMetrics this is not a MUST. + } + + public static abstract class Builder> { + + private String name; + private String help; + private Unit unit; + + /** + * The name is required. + * If the name is missing or invalid, {@code build()} will throw an {@link IllegalArgumentException}. + * See {@link MetricMetadata#isValidMetricName(String)} for info on valid metric names. + */ + public T withName(String name) { + this.name = name; + return self(); + } + + public T withHelp(String help) { + this.help = help; + return self(); + } + + public T withUnit(Unit unit) { + this.unit = unit; + return self(); + } + + protected MetricMetadata buildMetadata() { + return new MetricMetadata(name, help, unit); + } + + protected abstract T self(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java new file mode 100644 index 000000000..98200461f --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -0,0 +1,98 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import static java.util.Collections.unmodifiableList; +import static java.util.Comparator.comparing; + +/** + * Immutable list of metric snapshots. + */ +public class MetricSnapshots implements Iterable { + + private final List snapshots; + + /** + * See {@link #MetricSnapshots(Collection)} + */ + public MetricSnapshots(MetricSnapshot... snapshots) { + this(Arrays.asList(snapshots)); + } + + /** + * To create MetricSnapshots, you can either call the constructor directly + * or use {@link #newBuilder()}. + * + * @param snapshots the constructor creates a sorted copy of snapshots. + * @throws IllegalArgumentException if snapshots contains duplicate metric names. + * To avoid duplicate metric names use {@link #newBuilder()} and check + * {@link Builder#containsMetricName(String)} before calling + * {@link Builder#addMetricSnapshot(MetricSnapshot)}. + */ + public MetricSnapshots(Collection snapshots) { + List list = new ArrayList<>(snapshots); + list.sort(comparing(s -> s.getMetadata().getName())); + for (int i = 0; i < snapshots.size() - 1; i++) { + if (list.get(i).getMetadata().getName().equals(list.get(i + 1).getMetadata().getName())) { + throw new IllegalArgumentException(list.get(i).getMetadata().getName() + ": duplicate metric name"); + } + } + this.snapshots = unmodifiableList(list); + } + + public static MetricSnapshots of(MetricSnapshot... snapshots) { + return new MetricSnapshots(snapshots); + } + + @Override + public Iterator iterator() { + return snapshots.iterator(); + } + + public int size() { + return snapshots.size(); + } + + public MetricSnapshot get(int i) { + return snapshots.get(i); + } + + public Stream stream() { + return snapshots.stream(); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private final List snapshots = new ArrayList<>(); + + private Builder() { + } + + public boolean containsMetricName(String name) { + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals(name)) { + return true; + } + } + return false; + } + + public Builder addMetricSnapshot(MetricSnapshot snapshot) { + snapshots.add(snapshot); + return this; + } + + public MetricSnapshots build() { + return new MetricSnapshots(snapshots); + } + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java new file mode 100644 index 000000000..e7af0e6e8 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java @@ -0,0 +1,26 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * For iterating over {@link NativeHistogramBuckets}. + */ +public class NativeHistogramBucket { + + private final int bucketIndex; + private final long count; + + public NativeHistogramBucket(int bucketIndex, long count) { + this.bucketIndex = bucketIndex; + this.count = count; + } + + /** + * See {@link NativeHistogramBuckets} for info on native bucket indexes. + */ + public int getBucketIndex() { + return bucketIndex; + } + + public long getCount() { + return count; + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java new file mode 100644 index 000000000..6e0890a99 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java @@ -0,0 +1,159 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +/** + * Immutable representation of native histogram buckets. + *

+ * The bucket index defines the boundaries of the bucket, + * depending on the histogram's {@link HistogramSnapshot.HistogramDataPointSnapshot#getNativeSchema() schema}. + *

+ *     base = 2^(2^-schema)
+ *     lower bound = base^(index - 1)
+ *     upper bound = base^index
+ * 
+ */ +public class NativeHistogramBuckets implements Iterable { + + public static final NativeHistogramBuckets EMPTY = new NativeHistogramBuckets(new int[]{}, new long[]{}); + private final int[] bucketIndexes; + private final long[] counts; + + private NativeHistogramBuckets(int[] bucketIndexes, long[] counts) { + this.bucketIndexes = bucketIndexes; + this.counts = counts; + } + + /** + * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)} + * methods, or use {@link NativeHistogramBuckets#newBuilder()}. + * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty. + * @param counts must have the same length as bucketIndexes + */ + public static NativeHistogramBuckets of(int[] bucketIndexes, long[] counts) { + int[] bucketIndexesCopy = Arrays.copyOf(bucketIndexes, bucketIndexes.length); + long[] countsCopy = Arrays.copyOf(counts, counts.length); + sortAndValidate(bucketIndexesCopy, countsCopy); + return new NativeHistogramBuckets(bucketIndexesCopy, countsCopy); + } + + /** + * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)} + * methods, or use {@link NativeHistogramBuckets#newBuilder()}. + * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty. + * @param counts must have the same size as bucketIndexes + */ + public static NativeHistogramBuckets of(List bucketIndexes, List counts) { + int[] bucketIndexesCopy = new int[bucketIndexes.size()]; + for (int i=0; i asList() { + List result = new ArrayList<>(size()); + for (int i=0; i iterator() { + return asList().iterator(); + } + + public Stream stream() { + return asList().stream(); + } + + public int getBucketIndex(int i) { + return bucketIndexes[i]; + } + + public long getCount(int i) { + return counts[i]; + } + + private static void sortAndValidate(int[] bucketIndexes, long[] counts) { + if (bucketIndexes.length != counts.length) { + throw new IllegalArgumentException("bucketIndexes.length == " + bucketIndexes.length + " but counts.length == " + counts.length + ". Expected the same length."); + } + sort(bucketIndexes, counts); + validate(bucketIndexes, counts); + } + + private static void sort(int[] bucketIndexes, long[] counts) { + // Bubblesort. Should be efficient here as in most cases bucketIndexes is already sorted. + int n = bucketIndexes.length; + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (bucketIndexes[j] > bucketIndexes[j + 1]) { + swap(j, j+1, bucketIndexes, counts); + } + } + } + } + + private static void swap(int i, int j, int[] bucketIndexes, long[] counts) { + int tmpInt = bucketIndexes[j]; + bucketIndexes[j] = bucketIndexes[i]; + bucketIndexes[i] = tmpInt; + long tmpLong = counts[j]; + counts[j] = counts[i]; + counts[i] = tmpLong; + } + + private static void validate(int[] bucketIndexes, long[] counts) { + // Preconditions: + // * bucketIndexes sorted + // * bucketIndexes and counts have the same length + for (int i=0; i 0) { + if (bucketIndexes[i-1] == bucketIndexes[i]) { + throw new IllegalArgumentException("Duplicate bucket index " + bucketIndexes[i]); + } + } + } + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private final List bucketIndexes = new ArrayList<>(); + private final List counts = new ArrayList<>(); + + private Builder() {} + + public Builder addBucket(int bucketIndex, long count) { + bucketIndexes.add(bucketIndex); + counts.add(count); + return this; + } + + public NativeHistogramBuckets build() { + return NativeHistogramBuckets.of(bucketIndexes, counts); + } + } +} 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 new file mode 100644 index 000000000..7d5c1c166 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java @@ -0,0 +1,34 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Immutable representation of a Quantile. + */ +public class Quantile { + + 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(); + } + + public double getQuantile() { + return quantile; + } + + 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"); + } + } +} 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 new file mode 100644 index 000000000..1ad7002d2 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java @@ -0,0 +1,85 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.*; + +/** + * 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 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#newBuilder()}. + */ + 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#newBuilder()}. + */ + 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 class Builder { + + private final List quantiles = new ArrayList<>(); + private Builder() {} + + public Builder addQuantile(Quantile quantile) { + quantiles.add(quantile); + return this; + } + + /** + * @param quantile 0.0 <= quantile <= 1.0 + */ + public Builder addQuantile(double quantile, double value) { + quantiles.add(new Quantile(quantile, value)); + return this; + } + + public Quantiles build() { + return new Quantiles(quantiles); + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} 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 new file mode 100644 index 000000000..4cad4ac11 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java @@ -0,0 +1,225 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +/** + * 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#newBuilder()}. + * + * @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 : getData()) { + if (entry.getLabels().contains(getMetadata().getName())) { + throw new IllegalArgumentException("Label name " + getMetadata().getName() + " is reserved."); + } + } + } + + @Override + public List getData() { + return (List) data; + } + + + 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#newBuilder()}. + * + * @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(); + } + + 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() { + 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 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); + } + + @Override + public Iterator iterator() { + return asList().iterator(); + } + + public Stream stream() { + return asList().stream(); + } + + 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 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; + } + + public static class Builder extends DataPointSnapshot.Builder { + + private final ArrayList names = new ArrayList<>(); + private final ArrayList values = new ArrayList<>(); + + private Builder() {} + + public Builder addState(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 static Builder newBuilder() { + return new Builder(); + } + } + + 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 String getName() { + return name; + } + + public boolean isTrue() { + return value; + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(StateSetDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + @Override + public Builder withUnit(Unit unit) { + throw new IllegalArgumentException("StateSet metric cannot have a unit."); + } + + public StateSetSnapshot build() { + return new StateSetSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java new file mode 100644 index 000000000..cf84162a7 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java @@ -0,0 +1,136 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of a Summary metric. + */ +public final class SummarySnapshot extends MetricSnapshot { + + /** + * To create a new {@link SummarySnapshot}, you can either call the constructor directly or use + * the builder with {@link SummarySnapshot#newBuilder()}. + * + * @param metadata See {@link MetricMetadata} for more naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public SummarySnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getData() { + return (List) data; + } + + public static final class SummaryDataPointSnapshot extends DistributionDataPointSnapshot { + + private final Quantiles quantiles; + + + /** + * To create a new {@link SummaryDataPointSnapshot}, you can either call the constructor directly + * or use the Builder with {@link SummaryDataPointSnapshot#newBuilder()}. + * + * @param count total number of observations. Optional, pass -1 if not available. + * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. + * @param quantiles must not be {@code null}. Use {@link Quantiles#EMPTY} if there are no quantiles. + * @param labels must not be {@code null}. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be {@code null}. Use {@link Exemplars#EMPTY} if there are no exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when this summary + * data (this specific set of labels) was created. + * Note that this refers to the creation of the timeseries, + * not the creation of the snapshot. + * The created timestamp optional. Use {@code 0L} if there is no created timestamp. + */ + public SummaryDataPointSnapshot(long count, double sum, Quantiles quantiles, Labels labels, Exemplars exemplars, long createdTimestampMillis) { + this(count, sum, quantiles, labels, exemplars, createdTimestampMillis, 0); + } + + /** + * 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 SummaryDataPointSnapshot(long count, double sum, Quantiles quantiles, Labels labels, Exemplars exemplars, long createdTimestampMillis, long scrapeTimestampMillis) { + super(count, sum, exemplars, labels, createdTimestampMillis, scrapeTimestampMillis); + this.quantiles = quantiles; + validate(); + } + + public Quantiles getQuantiles() { + return quantiles; + } + + private void validate() { + for (Label label : getLabels()) { + if (label.getName().equals("quantile")) { + throw new IllegalArgumentException("quantile is a reserved label name for summaries"); + } + } + if (quantiles == null) { + throw new NullPointerException(); + } + } + + public static class Builder extends DistributionDataPointSnapshot.Builder { + + private Quantiles quantiles = Quantiles.EMPTY; + + private Builder() { + } + + @Override + protected Builder self() { + return this; + } + + public Builder withQuantiles(Quantiles quantiles) { + this.quantiles = quantiles; + return this; + } + + @Override + public Builder withCount(long count) { + super.withCount(count); + return this; + } + + public SummaryDataPointSnapshot build() { + return new SummaryDataPointSnapshot(count, sum, quantiles, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(SummaryDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + public SummarySnapshot build() { + return new SummarySnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java new file mode 100644 index 000000000..232cd9143 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -0,0 +1,47 @@ +package io.prometheus.metrics.model.snapshots; + +/** + * Some pre-defined units for convenience. You can create your own units with + *
+ *     new Unit("myUnit");
+ * 
+ * Note that in Prometheus, units are largely based on SI base units + * (seconds, bytes, joules, grams, meters, ratio, volts, amperes, and celsius). + */ +public class Unit { + + private final String name; + + public static final Unit RATIO = new Unit("ratio"); + public static final Unit SECONDS = new Unit("seconds"); + public static final Unit BYTES = new Unit("bytes"); + public static final Unit CELSIUS = new Unit("celsius"); + public static final Unit JOULES = new Unit("joules"); + public static final Unit GRAMS = new Unit("grams"); + public static final Unit METERS = new Unit("meters"); + public static final Unit VOLTS = new Unit("volts"); + public static final Unit AMPERES = new Unit("amperes"); + + public Unit(String name) { + this.name = name; + if (name == null) { + throw new NullPointerException("Unit name cannot be null."); + } + if (name.isEmpty()) { + throw new IllegalArgumentException("Unit name cannot be empty."); + } + } + + @Override + public String toString() { + return name; + } + + public static double nanosToSeconds(long nanos) { + return nanos / 1E9; + } + + public static double millisToSeconds(long nanos) { + return nanos / 1E3; + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java new file mode 100644 index 000000000..34735823b --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -0,0 +1,135 @@ +package io.prometheus.metrics.model.snapshots; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Immutable snapshot of an Unknown (Untyped) metric. + */ +public final class UnknownSnapshot extends MetricSnapshot { + + /** + * To create a new {@link UnknownSnapshot}, you can either call the constructor directly or use + * the builder with {@link UnknownSnapshot#newBuilder()}. + * + * @param metadata required name and optional help and unit. + * See {@link MetricMetadata} for naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public UnknownSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getData() { + return (List) data; + } + + public static final class UnknownDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + + /** + * To create a new {@link UnknownDataPointSnapshot}, you can either call the constructor directly or use the + * Builder with {@link UnknownDataPointSnapshot#newBuilder()}. + * + * @param value the value. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. + */ + public UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { + this(value, Labels.EMPTY, exemplar, 0); + } + + /** + * 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 UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; + } + + public double getValue() { + return value; + } + + /** + * May return {@code null}. + */ + public Exemplar getExemplar() { + return exemplar; + } + + public static class Builder extends DataPointSnapshot.Builder { + + private Exemplar exemplar = null; + private Double value = null; + + private Builder() { + } + + /** + * required. + */ + public Builder withValue(double value) { + this.value = value; + return this; + } + + /** + * Optional + */ + public Builder withExemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } + + public UnknownDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); + } + return new UnknownDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } + } + + public static class Builder extends MetricSnapshot.Builder { + + private final List dataPoints = new ArrayList<>(); + + private Builder() { + } + + public Builder addDataPoint(UnknownDataPointSnapshot data) { + dataPoints.add(data); + return this; + } + + public UnknownSnapshot build() { + return new UnknownSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; + } + } + + public static Builder newBuilder() { + return new Builder(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java new file mode 100644 index 000000000..04801e133 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java @@ -0,0 +1,104 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class ClassicHistogramBucketsTest { + + @Test + public void testGoodCase() { + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() + .addBucket(Double.NEGATIVE_INFINITY, 0) + .addBucket(-10.0, 7) + .addBucket(1024, 3) + .addBucket(Double.POSITIVE_INFINITY, 8) + .build(); + Assert.assertEquals(4, buckets.size()); + } + + @Test + public void testSort() { + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() + .addBucket(7, 2) + .addBucket(2, 0) + .addBucket(Double.POSITIVE_INFINITY, 3) + .build(); + Assert.assertEquals(3, buckets.size()); + Assert.assertEquals(2, buckets.getUpperBound(0), 0.0); + Assert.assertEquals(7, buckets.getUpperBound(1), 0.0); + Assert.assertEquals(Double.POSITIVE_INFINITY, buckets.getUpperBound(2), 0.0); + Assert.assertEquals(0, buckets.getCount(0)); + Assert.assertEquals(2, buckets.getCount(1)); + Assert.assertEquals(3, buckets.getCount(2)); + } + + @Test + public void testMinimalBuckets() { + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 0) + .build(); + Assert.assertEquals(1, buckets.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInfBucketMissing() { + ClassicHistogramBuckets.newBuilder() + .addBucket(Double.NEGATIVE_INFINITY, 0) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testNegativeCount() { + ClassicHistogramBuckets.newBuilder() + .addBucket(0.0, 10) + .addBucket(Double.POSITIVE_INFINITY, -1) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testNaNBoundary() { + ClassicHistogramBuckets.newBuilder() + .addBucket(0.0, 1) + .addBucket(Double.NaN, 2) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateBoundary() { + ClassicHistogramBuckets.newBuilder() + .addBucket(1.0, 1) + .addBucket(2.0, 2) + .addBucket(1.0, 2) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyBuckets() { + ClassicHistogramBuckets.newBuilder().build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testDifferentLength() { + double[] upperBounds = new double[] {0.7, 1.3, Double.POSITIVE_INFINITY}; + long[] counts = new long[] {13, 178, 1024, 3000}; + ClassicHistogramBuckets.of(upperBounds, counts); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() + .addBucket(1.0, 7) + .addBucket(2.0, 8) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build(); + Iterator iterator = buckets.iterator(); + iterator.next(); + iterator.remove(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java new file mode 100644 index 000000000..4f2b2d75d --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java @@ -0,0 +1,108 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; +import java.util.concurrent.TimeUnit; + +public class CounterSnapshotTest { + + @Test + public void testCompleteGoodCase() { + long createdTimestamp1 = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); + long createdTimestamp2 = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); + long exemplarTimestamp = System.currentTimeMillis(); + CounterSnapshot snapshot = CounterSnapshot.newBuilder() + .withName("http_server_requests_seconds") + .withHelp("total time spent serving requests") + .withUnit(Unit.SECONDS) + .addDataPoint(CounterDataPointSnapshot.newBuilder() + .withValue(1.0) + .withExemplar(Exemplar.newBuilder() + .withValue(3.0) + .withTraceId("abc123") + .withSpanId("123457") + .withTimestampMillis(exemplarTimestamp) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("path", "/world") + .build()) + .withCreatedTimestampMillis(createdTimestamp1) + .build() + ).addDataPoint(CounterDataPointSnapshot.newBuilder() + .withValue(2.0) + .withExemplar(Exemplar.newBuilder() + .withValue(4.0) + .withTraceId("def456") + .withSpanId("234567") + .withTimestampMillis(exemplarTimestamp) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("path", "/hello") + .build()) + .withCreatedTimestampMillis(createdTimestamp2) + .build() + ) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "http_server_requests_seconds", "total time spent serving requests", "seconds"); + Assert.assertEquals(2, snapshot.getData().size()); + CounterDataPointSnapshot data = snapshot.getData().get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(Labels.of("path", "/hello"), data.getLabels()); + Assert.assertEquals(2.0, data.getValue(), 0.0); + Assert.assertEquals(4.0, data.getExemplar().getValue(), 0.0); + Assert.assertEquals(createdTimestamp2, data.getCreatedTimestampMillis()); + Assert.assertFalse(data.hasScrapeTimestamp()); + data = snapshot.getData().get(1); + Assert.assertEquals(Labels.of("path", "/world"), data.getLabels()); + Assert.assertEquals(1.0, data.getValue(), 0.0); + Assert.assertEquals(3.0, data.getExemplar().getValue(), 0.0); + Assert.assertEquals(createdTimestamp1, data.getCreatedTimestampMillis()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } + + @Test + public void testMinimalGoodCase() { + CounterSnapshot snapshot = CounterSnapshot.newBuilder() + .withName("events") + .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "events", null, null); + Assert.assertEquals(1, snapshot.getData().size()); + CounterDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(Labels.EMPTY, data.getLabels()); + Assert.assertEquals(1.0, data.getValue(), 0.0); + Assert.assertNull(data.getExemplar()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } + + @Test + public void testEmptyCounter() { + CounterSnapshot snapshot = CounterSnapshot.newBuilder().withName("events").build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testTotalSuffixPresent() { + CounterSnapshot.newBuilder().withName("test_total").build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + CounterDataPointSnapshot.newBuilder().build(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + CounterSnapshot snapshot = CounterSnapshot.newBuilder() + .withName("events") + .addDataPoint(CounterDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "a")).withValue(1.0).build()) + .addDataPoint(CounterDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "b")).withValue(2.0).build()) + .build(); + Iterator iterator = snapshot.getData().iterator(); + iterator.next(); + iterator.remove(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java new file mode 100644 index 000000000..385ceb029 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java @@ -0,0 +1,78 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Labels; +import org.junit.Assert; +import org.junit.Test; + +public class ExemplarTest { + + @Test + public void testGoodCaseComplete() { + long timestamp = System.currentTimeMillis(); + Exemplar exemplar = Exemplar.newBuilder() + .withValue(2.2) + .withTraceId("abc123abc123") + .withSpanId("def456def456") + .withTimestampMillis(timestamp) + .withLabels(Labels.of("path", "/", "error", "none")) + .build(); + Assert.assertEquals(2.2, exemplar.getValue(), 0.0); + Assert.assertEquals(Labels.of(Exemplar.TRACE_ID, "abc123abc123", Exemplar.SPAN_ID, "def456def456", "path", "/", "error", "none"), exemplar.getLabels()); + Assert.assertTrue(exemplar.hasTimestamp()); + Assert.assertEquals(timestamp, exemplar.getTimestampMillis()); + } + + @Test(expected = IllegalStateException.class) + public void testValueMissing() { + Exemplar.newBuilder().build(); + } + + @Test + public void testMinimal() { + Exemplar exemplar = Exemplar.newBuilder().withValue(0.0).build(); + Assert.assertEquals(0.0, exemplar.getValue(), 0.0); + Assert.assertEquals(Labels.EMPTY, exemplar.getLabels()); + Assert.assertFalse(exemplar.hasTimestamp()); + } + + @Test + public void testLabelsMergeTraceId() { + Exemplar exemplar = Exemplar.newBuilder() + .withValue(0.0) + .withLabels(Labels.of("a", "b")) + .withTraceId("abc") + .build(); + Assert.assertEquals(Labels.of("a", "b", "trace_id", "abc"), exemplar.getLabels()); + } + + @Test + public void testLabelsMergeSpanId() { + Exemplar exemplar = Exemplar.newBuilder() + .withValue(0.0) + .withLabels(Labels.of("a", "b")) + .withSpanId("abc") + .build(); + Assert.assertEquals(Labels.of("a", "b", "span_id", "abc"), exemplar.getLabels()); + } + + @Test + public void testLabelsMergeTraceIdAndSpanId() { + Exemplar exemplar = Exemplar.newBuilder() + .withValue(0.0) + .withLabels(Labels.of("a", "b")) + .withSpanId("abc") + .withTraceId("def") + .build(); + Assert.assertEquals(Labels.of("span_id", "abc", "a", "b", "trace_id", "def"), exemplar.getLabels()); + } + + @Test + public void testLabelsMergeNone() { + Exemplar exemplar = Exemplar.newBuilder() + .withValue(0.0) + .withLabels(Labels.of("a", "b")) + .build(); + Assert.assertEquals(Labels.of("a", "b"), exemplar.getLabels()); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java new file mode 100644 index 000000000..3ef9447a7 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -0,0 +1,42 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class ExemplarsTest { + + @Test + public void testUpperBound() { + Exemplars exemplars = Exemplars.of( + Exemplar.newBuilder().withValue(1.0).build(), + Exemplar.newBuilder().withValue(3.0).build(), + Exemplar.newBuilder().withValue(2.0).build() + ); + Assert.assertEquals(3, exemplars.size()); + Assert.assertEquals(1.0, exemplars.get(0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(1).getValue(), 0.0); + Assert.assertEquals(2.0, exemplars.get(2).getValue(), 0.0); + Assert.assertEquals(1.0, exemplars.get(0.0, Double.POSITIVE_INFINITY).getValue(), 0.0); + Assert.assertEquals(1.0, exemplars.get(0.0, 1.0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(1.0, 4.0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(2.0, 3.0).getValue(), 0.0); + Assert.assertEquals(2.0, exemplars.get(1.0, 2.1).getValue(), 0.0); + Assert.assertNull(exemplars.get(2.0, 2.1)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + Exemplars exemplars = Exemplars.of( + Exemplar.newBuilder().withValue(1.0).build(), + Exemplar.newBuilder().withValue(3.0).build(), + Exemplar.newBuilder().withValue(2.0).build() + ); + Iterator iterator = exemplars.iterator(); + iterator.next(); + iterator.remove(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java new file mode 100644 index 000000000..20a094a23 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java @@ -0,0 +1,106 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class GaugeSnapshotTest { + + @Test + public void testCompleteGoodCase() { + long exemplarTimestamp = System.currentTimeMillis(); + GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() + .withName("cache_size_bytes") + .withHelp("cache size in Bytes") + .withUnit(Unit.BYTES) + .addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(1024.0) + .withExemplar(Exemplar.newBuilder() + .withValue(1024.0) + .withTraceId("abc123") + .withSpanId("123457") + .withTimestampMillis(exemplarTimestamp) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("env", "prod") + .build()) + .build() + ).addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(128.0) + .withExemplar(Exemplar.newBuilder() + .withValue(128.0) + .withTraceId("def456") + .withSpanId("234567") + .withTimestampMillis(exemplarTimestamp) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("env", "dev") + .build()) + .build() + ) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "cache_size_bytes", "cache size in Bytes", "bytes"); + Assert.assertEquals(2, snapshot.getData().size()); + GaugeDataPointSnapshot data = snapshot.getData().get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(Labels.of("env", "dev"), data.getLabels()); + Assert.assertEquals(128.0, data.getValue(), 0.0); + Assert.assertEquals(128.0, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + data = snapshot.getData().get(1); + Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); + Assert.assertEquals(1024.0, data.getValue(), 0.0); + Assert.assertEquals(1024.0, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } + + @Test + public void testMinimalGoodCase() { + GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() + .withName("temperature") + .addDataPoint(GaugeDataPointSnapshot.newBuilder().withValue(23.0).build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "temperature", null, null); + Assert.assertEquals(1, snapshot.getData().size()); + GaugeDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(Labels.EMPTY, data.getLabels()); + Assert.assertEquals(23.0, data.getValue(), 0.0); + Assert.assertNull(data.getExemplar()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } + + @Test + public void testEmptyGauge() { + GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() + .withName("temperature") + .build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testTotalSuffixPresent() { + CounterSnapshot.newBuilder().withName("test_total").build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + CounterDataPointSnapshot.newBuilder().build(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() + .withName("gauge") + .addDataPoint(GaugeDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "a")).withValue(23.0).build()) + .addDataPoint(GaugeDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "b")).withValue(23.0).build()) + .build(); + Iterator iterator = snapshot.getData().iterator(); + iterator.next(); + iterator.remove(); + } +} 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 new file mode 100644 index 000000000..9dc21a235 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java @@ -0,0 +1,269 @@ +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; + +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.newBuilder() + .withValue(129.0) + .withTraceId("abcabc") + .withSpanId("defdef") + .withLabels(Labels.of("status", "200")) + .withTimestampMillis(exemplarTimestamp) + .build(); + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("request_size_bytes") + .withHelp("request sizes in bytes") + .withUnit(Unit.BYTES) + .addDataPoint( + HistogramDataPointSnapshot.newBuilder() + .withSum(27000.0) + .withNativeSchema(5) + .withNativeZeroCount(2) + .withNativeZeroThreshold(0.0000001) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 0) + .addBucket(128.0, 7) + .addBucket(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. + .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + .addBucket(1, 12) + .addBucket(2, 3) + .addBucket(4, 2) + .build()) + .withNativeBucketsForNegativeValues(NativeHistogramBuckets.newBuilder() + .addBucket(-1, 1) + .addBucket(0, 2) + .build()) + .withLabels(Labels.of("path", "/")) + .withExemplars(Exemplars.of(exemplar1)) + .withCreatedTimestampMillis(createdTimestamp) + .withScrapeTimestampMillis(scrapeTimestamp) + .build()) + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withCount(3) // TODO how is that not a compile error? This is a protected method! + .withSum(400.2) + .withNativeSchema(5) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(128.0, 0) + .addBucket(1024.0, 4) + .addBucket(Double.POSITIVE_INFINITY, 2) + .build()) + .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + .addBucket(-1, 1) + .addBucket(3, 3) + .addBucket(4, 2) + .build()) + .withLabels(Labels.of("path", "/api/v1")) + .withExemplars(Exemplars.of(exemplar1)) + .withCreatedTimestampMillis(createdTimestamp) + .withScrapeTimestampMillis(scrapeTimestamp) + .build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "request_size_bytes", "request sizes in bytes", "bytes"); + + Assert.assertEquals(2, snapshot.getData().size()); + HistogramDataPointSnapshot data = snapshot.getData().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.getData().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 testEmptyHistogram() { + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("empty_histogram") + .build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test + public void testMinimalClassicHistogram() { + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("minimal_histogram") + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0})) + .build()) + .build(); + HistogramDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertFalse(data.hasSum()); + Assert.assertEquals(1, snapshot.getData().get(0).getClassicBuckets().size()); + } + + @Test + public void testMinimalNativeHistogram() { + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("hist") + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withNativeSchema(5) + .build()) + .build(); + Assert.assertEquals("hist", snapshot.getMetadata().getName()); + Assert.assertFalse(snapshot.getMetadata().hasUnit()); + Assert.assertEquals(1, snapshot.getData().size()); + HistogramDataPointSnapshot data = snapshot.getData().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 testClassicCount() { + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("test_histogram") + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(1.0, 3) + .addBucket(2.0, 2) + .addBucket(Double.POSITIVE_INFINITY, 0) + .build()) + .build()) + .build(); + HistogramDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertFalse(data.hasSum()); + Assert.assertTrue(data.hasCount()); + Assert.assertEquals(5, data.getCount()); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyData() { + // This will fail because one of nativeSchema and classicHistogramBuckets is required + HistogramDataPointSnapshot.newBuilder().build(); + } + + @Test + public void testEmptyNativeData() { + HistogramDataPointSnapshot data = HistogramDataPointSnapshot.newBuilder() + .withNativeSchema(5) + .build(); + Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size()); + Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() + .withName("test_histogram") + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withLabels(Labels.of("a", "a")) + .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0})) + .build()) + .addDataPoint(HistogramDataPointSnapshot.newBuilder() + .withLabels(Labels.of("a", "b")) + .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{2})) + .build()) + .build(); + Iterator iterator = snapshot.getData().iterator(); + iterator.next(); + iterator.remove(); + } + + @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.newBuilder() + .addBucket(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/InfoSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java new file mode 100644 index 000000000..e5b7d55be --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java @@ -0,0 +1,46 @@ +package io.prometheus.metrics.model.snapshots; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class InfoSnapshotTest { + + @Test + public void testCompleteGoodCase() { + InfoSnapshot snapshot = InfoSnapshot.newBuilder() + .withName("target") + .withHelp("Target info") + .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) + .build()) + .build(); + Assert.assertEquals("target", snapshot.getMetadata().getName()); + Assert.assertEquals("Target info", snapshot.getMetadata().getHelp()); + Assert.assertFalse(snapshot.getMetadata().hasUnit()); + Assert.assertEquals(1, snapshot.getData().size()); + } + + @Test + public void testEmptyInfo() { + InfoSnapshot snapshot = InfoSnapshot.newBuilder().withName("target").build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + InfoSnapshot snapshot = InfoSnapshot.newBuilder() + .withName("target") + .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway.v1")) + .build()) + .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of("instance_id", "127.0.0.1:9200", "service_name", "gateway.v2")) + .build()) + .build(); + Iterator iterator = snapshot.getData().iterator(); + iterator.next(); + iterator.remove(); + } +} 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 new file mode 100644 index 000000000..8eaa8333a --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java @@ -0,0 +1,80 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.Labels; +import org.junit.Assert; +import org.junit.Test; + +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 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("http.status_code", "200"); + } + + @Test(expected = IllegalArgumentException.class) + public void testReservedLabelName() { + Labels.of("__name__", "requests_total"); + } + + @Test + public void testSanitizeLabelName() { + Assert.assertEquals("_my_label", Labels.sanitizeLabelName("...my/label")); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateLabelName() { + Labels.of("name1", "value1", "name2", "value2", "name1", "value3"); + } +} 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 new file mode 100644 index 000000000..a655954f7 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java @@ -0,0 +1,55 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.Unit; +import org.junit.Assert; +import org.junit.Test; + +public class MetricMetadataTest { + + @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 testIllegalName() { + new MetricMetadata("http.server.duration"); + } + + @Test + public void testSanitizationIllegalCharacters() { + MetricMetadata metadata = new MetricMetadata(MetricMetadata.sanitizeMetricName("http.server.duration"), "help string", Unit.SECONDS); + Assert.assertEquals("http_server_duration", metadata.getName()); + Assert.assertEquals("help string", metadata.getHelp()); + Assert.assertEquals("seconds", metadata.getUnit().toString()); + } + + @Test + public void testSanitizationCounter() { + MetricMetadata metadata = new MetricMetadata(MetricMetadata.sanitizeMetricName("my_events_total")); + Assert.assertEquals("my_events", metadata.getName()); + } + + @Test + public void testSanitizationInfo() { + MetricMetadata metadata = new MetricMetadata(MetricMetadata.sanitizeMetricName("target_info")); + Assert.assertEquals("target", metadata.getName()); + } + + @Test + public void testSanitizationWeirdCornerCase() { + MetricMetadata metadata = new MetricMetadata(MetricMetadata.sanitizeMetricName("_total_created")); + Assert.assertEquals("total", metadata.getName()); + } + + @Test(expected = IllegalArgumentException.class) + public void testSanitizeEmptyString() { + MetricMetadata.sanitizeMetricName(""); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java new file mode 100644 index 000000000..492472c94 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -0,0 +1,37 @@ +package io.prometheus.metrics.model.snapshots; + +import org.junit.Assert; +import org.junit.Test; + +public class MetricSnapshotTest { + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateLabels() { + CounterSnapshot.newBuilder() + .withName("events") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() + .withLabels(Labels.of("path", "/hello", "status", "200")) + .withValue(1.0) + .build()) + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() + .withLabels(Labels.of("path", "/world", "status", "200")) + .withValue(2.0) + .build()) + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() + .withLabels(Labels.of("status", "200", "path", "/hello")) + .withValue(3.0) + .build()) + .build(); + } + + @Test + public void testNoData() { + MetricSnapshot snapshot = CounterSnapshot.newBuilder().withName("test").build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test(expected = NullPointerException.class) + public void testNullData() { + new CounterSnapshot(new MetricMetadata("test"), null); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java new file mode 100644 index 000000000..7066146c4 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java @@ -0,0 +1,86 @@ +package io.prometheus.metrics.model.snapshots; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class MetricSnapshotsTest { + + @Test + public void testEmpty() { + MetricSnapshots snapshots = MetricSnapshots.newBuilder().build(); + Assert.assertFalse(snapshots.stream().findAny().isPresent()); + } + + @Test + public void testSort() { + CounterSnapshot c1 = CounterSnapshot.newBuilder() + .withName("counter1") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + CounterSnapshot c2 = CounterSnapshot.newBuilder() + .withName("counter2") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + CounterSnapshot c3 = CounterSnapshot.newBuilder() + .withName("counter3") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); + Assert.assertEquals(3, snapshots.size()); + Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName()); + Assert.assertEquals("counter2", snapshots.get(1).getMetadata().getName()); + Assert.assertEquals("counter3", snapshots.get(2).getMetadata().getName()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateName() { + // Q: What if you have a counter named "foo" and a gauge named "foo"? + // A: Great question. You might think this is a valid scenario, because the counter will produce + // the values "foo_total" and "foo_created" while the gauge will produce the value "foo". + // So from that perspective there is no conflict. However, the name for HELP, TYPE, UNIT is the same, + // and that is the conflict. Therefore, you cannot have a counter named "foo" and a gauge named "foo". + CounterSnapshot c = CounterSnapshot.newBuilder() + .withName("my_metric") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + GaugeSnapshot g = GaugeSnapshot.newBuilder() + .withName("my_metric") + .addDataPoint(GaugeSnapshot.GaugeDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + new MetricSnapshots(c, g); + } + + @Test + public void testBuilder() { + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("my_metric") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + MetricSnapshots.Builder builder = MetricSnapshots.newBuilder(); + Assert.assertFalse(builder.containsMetricName("my_metric")); + builder.addMetricSnapshot(counter); + Assert.assertTrue(builder.containsMetricName("my_metric")); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + CounterSnapshot c1 = CounterSnapshot.newBuilder() + .withName("counter1") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + CounterSnapshot c2 = CounterSnapshot.newBuilder() + .withName("counter2") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + CounterSnapshot c3 = CounterSnapshot.newBuilder() + .withName("counter3") + .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + .build(); + MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); + Iterator iterator = snapshots.iterator(); + iterator.next(); + iterator.remove(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java new file mode 100644 index 000000000..2797be556 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java @@ -0,0 +1,65 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.NativeHistogramBucket; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class NativeHistogramBucketsTest { + + @Test + public void testGoodCase() { + NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() + .addBucket(-10, 12) + .addBucket(120, 17) + .build(); + Assert.assertEquals(2, buckets.size()); + Assert.assertEquals(-10, buckets.getBucketIndex(0)); + Assert.assertEquals(12, buckets.getCount(0)); + Assert.assertEquals(120, buckets.getBucketIndex(1)); + Assert.assertEquals(17, buckets.getCount(1)); + } + + @Test + public void testEmpty() { + NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder().build(); + Assert.assertEquals(0, buckets.size()); + } + + @Test + public void testSort() { + NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() + .addBucket(7, 4) + .addBucket(2, 0) + .addBucket(5, 3) + .build(); + Assert.assertEquals(3, buckets.size()); + Assert.assertEquals(2, buckets.getBucketIndex(0)); + Assert.assertEquals(5, buckets.getBucketIndex(1)); + Assert.assertEquals(7, buckets.getBucketIndex(2)); + Assert.assertEquals(0, buckets.getCount(0)); + Assert.assertEquals(3, buckets.getCount(1)); + Assert.assertEquals(4, buckets.getCount(2)); + } + + @Test(expected = IllegalArgumentException.class) + public void testDifferentLength() { + int[] bucketIndexes = new int[] {0, 1, 2}; + long[] cumulativeCounts = new long[] {13, 178, 1024, 3000}; + NativeHistogramBuckets.of(bucketIndexes, cumulativeCounts); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() + .addBucket(1, 1) + .addBucket(2, 1) + .build(); + Iterator iterator = buckets.iterator(); + iterator.next(); + iterator.remove(); + } + +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java new file mode 100644 index 000000000..43b586119 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java @@ -0,0 +1,53 @@ +package io.prometheus.metrics.model.snapshots; + +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Iterator; + +public class QuantilesTest { + + @Test + public void testSort() { + Quantiles quantiles = Quantiles.newBuilder() + .addQuantile(0.99, 0.23) + .addQuantile(0.5, 0.2) + .addQuantile(0.95, 0.22) + .build(); + Assert.assertEquals(3, quantiles.size()); + Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0); + Assert.assertEquals(0.2, quantiles.get(0).getValue(), 0); + Assert.assertEquals(0.95, quantiles.get(1).getQuantile(), 0); + Assert.assertEquals(0.22, quantiles.get(1).getValue(), 0); + Assert.assertEquals(0.99, quantiles.get(2).getQuantile(), 0); + Assert.assertEquals(0.23, quantiles.get(2).getValue(), 0); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + Quantiles quantiles = Quantiles.newBuilder() + .addQuantile(0.99, 0.23) + .addQuantile(0.5, 0.2) + .addQuantile(0.95, 0.22) + .build(); + Iterator iterator = quantiles.iterator(); + iterator.next(); + iterator.remove(); + } + + @Test + public void testEmpty() { + Assert.assertEquals(0, Quantiles.EMPTY.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicate() { + Quantiles.newBuilder() + .addQuantile(0.95, 0.23) + .addQuantile(0.5, 0.2) + .addQuantile(0.95, 0.22) + .build(); + } +} 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 new file mode 100644 index 000000000..54766debd --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java @@ -0,0 +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()); + } + } +} 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 new file mode 100644 index 000000000..6c4fa61d3 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java @@ -0,0 +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; + +public class StateSetSnapshotTest { + + @Test + public void testCompleteGoodCase() { + long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); + StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() + .withName("my_feature_flags") + .withHelp("Feature Flags") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("entity", "controller")) + .withScrapeTimestampMillis(scrapeTimestamp) + .addState("feature1", true) + .addState("feature2", false) + .build() + ) + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("entity", "api")) + .addState("feature1", false) + .addState("feature2", false) + .build() + ) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "my_feature_flags", "Feature Flags", null); + Assert.assertEquals(2, snapshot.getData().size()); + StateSetSnapshot.StateSetDataPointSnapshot data = snapshot.getData().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.newBuilder() + .addState("b", true) + .addState("d", false) + .addState("c", true) + .addState("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(expected = IllegalArgumentException.class) + public void testMustHaveState() { + // Must have at least one state. + StateSetSnapshot.StateSetDataPointSnapshot.newBuilder().build(); + } + + @Test + public void testMinimal() { + StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() + .withName("my_flag") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("flag", true) + .build() + ) + .build(); + Assert.assertEquals(1, snapshot.data.size()); + } + + @Test + public void testEmpty() { + StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() + .withName("my_flag") + .build(); + Assert.assertEquals(0, snapshot.data.size()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("a", true) + .addState("b", true) + .addState("c", true) + .build(); + Iterator iterator = data.iterator(); + iterator.next(); + iterator.remove(); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateState() { + StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("a", true) + .addState("b", true) + .addState("a", true) + .build(); + } + + @Test(expected = UnsupportedOperationException.class) + public void testStateSetImmutable() { + StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() + .withName("flags") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("entity", "controller")) + .addState("feature", true) + .build() + ) + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("entity", "api")) + .addState("feature", true) + .build() + ) + .build(); + Iterator iterator = snapshot.getData().iterator(); + iterator.next(); + iterator.remove(); + } + + @Test(expected = IllegalArgumentException.class) + public void testLabelsUnique() { + StateSetSnapshot.newBuilder() + .withName("flags") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("feature", true) + .build() + ) + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .addState("feature", true) + .build() + ) + .build(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java new file mode 100644 index 000000000..cf65f46bf --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java @@ -0,0 +1,105 @@ +package io.prometheus.metrics.model.snapshots; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +public class SummarySnapshotTest { + + @Test + public void testCompleteGoodCase() { + long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); + long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); + long exemplarTimestamp = System.currentTimeMillis(); + SummarySnapshot snapshot = SummarySnapshot.newBuilder() + .withName("latency_seconds") + .withHelp("latency in seconds") + .withUnit(Unit.SECONDS) + .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() + .withCreatedTimestampMillis(createdTimestamp) + .withScrapeTimestampMillis(scrapeTimestamp) + .withLabels(Labels.of("endpoint", "/")) + .withQuantiles(Quantiles.newBuilder() + .addQuantile(0.5, 0.2) + .addQuantile(0.95, 0.22) + .addQuantile(0.99, 0.23) + .build()) + .withExemplars(Exemplars.newBuilder() + .addExemplar(Exemplar.newBuilder() + .withValue(0.2) + .withTraceId("abc123") + .withSpanId("123457") + .withTimestampMillis(exemplarTimestamp) + .build()) + .addExemplar(Exemplar.newBuilder() + .withValue(0.21) + .withTraceId("abc124") + .withSpanId("123458") + .withTimestampMillis(exemplarTimestamp) + .build()) + .build()) + .withCount(1093) + .withSum(218.6) + .build()) + .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() + .withLabels(Labels.of("endpoint", "/test")) + .withCount(1093) + .withSum(218.6) + .build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "latency_seconds", "latency in seconds", "seconds"); + Assert.assertEquals(2, snapshot.getData().size()); + SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(Labels.of("endpoint", "/"), data.getLabels()); + Assert.assertTrue(data.hasCount()); + Assert.assertEquals(1093, data.getCount()); + Assert.assertTrue(data.hasSum()); + Assert.assertEquals(218.6, data.getSum(), 0); + Assert.assertTrue(data.hasCreatedTimestamp()); + Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis()); + Assert.assertTrue(data.hasScrapeTimestamp()); + Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis()); + Quantiles quantiles = data.getQuantiles(); + Assert.assertEquals(3, quantiles.size()); + // quantiles are tested in QuantilesTest already, skipping here. + Assert.assertEquals(2, data.getExemplars().size()); + // exemplars are tested in ExemplarsTest already, skipping here. + + data = snapshot.getData().get(1); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + Assert.assertTrue(data.hasCount()); + Assert.assertTrue(data.hasSum()); + } + + @Test + public void testMinimal() { + SummarySnapshot snapshot = SummarySnapshot.newBuilder() + .withName("size_bytes") + .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() + .withCount(10) + .withSum(12.0) + .build()) + .build(); + Assert.assertEquals(1, snapshot.getData().size()); + Assert.assertEquals(Labels.EMPTY, snapshot.getData().get(0).getLabels()); + } + + @Test + public void testEmptySnapshot() { + SummarySnapshot snapshot = SummarySnapshot.newBuilder().withName("empty_summary").build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test + public void testEmptyData() { + SummarySnapshot.SummaryDataPointSnapshot data = SummarySnapshot.SummaryDataPointSnapshot.newBuilder().build(); + Assert.assertEquals(0, data.getQuantiles().size()); + Assert.assertFalse(data.hasCount()); + Assert.assertFalse(data.hasSum()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + Assert.assertEquals(0, data.getExemplars().size()); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java new file mode 100644 index 000000000..b8a9827d2 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java @@ -0,0 +1,71 @@ +package io.prometheus.metrics.model.snapshots; + +import org.junit.Assert; +import org.junit.Test; + +public class UnknownSnapshotTest { + + @Test + public void testCompleteGoodCase() { + long exemplarTimestamp = System.currentTimeMillis(); + UnknownSnapshot snapshot = UnknownSnapshot.newBuilder() + .withName("my_unknown_seconds") + .withHelp("something in seconds") + .withUnit(Unit.SECONDS) + .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() + .withValue(0.3) + .withExemplar(Exemplar.newBuilder() + .withValue(0.12) + .withTraceId("abc123") + .withSpanId("123457") + .withTimestampMillis(exemplarTimestamp) + .build()) + .withLabels(Labels.newBuilder() + .addLabel("env", "prod") + .build()) + .build() + ).addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() + .withValue(0.29) + .withLabels(Labels.newBuilder() + .addLabel("env", "dev") + .build()) + .build() + ) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "my_unknown_seconds", "something in seconds", "seconds"); + Assert.assertEquals(2, snapshot.getData().size()); + UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getData().get(1); // env="prod" + Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); + Assert.assertEquals(0.3, data.getValue(), 0.0); + Assert.assertEquals(0.12, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } + + @Test + public void testMinimal() { + UnknownSnapshot snapshot = UnknownSnapshot.newBuilder() + .withName("test") + .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() + .withValue(1.0) + .build()) + .build(); + Assert.assertEquals(1, snapshot.getData().size()); + } + + @Test + public void testEmpty() { + UnknownSnapshot snapshot = UnknownSnapshot.newBuilder().withName("test").build(); + Assert.assertEquals(0, snapshot.getData().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testNameMissing() { + UnknownSnapshot.newBuilder().build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + UnknownSnapshot.UnknownDataPointSnapshot.newBuilder().build(); + } +} diff --git a/prometheus-metrics-model/version-rules.xml b/prometheus-metrics-model/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-model/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml new file mode 100644 index 000000000..f8e9ed1d3 --- /dev/null +++ b/prometheus-metrics-tracer/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-tracer + pom + + Prometheus Metrics Tracer + + Parent for Prometheus integrations with distributed tracing libraries. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + + io.opentelemetry + opentelemetry-api + 1.28.0 + + + + + + prometheus-metrics-tracer-common + prometheus-metrics-tracer-initializer + prometheus-metrics-tracer-otel + prometheus-metrics-tracer-otel-agent + + + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml new file mode 100644 index 000000000..2bd042af9 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + + io.prometheus + prometheus-metrics-tracer + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-tracer-common + bundle + + Prometheus Metrics Tracer Common + + Common Module for Prometheus integrations with distributed tracing libraries. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java new file mode 100644 index 000000000..b53fe4d20 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java @@ -0,0 +1,26 @@ +package io.prometheus.metrics.tracer.common; + +public interface SpanContext { + + public static final String EXEMPLAR_ATTRIBUTE_NAME = "exemplar"; + public static final String EXEMPLAR_ATTRIBUTE_VALUE = "true"; + + /** + * @return the current trace id, or {@code null} if this call is not happening within a span context. + */ + String getCurrentTraceId(); + + /** + * @return the current span id, or {@code null} if this call is not happening within a span context. + */ + String getCurrentSpanId(); + + /** + * @return the state of the current Span. If this value is false a component before in the chain take the decision to not record it. Subsequent calling service have + * to respect this value in order not to have partial TraceID with only some Span in it. This value is important to be sure to choose a recorded Trace in Examplar + * sampling process + */ + boolean isCurrentSpanSampled(); + + void markCurrentSpanAsExemplar(); +} diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/version-rules.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml new file mode 100644 index 000000000..ec939e20e --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + + io.prometheus + prometheus-metrics-tracer + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-tracer-initializer + bundle + + Prometheus Metrics Tracer Initializer + + Initialize Prometheus integrations with distributed tracing libraries. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-tracer-common + ${project.version} + + + io.prometheus + prometheus-metrics-tracer-otel + ${project.version} + + + io.prometheus + prometheus-metrics-tracer-otel-agent + ${project.version} + + + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java new file mode 100644 index 000000000..caecb6055 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java @@ -0,0 +1,45 @@ +package io.prometheus.metrics.tracer.initializer; + +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.otel.OpenTelemetrySpanContext; +import io.prometheus.metrics.tracer.otel_agent.OpenTelemetryAgentSpanContext; + +import java.util.concurrent.atomic.AtomicReference; + +public class SpanContextSupplier { + + private static final AtomicReference spanContextRef = new AtomicReference(); + + public static void setSpanContext(SpanContext spanContext) { + spanContextRef.set(spanContext); + } + + public static boolean hasSpanContext() { + return getSpanContext() != null; + } + + public static SpanContext getSpanContext() { + return spanContextRef.get(); + } + + static { + try { + if (OpenTelemetrySpanContext.isAvailable()) { + spanContextRef.set(new OpenTelemetrySpanContext()); + } + } catch (NoClassDefFoundError ignored) { + // tracer_otel dependency not found + } catch (UnsupportedClassVersionError ignored) { + // OpenTelemetry requires Java 8, but client_java might run on Java 6. + } + try { + if (OpenTelemetryAgentSpanContext.isAvailable()) { + spanContextRef.set(new OpenTelemetryAgentSpanContext()); + } + } catch (NoClassDefFoundError ignored) { + // tracer_otel_agent dependency not found + } catch (UnsupportedClassVersionError ignored) { + // OpenTelemetry requires Java 8, but client_java might run on Java 6. + } + } +} diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/version-rules.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml new file mode 100644 index 000000000..e24405186 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + + + io.prometheus + prometheus-metrics-tracer + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-tracer-otel-agent + bundle + + Prometheus Metrics Tracer OpenTelemetry Agent + + Prometheus integration with the OpenTelemetry Java agent for distributed tracing. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-tracer-common + ${project.version} + + + io.opentelemetry + opentelemetry-api + provided + true + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.opentelemetry.api + io.opentelemetry.javaagent.shaded.io.opentelemetry.api + + + + + io.prometheus:prometheus-metrics-tracer-common + + + + + + + + + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java new file mode 100644 index 000000000..36cba7076 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java @@ -0,0 +1,52 @@ +package io.prometheus.metrics.tracer.otel_agent; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.prometheus.metrics.tracer.common.SpanContext; + +/** + * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}. + * However, the {@code io.opentelemetry.api} package is relocated to + * {@code io.opentelemetry.javaagent.shaded.io.opentelemetry.api} in the OpenTelemetry agent. + */ +public class OpenTelemetryAgentSpanContext implements SpanContext { + + public static boolean isAvailable() { + try { + OpenTelemetryAgentSpanContext test = new OpenTelemetryAgentSpanContext(); + test.getCurrentSpanId(); + test.getCurrentTraceId(); + test.isCurrentSpanSampled(); + return true; + } catch (LinkageError ignored) { + // NoClassDefFoundError: + // Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist. + // IncompatibleClassChangeError: + // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface. + return false; + } + } + + @Override + public String getCurrentTraceId() { + String traceId = Span.current().getSpanContext().getTraceId(); + return TraceId.isValid(traceId) ? traceId : null; + } + + @Override + public String getCurrentSpanId() { + String spanId = Span.current().getSpanContext().getSpanId(); + return SpanId.isValid(spanId) ? spanId : null; + } + + @Override + public boolean isCurrentSpanSampled() { + return Span.current().getSpanContext().isSampled(); + } + + @Override + public void markCurrentSpanAsExemplar() { + Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE); + } +} diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/version-rules.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml new file mode 100644 index 000000000..6ee789fdf --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + io.prometheus + prometheus-metrics-tracer + 1.0.0-alpha-1-SNAPSHOT + + + prometheus-metrics-tracer-otel + bundle + + Prometheus Metrics Tracer OpenTelemetry + + Prometheus integration with the OpenTelemetry distributed tracing library. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-tracer-common + ${project.version} + + + io.opentelemetry + opentelemetry-api + provided + true + + + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java new file mode 100644 index 000000000..dd338cea2 --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java @@ -0,0 +1,47 @@ +package io.prometheus.metrics.tracer.otel; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanId; +import io.opentelemetry.api.trace.TraceId; +import io.prometheus.metrics.tracer.common.SpanContext; + +public class OpenTelemetrySpanContext implements SpanContext { + + public static boolean isAvailable() { + try { + OpenTelemetrySpanContext test = new OpenTelemetrySpanContext(); + test.getCurrentSpanId(); + test.getCurrentTraceId(); + test.isCurrentSpanSampled(); + return true; + } catch (LinkageError ignored) { + // NoClassDefFoundError: + // Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist. + // IncompatibleClassChangeError: + // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface. + return false; + } + } + + @Override + public String getCurrentTraceId() { + String traceId = Span.current().getSpanContext().getTraceId(); + return TraceId.isValid(traceId) ? traceId : null; + } + + @Override + public String getCurrentSpanId() { + String spanId = Span.current().getSpanContext().getSpanId(); + return SpanId.isValid(spanId) ? spanId : null; + } + + @Override + public boolean isCurrentSpanSampled() { + return Span.current().getSpanContext().isSampled(); + } + + @Override + public void markCurrentSpanAsExemplar() { + Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE); + } +} diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/version-rules.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-tracer/version-rules.xml b/prometheus-metrics-tracer/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-tracer/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/protobuf-shaded/.gitignore b/protobuf-shaded/.gitignore new file mode 100644 index 000000000..b929015f9 --- /dev/null +++ b/protobuf-shaded/.gitignore @@ -0,0 +1 @@ +src/main/java diff --git a/protobuf-shaded/README.md b/protobuf-shaded/README.md new file mode 100644 index 000000000..5db4149b7 --- /dev/null +++ b/protobuf-shaded/README.md @@ -0,0 +1 @@ +See [https://github.com/apache/hbase-thirdparty/tree/master/hbase-shaded-protobuf](https://github.com/apache/hbase-thirdparty/tree/master/hbase-shaded-protobuf) diff --git a/protobuf-shaded/pom.xml b/protobuf-shaded/pom.xml new file mode 100644 index 000000000..42cb34138 --- /dev/null +++ b/protobuf-shaded/pom.xml @@ -0,0 +1,160 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-1-SNAPSHOT + + + protobuf-shaded + Shaded (relocated to another package) Protobuf + + Downloads Google Protobuf, compiles it, and reloacates/shades. + See also hbase-thirdparty/hbase-shaded-protobuf + + + + + + 3.21.7 + + 3_21_7 + + + + + + src/main/java + + + google/** + + + + + + + maven-clean-plugin + + + pre-generate-sources + generate-sources + + clean + + + + + + + ${basedir}/src/main/java + + **/** + + false + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + generate-sources + + unpack + + + + + + com.google.protobuf + protobuf-java + + 3.21.7 + sources + jar + true + ${basedir}/src/main/java + **/** + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + google/protobuf/*.proto + google/protobuf/compiler/*.proto + + + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + true + true + + + com.google.protobuf + + io.prometheus.metrics.com_google_protobuf_${protobuf.version.string} + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + google/protobuf/*.proto + google/protobuf/compiler/*.proto + + + + + + diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 9e1a70c49..16dd46d4f 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 47c8852a9..e54830a6d 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 9fa1e392b..d6a195f49 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_caffeine @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} com.github.ben-manes.caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 1be246531..67c05bbcd 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_common @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index eb0789354..f6aeabbe5 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_dropwizard @@ -34,7 +34,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.dropwizard.metrics @@ -63,49 +63,4 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - 1.8 - 1.8 - - - - - - - - - - - intellij - - false - - - - - idea.maven.embedder.version - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 41ca436fc..862ebd4c8 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_graphite_bridge @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 528fe0259..9ddb2f231 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_guava @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} com.google.guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 84553ed9e..586956466 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_hibernate @@ -37,7 +37,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index bec6faa07..30c3f5ed7 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_hotspot @@ -36,14 +36,14 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_servlet - 0.16.1-SNAPSHOT + ${project.version} test @@ -67,48 +67,4 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - 1.8 - 1.8 - - - - - - - - - - - intellij - - false - - - - - idea.maven.embedder.version - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 5b3da856b..693bc9dcc 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_httpserver @@ -36,12 +36,12 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index a6280f7f5..44a8dd332 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_jetty @@ -38,7 +38,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} org.eclipse.jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 38199d315..5ed130a89 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_jetty_jdk8 @@ -16,19 +16,6 @@ Collector of data from Jetty Statistics for Jetty versions which require JDK 8. - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - The Apache Software License, Version 2.0 @@ -47,7 +34,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} org.eclipse.jetty diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 0f1b50dcf..67d294ff7 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_log4j @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} org.apache.logging.log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 5b0ff589a..13af55105 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_log4j2 @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} org.apache.logging.log4j diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 953a322c2..51aaa5cde 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_logback @@ -36,7 +36,7 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} ch.qos.logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 3163135b2..6197919d5 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_pushgateway @@ -37,12 +37,12 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} javax.xml.bind diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index e599bfb01..2e2033e41 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_servlet @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_servlet_common - 0.16.1-SNAPSHOT + ${project.version} javax.servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index fac7cbbf8..df5068323 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_servlet_common @@ -40,12 +40,12 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 3a9d4ac83..ede162091 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_servlet_jakarta @@ -40,17 +40,17 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_servlet_common - 0.16.1-SNAPSHOT + ${project.version} jakarta.servlet diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient_spring_boot/pom.xml index eb5dc6888..0f8e40208 100644 --- a/simpleclient_spring_boot/pom.xml +++ b/simpleclient_spring_boot/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_spring_boot @@ -51,17 +51,17 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_spring_web - 0.16.1-SNAPSHOT + ${project.version} org.springframework.boot diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index c6562947e..982d8f227 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_spring_web @@ -51,12 +51,12 @@ io.prometheus simpleclient - 0.16.1-SNAPSHOT + ${project.version} io.prometheus simpleclient_common - 0.16.1-SNAPSHOT + ${project.version} org.springframework diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 59e0c35e2..92f806f61 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -4,8 +4,8 @@ io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index c1f2ee7a5..5536dfe89 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index f8274fb82..dedf92042 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT simpleclient_tracer_otel @@ -27,19 +27,6 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - The Apache Software License, Version 2.0 diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index b29b27008..488b3db0a 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 0.16.1-SNAPSHOT + 1.0.0-alpha-1-SNAPSHOT simpleclient_tracer_otel_agent @@ -54,14 +54,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index d29591571..dd3fba81c 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -1,23 +1,11 @@ 4.0.0 - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 750b4bf88..5ddc9f567 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -1,23 +1,11 @@ 4.0.0 - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - io.prometheus - parent - 0.16.1-SNAPSHOT + client_java + 1.0.0-alpha-1-SNAPSHOT simpleclient_vertx4 From 3ef02e62c7339872e7ad9bb663e9ff3473943524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 11:05:48 +0200 Subject: [PATCH 179/980] Temporarily add protobuf-shaded to prepare for release --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index a1259a598..038744d94 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,7 @@ prometheus-metrics-exposition-formats prometheus-metrics-exporter-servlet-jakarta examples + protobuf-shaded simpleclient simpleclient_common From 509e7bd696c893a293e48e56afcb8e2d2e775208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 12:05:12 +0200 Subject: [PATCH 180/980] Update parent pom metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 038744d94..31ccbeb7c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,10 +7,10 @@ client_java 1.0.0-alpha-1-SNAPSHOT - Prometheus Java Suite + Prometheus Metrics Library http://github.com/prometheus/client_java - The Prometheus Java Suite: Client Metrics, Exposition, and Examples + The Prometheus Java Metrics Library @@ -34,6 +34,16 @@ Matt T. Proud matt.proud@gmail.com + + brian-brazil + Brian Brazil + brian.brazil@boxever.com + + + fstab + Fabian Stäber + fabian@fstab.de + @@ -193,6 +203,7 @@ false release deploy + v${project.version} From 427dc06fea5d3b739d09e09400ac4aa7462d72d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 13:27:45 +0200 Subject: [PATCH 181/980] Fix JavaDoc --- .../java/io/prometheus/metrics/core/metrics/Histogram.java | 7 ++++--- protobuf-shaded/pom.xml | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index 50f352e26..cfe3f2944 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -799,15 +799,16 @@ public Builder withClassicExponentialBuckets(double start, double factor, int co *
  • factor: The growth factor for bucket boundaries, i.e. next bucket boundary = growth factor * previous bucket boundary. *
  • max quantile error: The maximum error for quantiles calculated using the Prometheus histogram_quantile() function, relative to the observed value, assuming harmonic mean. * - * + *
    + * * * * * - * 99% + * * * - * 99% + * * * * diff --git a/protobuf-shaded/pom.xml b/protobuf-shaded/pom.xml index 42cb34138..b6d85c8c2 100644 --- a/protobuf-shaded/pom.xml +++ b/protobuf-shaded/pom.xml @@ -155,6 +155,13 @@ + + maven-javadoc-plugin + + + com.google.protobuf + + From aa72e2a9edc81edf7c68b63fef0b7b9adbae9470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 13:29:42 +0200 Subject: [PATCH 182/980] [maven-release-plugin] prepare release v1.0.0-alpha-1 --- benchmarks/pom.xml | 2 +- examples/pom.xml | 2 +- examples/tomcat-servlet-example/pom.xml | 5 ++--- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 5 ++--- prometheus-metrics-core/pom.xml | 5 ++--- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 5 ++--- prometheus-metrics-model/pom.xml | 5 ++--- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- protobuf-shaded/pom.xml | 5 ++--- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 49 files changed, 56 insertions(+), 62 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index db455570b..8c3fe0d43 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 benchmarks diff --git a/examples/pom.xml b/examples/pom.xml index fb53876ed..180db27c8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 examples diff --git a/examples/tomcat-servlet-example/pom.xml b/examples/tomcat-servlet-example/pom.xml index 0688b6045..00e9c7303 100644 --- a/examples/tomcat-servlet-example/pom.xml +++ b/examples/tomcat-servlet-example/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus examples - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 tomcat-servlet-example diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 44758744c..467ae1dc0 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 80a97e549..bdb7a3634 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 90c99c155..23a3b2458 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 64441aee0..101fb04b4 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 3090704cd..79019eb3e 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index aa17740a1..4c8190bf8 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 487dba31d..dce018335 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 05a56956f..dd8a9666a 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 integration_tests diff --git a/pom.xml b/pom.xml index 31ccbeb7c..fd0842a2b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-1 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 5810c19b7..5b6a16a18 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 06d350b69..0c64d2044 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index a6038dd91..e7829efad 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 9de57e88c..364c081fa 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index b1f06cc23..8815b15d2 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-model diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index f8e9ed1d3..0c1176834 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 2bd042af9..40e4e6dd6 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index ec939e20e..9a4cfda2e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index e24405186..d7163b2d9 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 6ee789fdf..ad3900400 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 prometheus-metrics-tracer-otel diff --git a/protobuf-shaded/pom.xml b/protobuf-shaded/pom.xml index b6d85c8c2..fa9d90e85 100644 --- a/protobuf-shaded/pom.xml +++ b/protobuf-shaded/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 protobuf-shaded diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 16dd46d4f..a94a98560 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index e54830a6d..47fff77bd 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index d6a195f49..c020a91e4 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 67c05bbcd..2dbe54451 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index f6aeabbe5..3be5f9582 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 862ebd4c8..30f5436f1 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 9ddb2f231..53f8ebcdf 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 586956466..acc2f9638 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 30c3f5ed7..2c01371a3 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 693bc9dcc..a336c0995 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 44a8dd332..57563ce62 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 5ed130a89..0b6d8b4ba 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 67d294ff7..6f9b8f655 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 13af55105..ad85625aa 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 51aaa5cde..e78ef0b10 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 6197919d5..df6f86248 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 2e2033e41..ddedfc18d 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index df5068323..5e71a629d 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index ede162091..94b821104 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 982d8f227..4ccbcee9a 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 92f806f61..8efaae510 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 5536dfe89..fcdd572fc 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index dedf92042..56be6b1a2 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 488b3db0a..19c8edc4d 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index dd3fba81c..cf0649de1 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 5ddc9f567..155425d2f 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1 simpleclient_vertx4 From 07881ded68a8f22346918a6abb9ee93fd46bfca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 13:29:47 +0200 Subject: [PATCH 183/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- examples/pom.xml | 2 +- examples/tomcat-servlet-example/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- protobuf-shaded/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 49 files changed, 50 insertions(+), 50 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 8c3fe0d43..7d207b99a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT benchmarks diff --git a/examples/pom.xml b/examples/pom.xml index 180db27c8..b76818b77 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT examples diff --git a/examples/tomcat-servlet-example/pom.xml b/examples/tomcat-servlet-example/pom.xml index 00e9c7303..51c0fa5f0 100644 --- a/examples/tomcat-servlet-example/pom.xml +++ b/examples/tomcat-servlet-example/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT tomcat-servlet-example diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 467ae1dc0..5a200b51d 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index bdb7a3634..519d5355e 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 23a3b2458..c2a6763cc 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 101fb04b4..34df8597c 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 79019eb3e..d3236f7d3 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 4c8190bf8..739e8684b 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index dce018335..11db7010b 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index dd8a9666a..2ede9491e 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index fd0842a2b..7b24d41e2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-1 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 5b6a16a18..6bb255583 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 0c64d2044..15f75c01e 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index e7829efad..95129ce21 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 364c081fa..fafdde58d 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 8815b15d2..a28d6c18a 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 0c1176834..19d0a2f52 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 40e4e6dd6..807b126dd 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 9a4cfda2e..da05c1056 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index d7163b2d9..0fdd4cf49 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index ad3900400..da389af0c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/protobuf-shaded/pom.xml b/protobuf-shaded/pom.xml index fa9d90e85..ddfe62d98 100644 --- a/protobuf-shaded/pom.xml +++ b/protobuf-shaded/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT protobuf-shaded diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index a94a98560..1b6c4ae1d 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 47fff77bd..18e4372cc 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index c020a91e4..44c9105c6 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 2dbe54451..cbed662ec 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 3be5f9582..64f1c46af 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 30f5436f1..f2b27bac6 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 53f8ebcdf..06d9a07dc 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index acc2f9638..933fc4a45 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 2c01371a3..b7d9af559 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index a336c0995..ce830ebd7 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 57563ce62..b5bd23c7b 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 0b6d8b4ba..1628141a7 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 6f9b8f655..72f5a210b 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index ad85625aa..4a772b5e2 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index e78ef0b10..73ef79f42 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index df6f86248..334d299aa 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index ddedfc18d..055caf224 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 5e71a629d..02a49fd7d 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 94b821104..4a8683491 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 4ccbcee9a..9833ddf60 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 8efaae510..0d5b9245d 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index fcdd572fc..ff5a09c58 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 56be6b1a2..f0b4a2114 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 19c8edc4d..f08539d4b 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index cf0649de1..ac11b3bea 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 155425d2f..153f32248 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-1 + 1.0.0-alpha-2-SNAPSHOT simpleclient_vertx4 From 694b4f82a72e0a4121ab870ce0fcea3074b73c68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 17 Jul 2023 14:59:03 +0200 Subject: [PATCH 184/980] Remove protobuf-shaded from project after release --- pom.xml | 1 - prometheus-metrics-exposition-formats/pom.xml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7b24d41e2..7ba273e55 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,6 @@ prometheus-metrics-exposition-formats prometheus-metrics-exporter-servlet-jakarta examples - protobuf-shaded simpleclient simpleclient_common diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index fafdde58d..2cd178393 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -46,7 +46,7 @@ io.prometheus protobuf-shaded - ${project.version} + 1.0.0-alpha-1 From b22ad1b4a06602ea183a604686214d73657a691d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 19 Jul 2023 22:12:10 +0200 Subject: [PATCH 185/980] Add README to the tomcat-servlet-example #850 --- examples/tomcat-servlet-example/README.md | 82 +++++++++++++++++++ .../tomcat_servlet/HelloWorldServlet.java | 3 + .../metrics/examples/tomcat_servlet/Main.java | 4 +- 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 examples/tomcat-servlet-example/README.md diff --git a/examples/tomcat-servlet-example/README.md b/examples/tomcat-servlet-example/README.md new file mode 100644 index 000000000..66d6378f7 --- /dev/null +++ b/examples/tomcat-servlet-example/README.md @@ -0,0 +1,82 @@ +# Tomcat Servlet Example + +## Build + +This example is built as part of the `client_java` project. + +``` +./mvnw package +``` + +## Run + +The build creates a JAR file with the example application in `./examples/tomcat-servlet-example/target/`. + +``` +java -jar ./examples/tomcat-servlet-example/target/tomcat-servlet-example-1.0.0-alpha-2-SNAPSHOT.jar +``` + +Accessing [http://localhost:8080/](http://localhost:8080/) with a Web browser should yield `Hello, World!`. + +## Manually testing the Metrics Endpoint + +Metrics are available on [http://localhost:8080/metrics](http://localhost:8080/metrics). The default Prometheus text format looks like this: + +``` +# HELP request_duration_seconds request duration in seconds +# TYPE request_duration_seconds histogram +request_duration_seconds_bucket{http_status="200",le="0.005"} 0 +request_duration_seconds_bucket{http_status="200",le="0.01"} 1 +request_duration_seconds_bucket{http_status="200",le="0.025"} 1 +request_duration_seconds_bucket{http_status="200",le="0.05"} 2 +request_duration_seconds_bucket{http_status="200",le="0.1"} 5 +request_duration_seconds_bucket{http_status="200",le="0.25"} 11 +request_duration_seconds_bucket{http_status="200",le="0.5"} 12 +request_duration_seconds_bucket{http_status="200",le="1.0"} 12 +request_duration_seconds_bucket{http_status="200",le="2.5"} 12 +request_duration_seconds_bucket{http_status="200",le="5.0"} 12 +request_duration_seconds_bucket{http_status="200",le="10.0"} 12 +request_duration_seconds_bucket{http_status="200",le="+Inf"} 12 +request_duration_seconds_count{http_status="200"} 12 +request_duration_seconds_sum{http_status="200"} 1.513772412 +# HELP requests_total total number of requests +# TYPE requests_total counter +requests_total{http_status="200"} 12.0 +``` + +The exporter servlet supports a `debug` URL parameter to quickly view other formats in your Web browser: + +* [http://localhost:8080/metrics?debug=text](http://localhost:8080/metrics?debug=text): Prometheus text format, same as without the `debug` option. +* [http://localhost:8080/metrics?debug=openmetrics](http://localhost:8080/metrics?debug=openmetrics): OpenMetrics text format. +* [http://localhost:8080/metrics?debug=prometheus-protobuf](http://localhost:8080/metrics?debug=prometheus-protobuf): Text representation of the Prometheus protobuf format. + +## Testing with the Prometheus Server + +1. Download the latest Prometheus server release from [https://github.com/prometheus/prometheus/releases](https://github.com/prometheus/prometheus/releases). +2. Extract the archive +3. Edit `prometheus.yml` and append the following snippet at the end: + ```yaml + job_name: "tomcat-servlet-example" + static_configs: + - targets: ["localhost:8080"] + ``` +4. Run with native histograms and examplars enabled: + ```shell + ./prometheus --enable-feature=native-histograms --enable-feature=exemplar-storage + ``` + +Verify that the `tomcat-servlet-example` target is up on [http://localhost:9090/targets](http://localhost:9090/targets). + +Prometheus is now scraping metrics in Protobuf format. If you type the name `request_duration_seconds` you will see a non-human-readable representation of the histogram including the native buckets: + +![Screenshot showing a Prometheus Native Histogram in Text Format](https://github.com/prometheus/client_java/assets/330535/863efe0b-a9eb-40ae-a078-72497abc6f04) + +Note: You have to run at least one GET request on the Hello World endpoint [http://localhost:8080](http://localhost:8080) before you see the metric. + +Use the `histogram_quantile()` function to calculate quantiles from the native histogram: + +``` +histogram_quantile(0.95, rate(request_duration_seconds[10m])) +``` + +![Screenshot showing the 95th Percentile Calculated from a Prometheus Native Histogram](https://github.com/prometheus/client_java/assets/330535/889fb769-9445-4f6f-8540-2b1ddffca55e) diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index 97d4161ef..1598028db 100644 --- a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -12,6 +12,9 @@ import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; +/** + * Hello World REST servlet, with an example counter and an example histogram. + */ public class HelloWorldServlet extends HttpServlet { private final Random random = new Random(0); diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java index 759b88cb9..3e33b1192 100644 --- a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java +++ b/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java @@ -1,8 +1,6 @@ package io.prometheus.metrics.examples.tomcat_servlet; -import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; -import io.prometheus.metrics.model.registry.PrometheusRegistry; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; @@ -10,7 +8,7 @@ import java.io.File; /** - * Simple example using embedded Tomcat an the {@link PrometheusMetricsServlet}. + * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */ public class Main { From 0d232b44723a5275f9cdee4eae99a8c35ca923d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 21 Jul 2023 22:13:12 +0200 Subject: [PATCH 186/980] Add OpenTelemetry Exemplars example --- .../example-exemplars-tail-sampling/README.md | 131 +++++++ .../config/grafana-dashboards.yaml | 8 + .../config/grafana-datasources.yaml | 22 ++ .../config/grafana-example-dashboard.json | 356 ++++++++++++++++++ .../config/k6-script.js | 18 + .../config/otelcol-config.yaml | 34 ++ .../config/prometheus.yaml | 13 + .../config/tempo-config.yaml | 20 + .../docker-compose.yaml | 91 +++++ .../example-greeting-service/pom.xml | 75 ++++ .../greeting/GreetingServlet.java | 47 +++ .../otel_exemplars/greeting/Main.java | 32 ++ .../example-hello-world-app/pom.xml | 75 ++++ .../otel_exemplars/app/HelloWorldServlet.java | 65 ++++ .../examples/otel_exemplars/app/Main.java | 32 ++ .../example-exemplars-tail-sampling/pom.xml | 51 +++ .../README.md | 0 .../pom.xml | 4 +- .../tomcat_servlet/HelloWorldServlet.java | 0 .../metrics/examples/tomcat_servlet/Main.java | 0 examples/pom.xml | 5 +- 21 files changed, 1075 insertions(+), 4 deletions(-) create mode 100644 examples/example-exemplars-tail-sampling/README.md create mode 100644 examples/example-exemplars-tail-sampling/config/grafana-dashboards.yaml create mode 100644 examples/example-exemplars-tail-sampling/config/grafana-datasources.yaml create mode 100644 examples/example-exemplars-tail-sampling/config/grafana-example-dashboard.json create mode 100644 examples/example-exemplars-tail-sampling/config/k6-script.js create mode 100644 examples/example-exemplars-tail-sampling/config/otelcol-config.yaml create mode 100644 examples/example-exemplars-tail-sampling/config/prometheus.yaml create mode 100644 examples/example-exemplars-tail-sampling/config/tempo-config.yaml create mode 100644 examples/example-exemplars-tail-sampling/docker-compose.yaml create mode 100644 examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml create mode 100644 examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java create mode 100644 examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java create mode 100644 examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml create mode 100644 examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java create mode 100644 examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java create mode 100644 examples/example-exemplars-tail-sampling/pom.xml rename examples/{tomcat-servlet-example => example-tomcat-servlet}/README.md (100%) rename examples/{tomcat-servlet-example => example-tomcat-servlet}/pom.xml (96%) rename examples/{tomcat-servlet-example => example-tomcat-servlet}/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java (100%) rename examples/{tomcat-servlet-example => example-tomcat-servlet}/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java (100%) diff --git a/examples/example-exemplars-tail-sampling/README.md b/examples/example-exemplars-tail-sampling/README.md new file mode 100644 index 000000000..38869c26d --- /dev/null +++ b/examples/example-exemplars-tail-sampling/README.md @@ -0,0 +1,131 @@ +Exemplars with OpenTelemetry's Tail Sampling +-------------------------------------------- + +## Background: What are Exemplars? + +Each Prometheus time series may contain Exemplars. Exemplars are additional metadata attached to a Prometheus time series. +Exemplars are often used to reference trace IDs when distributed tracing is used. +The following shows an example of a histogram in OpenMetrics text format where each non-empty bucket has an Exemplar: + +``` +# TYPE request_duration_seconds histogram +# UNIT request_duration_seconds seconds +# HELP request_duration_seconds request duration in seconds +request_duration_seconds_bucket{http_status="200",le="0.005"} 0 +request_duration_seconds_bucket{http_status="200",le="0.01"} 5 # {span_id="826c6f49a0d6c931",trace_id="d2cf83f9f1fd22f793855edc4ae53320"} 0.007341934 1689971637.765 +request_duration_seconds_bucket{http_status="200",le="0.025"} 64 # {span_id="9ae17d91c9822c88",trace_id="320e53f894781db26fa0eb5fb0640426"} 0.014081662 1689971677.851 +request_duration_seconds_bucket{http_status="200",le="0.05"} 281 # {span_id="32c9706b1f798fce",trace_id="636a2bb9fe4aabea0f412b8cd6da2290"} 0.047227664 1689971700.484 +request_duration_seconds_bucket{http_status="200",le="0.1"} 1203 # {span_id="04902c82f56fb441",trace_id="c5cf7c1a4805e4b7a991c4e99fb38f87"} 0.094949368 1689971706.913 +request_duration_seconds_bucket{http_status="200",le="0.25"} 6338 # {span_id="81ffa3cbe3c8bf7e",trace_id="106a0d13ca1578a4c3ae4ec987b7f8f7"} 0.226545183 1689971700.004 +request_duration_seconds_bucket{http_status="200",le="0.5"} 10969 # {span_id="b7ac3d0a2b9570c3",trace_id="79b641c3d96bdba5554395e1521ffb13"} 0.439355954 1689971700.997 +request_duration_seconds_bucket{http_status="200",le="1.0"} 11180 # {span_id="b0cb8480a8b5c1ac",trace_id="4c57125265c4a7caa83c4d354f94bd40"} 0.625977473 1689971700.263 +request_duration_seconds_bucket{http_status="200",le="2.5"} 11209 # {span_id="4bce9aa28f1f8a65",trace_id="7fa30e3153f5129694bd58a23bcc96a8"} 1.529906213 1689971659.228 +request_duration_seconds_bucket{http_status="200",le="5.0"} 11236 # {span_id="e629a7d546da77e1",trace_id="20a43851621f908eab359217df2b5eed"} 2.936415405 1689971661.293 +request_duration_seconds_bucket{http_status="200",le="10.0"} 11243 # {span_id="024e3119605ab66e",trace_id="84721fdc42ef4d55e8416d3191b4d19e"} 5.163273443 1689971663.080 +request_duration_seconds_bucket{http_status="200",le="+Inf"} 11243 +request_duration_seconds_count{http_status="200"} 11243 +request_duration_seconds_sum{http_status="200"} 2843.3178731140015 +``` + +In Grafana Exemplars can be visualized as little green dots. The following shows an example of the 95th [quantile](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for the histogram above. + +![Screenshot of a Latency Graph with Exemplars](https://github.com/prometheus/client_java/assets/330535/68aada3d-f55b-4a7b-90be-222481f0ec79) + +If you move the mouse over an Exemplar, an overlay pops up with a link to a tracing tool like [Tempo](https://github.com/grafana/tempo). + +## Automatic Exemplar Generation + +The Prometheus Java client library automatically detects OpenTelemetry tracing. The library automatically produces Exemplars with OpenTelemetry trace IDs if applicable. + +## Sampling + +Distributed tracing produces a lot of data, and it is quite common to apply a sampling strategy to reduce the number of traces. + +There are two ways how to do this: + +1. _Head-based sampling_ is performed by the tracing library in the application itself. +2. _Tail-based sampling_ is performed by an external infrastructure component like the [OpenTelemetry collector](https://opentelemetry.io/docs/collector/). + +When generating Exemplars, the Prometheus Java client libray must make sure that the Exemplar points to a trace that is actually sampled. Otherwise, Exemplar's trace ID will not be available in the monitoring backend, i.e. the Exemplar will link to a non-existing trace ID. + +With _head-based sampling_ this works out-of-the-box: The Prometheus client library calls OpenTelemetry's `Span.current().getSpanContext().isSampled()` function and selects Exemplars only if the current Span is sampled. + +With _tail-based sampling_ there is a trick: The Prometheus client library adds an attribute `exemplar="true"` to each Span that is used as an Exemplar. The remainder of this README shows how you can configure the `tail_sampling` processor of the OpenTelemetry collector to sample Spans marked with `exemplar="true"`. + +## Build the Example + +The example is built as part of the `client_java` parent project with + +```shell +./mvnw package +``` + +This should generate two Java services `.../example-greeting-service/target/example-greeting-service-[version].jar` and `.../example-hello-world-app/target/example-hello-world-app-[version].jar`. + +## Run the Example + +The `docker-compose` file will run the example with the following containers: + +* `hello-world-app`: Java service described above, with the OpenTelemetry Java instrumentation agent attached for distrubted tracing. +* `greeting-service`: Java service described above, with the OpenTelemetry Java instrumentation agent attached for distrubted tracing. +* `collector`: OpenTelemetry collector for receiving the distributed traces, performing _tail sampling_, and forwarding them to `tempo`. +* `prometheus`: Prometheus server scraping metrics from `hello-world-app`, `greeting-service`, and `tempo`. +* `tempo`: Trace database. +* `grafana`: Has `prometheus` and `tempo` configured as data sources, and is configured with an example dashboard with Exemplars enabled. +* `k6`: The [k6](https://k6.io/) load test tool for generating 50 requests / second on the Java services. + +With the Java services described above available in the `target/` directories, you can run the example with: + +```shell +cd example-exemplars-tail-sampling +docker-compose up +``` + +Grafana will run on [http://localhost:3000](ttp://localhost:3000). The default user is _admin_ with password _admin_. + +## Example Dashboard + +The example dashboard shows 50 requests / second for the Java serices: + +![Screenshot showing the request rate on the Java services](https://github.com/prometheus/client_java/assets/330535/9f8dc92e-c9aa-40b6-8fda-a0f7e98560ba) + +The Tempo metrics show that only ~5 traces / second are received: + +![Screenshot showing the number of traces per second received by Tempo](https://github.com/prometheus/client_java/assets/330535/5e439ac5-3c5c-4d40-a4cd-6737c2c82dfd) + +The reason is that the OpenTelemetry collector is configured to sample only 10% of the traces. Yet, all Exemplars in the latency graph point to traces that actually made it to Tempo. + +## OpenTelemetry Collector Config + +The OpenTelemetry collector is configured to keep all Spans with the attribute `exemplar="true"`. Probabilistic sampling applies only to the remainder of the Spans. + +```yaml +processors: + batch: + tail_sampling: + expected_new_traces_per_sec: 10 + policies: + [ + { + name: keep-exemplars, + type: string_attribute, + string_attribute: { key: "exemplar", values: [ "true" ] } + }, + { + name: keep-10-percent, + type: probabilistic, + probabilistic: { sampling_percentage: 10 } + }, + ] +``` + +The Prometheus Java client library automatically sets the `exemplar="true"` attribute for each Span that is used as an Exemplar. + +The Exemplar sampler of the Prometheus Java client library is rate-limited, the `DEFAULT_MIN_RETENTION_PERIOD_SECONDS` is 7s. +So only one Span per 7 seconds per time series will be marked with `exemplar="true"`. + +## Conclusion + +The Prometheus Java client library automatically generates Exemplars if OpenTelemetry tracing is detected. +In order to make that work with _tail-based sampling_, the Prometheus Java client library adds an attribute `exemplar="true"` to each Span that's used as an Exemplar. +The `tail_sampling` processor in the OpenTelemetry collector can be configured to always sample Spans marked as `exemplar="true"`. diff --git a/examples/example-exemplars-tail-sampling/config/grafana-dashboards.yaml b/examples/example-exemplars-tail-sampling/config/grafana-dashboards.yaml new file mode 100644 index 000000000..f3bca68b8 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/grafana-dashboards.yaml @@ -0,0 +1,8 @@ +apiVersion: 1 + +providers: + - name: 'Example Dashboard' + type: file + options: + path: /etc/grafana/example-dashboard.json + foldersFromFilesStructure: false diff --git a/examples/example-exemplars-tail-sampling/config/grafana-datasources.yaml b/examples/example-exemplars-tail-sampling/config/grafana-datasources.yaml new file mode 100644 index 000000000..6f31ecb53 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/grafana-datasources.yaml @@ -0,0 +1,22 @@ +apiVersion: 1 + +datasources: + + - name: Prometheus + type: prometheus + uid: prometheus + url: http://localhost:9090 + + - name: Tempo + type: tempo + uid: tempo + url: http://localhost:3200 + + - name: Prometheus + type: prometheus + uid: prometheus + url: http://localhost:9090 + jsonData: + exemplarTraceIdDestinations: + - name: trace_id + datasourceUid: tempo diff --git a/examples/example-exemplars-tail-sampling/config/grafana-example-dashboard.json b/examples/example-exemplars-tail-sampling/config/grafana-example-dashboard.json new file mode 100644 index 000000000..15c14e9e1 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/grafana-example-dashboard.json @@ -0,0 +1,356 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 13, + "w": 18, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "histogram_quantile(0.95, rate(request_duration_seconds{job=\"$instance\"}[5m]))", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Request Duration 95th Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 11, + "w": 18, + "x": 0, + "y": 13 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "histogram_count(rate(request_duration_seconds{job=\"$instance\"}[5m]))", + "instant": true, + "key": "Q-ddf5e7ad-fa7a-4342-acf8-819848f226a3-0", + "range": true, + "refId": "A" + } + ], + "title": "Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 0, + "y": 24 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "rate(tempo_ingester_traces_created_total[5m])", + "instant": true, + "key": "Q-0e8731c6-7df2-47bc-a1a3-45dcb9f5e92d-0", + "range": true, + "refId": "A" + } + ], + "title": "Traces Ingested in Tempo", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "greeting-service", + "value": "greeting-service" + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(job)", + "hide": 0, + "includeAll": false, + "multi": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values(job)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "/[^tempo]/", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Example Dashboard", + "uid": "e11cc371-fef5-4783-b5a5-fe0302f00740", + "version": 1, + "weekStart": "" +} diff --git a/examples/example-exemplars-tail-sampling/config/k6-script.js b/examples/example-exemplars-tail-sampling/config/k6-script.js new file mode 100644 index 000000000..5521a9565 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/k6-script.js @@ -0,0 +1,18 @@ +import http from 'k6/http'; + +export const options = { + scenarios: { + constant_request_rate: { + executor: 'constant-arrival-rate', + rate: 50, + timeUnit: '1s', + duration: '2h', + preAllocatedVUs: 10, + maxVUs: 100, + }, + }, +}; + +export default function () { + http.get('http://localhost:8080'); +} diff --git a/examples/example-exemplars-tail-sampling/config/otelcol-config.yaml b/examples/example-exemplars-tail-sampling/config/otelcol-config.yaml new file mode 100644 index 000000000..2ad19f013 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/otelcol-config.yaml @@ -0,0 +1,34 @@ +receivers: + otlp: + protocols: + grpc: + http: + +processors: + batch: + tail_sampling: + expected_new_traces_per_sec: 10 + policies: + [ + { + name: keep-exemplars, + type: string_attribute, + string_attribute: { key: "exemplar", values: [ "true" ] } + }, + { + name: keep-10-percent, + type: probabilistic, + probabilistic: { sampling_percentage: 10 } + }, + ] + +exporters: + otlphttp: + endpoint: http://localhost:4418 + +service: + pipelines: + traces: + receivers: [otlp] + processors: [tail_sampling, batch] + exporters: [otlphttp] diff --git a/examples/example-exemplars-tail-sampling/config/prometheus.yaml b/examples/example-exemplars-tail-sampling/config/prometheus.yaml new file mode 100644 index 000000000..037c515f8 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/prometheus.yaml @@ -0,0 +1,13 @@ +global: + scrape_interval: 5s + +scrape_configs: + - job_name: "tempo" + static_configs: + - targets: ["localhost:3200"] + - job_name: "hello-world-app" + static_configs: + - targets: ["localhost:8080"] + - job_name: "greeting-service" + static_configs: + - targets: ["localhost:8081"] diff --git a/examples/example-exemplars-tail-sampling/config/tempo-config.yaml b/examples/example-exemplars-tail-sampling/config/tempo-config.yaml new file mode 100644 index 000000000..12eed44cf --- /dev/null +++ b/examples/example-exemplars-tail-sampling/config/tempo-config.yaml @@ -0,0 +1,20 @@ +server: + http_listen_port: 3200 + grpc_listen_port: 9096 + +distributor: + receivers: + otlp: + protocols: + grpc: + endpoint: "localhost:4417" + http: + endpoint: "localhost:4418" + +storage: + trace: + backend: local + wal: + path: /tmp/tempo/wal + local: + path: /tmp/tempo/blocks diff --git a/examples/example-exemplars-tail-sampling/docker-compose.yaml b/examples/example-exemplars-tail-sampling/docker-compose.yaml new file mode 100644 index 000000000..e4c43f99c --- /dev/null +++ b/examples/example-exemplars-tail-sampling/docker-compose.yaml @@ -0,0 +1,91 @@ +version: "3" +services: + hello-world-app: + image: opentelemetry-java-agent + build: + context: . + dockerfile_inline: | + FROM openjdk:11-jre + WORKDIR / + RUN curl -sOL https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.28.0/opentelemetry-javaagent.jar + network_mode: host + ports: + - "8080:8080" + volumes: + - ./example-hello-world-app/target/example-hello-world-app-1.0.0-alpha-2-SNAPSHOT.jar:/hello-world-app.jar + environment: + - OTEL_TRACES_EXPORTER=otlp + - OTEL_METRICS_EXPORTER=none + - OTEL_LOGS_EXPORTER=none + command: + - java + - -javaagent:/opentelemetry-javaagent.jar + - -jar + - /hello-world-app.jar + greeting-service: + # The opentelemetry-java-agent image is coming from the hello-world-up service above. + image: opentelemetry-java-agent + network_mode: host + ports: + - "8081:8081" + volumes: + - ./example-greeting-service/target/example-greeting-service-1.0.0-alpha-2-SNAPSHOT.jar:/greeting-service.jar + environment: + - OTEL_TRACES_EXPORTER=otlp + - OTEL_METRICS_EXPORTER=none + - OTEL_LOGS_EXPORTER=none + command: + - java + - -javaagent:/opentelemetry-javaagent.jar + - -jar + - /greeting-service.jar + collector: + image: otel/opentelemetry-collector-contrib:0.79.0 + network_mode: host + ports: + - "4317:4317" + - "4318:4318" + volumes: + - ./config/otelcol-config.yaml:/config.yaml + command: + - --config=file:/config.yaml + prometheus: + image: prom/prometheus:v2.45.0 + network_mode: host + ports: + - "9090:9090" + volumes: + - ./config/prometheus.yaml:/prometheus.yaml + command: + - --enable-feature=exemplar-storage + - --enable-feature=native-histograms + - --config.file=/prometheus.yaml + tempo: + image: grafana/tempo:2.1.1 + network_mode: host + ports: + - "3200:3200" + - "4417:4417" + - "4418:4418" + - "9096:9096" + volumes: + - ./config/tempo-config.yaml:/config.yaml + command: + - --config.file=/config.yaml + grafana: + image: grafana/grafana:10.0.0 + network_mode: host + ports: + - "3000:3000" + volumes: + - ./config/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/grafana-datasources.yaml + - ./config/grafana-dashboards.yaml:/etc/grafana/provisioning/dashboards/grafana-dashboards.yaml + - ./config/grafana-example-dashboard.json:/etc/grafana/example-dashboard.json + k6: + image: grafana/k6 + network_mode: host + volumes: + - ./config/k6-script.js:/k6-script.js + command: + - run + - /k6-script.js diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml new file mode 100644 index 000000000..627af543c --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + io.prometheus + example-exemplars-tail-sampling + 1.0.0-alpha-2-SNAPSHOT + + + example-greeting-service + + Example - OpenTelemetry Exemplars - Greeting Service + + Part of a distributed "Hello, World" REST service to show Exemplars with OpenTelemetry's distributed tracing + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-servlet-jakarta + ${project.version} + + + org.apache.tomcat.embed + tomcat-embed-core + 10.1.11 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.otel_exemplars.greeting.Main + + + + + + + + + diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java new file mode 100644 index 000000000..2fd266cd9 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -0,0 +1,47 @@ +package io.prometheus.metrics.examples.otel_exemplars.greeting; + +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.model.snapshots.Unit; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.Random; + +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; + +/** + * Hello World REST servlet, with an example counter and an example histogram. + */ +public class GreetingServlet extends HttpServlet { + + private final Random random = new Random(0); + + private final Histogram histogram; + + public GreetingServlet() { + histogram = Histogram.newBuilder() + .withName("request_duration_seconds") + .withHelp("request duration in seconds") + .withUnit(Unit.SECONDS) + .withLabelNames("http_status") + .register(); + histogram.withLabelValues("200"); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("Hello, World!"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + } + } +} diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java new file mode 100644 index 000000000..4982be376 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.examples.otel_exemplars.greeting; + +import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; + +import java.io.File; + +/** + * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. + */ +public class Main { + + public static void main(String[] args) throws LifecycleException { + + Tomcat tomcat = new Tomcat(); + tomcat.setPort(8081); + + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + + Tomcat.addServlet(ctx, "hello", new GreetingServlet()); + ctx.addServletMappingDecoded("/*", "hello"); + + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); + + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } +} diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml new file mode 100644 index 000000000..5e7056512 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + + io.prometheus + example-exemplars-tail-sampling + 1.0.0-alpha-2-SNAPSHOT + + + example-hello-world-app + + Example - OpenTelemetry Exemplars - Hello World App + + Part of a distributed "Hello, World" REST service to show Exemplars with OpenTelemetry's distributed tracing + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-servlet-jakarta + ${project.version} + + + org.apache.tomcat.embed + tomcat-embed-core + 10.1.11 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.otel_exemplars.app.Main + + + + + + + + + diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java new file mode 100644 index 000000000..d7c5db034 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -0,0 +1,65 @@ +package io.prometheus.metrics.examples.otel_exemplars.app; + +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.model.snapshots.Unit; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Random; + +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; +import static java.net.http.HttpResponse.BodyHandlers.ofString; + +/** + * Hello World REST servlet, with an example counter and an example histogram. + */ +public class HelloWorldServlet extends HttpServlet { + + private final Random random = new Random(0); + + private final Histogram histogram; + + public HelloWorldServlet() { + histogram = Histogram.newBuilder() + .withName("request_duration_seconds") + .withHelp("request duration in seconds") + .withUnit(Unit.SECONDS) + .withLabelNames("http_status") + .register(); + histogram.withLabelValues("200"); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + String greeting = executeGreetingServiceRequest(); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().print(greeting); + } catch (Exception e) { + throw new ServletException(e); + } finally { + histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + } + } + + private String executeGreetingServiceRequest() throws URISyntaxException, IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(new URI("http://localhost:8081/")) + .build(); + HttpClient httpClient = HttpClient.newHttpClient(); + HttpResponse response = httpClient.send(request, ofString()); + return response.body(); + } +} diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java new file mode 100644 index 000000000..cf8fee7f1 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.examples.otel_exemplars.app; + +import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; + +import java.io.File; + +/** + * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. + */ +public class Main { + + public static void main(String[] args) throws LifecycleException { + + Tomcat tomcat = new Tomcat(); + tomcat.setPort(8080); + + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + + Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); + ctx.addServletMappingDecoded("/*", "hello"); + + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); + + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } +} diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml new file mode 100644 index 000000000..eb93cabb5 --- /dev/null +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.0.0-alpha-2-SNAPSHOT + + + example-exemplars-tail-sampling + pom + + Example - Exemplars with OpenTelemetry's Tail Sampling + + Example project showing Examplars with OpenTelemetry's Tail Sampling. + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + example-greeting-service + example-hello-world-app + + + + + + maven-compiler-plugin + + 11 + 11 + + + + + diff --git a/examples/tomcat-servlet-example/README.md b/examples/example-tomcat-servlet/README.md similarity index 100% rename from examples/tomcat-servlet-example/README.md rename to examples/example-tomcat-servlet/README.md diff --git a/examples/tomcat-servlet-example/pom.xml b/examples/example-tomcat-servlet/pom.xml similarity index 96% rename from examples/tomcat-servlet-example/pom.xml rename to examples/example-tomcat-servlet/pom.xml index 51c0fa5f0..bc29592e3 100644 --- a/examples/tomcat-servlet-example/pom.xml +++ b/examples/example-tomcat-servlet/pom.xml @@ -8,9 +8,9 @@ 1.0.0-alpha-2-SNAPSHOT - tomcat-servlet-example + example-tomcat-servlet - Tomcat Servlet Example + Example - Tomcat Servlet Prometheus Metrics Example using Embedded Tomcat and the Exporter Servlet diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java similarity index 100% rename from examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java rename to examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java diff --git a/examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java similarity index 100% rename from examples/tomcat-servlet-example/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java rename to examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java diff --git a/examples/pom.xml b/examples/pom.xml index b76818b77..ebd589b48 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -11,7 +11,7 @@ examples pom - Prometheus Metrics Examples + Examples Example projects for the Prometheus Metrics Library. @@ -33,7 +33,8 @@ - tomcat-servlet-example + example-tomcat-servlet + example-exemplars-tail-sampling From 1a955b1d99b3a31f2c48db146832bf4466f9e12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 23 Jul 2023 22:56:53 +0200 Subject: [PATCH 187/980] Allow dots in metric names and label names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../greeting/GreetingServlet.java | 2 +- .../otel_exemplars/app/HelloWorldServlet.java | 2 +- .../tomcat_servlet/HelloWorldServlet.java | 5 + .../metrics/config/PrometheusProperties.java | 2 +- .../config/PrometheusPropertiesLoader.java | 4 +- .../metrics/core/metrics/Counter.java | 11 +- .../core/metrics/CounterWithCallback.java | 4 +- .../prometheus/metrics/core/metrics/Info.java | 17 +- .../core/metrics/MetricWithFixedMetadata.java | 12 +- .../metrics/core/metrics/StateSet.java | 5 +- .../metrics/core/metrics/StatefulMetric.java | 29 +- .../metrics/core/metrics/CounterTest.java | 24 +- .../metrics/core/metrics/HistogramTest.java | 22 +- .../metrics/core/metrics/InfoTest.java | 33 +- .../OpenMetricsTextFormatWriter.java | 31 +- .../PrometheusProtobufWriter.java | 11 +- .../PrometheusTextFormatWriter.java | 37 +- .../expositionformats/TextFormatUtil.java | 4 +- .../ExpositionFormatsTest.java | 355 ++++++++++++++++++ .../metrics/model/registry/Collector.java | 10 +- .../model/registry/MultiCollector.java | 8 +- .../model/registry/PrometheusRegistry.java | 45 ++- .../metrics/model/snapshots/InfoSnapshot.java | 3 - .../metrics/model/snapshots/Labels.java | 178 ++++++--- .../model/snapshots/MetricMetadata.java | 143 +++---- .../model/snapshots/MetricSnapshot.java | 9 +- .../model/snapshots/MetricSnapshots.java | 9 +- .../model/snapshots/PrometheusNaming.java | 178 +++++++++ .../model/snapshots/StateSetSnapshot.java | 4 +- .../registry/PrometheusRegistryTest.java | 82 ++++ .../model/snapshots/GaugeSnapshotTest.java | 5 + .../model/snapshots/InfoSnapshotTest.java | 14 + .../metrics/model/snapshots/LabelsTest.java | 61 ++- .../model/snapshots/MetricMetadataTest.java | 20 +- .../model/snapshots/PrometheusNamingTest.java | 34 ++ 35 files changed, 1096 insertions(+), 317 deletions(-) create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java index 2fd266cd9..a1046e2a2 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -27,7 +27,7 @@ public GreetingServlet() { .withUnit(Unit.SECONDS) .withLabelNames("http_status") .register(); - histogram.withLabelValues("200"); + histogram.initLabelValues("200"); } @Override diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java index d7c5db034..cabedbce5 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -34,7 +34,7 @@ public HelloWorldServlet() { .withUnit(Unit.SECONDS) .withLabelNames("http_status") .register(); - histogram.withLabelValues("200"); + histogram.initLabelValues("200"); } @Override diff --git a/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index 1598028db..7a95e36da 100644 --- a/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-tomcat-servlet/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -32,6 +32,11 @@ public class HelloWorldServlet extends HttpServlet { .withLabelNames("http_status") .register(); + public HelloWorldServlet() { + counter.initLabelValues("200"); + histogram.initLabelValues("200"); + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { long start = System.nanoTime(); diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java index 9341c5988..95660a463 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java @@ -58,7 +58,7 @@ public MetricsProperties getDefaultMetricProperties() { * May return {@code null} if no metric-specific properties are configured for a metric name. */ public MetricsProperties getMetricProperties(String metricName) { - return metricProperties.get(metricName); + return metricProperties.get(metricName.replace(".", "_")); } public ExemplarsProperties getExemplarProperties() { diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java index ba52372e5..58ddc2669 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java @@ -39,6 +39,8 @@ public static PrometheusProperties load() throws PrometheusPropertiesException { // This will remove entries from properties when they are processed. private static Map loadMetricsConfigs(Map properties) { Map result = new HashMap<>(); + // Note that the metric name in the properties file must be as exposed in the Prometheus exposition formats, + // i.e. all dots replaced with underscores. Pattern pattern = Pattern.compile("io\\.prometheus\\.metrics\\.([^.]+)\\."); // Create a copy of the keySet() for iterating. We cannot iterate directly over keySet() // because entries are removed when MetricsConfig.load(...) is called. @@ -49,7 +51,7 @@ private static Map loadMetricsConfigs(Map @@ -109,8 +112,8 @@ protected CounterSnapshot collect(List labels, List metricDat return new CounterSnapshot(getMetadata(), data); } - static String normalizeName(String name) { - if (name != null && name.endsWith("_total")) { + static String stripTotalSuffix(String name) { + if (name != null && (name.endsWith("_total") || name.endsWith(".total"))) { name = name.substring(0, name.length() - 6); } return name; @@ -231,12 +234,12 @@ private Builder(PrometheusProperties properties) { * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. *

    * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} * is {@code false}. */ @Override public Builder withName(String name) { - return super.withName(normalizeName(name)); + return super.withName(stripTotalSuffix(name)); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java index c7446f4c1..b4d7bc761 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java @@ -80,12 +80,12 @@ private Builder(PrometheusProperties properties) { * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. *

    * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} * is {@code false}. */ @Override public Builder withName(String name) { - return super.withName(Counter.normalizeName(name)); + return super.withName(Counter.stripTotalSuffix(name)); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java index 9d6675dbb..5731e2843 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java @@ -2,16 +2,16 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.Unit; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + /** * Info metric. Example: *

    {@code
    @@ -90,15 +90,12 @@ private Builder(PrometheusProperties config) {
              * In the example above both {@code info1} and {@code info2} will be named {@code "runtime_info"} in Prometheus.
              * 

    * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.MetricMetadata#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} + * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} * is {@code false}. */ @Override public Builder withName(String name) { - if (name != null && name.endsWith("_info")) { - name = name.substring(0, name.length() - 5); - } - return super.withName(name); + return super.withName(stripInfoSuffix(name)); } /** @@ -112,8 +109,8 @@ public Builder withUnit(Unit unit) { return this; } - private static String normalizeName(String name) { - if (name != null && name.endsWith("_info")) { + private static String stripInfoSuffix(String name) { + if (name != null && (name.endsWith("_info") || name.endsWith(".info"))) { name = name.substring(0, name.length() - 5); } return name; @@ -121,7 +118,7 @@ private static String normalizeName(String name) { @Override public Info build() { - return new Info(withName(normalizeName(name))); + return new Info(this); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 22b607654..6f963c299 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -3,11 +3,14 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; import io.prometheus.metrics.model.snapshots.Unit; import java.util.Arrays; import java.util.List; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + /** * Almost all metrics have fixed metadata, i.e. the metric name is known when the metric is created. *

    @@ -31,9 +34,8 @@ protected MetricMetadata getMetadata() { private String makeName(String name, Unit unit) { if (unit != null) { - String suffix = "_" + unit; - if (!name.endsWith(suffix)) { - name = name + suffix; + if (!name.endsWith(unit.toString())) { + name = name + "_" + unit; } } return name; @@ -51,7 +53,7 @@ protected Builder(List illegalLabelNames, PrometheusProperties propertie } public B withName(String name) { - if (!MetricMetadata.isValidMetricName(name)) { + if (!PrometheusNaming.isValidMetricName(name)) { throw new IllegalArgumentException("'" + name + "': Illegal metric name."); } this.name = name; @@ -70,7 +72,7 @@ public B withHelp(String help) { public B withLabelNames(String... labelNames) { for (String labelName : labelNames) { - if (!Labels.isValidLabelName(labelName)) { + if (!PrometheusNaming.isValidLabelName(labelName)) { throw new IllegalArgumentException(labelName + ": illegal label name"); } if (illegalLabelNames.contains(labelName)) { diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java index 308c61be1..7348c0410 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -3,6 +3,7 @@ import io.prometheus.metrics.config.MetricsProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.core.datapoints.StateSetDataPoint; @@ -11,6 +12,8 @@ import java.util.List; import java.util.stream.Stream; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + /** * StateSet metric. Example: *

    {@code
    @@ -58,7 +61,7 @@ private StateSet(Builder builder, PrometheusProperties prometheusProperties) {
             exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled);
             this.names = builder.names; // builder.names is already a validated copy
             for (String name : names) {
    -            if (this.getMetadata().getName().equals(name)) {
    +            if (this.getMetadata().getPrometheusName().equals(prometheusName(name))) {
                     throw new IllegalArgumentException("Label name " + name + " is illegal (can't use the metric name as label name in state set metrics)");
                 }
             }
    diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java
    index 591c16e6b..17d8da246 100644
    --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java
    +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java
    @@ -62,6 +62,34 @@ public MetricSnapshot collect() {
             return collect(labels, metricData);
         }
     
    +    /**
    +     * Initialize label values.
    +     * 

    + * Example: Imagine you have a counter for payments as follows + *

    +     * payment_transactions_total{payment_type="credit card"} 7.0
    +     * payment_transactions_total{payment_type="paypal"} 3.0
    +     * 
    + * Now, the data points for the {@code payment_type} label values get initialized when they are + * first used, i.e. the first time you call + *
    {@code
    +     * counter.withLabelValues("paypal").inc();
    +     * }
    + * the data point with label {@code payment_type="paypal"} will go from non-existent to having value {@code 1.0}. + *

    + * In some cases this is confusing, and you want to have data points initialized on application start + * with an initial value of {@code 0.0}: + *

    +     * payment_transactions_total{payment_type="credit card"} 0.0
    +     * payment_transactions_total{payment_type="paypal"} 0.0
    +     * 
    + * {@code initLabelValues(...)} can be used to initialize label value, so that the data points + * show up in the exposition format with an initial value of zero. + */ + public void initLabelValues(String... labelValues) { + withLabelValues(labelValues); + } + public D withLabelValues(String... labelValues) { if (labelValues.length != labelNames.length) { if (labelValues.length == 0) { @@ -73,7 +101,6 @@ public D withLabelValues(String... labelValues) { return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); } - // TODO: Remove automatically if label values have not been used in a while? public void remove(String... labelValues) { data.remove(Arrays.asList(labelValues)); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 0efa6ee4a..a967a8d64 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -109,18 +109,18 @@ public void testLabels() { @Test public void testTotalStrippedFromName() { - Counter counter = Counter.newBuilder() - .withName("my_counter_total") - .withUnit(Unit.SECONDS) - .build(); - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertEquals("name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData)); - - counter = Counter.newBuilder() - .withName("my_counter") - .build(); - protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertEquals("name: \"my_counter_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData)); + for (String name : new String[]{ + "my_counter_total", "my.counter.total", + "my_counter_seconds_total", "my.counter.seconds.total", + "my_counter", "my.counter", + "my_counter_seconds", "my.counter.seconds"}) { + Counter counter = Counter.newBuilder() + .withName(name) + .withUnit(Unit.SECONDS) + .build(); + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); + assertEquals("name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData)); + } } @Test diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 393e2c876..2af392097 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1,19 +1,19 @@ package io.prometheus.metrics.core.metrics; import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; -import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.tracer.common.SpanContext; -import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.core.datapoints.DistributionDataPoint; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -1043,19 +1043,9 @@ public void testIllegalLabelNamePrefix() { .withLabelNames("__hello"); } - @Test(expected = IllegalArgumentException.class) - public void testIllegalLabelNameDot() { - // The Prometheus team are investigating to allow dots in future Prometheus versions, but for now it's invalid. - // The reason is that you cannot use illegal label names in the Prometheus query language. - Histogram.newBuilder() - .withName("test") - .withLabelNames("http.status"); - } - @Test(expected = IllegalArgumentException.class) public void testIllegalName() { - Histogram.newBuilder() - .withName("server.durations"); + Histogram.newBuilder().withName("my_namespace/server.durations"); } @Test(expected = IllegalArgumentException.class) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 4cca37ef6..5b1bbf991 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -1,23 +1,28 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.model.snapshots.Labels; -import org.junit.Assert; +import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class InfoTest { @Test - public void testIncrement() { - Info info = Info.newBuilder() - .withName("target_info") - .withLabelNames("key") - .build(); - info.infoLabelValues("value"); - InfoSnapshot snapshot = info.collect(); - Assert.assertEquals("target", snapshot.getMetadata().getName()); - Assert.assertEquals(1, snapshot.getData().size()); - InfoSnapshot.InfoDataPointSnapshot data = snapshot.getData().stream().findAny().orElseThrow(RuntimeException::new); - Assert.assertEquals(Labels.of("key", "value"), data.getLabels()); + public void testInfoStrippedFromName() { + for (String name : new String[]{ + "jvm.runtime", "jvm_runtime", + "jvm.runtime.info", "jvm_runtime_info"}) { + for (String labelName : new String[]{"my.key", "my_key"}) { + Info info = Info.newBuilder() + .withName(name) + .withLabelNames(labelName) + .build(); + info.infoLabelValues("value"); + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); + assertEquals("name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }", TextFormat.printer().shortDebugString(protobufData)); + } + } } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index 0559ce0be..fa131335e 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -29,6 +29,7 @@ import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; /** * Write the OpenMetrics text format as defined on https://openmetrics.io. @@ -89,7 +90,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) t MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "counter", metadata); for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), "_total", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); writeCreated(writer, metadata, data); @@ -100,7 +101,7 @@ private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throw MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "gauge", metadata); for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); if (exemplarsOnAllMetricTypesEnabled) { writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); @@ -128,7 +129,7 @@ private void writeClassicHistogramBuckets(OutputStreamWriter writer, MetricMetad long cumulativeCount = 0; for (int i = 0; i < buckets.size(); i++) { cumulativeCount += buckets.getCount(i); - writeNameAndLabels(writer, metadata.getName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); writeLong(writer, cumulativeCount); Exemplar exemplar; if (i == 0) { @@ -176,7 +177,7 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) t // quantiles, all indexes modulo exemplars.length. int exemplarIndex = 1; for (Quantile quantile : data.getQuantiles()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels(), "quantile", quantile.getQuantile()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels(), "quantile", quantile.getQuantile()); writeDouble(writer, quantile.getValue()); if (exemplars.size() > 0 && exemplarsOnAllMetricTypesEnabled) { exemplarIndex = (exemplarIndex + 1) % exemplars.size(); @@ -195,7 +196,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "info", metadata); for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), "_info", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); writer.write("1"); writeScrapeTimestampAndExemplar(writer, data, null); } @@ -206,13 +207,13 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) writeMetadata(writer, "stateset", metadata); for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { for (int i = 0; i < data.size(); i++) { - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write('{'); for (int j = 0; j < data.getLabels().size(); j++) { if (j > 0) { writer.write(","); } - writer.write(data.getLabels().getName(j)); + writer.write(data.getLabels().getPrometheusName(j)); writer.write("=\""); writeEscapedLabelValue(writer, data.getLabels().getValue(j)); writer.write("\""); @@ -220,7 +221,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) if (!data.getLabels().isEmpty()) { writer.write(","); } - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write("=\""); writeEscapedLabelValue(writer, data.getName(i)); writer.write("\"} "); @@ -238,7 +239,7 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) t MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "unknown", metadata); for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); if (exemplarsOnAllMetricTypesEnabled) { writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); @@ -251,7 +252,7 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) t private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata, DistributionDataPointSnapshot data, String countSuffix, String sumSuffix, Exemplars exemplars) throws IOException { int exemplarIndex = 0; if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getName(), countSuffix, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), countSuffix, data.getLabels()); writeLong(writer, data.getCount()); if (exemplars.size() > 0) { writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); @@ -261,7 +262,7 @@ private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata } } if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getName(), sumSuffix, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), sumSuffix, data.getLabels()); writeDouble(writer, data.getSum()); if (exemplars.size() > 0) { writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); @@ -273,7 +274,7 @@ private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata private void writeCreated(OutputStreamWriter writer, MetricMetadata metadata, DataPointSnapshot data) throws IOException { if (createdTimestampsEnabled && data.hasCreatedTimestamp()) { - writeNameAndLabels(writer, metadata.getName(), "_created", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); writeTimestamp(writer, data.getCreatedTimestampMillis()); if (data.hasScrapeTimestamp()) { writer.write(' '); @@ -319,20 +320,20 @@ private void writeScrapeTimestampAndExemplar(OutputStreamWriter writer, DataPoin private void writeMetadata(OutputStreamWriter writer, String typeName, MetricMetadata metadata) throws IOException { writer.write("# TYPE "); - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write(' '); writer.write(typeName); writer.write('\n'); if (metadata.getUnit() != null) { writer.write("# UNIT "); - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write(' '); writeEscapedLabelValue(writer, metadata.getUnit().toString()); writer.write('\n'); } if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { writer.write("# HELP "); - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write(' '); writeEscapedLabelValue(writer, metadata.getHelp()); writer.write('\n'); diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index d6de08114..6f4eb6e67 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -24,6 +24,7 @@ import java.io.OutputStream; import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; /** * Write the Prometheus protobuf format as defined in @@ -103,7 +104,7 @@ public Metrics.MetricFamily convert(MetricSnapshot snapshot) { } else if (snapshot instanceof StateSetSnapshot) { for (StateSetSnapshot.StateSetDataPointSnapshot data : ((StateSetSnapshot) snapshot).getData()) { for (int i = 0; i < data.size(); i++) { - builder.addMetric(convert(data, snapshot.getMetadata().getName(), i)); + builder.addMetric(convert(data, snapshot.getMetadata().getPrometheusName(), i)); } } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); @@ -121,9 +122,9 @@ private void setMetadataUnlessEmpty(Metrics.MetricFamily.Builder builder, Metric return; } if (nameSuffix == null) { - builder.setName(metadata.getName()); + builder.setName(metadata.getPrometheusName()); } else { - builder.setName(metadata.getName() + nameSuffix); + builder.setName(metadata.getPrometheusName() + nameSuffix); } if (metadata.getHelp() != null) { builder.setHelp(metadata.getHelp()); @@ -335,7 +336,7 @@ private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { for (int i = 0; i < labels.size(); i++) { metricBuilder.addLabel(Metrics.LabelPair.newBuilder() - .setName(labels.getName(i)) + .setName(labels.getPrometheusName(i)) .setValue(labels.getValue(i)) .build()); } @@ -344,7 +345,7 @@ private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { private void addLabels(Metrics.Exemplar.Builder metricBuilder, Labels labels) { for (int i = 0; i < labels.size(); i++) { metricBuilder.addLabel(Metrics.LabelPair.newBuilder() - .setName(labels.getName(i)) + .setName(labels.getPrometheusName(i)) .setValue(labels.getValue(i)) .build()); } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index a4499dd9d..bc187a886 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -26,6 +26,7 @@ import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; /** * Write the Prometheus text format. This is the default if you view a Prometheus endpoint with your Web browser. @@ -102,7 +103,7 @@ public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) thr writeMetadata(writer, "_created", "gauge", metadata); metadataWritten = true; } - writeNameAndLabels(writer, metadata.getName(), "_created", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); writeTimestamp(writer, data.getCreatedTimestampMillis()); writeScrapeTimestampAndNewline(writer, data); } @@ -115,7 +116,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) t MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "_total", "counter", metadata); for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), "_total", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); } @@ -126,7 +127,7 @@ private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throw MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "gauge", metadata); for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); } @@ -140,18 +141,18 @@ private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapsho long cumulativeCount = 0; for (int i = 0; i < buckets.size(); i++) { cumulativeCount += buckets.getCount(i); - writeNameAndLabels(writer, metadata.getName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); writeLong(writer, cumulativeCount); writeScrapeTimestampAndNewline(writer, data); } if (!snapshot.isGaugeHistogram()) { if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getName(), "_count", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); writeLong(writer, data.getCount()); writeScrapeTimestampAndNewline(writer, data); } if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getName(), "_sum", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); writeDouble(writer, data.getSum()); writeScrapeTimestampAndNewline(writer, data); } @@ -183,7 +184,7 @@ private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot sna writeMetadata(writer, "_gcount", "gauge", metadata); metadataWritten = true; } - writeNameAndLabels(writer, metadata.getName(), "_gcount", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_gcount", data.getLabels()); writeLong(writer, data.getCount()); writeScrapeTimestampAndNewline(writer, data); } @@ -195,7 +196,7 @@ private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot sna writeMetadata(writer, "_gsum", "gauge", metadata); metadataWritten = true; } - writeNameAndLabels(writer, metadata.getName(), "_gsum", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_gsum", data.getLabels()); writeDouble(writer, data.getSum()); writeScrapeTimestampAndNewline(writer, data); } @@ -214,17 +215,17 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) t metadataWritten = true; } for (Quantile quantile : data.getQuantiles()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels(), "quantile", quantile.getQuantile()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels(), "quantile", quantile.getQuantile()); writeDouble(writer, quantile.getValue()); writeScrapeTimestampAndNewline(writer, data); } if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getName(), "_count", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); writeLong(writer, data.getCount()); writeScrapeTimestampAndNewline(writer, data); } if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getName(), "_sum", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); writeDouble(writer, data.getSum()); writeScrapeTimestampAndNewline(writer, data); } @@ -235,7 +236,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "_info", "gauge", metadata); for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), "_info", data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); writer.write("1"); writeScrapeTimestampAndNewline(writer, data); } @@ -246,13 +247,13 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) writeMetadata(writer, "", "gauge", metadata); for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { for (int i = 0; i < data.size(); i++) { - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write('{'); for (int j = 0; j < data.getLabels().size(); j++) { if (j > 0) { writer.write(","); } - writer.write(data.getLabels().getName(j)); + writer.write(data.getLabels().getPrometheusName(j)); writer.write("=\""); writeEscapedLabelValue(writer, data.getLabels().getValue(j)); writer.write("\""); @@ -260,7 +261,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) if (!data.getLabels().isEmpty()) { writer.write(","); } - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); writer.write("=\""); writeEscapedLabelValue(writer, data.getName(i)); writer.write("\"} "); @@ -278,7 +279,7 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) t MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "untyped", metadata); for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { - writeNameAndLabels(writer, metadata.getName(), null, data.getLabels()); + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); } @@ -303,7 +304,7 @@ private void writeNameAndLabels(OutputStreamWriter writer, String name, String s private void writeMetadata(OutputStreamWriter writer, String suffix, String typeString, MetricMetadata metadata) throws IOException { if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { writer.write("# HELP "); - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); if (suffix != null) { writer.write(suffix); } @@ -312,7 +313,7 @@ private void writeMetadata(OutputStreamWriter writer, String suffix, String type writer.write('\n'); } writer.write("# TYPE "); - writer.write(metadata.getName()); + writer.write(metadata.getPrometheusName()); if (suffix != null) { writer.write(suffix); } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index 5bb15c312..423fa6692 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -6,6 +6,8 @@ import java.io.OutputStreamWriter; import java.io.Writer; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + public class TextFormatUtil { static void writeLong(OutputStreamWriter writer, long value) throws IOException { @@ -61,7 +63,7 @@ static void writeLabels(OutputStreamWriter writer, Labels labels, String additio if (i > 0) { writer.write(","); } - writer.write(labels.getName(i)); + writer.write(labels.getPrometheusName(i)); writer.write("=\""); writeEscapedLabelValue(writer, labels.getValue(i)); writer.write("\""); diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 233953e00..7c9e714df 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -23,6 +23,7 @@ import io.prometheus.metrics.model.snapshots.UnknownSnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import java.io.ByteArrayOutputStream; @@ -32,6 +33,7 @@ public class ExpositionFormatsTest { private final String exemplar1String = "{env=\"prod\",span_id=\"12345\",trace_id=\"abcde\"} 1.7 1672850685.829"; private final String exemplar2String = "{env=\"dev\",span_id=\"23456\",trace_id=\"bcdef\"} 2.4 1672850685.830"; + private final String exemplarWithDotsString = "{some_exemplar_key=\"some value\"} 3.0 1690298864.383"; private final String exemplar1protoString = "exemplar { " + "label { name: \"env\" value: \"prod\" } " + @@ -47,6 +49,11 @@ public class ExpositionFormatsTest { "value: 2.4 " + "timestamp { seconds: 1672850685 nanos: 830000000 } }"; + private final String exemplarWithDotsProtoString = "exemplar { " + + "label { name: \"some_exemplar_key\" value: \"some value\" } " + + "value: 3.0 " + + "timestamp { seconds: 1690298864 nanos: 383000000 } }"; + private final String createdTimestamp1s = "1672850385.800"; private final long createdTimestamp1 = (long) (1000 * Double.parseDouble(createdTimestamp1s)); private final String createdTimestamp2s = "1672850285.000"; @@ -72,6 +79,12 @@ public class ExpositionFormatsTest { .withTimestampMillis(1672850685830L) .build(); + private final Exemplar exemplarWithDots = Exemplar.newBuilder() + .withLabels(Labels.of("some.exemplar.key", "some value")) + .withValue(3.0) + .withTimestampMillis(1690298864383L) + .build(); + @Test public void testCounterComplete() throws IOException { String openMetricsText = "" + @@ -183,6 +196,42 @@ public void testCounterMinimal() throws IOException { assertPrometheusProtobuf(prometheusProtobuf, counter); } + @Test + public void testCounterWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_request_count counter\n" + + "my_request_count_total{http_path=\"/hello\"} 3.0 # " + exemplarWithDotsString + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# TYPE my_request_count_total counter\n" + + "my_request_count_total{http_path=\"/hello\"} 3.0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_request_count_total\" " + + "type: COUNTER " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "counter { " + + "value: 3.0 " + exemplarWithDotsProtoString + " " + + "} " + + "}"; + //@formatter:on + + CounterSnapshot counter = CounterSnapshot.newBuilder() + .withName("my.request.count") + .addDataPoint(CounterDataPointSnapshot.newBuilder() + .withValue(3.0) + .withLabels(Labels.newBuilder() + .addLabel("http.path", "/hello") + .build()) + .withExemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } + @Test public void testGaugeComplete() throws IOException { String openMetricsText = "" + @@ -264,6 +313,48 @@ public void testGaugeMinimal() throws IOException { assertPrometheusProtobuf(prometheusProtobuf, gauge); } + @Test + public void testGaugeWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_temperature_celsius gauge\n" + + "# UNIT my_temperature_celsius celsius\n" + + "# HELP my_temperature_celsius Temperature\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0 # " + exemplarWithDotsString + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP my_temperature_celsius Temperature\n" + + "# TYPE my_temperature_celsius gauge\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_temperature_celsius\" " + + "help: \"Temperature\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"location_id\" value: \"data-center-1\" } " + + "gauge { " + + "value: 23.0 " + + "} " + + "}"; + //@formatter:on + + GaugeSnapshot gauge = GaugeSnapshot.newBuilder() + .withName("my.temperature.celsius") + .withHelp("Temperature") + .withUnit(Unit.CELSIUS) + .addDataPoint(GaugeDataPointSnapshot.newBuilder() + .withValue(23.0) + .withLabels(Labels.newBuilder() + .addLabel("location.id", "data-center-1") + .build()) + .withExemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertPrometheusText(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } + @Test public void testSummaryComplete() throws IOException { String openMetricsText = "" + @@ -596,6 +687,49 @@ public void testSummaryEmptyAndNonEmpty() throws IOException { assertPrometheusProtobuf(prometheusProtobuf, summary); } + @Test + public void testSummaryWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_request_duration_seconds summary\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03 # " + exemplarWithDotsString + "\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds summary\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "summary { sample_count: 1 sample_sum: 0.03 } " + + "}"; + //@formatter:on + + SummarySnapshot summary = SummarySnapshot.newBuilder() + .withName("my.request.duration.seconds") + .withHelp("Request duration in seconds") + .withUnit(Unit.SECONDS) + .addDataPoint(SummaryDataPointSnapshot.newBuilder() + .withCount(1) + .withSum(0.03) + .withLabels(Labels.newBuilder() + .addLabel("http.path", "/hello") + .build()) + .withExemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } + @Test public void testClassicHistogramComplete() throws Exception { String openMetricsText = "" + @@ -1047,6 +1181,57 @@ public void testClassicGaugeHistogramCountAndSum() throws IOException { assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); } + @Test + public void testClassicHistogramWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds histogram\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "histogram { " + + "sample_count: 130 " + + "sample_sum: 0.01 " + + "bucket { cumulative_count: 130 upper_bound: Infinity " + exemplarWithDotsProtoString + " } " + + "} " + + "}"; + //@formatter:on + + HistogramSnapshot histogram = HistogramSnapshot.newBuilder() + .withName("my.request.duration.seconds") + .withHelp("Request duration in seconds") + .withUnit(Unit.SECONDS) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withSum(0.01) + .withLabels(Labels.newBuilder() + .addLabel("http.path", "/hello") + .build()) + .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() + .addBucket(Double.POSITIVE_INFINITY, 130) + .build()) + .withExemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } + @Test public void testNativeHistogramComplete() throws IOException { String openMetricsText = "" + @@ -1244,6 +1429,64 @@ public void testNativeHistogramMinimal() throws IOException { assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); } + @Test + public void testNativeHistogramWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds histogram\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 3.2 " + + "bucket { cumulative_count: 4 upper_bound: Infinity " + exemplarWithDotsProtoString + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 2 length: 1 } " + + "positive_delta: 3 " + + "} " + + "}"; + //@formatter:on + + HistogramSnapshot histogram = HistogramSnapshot.newBuilder() + .withName("my.request.duration.seconds") + .withHelp("Request duration in seconds") + .withUnit(Unit.SECONDS) + .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withLabels(Labels.newBuilder() + .addLabel("http.path", "/hello") + .build()) + .withSum(3.2) + .withNativeSchema(5) + .withNativeZeroCount(1) + .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + .addBucket(2, 3) + .build() + ) + .withExemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } // TODO: Gauge Native Histogram @Test @@ -1270,6 +1513,39 @@ public void testInfo() throws IOException { assertPrometheusTextWithoutCreated(prometheus, info); } + @Test + public void testInfoWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE jvm_status info\n" + + "# HELP jvm_status JVM status info\n" + + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP jvm_status_info JVM status info\n" + + "# TYPE jvm_status_info gauge\n" + + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"jvm_status_info\" " + + "help: \"JVM status info\" " + + "type: GAUGE " + + "metric { " + "" + + "label { name: \"jvm_version\" value: \"1.2.3\" } " + + "gauge { value: 1.0 } " + + "}"; + //@formatter:on + InfoSnapshot info = InfoSnapshot.newBuilder() + .withName("jvm.status") + .withHelp("JVM status info") + .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of("jvm.version", "1.2.3")) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, info); + assertPrometheusText(prometheusText, info); + assertPrometheusProtobuf(prometheusProtobuf, info); + } + @Test public void testStateSetComplete() throws IOException { String openMetrics = "" + @@ -1333,6 +1609,48 @@ public void testStateSetMinimal() throws IOException { assertPrometheusTextWithoutCreated(prometheus, stateSet); } + @Test + public void testStateSetWithDots() throws IOException { + String openMetricsText = "" + + "# TYPE my_application_state stateset\n" + + "# HELP my_application_state My application state\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n" + + "# EOF\n"; + String prometheusText = "" + + "# HELP my_application_state My application state\n" + + "# TYPE my_application_state gauge\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"my_application_state\" " + + "help: \"My application state\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"data_center\" value: \"us east\" } " + + "label { name: \"my_application_state\" value: \"feature.enabled\" } " + + "gauge { value: 1.0 } " + + "} metric { " + + "label { name: \"data_center\" value: \"us east\" } " + + "label { name: \"my_application_state\" value: \"is.alpha.version\" } " + + "gauge { value: 0.0 } " + + "}"; + //@formatter:on + StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() + .withName("my.application.state") + .withHelp("My application state") + .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() + .withLabels(Labels.of("data.center", "us east")) + .addState("feature.enabled", true) + .addState("is.alpha.version", false) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, stateSet); + assertPrometheusText(prometheusText, stateSet); + assertPrometheusProtobuf(prometheusProtobuf, stateSet); + } + @Test public void testUnknownComplete() throws IOException { String openMetrics = "" + @@ -1391,6 +1709,43 @@ public void testUnknownMinimal() throws IOException { assertPrometheusTextWithoutCreated(prometheus, unknown); } + @Test + public void testUnknownWithDots() throws IOException { + String openMetrics = "" + + "# TYPE some_unknown_metric unknown\n" + + "# UNIT some_unknown_metric bytes\n" + + "# HELP some_unknown_metric help message\n" + + "some_unknown_metric{test_env=\"7\"} 0.7 # " + exemplarWithDotsString + "\n" + + "# EOF\n"; + String prometheus = "" + + "# HELP some_unknown_metric help message\n" + + "# TYPE some_unknown_metric untyped\n" + + "some_unknown_metric{test_env=\"7\"} 0.7\n"; + String prometheusProtobuf = "" + + //@formatter:off + "name: \"some_unknown_metric\" " + + "help: \"help message\" " + + "type: UNTYPED " + + "metric { " + + "label { name: \"test_env\" value: \"7\" } " + + "untyped { value: 0.7 } " + + "}"; + //@formatter:on + UnknownSnapshot unknown = UnknownSnapshot.newBuilder() + .withName("some.unknown.metric") + .withHelp("help message") + .withUnit(Unit.BYTES) + .addDataPoint(UnknownDataPointSnapshot.newBuilder() + .withValue(0.7) + .withLabels(Labels.of("test.env", "7")) + .withExemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertPrometheusText(prometheus, unknown); + assertPrometheusProtobuf(prometheusProtobuf, unknown); + } + @Test public void testHelpEscape() throws IOException { String openMetrics = "" + 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 b0fba2db1..349ebda60 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,11 +1,11 @@ package io.prometheus.metrics.model.registry; import io.prometheus.metrics.model.snapshots.MetricSnapshot; -import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import java.util.List; 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 @@ -26,7 +26,7 @@ public interface Collector { */ default MetricSnapshot collect(Predicate includedNames) { MetricSnapshot result = collect(); - if (includedNames.test(result.getMetadata().getName())) { + if (includedNames.test(result.getMetadata().getPrometheusName())) { return result; } else { return null; @@ -36,7 +36,7 @@ default MetricSnapshot collect(Predicate includedNames) { /** * Override this and return {@code null} if a collector does not have a constant name (name may change between scrapes). */ - default String getName() { - return collect().getMetadata().getName(); + default String getPrometheusName() { + return collect().getMetadata().getPrometheusName(); } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java index 3fd56e493..8e5aff15f 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -7,6 +7,8 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + /** * Like {@link Collector}, but collecting multiple Snapshots at once. */ @@ -27,7 +29,7 @@ default MetricSnapshots collect(Predicate includedNames) { MetricSnapshots allSnapshots = collect(); MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); for (MetricSnapshot snapshot : allSnapshots) { - if (includedNames.test(snapshot.getMetadata().getName())) { + if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { result.addMetricSnapshot(snapshot); } } @@ -38,7 +40,7 @@ default MetricSnapshots collect(Predicate includedNames) { * Override this and return an empty list if the MultiCollector does not return a constant list of names * (names may be added / removed between scrapes). */ - default List getNames() { - return collect().stream().map(snapshot -> snapshot.getMetadata().getName()).collect(Collectors.toList()); + default List getPrometheusNames() { + return collect().stream().map(snapshot -> snapshot.getMetadata().getPrometheusName()).collect(Collectors.toList()); } } 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 858a1b37d..373d32a89 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 @@ -9,26 +9,30 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Predicate; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + public class PrometheusRegistry { public static final PrometheusRegistry defaultRegistry = new PrometheusRegistry(); - private final Set names = ConcurrentHashMap.newKeySet(); + private final Set prometheusNames = ConcurrentHashMap.newKeySet(); private final List collectors = new CopyOnWriteArrayList<>(); private final List multiCollectors = new CopyOnWriteArrayList<>(); public void register(Collector collector) { - String name = collector.getName(); - if (!names.add(name)) { - throw new IllegalStateException("Can't register " + name + " because that name is already registered."); + 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 register(MultiCollector collector) { - for (String name : collector.getNames()) { - if (!names.add(name)) { - throw new IllegalStateException("Can't register " + name + " because that name is already registered."); + 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); @@ -36,23 +40,32 @@ public void register(MultiCollector collector) { public void unregister(Collector collector) { collectors.remove(collector); - names.remove(collector.getName()); + prometheusNames.remove(collector.getPrometheusName()); } public void unregister(MultiCollector collector) { multiCollectors.remove(collector); - for (String name : collector.getNames()) { - names.remove(name); + for (String prometheusName : collector.getPrometheusNames()) { + prometheusNames.remove(prometheusName(prometheusName)); } } public MetricSnapshots scrape() { MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); for (Collector collector : collectors) { - result.addMetricSnapshot(collector.collect()); + MetricSnapshot snapshot = collector.collect(); + if (snapshot != null) { + if (result.containsMetricName(snapshot.getMetadata().getName())) { + throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name."); + } + result.addMetricSnapshot(snapshot); + } } for (MultiCollector collector : multiCollectors) { for (MetricSnapshot snapshot : collector.collect()) { + if (result.containsMetricName(snapshot.getMetadata().getName())) { + throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name."); + } result.addMetricSnapshot(snapshot); } } @@ -65,8 +78,8 @@ public MetricSnapshots scrape(Predicate includedNames) { } MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); for (Collector collector : collectors) { - String name = collector.getName(); - if (name == null || includedNames.test(name)) { + String prometheusName = collector.getPrometheusName(); + if (prometheusName == null || includedNames.test(prometheusName)) { MetricSnapshot snapshot = collector.collect(includedNames); if (snapshot != null) { result.addMetricSnapshot(snapshot); @@ -74,10 +87,10 @@ public MetricSnapshots scrape(Predicate includedNames) { } } for (MultiCollector collector : multiCollectors) { - List names = collector.getNames(); + List prometheusNames = collector.getPrometheusNames(); boolean excluded = true; // the multi-collector is excluded unless at least one name matches - for (String name : names) { - if (includedNames.test(name)) { + for (String prometheusName : prometheusNames) { + if (includedNames.test(prometheusName)) { excluded = false; break; } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java index b49e0d121..dac311004 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -20,9 +20,6 @@ public final class InfoSnapshot extends MetricSnapshot { */ public InfoSnapshot(MetricMetadata metadata, Collection data) { super(metadata, data); - if (metadata.getName().endsWith("_info")) { - throw new IllegalArgumentException("The name of an info snapshot must not include the _info suffix"); - } if (metadata.hasUnit()) { throw new IllegalArgumentException("An Info metric cannot have a unit."); } 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 8f9d36ea4..60b1b58be 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 @@ -5,23 +5,37 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.regex.Pattern; 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. */ public class Labels implements Comparable, Iterable
    */ public class Info extends MetricWithFixedMetadata { - private final List labels = new CopyOnWriteArrayList<>(); + private final Set labels = new CopyOnWriteArraySet<>(); private Info(Builder builder) { super(builder); } + /** + * Set the info label values. This will replace any previous values, + * i.e. the info metric will only have one data point after calling setLabelValues(). + * This is good for a metric like {@code target_info} where you want only one single data point. + */ + public void setLabelValues(String... labelValues) { + if (labelValues.length != labelNames.length) { + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called setLabelValues() with " + labelValues.length + " label values."); + } + Labels newLabels = Labels.of(labelNames, labelValues); + labels.add(newLabels); + labels.retainAll(Collections.singletonList(newLabels)); + } + /** * Create an info data point with the given label values. */ - public void infoLabelValues(String... labelValues) { + public void addLabelValues(String... labelValues) { if (labelValues.length != labelNames.length) { - if (labelValues.length == 0) { - throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call withLabelValues(...) when using it."); - } else { - throw new IllegalArgumentException("Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); - } + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called addLabelValues() with " + labelValues.length + " label values."); } labels.add(Labels.of(labelNames, labelValues)); } + /** + * Remove the data point with the specified label values. + */ + public void remove(String... labelValues) { + if (labelValues.length != labelNames.length) { + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called remove() with " + labelValues.length + " label values."); + } + Labels toBeRemoved = Labels.of(labelNames, labelValues); + labels.remove(toBeRemoved); + } + /** * {@inheritDoc} */ @Override public InfoSnapshot collect() { List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(new InfoSnapshot.InfoDataPointSnapshot(labels.get(i).merge(constLabels))); + if (labelNames.length == 0) { + data.add(new InfoSnapshot.InfoDataPointSnapshot(constLabels)); + } else { + for (Labels label : labels) { + data.add(new InfoSnapshot.InfoDataPointSnapshot(label.merge(constLabels))); + } } return new InfoSnapshot(getMetadata(), data); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java index 81ff931ce..d324a2700 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java @@ -28,7 +28,7 @@ protected static abstract class Builder, M extends Metri protected final List illegalLabelNames; protected final PrometheusProperties properties; - private Labels constLabels = Labels.EMPTY; + protected Labels constLabels = Labels.EMPTY; protected Builder(List illegalLabelNames, PrometheusProperties properties) { this.illegalLabelNames = new ArrayList<>(illegalLabelNames); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 6f963c299..a1c1769d9 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -78,11 +78,23 @@ public B withLabelNames(String... labelNames) { if (illegalLabelNames.contains(labelName)) { throw new IllegalArgumentException(labelName + ": illegal label name for this metric type"); } + if (constLabels.contains(labelName)) { + throw new IllegalArgumentException(labelName + ": duplicate label name"); + } } this.labelNames = labelNames; return self(); } + public B withConstLabels(Labels constLabels) { + for (String labelName : labelNames) { + if (constLabels.contains(labelName)) { // Labels.contains() treats dots like underscores + throw new IllegalArgumentException(labelName + ": duplicate label name"); + } + } + return super.withConstLabels(constLabels); + } + @Override public abstract M build(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index a967a8d64..035f21334 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -297,4 +297,22 @@ public void testExemplarSamplerDisabled() { counter.inc(2.0); Assert.assertNull(getData(counter).getExemplar()); } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsFirst() { + Counter.newBuilder() + .withName("test_total") + .withConstLabels(Labels.of("const_a", "const_b")) + .withLabelNames("const.a") + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsSecond() { + Counter.newBuilder() + .withName("test_total") + .withLabelNames("const.a") + .withConstLabels(Labels.of("const_a", "const_b")) + .build(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 2af392097..48a3dbd52 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 5b1bbf991..c6d5b7719 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -1,10 +1,19 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import org.junit.Assert; import org.junit.Test; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + import static org.junit.Assert.assertEquals; public class InfoTest { @@ -19,10 +28,81 @@ public void testInfoStrippedFromName() { .withName(name) .withLabelNames(labelName) .build(); - info.infoLabelValues("value"); + info.addLabelValues("value"); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); assertEquals("name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }", TextFormat.printer().shortDebugString(protobufData)); } } } + + @Test + public void testAddAndRemove() throws IOException { + Info info = Info.newBuilder() + .withName("test_info") + .withLabelNames("a", "b") + .build(); + Assert.assertEquals(0, info.collect().getData().size()); + info.addLabelValues("val1", "val2"); + Assert.assertEquals(1, info.collect().getData().size()); + info.addLabelValues("val1", "val2"); // already exist, so no change + Assert.assertEquals(1, info.collect().getData().size()); + info.addLabelValues("val2", "val2"); + Assert.assertEquals(2, info.collect().getData().size()); + info.remove("val1", "val3"); // does not exist, so no change + Assert.assertEquals(2, info.collect().getData().size()); + info.remove("val1", "val2"); + Assert.assertEquals(1, info.collect().getData().size()); + info.remove("val2", "val2"); + Assert.assertEquals(0, info.collect().getData().size()); + } + + @Test + public void testSet() throws IOException { + Info info = Info.newBuilder() + .withName("target_info") + .withConstLabels(Labels.of("service.name", "test", "service.instance.id", "123")) + .withLabelNames("service.version") + .build(); + info.setLabelValues("1.0.0"); + Assert.assertEquals(1, info.collect().getData().size()); + info.setLabelValues("2.0.0"); + Assert.assertEquals(1, info.collect().getData().size()); + assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info); + } + + @Test + public void testConstLabelsOnly() throws IOException { + Info info = Info.newBuilder() + .withName("target_info") + .withConstLabels(Labels.of("service.name", "test", "service.instance.id", "123")) + .build(); + Assert.assertEquals(1, info.collect().getData().size()); + assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsDuplicate1() { + Info.newBuilder() + .withConstLabels(Labels.of("a_1", "val1")) + .withLabelNames("a.1") + .build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsDuplicate2() { + Info.newBuilder() + .withLabelNames("a_1") + .withConstLabels(Labels.of("a.1", "val1")) + .build(); + } + + private void assertTextFormat(String expected, Info info) throws IOException { + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + writer.write(outputStream, MetricSnapshots.of(info.collect())); + String result = outputStream.toString(StandardCharsets.UTF_8.name()); + if (!result.contains(expected)) { + throw new AssertionError(expected + " is not contained in the following output:\n" + result); + } + } } diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml new file mode 100644 index 000000000..6b5266962 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -0,0 +1,183 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-3-SNAPSHOT + + + prometheus-metrics-exporter-opentelemetry + bundle + + Prometheus Metrics to OpenTelemetry Exporter + + Converts Prometheus metrics to OpenTelemetry format and pushes them to an OTLP endpoint + + + + 1.28.0 + ${otel.version}-alpha + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-shaded-opentelemetry + ${project.version} + + + + + + junit + junit + 4.13.2 + test + + + + + + + src/main/resources + + + src/main/resources-filtered + true + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.0 + + + copy + package + + copy + + + + + + + io.opentelemetry + opentelemetry-api + 1.29.0 + ${project.basedir}/src/main/resources/lib/ + + + io.opentelemetry + opentelemetry-context + 1.29.0 + ${project.basedir}/src/main/resources/lib/ + + + + + + + + + diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java new file mode 100644 index 000000000..ce90e4145 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -0,0 +1,448 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.export.MetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.export.PeriodicMetricReader; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.ResourceBuilder; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class OpenTelemetryExporter { + + private OpenTelemetryExporter(Builder builder, PrometheusProperties config, PrometheusRegistry registry) { + InstrumentationScopeInfo instrumentationScopeInfo = PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); + ExporterOpenTelemetryProperties properties = config.getExporterOpenTelemetryProperties(); + Resource resource = initResourceAttributes(builder, properties, instrumentationScopeInfo); + MetricExporter exporter; + if (ConfigHelper.getProtocol(builder, properties).equals("grpc")) { + OtlpGrpcMetricExporterBuilder exporterBuilder = OtlpGrpcMetricExporter.builder() + .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) + .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); + for (Map.Entry header : ConfigHelper.getHeaders(builder, properties).entrySet()) { + exporterBuilder.addHeader(header.getKey(), header.getValue()); + } + exporter = exporterBuilder.build(); + } else { + OtlpHttpMetricExporterBuilder exporterBuilder = OtlpHttpMetricExporter.builder() + .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) + .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); + for (Map.Entry header : ConfigHelper.getHeaders(builder, properties).entrySet()) { + exporterBuilder.addHeader(header.getKey(), header.getValue()); + } + exporter = exporterBuilder.build(); + } + PeriodicMetricReader reader = PeriodicMetricReader.builder(exporter) + .setInterval(Duration.ofSeconds(ConfigHelper.getIntervalSeconds(builder, properties))) + .build(); + PrometheusMetricProducer prometheusMetricProducer = new PrometheusMetricProducer(registry, instrumentationScopeInfo, resource); + reader.register(prometheusMetricProducer); + } + + private Resource initResourceAttributes(Builder builder, ExporterOpenTelemetryProperties properties, InstrumentationScopeInfo instrumentationScopeInfo) { + String serviceName = ConfigHelper.getServiceName(builder, properties); + String serviceNamespace = ConfigHelper.getServiceNamespace(builder, properties); + String serviceInstanceId = ConfigHelper.getServiceInstanceId(builder, properties); + String serviceVersion = ConfigHelper.getServiceVersion(builder, properties); + Map resourceAttributes = ResourceAttributes.get(instrumentationScopeInfo.getName(), serviceName, serviceNamespace, serviceInstanceId, serviceVersion, ConfigHelper.getResourceAttributes(builder, properties)); + ResourceBuilder resourceBuilder = Resource.builder(); + for (Map.Entry entry : resourceAttributes.entrySet()) { + resourceBuilder.put(entry.getKey(), entry.getValue()); + } + return resourceBuilder.build(); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private PrometheusRegistry registry = null; + private String protocol; + private String endpoint; + private final Map headers = new HashMap<>(); + private Integer intervalSeconds; + private Integer timeoutSeconds; + private String serviceName; + private String serviceNamespace; + private String serviceInstanceId; + private String serviceVersion; + private final Map resourceAttributes = new HashMap<>(); + + private Builder(PrometheusProperties config) { + this.config = config; + } + + public Builder withRegistry(PrometheusRegistry registry) { + this.registry = registry; + return this; + } + + /** + * Specifies the OTLP transport protocol to be used when exporting metrics. + *

    + * Supported values are {@code "grpc"} and {@code "http/protobuf"}. Default is {@code "grpc"}. + *

    + * See OpenTelemetry's OTEL_EXPORTER_OTLP_PROTOCOL. + */ + public Builder withProtocol(String protocol) { + if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new IllegalArgumentException(protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); + } + this.protocol = protocol; + return this; + } + + /** + * The OTLP endpoint to send metric data to. + *

    + * The default depends on the protocol: + *

      + *
    • {@code "grpc"}: {@code "http://localhost:4317"}
    • + *
    • {@code "http/protobuf"}: {@code "http://localhost:4318/v1/metrics"}
    • + *
    + * If the protocol is {@code "http/protobuf"} and the endpoint does not have the {@code "/v1/metrics"} suffix, + * the {@code "/v1/metrics"} suffix will automatically be appended. + *

    + * See OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_ENDPOINT. + */ + public Builder withEndpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } + + /** + * Add an HTTP header to be applied to outgoing requests. + *

    + * See OpenTelemetry's OTEL_EXPORTER_OTLP_HEADERS. + */ + public Builder addHeader(String name, String value) { + this.headers.put(name, value); + return this; + } + + /** + * The interval between the start of two export attempts. Default is 60000. + *

    + * Like OpenTelemetry's OTEL_METRIC_EXPORT_INTERVAL, + * but in seconds rather than milliseconds. + */ + public Builder withIntervalSeconds(int intervalSeconds) { + if (intervalSeconds <= 0) { + throw new IllegalStateException(intervalSeconds + ": expecting a push interval > 0s"); + } + this.intervalSeconds = intervalSeconds; + return this; + } + + /** + * The timeout for outgoing requests. Default is 10. + *

    + * Like OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, + * but in seconds rather than milliseconds. + */ + public Builder withTimeoutSeconds(int timeoutSeconds) { + if (timeoutSeconds <= 0) { + throw new IllegalStateException(timeoutSeconds + ": expecting a push interval > 0s"); + } + this.timeoutSeconds = timeoutSeconds; + return this; + } + + /** + * The {@code service.name} resource attribute. + *

    + * If not explicitly specified, {@code client_java} will try to initialize it with a reasonable default, like the JAR file name. + *

    + * See {@code service.name} in OpenTelemetry's Resource Semantic Conventions. + */ + public Builder withServiceName(String serviceName) { + this.serviceName = serviceName; + return this; + } + + /** + * The {@code service.namespace} resource attribute. + *

    + * See {@code service.namespace} in OpenTelemetry's Resource Semantic Conventions. + */ + public Builder withServiceNamespace(String serviceNamespace) { + this.serviceNamespace = serviceNamespace; + return this; + } + + /** + * The {@code service.instance.id} resource attribute. + *

    + * See {@code service.instance.id} in OpenTelemetry's Resource Semantic Conventions. + */ + public Builder withServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + return this; + } + + /** + * The {@code service.version} resource attribute. + *

    + * See {@code service.version} in OpenTelemetry's Resource Semantic Conventions. + */ + public Builder withServiceVersion(String serviceVersion) { + this.serviceVersion = serviceVersion; + return this; + } + + /** + * Add a resource attribute. + *

    + * See OpenTelemetry's OTEL_RESOURCE_ATTRIBUTES. + */ + public Builder addResourceAttribute(String name, String value) { + this.resourceAttributes.put(name, value); + return this; + } + + public OpenTelemetryExporter buildAndStart() { + if (registry == null) { + registry = PrometheusRegistry.defaultRegistry; + } + return new OpenTelemetryExporter(this, config, registry); + } + } + + private static class ConfigHelper { + + private static String getProtocol(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String protocol = config.getProtocol(); + if (protocol != null) { + return protocol; + } + protocol = getString("otel.exporter.otlp.protocol"); + if (protocol != null) { + if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new IllegalStateException(protocol + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf."); + } + return protocol; + } + if (builder.protocol != null) { + return builder.protocol; + } + return "grpc"; + } + + private static String getEndpoint(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String endpoint = config.getEndpoint(); + if (endpoint == null) { + endpoint = getString("otel.exporter.otlp.metrics.endpoint"); + } + if (endpoint == null) { + endpoint = getString("otel.exporter.otlp.endpoint"); + } + if (endpoint == null) { + endpoint = builder.endpoint; + } + if (endpoint == null) { + if (getProtocol(builder, config).equals("grpc")) { + endpoint = "http://localhost:4317"; + } else { // http/protobuf + endpoint = "http://localhost:4318/v1/metrics"; + } + } + if (getProtocol(builder, config).equals("grpc")) { + return endpoint; + } else { // http/protobuf + if (!endpoint.endsWith("v1/metrics")) { + if (!endpoint.endsWith("/")) { + return endpoint + "/v1/metrics"; + } else { + return endpoint + "v1/metrics"; + } + } else { + return endpoint; + } + } + } + + private static Map getHeaders(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Map headers = config.getHeaders(); + if (!headers.isEmpty()) { + return headers; + } + headers = getMap("otel.exporter.otlp.headers"); + if (!headers.isEmpty()) { + return headers; + } + if (!builder.headers.isEmpty()) { + return builder.headers; + } + return new HashMap<>(); + } + + private static int getIntervalSeconds(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Integer intervalSeconds = config.getIntervalSeconds(); + if (intervalSeconds != null) { + return intervalSeconds; + } + intervalSeconds = getPositiveInteger("otel.metric.export.interval"); + if (intervalSeconds != null) { + return (int) TimeUnit.MILLISECONDS.toSeconds(intervalSeconds); + } + if (builder.intervalSeconds != null) { + return builder.intervalSeconds; + } + return 60; + } + + private static int getTimeoutSeconds(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Integer timeoutSeconds = config.getTimeoutSeconds(); + if (timeoutSeconds != null) { + return timeoutSeconds; + } + Integer timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.metrics.timeout"); + if (timeoutMilliseconds == null) { + timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.timeout"); + } + if (timeoutMilliseconds != null) { + return (int) TimeUnit.MILLISECONDS.toSeconds(timeoutMilliseconds); + } + if (builder.timeoutSeconds != null) { + return builder.timeoutSeconds; + } + return 10; + } + + private static String getServiceName(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceName = config.getServiceName(); + if (serviceName != null) { + return serviceName; + } + serviceName = getString("otel.service.name"); + if (serviceName != null) { + return serviceName; + } + if (builder.serviceName != null) { + return builder.serviceName; + } + return null; + } + + private static String getServiceNamespace(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceNamespace = config.getServiceNamespace(); + if (serviceNamespace != null) { + return serviceNamespace; + } + if (builder.serviceNamespace != null) { + return builder.serviceNamespace; + } + return null; + } + + private static String getServiceInstanceId(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceInstanceId = config.getServiceInstanceId(); + if (serviceInstanceId != null) { + return serviceInstanceId; + } + if (builder.serviceInstanceId != null) { + return builder.serviceInstanceId; + } + return null; + } + + private static String getServiceVersion(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceVersion = config.getServiceVersion(); + if (serviceVersion != null) { + return serviceVersion; + } + if (builder.serviceVersion != null) { + return builder.serviceVersion; + } + return null; + } + + private static Map getResourceAttributes(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Map resourceAttributes = config.getResourceAttributes(); + if (!resourceAttributes.isEmpty()) { + return resourceAttributes; + } + resourceAttributes = getMap("otel.resource.attributes"); + if (!resourceAttributes.isEmpty()) { + return resourceAttributes; + } + if (!builder.resourceAttributes.isEmpty()) { + return builder.resourceAttributes; + } + return new HashMap<>(); + } + + private static String getString(String otelPropertyName) { + String otelEnvVarName = otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(); + if (System.getenv(otelEnvVarName) != null) { + return System.getenv(otelEnvVarName); + } + if (System.getProperty(otelPropertyName) != null) { + return System.getProperty(otelPropertyName); + } + return null; + } + + private static Integer getInteger(String otelPropertyName) { + String result = getString(otelPropertyName); + if (result == null) { + return null; + } else { + try { + return Integer.parseInt(result); + } catch (NumberFormatException e) { + throw new IllegalStateException(otelPropertyName + "=" + result + " - illegal value."); + } + } + } + + private static Integer getPositiveInteger(String otelPropertyName) { + Integer result = getInteger(otelPropertyName); + if (result == null) { + return null; + } + if (result <= 0) { + throw new IllegalStateException(otelPropertyName + "=" + result + ": Expecting value > 0."); + } + return result; + } + + private static Map getMap(String otelPropertyName) { + Map result = new HashMap<>(); + String property = getString(otelPropertyName); + if (property != null) { + String[] pairs = property.split(","); + for (String pair : pairs) { + if (pair.contains("=")) { + String[] keyValue = pair.split("=", 1); + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + if (key.length() > 0 && value.length() > 0) { + result.putIfAbsent(key, value); + } + } + } + } + } + return result; + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java new file mode 100644 index 000000000..1f38e66e2 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo; + +import java.util.Properties; + +class PrometheusInstrumentationScope { + + private static final String instrumentationScopePropertiesFile = "instrumentationScope.properties"; + private static final String instrumentationScopeNameKey = "instrumentationScope.name"; + private static final String instrumentationScopeVersionKey = "instrumentationScope.version"; + + public static InstrumentationScopeInfo loadInstrumentationScopeInfo() { + try { + Properties properties = new Properties(); + properties.load(PrometheusInstrumentationScope.class.getClassLoader().getResourceAsStream(instrumentationScopePropertiesFile)); + String instrumentationScopeName = properties.getProperty(instrumentationScopeNameKey); + if (instrumentationScopeName == null) { + throw new IllegalStateException("Prometheus metrics library initialization error: " + instrumentationScopeNameKey + " not found in " + instrumentationScopePropertiesFile + " in classpath."); + } + String instrumentationScopeVersion = properties.getProperty(instrumentationScopeVersionKey); + if (instrumentationScopeVersion == null) { + throw new IllegalStateException("Prometheus metrics library initialization error: " + instrumentationScopeVersionKey + " not found in " + instrumentationScopePropertiesFile + " in classpath."); + } + return InstrumentationScopeInfo.builder(instrumentationScopeName) + .setVersion(instrumentationScopeVersion) + .build(); + } catch (Exception e) { + throw new IllegalStateException("Prometheus metrics library initialization error: Failed to read " + instrumentationScopePropertiesFile + " from classpath.", e); + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java new file mode 100644 index 000000000..762060efc --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -0,0 +1,124 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.prometheus.metrics.exporter.opentelemetry.otelmodel.MetricDataFactory; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.internal.export.MetricProducer; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.ResourceBuilder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +class PrometheusMetricProducer implements MetricProducer { + + private final PrometheusRegistry registry; + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; + + public PrometheusMetricProducer(PrometheusRegistry registry, InstrumentationScopeInfo instrumentationScopeInfo, Resource resource) { + this.registry = registry; + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.resource = resource; + } + + @Override + public Collection collectAllMetrics() { + // TODO: We could add a filter configuration for the OpenTelemetry exporter and call registry.scrape(filter) if a filter is configured, like in the Servlet exporter. + MetricSnapshots snapshots = registry.scrape(); + Resource resourceWithTargetInfo = resource.merge(resourceFromTargetInfo(snapshots)); + InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOTelScopeInfo(snapshots); + List result = new ArrayList<>(snapshots.size()); + MetricDataFactory factory = new MetricDataFactory(resourceWithTargetInfo, scopeFromInfo != null ? scopeFromInfo : instrumentationScopeInfo, System.currentTimeMillis()); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot instanceof CounterSnapshot) { + addUnlessNull(result, factory.create((CounterSnapshot) snapshot)); + } else if (snapshot instanceof GaugeSnapshot) { + addUnlessNull(result, factory.create((GaugeSnapshot) snapshot)); + } else if (snapshot instanceof HistogramSnapshot) { + if (!((HistogramSnapshot) snapshot).isGaugeHistogram()) { + addUnlessNull(result, factory.create((HistogramSnapshot) snapshot)); + } + } else if (snapshot instanceof SummarySnapshot) { + addUnlessNull(result, factory.create((SummarySnapshot) snapshot)); + } else if (snapshot instanceof InfoSnapshot) { + String name = snapshot.getMetadata().getPrometheusName(); + if (!name.equals("target") && !name.equals("otel_scope")) { + addUnlessNull(result, factory.create((InfoSnapshot) snapshot)); + } + } else if (snapshot instanceof StateSetSnapshot) { + addUnlessNull(result, factory.create((StateSetSnapshot) snapshot)); + } else if (snapshot instanceof UnknownSnapshot) { + addUnlessNull(result, factory.create((UnknownSnapshot) snapshot)); + } + } + return result; + } + + private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { + ResourceBuilder result = Resource.builder(); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) { + InfoSnapshot targetInfo = (InfoSnapshot) snapshot; + if (targetInfo.getData().size() > 0) { + InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getData().get(0); + Labels labels = data.getLabels(); + for (int i = 0; i < labels.size(); i++) { + result.put(labels.getName(i), labels.getValue(i)); + } + } + } + } + return result.build(); + } + + private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo(MetricSnapshots snapshots) { + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") && snapshot instanceof InfoSnapshot) { + InfoSnapshot scopeInfo = (InfoSnapshot) snapshot; + if (scopeInfo.getData().size() > 0) { + Labels labels = scopeInfo.getData().get(0).getLabels(); + String name = null; + String version = null; + AttributesBuilder attributesBuilder = Attributes.builder(); + for (int i = 0; i < labels.size(); i++) { + if (labels.getPrometheusName(i).equals("otel_scope_name")) { + name = labels.getValue(i); + } else if (labels.getPrometheusName(i).equals("otel_scope_version")) { + version = labels.getValue(i); + } else { + attributesBuilder.put(labels.getName(i), labels.getValue(i)); + } + } + if (name != null) { + return InstrumentationScopeInfo.builder(name) + .setVersion(version) + .setAttributes(attributesBuilder.build()) + .build(); + } + } + } + } + return null; + } + + private void addUnlessNull(List result, MetricData data) { + if (data != null) { + result.add(data); + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java new file mode 100644 index 000000000..c4319b7fc --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java @@ -0,0 +1,34 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import java.util.HashMap; +import java.util.Map; + +public class ResourceAttributes { + + // TODO: The OTel Java instrumentation also has a SpringBootServiceNameDetector, we should port this over. + public static Map get(String instrumentationScopeName, + String serviceName, + String serviceNamespace, + String serviceInstanceId, + String serviceVersion, + Map configuredResourceAttributes) { + Map result = new HashMap<>(); + ResourceAttributesFromOtelAgent.addIfAbsent(result, instrumentationScopeName); + putIfAbsent(result, "service.name", serviceName); + putIfAbsent(result, "service.namespace", serviceNamespace); + putIfAbsent(result, "service.instance.id", serviceInstanceId); + putIfAbsent(result, "service.version", serviceVersion); + for (Map.Entry attribute : configuredResourceAttributes.entrySet()) { + putIfAbsent(result, attribute.getKey(), attribute.getValue()); + } + ResourceAttributesFromJarFileName.addIfAbsent(result); + ResourceAttributesDefaults.addIfAbsent(result); + return result; + } + + private static void putIfAbsent(Map result, String key, String value) { + if (value != null) { + result.putIfAbsent(key, value); + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java new file mode 100644 index 000000000..053c2b53a --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java @@ -0,0 +1,10 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import java.util.Map; + +public class ResourceAttributesDefaults { + + public static void addIfAbsent(Map result) { + result.putIfAbsent("service.name", "unknown_service:java"); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java new file mode 100644 index 000000000..093b3b44d --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java @@ -0,0 +1,60 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +// See io.opentelemetry.instrumentation.resources.JarServiceNameDetector +public class ResourceAttributesFromJarFileName { + + public static void addIfAbsent(Map result) { + if (result.containsKey("service.name")) { + return; + } + Path jarPath = getJarPathFromSunCommandLine(); + if (jarPath == null) { + return; + } + String serviceName = getServiceName(jarPath); + result.putIfAbsent("service.name", serviceName); + } + + private static Path getJarPathFromSunCommandLine() { + String programArguments = System.getProperty("sun.java.command"); + if (programArguments == null) { + return null; + } + // Take the path until the first space. If the path doesn't exist extend it up to the next + // space. Repeat until a path that exists is found or input runs out. + int next = 0; + while (true) { + int nextSpace = programArguments.indexOf(' ', next); + if (nextSpace == -1) { + return pathIfExists(programArguments); + } + Path path = pathIfExists(programArguments.substring(0, nextSpace)); + next = nextSpace + 1; + if (path != null) { + return path; + } + } + } + + private static Path pathIfExists(String programArguments) { + Path candidate; + try { + candidate = Paths.get(programArguments); + } catch (InvalidPathException e) { + return null; + } + return Files.isRegularFile(candidate) ? candidate : null; + } + + private static String getServiceName(Path jarPath) { + String jarName = jarPath.getFileName().toString(); + int dotIndex = jarName.lastIndexOf("."); + return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java new file mode 100644 index 000000000..fcf6e0ba0 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java @@ -0,0 +1,87 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.Map; + +import static java.nio.file.Files.createTempDirectory; + +public class ResourceAttributesFromOtelAgent { + + private static final String[] OTEL_JARS = new String[]{"opentelemetry-api-1.29.0.jar", "opentelemetry-context-1.29.0.jar"}; + + public static void addIfAbsent(Map result, String instrumentationScopeName) { + try { + Path tmpDir = createTempDirectory(instrumentationScopeName + "-"); + try { + URL[] otelJars = copyOtelJarsToTempDir(tmpDir, instrumentationScopeName); + + try (URLClassLoader classLoader = new URLClassLoader(otelJars)) { + Class globalOpenTelemetryClass = classLoader.loadClass("io.opentelemetry.api.GlobalOpenTelemetry"); + Object globalOpenTelemetry = globalOpenTelemetryClass.getMethod("get").invoke(null); + if (globalOpenTelemetry.getClass().getSimpleName().contains("ApplicationOpenTelemetry")) { + // GlobalOpenTelemetry is injected by the OTel Java aqent + Object applicationMeterProvider = callMethod("getMeterProvider", globalOpenTelemetry); + Object agentMeterProvider = getField("agentMeterProvider", applicationMeterProvider); + Object sdkMeterProvider = getField("delegate", agentMeterProvider); + Object sharedState = getField("sharedState", sdkMeterProvider); + Object resource = callMethod("getResource", sharedState); + Object attributes = callMethod("getAttributes", resource); + Map attributeMap = (Map) callMethod("asMap", attributes); + + for (Map.Entry entry : attributeMap.entrySet()) { + if (entry.getKey() != null && entry.getValue() != null) { + result.putIfAbsent(entry.getKey().toString(), entry.getValue().toString()); + } + } + } + } + } finally { + deleteTempDir(tmpDir.toFile()); + } + } catch (Exception ignored) { + } + } + + private static Object getField(String name, Object obj) throws Exception { + Field field = obj.getClass().getDeclaredField(name); + field.setAccessible(true); + return field.get(obj); + } + + private static Object callMethod(String name, Object obj) throws Exception { + Method method = obj.getClass().getMethod(name); + method.setAccessible(true); + return method.invoke(obj); + } + + private static URL[] copyOtelJarsToTempDir(Path tmpDir, String instrumentationScopeName) throws Exception { + URL[] result = new URL[OTEL_JARS.length]; + for (int i = 0; i < OTEL_JARS.length; i++) { + InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("lib/" + OTEL_JARS[i]); + if (inputStream == null) { + throw new IllegalStateException("Error initializing " + instrumentationScopeName + ": lib/" + OTEL_JARS[i] + " not found in classpath."); + } + File outputFile = tmpDir.resolve(OTEL_JARS[i]).toFile(); + Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + inputStream.close(); + result[i] = outputFile.toURI().toURL(); + } + return result; + } + + private static void deleteTempDir(File tmpDir) { + // We don't have subdirectories, so this simple implementation should work. + for (File file : tmpDir.listFiles()) { + file.delete(); + } + tmpDir.delete(); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java new file mode 100644 index 000000000..6c93f74e7 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java @@ -0,0 +1,22 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData; + +import java.util.List; + +class DoublePointDataImpl extends PointDataImpl implements DoublePointData { + + private final double value; + + public DoublePointDataImpl(double value, long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.value = value; + } + + @Override + public double getValue() { + return value; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java new file mode 100644 index 000000000..d365c26fb --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java @@ -0,0 +1,46 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets; + +import java.util.ArrayList; +import java.util.List; + +class ExponentialHistogramBucketsImpl implements ExponentialHistogramBuckets { + + private final int scale; + private final int offset; + private final List bucketCounts = new ArrayList<>(); + + ExponentialHistogramBucketsImpl(int scale, int offset) { + this.scale = scale; + this.offset = offset; + } + + void addCount(long count) { + bucketCounts.add(count); + } + + @Override + public int getScale() { + return scale; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public List getBucketCounts() { + return bucketCounts; + } + + @Override + public long getTotalCount() { + long result = 0; + for (Long count : bucketCounts) { + result += count; + } + return result; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java new file mode 100644 index 000000000..86d56d2d7 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java @@ -0,0 +1,85 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramPointData; + +import java.util.List; + +public class ExponentialHistogramPointDataImpl extends PointDataImpl implements ExponentialHistogramPointData { + + private final int scale; + private final double sum; + private final long count; + private final long zeroCount; + private final double min; + private final double max; + + private final ExponentialHistogramBuckets positiveBuckets; + private final ExponentialHistogramBuckets negativeBuckets; + + ExponentialHistogramPointDataImpl(int scale, double sum, long count, long zeroCount, double min, double max, + ExponentialHistogramBuckets positiveBuckets, ExponentialHistogramBuckets negativeBuckets, + long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.scale = scale; + this.sum = sum; + this.count = count; + this.zeroCount = zeroCount; + this.min = min; + this.max = max; + this.positiveBuckets = positiveBuckets; + this.negativeBuckets = negativeBuckets; + } + + @Override + public int getScale() { + return scale; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public long getCount() { + return count; + } + + @Override + public long getZeroCount() { + return zeroCount; + } + + @Override + public boolean hasMin() { + return !Double.isNaN(min); + } + + @Override + public double getMin() { + return min; + } + + @Override + public boolean hasMax() { + return !Double.isNaN(max); + } + + @Override + public double getMax() { + return max; + } + + @Override + public ExponentialHistogramBuckets getPositiveBuckets() { + return positiveBuckets; + } + + @Override + public ExponentialHistogramBuckets getNegativeBuckets() { + return negativeBuckets; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java new file mode 100644 index 000000000..7908bee2b --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java @@ -0,0 +1,68 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramPointData; + +import java.util.List; + +public class HistogramPointDataImpl extends PointDataImpl implements HistogramPointData { + + private final double sum; + private final long count; + private final double min; + private final double max; + private final List boundaries; + private final List counts; + + public HistogramPointDataImpl(double sum, long count, double min, double max, List boundaries, List counts, + long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.sum = sum; + this.count = count; + this.min = min; + this.max = max; + this.boundaries = boundaries; + this.counts = counts; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public long getCount() { + return count; + } + + @Override + public boolean hasMin() { + return !Double.isNaN(min); + } + + @Override + public double getMin() { + return min; + } + + @Override + public boolean hasMax() { + return !Double.isNaN(max); + } + + @Override + public double getMax() { + return max; + } + + @Override + public List getBoundaries() { + return boundaries; + } + + @Override + public List getCounts() { + return counts; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java new file mode 100644 index 000000000..3e30c4a6a --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -0,0 +1,61 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource; + +public class MetricDataFactory { + + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; + private final long currentTimeMillis; + + public MetricDataFactory(Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, long currentTimeMillis) { + this.resource = resource; + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.currentTimeMillis = currentTimeMillis; + } + + public MetricData create(CounterSnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusCounter(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + + public MetricData create(GaugeSnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusGauge(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + + public MetricData create(HistogramSnapshot snapshot) { + if (!snapshot.getData().isEmpty()) { + HistogramSnapshot.HistogramDataPointSnapshot firstDataPoint = snapshot.getData().get(0); + if (firstDataPoint.hasNativeHistogramData()) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusNativeHistogram(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } else if (firstDataPoint.hasClassicHistogramData()) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusClassicHistogram(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + } + return null; + } + + public MetricData create(SummarySnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusSummary(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + + public MetricData create(InfoSnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusInfo(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + + public MetricData create(StateSetSnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusStateSet(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } + + public MetricData create(UnknownSnapshot snapshot) { + return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusUnknown(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java new file mode 100644 index 000000000..a0b4aed83 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java @@ -0,0 +1,43 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.PointData; + +import java.util.List; + +abstract class PointDataImpl implements PointData { + + private final long startEpochNanos; + private final long epochNanos; + private final Attributes attributes; + private final List exemplars; + + PointDataImpl(long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.exemplars = exemplars; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public List getExemplars() { + return exemplars; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java new file mode 100644 index 000000000..a6d4d3830 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -0,0 +1,80 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +class PrometheusClassicHistogram extends PrometheusData implements HistogramData { + + private final List points; + + PrometheusClassicHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.HISTOGRAM); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private HistogramPointData toOtelDataPoint(HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { + if (!dataPoint.hasClassicHistogramData()) { + return null; + } else { + return new HistogramPointDataImpl( + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() ? dataPoint.getCount() : calculateCount(dataPoint.getClassicBuckets()), + Double.NaN, + Double.NaN, + makeBoundaries(dataPoint.getClassicBuckets()), + makeCounts(dataPoint.getClassicBuckets()), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars()) + ); + } + } + + private long calculateCount(ClassicHistogramBuckets buckets) { + int result = 0; + for (int i=0; i makeBoundaries(ClassicHistogramBuckets buckets) { + List result = new ArrayList<>(buckets.size()); + for (int i=0; i makeCounts(ClassicHistogramBuckets buckets) { + List result = new ArrayList<>(buckets.size()); + for (int i=0; i implements SumData { + + private final List points; + + public PrometheusCounter(CounterSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public boolean isMonotonic() { + return true; + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint(CounterSnapshot.CounterDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar()) + ); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java new file mode 100644 index 000000000..353a1623c --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -0,0 +1,58 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.Data; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.PointData; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Labels; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +abstract class PrometheusData implements Data { + + private final MetricDataType type; + + public PrometheusData(MetricDataType type) { + this.type = type; + } + + public MetricDataType getType() { + return type; + } + + protected Attributes labelsToAttributes(Labels labels) { + if (labels.isEmpty()) { + return Attributes.empty(); + } else { + AttributesBuilder builder = Attributes.builder(); + for (int i=0; i convertExemplar(Exemplar exemplar) { + return convertExemplars(Exemplars.of(exemplar)); + } + + protected List convertExemplars(Exemplars exemplars) { + // TODO: Exemplars not implemented yet. + return Collections.emptyList(); + } + + protected long getStartEpochNanos(DataPointSnapshot dataPoint) { + return dataPoint.hasCreatedTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getCreatedTimestampMillis()) : 0L; + } + + protected long getEpochNanos(DataPointSnapshot dataPoint, long currentTimeMillis) { + return dataPoint.hasScrapeTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getScrapeTimestampMillis()) : TimeUnit.MILLISECONDS.toNanos(currentTimeMillis); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java new file mode 100644 index 000000000..16c307059 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -0,0 +1,38 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +class PrometheusGauge extends PrometheusData implements GaugeData { + + private final List points; + + public PrometheusGauge(GaugeSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_GAUGE); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint(GaugeSnapshot.GaugeDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar()) + ); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java new file mode 100644 index 000000000..0dce35fa6 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -0,0 +1,49 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class PrometheusInfo extends PrometheusData implements SumData { + + private final List points; + + public PrometheusInfo(InfoSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public boolean isMonotonic() { + return false; + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint(InfoSnapshot.InfoDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + 1.0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + Collections.emptyList() + ); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java new file mode 100644 index 000000000..ddf2160d0 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -0,0 +1,135 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; +import io.prometheus.metrics.model.snapshots.Unit; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource; + +class PrometheusMetricData> implements MetricData { + + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; + private final String name; + private final String description; + private final String unit; + T data; + + PrometheusMetricData(MetricMetadata metricMetadata, T data, InstrumentationScopeInfo instrumentationScopeInfo, Resource resource) { + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.resource = resource; + this.name = getNameWithoutUnit(metricMetadata); + this.description = metricMetadata.getHelp(); + this.unit = convertUnit(metricMetadata.getUnit()); + this.data = data; + } + + // In OpenTelemetry the unit should not be part of the metric name. + private String getNameWithoutUnit(MetricMetadata metricMetadata) { + String name = metricMetadata.getName(); + if (metricMetadata.getUnit() != null) { + String unit = metricMetadata.getUnit().toString(); + if (name.endsWith(unit)) { + name = name.substring(0, name.length() - unit.length()); + } + while (name.endsWith("_")) { + name = name.substring(0, name.length()-1); + } + } + return name; + } + + // See https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/6cf4dec6cb42d87d8840e9f67d4acf66d4eb8fda/pkg/translator/prometheus/normalize_name.go#L19 + private String convertUnit(Unit unit) { + if (unit == null) { + return null; + } + switch (unit.toString()) { + // Time + case "days": return "d"; + case "hours": return "h"; + case "minutes": return "min"; + case "seconds": return "s"; + case "milliseconds": return "ms"; + case "microseconds": return "us"; + case "nanoseconds": return "ns"; + // Bytes + case "bytes": return "By"; + case "kibibytes": return "KiBy"; + case "mebibytes": return "MiBy"; + case "gibibytes": return "GiBy"; + case "tibibytes": return "TiBy"; + case "kilobytes": return "KBy"; + case "megabytes": return "MBy"; + case "gigabytes": return "GBy"; + case "terabytes": return "TBy"; + // SI + case "meters": return "m"; + case "volts": return "V"; + case "amperes": return "A"; + case "joules": return "J"; + case "watts": return "W"; + case "grams": return "g"; + // Misc + case "celsius": return "Cel"; + case "hertz": return "Hz"; + case "percent": return "%"; + // default + default: + return unit.toString(); + } + } + + @Override + public Resource getResource() { + return resource; + } + + @Override + public InstrumentationScopeInfo getInstrumentationScopeInfo() { + return instrumentationScopeInfo; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getUnit() { + return unit; + } + + @Override + public MetricDataType getType() { + return data.getType(); + } + + @Override + public T getData() { + return data; + } + + @Override + public SumData getDoubleSumData() { + if (data instanceof PrometheusCounter) { + return (PrometheusCounter) data; + } + if (data instanceof PrometheusStateSet) { + return (PrometheusStateSet) data; + } + if (data instanceof PrometheusInfo) { + return (PrometheusInfo) data; + } + return MetricData.super.getDoubleSumData(); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java new file mode 100644 index 000000000..7584949f6 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -0,0 +1,87 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +class PrometheusNativeHistogram extends PrometheusData implements ExponentialHistogramData { + + private final List points; + + PrometheusNativeHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.EXPONENTIAL_HISTOGRAM); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private ExponentialHistogramPointData toOtelDataPoint(HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { + if (!dataPoint.hasNativeHistogramData()) { + return null; + } + return new ExponentialHistogramPointDataImpl( + dataPoint.getNativeSchema(), + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() ? dataPoint.getCount() : calculateCount(dataPoint), + dataPoint.getNativeZeroCount(), + Double.NaN, + Double.NaN, + convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForPositiveValues()), + convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForNegativeValues()), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars()) + ); + } + + private ExponentialHistogramBuckets convertBuckets(int scale, NativeHistogramBuckets buckets) { + if (buckets.size() == 0) { + return new ExponentialHistogramBucketsImpl(scale, 0); + } + int offset = buckets.getBucketIndex(0); + ExponentialHistogramBucketsImpl result = new ExponentialHistogramBucketsImpl(scale, offset-1); + int currentBucket = 0; + for (int i=offset; i<=buckets.getBucketIndex(buckets.size()-1); i++) { + if (buckets.getBucketIndex(currentBucket) == i) { + result.addCount(buckets.getCount(currentBucket)); + currentBucket++; + } else { + result.addCount(0); + } + } + return result; + } + + private long calculateCount(HistogramSnapshot.HistogramDataPointSnapshot dataPoint) { + long result = 0L; + for (int i=0; i implements SumData { + + private final List points; + public PrometheusStateSet(StateSetSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = new ArrayList<>(); + for (StateSetSnapshot.StateSetDataPointSnapshot dataPoint : snapshot.getData()) { + for (int i=0; i getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint(StateSetSnapshot snapshot, StateSetSnapshot.StateSetDataPointSnapshot dataPoint, int i, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.isTrue(i) ? 1.0 : 0.0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels().merge(Labels.of(snapshot.getMetadata().getName(), dataPoint.getName(i)))), + Collections.emptyList() + ); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java new file mode 100644 index 000000000..9b2f53c12 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java @@ -0,0 +1,43 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryPointData; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +class PrometheusSummary extends PrometheusData implements SummaryData { + + private final List points; + + PrometheusSummary(SummarySnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.SUMMARY); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public Collection getPoints() { + return points; + } + + private SummaryPointData toOtelDataPoint(SummarySnapshot.SummaryDataPointSnapshot dataPoint, long currentTimeMillis) { + SummaryPointDataImpl result = new SummaryPointDataImpl( + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() ? dataPoint.getCount() : 0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars()) + ); + for (Quantile quantile : dataPoint.getQuantiles()) { + result.addValue(quantile.getQuantile(), quantile.getValue()); + } + return result; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java new file mode 100644 index 000000000..930715492 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -0,0 +1,37 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +class PrometheusUnknown extends PrometheusData implements GaugeData { + + private final List points; + + public PrometheusUnknown(UnknownSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_GAUGE); + this.points = snapshot.getData().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint(UnknownSnapshot.UnknownDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar()) + ); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java new file mode 100644 index 000000000..0e9c61c1f --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java @@ -0,0 +1,41 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ValueAtQuantile; + +import java.util.ArrayList; +import java.util.List; + +public class SummaryPointDataImpl extends PointDataImpl implements SummaryPointData { + private final double sum; + private final long count; + private final List values; + + public SummaryPointDataImpl(double sum, long count, long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.sum = sum; + this.count = count; + this.values = new ArrayList<>(); + } + + void addValue(double quantile, double value) { + values.add(new ValueAtQuantileImpl(quantile, value)); + } + + @Override + public long getCount() { + return count; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public List getValues() { + return values; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java new file mode 100644 index 000000000..fafc2be77 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java @@ -0,0 +1,24 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ValueAtQuantile; + +public class ValueAtQuantileImpl implements ValueAtQuantile { + + private final double quantile; + private final double value; + + public ValueAtQuantileImpl(double quantile, double value) { + this.quantile = quantile; + this.value = value; + } + + @Override + public double getQuantile() { + return quantile; + } + + @Override + public double getValue() { + return value; + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/resources-filtered/instrumentationScope.properties b/prometheus-metrics-exporter-opentelemetry/src/main/resources-filtered/instrumentationScope.properties new file mode 100644 index 000000000..f5d86ba1f --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/resources-filtered/instrumentationScope.properties @@ -0,0 +1,3 @@ +# Variables will be replaced by Maven at build time when this file is copied to the target/ directory. +instrumentationScope.name=${project.artifactId} +instrumentationScope.version=${project.version} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/resources/lib/.gitignore b/prometheus-metrics-exporter-opentelemetry/src/main/resources/lib/.gitignore new file mode 100644 index 000000000..d392f0e82 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/resources/lib/.gitignore @@ -0,0 +1 @@ +*.jar diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index e61d58055..24a9f8dff 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -13,4 +13,4 @@ curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/pro sed -i "s/java_package = \"io.prometheus.client\"/java_package = \"io.prometheus.metrics.expositionformats.generated.com_google_protobuf_${PROTOBUF_VERSION_STRING}\"/" src/main/protobuf/metrics.proto rm -rf src/main/generated/* protoc --java_out src/main/generated src/main/protobuf/metrics.proto -sed -i "s/com\\.google\\.protobuf/io.prometheus.com_google_protobuf_${PROTOBUF_VERSION_STRING}/g" "src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_${PROTOBUF_VERSION_STRING}/Metrics.java" +sed -i "s/com\\.google\\.protobuf/io.prometheus.metrics.shaded.com_google_protobuf_${PROTOBUF_VERSION_STRING}/g" "src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_${PROTOBUF_VERSION_STRING}/Metrics.java" diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 7b50b05ee..a8eef2c7a 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -45,8 +45,8 @@ io.prometheus - protobuf-shaded - 1.0.0-alpha-1 + prometheus-metrics-shaded-protobuf + ${project.version} diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java index 94e92a1f3..d66bf16a8 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java @@ -6,19 +6,19 @@ public final class Metrics { private Metrics() {} public static void registerAllExtensions( - io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite registry) { + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite registry) { } public static void registerAllExtensions( - io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistry registry) { + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistry registry) { registerAllExtensions( - (io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite) registry); + (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite) registry); } /** * Protobuf enum {@code io.prometheus.client.MetricType} */ public enum MetricType - implements io.prometheus.metrics.com_google_protobuf_3_21_7.ProtocolMessageEnum { + implements io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ProtocolMessageEnum { /** *

          * COUNTER must use the Metric field "counter".
    @@ -149,27 +149,27 @@ public static MetricType forNumber(int value) {
           }
         }
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap
             internalGetValueMap() {
           return internalValueMap;
         }
    -    private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap<
    +    private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap<
             MetricType> internalValueMap =
    -          new io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.EnumLiteMap() {
    +          new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap() {
                 public MetricType findValueByNumber(int number) {
                   return MetricType.forNumber(number);
                 }
               };
     
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor
    +    public final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor
             getValueDescriptor() {
           return getDescriptor().getValues().get(ordinal());
         }
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
    +    public final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
             getDescriptorForType() {
           return getDescriptor();
         }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.getDescriptor().getEnumTypes().get(0);
         }
    @@ -177,7 +177,7 @@ public MetricType findValueByNumber(int number) {
         private static final MetricType[] VALUES = values();
     
         public static MetricType valueOf(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor desc) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor desc) {
           if (desc.getType() != getDescriptor()) {
             throw new java.lang.IllegalArgumentException(
               "EnumValueDescriptor is not for this type.");
    @@ -196,7 +196,7 @@ private MetricType(int value) {
     
       public interface LabelPairOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.LabelPair)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional string name = 1;
    @@ -212,7 +212,7 @@ public interface LabelPairOrBuilder extends
          * optional string name = 1;
          * @return The bytes for name.
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getNameBytes();
     
         /**
    @@ -229,19 +229,19 @@ public interface LabelPairOrBuilder extends
          * optional string value = 2;
          * @return The bytes for value.
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getValueBytes();
       }
       /**
        * Protobuf type {@code io.prometheus.client.LabelPair}
        */
       public static final class LabelPair extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.LabelPair)
           LabelPairOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use LabelPair.newBuilder() to construct.
    -    private LabelPair(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private LabelPair(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private LabelPair() {
    @@ -256,18 +256,13 @@ protected java.lang.Object newInstance(
           return new LabelPair();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -296,8 +291,8 @@ public java.lang.String getName() {
           if (ref instanceof java.lang.String) {
             return (java.lang.String) ref;
           } else {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = 
    -            (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
    +            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             java.lang.String s = bs.toStringUtf8();
             if (bs.isValidUtf8()) {
               name_ = s;
    @@ -310,17 +305,17 @@ public java.lang.String getName() {
          * @return The bytes for name.
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getNameBytes() {
           java.lang.Object ref = name_;
           if (ref instanceof java.lang.String) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -            io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                     (java.lang.String) ref);
             name_ = b;
             return b;
           } else {
    -        return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
           }
         }
     
    @@ -345,8 +340,8 @@ public java.lang.String getValue() {
           if (ref instanceof java.lang.String) {
             return (java.lang.String) ref;
           } else {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = 
    -            (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
    +            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             java.lang.String s = bs.toStringUtf8();
             if (bs.isValidUtf8()) {
               value_ = s;
    @@ -359,17 +354,17 @@ public java.lang.String getValue() {
          * @return The bytes for value.
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getValueBytes() {
           java.lang.Object ref = value_;
           if (ref instanceof java.lang.String) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -            io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                     (java.lang.String) ref);
             value_ = b;
             return b;
           } else {
    -        return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
           }
         }
     
    @@ -385,13 +380,13 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, value_);
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, value_);
           }
           getUnknownFields().writeTo(output);
         }
    @@ -403,10 +398,10 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, value_);
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, value_);
           }
           size += getUnknownFields().getSerializedSize();
           memoizedSize = size;
    @@ -459,71 +454,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -543,7 +540,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -551,16 +548,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.LabelPair}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -573,7 +570,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -587,7 +584,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
    @@ -634,34 +631,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair)other);
             } else {
    @@ -694,8 +691,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -726,7 +723,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -750,8 +747,8 @@ public boolean hasName() {
           public java.lang.String getName() {
             java.lang.Object ref = name_;
             if (!(ref instanceof java.lang.String)) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs =
    -              (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
    +              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
    @@ -765,17 +762,17 @@ public java.lang.String getName() {
            * optional string name = 1;
            * @return The bytes for name.
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof String) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
    -          return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             }
           }
           /**
    @@ -807,7 +804,7 @@ public Builder clearName() {
            * @return This builder for chaining.
            */
           public Builder setNameBytes(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
             if (value == null) { throw new NullPointerException(); }
             name_ = value;
             bitField0_ |= 0x00000001;
    @@ -830,8 +827,8 @@ public boolean hasValue() {
           public java.lang.String getValue() {
             java.lang.Object ref = value_;
             if (!(ref instanceof java.lang.String)) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs =
    -              (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
    +              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 value_ = s;
    @@ -845,17 +842,17 @@ public java.lang.String getValue() {
            * optional string value = 2;
            * @return The bytes for value.
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
               getValueBytes() {
             java.lang.Object ref = value_;
             if (ref instanceof String) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               value_ = b;
               return b;
             } else {
    -          return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             }
           }
           /**
    @@ -887,7 +884,7 @@ public Builder clearValue() {
            * @return This builder for chaining.
            */
           public Builder setValueBytes(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
             if (value == null) { throw new NullPointerException(); }
             value_ = value;
             bitField0_ |= 0x00000002;
    @@ -896,13 +893,13 @@ public Builder setValueBytes(
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -920,34 +917,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public LabelPair parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -960,7 +957,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface GaugeOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Gauge)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional double value = 1;
    @@ -977,12 +974,12 @@ public interface GaugeOrBuilder extends
        * Protobuf type {@code io.prometheus.client.Gauge}
        */
       public static final class Gauge extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Gauge)
           GaugeOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Gauge.newBuilder() to construct.
    -    private Gauge(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Gauge(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Gauge() {
    @@ -995,18 +992,13 @@ protected java.lang.Object newInstance(
           return new Gauge();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -1045,7 +1037,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeDouble(1, value_);
    @@ -1060,7 +1052,7 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(1, value_);
           }
           size += getUnknownFields().getSerializedSize();
    @@ -1097,7 +1089,7 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasValue()) {
             hash = (37 * hash) + VALUE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getValue()));
           }
           hash = (29 * hash) + getUnknownFields().hashCode();
    @@ -1107,71 +1099,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -1191,7 +1185,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -1199,16 +1193,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Gauge}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -1221,7 +1215,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -1234,7 +1228,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
    @@ -1277,34 +1271,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge)other);
             } else {
    @@ -1330,8 +1324,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -1357,7 +1351,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -1389,7 +1383,7 @@ public double getValue() {
            * @return This builder for chaining.
            */
           public Builder setValue(double value) {
    -        
    +
             value_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -1407,13 +1401,13 @@ public Builder clearValue() {
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -1431,34 +1425,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Gauge parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -1471,7 +1465,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface CounterOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Counter)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional double value = 1;
    @@ -1498,17 +1492,32 @@ public interface CounterOrBuilder extends
          * optional .io.prometheus.client.Exemplar exemplar = 2;
          */
         io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
    +
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     * @return Whether the createdTimestamp field is set.
    +     */
    +    boolean hasCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     * @return The createdTimestamp.
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
       }
       /**
        * Protobuf type {@code io.prometheus.client.Counter}
        */
       public static final class Counter extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Counter)
           CounterOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Counter.newBuilder() to construct.
    -    private Counter(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Counter(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Counter() {
    @@ -1521,18 +1530,13 @@ protected java.lang.Object newInstance(
           return new Counter();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -1585,6 +1589,32 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
         }
     
    +    public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     * @return Whether the createdTimestamp field is set.
    +     */
    +    @java.lang.Override
    +    public boolean hasCreatedTimestamp() {
    +      return ((bitField0_ & 0x00000004) != 0);
    +    }
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     * @return The createdTimestamp.
    +     */
    +    @java.lang.Override
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
    +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +    }
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 3;
    +     */
    +    @java.lang.Override
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
    +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +    }
    +
         private byte memoizedIsInitialized = -1;
         @java.lang.Override
         public final boolean isInitialized() {
    @@ -1597,7 +1627,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeDouble(1, value_);
    @@ -1605,6 +1635,9 @@ public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutput
           if (((bitField0_ & 0x00000002) != 0)) {
             output.writeMessage(2, getExemplar());
           }
    +      if (((bitField0_ & 0x00000004) != 0)) {
    +        output.writeMessage(3, getCreatedTimestamp());
    +      }
           getUnknownFields().writeTo(output);
         }
     
    @@ -1615,13 +1648,17 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(1, value_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(2, getExemplar());
           }
    +      if (((bitField0_ & 0x00000004) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
    +          .computeMessageSize(3, getCreatedTimestamp());
    +      }
           size += getUnknownFields().getSerializedSize();
           memoizedSize = size;
           return size;
    @@ -1648,6 +1685,11 @@ public boolean equals(final java.lang.Object obj) {
             if (!getExemplar()
                 .equals(other.getExemplar())) return false;
           }
    +      if (hasCreatedTimestamp() != other.hasCreatedTimestamp()) return false;
    +      if (hasCreatedTimestamp()) {
    +        if (!getCreatedTimestamp()
    +            .equals(other.getCreatedTimestamp())) return false;
    +      }
           if (!getUnknownFields().equals(other.getUnknownFields())) return false;
           return true;
         }
    @@ -1661,13 +1703,17 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasValue()) {
             hash = (37 * hash) + VALUE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getValue()));
           }
           if (hasExemplar()) {
             hash = (37 * hash) + EXEMPLAR_FIELD_NUMBER;
             hash = (53 * hash) + getExemplar().hashCode();
           }
    +      if (hasCreatedTimestamp()) {
    +        hash = (37 * hash) + CREATED_TIMESTAMP_FIELD_NUMBER;
    +        hash = (53 * hash) + getCreatedTimestamp().hashCode();
    +      }
           hash = (29 * hash) + getUnknownFields().hashCode();
           memoizedHashCode = hash;
           return hash;
    @@ -1675,71 +1721,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -1759,7 +1807,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -1767,16 +1815,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Counter}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -1789,14 +1837,15 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
             maybeForceBuilderInitialization();
           }
           private void maybeForceBuilderInitialization() {
    -        if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
                     .alwaysUseFieldBuilders) {
               getExemplarFieldBuilder();
    +          getCreatedTimestampFieldBuilder();
             }
           }
           @java.lang.Override
    @@ -1809,11 +1858,16 @@ public Builder clear() {
               exemplarBuilder_.dispose();
               exemplarBuilder_ = null;
             }
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
             return this;
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
    @@ -1853,6 +1907,12 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
                   : exemplarBuilder_.build();
               to_bitField0_ |= 0x00000002;
             }
    +        if (((from_bitField0_ & 0x00000004) != 0)) {
    +          result.createdTimestamp_ = createdTimestampBuilder_ == null
    +              ? createdTimestamp_
    +              : createdTimestampBuilder_.build();
    +          to_bitField0_ |= 0x00000004;
    +        }
             result.bitField0_ |= to_bitField0_;
           }
     
    @@ -1862,34 +1922,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter)other);
             } else {
    @@ -1906,6 +1966,9 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
             if (other.hasExemplar()) {
               mergeExemplar(other.getExemplar());
             }
    +        if (other.hasCreatedTimestamp()) {
    +          mergeCreatedTimestamp(other.getCreatedTimestamp());
    +        }
             this.mergeUnknownFields(other.getUnknownFields());
             onChanged();
             return this;
    @@ -1918,8 +1981,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -1944,6 +2007,13 @@ public Builder mergeFrom(
                     bitField0_ |= 0x00000002;
                     break;
                   } // case 18
    +              case 26: {
    +                input.readMessage(
    +                    getCreatedTimestampFieldBuilder().getBuilder(),
    +                    extensionRegistry);
    +                bitField0_ |= 0x00000004;
    +                break;
    +              } // case 26
                   default: {
                     if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                       done = true; // was an endgroup tag
    @@ -1952,7 +2022,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -1984,7 +2054,7 @@ public double getValue() {
            * @return This builder for chaining.
            */
           public Builder setValue(double value) {
    -        
    +
             value_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -2002,7 +2072,7 @@ public Builder clearValue() {
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
    @@ -2106,11 +2176,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> 
               getExemplarFieldBuilder() {
             if (exemplarBuilder_ == null) {
    -          exemplarBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>(
                       getExemplar(),
                       getParentForChildren(),
    @@ -2119,15 +2189,134 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
             return exemplarBuilder_;
           }
    +
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       * @return Whether the createdTimestamp field is set.
    +       */
    +      public boolean hasCreatedTimestamp() {
    +        return ((bitField0_ & 0x00000004) != 0);
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       * @return The createdTimestamp.
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
    +        if (createdTimestampBuilder_ == null) {
    +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        } else {
    +          return createdTimestampBuilder_.getMessage();
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (value == null) {
    +            throw new NullPointerException();
    +          }
    +          createdTimestamp_ = value;
    +        } else {
    +          createdTimestampBuilder_.setMessage(value);
    +        }
    +        bitField0_ |= 0x00000004;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public Builder setCreatedTimestamp(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestamp_ = builderForValue.build();
    +        } else {
    +          createdTimestampBuilder_.setMessage(builderForValue.build());
    +        }
    +        bitField0_ |= 0x00000004;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (((bitField0_ & 0x00000004) != 0) &&
    +            createdTimestamp_ != null &&
    +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
    +            getCreatedTimestampBuilder().mergeFrom(value);
    +          } else {
    +            createdTimestamp_ = value;
    +          }
    +        } else {
    +          createdTimestampBuilder_.mergeFrom(value);
    +        }
    +        bitField0_ |= 0x00000004;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public Builder clearCreatedTimestamp() {
    +        bitField0_ = (bitField0_ & ~0x00000004);
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
    +        bitField0_ |= 0x00000004;
    +        onChanged();
    +        return getCreatedTimestampFieldBuilder().getBuilder();
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
    +        if (createdTimestampBuilder_ != null) {
    +          return createdTimestampBuilder_.getMessageOrBuilder();
    +        } else {
    +          return createdTimestamp_ == null ?
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 3;
    +       */
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
    +          getCreatedTimestampFieldBuilder() {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
    +                  getCreatedTimestamp(),
    +                  getParentForChildren(),
    +                  isClean());
    +          createdTimestamp_ = null;
    +        }
    +        return createdTimestampBuilder_;
    +      }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -2145,34 +2334,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Counter parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -2185,7 +2374,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface QuantileOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Quantile)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional double quantile = 1;
    @@ -2213,12 +2402,12 @@ public interface QuantileOrBuilder extends
        * Protobuf type {@code io.prometheus.client.Quantile}
        */
       public static final class Quantile extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Quantile)
           QuantileOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Quantile.newBuilder() to construct.
    -    private Quantile(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Quantile(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Quantile() {
    @@ -2231,18 +2420,13 @@ protected java.lang.Object newInstance(
           return new Quantile();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -2300,7 +2484,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeDouble(1, quantile_);
    @@ -2318,11 +2502,11 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(1, quantile_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(2, value_);
           }
           size += getUnknownFields().getSerializedSize();
    @@ -2365,12 +2549,12 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasQuantile()) {
             hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getQuantile()));
           }
           if (hasValue()) {
             hash = (37 * hash) + VALUE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getValue()));
           }
           hash = (29 * hash) + getUnknownFields().hashCode();
    @@ -2380,71 +2564,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -2464,7 +2650,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -2472,16 +2658,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Quantile}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -2494,7 +2680,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -2508,7 +2694,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
    @@ -2555,34 +2741,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile)other);
             } else {
    @@ -2611,8 +2797,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -2643,7 +2829,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -2675,7 +2861,7 @@ public double getQuantile() {
            * @return This builder for chaining.
            */
           public Builder setQuantile(double value) {
    -        
    +
             quantile_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -2715,7 +2901,7 @@ public double getValue() {
            * @return This builder for chaining.
            */
           public Builder setValue(double value) {
    -        
    +
             value_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -2733,13 +2919,13 @@ public Builder clearValue() {
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -2757,34 +2943,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Quantile parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -2797,7 +2983,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface SummaryOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Summary)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional uint64 sample_count = 1;
    @@ -2844,17 +3030,32 @@ public interface SummaryOrBuilder extends
          */
         io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder(
             int index);
    +
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     * @return Whether the createdTimestamp field is set.
    +     */
    +    boolean hasCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     * @return The createdTimestamp.
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
       }
       /**
        * Protobuf type {@code io.prometheus.client.Summary}
        */
       public static final class Summary extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Summary)
           SummaryOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Summary.newBuilder() to construct.
    -    private Summary(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Summary(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Summary() {
    @@ -2868,18 +3069,13 @@ protected java.lang.Object newInstance(
           return new Summary();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -2966,6 +3162,32 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           return quantile_.get(index);
         }
     
    +    public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 4;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     * @return Whether the createdTimestamp field is set.
    +     */
    +    @java.lang.Override
    +    public boolean hasCreatedTimestamp() {
    +      return ((bitField0_ & 0x00000004) != 0);
    +    }
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     * @return The createdTimestamp.
    +     */
    +    @java.lang.Override
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
    +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +    }
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 4;
    +     */
    +    @java.lang.Override
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
    +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +    }
    +
         private byte memoizedIsInitialized = -1;
         @java.lang.Override
         public final boolean isInitialized() {
    @@ -2978,7 +3200,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeUInt64(1, sampleCount_);
    @@ -2989,6 +3211,9 @@ public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutput
           for (int i = 0; i < quantile_.size(); i++) {
             output.writeMessage(3, quantile_.get(i));
           }
    +      if (((bitField0_ & 0x00000004) != 0)) {
    +        output.writeMessage(4, getCreatedTimestamp());
    +      }
           getUnknownFields().writeTo(output);
         }
     
    @@ -2999,17 +3224,21 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeUInt64Size(1, sampleCount_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(2, sampleSum_);
           }
           for (int i = 0; i < quantile_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(3, quantile_.get(i));
           }
    +      if (((bitField0_ & 0x00000004) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
    +          .computeMessageSize(4, getCreatedTimestamp());
    +      }
           size += getUnknownFields().getSerializedSize();
           memoizedSize = size;
           return size;
    @@ -3038,6 +3267,11 @@ public boolean equals(final java.lang.Object obj) {
           }
           if (!getQuantileList()
               .equals(other.getQuantileList())) return false;
    +      if (hasCreatedTimestamp() != other.hasCreatedTimestamp()) return false;
    +      if (hasCreatedTimestamp()) {
    +        if (!getCreatedTimestamp()
    +            .equals(other.getCreatedTimestamp())) return false;
    +      }
           if (!getUnknownFields().equals(other.getUnknownFields())) return false;
           return true;
         }
    @@ -3051,18 +3285,22 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasSampleCount()) {
             hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 getSampleCount());
           }
           if (hasSampleSum()) {
             hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getSampleSum()));
           }
           if (getQuantileCount() > 0) {
             hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
             hash = (53 * hash) + getQuantileList().hashCode();
           }
    +      if (hasCreatedTimestamp()) {
    +        hash = (37 * hash) + CREATED_TIMESTAMP_FIELD_NUMBER;
    +        hash = (53 * hash) + getCreatedTimestamp().hashCode();
    +      }
           hash = (29 * hash) + getUnknownFields().hashCode();
           memoizedHashCode = hash;
           return hash;
    @@ -3070,71 +3308,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -3154,7 +3394,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -3162,16 +3402,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Summary}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -3180,13 +3420,20 @@ public static final class Builder extends
     
           // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.newBuilder()
           private Builder() {
    -
    +        maybeForceBuilderInitialization();
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
    -
    +        maybeForceBuilderInitialization();
    +      }
    +      private void maybeForceBuilderInitialization() {
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
    +                .alwaysUseFieldBuilders) {
    +          getQuantileFieldBuilder();
    +          getCreatedTimestampFieldBuilder();
    +        }
           }
           @java.lang.Override
           public Builder clear() {
    @@ -3201,11 +3448,16 @@ public Builder clear() {
               quantileBuilder_.clear();
             }
             bitField0_ = (bitField0_ & ~0x00000004);
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
             return this;
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
    @@ -3256,6 +3508,12 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
               result.sampleSum_ = sampleSum_;
               to_bitField0_ |= 0x00000002;
             }
    +        if (((from_bitField0_ & 0x00000008) != 0)) {
    +          result.createdTimestamp_ = createdTimestampBuilder_ == null
    +              ? createdTimestamp_
    +              : createdTimestampBuilder_.build();
    +          to_bitField0_ |= 0x00000004;
    +        }
             result.bitField0_ |= to_bitField0_;
           }
     
    @@ -3265,34 +3523,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary)other);
             } else {
    @@ -3328,13 +3586,16 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   quantile_ = other.quantile_;
                   bitField0_ = (bitField0_ & ~0x00000004);
                   quantileBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getQuantileFieldBuilder() : null;
                 } else {
                   quantileBuilder_.addAllMessages(other.quantile_);
                 }
               }
             }
    +        if (other.hasCreatedTimestamp()) {
    +          mergeCreatedTimestamp(other.getCreatedTimestamp());
    +        }
             this.mergeUnknownFields(other.getUnknownFields());
             onChanged();
             return this;
    @@ -3347,8 +3608,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -3384,6 +3645,13 @@ public Builder mergeFrom(
                     }
                     break;
                   } // case 26
    +              case 34: {
    +                input.readMessage(
    +                    getCreatedTimestampFieldBuilder().getBuilder(),
    +                    extensionRegistry);
    +                bitField0_ |= 0x00000008;
    +                break;
    +              } // case 34
                   default: {
                     if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                       done = true; // was an endgroup tag
    @@ -3392,7 +3660,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -3424,7 +3692,7 @@ public long getSampleCount() {
            * @return This builder for chaining.
            */
           public Builder setSampleCount(long value) {
    -        
    +
             sampleCount_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -3464,7 +3732,7 @@ public double getSampleSum() {
            * @return This builder for chaining.
            */
           public Builder setSampleSum(double value) {
    -        
    +
             sampleSum_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -3490,7 +3758,7 @@ private void ensureQuantileIsMutable() {
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> quantileBuilder_;
     
           /**
    @@ -3622,7 +3890,7 @@ public Builder addAllQuantile(
               java.lang.Iterable values) {
             if (quantileBuilder_ == null) {
               ensureQuantileIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, quantile_);
               onChanged();
             } else {
    @@ -3706,11 +3974,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getQuantileBuilderList() {
             return getQuantileFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> 
               getQuantileFieldBuilder() {
             if (quantileBuilder_ == null) {
    -          quantileBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          quantileBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder>(
                       quantile_,
                       ((bitField0_ & 0x00000004) != 0),
    @@ -3720,15 +3988,134 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
             return quantileBuilder_;
           }
    +
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       * @return Whether the createdTimestamp field is set.
    +       */
    +      public boolean hasCreatedTimestamp() {
    +        return ((bitField0_ & 0x00000008) != 0);
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       * @return The createdTimestamp.
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
    +        if (createdTimestampBuilder_ == null) {
    +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        } else {
    +          return createdTimestampBuilder_.getMessage();
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (value == null) {
    +            throw new NullPointerException();
    +          }
    +          createdTimestamp_ = value;
    +        } else {
    +          createdTimestampBuilder_.setMessage(value);
    +        }
    +        bitField0_ |= 0x00000008;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public Builder setCreatedTimestamp(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestamp_ = builderForValue.build();
    +        } else {
    +          createdTimestampBuilder_.setMessage(builderForValue.build());
    +        }
    +        bitField0_ |= 0x00000008;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (((bitField0_ & 0x00000008) != 0) &&
    +            createdTimestamp_ != null &&
    +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
    +            getCreatedTimestampBuilder().mergeFrom(value);
    +          } else {
    +            createdTimestamp_ = value;
    +          }
    +        } else {
    +          createdTimestampBuilder_.mergeFrom(value);
    +        }
    +        bitField0_ |= 0x00000008;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public Builder clearCreatedTimestamp() {
    +        bitField0_ = (bitField0_ & ~0x00000008);
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
    +        bitField0_ |= 0x00000008;
    +        onChanged();
    +        return getCreatedTimestampFieldBuilder().getBuilder();
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
    +        if (createdTimestampBuilder_ != null) {
    +          return createdTimestampBuilder_.getMessageOrBuilder();
    +        } else {
    +          return createdTimestamp_ == null ?
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 4;
    +       */
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
    +          getCreatedTimestampFieldBuilder() {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
    +                  getCreatedTimestamp(),
    +                  getParentForChildren(),
    +                  isClean());
    +          createdTimestamp_ = null;
    +        }
    +        return createdTimestampBuilder_;
    +      }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -3746,34 +4133,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Summary parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -3786,7 +4173,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface UntypedOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Untyped)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional double value = 1;
    @@ -3803,12 +4190,12 @@ public interface UntypedOrBuilder extends
        * Protobuf type {@code io.prometheus.client.Untyped}
        */
       public static final class Untyped extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Untyped)
           UntypedOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Untyped.newBuilder() to construct.
    -    private Untyped(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Untyped(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Untyped() {
    @@ -3821,18 +4208,13 @@ protected java.lang.Object newInstance(
           return new Untyped();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -3871,7 +4253,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeDouble(1, value_);
    @@ -3886,7 +4268,7 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(1, value_);
           }
           size += getUnknownFields().getSerializedSize();
    @@ -3923,7 +4305,7 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasValue()) {
             hash = (37 * hash) + VALUE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getValue()));
           }
           hash = (29 * hash) + getUnknownFields().hashCode();
    @@ -3933,71 +4315,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -4017,7 +4401,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -4025,16 +4409,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Untyped}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -4047,7 +4431,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -4060,7 +4444,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
    @@ -4103,34 +4487,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped)other);
             } else {
    @@ -4156,8 +4540,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -4183,7 +4567,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -4215,7 +4599,7 @@ public double getValue() {
            * @return This builder for chaining.
            */
           public Builder setValue(double value) {
    -        
    +
             value_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -4233,13 +4617,13 @@ public Builder clearValue() {
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -4257,34 +4641,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Untyped parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -4297,7 +4681,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface HistogramOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Histogram)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional uint64 sample_count = 1;
    @@ -4384,6 +4768,21 @@ public interface HistogramOrBuilder extends
         io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder(
             int index);
     
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 15;
    +     * @return Whether the createdTimestamp field is set.
    +     */
    +    boolean hasCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 15;
    +     * @return The createdTimestamp.
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
    +    /**
    +     * optional .google.protobuf.Timestamp created_timestamp = 15;
    +     */
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
    +
         /**
          * 
          * schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
    @@ -4579,6 +4978,9 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
         /**
          * 
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -4588,6 +4990,9 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -4596,6 +5001,9 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -4604,6 +5012,9 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -4613,6 +5024,9 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -4688,12 +5102,12 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met * Protobuf type {@code io.prometheus.client.Histogram} */ public static final class Histogram extends - io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:io.prometheus.client.Histogram) HistogramOrBuilder { private static final long serialVersionUID = 0L; // Use Histogram.newBuilder() to construct. - private Histogram(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + private Histogram(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { super(builder); } private Histogram() { @@ -4713,18 +5127,13 @@ protected java.lang.Object newInstance( return new Histogram(); } - @java.lang.Override - public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor + public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor getDescriptor() { return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; } @java.lang.Override - protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable .ensureFieldAccessorsInitialized( @@ -4858,6 +5267,32 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 return bucket_.get(index); } + public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 15; + private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_; + /** + * optional .google.protobuf.Timestamp created_timestamp = 15; + * @return Whether the createdTimestamp field is set. + */ + @java.lang.Override + public boolean hasCreatedTimestamp() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional .google.protobuf.Timestamp created_timestamp = 15; + * @return The createdTimestamp. + */ + @java.lang.Override + public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() { + return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_; + } + /** + * optional .google.protobuf.Timestamp created_timestamp = 15; + */ + @java.lang.Override + public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() { + return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_; + } + public static final int SCHEMA_FIELD_NUMBER = 5; private int schema_ = 0; /** @@ -4874,7 +5309,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 */ @java.lang.Override public boolean hasSchema() { - return ((bitField0_ & 0x00000008) != 0); + return ((bitField0_ & 0x00000010) != 0); } /** *
    @@ -4905,7 +5340,7 @@ public int getSchema() {
          */
         @java.lang.Override
         public boolean hasZeroThreshold() {
    -      return ((bitField0_ & 0x00000010) != 0);
    +      return ((bitField0_ & 0x00000020) != 0);
         }
         /**
          * 
    @@ -4932,7 +5367,7 @@ public double getZeroThreshold() {
          */
         @java.lang.Override
         public boolean hasZeroCount() {
    -      return ((bitField0_ & 0x00000020) != 0);
    +      return ((bitField0_ & 0x00000040) != 0);
         }
         /**
          * 
    @@ -4959,7 +5394,7 @@ public long getZeroCount() {
          */
         @java.lang.Override
         public boolean hasZeroCountFloat() {
    -      return ((bitField0_ & 0x00000040) != 0);
    +      return ((bitField0_ & 0x00000080) != 0);
         }
         /**
          * 
    @@ -5037,7 +5472,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
         public static final int NEGATIVE_DELTA_FIELD_NUMBER = 10;
         @SuppressWarnings("serial")
    -    private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_;
         /**
          * 
          * Use either "negative_delta" or "negative_count", the former for
    @@ -5083,7 +5518,7 @@ public long getNegativeDelta(int index) {
     
         public static final int NEGATIVE_COUNT_FIELD_NUMBER = 11;
         @SuppressWarnings("serial")
    -    private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_;
         /**
          * 
          * Absolute count of each bucket.
    @@ -5127,6 +5562,9 @@ public double getNegativeCount(int index) {
         /**
          * 
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -5138,6 +5576,9 @@ public java.util.List * Positive buckets for the native histogram. + * Use a no-op span (offset 0, length 0) for a native histogram without any + * observations yet and with a zero_threshold of 0. Otherwise, it would be + * indistinguishable from a classic histogram. *
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -5150,6 +5591,9 @@ public java.util.List * Positive buckets for the native histogram. + * Use a no-op span (offset 0, length 0) for a native histogram without any + * observations yet and with a zero_threshold of 0. Otherwise, it would be + * indistinguishable from a classic histogram. *
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -5161,6 +5605,9 @@ public int getPositiveSpanCount() { /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -5172,6 +5619,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
          * Positive buckets for the native histogram.
    +     * Use a no-op span (offset 0, length 0) for a native histogram without any
    +     * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +     * indistinguishable from a classic histogram.
          * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -5184,7 +5634,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 public static final int POSITIVE_DELTA_FIELD_NUMBER = 13; @SuppressWarnings("serial") - private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_; + private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_; /** *
          * Use either "positive_delta" or "positive_count", the former for
    @@ -5230,7 +5680,7 @@ public long getPositiveDelta(int index) {
     
         public static final int POSITIVE_COUNT_FIELD_NUMBER = 14;
         @SuppressWarnings("serial")
    -    private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_;
         /**
          * 
          * Absolute count of each bucket.
    @@ -5280,7 +5730,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeUInt64(1, sampleCount_);
    @@ -5294,16 +5744,16 @@ public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutput
           if (((bitField0_ & 0x00000002) != 0)) {
             output.writeDouble(4, sampleCountFloat_);
           }
    -      if (((bitField0_ & 0x00000008) != 0)) {
    +      if (((bitField0_ & 0x00000010) != 0)) {
             output.writeSInt32(5, schema_);
           }
    -      if (((bitField0_ & 0x00000010) != 0)) {
    +      if (((bitField0_ & 0x00000020) != 0)) {
             output.writeDouble(6, zeroThreshold_);
           }
    -      if (((bitField0_ & 0x00000020) != 0)) {
    +      if (((bitField0_ & 0x00000040) != 0)) {
             output.writeUInt64(7, zeroCount_);
           }
    -      if (((bitField0_ & 0x00000040) != 0)) {
    +      if (((bitField0_ & 0x00000080) != 0)) {
             output.writeDouble(8, zeroCountFloat_);
           }
           for (int i = 0; i < negativeSpan_.size(); i++) {
    @@ -5324,6 +5774,9 @@ public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutput
           for (int i = 0; i < positiveCount_.size(); i++) {
             output.writeDouble(14, positiveCount_.getDouble(i));
           }
    +      if (((bitField0_ & 0x00000008) != 0)) {
    +        output.writeMessage(15, getCreatedTimestamp());
    +      }
           getUnknownFields().writeTo(output);
         }
     
    @@ -5334,45 +5787,45 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeUInt64Size(1, sampleCount_);
           }
           if (((bitField0_ & 0x00000004) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(2, sampleSum_);
           }
           for (int i = 0; i < bucket_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(3, bucket_.get(i));
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(4, sampleCountFloat_);
           }
    -      if (((bitField0_ & 0x00000008) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +      if (((bitField0_ & 0x00000010) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeSInt32Size(5, schema_);
           }
    -      if (((bitField0_ & 0x00000010) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +      if (((bitField0_ & 0x00000020) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(6, zeroThreshold_);
           }
    -      if (((bitField0_ & 0x00000020) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +      if (((bitField0_ & 0x00000040) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeUInt64Size(7, zeroCount_);
           }
    -      if (((bitField0_ & 0x00000040) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +      if (((bitField0_ & 0x00000080) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(8, zeroCountFloat_);
           }
           for (int i = 0; i < negativeSpan_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(9, negativeSpan_.get(i));
           }
           {
             int dataSize = 0;
             for (int i = 0; i < negativeDelta_.size(); i++) {
    -          dataSize += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +          dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
                 .computeSInt64SizeNoTag(negativeDelta_.getLong(i));
             }
             size += dataSize;
    @@ -5385,13 +5838,13 @@ public int getSerializedSize() {
             size += 1 * getNegativeCountList().size();
           }
           for (int i = 0; i < positiveSpan_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(12, positiveSpan_.get(i));
           }
           {
             int dataSize = 0;
             for (int i = 0; i < positiveDelta_.size(); i++) {
    -          dataSize += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +          dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
                 .computeSInt64SizeNoTag(positiveDelta_.getLong(i));
             }
             size += dataSize;
    @@ -5403,6 +5856,10 @@ public int getSerializedSize() {
             size += dataSize;
             size += 1 * getPositiveCountList().size();
           }
    +      if (((bitField0_ & 0x00000008) != 0)) {
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
    +          .computeMessageSize(15, getCreatedTimestamp());
    +      }
           size += getUnknownFields().getSerializedSize();
           memoizedSize = size;
           return size;
    @@ -5437,6 +5894,11 @@ public boolean equals(final java.lang.Object obj) {
           }
           if (!getBucketList()
               .equals(other.getBucketList())) return false;
    +      if (hasCreatedTimestamp() != other.hasCreatedTimestamp()) return false;
    +      if (hasCreatedTimestamp()) {
    +        if (!getCreatedTimestamp()
    +            .equals(other.getCreatedTimestamp())) return false;
    +      }
           if (hasSchema() != other.hasSchema()) return false;
           if (hasSchema()) {
             if (getSchema()
    @@ -5484,40 +5946,44 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasSampleCount()) {
             hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 getSampleCount());
           }
           if (hasSampleCountFloat()) {
             hash = (37 * hash) + SAMPLE_COUNT_FLOAT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getSampleCountFloat()));
           }
           if (hasSampleSum()) {
             hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getSampleSum()));
           }
           if (getBucketCount() > 0) {
             hash = (37 * hash) + BUCKET_FIELD_NUMBER;
             hash = (53 * hash) + getBucketList().hashCode();
           }
    +      if (hasCreatedTimestamp()) {
    +        hash = (37 * hash) + CREATED_TIMESTAMP_FIELD_NUMBER;
    +        hash = (53 * hash) + getCreatedTimestamp().hashCode();
    +      }
           if (hasSchema()) {
             hash = (37 * hash) + SCHEMA_FIELD_NUMBER;
             hash = (53 * hash) + getSchema();
           }
           if (hasZeroThreshold()) {
             hash = (37 * hash) + ZERO_THRESHOLD_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getZeroThreshold()));
           }
           if (hasZeroCount()) {
             hash = (37 * hash) + ZERO_COUNT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 getZeroCount());
           }
           if (hasZeroCountFloat()) {
             hash = (37 * hash) + ZERO_COUNT_FLOAT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getZeroCountFloat()));
           }
           if (getNegativeSpanCount() > 0) {
    @@ -5551,71 +6017,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -5635,7 +6103,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -5643,16 +6111,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Histogram}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -5661,13 +6129,22 @@ public static final class Builder extends
     
           // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.newBuilder()
           private Builder() {
    -
    +        maybeForceBuilderInitialization();
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
    -
    +        maybeForceBuilderInitialization();
    +      }
    +      private void maybeForceBuilderInitialization() {
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
    +                .alwaysUseFieldBuilders) {
    +          getBucketFieldBuilder();
    +          getCreatedTimestampFieldBuilder();
    +          getNegativeSpanFieldBuilder();
    +          getPositiveSpanFieldBuilder();
    +        }
           }
           @java.lang.Override
           public Builder clear() {
    @@ -5683,6 +6160,11 @@ public Builder clear() {
               bucketBuilder_.clear();
             }
             bitField0_ = (bitField0_ & ~0x00000008);
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
             schema_ = 0;
             zeroThreshold_ = 0D;
             zeroCount_ = 0L;
    @@ -5693,7 +6175,7 @@ public Builder clear() {
               negativeSpan_ = null;
               negativeSpanBuilder_.clear();
             }
    -        bitField0_ = (bitField0_ & ~0x00000100);
    +        bitField0_ = (bitField0_ & ~0x00000200);
             negativeDelta_ = emptyLongList();
             negativeCount_ = emptyDoubleList();
             if (positiveSpanBuilder_ == null) {
    @@ -5702,14 +6184,14 @@ public Builder clear() {
               positiveSpan_ = null;
               positiveSpanBuilder_.clear();
             }
    -        bitField0_ = (bitField0_ & ~0x00000800);
    +        bitField0_ = (bitField0_ & ~0x00001000);
             positiveDelta_ = emptyLongList();
             positiveCount_ = emptyDoubleList();
             return this;
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
    @@ -5748,41 +6230,41 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               result.bucket_ = bucketBuilder_.build();
             }
             if (negativeSpanBuilder_ == null) {
    -          if (((bitField0_ & 0x00000100) != 0)) {
    +          if (((bitField0_ & 0x00000200) != 0)) {
                 negativeSpan_ = java.util.Collections.unmodifiableList(negativeSpan_);
    -            bitField0_ = (bitField0_ & ~0x00000100);
    +            bitField0_ = (bitField0_ & ~0x00000200);
               }
               result.negativeSpan_ = negativeSpan_;
             } else {
               result.negativeSpan_ = negativeSpanBuilder_.build();
             }
    -        if (((bitField0_ & 0x00000200) != 0)) {
    +        if (((bitField0_ & 0x00000400) != 0)) {
               negativeDelta_.makeImmutable();
    -          bitField0_ = (bitField0_ & ~0x00000200);
    +          bitField0_ = (bitField0_ & ~0x00000400);
             }
             result.negativeDelta_ = negativeDelta_;
    -        if (((bitField0_ & 0x00000400) != 0)) {
    +        if (((bitField0_ & 0x00000800) != 0)) {
               negativeCount_.makeImmutable();
    -          bitField0_ = (bitField0_ & ~0x00000400);
    +          bitField0_ = (bitField0_ & ~0x00000800);
             }
             result.negativeCount_ = negativeCount_;
             if (positiveSpanBuilder_ == null) {
    -          if (((bitField0_ & 0x00000800) != 0)) {
    +          if (((bitField0_ & 0x00001000) != 0)) {
                 positiveSpan_ = java.util.Collections.unmodifiableList(positiveSpan_);
    -            bitField0_ = (bitField0_ & ~0x00000800);
    +            bitField0_ = (bitField0_ & ~0x00001000);
               }
               result.positiveSpan_ = positiveSpan_;
             } else {
               result.positiveSpan_ = positiveSpanBuilder_.build();
             }
    -        if (((bitField0_ & 0x00001000) != 0)) {
    +        if (((bitField0_ & 0x00002000) != 0)) {
               positiveDelta_.makeImmutable();
    -          bitField0_ = (bitField0_ & ~0x00001000);
    +          bitField0_ = (bitField0_ & ~0x00002000);
             }
             result.positiveDelta_ = positiveDelta_;
    -        if (((bitField0_ & 0x00002000) != 0)) {
    +        if (((bitField0_ & 0x00004000) != 0)) {
               positiveCount_.makeImmutable();
    -          bitField0_ = (bitField0_ & ~0x00002000);
    +          bitField0_ = (bitField0_ & ~0x00004000);
             }
             result.positiveCount_ = positiveCount_;
           }
    @@ -5803,21 +6285,27 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
               to_bitField0_ |= 0x00000004;
             }
             if (((from_bitField0_ & 0x00000010) != 0)) {
    -          result.schema_ = schema_;
    +          result.createdTimestamp_ = createdTimestampBuilder_ == null
    +              ? createdTimestamp_
    +              : createdTimestampBuilder_.build();
               to_bitField0_ |= 0x00000008;
             }
             if (((from_bitField0_ & 0x00000020) != 0)) {
    -          result.zeroThreshold_ = zeroThreshold_;
    +          result.schema_ = schema_;
               to_bitField0_ |= 0x00000010;
             }
             if (((from_bitField0_ & 0x00000040) != 0)) {
    -          result.zeroCount_ = zeroCount_;
    +          result.zeroThreshold_ = zeroThreshold_;
               to_bitField0_ |= 0x00000020;
             }
             if (((from_bitField0_ & 0x00000080) != 0)) {
    -          result.zeroCountFloat_ = zeroCountFloat_;
    +          result.zeroCount_ = zeroCount_;
               to_bitField0_ |= 0x00000040;
             }
    +        if (((from_bitField0_ & 0x00000100) != 0)) {
    +          result.zeroCountFloat_ = zeroCountFloat_;
    +          to_bitField0_ |= 0x00000080;
    +        }
             result.bitField0_ |= to_bitField0_;
           }
     
    @@ -5827,34 +6315,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram)other);
             } else {
    @@ -5893,13 +6381,16 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   bucket_ = other.bucket_;
                   bitField0_ = (bitField0_ & ~0x00000008);
                   bucketBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getBucketFieldBuilder() : null;
                 } else {
                   bucketBuilder_.addAllMessages(other.bucket_);
                 }
               }
             }
    +        if (other.hasCreatedTimestamp()) {
    +          mergeCreatedTimestamp(other.getCreatedTimestamp());
    +        }
             if (other.hasSchema()) {
               setSchema(other.getSchema());
             }
    @@ -5916,7 +6407,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
               if (!other.negativeSpan_.isEmpty()) {
                 if (negativeSpan_.isEmpty()) {
                   negativeSpan_ = other.negativeSpan_;
    -              bitField0_ = (bitField0_ & ~0x00000100);
    +              bitField0_ = (bitField0_ & ~0x00000200);
                 } else {
                   ensureNegativeSpanIsMutable();
                   negativeSpan_.addAll(other.negativeSpan_);
    @@ -5929,9 +6420,9 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   negativeSpanBuilder_.dispose();
                   negativeSpanBuilder_ = null;
                   negativeSpan_ = other.negativeSpan_;
    -              bitField0_ = (bitField0_ & ~0x00000100);
    +              bitField0_ = (bitField0_ & ~0x00000200);
                   negativeSpanBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getNegativeSpanFieldBuilder() : null;
                 } else {
                   negativeSpanBuilder_.addAllMessages(other.negativeSpan_);
    @@ -5941,7 +6432,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
             if (!other.negativeDelta_.isEmpty()) {
               if (negativeDelta_.isEmpty()) {
                 negativeDelta_ = other.negativeDelta_;
    -            bitField0_ = (bitField0_ & ~0x00000200);
    +            bitField0_ = (bitField0_ & ~0x00000400);
               } else {
                 ensureNegativeDeltaIsMutable();
                 negativeDelta_.addAll(other.negativeDelta_);
    @@ -5951,7 +6442,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
             if (!other.negativeCount_.isEmpty()) {
               if (negativeCount_.isEmpty()) {
                 negativeCount_ = other.negativeCount_;
    -            bitField0_ = (bitField0_ & ~0x00000400);
    +            bitField0_ = (bitField0_ & ~0x00000800);
               } else {
                 ensureNegativeCountIsMutable();
                 negativeCount_.addAll(other.negativeCount_);
    @@ -5962,7 +6453,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
               if (!other.positiveSpan_.isEmpty()) {
                 if (positiveSpan_.isEmpty()) {
                   positiveSpan_ = other.positiveSpan_;
    -              bitField0_ = (bitField0_ & ~0x00000800);
    +              bitField0_ = (bitField0_ & ~0x00001000);
                 } else {
                   ensurePositiveSpanIsMutable();
                   positiveSpan_.addAll(other.positiveSpan_);
    @@ -5975,9 +6466,9 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   positiveSpanBuilder_.dispose();
                   positiveSpanBuilder_ = null;
                   positiveSpan_ = other.positiveSpan_;
    -              bitField0_ = (bitField0_ & ~0x00000800);
    +              bitField0_ = (bitField0_ & ~0x00001000);
                   positiveSpanBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getPositiveSpanFieldBuilder() : null;
                 } else {
                   positiveSpanBuilder_.addAllMessages(other.positiveSpan_);
    @@ -5987,7 +6478,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
             if (!other.positiveDelta_.isEmpty()) {
               if (positiveDelta_.isEmpty()) {
                 positiveDelta_ = other.positiveDelta_;
    -            bitField0_ = (bitField0_ & ~0x00001000);
    +            bitField0_ = (bitField0_ & ~0x00002000);
               } else {
                 ensurePositiveDeltaIsMutable();
                 positiveDelta_.addAll(other.positiveDelta_);
    @@ -5997,7 +6488,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
             if (!other.positiveCount_.isEmpty()) {
               if (positiveCount_.isEmpty()) {
                 positiveCount_ = other.positiveCount_;
    -            bitField0_ = (bitField0_ & ~0x00002000);
    +            bitField0_ = (bitField0_ & ~0x00004000);
               } else {
                 ensurePositiveCountIsMutable();
                 positiveCount_.addAll(other.positiveCount_);
    @@ -6016,8 +6507,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -6060,22 +6551,22 @@ public Builder mergeFrom(
                   } // case 33
                   case 40: {
                     schema_ = input.readSInt32();
    -                bitField0_ |= 0x00000010;
    +                bitField0_ |= 0x00000020;
                     break;
                   } // case 40
                   case 49: {
                     zeroThreshold_ = input.readDouble();
    -                bitField0_ |= 0x00000020;
    +                bitField0_ |= 0x00000040;
                     break;
                   } // case 49
                   case 56: {
                     zeroCount_ = input.readUInt64();
    -                bitField0_ |= 0x00000040;
    +                bitField0_ |= 0x00000080;
                     break;
                   } // case 56
                   case 65: {
                     zeroCountFloat_ = input.readDouble();
    -                bitField0_ |= 0x00000080;
    +                bitField0_ |= 0x00000100;
                     break;
                   } // case 65
                   case 74: {
    @@ -6168,6 +6659,13 @@ public Builder mergeFrom(
                     input.popLimit(limit);
                     break;
                   } // case 114
    +              case 122: {
    +                input.readMessage(
    +                    getCreatedTimestampFieldBuilder().getBuilder(),
    +                    extensionRegistry);
    +                bitField0_ |= 0x00000010;
    +                break;
    +              } // case 122
                   default: {
                     if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                       done = true; // was an endgroup tag
    @@ -6176,7 +6674,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -6208,7 +6706,7 @@ public long getSampleCount() {
            * @return This builder for chaining.
            */
           public Builder setSampleCount(long value) {
    -        
    +
             sampleCount_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -6260,7 +6758,7 @@ public double getSampleCountFloat() {
            * @return This builder for chaining.
            */
           public Builder setSampleCountFloat(double value) {
    -        
    +
             sampleCountFloat_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -6304,7 +6802,7 @@ public double getSampleSum() {
            * @return This builder for chaining.
            */
           public Builder setSampleSum(double value) {
    -        
    +
             sampleSum_ = value;
             bitField0_ |= 0x00000004;
             onChanged();
    @@ -6330,7 +6828,7 @@ private void ensureBucketIsMutable() {
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> bucketBuilder_;
     
           /**
    @@ -6502,7 +7000,7 @@ public Builder addAllBucket(
               java.lang.Iterable values) {
             if (bucketBuilder_ == null) {
               ensureBucketIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, bucket_);
               onChanged();
             } else {
    @@ -6618,11 +7116,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getBucketBuilderList() {
             return getBucketFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> 
               getBucketFieldBuilder() {
             if (bucketBuilder_ == null) {
    -          bucketBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          bucketBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder>(
                       bucket_,
                       ((bitField0_ & 0x00000008) != 0),
    @@ -6633,6 +7131,125 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             return bucketBuilder_;
           }
     
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       * @return Whether the createdTimestamp field is set.
    +       */
    +      public boolean hasCreatedTimestamp() {
    +        return ((bitField0_ & 0x00000010) != 0);
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       * @return The createdTimestamp.
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
    +        if (createdTimestampBuilder_ == null) {
    +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        } else {
    +          return createdTimestampBuilder_.getMessage();
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (value == null) {
    +            throw new NullPointerException();
    +          }
    +          createdTimestamp_ = value;
    +        } else {
    +          createdTimestampBuilder_.setMessage(value);
    +        }
    +        bitField0_ |= 0x00000010;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public Builder setCreatedTimestamp(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestamp_ = builderForValue.build();
    +        } else {
    +          createdTimestampBuilder_.setMessage(builderForValue.build());
    +        }
    +        bitField0_ |= 0x00000010;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
    +        if (createdTimestampBuilder_ == null) {
    +          if (((bitField0_ & 0x00000010) != 0) &&
    +            createdTimestamp_ != null &&
    +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
    +            getCreatedTimestampBuilder().mergeFrom(value);
    +          } else {
    +            createdTimestamp_ = value;
    +          }
    +        } else {
    +          createdTimestampBuilder_.mergeFrom(value);
    +        }
    +        bitField0_ |= 0x00000010;
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public Builder clearCreatedTimestamp() {
    +        bitField0_ = (bitField0_ & ~0x00000010);
    +        createdTimestamp_ = null;
    +        if (createdTimestampBuilder_ != null) {
    +          createdTimestampBuilder_.dispose();
    +          createdTimestampBuilder_ = null;
    +        }
    +        onChanged();
    +        return this;
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
    +        bitField0_ |= 0x00000010;
    +        onChanged();
    +        return getCreatedTimestampFieldBuilder().getBuilder();
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
    +        if (createdTimestampBuilder_ != null) {
    +          return createdTimestampBuilder_.getMessageOrBuilder();
    +        } else {
    +          return createdTimestamp_ == null ?
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
    +        }
    +      }
    +      /**
    +       * optional .google.protobuf.Timestamp created_timestamp = 15;
    +       */
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
    +          getCreatedTimestampFieldBuilder() {
    +        if (createdTimestampBuilder_ == null) {
    +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
    +                  getCreatedTimestamp(),
    +                  getParentForChildren(),
    +                  isClean());
    +          createdTimestamp_ = null;
    +        }
    +        return createdTimestampBuilder_;
    +      }
    +
           private int schema_ ;
           /**
            * 
    @@ -6648,7 +7265,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            */
           @java.lang.Override
           public boolean hasSchema() {
    -        return ((bitField0_ & 0x00000010) != 0);
    +        return ((bitField0_ & 0x00000020) != 0);
           }
           /**
            * 
    @@ -6680,9 +7297,9 @@ public int getSchema() {
            * @return This builder for chaining.
            */
           public Builder setSchema(int value) {
    -        
    +
             schema_ = value;
    -        bitField0_ |= 0x00000010;
    +        bitField0_ |= 0x00000020;
             onChanged();
             return this;
           }
    @@ -6699,7 +7316,7 @@ public Builder setSchema(int value) {
            * @return This builder for chaining.
            */
           public Builder clearSchema() {
    -        bitField0_ = (bitField0_ & ~0x00000010);
    +        bitField0_ = (bitField0_ & ~0x00000020);
             schema_ = 0;
             onChanged();
             return this;
    @@ -6716,7 +7333,7 @@ public Builder clearSchema() {
            */
           @java.lang.Override
           public boolean hasZeroThreshold() {
    -        return ((bitField0_ & 0x00000020) != 0);
    +        return ((bitField0_ & 0x00000040) != 0);
           }
           /**
            * 
    @@ -6740,9 +7357,9 @@ public double getZeroThreshold() {
            * @return This builder for chaining.
            */
           public Builder setZeroThreshold(double value) {
    -        
    +
             zeroThreshold_ = value;
    -        bitField0_ |= 0x00000020;
    +        bitField0_ |= 0x00000040;
             onChanged();
             return this;
           }
    @@ -6755,7 +7372,7 @@ public Builder setZeroThreshold(double value) {
            * @return This builder for chaining.
            */
           public Builder clearZeroThreshold() {
    -        bitField0_ = (bitField0_ & ~0x00000020);
    +        bitField0_ = (bitField0_ & ~0x00000040);
             zeroThreshold_ = 0D;
             onChanged();
             return this;
    @@ -6772,7 +7389,7 @@ public Builder clearZeroThreshold() {
            */
           @java.lang.Override
           public boolean hasZeroCount() {
    -        return ((bitField0_ & 0x00000040) != 0);
    +        return ((bitField0_ & 0x00000080) != 0);
           }
           /**
            * 
    @@ -6796,9 +7413,9 @@ public long getZeroCount() {
            * @return This builder for chaining.
            */
           public Builder setZeroCount(long value) {
    -        
    +
             zeroCount_ = value;
    -        bitField0_ |= 0x00000040;
    +        bitField0_ |= 0x00000080;
             onChanged();
             return this;
           }
    @@ -6811,7 +7428,7 @@ public Builder setZeroCount(long value) {
            * @return This builder for chaining.
            */
           public Builder clearZeroCount() {
    -        bitField0_ = (bitField0_ & ~0x00000040);
    +        bitField0_ = (bitField0_ & ~0x00000080);
             zeroCount_ = 0L;
             onChanged();
             return this;
    @@ -6828,7 +7445,7 @@ public Builder clearZeroCount() {
            */
           @java.lang.Override
           public boolean hasZeroCountFloat() {
    -        return ((bitField0_ & 0x00000080) != 0);
    +        return ((bitField0_ & 0x00000100) != 0);
           }
           /**
            * 
    @@ -6852,9 +7469,9 @@ public double getZeroCountFloat() {
            * @return This builder for chaining.
            */
           public Builder setZeroCountFloat(double value) {
    -        
    +
             zeroCountFloat_ = value;
    -        bitField0_ |= 0x00000080;
    +        bitField0_ |= 0x00000100;
             onChanged();
             return this;
           }
    @@ -6867,7 +7484,7 @@ public Builder setZeroCountFloat(double value) {
            * @return This builder for chaining.
            */
           public Builder clearZeroCountFloat() {
    -        bitField0_ = (bitField0_ & ~0x00000080);
    +        bitField0_ = (bitField0_ & ~0x00000100);
             zeroCountFloat_ = 0D;
             onChanged();
             return this;
    @@ -6876,13 +7493,13 @@ public Builder clearZeroCountFloat() {
           private java.util.List negativeSpan_ =
             java.util.Collections.emptyList();
           private void ensureNegativeSpanIsMutable() {
    -        if (!((bitField0_ & 0x00000100) != 0)) {
    +        if (!((bitField0_ & 0x00000200) != 0)) {
               negativeSpan_ = new java.util.ArrayList(negativeSpan_);
    -          bitField0_ |= 0x00000100;
    +          bitField0_ |= 0x00000200;
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
     
           /**
    @@ -7054,7 +7671,7 @@ public Builder addAllNegativeSpan(
               java.lang.Iterable values) {
             if (negativeSpanBuilder_ == null) {
               ensureNegativeSpanIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, negativeSpan_);
               onChanged();
             } else {
    @@ -7072,7 +7689,7 @@ public Builder addAllNegativeSpan(
           public Builder clearNegativeSpan() {
             if (negativeSpanBuilder_ == null) {
               negativeSpan_ = java.util.Collections.emptyList();
    -          bitField0_ = (bitField0_ & ~0x00000100);
    +          bitField0_ = (bitField0_ & ~0x00000200);
               onChanged();
             } else {
               negativeSpanBuilder_.clear();
    @@ -7170,14 +7787,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getNegativeSpanBuilderList() {
             return getNegativeSpanFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> 
               getNegativeSpanFieldBuilder() {
             if (negativeSpanBuilder_ == null) {
    -          negativeSpanBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          negativeSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>(
                       negativeSpan_,
    -                  ((bitField0_ & 0x00000100) != 0),
    +                  ((bitField0_ & 0x00000200) != 0),
                       getParentForChildren(),
                       isClean());
               negativeSpan_ = null;
    @@ -7185,11 +7802,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             return negativeSpanBuilder_;
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_ = emptyLongList();
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_ = emptyLongList();
           private void ensureNegativeDeltaIsMutable() {
    -        if (!((bitField0_ & 0x00000200) != 0)) {
    +        if (!((bitField0_ & 0x00000400) != 0)) {
               negativeDelta_ = mutableCopy(negativeDelta_);
    -          bitField0_ |= 0x00000200;
    +          bitField0_ |= 0x00000400;
             }
           }
           /**
    @@ -7204,7 +7821,7 @@ private void ensureNegativeDeltaIsMutable() {
            */
           public java.util.List
               getNegativeDeltaList() {
    -        return ((bitField0_ & 0x00000200) != 0) ?
    +        return ((bitField0_ & 0x00000400) != 0) ?
                      java.util.Collections.unmodifiableList(negativeDelta_) : negativeDelta_;
           }
           /**
    @@ -7248,7 +7865,7 @@ public long getNegativeDelta(int index) {
            */
           public Builder setNegativeDelta(
               int index, long value) {
    -        
    +
             ensureNegativeDeltaIsMutable();
             negativeDelta_.setLong(index, value);
             onChanged();
    @@ -7266,7 +7883,7 @@ public Builder setNegativeDelta(
            * @return This builder for chaining.
            */
           public Builder addNegativeDelta(long value) {
    -        
    +
             ensureNegativeDeltaIsMutable();
             negativeDelta_.addLong(value);
             onChanged();
    @@ -7286,7 +7903,7 @@ public Builder addNegativeDelta(long value) {
           public Builder addAllNegativeDelta(
               java.lang.Iterable values) {
             ensureNegativeDeltaIsMutable();
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                 values, negativeDelta_);
             onChanged();
             return this;
    @@ -7303,16 +7920,16 @@ public Builder addAllNegativeDelta(
            */
           public Builder clearNegativeDelta() {
             negativeDelta_ = emptyLongList();
    -        bitField0_ = (bitField0_ & ~0x00000200);
    +        bitField0_ = (bitField0_ & ~0x00000400);
             onChanged();
             return this;
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_ = emptyDoubleList();
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_ = emptyDoubleList();
           private void ensureNegativeCountIsMutable() {
    -        if (!((bitField0_ & 0x00000400) != 0)) {
    +        if (!((bitField0_ & 0x00000800) != 0)) {
               negativeCount_ = mutableCopy(negativeCount_);
    -          bitField0_ |= 0x00000400;
    +          bitField0_ |= 0x00000800;
             }
           }
           /**
    @@ -7325,7 +7942,7 @@ private void ensureNegativeCountIsMutable() {
            */
           public java.util.List
               getNegativeCountList() {
    -        return ((bitField0_ & 0x00000400) != 0) ?
    +        return ((bitField0_ & 0x00000800) != 0) ?
                      java.util.Collections.unmodifiableList(negativeCount_) : negativeCount_;
           }
           /**
    @@ -7363,7 +7980,7 @@ public double getNegativeCount(int index) {
            */
           public Builder setNegativeCount(
               int index, double value) {
    -        
    +
             ensureNegativeCountIsMutable();
             negativeCount_.setDouble(index, value);
             onChanged();
    @@ -7379,7 +7996,7 @@ public Builder setNegativeCount(
            * @return This builder for chaining.
            */
           public Builder addNegativeCount(double value) {
    -        
    +
             ensureNegativeCountIsMutable();
             negativeCount_.addDouble(value);
             onChanged();
    @@ -7397,7 +8014,7 @@ public Builder addNegativeCount(double value) {
           public Builder addAllNegativeCount(
               java.lang.Iterable values) {
             ensureNegativeCountIsMutable();
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                 values, negativeCount_);
             onChanged();
             return this;
    @@ -7412,7 +8029,7 @@ public Builder addAllNegativeCount(
            */
           public Builder clearNegativeCount() {
             negativeCount_ = emptyDoubleList();
    -        bitField0_ = (bitField0_ & ~0x00000400);
    +        bitField0_ = (bitField0_ & ~0x00000800);
             onChanged();
             return this;
           }
    @@ -7420,18 +8037,21 @@ public Builder clearNegativeCount() {
           private java.util.List positiveSpan_ =
             java.util.Collections.emptyList();
           private void ensurePositiveSpanIsMutable() {
    -        if (!((bitField0_ & 0x00000800) != 0)) {
    +        if (!((bitField0_ & 0x00001000) != 0)) {
               positiveSpan_ = new java.util.ArrayList(positiveSpan_);
    -          bitField0_ |= 0x00000800;
    +          bitField0_ |= 0x00001000;
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
     
           /**
            * 
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7446,6 +8066,9 @@ public java.util.List * Positive buckets for the native histogram. + * Use a no-op span (offset 0, length 0) for a native histogram without any + * observations yet and with a zero_threshold of 0. Otherwise, it would be + * indistinguishable from a classic histogram. *
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7460,6 +8083,9 @@ public int getPositiveSpanCount() { /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7474,6 +8100,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7495,6 +8124,9 @@ public Builder setPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7513,6 +8145,9 @@ public Builder setPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7533,6 +8168,9 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7554,6 +8192,9 @@ public Builder addPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7572,6 +8213,9 @@ public Builder addPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7590,6 +8234,9 @@ public Builder addPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7598,7 +8245,7 @@ public Builder addAllPositiveSpan( java.lang.Iterable values) { if (positiveSpanBuilder_ == null) { ensurePositiveSpanIsMutable(); - io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( values, positiveSpan_); onChanged(); } else { @@ -7609,6 +8256,9 @@ public Builder addAllPositiveSpan( /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7616,7 +8266,7 @@ public Builder addAllPositiveSpan( public Builder clearPositiveSpan() { if (positiveSpanBuilder_ == null) { positiveSpan_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000800); + bitField0_ = (bitField0_ & ~0x00001000); onChanged(); } else { positiveSpanBuilder_.clear(); @@ -7626,6 +8276,9 @@ public Builder clearPositiveSpan() { /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7643,6 +8296,9 @@ public Builder removePositiveSpan(int index) { /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7654,6 +8310,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7668,6 +8327,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7683,6 +8345,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7694,6 +8359,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7706,6 +8374,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 /** *
            * Positive buckets for the native histogram.
    +       * Use a no-op span (offset 0, length 0) for a native histogram without any
    +       * observations yet and with a zero_threshold of 0. Otherwise, it would be
    +       * indistinguishable from a classic histogram.
            * 
    * * repeated .io.prometheus.client.BucketSpan positive_span = 12; @@ -7714,14 +8385,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 getPositiveSpanBuilderList() { return getPositiveSpanFieldBuilder().getBuilderList(); } - private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> getPositiveSpanFieldBuilder() { if (positiveSpanBuilder_ == null) { - positiveSpanBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< + positiveSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>( positiveSpan_, - ((bitField0_ & 0x00000800) != 0), + ((bitField0_ & 0x00001000) != 0), getParentForChildren(), isClean()); positiveSpan_ = null; @@ -7729,11 +8400,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 return positiveSpanBuilder_; } - private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_ = emptyLongList(); + private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_ = emptyLongList(); private void ensurePositiveDeltaIsMutable() { - if (!((bitField0_ & 0x00001000) != 0)) { + if (!((bitField0_ & 0x00002000) != 0)) { positiveDelta_ = mutableCopy(positiveDelta_); - bitField0_ |= 0x00001000; + bitField0_ |= 0x00002000; } } /** @@ -7748,7 +8419,7 @@ private void ensurePositiveDeltaIsMutable() { */ public java.util.List getPositiveDeltaList() { - return ((bitField0_ & 0x00001000) != 0) ? + return ((bitField0_ & 0x00002000) != 0) ? java.util.Collections.unmodifiableList(positiveDelta_) : positiveDelta_; } /** @@ -7792,7 +8463,7 @@ public long getPositiveDelta(int index) { */ public Builder setPositiveDelta( int index, long value) { - + ensurePositiveDeltaIsMutable(); positiveDelta_.setLong(index, value); onChanged(); @@ -7810,7 +8481,7 @@ public Builder setPositiveDelta( * @return This builder for chaining. */ public Builder addPositiveDelta(long value) { - + ensurePositiveDeltaIsMutable(); positiveDelta_.addLong(value); onChanged(); @@ -7830,7 +8501,7 @@ public Builder addPositiveDelta(long value) { public Builder addAllPositiveDelta( java.lang.Iterable values) { ensurePositiveDeltaIsMutable(); - io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( values, positiveDelta_); onChanged(); return this; @@ -7847,16 +8518,16 @@ public Builder addAllPositiveDelta( */ public Builder clearPositiveDelta() { positiveDelta_ = emptyLongList(); - bitField0_ = (bitField0_ & ~0x00001000); + bitField0_ = (bitField0_ & ~0x00002000); onChanged(); return this; } - private io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_ = emptyDoubleList(); + private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_ = emptyDoubleList(); private void ensurePositiveCountIsMutable() { - if (!((bitField0_ & 0x00002000) != 0)) { + if (!((bitField0_ & 0x00004000) != 0)) { positiveCount_ = mutableCopy(positiveCount_); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00004000; } } /** @@ -7869,7 +8540,7 @@ private void ensurePositiveCountIsMutable() { */ public java.util.List getPositiveCountList() { - return ((bitField0_ & 0x00002000) != 0) ? + return ((bitField0_ & 0x00004000) != 0) ? java.util.Collections.unmodifiableList(positiveCount_) : positiveCount_; } /** @@ -7907,7 +8578,7 @@ public double getPositiveCount(int index) { */ public Builder setPositiveCount( int index, double value) { - + ensurePositiveCountIsMutable(); positiveCount_.setDouble(index, value); onChanged(); @@ -7923,7 +8594,7 @@ public Builder setPositiveCount( * @return This builder for chaining. */ public Builder addPositiveCount(double value) { - + ensurePositiveCountIsMutable(); positiveCount_.addDouble(value); onChanged(); @@ -7941,7 +8612,7 @@ public Builder addPositiveCount(double value) { public Builder addAllPositiveCount( java.lang.Iterable values) { ensurePositiveCountIsMutable(); - io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll( values, positiveCount_); onChanged(); return this; @@ -7956,19 +8627,19 @@ public Builder addAllPositiveCount( */ public Builder clearPositiveCount() { positiveCount_ = emptyDoubleList(); - bitField0_ = (bitField0_ & ~0x00002000); + bitField0_ = (bitField0_ & ~0x00004000); onChanged(); return this; } @java.lang.Override public final Builder setUnknownFields( - final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } @java.lang.Override public final Builder mergeUnknownFields( - final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); } @@ -7986,34 +8657,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser - PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser + PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() { @java.lang.Override public Histogram parsePartialFrom( - io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input, - io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) - throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input, + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { Builder builder = newBuilder(); try { builder.mergeFrom(input, extensionRegistry); - } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) { + } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) { throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); } catch (java.io.IOException e) { - throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) .setUnfinishedMessage(builder.buildPartial()); } return builder.buildPartial(); } }; - public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() { + public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() { return PARSER; } @java.lang.Override - public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() { + public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() { return PARSER; } @@ -8026,7 +8697,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 public interface BucketOrBuilder extends // @@protoc_insertion_point(interface_extends:io.prometheus.client.Bucket) - io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder { + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder { /** *
    @@ -8109,12 +8780,12 @@ public interface BucketOrBuilder extends
        * Protobuf type {@code io.prometheus.client.Bucket}
        */
       public static final class Bucket extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Bucket)
           BucketOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Bucket.newBuilder() to construct.
    -    private Bucket(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Bucket(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Bucket() {
    @@ -8127,18 +8798,13 @@ protected java.lang.Object newInstance(
           return new Bucket();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -8265,7 +8931,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeUInt64(1, cumulativeCount_);
    @@ -8289,19 +8955,19 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeUInt64Size(1, cumulativeCount_);
           }
           if (((bitField0_ & 0x00000004) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(2, upperBound_);
           }
           if (((bitField0_ & 0x00000008) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(3, getExemplar());
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(4, cumulativeCountFloat_);
           }
           size += getUnknownFields().getSerializedSize();
    @@ -8354,17 +9020,17 @@ public int hashCode() {
           hash = (19 * hash) + getDescriptor().hashCode();
           if (hasCumulativeCount()) {
             hash = (37 * hash) + CUMULATIVE_COUNT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 getCumulativeCount());
           }
           if (hasCumulativeCountFloat()) {
             hash = (37 * hash) + CUMULATIVE_COUNT_FLOAT_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getCumulativeCountFloat()));
           }
           if (hasUpperBound()) {
             hash = (37 * hash) + UPPER_BOUND_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getUpperBound()));
           }
           if (hasExemplar()) {
    @@ -8378,71 +9044,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -8462,7 +9130,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -8475,16 +9143,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Bucket}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -8497,12 +9165,12 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
             maybeForceBuilderInitialization();
           }
           private void maybeForceBuilderInitialization() {
    -        if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
                     .alwaysUseFieldBuilders) {
               getExemplarFieldBuilder();
             }
    @@ -8523,7 +9191,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
    @@ -8580,34 +9248,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket)other);
             } else {
    @@ -8642,8 +9310,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -8686,7 +9354,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -8730,7 +9398,7 @@ public long getCumulativeCount() {
            * @return This builder for chaining.
            */
           public Builder setCumulativeCount(long value) {
    -        
    +
             cumulativeCount_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -8786,7 +9454,7 @@ public double getCumulativeCountFloat() {
            * @return This builder for chaining.
            */
           public Builder setCumulativeCountFloat(double value) {
    -        
    +
             cumulativeCountFloat_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -8842,7 +9510,7 @@ public double getUpperBound() {
            * @return This builder for chaining.
            */
           public Builder setUpperBound(double value) {
    -        
    +
             upperBound_ = value;
             bitField0_ |= 0x00000004;
             onChanged();
    @@ -8864,7 +9532,7 @@ public Builder clearUpperBound() {
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
    @@ -8968,11 +9636,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> 
               getExemplarFieldBuilder() {
             if (exemplarBuilder_ == null) {
    -          exemplarBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>(
                       getExemplar(),
                       getParentForChildren(),
    @@ -8983,13 +9651,13 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -9007,34 +9675,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Bucket parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -9047,7 +9715,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface BucketSpanOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.BucketSpan)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * 
    @@ -9100,12 +9768,12 @@ public interface BucketSpanOrBuilder extends
        * Protobuf type {@code io.prometheus.client.BucketSpan}
        */
       public static final class BucketSpan extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.BucketSpan)
           BucketSpanOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use BucketSpan.newBuilder() to construct.
    -    private BucketSpan(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private BucketSpan(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private BucketSpan() {
    @@ -9118,18 +9786,13 @@ protected java.lang.Object newInstance(
           return new BucketSpan();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -9203,7 +9866,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
             output.writeSInt32(1, offset_);
    @@ -9221,11 +9884,11 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeSInt32Size(1, offset_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeUInt32Size(2, length_);
           }
           size += getUnknownFields().getSerializedSize();
    @@ -9279,71 +9942,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -9363,7 +10028,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -9380,16 +10045,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.BucketSpan}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -9402,7 +10067,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -9416,7 +10081,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
    @@ -9463,34 +10128,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan)other);
             } else {
    @@ -9519,8 +10184,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -9551,7 +10216,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -9595,7 +10260,7 @@ public int getOffset() {
            * @return This builder for chaining.
            */
           public Builder setOffset(int value) {
    -        
    +
             offset_ = value;
             bitField0_ |= 0x00000001;
             onChanged();
    @@ -9651,7 +10316,7 @@ public int getLength() {
            * @return This builder for chaining.
            */
           public Builder setLength(int value) {
    -        
    +
             length_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -9673,13 +10338,13 @@ public Builder clearLength() {
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -9697,34 +10362,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public BucketSpan parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -9737,7 +10402,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface ExemplarOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Exemplar)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * repeated .io.prometheus.client.LabelPair label = 1;
    @@ -9791,7 +10456,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
          * optional .google.protobuf.Timestamp timestamp = 3;
          * @return The timestamp.
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp();
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp();
         /**
          * 
          * OpenMetrics-style.
    @@ -9799,18 +10464,18 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
          *
          * optional .google.protobuf.Timestamp timestamp = 3;
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder();
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder();
       }
       /**
        * Protobuf type {@code io.prometheus.client.Exemplar}
        */
       public static final class Exemplar extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Exemplar)
           ExemplarOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Exemplar.newBuilder() to construct.
    -    private Exemplar(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Exemplar(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Exemplar() {
    @@ -9824,18 +10489,13 @@ protected java.lang.Object newInstance(
           return new Exemplar();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -9904,7 +10564,7 @@ public double getValue() {
         }
     
         public static final int TIMESTAMP_FIELD_NUMBER = 3;
    -    private io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp timestamp_;
    +    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp timestamp_;
         /**
          * 
          * OpenMetrics-style.
    @@ -9926,8 +10586,8 @@ public boolean hasTimestamp() {
          * @return The timestamp.
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
    -      return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
    +      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
         }
         /**
          * 
    @@ -9937,8 +10597,8 @@ public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp()
          * optional .google.protobuf.Timestamp timestamp = 3;
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
    -      return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
    +      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
         }
     
         private byte memoizedIsInitialized = -1;
    @@ -9953,7 +10613,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           for (int i = 0; i < label_.size(); i++) {
             output.writeMessage(1, label_.get(i));
    @@ -9974,15 +10634,15 @@ public int getSerializedSize() {
     
           size = 0;
           for (int i = 0; i < label_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(1, label_.get(i));
           }
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeDoubleSize(2, value_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(3, getTimestamp());
           }
           size += getUnknownFields().getSerializedSize();
    @@ -10030,7 +10690,7 @@ public int hashCode() {
           }
           if (hasValue()) {
             hash = (37 * hash) + VALUE_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 java.lang.Double.doubleToLongBits(getValue()));
           }
           if (hasTimestamp()) {
    @@ -10044,71 +10704,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -10128,7 +10790,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -10136,16 +10798,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Exemplar}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -10158,12 +10820,12 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
             maybeForceBuilderInitialization();
           }
           private void maybeForceBuilderInitialization() {
    -        if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
                     .alwaysUseFieldBuilders) {
               getLabelFieldBuilder();
               getTimestampFieldBuilder();
    @@ -10190,7 +10852,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
    @@ -10252,34 +10914,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar)other);
             } else {
    @@ -10309,7 +10971,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   label_ = other.label_;
                   bitField0_ = (bitField0_ & ~0x00000001);
                   labelBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getLabelFieldBuilder() : null;
                 } else {
                   labelBuilder_.addAllMessages(other.label_);
    @@ -10334,8 +10996,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -10381,7 +11043,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -10399,7 +11061,7 @@ private void ensureLabelIsMutable() {
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_;
     
           /**
    @@ -10531,7 +11193,7 @@ public Builder addAllLabel(
               java.lang.Iterable values) {
             if (labelBuilder_ == null) {
               ensureLabelIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, label_);
               onChanged();
             } else {
    @@ -10615,11 +11277,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getLabelBuilderList() {
             return getLabelFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> 
               getLabelFieldBuilder() {
             if (labelBuilder_ == null) {
    -          labelBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>(
                       label_,
                       ((bitField0_ & 0x00000001) != 0),
    @@ -10653,7 +11315,7 @@ public double getValue() {
            * @return This builder for chaining.
            */
           public Builder setValue(double value) {
    -        
    +
             value_ = value;
             bitField0_ |= 0x00000002;
             onChanged();
    @@ -10670,9 +11332,9 @@ public Builder clearValue() {
             return this;
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp timestamp_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder> timestampBuilder_;
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp timestamp_;
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> timestampBuilder_;
           /**
            * 
            * OpenMetrics-style.
    @@ -10692,9 +11354,9 @@ public boolean hasTimestamp() {
            * optional .google.protobuf.Timestamp timestamp = 3;
            * @return The timestamp.
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
             if (timestampBuilder_ == null) {
    -          return timestamp_ == null ? io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
    +          return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
             } else {
               return timestampBuilder_.getMessage();
             }
    @@ -10706,7 +11368,7 @@ public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp getTimestamp()
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
    -      public Builder setTimestamp(io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp value) {
    +      public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
             if (timestampBuilder_ == null) {
               if (value == null) {
                 throw new NullPointerException();
    @@ -10727,7 +11389,7 @@ public Builder setTimestamp(io.prometheus.metrics.com_google_protobuf_3_21_7.Tim
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
           public Builder setTimestamp(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
             if (timestampBuilder_ == null) {
               timestamp_ = builderForValue.build();
             } else {
    @@ -10744,11 +11406,11 @@ public Builder setTimestamp(
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
    -      public Builder mergeTimestamp(io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp value) {
    +      public Builder mergeTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
             if (timestampBuilder_ == null) {
               if (((bitField0_ & 0x00000004) != 0) &&
                 timestamp_ != null &&
    -            timestamp_ != io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
    +            timestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
                 getTimestampBuilder().mergeFrom(value);
               } else {
                 timestamp_ = value;
    @@ -10784,7 +11446,7 @@ public Builder clearTimestamp() {
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder getTimestampBuilder() {
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getTimestampBuilder() {
             bitField0_ |= 0x00000004;
             onChanged();
             return getTimestampFieldBuilder().getBuilder();
    @@ -10796,12 +11458,12 @@ public io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder getTim
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
             if (timestampBuilder_ != null) {
               return timestampBuilder_.getMessageOrBuilder();
             } else {
               return timestamp_ == null ?
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
             }
           }
           /**
    @@ -10811,12 +11473,12 @@ public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTi
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder> 
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
               getTimestampFieldBuilder() {
             if (timestampBuilder_ == null) {
    -          timestampBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder>(
    +          timestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
                       getTimestamp(),
                       getParentForChildren(),
                       isClean());
    @@ -10826,13 +11488,13 @@ public io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampOrBuilder getTi
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -10850,34 +11512,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Exemplar parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -10890,7 +11552,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface MetricOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.Metric)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * repeated .io.prometheus.client.LabelPair label = 1;
    @@ -11006,12 +11668,12 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
        * Protobuf type {@code io.prometheus.client.Metric}
        */
       public static final class Metric extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.Metric)
           MetricOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use Metric.newBuilder() to construct.
    -    private Metric(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private Metric(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private Metric() {
    @@ -11025,18 +11687,13 @@ protected java.lang.Object newInstance(
           return new Metric();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -11246,7 +11903,7 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           for (int i = 0; i < label_.size(); i++) {
             output.writeMessage(1, label_.get(i));
    @@ -11279,31 +11936,31 @@ public int getSerializedSize() {
     
           size = 0;
           for (int i = 0; i < label_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(1, label_.get(i));
           }
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(2, getGauge());
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(3, getCounter());
           }
           if (((bitField0_ & 0x00000004) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(4, getSummary());
           }
           if (((bitField0_ & 0x00000008) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(5, getUntyped());
           }
           if (((bitField0_ & 0x00000020) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeInt64Size(6, timestampMs_);
           }
           if (((bitField0_ & 0x00000010) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(7, getHistogram());
           }
           size += getUnknownFields().getSerializedSize();
    @@ -11390,7 +12047,7 @@ public int hashCode() {
           }
           if (hasTimestampMs()) {
             hash = (37 * hash) + TIMESTAMP_MS_FIELD_NUMBER;
    -        hash = (53 * hash) + io.prometheus.metrics.com_google_protobuf_3_21_7.Internal.hashLong(
    +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
                 getTimestampMs());
           }
           hash = (29 * hash) + getUnknownFields().hashCode();
    @@ -11400,71 +12057,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -11484,7 +12143,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -11492,16 +12151,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.Metric}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -11514,12 +12173,12 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
             maybeForceBuilderInitialization();
           }
           private void maybeForceBuilderInitialization() {
    -        if (io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
                     .alwaysUseFieldBuilders) {
               getLabelFieldBuilder();
               getGaugeFieldBuilder();
    @@ -11570,7 +12229,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
    @@ -11656,34 +12315,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric)other);
             } else {
    @@ -11713,7 +12372,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   label_ = other.label_;
                   bitField0_ = (bitField0_ & ~0x00000001);
                   labelBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getLabelFieldBuilder() : null;
                 } else {
                   labelBuilder_.addAllMessages(other.label_);
    @@ -11750,8 +12409,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -11825,7 +12484,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -11843,7 +12502,7 @@ private void ensureLabelIsMutable() {
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_;
     
           /**
    @@ -11975,7 +12634,7 @@ public Builder addAllLabel(
               java.lang.Iterable values) {
             if (labelBuilder_ == null) {
               ensureLabelIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, label_);
               onChanged();
             } else {
    @@ -12059,11 +12718,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getLabelBuilderList() {
             return getLabelFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> 
               getLabelFieldBuilder() {
             if (labelBuilder_ == null) {
    -          labelBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>(
                       label_,
                       ((bitField0_ & 0x00000001) != 0),
    @@ -12075,7 +12734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge gauge_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> gaugeBuilder_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
    @@ -12179,11 +12838,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> 
               getGaugeFieldBuilder() {
             if (gaugeBuilder_ == null) {
    -          gaugeBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          gaugeBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder>(
                       getGauge(),
                       getParentForChildren(),
    @@ -12194,7 +12853,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter counter_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> counterBuilder_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
    @@ -12298,11 +12957,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> 
               getCounterFieldBuilder() {
             if (counterBuilder_ == null) {
    -          counterBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          counterBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder>(
                       getCounter(),
                       getParentForChildren(),
    @@ -12313,7 +12972,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary summary_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> summaryBuilder_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
    @@ -12417,11 +13076,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> 
               getSummaryFieldBuilder() {
             if (summaryBuilder_ == null) {
    -          summaryBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          summaryBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder>(
                       getSummary(),
                       getParentForChildren(),
    @@ -12432,7 +13091,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped untyped_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> untypedBuilder_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
    @@ -12536,11 +13195,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> 
               getUntypedFieldBuilder() {
             if (untypedBuilder_ == null) {
    -          untypedBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          untypedBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder>(
                       getUntyped(),
                       getParentForChildren(),
    @@ -12551,7 +13210,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
     
           private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram histogram_;
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> histogramBuilder_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
    @@ -12655,11 +13314,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> 
               getHistogramFieldBuilder() {
             if (histogramBuilder_ == null) {
    -          histogramBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
    +          histogramBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder>(
                       getHistogram(),
                       getParentForChildren(),
    @@ -12692,7 +13351,7 @@ public long getTimestampMs() {
            * @return This builder for chaining.
            */
           public Builder setTimestampMs(long value) {
    -        
    +
             timestampMs_ = value;
             bitField0_ |= 0x00000040;
             onChanged();
    @@ -12710,13 +13369,13 @@ public Builder clearTimestampMs() {
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -12734,34 +13393,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public Metric parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -12774,7 +13433,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       public interface MetricFamilyOrBuilder extends
           // @@protoc_insertion_point(interface_extends:io.prometheus.client.MetricFamily)
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.MessageOrBuilder {
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
     
         /**
          * optional string name = 1;
    @@ -12790,7 +13449,7 @@ public interface MetricFamilyOrBuilder extends
          * optional string name = 1;
          * @return The bytes for name.
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getNameBytes();
     
         /**
    @@ -12807,7 +13466,7 @@ public interface MetricFamilyOrBuilder extends
          * optional string help = 2;
          * @return The bytes for help.
          */
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getHelpBytes();
     
         /**
    @@ -12849,12 +13508,12 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
        * Protobuf type {@code io.prometheus.client.MetricFamily}
        */
       public static final class MetricFamily extends
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
           // @@protoc_insertion_point(message_implements:io.prometheus.client.MetricFamily)
           MetricFamilyOrBuilder {
       private static final long serialVersionUID = 0L;
         // Use MetricFamily.newBuilder() to construct.
    -    private MetricFamily(io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
    +    private MetricFamily(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
           super(builder);
         }
         private MetricFamily() {
    @@ -12871,18 +13530,13 @@ protected java.lang.Object newInstance(
           return new MetricFamily();
         }
     
    -    @java.lang.Override
    -    public final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet
    -    getUnknownFields() {
    -      return this.unknownFields;
    -    }
    -    public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
             getDescriptor() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
         }
     
         @java.lang.Override
    -    protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
             internalGetFieldAccessorTable() {
           return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
               .ensureFieldAccessorsInitialized(
    @@ -12911,8 +13565,8 @@ public java.lang.String getName() {
           if (ref instanceof java.lang.String) {
             return (java.lang.String) ref;
           } else {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = 
    -            (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
    +            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             java.lang.String s = bs.toStringUtf8();
             if (bs.isValidUtf8()) {
               name_ = s;
    @@ -12925,17 +13579,17 @@ public java.lang.String getName() {
          * @return The bytes for name.
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getNameBytes() {
           java.lang.Object ref = name_;
           if (ref instanceof java.lang.String) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -            io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                     (java.lang.String) ref);
             name_ = b;
             return b;
           } else {
    -        return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
           }
         }
     
    @@ -12960,8 +13614,8 @@ public java.lang.String getHelp() {
           if (ref instanceof java.lang.String) {
             return (java.lang.String) ref;
           } else {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs = 
    -            (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
    +            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             java.lang.String s = bs.toStringUtf8();
             if (bs.isValidUtf8()) {
               help_ = s;
    @@ -12974,17 +13628,17 @@ public java.lang.String getHelp() {
          * @return The bytes for help.
          */
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
             getHelpBytes() {
           java.lang.Object ref = help_;
           if (ref instanceof java.lang.String) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -            io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                     (java.lang.String) ref);
             help_ = b;
             return b;
           } else {
    -        return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
           }
         }
     
    @@ -13059,13 +13713,13 @@ public final boolean isInitialized() {
         }
     
         @java.lang.Override
    -    public void writeTo(io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream output)
    +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
                             throws java.io.IOException {
           if (((bitField0_ & 0x00000001) != 0)) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, help_);
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, help_);
           }
           if (((bitField0_ & 0x00000004) != 0)) {
             output.writeEnum(3, type_);
    @@ -13083,17 +13737,17 @@ public int getSerializedSize() {
     
           size = 0;
           if (((bitField0_ & 0x00000001) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
           }
           if (((bitField0_ & 0x00000002) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, help_);
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, help_);
           }
           if (((bitField0_ & 0x00000004) != 0)) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeEnumSize(3, type_);
           }
           for (int i = 0; i < metric_.size(); i++) {
    -        size += io.prometheus.metrics.com_google_protobuf_3_21_7.CodedOutputStream
    +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
               .computeMessageSize(4, metric_.get(i));
           }
           size += getUnknownFields().getSerializedSize();
    @@ -13161,71 +13815,73 @@ public int hashCode() {
     
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
             java.nio.ByteBuffer data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
             java.nio.ByteBuffer data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(byte[] data)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
             byte[] data,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -        throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
           return PARSER.parseFrom(data, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input);
         }
    +
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom(
             java.io.InputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input);
         }
         public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
             throws java.io.IOException {
    -      return io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3
    +      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
               .parseWithIOException(PARSER, input, extensionRegistry);
         }
     
    @@ -13245,7 +13901,7 @@ public Builder toBuilder() {
     
         @java.lang.Override
         protected Builder newBuilderForType(
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
           Builder builder = new Builder(parent);
           return builder;
         }
    @@ -13253,16 +13909,16 @@ protected Builder newBuilderForType(
          * Protobuf type {@code io.prometheus.client.MetricFamily}
          */
         public static final class Builder extends
    -        io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
    +        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
             // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
             io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamilyOrBuilder {
    -      public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptor() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
     
           @java.lang.Override
    -      protected io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
    @@ -13275,7 +13931,7 @@ private Builder() {
           }
     
           private Builder(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
             super(parent);
     
           }
    @@ -13297,7 +13953,7 @@ public Builder clear() {
           }
     
           @java.lang.Override
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
               getDescriptorForType() {
             return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
    @@ -13361,34 +14017,34 @@ public Builder clone() {
           }
           @java.lang.Override
           public Builder setField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.setField(field, value);
           }
           @java.lang.Override
           public Builder clearField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
             return super.clearField(field);
           }
           @java.lang.Override
           public Builder clearOneof(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
             return super.clearOneof(oneof);
           }
           @java.lang.Override
           public Builder setRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               int index, java.lang.Object value) {
             return super.setRepeatedField(field, index, value);
           }
           @java.lang.Override
           public Builder addRepeatedField(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
               java.lang.Object value) {
             return super.addRepeatedField(field, value);
           }
           @java.lang.Override
    -      public Builder mergeFrom(io.prometheus.metrics.com_google_protobuf_3_21_7.Message other) {
    +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
             if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily) {
               return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily)other);
             } else {
    @@ -13431,7 +14087,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                   metric_ = other.metric_;
                   bitField0_ = (bitField0_ & ~0x00000008);
                   metricBuilder_ = 
    -                io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
    +                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
                        getMetricFieldBuilder() : null;
                 } else {
                   metricBuilder_.addAllMessages(other.metric_);
    @@ -13450,8 +14106,8 @@ public final boolean isInitialized() {
     
           @java.lang.Override
           public Builder mergeFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             if (extensionRegistry == null) {
               throw new java.lang.NullPointerException();
    @@ -13507,7 +14163,7 @@ public Builder mergeFrom(
                   } // default:
                 } // switch (tag)
               } // while (!done)
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.unwrapIOException();
             } finally {
               onChanged();
    @@ -13531,8 +14187,8 @@ public boolean hasName() {
           public java.lang.String getName() {
             java.lang.Object ref = name_;
             if (!(ref instanceof java.lang.String)) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs =
    -              (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
    +              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
    @@ -13546,17 +14202,17 @@ public java.lang.String getName() {
            * optional string name = 1;
            * @return The bytes for name.
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof String) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
    -          return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             }
           }
           /**
    @@ -13588,7 +14244,7 @@ public Builder clearName() {
            * @return This builder for chaining.
            */
           public Builder setNameBytes(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
             if (value == null) { throw new NullPointerException(); }
             name_ = value;
             bitField0_ |= 0x00000001;
    @@ -13611,8 +14267,8 @@ public boolean hasHelp() {
           public java.lang.String getHelp() {
             java.lang.Object ref = help_;
             if (!(ref instanceof java.lang.String)) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString bs =
    -              (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
    +              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 help_ = s;
    @@ -13626,17 +14282,17 @@ public java.lang.String getHelp() {
            * optional string help = 2;
            * @return The bytes for help.
            */
    -      public io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString
    +      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
               getHelpBytes() {
             java.lang.Object ref = help_;
             if (ref instanceof String) {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString b = 
    -              io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
    +              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               help_ = b;
               return b;
             } else {
    -          return (io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString) ref;
    +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
             }
           }
           /**
    @@ -13668,7 +14324,7 @@ public Builder clearHelp() {
            * @return This builder for chaining.
            */
           public Builder setHelpBytes(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ByteString value) {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
             if (value == null) { throw new NullPointerException(); }
             help_ = value;
             bitField0_ |= 0x00000002;
    @@ -13727,7 +14383,7 @@ private void ensureMetricIsMutable() {
              }
           }
     
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> metricBuilder_;
     
           /**
    @@ -13859,7 +14515,7 @@ public Builder addAllMetric(
               java.lang.Iterable values) {
             if (metricBuilder_ == null) {
               ensureMetricIsMutable();
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
                   values, metric_);
               onChanged();
             } else {
    @@ -13943,11 +14599,11 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
                getMetricBuilderList() {
             return getMetricFieldBuilder().getBuilderList();
           }
    -      private io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
               io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> 
               getMetricFieldBuilder() {
             if (metricBuilder_ == null) {
    -          metricBuilder_ = new io.prometheus.metrics.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
    +          metricBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
                   io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder>(
                       metric_,
                       ((bitField0_ & 0x00000008) != 0),
    @@ -13959,13 +14615,13 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
           }
           @java.lang.Override
           public final Builder setUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.setUnknownFields(unknownFields);
           }
     
           @java.lang.Override
           public final Builder mergeUnknownFields(
    -          final io.prometheus.metrics.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
    +          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
             return super.mergeUnknownFields(unknownFields);
           }
     
    @@ -13983,34 +14639,34 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           return DEFAULT_INSTANCE;
         }
     
    -    @java.lang.Deprecated public static final io.prometheus.metrics.com_google_protobuf_3_21_7.Parser
    -        PARSER = new io.prometheus.metrics.com_google_protobuf_3_21_7.AbstractParser() {
    +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
    +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
           @java.lang.Override
           public MetricFamily parsePartialFrom(
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.CodedInputStream input,
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    -          throws io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
    +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
             Builder builder = newBuilder();
             try {
               builder.mergeFrom(input, extensionRegistry);
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
               throw e.setUnfinishedMessage(builder.buildPartial());
    -        } catch (io.prometheus.metrics.com_google_protobuf_3_21_7.UninitializedMessageException e) {
    +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
               throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
             } catch (java.io.IOException e) {
    -          throw new io.prometheus.metrics.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
    +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
                   .setUnfinishedMessage(builder.buildPartial());
             }
             return builder.buildPartial();
           }
         };
     
    -    public static io.prometheus.metrics.com_google_protobuf_3_21_7.Parser parser() {
    +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
           return PARSER;
         }
     
         @java.lang.Override
    -    public io.prometheus.metrics.com_google_protobuf_3_21_7.Parser getParserForType() {
    +    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
           return PARSER;
         }
     
    @@ -14021,200 +14677,205 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
     
       }
     
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_LabelPair_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_LabelPair_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Gauge_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Gauge_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Counter_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Counter_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Quantile_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Quantile_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Summary_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Summary_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Untyped_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Untyped_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Histogram_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Histogram_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Bucket_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Bucket_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_BucketSpan_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Exemplar_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Exemplar_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_Metric_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_Metric_fieldAccessorTable;
    -  private static final io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.Descriptor
    +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
         internal_static_io_prometheus_client_MetricFamily_descriptor;
       private static final 
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
           internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable;
     
    -  public static io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
    +  public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
           getDescriptor() {
         return descriptor;
       }
    -  private static  io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
    +  private static  io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
           descriptor;
       static {
         java.lang.String[] descriptorData = {
           "\n\037src/main/protobuf/metrics.proto\022\024io.pr" +
           "ometheus.client\032\037google/protobuf/timesta" +
           "mp.proto\"(\n\tLabelPair\022\014\n\004name\030\001 \001(\t\022\r\n\005v" +
    -      "alue\030\002 \001(\t\"\026\n\005Gauge\022\r\n\005value\030\001 \001(\001\"J\n\007Co" +
    -      "unter\022\r\n\005value\030\001 \001(\001\0220\n\010exemplar\030\002 \001(\0132\036" +
    -      ".io.prometheus.client.Exemplar\"+\n\010Quanti" +
    -      "le\022\020\n\010quantile\030\001 \001(\001\022\r\n\005value\030\002 \001(\001\"e\n\007S" +
    -      "ummary\022\024\n\014sample_count\030\001 \001(\004\022\022\n\nsample_s" +
    -      "um\030\002 \001(\001\0220\n\010quantile\030\003 \003(\0132\036.io.promethe" +
    -      "us.client.Quantile\"\030\n\007Untyped\022\r\n\005value\030\001" +
    -      " \001(\001\"\247\003\n\tHistogram\022\024\n\014sample_count\030\001 \001(\004" +
    -      "\022\032\n\022sample_count_float\030\004 \001(\001\022\022\n\nsample_s" +
    -      "um\030\002 \001(\001\022,\n\006bucket\030\003 \003(\0132\034.io.prometheus" +
    -      ".client.Bucket\022\016\n\006schema\030\005 \001(\021\022\026\n\016zero_t" +
    -      "hreshold\030\006 \001(\001\022\022\n\nzero_count\030\007 \001(\004\022\030\n\020ze" +
    -      "ro_count_float\030\010 \001(\001\0227\n\rnegative_span\030\t " +
    -      "\003(\0132 .io.prometheus.client.BucketSpan\022\026\n" +
    -      "\016negative_delta\030\n \003(\022\022\026\n\016negative_count\030" +
    -      "\013 \003(\001\0227\n\rpositive_span\030\014 \003(\0132 .io.promet" +
    -      "heus.client.BucketSpan\022\026\n\016positive_delta" +
    -      "\030\r \003(\022\022\026\n\016positive_count\030\016 \003(\001\"\211\001\n\006Bucke" +
    -      "t\022\030\n\020cumulative_count\030\001 \001(\004\022\036\n\026cumulativ" +
    -      "e_count_float\030\004 \001(\001\022\023\n\013upper_bound\030\002 \001(\001" +
    -      "\0220\n\010exemplar\030\003 \001(\0132\036.io.prometheus.clien" +
    -      "t.Exemplar\",\n\nBucketSpan\022\016\n\006offset\030\001 \001(\021" +
    -      "\022\016\n\006length\030\002 \001(\r\"x\n\010Exemplar\022.\n\005label\030\001 " +
    -      "\003(\0132\037.io.prometheus.client.LabelPair\022\r\n\005" +
    -      "value\030\002 \001(\001\022-\n\ttimestamp\030\003 \001(\0132\032.google." +
    -      "protobuf.Timestamp\"\276\002\n\006Metric\022.\n\005label\030\001" +
    -      " \003(\0132\037.io.prometheus.client.LabelPair\022*\n" +
    -      "\005gauge\030\002 \001(\0132\033.io.prometheus.client.Gaug" +
    -      "e\022.\n\007counter\030\003 \001(\0132\035.io.prometheus.clien" +
    -      "t.Counter\022.\n\007summary\030\004 \001(\0132\035.io.promethe" +
    -      "us.client.Summary\022.\n\007untyped\030\005 \001(\0132\035.io." +
    -      "prometheus.client.Untyped\0222\n\thistogram\030\007" +
    -      " \001(\0132\037.io.prometheus.client.Histogram\022\024\n" +
    -      "\014timestamp_ms\030\006 \001(\003\"\210\001\n\014MetricFamily\022\014\n\004" +
    -      "name\030\001 \001(\t\022\014\n\004help\030\002 \001(\t\022.\n\004type\030\003 \001(\0162 " +
    -      ".io.prometheus.client.MetricType\022,\n\006metr" +
    -      "ic\030\004 \003(\0132\034.io.prometheus.client.Metric*b" +
    -      "\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUGE\020\001\022\013\n\007" +
    -      "SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n" +
    -      "\017GAUGE_HISTOGRAM\020\005B\212\001\nLio.prometheus.met" +
    -      "rics.expositionformats.generated.com_goo" +
    -      "gle_protobuf_3_21_7Z:github.com/promethe" +
    -      "us/client_model/go;io_prometheus_client"
    +      "alue\030\002 \001(\t\"\026\n\005Gauge\022\r\n\005value\030\001 \001(\001\"\201\001\n\007C" +
    +      "ounter\022\r\n\005value\030\001 \001(\001\0220\n\010exemplar\030\002 \001(\0132" +
    +      "\036.io.prometheus.client.Exemplar\0225\n\021creat" +
    +      "ed_timestamp\030\003 \001(\0132\032.google.protobuf.Tim" +
    +      "estamp\"+\n\010Quantile\022\020\n\010quantile\030\001 \001(\001\022\r\n\005" +
    +      "value\030\002 \001(\001\"\234\001\n\007Summary\022\024\n\014sample_count\030" +
    +      "\001 \001(\004\022\022\n\nsample_sum\030\002 \001(\001\0220\n\010quantile\030\003 " +
    +      "\003(\0132\036.io.prometheus.client.Quantile\0225\n\021c" +
    +      "reated_timestamp\030\004 \001(\0132\032.google.protobuf" +
    +      ".Timestamp\"\030\n\007Untyped\022\r\n\005value\030\001 \001(\001\"\336\003\n" +
    +      "\tHistogram\022\024\n\014sample_count\030\001 \001(\004\022\032\n\022samp" +
    +      "le_count_float\030\004 \001(\001\022\022\n\nsample_sum\030\002 \001(\001" +
    +      "\022,\n\006bucket\030\003 \003(\0132\034.io.prometheus.client." +
    +      "Bucket\0225\n\021created_timestamp\030\017 \001(\0132\032.goog" +
    +      "le.protobuf.Timestamp\022\016\n\006schema\030\005 \001(\021\022\026\n" +
    +      "\016zero_threshold\030\006 \001(\001\022\022\n\nzero_count\030\007 \001(" +
    +      "\004\022\030\n\020zero_count_float\030\010 \001(\001\0227\n\rnegative_" +
    +      "span\030\t \003(\0132 .io.prometheus.client.Bucket" +
    +      "Span\022\026\n\016negative_delta\030\n \003(\022\022\026\n\016negative" +
    +      "_count\030\013 \003(\001\0227\n\rpositive_span\030\014 \003(\0132 .io" +
    +      ".prometheus.client.BucketSpan\022\026\n\016positiv" +
    +      "e_delta\030\r \003(\022\022\026\n\016positive_count\030\016 \003(\001\"\211\001" +
    +      "\n\006Bucket\022\030\n\020cumulative_count\030\001 \001(\004\022\036\n\026cu" +
    +      "mulative_count_float\030\004 \001(\001\022\023\n\013upper_boun" +
    +      "d\030\002 \001(\001\0220\n\010exemplar\030\003 \001(\0132\036.io.prometheu" +
    +      "s.client.Exemplar\",\n\nBucketSpan\022\016\n\006offse" +
    +      "t\030\001 \001(\021\022\016\n\006length\030\002 \001(\r\"x\n\010Exemplar\022.\n\005l" +
    +      "abel\030\001 \003(\0132\037.io.prometheus.client.LabelP" +
    +      "air\022\r\n\005value\030\002 \001(\001\022-\n\ttimestamp\030\003 \001(\0132\032." +
    +      "google.protobuf.Timestamp\"\276\002\n\006Metric\022.\n\005" +
    +      "label\030\001 \003(\0132\037.io.prometheus.client.Label" +
    +      "Pair\022*\n\005gauge\030\002 \001(\0132\033.io.prometheus.clie" +
    +      "nt.Gauge\022.\n\007counter\030\003 \001(\0132\035.io.prometheu" +
    +      "s.client.Counter\022.\n\007summary\030\004 \001(\0132\035.io.p" +
    +      "rometheus.client.Summary\022.\n\007untyped\030\005 \001(" +
    +      "\0132\035.io.prometheus.client.Untyped\0222\n\thist" +
    +      "ogram\030\007 \001(\0132\037.io.prometheus.client.Histo" +
    +      "gram\022\024\n\014timestamp_ms\030\006 \001(\003\"\210\001\n\014MetricFam" +
    +      "ily\022\014\n\004name\030\001 \001(\t\022\014\n\004help\030\002 \001(\t\022.\n\004type\030" +
    +      "\003 \001(\0162 .io.prometheus.client.MetricType\022" +
    +      ",\n\006metric\030\004 \003(\0132\034.io.prometheus.client.M" +
    +      "etric*b\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUG" +
    +      "E\020\001\022\013\n\007SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGR" +
    +      "AM\020\004\022\023\n\017GAUGE_HISTOGRAM\020\005B\212\001\nLio.prometh" +
    +      "eus.metrics.expositionformats.generated." +
    +      "com_google_protobuf_3_21_7Z:github.com/p" +
    +      "rometheus/client_model/go;io_prometheus_" +
    +      "client"
         };
    -    descriptor = io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
    +    descriptor = io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
           .internalBuildGeneratedFileFrom(descriptorData,
    -        new io.prometheus.metrics.com_google_protobuf_3_21_7.Descriptors.FileDescriptor[] {
    -          io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampProto.getDescriptor(),
    +        new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor[] {
    +          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampProto.getDescriptor(),
             });
         internal_static_io_prometheus_client_LabelPair_descriptor =
           getDescriptor().getMessageTypes().get(0);
         internal_static_io_prometheus_client_LabelPair_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_LabelPair_descriptor,
             new java.lang.String[] { "Name", "Value", });
         internal_static_io_prometheus_client_Gauge_descriptor =
           getDescriptor().getMessageTypes().get(1);
         internal_static_io_prometheus_client_Gauge_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Gauge_descriptor,
             new java.lang.String[] { "Value", });
         internal_static_io_prometheus_client_Counter_descriptor =
           getDescriptor().getMessageTypes().get(2);
         internal_static_io_prometheus_client_Counter_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Counter_descriptor,
    -        new java.lang.String[] { "Value", "Exemplar", });
    +        new java.lang.String[] { "Value", "Exemplar", "CreatedTimestamp", });
         internal_static_io_prometheus_client_Quantile_descriptor =
           getDescriptor().getMessageTypes().get(3);
         internal_static_io_prometheus_client_Quantile_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Quantile_descriptor,
             new java.lang.String[] { "Quantile", "Value", });
         internal_static_io_prometheus_client_Summary_descriptor =
           getDescriptor().getMessageTypes().get(4);
         internal_static_io_prometheus_client_Summary_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Summary_descriptor,
    -        new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", });
    +        new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", "CreatedTimestamp", });
         internal_static_io_prometheus_client_Untyped_descriptor =
           getDescriptor().getMessageTypes().get(5);
         internal_static_io_prometheus_client_Untyped_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Untyped_descriptor,
             new java.lang.String[] { "Value", });
         internal_static_io_prometheus_client_Histogram_descriptor =
           getDescriptor().getMessageTypes().get(6);
         internal_static_io_prometheus_client_Histogram_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Histogram_descriptor,
    -        new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", });
    +        new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "CreatedTimestamp", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", });
         internal_static_io_prometheus_client_Bucket_descriptor =
           getDescriptor().getMessageTypes().get(7);
         internal_static_io_prometheus_client_Bucket_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Bucket_descriptor,
             new java.lang.String[] { "CumulativeCount", "CumulativeCountFloat", "UpperBound", "Exemplar", });
         internal_static_io_prometheus_client_BucketSpan_descriptor =
           getDescriptor().getMessageTypes().get(8);
         internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_BucketSpan_descriptor,
             new java.lang.String[] { "Offset", "Length", });
         internal_static_io_prometheus_client_Exemplar_descriptor =
           getDescriptor().getMessageTypes().get(9);
         internal_static_io_prometheus_client_Exemplar_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Exemplar_descriptor,
             new java.lang.String[] { "Label", "Value", "Timestamp", });
         internal_static_io_prometheus_client_Metric_descriptor =
           getDescriptor().getMessageTypes().get(10);
         internal_static_io_prometheus_client_Metric_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_Metric_descriptor,
             new java.lang.String[] { "Label", "Gauge", "Counter", "Summary", "Untyped", "Histogram", "TimestampMs", });
         internal_static_io_prometheus_client_MetricFamily_descriptor =
           getDescriptor().getMessageTypes().get(11);
         internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable = new
    -      io.prometheus.metrics.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
    +      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
             internal_static_io_prometheus_client_MetricFamily_descriptor,
             new java.lang.String[] { "Name", "Help", "Type", "Metric", });
    -    io.prometheus.metrics.com_google_protobuf_3_21_7.TimestampProto.getDescriptor();
    +    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampProto.getDescriptor();
       }
     
       // @@protoc_insertion_point(outer_class_scope)
    diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
    index 6f4eb6e67..eea5f929a 100644
    --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
    +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
    @@ -1,6 +1,6 @@
     package io.prometheus.metrics.expositionformats;
     
    -import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat;
    +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat;
     import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics;
     import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
     import io.prometheus.metrics.model.snapshots.CounterSnapshot;
    diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
    index fe496df8c..e8beeee6c 100644
    --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
    +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
    @@ -1,6 +1,6 @@
     package io.prometheus.metrics.expositionformats;
     
    -import io.prometheus.metrics.com_google_protobuf_3_21_7.Timestamp;
    +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp;
     
     public class ProtobufUtil {
     
    diff --git a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
    index b351b6d5a..1faefbca4 100644
    --- a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
    +++ b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
    @@ -46,6 +46,8 @@ message Gauge {
     message Counter {
       optional double   value    = 1;
       optional Exemplar exemplar = 2;
    +
    +  optional google.protobuf.Timestamp  created_timestamp = 3;
     }
     
     message Quantile {
    @@ -57,6 +59,8 @@ message Summary {
       optional uint64   sample_count = 1;
       optional double   sample_sum   = 2;
       repeated Quantile quantile     = 3;
    +
    +  optional google.protobuf.Timestamp  created_timestamp = 4;
     }
     
     message Untyped {
    @@ -70,6 +74,8 @@ message Histogram {
       // Buckets for the conventional histogram.
       repeated Bucket bucket             = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
     
    +  optional google.protobuf.Timestamp created_timestamp = 15;
    +
       // Everything below here is for native histograms (also known as sparse histograms).
       // Native histograms are an experimental feature without stability guarantees.
     
    @@ -92,6 +98,9 @@ message Histogram {
       repeated double negative_count    = 11; // Absolute count of each bucket.
     
       // Positive buckets for the native histogram.
    +  // Use a no-op span (offset 0, length 0) for a native histogram without any
    +  // observations yet and with a zero_threshold of 0. Otherwise, it would be
    +  // indistinguishable from a classic histogram.
       repeated BucketSpan positive_span = 12;
       // Use either "positive_delta" or "positive_count", the former for
       // regular histograms with integer counts, the latter for float
    diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
    index 7c9e714df..cf6cb09a6 100644
    --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
    +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
    @@ -1,6 +1,6 @@
     package io.prometheus.metrics.expositionformats;
     
    -import io.prometheus.metrics.com_google_protobuf_3_21_7.TextFormat;
    +import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat;
     import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics;
     import io.prometheus.metrics.model.snapshots.CounterSnapshot;
     import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
    diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java
    index 6e0890a99..6cad6a6a3 100644
    --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java
    +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java
    @@ -21,7 +21,7 @@
     public class NativeHistogramBuckets implements Iterable {
     
         public static final NativeHistogramBuckets EMPTY = new NativeHistogramBuckets(new int[]{}, new long[]{});
    -    private final int[] bucketIndexes;
    +    private final int[] bucketIndexes; // sorted
         private final long[] counts;
     
         private NativeHistogramBuckets(int[] bucketIndexes, long[] counts) {
    diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
    new file mode 100644
    index 000000000..b872ee0ce
    --- /dev/null
    +++ b/prometheus-metrics-shaded-dependencies/pom.xml
    @@ -0,0 +1,40 @@
    +
    +
    +    4.0.0
    +
    +    
    +        io.prometheus
    +        client_java
    +        1.0.0-alpha-3-SNAPSHOT
    +    
    +
    +    prometheus-metrics-shaded-dependencies
    +    pom
    +
    +    Shaded Dependencies
    +    
    +        Shaded (relocated to another packagage) dependencies.
    +    
    +
    +    
    +        
    +            The Apache Software License, Version 2.0
    +            http://www.apache.org/licenses/LICENSE-2.0.txt
    +            repo
    +        
    +    
    +
    +    
    +        
    +            fstab
    +            Fabian Stäber
    +            fabian@fstab.de
    +        
    +    
    +
    +    
    +        prometheus-metrics-shaded-opentelemetry
    +        prometheus-metrics-shaded-protobuf
    +    
    +
    +
    diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
    new file mode 100644
    index 000000000..d68cc1c04
    --- /dev/null
    +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
    @@ -0,0 +1,126 @@
    +
    +
    +    4.0.0
    +
    +    
    +        io.prometheus
    +        prometheus-metrics-shaded-dependencies
    +        1.0.0-alpha-3-SNAPSHOT
    +    
    +
    +    prometheus-metrics-shaded-opentelemetry
    +
    +    Shaded OpenTelemetry
    +    
    +        Shaded (reolocated to another package) dependencies for the OpenTelemetry exporter module.
    +    
    +
    +    
    +        1.28.0
    +        ${otel.version}-alpha
    +        1_28_0
    +    
    +
    +    
    +        
    +            The Apache Software License, Version 2.0
    +            http://www.apache.org/licenses/LICENSE-2.0.txt
    +            repo
    +        
    +    
    +
    +    
    +        
    +            fstab
    +            Fabian Stäber
    +            fabian@fstab.de
    +        
    +    
    +
    +    
    +        
    +            io.opentelemetry
    +            opentelemetry-api
    +            ${otel.version}
    +        
    +        
    +            io.opentelemetry
    +            opentelemetry-sdk
    +            ${otel.version}
    +        
    +        
    +            io.opentelemetry
    +            opentelemetry-semconv
    +            ${otel.semconv.version}
    +        
    +        
    +            io.opentelemetry
    +            opentelemetry-exporter-otlp
    +            ${otel.version}
    +        
    +    
    +
    +    
    +        
    +            
    +                org.apache.maven.plugins
    +                maven-shade-plugin
    +                
    +                    
    +                        package
    +                        
    +                            shade
    +                        
    +                        
    +                            
    +                                
    +                                    io.opentelemetry
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}
    +                                
    +                                
    +                                    okhttp3
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.okhttp3
    +                                
    +                                
    +                                    kotlin
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.kotlin
    +                                
    +                                
    +                                    org.intellij
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.org.intellij
    +                                
    +                                
    +                                    org.jetbrains
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.org.jetbrains
    +                                
    +                                
    +                                    okio
    +                                    io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.okio
    +                                
    +                            
    +                            
    +                                
    +                                
    +                            
    +                            
    +                                
    +                                    *:*
    +                                    
    +                                        META-INF/maven/org.jctools/**
    +                                        META-INF/maven/org.jetbrains/**
    +                                        META-INF/versions/**
    +                                        META-INF/native-image/**
    +                                        META-INF/proguard/**
    +                                        META-INF/*.kotlin_module
    +                                        META-INF/MANIFEST.MF
    +                                    
    +                                
    +                            
    +                        
    +                    
    +                
    +            
    +        
    +    
    +
    diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java
    new file mode 100644
    index 000000000..7b0019461
    --- /dev/null
    +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java
    @@ -0,0 +1,9 @@
    +package io.prometheus.metrics.shaded.io_opentelemetry;
    +
    +/**
    + * This module does not need any source code, however, in order to publish it to Maven central it needs JavaDoc.
    + * 

    + * I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. + */ +public class PrometheusMetricsShadedOpenTelemetry { +} diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml new file mode 100644 index 000000000..b856ef185 --- /dev/null +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + + io.prometheus + prometheus-metrics-shaded-dependencies + 1.0.0-alpha-3-SNAPSHOT + + + prometheus-metrics-shaded-protobuf + + Shaded Protobuf + + Shaded (reolocated to another package) dependencies for the Protobuf library used to create the Prometheus + Protobuf format + + + + + + + 3.21.7 + + 3_21_7 + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + com.google.protobuf + protobuf-java + ${protobuf.version} + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + true + true + + + com.google.protobuf + io.prometheus.metrics.shaded.com_google_protobuf_${protobuf.version.string} + + + + + + + + *:* + + META-INF/maven/com.google.protobuf/** + **/*.proto + META-INF/MANIFEST.MF + + + + + + + + + + diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java new file mode 100644 index 000000000..3f63392a7 --- /dev/null +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java @@ -0,0 +1,9 @@ +package io.prometheus.metrics.shaded.com_google_protobuf; + +/** + * This module does not need any source code, however, in order to publish it to Maven central it needs JavaDoc. + *

    + * I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. + */ +public class PrometheusMetricsShadedProtobuf { +} diff --git a/protobuf-shaded/.gitignore b/protobuf-shaded/.gitignore deleted file mode 100644 index b929015f9..000000000 --- a/protobuf-shaded/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src/main/java diff --git a/protobuf-shaded/README.md b/protobuf-shaded/README.md deleted file mode 100644 index 5db4149b7..000000000 --- a/protobuf-shaded/README.md +++ /dev/null @@ -1 +0,0 @@ -See [https://github.com/apache/hbase-thirdparty/tree/master/hbase-shaded-protobuf](https://github.com/apache/hbase-thirdparty/tree/master/hbase-shaded-protobuf) diff --git a/protobuf-shaded/pom.xml b/protobuf-shaded/pom.xml deleted file mode 100644 index ddfe62d98..000000000 --- a/protobuf-shaded/pom.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - 4.0.0 - - - io.prometheus - client_java - 1.0.0-alpha-2-SNAPSHOT - - - protobuf-shaded - Shaded (relocated to another package) Protobuf - - Downloads Google Protobuf, compiles it, and reloacates/shades. - See also hbase-thirdparty/hbase-shaded-protobuf - - - - - - 3.21.7 - - 3_21_7 - - - - - - src/main/java - - - google/** - - - - - - - maven-clean-plugin - - - pre-generate-sources - generate-sources - - clean - - - - - - - ${basedir}/src/main/java - - **/** - - false - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - generate-sources - - unpack - - - - - - com.google.protobuf - protobuf-java - - 3.21.7 - sources - jar - true - ${basedir}/src/main/java - **/** - - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - google/protobuf/*.proto - google/protobuf/compiler/*.proto - - - - - attach-sources - - jar-no-fork - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - true - true - - - com.google.protobuf - - io.prometheus.metrics.com_google_protobuf_${protobuf.version.string} - - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - google/protobuf/*.proto - google/protobuf/compiler/*.proto - - - - - maven-javadoc-plugin - - - com.google.protobuf - - - - - From b68c124c817df7697c06c5e67aee66a1c22c4ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 29 Aug 2023 22:45:26 +0200 Subject: [PATCH 193/980] Make the DefaultHandler in HTTPServer configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/exporter/httpserver/HTTPServer.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 7c0275fc3..47a512066 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -45,13 +45,13 @@ public class HTTPServer implements Closeable { protected final HttpServer server; protected final ExecutorService executorService; - private HTTPServer(PrometheusProperties config, ExecutorService executorService, HttpServer httpServer, PrometheusRegistry registry, Authenticator authenticator) { + private HTTPServer(PrometheusProperties config, ExecutorService executorService, HttpServer httpServer, PrometheusRegistry registry, Authenticator authenticator, HttpHandler defaultHandler) { if (httpServer.getAddress() == null) { throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); } this.server = httpServer; this.executorService = executorService; - registerHandler("/", new DefaultHandler(), authenticator); + registerHandler("/", defaultHandler == null ? new DefaultHandler() : defaultHandler, authenticator); registerHandler("/metrics", new MetricsHandler(config, registry), authenticator); registerHandler("/-/healthy", new HealthyHandler(), authenticator); this.server.start(); @@ -108,6 +108,7 @@ public static class Builder { private ExporterHttpServerProperties properties = null; private Authenticator authenticator = null; private HttpsConfigurator httpsConfigurator = null; + private HttpHandler defaultHandler = null; private Builder(PrometheusProperties config) { this.config = config; @@ -174,6 +175,14 @@ public Builder withHttpsConfigurator(HttpsConfigurator configurator) { return this; } + /** + * Optional: Override default handler, i.e. the handler that will be registered for the / endpoint. + */ + public Builder withDefaultHandler(HttpHandler defaultHandler) { + this.defaultHandler = defaultHandler; + return this; + } + /** * Build and start the HTTPServer. */ @@ -190,7 +199,7 @@ public HTTPServer buildAndStart() throws IOException { } ExecutorService executorService = makeExecutorService(); httpServer.setExecutor(executorService); - return new HTTPServer(config, executorService, httpServer, registry, authenticator); + return new HTTPServer(config, executorService, httpServer, registry, authenticator, defaultHandler); } private InetSocketAddress makeInetSocketAddress() { From de20057419d811cc00b1b70476c7f0cc2253c2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 29 Aug 2023 22:48:31 +0200 Subject: [PATCH 194/980] Temporarily add shaded dependencies to prepare for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba5d97577..47c3ccc61 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ prometheus-metrics-exporter-servlet-jakarta prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry - + prometheus-metrics-shaded-dependencies examples integration-tests From 810cdcb4a916e669645eb585f0aced4e6db70bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 29 Aug 2023 23:02:06 +0200 Subject: [PATCH 195/980] [maven-release-plugin] prepare release v1.0.0-alpha-3 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 4 ++-- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 8 +++----- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 8 +++----- .../it-exporter-servlet-tomcat-sample/pom.xml | 8 +++----- integration-tests/it-exporter/it-exporter-test/pom.xml | 5 ++--- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 5 ++--- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 7 +++---- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 9 ++++----- .../prometheus-metrics-shaded-protobuf/pom.xml | 5 ++--- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- .../simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 66 files changed, 83 insertions(+), 94 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 71f4f67e4..1aa6fad17 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 81c6d573c..a8eeb5d48 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index e91ade6ac..c431418ed 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 0441d0467..65484d6e1 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index a425c3268..467fb348d 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,12 +5,12 @@ io.prometheus examples - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-exporter-httpserver - >Example - HTTPServer Exporter + >Example - HTTPServer Exporter Prometheus Metrics Example using the HTTPServer for exposing the metrics endpoint diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 842faa1a3..a90000162 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index aa89bfc43..fc2cfb930 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 example-exporter-servlet-tomcat diff --git a/examples/pom.xml b/examples/pom.xml index 6535b05e1..df80b2dc9 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index aa81b08e8..3b1f6e7bf 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 8767c971d..e4c82f5d7 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus it-exporter - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-exporter-httpserver-sample @@ -59,8 +58,7 @@ - + io.prometheus.metrics.it.exporter.httpserver.HTTPServerSample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index a470df5c0..d540031c3 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus it-exporter - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-exporter-servlet-jetty-sample @@ -69,8 +68,7 @@ - + io.prometheus.metrics.it.exporter.servlet.jetty.ExporterServletJettySample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index ce389c352..14dc22641 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus it-exporter - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-exporter-servlet-tomcat-sample @@ -64,8 +63,7 @@ - + io.prometheus.metrics.it.exporter.servlet.tomcat.ExporterServletTomcatSample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 8d7404585..46210fb41 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus it-exporter - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index e5a7e8c99..6cfe69392 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-3 diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index cce89906f..606f76c19 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index b837d2539..4ca25a7cb 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index d4e59503c..b92735709 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 1bb9cf17a..9fb9b2546 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 315fe7aa6..d64cb5d18 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 924ab8d79..30ad7acff 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 9fc322067..b5ad62158 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 8520458cf..d5778e6f8 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 58ce74c9f..2daf4dfac 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 integration_tests diff --git a/pom.xml b/pom.xml index 47c3ccc61..97dcd97cc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-3 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 2d4b142f8..8e1b23b44 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 019c8e62a..29006bdf7 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 83a3b1d42..390439f70 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 7ddc44a42..3b14f9dc5 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 6b5266962..0a2cd8150 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-exporter-opentelemetry @@ -163,7 +162,7 @@ - + diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index b1c66016c..8bfdfc261 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index a8eef2c7a..fd3e07332 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index d427bf8ff..5e5624b09 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index b872ee0ce..fabe5129d 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index d68cc1c04..5c1794ba4 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-shaded-opentelemetry @@ -100,8 +99,8 @@ - - + + diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index b856ef185..4f6338bd6 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 6cbda2290..d0273c9a8 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 571d73ba3..c9ec1c6a9 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index bea2bd0d2..d20c307b3 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index c285dc340..0c2f2fac8 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 6d60235c7..d78f16b88 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index d4d55bbc9..2818fd558 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index f43a7943d..756e119ae 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index df6d786b5..20569d351 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 213785cb6..aa51669f1 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index eb95bc7b6..9620fb10b 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 70c20acf1..84c8754d7 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 91d485403..daa0976c8 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 2b39eda26..29d10e14a 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index b078a86ae..2919ee055 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 112b99bcc..b2e145427 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index a2380c4c4..e6c9be70e 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 7e2b1400b..0c90d94b7 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index a51fd5c38..601b78883 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 4fd9630f8..278d3927a 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 7ffb3d797..68c5cf331 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index dfe24b0f6..14e1db742 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 2e0f55124..9e50abf59 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 9f158dc38..e3e087827 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 6c1957a19..f714b6fae 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index a08e967dc..8b5543dd4 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 0e8eff353..c98b788ea 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 1dff24da5..1b1381afc 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index be1b894e8..01558b9ee 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 8574abbff..15120bf10 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 0c7da6903..dadab7e3e 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 0bf3a1052..75dd831a8 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3-SNAPSHOT + 1.0.0-alpha-3 simpleclient_vertx4 From 950cedb9c5d67de39347c96e92971cd424f3832b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 29 Aug 2023 23:02:10 +0200 Subject: [PATCH 196/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 66 files changed, 68 insertions(+), 68 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 1aa6fad17..783ee55eb 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index a8eeb5d48..f6ab3646b 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index c431418ed..c37ab1418 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 65484d6e1..4f34ee5ab 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 467fb348d..907e7f44e 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index a90000162..076cdd24e 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index fc2cfb930..345a4328f 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/pom.xml b/examples/pom.xml index df80b2dc9..bbbe729f6 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 3b1f6e7bf..0e3b099c6 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index e4c82f5d7..d4f83ac82 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index d540031c3..104666b07 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 14dc22641..ccfbcdc12 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 46210fb41..59110421d 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 6cfe69392..b14c5bca6 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-3 + HEAD diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 606f76c19..223de113f 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 4ca25a7cb..5a36f4489 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index b92735709..625d2c9b9 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 9fb9b2546..b9cd61ca1 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index d64cb5d18..dd303f86e 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 30ad7acff..38bfa4fb3 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index b5ad62158..9d3cab3a2 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index d5778e6f8..195f5ae46 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 2daf4dfac..942b912ab 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index 97dcd97cc..c6f25cd14 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-3 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 8e1b23b44..071cf4a28 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 29006bdf7..2151549bd 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 390439f70..309674dbd 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 3b14f9dc5..8675e8047 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 0a2cd8150..a331de619 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 8bfdfc261..9a369f799 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index fd3e07332..62f6a806b 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 5e5624b09..8a8c20631 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index fabe5129d..0e0f4f266 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 5c1794ba4..fd69c1689 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 4f6338bd6..47746ea40 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index d0273c9a8..d000e3ea6 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index c9ec1c6a9..0e01fd462 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index d20c307b3..4a15f1189 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 0c2f2fac8..e5bab6fc5 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index d78f16b88..e3c01697f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 2818fd558..f5f030552 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 756e119ae..f78c01c6d 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 20569d351..4a820d18c 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index aa51669f1..a3facdc4f 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 9620fb10b..deede1590 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 84c8754d7..67e48acd2 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index daa0976c8..50b704b75 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 29d10e14a..df4569384 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 2919ee055..4dc25a5f5 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index b2e145427..c8bcaee09 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index e6c9be70e..91d9ca763 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 0c90d94b7..26c601a77 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 601b78883..1d804e9c9 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 278d3927a..31805d97d 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 68c5cf331..39e6acabb 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 14e1db742..4fb7ab4b8 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 9e50abf59..4c7e4d4fa 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index e3e087827..ad3ce2f57 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index f714b6fae..d223bc04e 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 8b5543dd4..3c36741f6 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index c98b788ea..74ca017da 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 1b1381afc..996ccb70d 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 01558b9ee..c86e7c1f5 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 15120bf10..71299100b 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index dadab7e3e..c2d5b0ee1 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 75dd831a8..50d3bdeea 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-3 + 1.0.0-alpha-4-SNAPSHOT simpleclient_vertx4 From b94922fad2a31d4fa2b04cccdf1666b7e5c2731f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 29 Aug 2023 23:35:26 +0200 Subject: [PATCH 197/980] Exclude shaded dependencies from the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c6f25cd14..cb9c242e7 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ prometheus-metrics-exporter-servlet-jakarta prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry - prometheus-metrics-shaded-dependencies + examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index a331de619..033bd8c99 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - ${project.version} + 1.0.0-alpha-3 From f9a42e604e59385dd7e44554fae6663663c404bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 30 Aug 2023 23:14:39 +0200 Subject: [PATCH 198/980] Prevent unnecessary collect() calls during register() --- .../metrics/core/metrics/Counter.java | 2 +- .../core/metrics/MetricWithFixedMetadata.java | 5 +++++ .../metrics/model/snapshots/Labels.java | 19 +++++++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index caf2cf854..57ed0c05b 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -33,7 +33,7 @@ * requestCount.withLabelValues("/hello-world", "500").inc(); * }

    */ -public class Counter extends StatefulMetric implements CounterDataPoint, Collector { +public class Counter extends StatefulMetric implements CounterDataPoint { private final boolean exemplarsEnabled; private final ExemplarSamplerConfig exemplarSamplerConfig; diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index a1c1769d9..7a3649861 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -41,6 +41,11 @@ private String makeName(String name, Unit unit) { return name; } + @Override + public String getPrometheusName() { + return metadata.getPrometheusName(); + } + public static abstract class Builder, M extends MetricWithFixedMetadata> extends Metric.Builder { protected String name; 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 60b1b58be..fd0b01e2a 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 @@ -139,13 +139,24 @@ public static Labels of(String[] names, String[] values) { * 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 (String name : prometheusNames) { - if (name.equals(labelName)) { - return true; + for (int i=0; i Date: Wed, 30 Aug 2023 23:15:16 +0200 Subject: [PATCH 199/980] Add JVM metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../example-greeting-service/pom.xml | 5 + .../otel_exemplars/greeting/Main.java | 3 + .../example-hello-world-app/pom.xml | 5 + .../examples/otel_exemplars/app/Main.java | 3 + examples/example-exporter-httpserver/pom.xml | 5 + .../metrics/examples/httpserver/Main.java | 9 + .../example-exporter-opentelemetry/pom.xml | 5 + .../metrics/examples/opentelemetry/Main.java | 12 + .../example-exporter-servlet-tomcat/pom.xml | 5 + .../tomcat_servlet/HelloWorldServlet.java | 2 + .../metrics/examples/tomcat_servlet/Main.java | 3 + pom.xml | 1 + .../metrics/core/metrics/StatefulMetric.java | 7 + .../pom.xml | 73 +++++ .../jvm/JvmBufferPoolMetrics.java | 126 ++++++++ .../jvm/JvmClassLoadingMetrics.java | 102 ++++++ .../jvm/JvmCompilationMetrics.java | 89 ++++++ .../jvm/JvmGarbageCollectorMetrics.java | 96 ++++++ .../instrumentation/jvm/JvmMemoryMetrics.java | 298 ++++++++++++++++++ .../jvm/JvmMemoryPoolAllocationMetrics.java | 170 ++++++++++ .../instrumentation/jvm/JvmMetrics.java | 67 ++++ .../jvm/JvmRuntimeInfoMetric.java | 104 ++++++ .../jvm/JvmThreadsMetrics.java | 215 +++++++++++++ .../jvm/NativeImageChecker.java | 13 + .../instrumentation/jvm/ProcessMetrics.java | 285 +++++++++++++++++ .../jvm/ExampleExporterForManualTesting.java | 25 ++ .../jvm/JvmBufferPoolMetricsTest.java | 85 +++++ .../jvm/JvmClassLoadingMetricsTest.java | 68 ++++ .../jvm/JvmCompilationMetricsTest.java | 62 ++++ .../jvm/JvmGarbageCollectorMetricsTest.java | 74 +++++ .../jvm/JvmMemoryMetricsTest.java | 177 +++++++++++ .../JvmMemoryPoolAllocationMetricsTest.java | 65 ++++ .../jvm/JvmRuntimeInfoMetricTest.java | 32 ++ .../jvm/JvmThreadsMetricsTest.java | 187 +++++++++++ .../jvm/ProcessMetricsTest.java | 115 +++++++ .../metrics/instrumentation/jvm/TestUtil.java | 18 ++ .../version-rules.xml | 12 + .../metrics/model/snapshots/Unit.java | 4 + 38 files changed, 2627 insertions(+) create mode 100644 prometheus-metrics-instrumentation-jvm/pom.xml create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java create mode 100644 prometheus-metrics-instrumentation-jvm/version-rules.xml diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index f6ab3646b..c8742ffdb 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -37,6 +37,11 @@ prometheus-metrics-core ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + io.prometheus prometheus-metrics-exporter-servlet-jakarta diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java index 4982be376..691ea6a1d 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.examples.otel_exemplars.greeting; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; @@ -14,6 +15,8 @@ public class Main { public static void main(String[] args) throws LifecycleException { + JvmMetrics.newBuilder().register(); + Tomcat tomcat = new Tomcat(); tomcat.setPort(8081); diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index c37ab1418..4fbc0c647 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -37,6 +37,11 @@ prometheus-metrics-core ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + io.prometheus prometheus-metrics-exporter-servlet-jakarta diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java index cf8fee7f1..4a7bf0fac 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.examples.otel_exemplars.app; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; @@ -14,6 +15,8 @@ public class Main { public static void main(String[] args) throws LifecycleException { + JvmMetrics.newBuilder().register(); + Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 907e7f44e..f8221fa8c 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -37,6 +37,11 @@ prometheus-metrics-core ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + io.prometheus prometheus-metrics-exporter-httpserver diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java index 0563d583a..dc0316b06 100644 --- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java +++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java @@ -2,6 +2,7 @@ import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; import java.io.IOException; @@ -13,6 +14,14 @@ public class Main { public static void main(String[] args) throws IOException, InterruptedException { + JvmMetrics.newBuilder().register(); + + // Note: uptime_seconds_total is not a great example: + // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds + // with the start timestamp in seconds, so if you want to know the uptime you can simply + // run the Prometheus query + // time() - process_start_time_seconds + // rather than creating a custom uptime metric. Counter counter = Counter.newBuilder() .withName("uptime_seconds_total") .withHelp("total number of seconds since this application was started") diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 076cdd24e..976a67f64 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -37,6 +37,11 @@ prometheus-metrics-core ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + io.prometheus prometheus-metrics-exporter-opentelemetry diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java index 9f7a3d5a8..7d257e6a7 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java @@ -2,6 +2,7 @@ import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.exporter.opentelemetry.OpenTelemetryExporter; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; /** @@ -11,6 +12,17 @@ public class Main { public static void main(String[] args) throws Exception { + // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions. + // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry + // naming conventions rather than the Prometheus names. + JvmMetrics.newBuilder().register(); + + // Note: uptime_seconds_total is not a great example: + // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds + // with the start timestamp in seconds, so if you want to know the uptime you can simply + // run the Prometheus query + // time() - process_start_time_seconds + // rather than creating a custom uptime metric. Counter counter = Counter.newBuilder() .withName("uptime_seconds_total") .withHelp("total number of seconds since this application was started") diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 345a4328f..7b5761519 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -37,6 +37,11 @@ prometheus-metrics-core ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + io.prometheus prometheus-metrics-exporter-servlet-jakarta diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index 7a95e36da..42f123f16 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -19,6 +19,8 @@ public class HelloWorldServlet extends HttpServlet { private final Random random = new Random(0); + // Note: The requests_total counter is not a great example, because the + // request_duration_seconds histogram below also has a count with the number of requests. private final Counter counter = Counter.newBuilder() .withName("requests_total") .withHelp("total number of requests") diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java index 571e55a2b..5525ed48e 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.examples.tomcat_servlet; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; @@ -17,6 +18,8 @@ public class Main { public static void main(String[] args) throws LifecycleException, IOException { + JvmMetrics.newBuilder().register(); + Tomcat tomcat = new Tomcat(); Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-"); tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath()); diff --git a/pom.xml b/pom.xml index cb9c242e7..18be07c93 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ prometheus-metrics-exporter-servlet-jakarta prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry + prometheus-metrics-instrumentation-jvm examples integration-tests diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 17d8da246..f3636b328 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -101,10 +101,17 @@ public D withLabelValues(String... labelValues) { return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); } + /** + * Remove the data point with the given label values. + * See https://prometheus.io/docs/instrumenting/writing_clientlibs/#labels. + */ public void remove(String... labelValues) { data.remove(Arrays.asList(labelValues)); } + // TODO: Write a clear() method that resets the metric (removes all data points), + // see https://prometheus.io/docs/instrumenting/writing_clientlibs/#labels + protected abstract T newDataPoint(); protected T getNoLabels() { diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml new file mode 100644 index 000000000..fdddcc1ee --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -0,0 +1,73 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-4-SNAPSHOT + + + prometheus-metrics-instrumentation-jvm + bundle + + Prometheus Metrics Instrumentation - JVM + + Instrumentation library for JVM metrics + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + brian-brazil + Brian Brazil + brian.brazil@boxever.com + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + + + junit + junit + 4.13.2 + test + + + org.mockito + mockito-core + 4.11.0 + test + + + io.prometheus + prometheus-metrics-exporter-httpserver + ${project.version} + test + + + io.prometheus + prometheus-metrics-exposition-formats + ${project.version} + test + + + diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java new file mode 100644 index 000000000..c1e66f31a --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java @@ -0,0 +1,126 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.lang.management.BufferPoolMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; + +/** + * JVM Buffer Pool metrics. The {@link JvmBufferPoolMetrics} are registered as part of the {@link JvmMetrics} like this: + *

    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmBufferPoolMetrics} you can also register them directly: + *
    {@code
    + *   JvmBufferPoolMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.
    + * # TYPE jvm_buffer_pool_capacity_bytes gauge
    + * jvm_buffer_pool_capacity_bytes{pool="direct"} 8192.0
    + * jvm_buffer_pool_capacity_bytes{pool="mapped"} 0.0
    + * # HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.
    + * # TYPE jvm_buffer_pool_used_buffers gauge
    + * jvm_buffer_pool_used_buffers{pool="direct"} 1.0
    + * jvm_buffer_pool_used_buffers{pool="mapped"} 0.0
    + * # HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.
    + * # TYPE jvm_buffer_pool_used_bytes gauge
    + * jvm_buffer_pool_used_bytes{pool="direct"} 8192.0
    + * jvm_buffer_pool_used_bytes{pool="mapped"} 0.0
    + * 
    + */ +public class JvmBufferPoolMetrics { + + private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes"; + private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes"; + private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers"; + + private final PrometheusProperties config; + private final List bufferPoolBeans; + + private JvmBufferPoolMetrics(List bufferPoolBeans, PrometheusProperties config) { + this.config = config; + this.bufferPoolBeans = bufferPoolBeans; + } + + private void register(PrometheusRegistry registry) { + + GaugeWithCallback.newBuilder(config) + .withName(JVM_BUFFER_POOL_USED_BYTES) + .withHelp("Used bytes of a given JVM buffer pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(callback -> { + for (BufferPoolMXBean pool : bufferPoolBeans) { + callback.call(pool.getMemoryUsed(), pool.getName()); + } + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_BUFFER_POOL_CAPACITY_BYTES) + .withHelp("Bytes capacity of a given JVM buffer pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(callback -> { + for (BufferPoolMXBean pool : bufferPoolBeans) { + callback.call(pool.getTotalCapacity(), pool.getName()); + } + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_BUFFER_POOL_USED_BUFFERS) + .withHelp("Used buffers of a given JVM buffer pool.") + .withLabelNames("pool") + .withCallback(callback -> { + for (BufferPoolMXBean pool : bufferPoolBeans) { + callback.call(pool.getCount(), pool.getName()); + } + }) + .register(registry); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private List bufferPoolBeans; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withBufferPoolBeans(List bufferPoolBeans) { + this.bufferPoolBeans = bufferPoolBeans; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + List bufferPoolBeans = this.bufferPoolBeans; + if (bufferPoolBeans == null) { + bufferPoolBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); + } + new JvmBufferPoolMetrics(bufferPoolBeans, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java new file mode 100644 index 000000000..803fb0747 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java @@ -0,0 +1,102 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.CounterWithCallback; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +import java.lang.management.ClassLoadingMXBean; +import java.lang.management.ManagementFactory; + +/** + * JVM Class Loading metrics. The {@link JvmClassLoadingMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmClassLoadingMetrics} you can also register them directly: + *
    {@code
    + *   JvmClassLoadingMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM
    + * # TYPE jvm_classes_currently_loaded gauge
    + * jvm_classes_currently_loaded 1109.0
    + * # HELP jvm_classes_loaded_total The total number of classes that have been loaded since the JVM has started execution
    + * # TYPE jvm_classes_loaded_total counter
    + * jvm_classes_loaded_total 1109.0
    + * # HELP jvm_classes_unloaded_total The total number of classes that have been unloaded since the JVM has started execution
    + * # TYPE jvm_classes_unloaded_total counter
    + * jvm_classes_unloaded_total 0.0
    + * 
    + */ +public class JvmClassLoadingMetrics { + + private static final String JVM_CLASSES_CURRENTLY_LOADED = "jvm_classes_currently_loaded"; + private static final String JVM_CLASSES_LOADED_TOTAL = "jvm_classes_loaded_total"; + private static final String JVM_CLASSES_UNLOADED_TOTAL = "jvm_classes_unloaded_total"; + + private final PrometheusProperties config; + private final ClassLoadingMXBean classLoadingBean; + + private JvmClassLoadingMetrics(ClassLoadingMXBean classLoadingBean, PrometheusProperties config) { + this.classLoadingBean = classLoadingBean; + this.config = config; + } + + private void register(PrometheusRegistry registry) { + + GaugeWithCallback.newBuilder(config) + .withName(JVM_CLASSES_CURRENTLY_LOADED) + .withHelp("The number of classes that are currently loaded in the JVM") + .withCallback(callback -> callback.call(classLoadingBean.getLoadedClassCount())) + .register(registry); + + CounterWithCallback.newBuilder(config) + .withName(JVM_CLASSES_LOADED_TOTAL) + .withHelp("The total number of classes that have been loaded since the JVM has started execution") + .withCallback(callback -> callback.call(classLoadingBean.getTotalLoadedClassCount())) + .register(registry); + + CounterWithCallback.newBuilder(config) + .withName(JVM_CLASSES_UNLOADED_TOTAL) + .withHelp("The total number of classes that have been unloaded since the JVM has started execution") + .withCallback(callback -> callback.call(classLoadingBean.getUnloadedClassCount())) + .register(registry); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private ClassLoadingMXBean classLoadingBean; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withClassLoadingBean(ClassLoadingMXBean classLoadingBean) { + this.classLoadingBean = classLoadingBean; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + ClassLoadingMXBean classLoadingBean = this.classLoadingBean != null ? this.classLoadingBean : ManagementFactory.getClassLoadingMXBean(); + new JvmClassLoadingMetrics(classLoadingBean, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java new file mode 100644 index 000000000..2e73ec1b1 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java @@ -0,0 +1,89 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.CounterWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.lang.management.CompilationMXBean; +import java.lang.management.ManagementFactory; + +import static io.prometheus.metrics.model.snapshots.Unit.millisToSeconds; + +/** + * JVM Compilation metrics. The {@link JvmCompilationMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmCompilationMetrics} you can also register them directly: + *
    {@code
    + *   JvmCompilationMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_compilation_time_seconds_total The total time in seconds taken for HotSpot class compilation
    + * # TYPE jvm_compilation_time_seconds_total counter
    + * jvm_compilation_time_seconds_total 0.152
    + * 
    + */ +public class JvmCompilationMetrics { + + private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL = "jvm_compilation_time_seconds_total"; + + private final PrometheusProperties config; + private final CompilationMXBean compilationBean; + + private JvmCompilationMetrics(CompilationMXBean compilationBean, PrometheusProperties config) { + this.compilationBean = compilationBean; + this.config = config; + } + + private void register(PrometheusRegistry registry) { + + if (compilationBean == null || !compilationBean.isCompilationTimeMonitoringSupported()) { + return; + } + + CounterWithCallback.newBuilder(config) + .withName(JVM_COMPILATION_TIME_SECONDS_TOTAL) + .withHelp("The total time in seconds taken for HotSpot class compilation") + .withUnit(Unit.SECONDS) + .withCallback(callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime()))) + .register(registry); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private CompilationMXBean compilationBean; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withCompilationBean(CompilationMXBean compilationBean) { + this.compilationBean = compilationBean; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + CompilationMXBean compilationBean = this.compilationBean != null ? this.compilationBean : ManagementFactory.getCompilationMXBean(); + new JvmCompilationMetrics(compilationBean, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java new file mode 100644 index 000000000..87b423987 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java @@ -0,0 +1,96 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.SummaryWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; + +/** + * JVM Garbage Collector metrics. The {@link JvmGarbageCollectorMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmGarbageCollectorMetrics} you can also register them directly: + *
    {@code
    + *   JvmGarbageCollectorMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
    + * # TYPE jvm_gc_collection_seconds summary
    + * jvm_gc_collection_seconds_count{gc="PS MarkSweep"} 0
    + * jvm_gc_collection_seconds_sum{gc="PS MarkSweep"} 0.0
    + * jvm_gc_collection_seconds_count{gc="PS Scavenge"} 0
    + * jvm_gc_collection_seconds_sum{gc="PS Scavenge"} 0.0
    + * 
    + */ +public class JvmGarbageCollectorMetrics { + + private static final String JVM_GC_COLLECTION_SECONDS = "jvm_gc_collection_seconds"; + + private final PrometheusProperties config; + private final List garbageCollectorBeans; + + private JvmGarbageCollectorMetrics(List garbageCollectorBeans, PrometheusProperties config) { + this.config = config; + this.garbageCollectorBeans = garbageCollectorBeans; + } + + private void register(PrometheusRegistry registry) { + + SummaryWithCallback.newBuilder(config) + .withName(JVM_GC_COLLECTION_SECONDS) + .withHelp("Time spent in a given JVM garbage collector in seconds.") + .withUnit(Unit.SECONDS) + .withLabelNames("gc") + .withCallback(callback -> { + for (GarbageCollectorMXBean gc : garbageCollectorBeans) { + callback.call(gc.getCollectionCount(), Unit.millisToSeconds(gc.getCollectionTime()), Quantiles.EMPTY, gc.getName()); + } + }) + .register(registry); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private List garbageCollectorBeans; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withGarbageCollectorBeans(List garbageCollectorBeans) { + this.garbageCollectorBeans = garbageCollectorBeans; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + List garbageCollectorBeans = this.garbageCollectorBeans; + if (garbageCollectorBeans == null) { + garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans(); + } + new JvmGarbageCollectorMetrics(garbageCollectorBeans, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java new file mode 100644 index 000000000..a9a5f2225 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java @@ -0,0 +1,298 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * JVM memory metrics. The {@link JvmMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmMemoryMetrics} you can also register them directly: + *
    {@code
    + *   JvmMemoryMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.
    + * # TYPE jvm_memory_committed_bytes gauge
    + * jvm_memory_committed_bytes{area="heap"} 4.98597888E8
    + * jvm_memory_committed_bytes{area="nonheap"} 1.1993088E7
    + * # HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.
    + * # TYPE jvm_memory_init_bytes gauge
    + * jvm_memory_init_bytes{area="heap"} 5.20093696E8
    + * jvm_memory_init_bytes{area="nonheap"} 2555904.0
    + * # HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.
    + * # TYPE jvm_memory_max_bytes gauge
    + * jvm_memory_max_bytes{area="heap"} 7.38983936E9
    + * jvm_memory_max_bytes{area="nonheap"} -1.0
    + * # HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.
    + * # TYPE jvm_memory_objects_pending_finalization gauge
    + * jvm_memory_objects_pending_finalization 0.0
    + * # HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_collection_committed_bytes gauge
    + * jvm_memory_pool_collection_committed_bytes{pool="PS Eden Space"} 1.30023424E8
    + * jvm_memory_pool_collection_committed_bytes{pool="PS Old Gen"} 3.47078656E8
    + * jvm_memory_pool_collection_committed_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_collection_init_bytes gauge
    + * jvm_memory_pool_collection_init_bytes{pool="PS Eden Space"} 1.30023424E8
    + * jvm_memory_pool_collection_init_bytes{pool="PS Old Gen"} 3.47078656E8
    + * jvm_memory_pool_collection_init_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_collection_max_bytes gauge
    + * jvm_memory_pool_collection_max_bytes{pool="PS Eden Space"} 2.727870464E9
    + * jvm_memory_pool_collection_max_bytes{pool="PS Old Gen"} 5.542248448E9
    + * jvm_memory_pool_collection_max_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_collection_used_bytes gauge
    + * jvm_memory_pool_collection_used_bytes{pool="PS Eden Space"} 0.0
    + * jvm_memory_pool_collection_used_bytes{pool="PS Old Gen"} 1249696.0
    + * jvm_memory_pool_collection_used_bytes{pool="PS Survivor Space"} 0.0
    + * # HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_committed_bytes gauge
    + * jvm_memory_pool_committed_bytes{pool="Code Cache"} 4128768.0
    + * jvm_memory_pool_committed_bytes{pool="Compressed Class Space"} 917504.0
    + * jvm_memory_pool_committed_bytes{pool="Metaspace"} 6946816.0
    + * jvm_memory_pool_committed_bytes{pool="PS Eden Space"} 1.30023424E8
    + * jvm_memory_pool_committed_bytes{pool="PS Old Gen"} 3.47078656E8
    + * jvm_memory_pool_committed_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_init_bytes gauge
    + * jvm_memory_pool_init_bytes{pool="Code Cache"} 2555904.0
    + * jvm_memory_pool_init_bytes{pool="Compressed Class Space"} 0.0
    + * jvm_memory_pool_init_bytes{pool="Metaspace"} 0.0
    + * jvm_memory_pool_init_bytes{pool="PS Eden Space"} 1.30023424E8
    + * jvm_memory_pool_init_bytes{pool="PS Old Gen"} 3.47078656E8
    + * jvm_memory_pool_init_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_max_bytes gauge
    + * jvm_memory_pool_max_bytes{pool="Code Cache"} 2.5165824E8
    + * jvm_memory_pool_max_bytes{pool="Compressed Class Space"} 1.073741824E9
    + * jvm_memory_pool_max_bytes{pool="Metaspace"} -1.0
    + * jvm_memory_pool_max_bytes{pool="PS Eden Space"} 2.727870464E9
    + * jvm_memory_pool_max_bytes{pool="PS Old Gen"} 5.542248448E9
    + * jvm_memory_pool_max_bytes{pool="PS Survivor Space"} 2.1495808E7
    + * # HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.
    + * # TYPE jvm_memory_pool_used_bytes gauge
    + * jvm_memory_pool_used_bytes{pool="Code Cache"} 4065472.0
    + * jvm_memory_pool_used_bytes{pool="Compressed Class Space"} 766680.0
    + * jvm_memory_pool_used_bytes{pool="Metaspace"} 6659432.0
    + * jvm_memory_pool_used_bytes{pool="PS Eden Space"} 7801536.0
    + * jvm_memory_pool_used_bytes{pool="PS Old Gen"} 1249696.0
    + * jvm_memory_pool_used_bytes{pool="PS Survivor Space"} 0.0
    + * # HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.
    + * # TYPE jvm_memory_used_bytes gauge
    + * jvm_memory_used_bytes{area="heap"} 9051232.0
    + * jvm_memory_used_bytes{area="nonheap"} 1.1490688E7
    + * 
    + */ +public class JvmMemoryMetrics { + + private static final String JVM_MEMORY_OBJECTS_PENDING_FINALIZATION = "jvm_memory_objects_pending_finalization"; + private static final String JVM_MEMORY_USED_BYTES = "jvm_memory_used_bytes"; + private static final String JVM_MEMORY_COMMITTED_BYTES = "jvm_memory_committed_bytes"; + private static final String JVM_MEMORY_MAX_BYTES = "jvm_memory_max_bytes"; + private static final String JVM_MEMORY_INIT_BYTES = "jvm_memory_init_bytes"; + private static final String JVM_MEMORY_POOL_USED_BYTES = "jvm_memory_pool_used_bytes"; + private static final String JVM_MEMORY_POOL_COMMITTED_BYTES = "jvm_memory_pool_committed_bytes"; + private static final String JVM_MEMORY_POOL_MAX_BYTES = "jvm_memory_pool_max_bytes"; + private static final String JVM_MEMORY_POOL_INIT_BYTES = "jvm_memory_pool_init_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_USED_BYTES = "jvm_memory_pool_collection_used_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES = "jvm_memory_pool_collection_committed_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_MAX_BYTES = "jvm_memory_pool_collection_max_bytes"; + private static final String JVM_MEMORY_POOL_COLLECTION_INIT_BYTES = "jvm_memory_pool_collection_init_bytes"; + + private final PrometheusProperties config; + private final MemoryMXBean memoryBean; + private final List poolBeans; + + private JvmMemoryMetrics(List poolBeans, MemoryMXBean memoryBean, PrometheusProperties config) { + this.config = config; + this.poolBeans = poolBeans; + this.memoryBean = memoryBean; + } + + private void register(PrometheusRegistry registry) { + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION) + .withHelp("The number of objects waiting in the finalizer queue.") + .withCallback(callback -> callback.call(memoryBean.getObjectPendingFinalizationCount())) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_USED_BYTES) + .withHelp("Used bytes of a given JVM memory area.") + .withUnit(Unit.BYTES) + .withLabelNames("area") + .withCallback(callback -> { + callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap"); + callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap"); + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_COMMITTED_BYTES) + .withHelp("Committed (bytes) of a given JVM memory area.") + .withUnit(Unit.BYTES) + .withLabelNames("area") + .withCallback(callback -> { + callback.call(memoryBean.getHeapMemoryUsage().getCommitted(), "heap"); + callback.call(memoryBean.getNonHeapMemoryUsage().getCommitted(), "nonheap"); + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_MAX_BYTES) + .withHelp("Max (bytes) of a given JVM memory area.") + .withUnit(Unit.BYTES) + .withLabelNames("area") + .withCallback(callback -> { + callback.call(memoryBean.getHeapMemoryUsage().getMax(), "heap"); + callback.call(memoryBean.getNonHeapMemoryUsage().getMax(), "nonheap"); + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_INIT_BYTES) + .withHelp("Initial bytes of a given JVM memory area.") + .withUnit(Unit.BYTES) + .withLabelNames("area") + .withCallback(callback -> { + callback.call(memoryBean.getHeapMemoryUsage().getInit(), "heap"); + callback.call(memoryBean.getNonHeapMemoryUsage().getInit(), "nonheap"); + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_USED_BYTES) + .withHelp("Used bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getUsed)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_COMMITTED_BYTES) + .withHelp("Committed bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getCommitted)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_MAX_BYTES) + .withHelp("Max bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getMax)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_INIT_BYTES) + .withHelp("Initial bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getInit)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_COLLECTION_USED_BYTES) + .withHelp("Used bytes after last collection of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getUsed)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES) + .withHelp("Committed after last collection bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getCommitted)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES) + .withHelp("Max bytes after last collection of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getMax)) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES) + .withHelp("Initial after last collection bytes of a given JVM memory pool.") + .withUnit(Unit.BYTES) + .withLabelNames("pool") + .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getInit)) + .register(registry); + } + + private Consumer makeCallback(List poolBeans, Function memoryUsageFunc, Function valueFunc) { + return callback -> { + for (MemoryPoolMXBean pool : poolBeans) { + MemoryUsage poolUsage = memoryUsageFunc.apply(pool); + if (poolUsage != null) { + callback.call(valueFunc.apply(poolUsage), pool.getName()); + } + } + }; + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private MemoryMXBean memoryBean; + private List poolBeans; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withMemoryBean(MemoryMXBean memoryBean) { + this.memoryBean = memoryBean; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withMemoryPoolBeans(List memoryPoolBeans) { + this.poolBeans = memoryPoolBeans; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + MemoryMXBean memoryMXBean = this.memoryBean != null ? this.memoryBean : ManagementFactory.getMemoryMXBean(); + List poolBeans = this.poolBeans != null ? this.poolBeans : ManagementFactory.getMemoryPoolMXBeans(); + new JvmMemoryMetrics(poolBeans, memoryMXBean, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java new file mode 100644 index 000000000..3adf4d2dc --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java @@ -0,0 +1,170 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import com.sun.management.GarbageCollectionNotificationInfo; +import com.sun.management.GcInfo; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +import javax.management.Notification; +import javax.management.NotificationEmitter; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them directly: + *
    {@code
    + *   JvmMemoryAllocationMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.
    + * # TYPE jvm_memory_pool_allocated_bytes_total counter
    + * jvm_memory_pool_allocated_bytes_total{pool="Code Cache"} 4336448.0
    + * jvm_memory_pool_allocated_bytes_total{pool="Compressed Class Space"} 875016.0
    + * jvm_memory_pool_allocated_bytes_total{pool="Metaspace"} 7480456.0
    + * jvm_memory_pool_allocated_bytes_total{pool="PS Eden Space"} 1.79232824E8
    + * jvm_memory_pool_allocated_bytes_total{pool="PS Old Gen"} 1428888.0
    + * jvm_memory_pool_allocated_bytes_total{pool="PS Survivor Space"} 4115280.0
    + * 
    + */ +public class JvmMemoryPoolAllocationMetrics { + + private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL = "jvm_memory_pool_allocated_bytes_total"; + + private final PrometheusProperties config; + private final List garbageCollectorBeans; + + private JvmMemoryPoolAllocationMetrics(List garbageCollectorBeans, PrometheusProperties config) { + this.garbageCollectorBeans = garbageCollectorBeans; + this.config = config; + } + + private void register(PrometheusRegistry registry) { + + Counter allocatedCounter = Counter.newBuilder() + .withName(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL) + .withHelp("Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.") + .withLabelNames("pool") + .register(registry); + + AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter); + for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) { + if (garbageCollectorMXBean instanceof NotificationEmitter) { + ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null); + } + } + } + + static class AllocationCountingNotificationListener implements NotificationListener { + + private final Map lastMemoryUsage = new HashMap(); + private final Counter counter; + + AllocationCountingNotificationListener(Counter counter) { + this.counter = counter; + } + + @Override + public synchronized void handleNotification(Notification notification, Object handback) { + GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData()); + GcInfo gcInfo = info.getGcInfo(); + Map memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc(); + Map memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc(); + for (Map.Entry entry : memoryUsageBeforeGc.entrySet()) { + String memoryPool = entry.getKey(); + long before = entry.getValue().getUsed(); + long after = memoryUsageAfterGc.get(memoryPool).getUsed(); + handleMemoryPool(memoryPool, before, after); + } + } + + // Visible for testing + void handleMemoryPool(String memoryPool, long before, long after) { + /* + * Calculate increase in the memory pool by comparing memory used + * after last GC, before this GC, and after this GC. + * See ascii illustration below. + * Make sure to count only increases and ignore decreases. + * (Typically a pool will only increase between GCs or during GCs, not both. + * E.g. eden pools between GCs. Survivor and old generation pools during GCs.) + * + * |<-- diff1 -->|<-- diff2 -->| + * Timeline: |-- last GC --| |---- GC -----| + * ___^__ ___^____ ___^___ + * Mem. usage vars: / last \ / before \ / after \ + */ + + // Get last memory usage after GC and remember memory used after for next time + long last = getAndSet(lastMemoryUsage, memoryPool, after); + // Difference since last GC + long diff1 = before - last; + // Difference during this GC + long diff2 = after - before; + // Make sure to only count increases + if (diff1 < 0) { + diff1 = 0; + } + if (diff2 < 0) { + diff2 = 0; + } + long increase = diff1 + diff2; + if (increase > 0) { + counter.withLabelValues(memoryPool).inc(increase); + } + } + + private static long getAndSet(Map map, String key, long value) { + Long last = map.put(key, value); + return last == null ? 0 : last; + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private List garbageCollectorBeans; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withGarbageCollectorBeans(List garbageCollectorBeans) { + this.garbageCollectorBeans = garbageCollectorBeans; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + List garbageCollectorBeans = this.garbageCollectorBeans; + if (garbageCollectorBeans == null) { + garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans(); + } + new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java new file mode 100644 index 000000000..841fc84e2 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java @@ -0,0 +1,67 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Registers all JVM metrics. Example usage: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + */ +public class JvmMetrics { + + private static AtomicBoolean registeredWithTheDefaultRegistry = new AtomicBoolean(false); + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you pass a config or not. + // However, we will add config options in the future, like whether you want to use Prometheus naming conventions + //'or OpenTelemetry semantic conventions for JVM metrics. + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Register all JVM metrics with the default registry. + *

    + * It's safe to call this multiple times: + * Only the first call will register the metrics, all subsequent calls will be ignored. + */ + public void register() { + if (!registeredWithTheDefaultRegistry.getAndSet(true)) { + register(PrometheusRegistry.defaultRegistry); + } + } + + /** + * Register all JVM metrics with the {@code registry}. + *

    + * You must make sure to call this only once per {@code registry}, otherwise it will + * throw an Exception because you are trying to register duplicate metrics. + */ + public void register(PrometheusRegistry registry) { + JvmThreadsMetrics.newBuilder(config).register(registry); + JvmBufferPoolMetrics.newBuilder(config).register(registry); + JvmClassLoadingMetrics.newBuilder(config).register(registry); + JvmCompilationMetrics.newBuilder(config).register(registry); + JvmGarbageCollectorMetrics.newBuilder(config).register(registry); + JvmMemoryPoolAllocationMetrics.newBuilder(config).register(registry); + JvmMemoryMetrics.newBuilder(config).register(registry); + JvmRuntimeInfoMetric.newBuilder(config).register(registry); + ProcessMetrics.newBuilder(config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java new file mode 100644 index 000000000..3f1771ac2 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java @@ -0,0 +1,104 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.Info; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +/** + * JVM Runtime Info metric. The {@link JvmRuntimeInfoMetric} is registered as part of the {@link JvmMetrics} like this: + *

    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmRuntimeInfoMetric} you can also register them directly: + *
    {@code
    + *   JvmRuntimeInfoMetric.newBuilder().register();
    + * }
    + * + *
    + * # TYPE jvm_runtime info
    + * # HELP jvm_runtime JVM runtime info
    + * jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1
    + * 
    + */ +public class JvmRuntimeInfoMetric { + + private static final String JVM_RUNTIME_INFO = "jvm_runtime_info"; + + private final PrometheusProperties config; + private final String version; + private final String vendor; + private final String runtime; + + private JvmRuntimeInfoMetric(String version, String vendor, String runtime, PrometheusProperties config) { + this.config = config; + this.version = version; + this.vendor = vendor; + this.runtime = runtime; + } + + private void register(PrometheusRegistry registry) { + + Info jvmInfo = Info.newBuilder(config) + .withName(JVM_RUNTIME_INFO) + .withHelp("JVM runtime info") + .withLabelNames("version", "vendor", "runtime") + .register(registry); + + jvmInfo.setLabelValues(version, vendor, runtime); + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private String version; + private String vendor; + private String runtime; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withVersion(String version) { + this.version = version; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withVendor(String vendor) { + this.vendor = vendor; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withRuntime(String runtime) { + this.runtime = runtime; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + String version = this.version != null ? this.version : System.getProperty("java.runtime.version", "unknown"); + String vendor = this.vendor != null ? this.vendor : System.getProperty("java.vm.vendor", "unknown"); + String runtime = this.runtime != null ? this.runtime : System.getProperty("java.runtime.name", "unknown"); + new JvmRuntimeInfoMetric(version, vendor, runtime, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java new file mode 100644 index 000000000..55f07133d --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java @@ -0,0 +1,215 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.CounterWithCallback; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link JvmMetrics} like this: + *
    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link JvmThreadsMetrics} you can also register them directly: + *
    {@code
    + *   JvmThreadMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP jvm_threads_current Current thread count of a JVM
    + * # TYPE jvm_threads_current gauge
    + * jvm_threads_current 10.0
    + * # HELP jvm_threads_daemon Daemon thread count of a JVM
    + * # TYPE jvm_threads_daemon gauge
    + * jvm_threads_daemon 8.0
    + * # HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers
    + * # TYPE jvm_threads_deadlocked gauge
    + * jvm_threads_deadlocked 0.0
    + * # HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors
    + * # TYPE jvm_threads_deadlocked_monitor gauge
    + * jvm_threads_deadlocked_monitor 0.0
    + * # HELP jvm_threads_peak Peak thread count of a JVM
    + * # TYPE jvm_threads_peak gauge
    + * jvm_threads_peak 10.0
    + * # HELP jvm_threads_started_total Started thread count of a JVM
    + * # TYPE jvm_threads_started_total counter
    + * jvm_threads_started_total 10.0
    + * # HELP jvm_threads_state Current count of threads by state
    + * # TYPE jvm_threads_state gauge
    + * jvm_threads_state{state="BLOCKED"} 0.0
    + * jvm_threads_state{state="NEW"} 0.0
    + * jvm_threads_state{state="RUNNABLE"} 5.0
    + * jvm_threads_state{state="TERMINATED"} 0.0
    + * jvm_threads_state{state="TIMED_WAITING"} 2.0
    + * jvm_threads_state{state="UNKNOWN"} 0.0
    + * jvm_threads_state{state="WAITING"} 3.0
    + * 
    + */ +public class JvmThreadsMetrics { + + private static final String UNKNOWN = "UNKNOWN"; + private static final String JVM_THREADS_STATE = "jvm_threads_state"; + private static final String JVM_THREADS_CURRENT = "jvm_threads_current"; + private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon"; + private static final String JVM_THREADS_PEAK = "jvm_threads_peak"; + private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total"; + private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked"; + private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor"; + + private final PrometheusProperties config; + private final ThreadMXBean threadBean; + private final boolean isNativeImage; + + private JvmThreadsMetrics(boolean isNativeImage, ThreadMXBean threadBean, PrometheusProperties config) { + this.config = config; + this.threadBean = threadBean; + this.isNativeImage = isNativeImage; + } + + private void register(PrometheusRegistry registry) { + + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_CURRENT) + .withHelp("Current thread count of a JVM") + .withCallback(callback -> callback.call(threadBean.getThreadCount())) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_DAEMON) + .withHelp("Daemon thread count of a JVM") + .withCallback(callback -> callback.call(threadBean.getDaemonThreadCount())) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_PEAK) + .withHelp("Peak thread count of a JVM") + .withCallback(callback -> callback.call(threadBean.getPeakThreadCount())) + .register(registry); + + CounterWithCallback.newBuilder(config) + .withName(JVM_THREADS_STARTED_TOTAL) + .withHelp("Started thread count of a JVM") + .withCallback(callback -> callback.call(threadBean.getTotalStartedThreadCount())) + .register(registry); + + if (!isNativeImage) { + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_DEADLOCKED) + .withHelp("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers") + .withCallback(callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads()))) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_DEADLOCKED_MONITOR) + .withHelp("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors") + .withCallback(callback -> callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads()))) + .register(registry); + + + GaugeWithCallback.newBuilder(config) + .withName(JVM_THREADS_STATE) + .withHelp("Current count of threads by state") + .withLabelNames("state") + .withCallback(callback -> { + Map threadStateCounts = getThreadStateCountMap(threadBean); + for (Map.Entry entry : threadStateCounts.entrySet()) { + callback.call(entry.getValue(), entry.getKey()); + } + }) + .register(registry); + } + } + + private Map getThreadStateCountMap(ThreadMXBean threadBean) { + long[] threadIds = threadBean.getAllThreadIds(); + + // Code to remove any thread id values <= 0 + int writePos = 0; + for (int i = 0; i < threadIds.length; i++) { + if (threadIds[i] > 0) { + threadIds[writePos++] = threadIds[i]; + } + } + + int numberOfInvalidThreadIds = threadIds.length - writePos; + threadIds = Arrays.copyOf(threadIds, writePos); + + // Get thread information without computing any stack traces + ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0); + + // Initialize the map with all thread states + HashMap threadCounts = new HashMap(); + for (Thread.State state : Thread.State.values()) { + threadCounts.put(state.name(), 0); + } + + // Collect the actual thread counts + for (ThreadInfo curThread : allThreads) { + if (curThread != null) { + Thread.State threadState = curThread.getThreadState(); + threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1); + } + } + + // Add the thread count for invalid thread ids + threadCounts.put(UNKNOWN, numberOfInvalidThreadIds); + + return threadCounts; + } + + private double nullSafeArrayLength(long[] array) { + return null == array ? 0 : array.length; + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private Boolean isNativeImage; + private ThreadMXBean threadBean; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withThreadBean(ThreadMXBean threadBean) { + this.threadBean = threadBean; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withIsNativeImage(boolean isNativeImage) { + this.isNativeImage = isNativeImage; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + ThreadMXBean threadBean = this.threadBean != null ? this.threadBean : ManagementFactory.getThreadMXBean(); + boolean isNativeImage = this.isNativeImage != null ? this.isNativeImage : NativeImageChecker.isGraalVmNativeImage; + new JvmThreadsMetrics(isNativeImage, threadBean, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java new file mode 100644 index 000000000..11e3efb2d --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java @@ -0,0 +1,13 @@ +package io.prometheus.metrics.instrumentation.jvm; + +/** + * Contains utilities to check if we are running inside or building for native image. Default behavior is to check + * if specific for graalvm runtime property is present. For additional optimizations it is possible to do add + * "--initialize-at-build-time=io.prometheus.client.hotspot.NativeImageChecker" to graalvm native image build command and + * the native image will be identified during build time. + */ +class NativeImageChecker { + static final boolean isGraalVmNativeImage = System.getProperty("org.graalvm.nativeimage.imagecode") != null; + + private NativeImageChecker() {} +} diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java new file mode 100644 index 000000000..478a17ca7 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java @@ -0,0 +1,285 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.CounterWithCallback; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.lang.management.RuntimeMXBean; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Process metrics. + *

    + * These metrics are defined in the process metrics + * section of the Prometheus client library documentation, and they are implemented across client libraries in multiple programming languages. + *

    + * Technically, some of them are OS-level metrics and not JVM-level metrics. However, I'm still putting them + * in the {@code prometheus-metrics-instrumentation-jvm} module, because first it seems overkill to create a separate + * Maven module just for the {@link ProcessMetrics} class, and seconds some of these metrics are coming from the JVM via JMX anyway. + *

    + * The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: + *

    {@code
    + *   JvmMetrics.newBuilder().register();
    + * }
    + * However, if you want only the {@link ProcessMetrics} you can also register them directly: + *
    {@code
    + *   ProcessMetrics.newBuilder().register();
    + * }
    + * Example metrics being exported: + *
    + * # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
    + * # TYPE process_cpu_seconds_total counter
    + * process_cpu_seconds_total 1.63
    + * # HELP process_max_fds Maximum number of open file descriptors.
    + * # TYPE process_max_fds gauge
    + * process_max_fds 524288.0
    + * # HELP process_open_fds Number of open file descriptors.
    + * # TYPE process_open_fds gauge
    + * process_open_fds 28.0
    + * # HELP process_resident_memory_bytes Resident memory size in bytes.
    + * # TYPE process_resident_memory_bytes gauge
    + * process_resident_memory_bytes 7.8577664E7
    + * # HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
    + * # TYPE process_start_time_seconds gauge
    + * process_start_time_seconds 1.693829439767E9
    + * # HELP process_virtual_memory_bytes Virtual memory size in bytes.
    + * # TYPE process_virtual_memory_bytes gauge
    + * process_virtual_memory_bytes 1.2683624448E10
    + * 
    + */ +public class ProcessMetrics { + + private static final String PROCESS_CPU_SECONDS_TOTAL = "process_cpu_seconds_total"; + private static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds"; + private static final String PROCESS_OPEN_FDS = "process_open_fds"; + private static final String PROCESS_MAX_FDS = "process_max_fds"; + private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes"; + private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes"; + + private static final File PROC_SELF_STATUS = new File("/proc/self/status"); + + private final PrometheusProperties config; + private final OperatingSystemMXBean osBean; + private final RuntimeMXBean runtimeBean; + private final Grepper grepper; + private final boolean linux; + + private ProcessMetrics(OperatingSystemMXBean osBean, RuntimeMXBean runtimeBean, Grepper grepper, PrometheusProperties config) { + this.osBean = osBean; + this.runtimeBean = runtimeBean; + this.grepper = grepper; + this.config = config; + this.linux = PROC_SELF_STATUS.canRead(); + } + + private void register(PrometheusRegistry registry) { + + CounterWithCallback.newBuilder(config) + .withName(PROCESS_CPU_SECONDS_TOTAL) + .withHelp("Total user and system CPU time spent in seconds.") + .withUnit(Unit.SECONDS) + .withCallback(callback -> { + try { + // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean interfaces, in + // com.sun.management and com.ibm.lang.management. Hence use reflection and recursively go + // through implemented interfaces until the method can be made accessible and invoked. + Long processCpuTime = callLongGetter("getProcessCpuTime", osBean); + if (processCpuTime != null) { + callback.call(Unit.millisToSeconds(processCpuTime)); + } + } catch (Exception ignored) { + } + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(PROCESS_START_TIME_SECONDS) + .withHelp("Start time of the process since unix epoch in seconds.") + .withUnit(Unit.SECONDS) + .withCallback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime()))) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(PROCESS_OPEN_FDS) + .withHelp("Number of open file descriptors.") + .withCallback(callback -> { + try { + Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean); + if (openFds != null) { + callback.call(openFds); + } + } catch (Exception ignored) { + } + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(PROCESS_MAX_FDS) + .withHelp("Maximum number of open file descriptors.") + .withCallback(callback -> { + try { + Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean); + if (maxFds != null) { + callback.call(maxFds); + } + } catch (Exception ignored) { + } + }) + .register(registry); + + if (linux) { + + GaugeWithCallback.newBuilder(config) + .withName(PROCESS_VIRTUAL_MEMORY_BYTES) + .withHelp("Virtual memory size in bytes.") + .withUnit(Unit.BYTES) + .withCallback(callback -> { + try { + String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:"); + callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); + } catch (Exception ignored) { + } + }) + .register(registry); + + GaugeWithCallback.newBuilder(config) + .withName(PROCESS_RESIDENT_MEMORY_BYTES) + .withHelp("Resident memory size in bytes.") + .withUnit(Unit.BYTES) + .withCallback(callback -> { + try { + String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:"); + callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); + } catch (Exception ignored) { + } + }) + .register(registry); + } + } + + private Long callLongGetter(String getterName, Object obj) throws NoSuchMethodException, InvocationTargetException { + return callLongGetter(obj.getClass().getMethod(getterName), obj); + } + + /** + * Attempts to call a method either directly or via one of the implemented interfaces. + *

    + * A Method object refers to a specific method declared in a specific class. The first invocation + * might happen with method == SomeConcreteClass.publicLongGetter() and will fail if + * SomeConcreteClass is not public. We then recurse over all interfaces implemented by + * SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke + * callMethod() with method == SomePublicInterface.publicLongGetter(), which will then succeed. + *

    + * There is a built-in assumption that the method will never return null (or, equivalently, that + * it returns the primitive data type, i.e. {@code long} rather than {@code Long}). If this + * assumption doesn't hold, the method might be called repeatedly and the returned value will be + * the one produced by the last call. + */ + private Long callLongGetter(Method method, Object obj) throws InvocationTargetException { + try { + return (Long) method.invoke(obj); + } catch (IllegalAccessException e) { + // Expected, the declaring class or interface might not be public. + } + + // Iterate over all implemented/extended interfaces and attempt invoking the method with the + // same name and parameters on each. + for (Class clazz : method.getDeclaringClass().getInterfaces()) { + try { + Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); + Long result = callLongGetter(interfaceMethod, obj); + if (result != null) { + return result; + } + } catch (NoSuchMethodException e) { + // Expected, class might implement multiple, unrelated interfaces. + } + } + return null; + } + + interface Grepper { + String lineStartingWith(File file, String prefix) throws IOException; + } + + private static class FileGrepper implements Grepper { + + @Override + public String lineStartingWith(File file, String prefix) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line = reader.readLine(); + while (line != null) { + if (line.startsWith(prefix)) { + return line; + } + line = reader.readLine(); + } + } + return null; + } + } + + public static Builder newBuilder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder newBuilder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private OperatingSystemMXBean osBean; + private RuntimeMXBean runtimeBean; + private Grepper grepper; + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Package private. For testing only. + */ + Builder withOsBean(OperatingSystemMXBean osBean) { + this.osBean = osBean; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withRuntimeBean(RuntimeMXBean runtimeBean) { + this.runtimeBean = runtimeBean; + return this; + } + + /** + * Package private. For testing only. + */ + Builder withGrepper(Grepper grepper) { + this.grepper = grepper; + return this; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + OperatingSystemMXBean osBean = this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); + RuntimeMXBean runtimeMXBean = this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); + Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); + new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java new file mode 100644 index 000000000..84aec8561 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java @@ -0,0 +1,25 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.exporter.httpserver.HTTPServer; + +import java.io.IOException; + + +public class ExampleExporterForManualTesting { + + public static void main(String[] args) throws IOException, InterruptedException { + + JvmMetrics.newBuilder().register(); + + HTTPServer server = HTTPServer.newBuilder() + .withPort(9400) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + while (true) { + Thread.sleep(100); + Runtime.getRuntime().gc(); // Memory allocation metrics only start after GC run. + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java new file mode 100644 index 000000000..7adc64bf0 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java @@ -0,0 +1,85 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.management.BufferPoolMXBean; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class JvmBufferPoolMetricsTest { + + private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); + private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); + + @Before + public void setUp() { + when(directBuffer.getName()).thenReturn("direct"); + when(directBuffer.getCount()).thenReturn(2L); + when(directBuffer.getMemoryUsed()).thenReturn(1234L); + when(directBuffer.getTotalCapacity()).thenReturn(3456L); + when(mappedBuffer.getName()).thenReturn("mapped"); + when(mappedBuffer.getCount()).thenReturn(3L); + when(mappedBuffer.getMemoryUsed()).thenReturn(2345L); + when(mappedBuffer.getTotalCapacity()).thenReturn(4567L); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.newBuilder() + .withBufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + + "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + + "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"mapped\"} 4567.0\n" + + "# TYPE jvm_buffer_pool_used_buffers gauge\n" + + "# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_buffers{pool=\"direct\"} 2.0\n" + + "jvm_buffer_pool_used_buffers{pool=\"mapped\"} 3.0\n" + + "# TYPE jvm_buffer_pool_used_bytes gauge\n" + + "# UNIT jvm_buffer_pool_used_bytes bytes\n" + + "# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_bytes{pool=\"direct\"} 1234.0\n" + + "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.newBuilder() + .withBufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer)) + .register(registry); + registry.scrape(filter); + + verify(directBuffer, times(0)).getMemoryUsed(); + verify(mappedBuffer, times(0)).getMemoryUsed(); + verify(directBuffer, times(1)).getTotalCapacity(); + verify(mappedBuffer, times(1)).getTotalCapacity(); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java new file mode 100644 index 000000000..fa019258c --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java @@ -0,0 +1,68 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.management.ClassLoadingMXBean; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class JvmClassLoadingMetricsTest { + + private ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); + + @Before + public void setUp() { + when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); + when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); + when(mockClassLoadingBean.getUnloadedClassCount()).thenReturn(500L); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.newBuilder() + .withClassLoadingBean(mockClassLoadingBean) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_classes_currently_loaded gauge\n" + + "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + + "jvm_classes_currently_loaded 1000.0\n" + + "# TYPE jvm_classes_loaded counter\n" + + "# HELP jvm_classes_loaded The total number of classes that have been loaded since the JVM has started execution\n" + + "jvm_classes_loaded_total 2000.0\n" + + "# TYPE jvm_classes_unloaded counter\n" + + "# HELP jvm_classes_unloaded The total number of classes that have been unloaded since the JVM has started execution\n" + + "jvm_classes_unloaded_total 500.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_classes_currently_loaded") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.newBuilder() + .withClassLoadingBean(mockClassLoadingBean) + .register(registry); + registry.scrape(filter); + + verify(mockClassLoadingBean, times(0)).getLoadedClassCount(); + verify(mockClassLoadingBean, times(1)).getTotalLoadedClassCount(); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java new file mode 100644 index 000000000..1bde4873d --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java @@ -0,0 +1,62 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.management.CompilationMXBean; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.internal.verification.VerificationModeFactory.times; + +public class JvmCompilationMetricsTest { + + private CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); + + @Before + public void setUp() { + when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000l); + when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.newBuilder() + .withCompilationBean(mockCompilationBean) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_compilation_time_seconds counter\n" + + "# UNIT jvm_compilation_time_seconds seconds\n" + + "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + + "jvm_compilation_time_seconds_total 10.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.newBuilder() + .withCompilationBean(mockCompilationBean) + .register(registry); + MetricSnapshots snapshots = registry.scrape(filter); + + verify(mockCompilationBean, times(0)).getTotalCompilationTime(); + Assert.assertEquals(0, snapshots.size()); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java new file mode 100644 index 000000000..5b00e61b3 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java @@ -0,0 +1,74 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.management.GarbageCollectorMXBean; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +public class JvmGarbageCollectorMetricsTest { + + private GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); + private GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); + + @Before + public void setUp() { + when(mockGcBean1.getName()).thenReturn("MyGC1"); + when(mockGcBean1.getCollectionCount()).thenReturn(100L); + when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10)); + when(mockGcBean2.getName()).thenReturn("MyGC2"); + when(mockGcBean2.getCollectionCount()).thenReturn(200L); + when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20)); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.newBuilder() + .withGarbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_gc_collection_seconds summary\n" + + "# UNIT jvm_gc_collection_seconds seconds\n" + + "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC1\"} 10.0\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC2\"} 200\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_gc_collection_seconds") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.newBuilder() + .withGarbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(filter); + + verify(mockGcBean1, times(0)).getCollectionTime(); + verify(mockGcBean1, times(0)).getCollectionCount(); + Assert.assertEquals(0, snapshots.size()); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java new file mode 100644 index 000000000..45da976bc --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java @@ -0,0 +1,177 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryUsage; +import java.util.Arrays; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class JvmMemoryMetricsTest { + + private MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); + private MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); + private MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class); + private MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); + + @Before + public void setUp() { + when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); + when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); + + long val = 1L; + when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn((int) val++); + + when(memoryUsageHeap.getUsed()).thenReturn(val++); + when(memoryUsageHeap.getMax()).thenReturn(val++); + when(memoryUsageHeap.getCommitted()).thenReturn(val++); + when(memoryUsageHeap.getInit()).thenReturn(val++); + + when(memoryUsageNonHeap.getUsed()).thenReturn(val++); + when(memoryUsageNonHeap.getMax()).thenReturn(val++); + when(memoryUsageNonHeap.getCommitted()).thenReturn(val++); + when(memoryUsageNonHeap.getInit()).thenReturn(val++); + + when(memoryUsagePoolEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolOldGen.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getInit()).thenReturn(val++); + + when(mockPoolsBeanEdenSpace.getName()).thenReturn("PS Eden Space"); + when(mockPoolsBeanEdenSpace.getUsage()).thenReturn(memoryUsagePoolEdenSpace); + when(mockPoolsBeanEdenSpace.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionEdenSpace); + + when(mockPoolsBeanOldGen.getName()).thenReturn("PS Old Gen"); + when(mockPoolsBeanOldGen.getUsage()).thenReturn(memoryUsagePoolOldGen); + when(mockPoolsBeanOldGen.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionOldGen); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.newBuilder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_memory_committed_bytes gauge\n" + + "# UNIT jvm_memory_committed_bytes bytes\n" + + "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + + "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" + + "jvm_memory_committed_bytes{area=\"nonheap\"} 8.0\n" + + "# TYPE jvm_memory_init_bytes gauge\n" + + "# UNIT jvm_memory_init_bytes bytes\n" + + "# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.\n" + + "jvm_memory_init_bytes{area=\"heap\"} 5.0\n" + + "jvm_memory_init_bytes{area=\"nonheap\"} 9.0\n" + + "# TYPE jvm_memory_max_bytes gauge\n" + + "# UNIT jvm_memory_max_bytes bytes\n" + + "# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.\n" + + "jvm_memory_max_bytes{area=\"heap\"} 3.0\n" + + "jvm_memory_max_bytes{area=\"nonheap\"} 7.0\n" + + "# TYPE jvm_memory_objects_pending_finalization gauge\n" + + "# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.\n" + + "jvm_memory_objects_pending_finalization 1.0\n" + + "# TYPE jvm_memory_pool_collection_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Eden Space\"} 20.0\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Old Gen\"} 24.0\n" + + "# TYPE jvm_memory_pool_collection_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_init_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Eden Space\"} 21.0\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Old Gen\"} 25.0\n" + + "# TYPE jvm_memory_pool_collection_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_max_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Eden Space\"} 19.0\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Old Gen\"} 23.0\n" + + "# TYPE jvm_memory_pool_collection_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_used_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Eden Space\"} 18.0\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Old Gen\"} 22.0\n" + + "# TYPE jvm_memory_pool_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Eden Space\"} 12.0\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Old Gen\"} 16.0\n" + + "# TYPE jvm_memory_pool_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_init_bytes bytes\n" + + "# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Eden Space\"} 13.0\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Old Gen\"} 17.0\n" + + "# TYPE jvm_memory_pool_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_max_bytes bytes\n" + + "# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Eden Space\"} 11.0\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Old Gen\"} 15.0\n" + + "# TYPE jvm_memory_pool_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_used_bytes bytes\n" + + "# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Eden Space\"} 10.0\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Old Gen\"} 14.0\n" + + "# TYPE jvm_memory_used_bytes gauge\n" + + "# UNIT jvm_memory_used_bytes bytes\n" + + "# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.\n" + + "jvm_memory_used_bytes{area=\"heap\"} 2.0\n" + + "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_memory_pool_used_bytes") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.newBuilder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + registry.scrape(filter); + + verify(memoryUsagePoolEdenSpace, times(0)).getUsed(); + verify(memoryUsagePoolOldGen, times(0)).getUsed(); + verify(memoryUsagePoolEdenSpace, times(1)).getMax(); + verify(memoryUsagePoolOldGen, times(1)).getMax(); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java new file mode 100644 index 000000000..19510da32 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java @@ -0,0 +1,65 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.instrumentation.jvm.JvmMemoryPoolAllocationMetrics.AllocationCountingNotificationListener; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JvmMemoryPoolAllocationMetricsTest { + + @Test + public void testListenerLogic() { + PrometheusRegistry registry = new PrometheusRegistry(); + Counter counter = Counter.newBuilder().withName("test").withLabelNames("pool").register(registry); + AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(counter); + + // Increase by 123 + listener.handleMemoryPool("TestPool", 0, 123); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // No increase + listener.handleMemoryPool("TestPool", 123, 123); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // No increase, then decrease to 0 + listener.handleMemoryPool("TestPool", 123, 0); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // No increase, then increase by 7 + listener.handleMemoryPool("TestPool", 0, 7); + assertEquals(130, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // Increase by 10, then decrease to 10 + listener.handleMemoryPool("TestPool", 17, 10); + assertEquals(140, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // Increase by 7, then increase by 3 + listener.handleMemoryPool("TestPool", 17, 20); + assertEquals(150, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + + // Decrease to 17, then increase by 3 + listener.handleMemoryPool("TestPool", 17, 20); + assertEquals(153, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + } + + private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) { + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getPrometheusName().equals(metricName)) { + for (CounterSnapshot.CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getData()) { + if (data.getLabels().get("pool").equals(poolName)) { + return data.getValue(); + } + } + } + } + Assert.fail("pool " + poolName + " not found."); + return 0.0; + } + +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java new file mode 100644 index 000000000..db611c4d1 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; + +public class JvmRuntimeInfoMetricTest { + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmRuntimeInfoMetric.newBuilder() + .withVersion("1.8.0_382-b05") + .withVendor("Oracle Corporation") + .withRuntime("OpenJDK Runtime Environment") + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_runtime info\n" + + "# HELP jvm_runtime JVM runtime info\n" + + "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java new file mode 100644 index 000000000..73832c303 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -0,0 +1,187 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class JvmThreadsMetricsTest { + + private ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); + private ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); + private ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); + private ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); + + @Before + public void setUp() { + when(mockThreadsBean.getThreadCount()).thenReturn(300); + when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); + when(mockThreadsBean.getPeakThreadCount()).thenReturn(301); + when(mockThreadsBean.getTotalStartedThreadCount()).thenReturn(503L); + when(mockThreadsBean.findDeadlockedThreads()).thenReturn(new long[]{1L, 2L, 3L}); + when(mockThreadsBean.findMonitorDeadlockedThreads()).thenReturn(new long[]{2L, 3L, 4L}); + when(mockThreadsBean.getAllThreadIds()).thenReturn(new long[]{3L, 4L, 5L}); + when(mockThreadInfoBlocked.getThreadState()).thenReturn(Thread.State.BLOCKED); + when(mockThreadInfoRunnable1.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadInfoRunnable2.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadsBean.getThreadInfo(new long[]{3L, 4L, 5L}, 0)).thenReturn(new ThreadInfo[]{ + mockThreadInfoBlocked, mockThreadInfoRunnable1, mockThreadInfoRunnable2 + }); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.newBuilder() + .withThreadBean(mockThreadsBean) + .withIsNativeImage(false) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_threads_current gauge\n" + + "# HELP jvm_threads_current Current thread count of a JVM\n" + + "jvm_threads_current 300.0\n" + + "# TYPE jvm_threads_daemon gauge\n" + + "# HELP jvm_threads_daemon Daemon thread count of a JVM\n" + + "jvm_threads_daemon 200.0\n" + + "# TYPE jvm_threads_deadlocked gauge\n" + + "# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers\n" + + "jvm_threads_deadlocked 3.0\n" + + "# TYPE jvm_threads_deadlocked_monitor gauge\n" + + "# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors\n" + + "jvm_threads_deadlocked_monitor 3.0\n" + + "# TYPE jvm_threads_peak gauge\n" + + "# HELP jvm_threads_peak Peak thread count of a JVM\n" + + "jvm_threads_peak 301.0\n" + + "# TYPE jvm_threads_started counter\n" + + "# HELP jvm_threads_started Started thread count of a JVM\n" + + "jvm_threads_started_total 503.0\n" + + "# TYPE jvm_threads_state gauge\n" + + "# HELP jvm_threads_state Current count of threads by state\n" + + "jvm_threads_state{state=\"BLOCKED\"} 1.0\n" + + "jvm_threads_state{state=\"NEW\"} 0.0\n" + + "jvm_threads_state{state=\"RUNNABLE\"} 2.0\n" + + "jvm_threads_state{state=\"TERMINATED\"} 0.0\n" + + "jvm_threads_state{state=\"TIMED_WAITING\"} 0.0\n" + + "jvm_threads_state{state=\"UNKNOWN\"} 0.0\n" + + "jvm_threads_state{state=\"WAITING\"} 0.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("jvm_threads_deadlocked") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.newBuilder() + .withThreadBean(mockThreadsBean) + .withIsNativeImage(false) + .register(registry); + registry.scrape(filter); + + verify(mockThreadsBean, times(0)).findDeadlockedThreads(); + verify(mockThreadsBean, times(1)).getThreadCount(); + } + + @Test + public void testInvalidThreadIds() { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.newBuilder().register(registry); + MetricSnapshots snapshots = registry.scrape(); + + // Number of threads to create with invalid thread ids + int numberOfInvalidThreadIds = 2; + + Map expected = getCountByState(snapshots); + expected.compute("UNKNOWN", (key, oldValue) -> oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); + + final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + + try { + // Create and start threads with invalid thread ids (id=0, id=-1, etc.) + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + new TestThread(-i, new TestRunnable(countDownLatch)).start(); + } + + Map actual = getCountByState(registry.scrape()); + + Assert.assertEquals(expected.size(), actual.size()); + for (String threadState : expected.keySet()) { + Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0); + } + } finally { + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + countDownLatch.countDown(); + } + } + } + + private Map getCountByState(MetricSnapshots snapshots) { + Map result = new HashMap<>(); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getData()) { + String state = data.getLabels().get("state"); + Assert.assertNotNull(state); + result.put(state, data.getValue()); + } + } + } + return result; + } + + private static class TestThread extends Thread { + + private final long id; + + public TestThread(long id, Runnable runnable) { + super(runnable); + setDaemon(true); + this.id = id; + } + + public long getId() { + return this.id; + } + } + + private static class TestRunnable implements Runnable { + + private final CountDownLatch countDownLatch; + + public TestRunnable(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + // DO NOTHING + } + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java new file mode 100644 index 000000000..23e030419 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java @@ -0,0 +1,115 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.MetricNameFilter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.File; +import java.io.IOException; +import java.lang.management.RuntimeMXBean; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class ProcessMetricsTest { + + private com.sun.management.UnixOperatingSystemMXBean sunOsBean = Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); + private java.lang.management.OperatingSystemMXBean javaOsBean = Mockito.mock(java.lang.management.OperatingSystemMXBean.class); + private ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); + + @Before + public void setUp() throws IOException { + when(sunOsBean.getProcessCpuTime()).thenReturn(72L); + when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); + when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); + when(runtimeBean.getStartTime()).thenReturn(37100L); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmSize:"))).thenReturn("VmSize: 6036 kB"); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmRSS:"))).thenReturn("VmRSS: 1012 kB"); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.newBuilder() + .withOsBean(sunOsBean) + .withRuntimeBean(runtimeBean) + .withGrepper(linuxGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE process_cpu_seconds counter\n" + + "# UNIT process_cpu_seconds seconds\n" + + "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + + "process_cpu_seconds_total 0.072\n" + + "# TYPE process_max_fds gauge\n" + + "# HELP process_max_fds Maximum number of open file descriptors.\n" + + "process_max_fds 244.0\n" + + "# TYPE process_open_fds gauge\n" + + "# HELP process_open_fds Number of open file descriptors.\n" + + "process_open_fds 127.0\n" + + "# TYPE process_resident_memory_bytes gauge\n" + + "# UNIT process_resident_memory_bytes bytes\n" + + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + + "process_resident_memory_bytes 1036288.0\n" + + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n" + + "# TYPE process_virtual_memory_bytes gauge\n" + + "# UNIT process_virtual_memory_bytes bytes\n" + + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + + "process_virtual_memory_bytes 6180864.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testMinimal() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.newBuilder() + .withOsBean(javaOsBean) + .withRuntimeBean(runtimeBean) + .withGrepper(windowsGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = MetricNameFilter.newBuilder() + .nameMustNotBeEqualTo("process_max_fds") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.newBuilder() + .withOsBean(sunOsBean) + .withRuntimeBean(runtimeBean) + .withGrepper(linuxGrepper) + .register(registry); + registry.scrape(filter); + + verify(sunOsBean, times(0)).getMaxFileDescriptorCount(); + verify(sunOsBean, times(1)).getOpenFileDescriptorCount(); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java new file mode 100644 index 000000000..2b0d7972c --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java @@ -0,0 +1,18 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class TestUtil { + + static String convertToOpenMetricsFormat(MetricSnapshots snapshots) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, snapshots); + return out.toString(StandardCharsets.UTF_8.name()); + } +} diff --git a/prometheus-metrics-instrumentation-jvm/version-rules.xml b/prometheus-metrics-instrumentation-jvm/version-rules.xml new file mode 100644 index 000000000..904c3c3a1 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^9].* + + + + diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index 232cd9143..e63cdc000 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -44,4 +44,8 @@ public static double nanosToSeconds(long nanos) { public static double millisToSeconds(long nanos) { return nanos / 1E3; } + + public static double kiloBytesToBytes(double kilobytes) { + return kilobytes * 1024; + } } From 1dd19e9bffe21c11fbfa01dc4e5a82e486aaaad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 7 Sep 2023 12:29:46 +0200 Subject: [PATCH 200/980] Temporarily add shaded dependencies to prepare for release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 18be07c93..d939faa10 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm - + prometheus-metrics-shaded-dependencies examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 033bd8c99..a331de619 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.0.0-alpha-3 + ${project.version} From a4e4f07ef20d765e62d2d4cb32086a85010cf3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 7 Sep 2023 12:32:55 +0200 Subject: [PATCH 201/980] [maven-release-plugin] prepare release v1.0.0-alpha-4 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 67 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 783ee55eb..e29219b8a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index c8742ffdb..0a7a5b8ac 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 4fbc0c647..540e15360 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 4f34ee5ab..994113612 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index f8221fa8c..5144c498c 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 976a67f64..2538dd5f1 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 7b5761519..bd770d8a9 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 example-exporter-servlet-tomcat diff --git a/examples/pom.xml b/examples/pom.xml index bbbe729f6..21dfce4c9 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 0e3b099c6..139ef449a 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index d4f83ac82..016ddaf36 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 104666b07..616e857c2 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index ccfbcdc12..d31d792eb 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 59110421d..2dde74cb4 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index b14c5bca6..cc268ac12 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-4 diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 223de113f..9795df88b 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 5a36f4489..5ce6f4d2a 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 625d2c9b9..5874aec01 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index b9cd61ca1..6a9a4a290 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index dd303f86e..46146f577 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 38bfa4fb3..190ed17d6 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 9d3cab3a2..eaece7f57 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 195f5ae46..608ba030c 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 942b912ab..52ae34196 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 integration_tests diff --git a/pom.xml b/pom.xml index d939faa10..a312758a3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-4 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 071cf4a28..934dba430 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 2151549bd..b648f574e 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 309674dbd..8e8ceb1ef 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 8675e8047..551ba4f5f 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index a331de619..1bca48ea0 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 9a369f799..24239d3e4 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 62f6a806b..1a7440f5a 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index fdddcc1ee..b89b21e41 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 8a8c20631..359c95274 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 0e0f4f266..babfcd19b 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index fd69c1689..6121bcd98 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 47746ea40..717ebef21 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index d000e3ea6..7338ed90b 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 0e01fd462..fbafc66fa 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 4a15f1189..8ec63a423 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index e5bab6fc5..396877d1c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index e3c01697f..1599a3a82 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index f5f030552..7209f1c6d 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index f78c01c6d..8a26f2f82 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 4a820d18c..33c7b6c08 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index a3facdc4f..300f8cfce 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index deede1590..5ffc5497f 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 67e48acd2..f0f11edb9 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 50b704b75..0b2d673f7 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index df4569384..13c99ca1c 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 4dc25a5f5..d93848d26 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index c8bcaee09..37fb32992 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 91d9ca763..43383a390 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 26c601a77..68701af43 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 1d804e9c9..8f22b8510 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 31805d97d..df7b0a635 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 39e6acabb..2875962f8 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 4fb7ab4b8..b2f0783ef 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 4c7e4d4fa..1f7c1a9cc 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index ad3ce2f57..3d58b715f 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index d223bc04e..0f1eac95d 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 3c36741f6..93c1bca1f 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 74ca017da..f1b07f1a4 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 996ccb70d..cc4fef72f 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index c86e7c1f5..f6f2d867f 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 71299100b..17d3537e6 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index c2d5b0ee1..09cb0c054 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 50d3bdeea..12db11748 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4-SNAPSHOT + 1.0.0-alpha-4 simpleclient_vertx4 From 584ebe39d00b6582df962c2cf5f5de8274dd23cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 7 Sep 2023 12:33:00 +0200 Subject: [PATCH 202/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 67 files changed, 69 insertions(+), 69 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index e29219b8a..375f3fb9b 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 0a7a5b8ac..2cc537e79 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 540e15360..bcebd17d6 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 994113612..0c189b110 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 5144c498c..b6e4d9399 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 2538dd5f1..a973a698d 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index bd770d8a9..47f055161 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/pom.xml b/examples/pom.xml index 21dfce4c9..30e6895dd 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 139ef449a..85f2cd2a1 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 016ddaf36..3760cb018 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 616e857c2..f078c3026 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index d31d792eb..47081063e 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 2dde74cb4..442d34b3b 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index cc268ac12..5f9b5f0a8 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-4 + HEAD diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 9795df88b..5dc330aea 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 5ce6f4d2a..e1f35cf56 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 5874aec01..fed6fbbf9 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 6a9a4a290..10ff2ea46 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 46146f577..257e32e6e 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 190ed17d6..a063bcaa3 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index eaece7f57..8831f4713 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 608ba030c..47717c6d1 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 52ae34196..31d756ce9 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index a312758a3..357c58f9f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-4 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 934dba430..b412a15e4 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index b648f574e..c8ecd259f 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 8e8ceb1ef..cd3f62575 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 551ba4f5f..c2aeb4995 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 1bca48ea0..8d646cbc4 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 24239d3e4..98a0c0d95 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 1a7440f5a..40e3f04d0 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index b89b21e41..2a6e6ce41 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 359c95274..7e3de38aa 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index babfcd19b..27512cb0b 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 6121bcd98..152666cca 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 717ebef21..51071a8c0 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 7338ed90b..2ba88fa0d 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index fbafc66fa..ac60addfb 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 8ec63a423..bb42f0681 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 396877d1c..a38ff4806 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 1599a3a82..df562046d 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 7209f1c6d..652bec540 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 8a26f2f82..567691996 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 33c7b6c08..9fcbe8435 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 300f8cfce..b07ae1a73 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 5ffc5497f..6c78f43d2 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index f0f11edb9..01f19b15f 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 0b2d673f7..3375774d8 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 13c99ca1c..833d0a797 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index d93848d26..3d7ecd892 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 37fb32992..3954d5e31 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 43383a390..b7653aecf 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 68701af43..12129962d 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 8f22b8510..d8eb1a2a0 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index df7b0a635..eb434a61d 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 2875962f8..e8c71e454 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index b2f0783ef..fcaa1ab97 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 1f7c1a9cc..3b8918b3b 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 3d58b715f..e99a3dc80 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 0f1eac95d..4667556d6 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 93c1bca1f..f335bc6b8 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index f1b07f1a4..4c0a0e141 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index cc4fef72f..ccdc01bd2 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index f6f2d867f..7bcdd770c 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 17d3537e6..3d7260323 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 09cb0c054..0155f9834 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 12db11748..7fdb7c10e 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-4 + 1.0.0-alpha-5-SNAPSHOT simpleclient_vertx4 From c5a95d95679bf21c2e2836d3e9ca11e025af554d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 7 Sep 2023 13:16:36 +0200 Subject: [PATCH 203/980] Exclude shaded dependencies from the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 357c58f9f..143f36c96 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm - prometheus-metrics-shaded-dependencies + examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 8d646cbc4..d471265e0 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - ${project.version} + 1.0.0-alpha-4 From 0f0d3020a4fa3e03c1d38bc5d926ce8448659eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 8 Sep 2023 16:14:12 +0200 Subject: [PATCH 204/980] Improve the default executor service in HTTPServer --- .../exporter/httpserver/HTTPServer.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 47a512066..7224ff3e7 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -16,6 +16,8 @@ import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -222,9 +224,14 @@ private ExecutorService makeExecutorService() { if (executorService != null) { return executorService; } else { - ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(NamedDaemonThreadFactory.defaultThreadFactory(true)); - executor.setKeepAliveTime(2, TimeUnit.MINUTES); - return executor; + return new ThreadPoolExecutor( + 1, + 10, + 120, + TimeUnit.SECONDS, + new SynchronousQueue<>(true), + NamedDaemonThreadFactory.defaultThreadFactory(true), + new BlockingRejectedExecutionHandler()); } } @@ -244,4 +251,17 @@ private void assertNull(Object o, String msg) { } } } + + private static class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { + if (!threadPoolExecutor.isShutdown()) { + try { + threadPoolExecutor.getQueue().put(runnable); + } catch (InterruptedException ignored) { + } + } + } + } } From 898d476cdc4b96b87d8f482e067f33b2bf3b0e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 8 Sep 2023 15:59:44 +0200 Subject: [PATCH 205/980] Add Simpleclient Backwards-Compatibility Module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- examples/example-exporter-httpserver/pom.xml | 2 +- .../example-simpleclient-bridge/README.md | 26 ++ examples/example-simpleclient-bridge/pom.xml | 76 ++++ .../metrics/examples/simpleclient/Main.java | 41 ++ examples/pom.xml | 1 + pom.xml | 1 + .../ExpositionFormatsTest.java | 12 +- .../metrics/model/snapshots/Unit.java | 8 +- .../pom.xml | 68 +++ .../bridge/SimpleclientCollector.java | 400 ++++++++++++++++++ .../bridge/SimpleclientCollectorTest.java | 250 +++++++++++ .../version-rules.xml | 12 + 12 files changed, 888 insertions(+), 9 deletions(-) create mode 100644 examples/example-simpleclient-bridge/README.md create mode 100644 examples/example-simpleclient-bridge/pom.xml create mode 100644 examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java create mode 100644 prometheus-metrics-simpleclient-bridge/pom.xml create mode 100644 prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java create mode 100644 prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java create mode 100644 prometheus-metrics-simpleclient-bridge/version-rules.xml diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index b6e4d9399..95a91eafa 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -64,7 +64,7 @@ - io.prometheus.metrics.examples.httpserver.Main + io.prometheus.metrics.examples.simpleclient.Main diff --git a/examples/example-simpleclient-bridge/README.md b/examples/example-simpleclient-bridge/README.md new file mode 100644 index 000000000..03ccd1ca2 --- /dev/null +++ b/examples/example-simpleclient-bridge/README.md @@ -0,0 +1,26 @@ +# Built-in HTTPServer for Exposing Metrics + +## Build + +This example is built as part of the `client_java` project. + +``` +./mvnw package +``` + +## Run + +The build creates a JAR file with the example application in `./examples/example-simpleclient-bridge/target/`. + +``` +java -jar ./examples/example-simpleclient-bridge/target/example-simpleclient-bridge.jar +``` + +This should expose a metrics endpoint on [http://localhost:9400/metrics](http://localhost:9400/metrics). +The `events_total` counter should be exposed.with a Web browser should yield an example of a counter metric. + +``` +# HELP events_total total number of events +# TYPE events_total counter +events_total 1.0 +``` diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml new file mode 100644 index 000000000..d819f300b --- /dev/null +++ b/examples/example-simpleclient-bridge/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.0.0-alpha-5-SNAPSHOT + + + example-simpleclient-bridge + + Example - Simpleclient Bridge + + Prometheus Metrics Example of the Simpleclient Backwards Compatibility module + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + simpleclient + 0.16.0 + + + io.prometheus + prometheus-metrics-simpleclient-bridge + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-httpserver + ${project.version} + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.simpleclient.Main + + + + + + + + + diff --git a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java new file mode 100644 index 000000000..0a72c960b --- /dev/null +++ b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java @@ -0,0 +1,41 @@ +package io.prometheus.metrics.examples.simpleclient; + +import io.prometheus.client.Counter; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.simpleclient.bridge.SimpleclientCollector; + +import java.io.IOException; + +/** + * Simple example of the simpleclient backwards compatibility module. + */ +public class Main { + + public static void main(String[] args) throws IOException, InterruptedException { + + // The following call will register all metrics from the old CollectorRegistry.defaultRegistry + // with the new PrometheusRegistry.defaultRegistry. + + SimpleclientCollector.newBuilder().register(); + + // Register a counter with the old CollectorRegistry. + // It doesn't matter whether the counter is registered before or after bridging with PrometheusRegistry. + + Counter simpleclientCounter = Counter.build() + .name("events_total") + .help("total number of events") + .register(); + + simpleclientCounter.inc(); + + // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric. + + HTTPServer server = HTTPServer.newBuilder() + .withPort(9400) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + Thread.currentThread().join(); + } +} diff --git a/examples/pom.xml b/examples/pom.xml index 30e6895dd..787db8b08 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -37,6 +37,7 @@ example-exporter-servlet-tomcat example-exporter-httpserver example-exporter-opentelemetry + example-simpleclient-bridge diff --git a/pom.xml b/pom.xml index 143f36c96..d187341fa 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,7 @@ prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm + prometheus-metrics-simpleclient-bridge examples integration-tests diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index cf6cb09a6..4d97b739f 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -741,7 +741,7 @@ public void testClassicHistogramComplete() throws Exception { "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + @@ -755,7 +755,7 @@ public void testClassicHistogramComplete() throws Exception { "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + @@ -772,7 +772,7 @@ public void testClassicHistogramComplete() throws Exception { "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + @@ -785,7 +785,7 @@ public void testClassicHistogramComplete() throws Exception { "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"0.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + @@ -819,7 +819,7 @@ public void testClassicHistogramComplete() throws Exception { "sample_sum: 3.2 " + "bucket { " + "cumulative_count: 3 " + - "upper_bound: 0.0 " + + "upper_bound: 1.0 " + "} bucket { " + "cumulative_count: 5 " + "upper_bound: 2.2 " + @@ -839,7 +839,7 @@ public void testClassicHistogramComplete() throws Exception { .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() .withSum(3.2) .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(0.0, 3) + .addBucket(1.0, 3) .addBucket(2.2, 2) .addBucket(Double.POSITIVE_INFINITY, 0) .build()) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index e63cdc000..d73980a97 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -41,8 +41,12 @@ public static double nanosToSeconds(long nanos) { return nanos / 1E9; } - public static double millisToSeconds(long nanos) { - return nanos / 1E3; + public static double millisToSeconds(long millis) { + return millis / 1E3; + } + + public static double secondsToMillis(double seconds) { + return seconds * 1E3; } public static double kiloBytesToBytes(double kilobytes) { diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml new file mode 100644 index 000000000..0dd0a75eb --- /dev/null +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.0.0-alpha-5-SNAPSHOT + + + prometheus-metrics-simpleclient-bridge + bundle + + Prometheus Metrics - Simpleclient Bridge + + Bridge the old simpleclient CollectorRegistry to the new PrometheusRegistry + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-model + ${project.version} + + + io.prometheus + simpleclient + 0.16.0 + provided + + + + + junit + junit + 4.13.2 + test + + + io.prometheus + prometheus-metrics-exposition-formats + ${project.version} + test + + + io.prometheus + simpleclient_common + 0.16.0 + test + + + diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java new file mode 100644 index 000000000..bbe82a5d1 --- /dev/null +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -0,0 +1,400 @@ +package io.prometheus.metrics.simpleclient.bridge; + +import io.prometheus.client.Collector; +import io.prometheus.client.CollectorRegistry; +import io.prometheus.metrics.model.registry.MultiCollector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +/** + * Bridge from {@code simpleclient} (version 0.16.0 and older) to the new {@code prometheus-metrics} (version 1.0.0 and newer). + *

    + * Usage: The following line will register all metrics from a {@code simpleclient} {@link CollectorRegistry#defaultRegistry} + * to a {@code prometheus-metrics} {@link PrometheusRegistry#defaultRegistry}: + *

    {@code
    + * SimpleclientCollector.newBuilder().register();
    + * }
    + *

    + * If you have custom registries (not the default registries), use the following snippet: + *

    {@code
    + * CollectorRegistry simpleclientRegistry = ...;
    + * PrometheusRegistry prometheusRegistry = ...;
    + * SimpleclientCollector.newBuilder()
    + *     .withCollectorRegistry(simpleclientRegistry)
    + *     .register(prometheusRegistry);
    + * }
    + */ +public class SimpleclientCollector implements MultiCollector { + + private final CollectorRegistry simpleclientRegistry; + + private SimpleclientCollector(CollectorRegistry simpleclientRegistry) { + this.simpleclientRegistry = simpleclientRegistry; + } + + @Override + public MetricSnapshots collect() { + return convert(simpleclientRegistry.metricFamilySamples()); + } + + @Override + public MetricSnapshots collect(Predicate includedNames) { + return MultiCollector.super.collect(includedNames); + } + + @Override + public List getPrometheusNames() { + return MultiCollector.super.getPrometheusNames(); + } + + private MetricSnapshots convert(Enumeration samples) { + MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); + while (samples.hasMoreElements()) { + Collector.MetricFamilySamples sample = samples.nextElement(); + switch (sample.type) { + case COUNTER: + result.addMetricSnapshot(convertCounter(sample)); + break; + case GAUGE: + result.addMetricSnapshot(convertGauge(sample)); + break; + case HISTOGRAM: + result.addMetricSnapshot(convertHistogram(sample, false)); + break; + case GAUGE_HISTOGRAM: + result.addMetricSnapshot(convertHistogram(sample, true)); + break; + case SUMMARY: + result.addMetricSnapshot(convertSummary(sample)); + break; + case INFO: + result.addMetricSnapshot(convertInfo(sample)); + break; + case STATE_SET: + result.addMetricSnapshot(convertStateSet(sample)); + break; + case UNKNOWN: + result.addMetricSnapshot(convertUnknown(sample)); + break; + default: + throw new IllegalStateException(sample.type + ": Unexpected metric type"); + } + } + return result.build(); + } + + private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) { + CounterSnapshot.Builder counter = CounterSnapshot.newBuilder() + .withName(stripSuffix(samples.name, "_total")) + .withHelp(samples.help) + .withUnit(convertUnit(samples)); + Map dataPoints = new HashMap<>(); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + Labels labels = Labels.of(sample.labelNames, sample.labelValues); + CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint = dataPoints.computeIfAbsent(labels, l -> CounterSnapshot.CounterDataPointSnapshot.newBuilder().withLabels(labels)); + if (sample.name.endsWith("_created")) { + dataPoint.withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + } else { + dataPoint.withValue(sample.value).withExemplar(convertExemplar(sample.exemplar)); + if (sample.timestampMs != null) { + dataPoint.withScrapeTimestampMillis(sample.timestampMs); + } + } + } + for (CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint : dataPoints.values()) { + counter.addDataPoint(dataPoint.build()); + } + return counter.build(); + } + + private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) { + GaugeSnapshot.Builder gauge = GaugeSnapshot.newBuilder() + .withName(samples.name) + .withHelp(samples.help) + .withUnit(convertUnit(samples)); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPoint = GaugeSnapshot.GaugeDataPointSnapshot.newBuilder() + .withValue(sample.value) + .withLabels(Labels.of(sample.labelNames, sample.labelValues)) + .withExemplar(convertExemplar(sample.exemplar)); + if (sample.timestampMs != null) { + dataPoint.withScrapeTimestampMillis(sample.timestampMs); + } + gauge.addDataPoint(dataPoint.build()); + } + return gauge.build(); + } + + private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, boolean isGaugeHistogram) { + HistogramSnapshot.Builder histogram = HistogramSnapshot.newBuilder() + .withName(samples.name) + .withHelp(samples.help) + .withUnit(convertUnit(samples)); + if (isGaugeHistogram) { + histogram.asGaugeHistogram(); + } + Map dataPoints = new HashMap<>(); + Map> cumulativeBuckets = new HashMap<>(); + Map exemplars = new HashMap<>(); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + Labels labels = labelsWithout(sample, "le"); + dataPoints.computeIfAbsent(labels, l -> HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() + .withLabels(labels)); + cumulativeBuckets.computeIfAbsent(labels, l -> new HashMap<>()); + exemplars.computeIfAbsent(labels, l -> Exemplars.newBuilder()); + if (sample.name.endsWith("_sum")) { + dataPoints.get(labels).withSum(sample.value); + } + if (sample.name.endsWith("_bucket")) { + addBucket(cumulativeBuckets.get(labels), sample); + } + if (sample.name.endsWith("_created")) { + dataPoints.get(labels).withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + } + if (sample.exemplar != null) { + exemplars.get(labels).addExemplar(convertExemplar(sample.exemplar)); + } + if (sample.timestampMs != null) { + dataPoints.get(labels).withScrapeTimestampMillis(sample.timestampMs); + } + } + for (Labels labels : dataPoints.keySet()) { + histogram.addDataPoint(dataPoints.get(labels) + .withClassicHistogramBuckets(makeBuckets(cumulativeBuckets.get(labels))) + .withExemplars(exemplars.get(labels).build()) + .build()); + } + return histogram.build(); + } + + private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) { + SummarySnapshot.Builder summary = SummarySnapshot.newBuilder() + .withName(samples.name) + .withHelp(samples.help) + .withUnit(convertUnit(samples)); + Map dataPoints = new HashMap<>(); + Map quantiles = new HashMap<>(); + Map exemplars = new HashMap<>(); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + Labels labels = labelsWithout(sample, "quantile"); + dataPoints.computeIfAbsent(labels, l -> SummarySnapshot.SummaryDataPointSnapshot.newBuilder() + .withLabels(labels)); + quantiles.computeIfAbsent(labels, l -> Quantiles.newBuilder()); + exemplars.computeIfAbsent(labels, l -> Exemplars.newBuilder()); + if (sample.name.endsWith("_sum")) { + dataPoints.get(labels).withSum(sample.value); + } else if (sample.name.endsWith("_count")) { + dataPoints.get(labels).withCount((long) sample.value); + } else if (sample.name.endsWith("_created")) { + dataPoints.get(labels).withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + } else { + for (int i=0; i dataPoints = new HashMap<>(); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + Labels labels = labelsWithout(sample, sample.name); + dataPoints.computeIfAbsent(labels, l -> StateSetSnapshot.StateSetDataPointSnapshot.newBuilder().withLabels(labels)); + String stateName = null; + for (int i=0; i cumulativeBuckets) { + List upperBounds = new ArrayList<>(cumulativeBuckets.size()); + Collections.sort(upperBounds); + upperBounds.addAll(cumulativeBuckets.keySet()); + ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.newBuilder(); + long previousCount = 0L; + for (Double upperBound : upperBounds) { + long cumulativeCount = cumulativeBuckets.get(upperBound); + result.addBucket(upperBound, cumulativeCount - previousCount); + previousCount = cumulativeCount; + } + return result.build(); + } + + private void addBucket(Map buckets, Collector.MetricFamilySamples.Sample sample) { + for (int i = 0; i < sample.labelNames.size(); i++) { + if (sample.labelNames.get(i).equals("le")) { + double upperBound; + switch (sample.labelValues.get(i)) { + case "+Inf": + upperBound = Double.POSITIVE_INFINITY; + break; + case "-Inf": // Doesn't make sense as count would always be zero. Catch this anyway. + upperBound = Double.NEGATIVE_INFINITY; + break; + default: + upperBound = Double.parseDouble(sample.labelValues.get(i)); + } + buckets.put(upperBound, (long) sample.value); + return; + } + } + throw new IllegalStateException(sample.name + " does not have a le label."); + } + + + private Labels labelsWithout(Collector.MetricFamilySamples.Sample sample, String excludedLabelName) { + Labels.Builder labels = Labels.newBuilder(); + for (int i = 0; i < sample.labelNames.size(); i++) { + if (!sample.labelNames.get(i).equals(excludedLabelName)) { + labels.addLabel(sample.labelNames.get(i), sample.labelValues.get(i)); + } + } + return labels.build(); + } + + private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) { + InfoSnapshot.Builder info = InfoSnapshot.newBuilder() + .withName(stripSuffix(samples.name, "_info")) + .withHelp(samples.help); + for (Collector.MetricFamilySamples.Sample sample : samples.samples) { + info.addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() + .withLabels(Labels.of(sample.labelNames, sample.labelValues)) + .build()); + } + return info.build(); + } + + private Exemplar convertExemplar(io.prometheus.client.exemplars.Exemplar exemplar) { + if (exemplar == null) { + return null; + } + Exemplar.Builder result = Exemplar.newBuilder().withValue(exemplar.getValue()); + if (exemplar.getTimestampMs() != null) { + result.withTimestampMillis(exemplar.getTimestampMs()); + } + Labels.Builder labels = Labels.newBuilder(); + for (int i = 0; i < exemplar.getNumberOfLabels(); i++) { + labels.addLabel(exemplar.getLabelName(i), exemplar.getLabelValue(i)); + } + return result.withLabels(labels.build()).build(); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + private CollectorRegistry collectorRegistry; + private Builder() {} + + public Builder withCollectorRegistry(CollectorRegistry registry) { + this.collectorRegistry = registry; + return this; + } + + public SimpleclientCollector build() { + return collectorRegistry != null ? new SimpleclientCollector(collectorRegistry) : new SimpleclientCollector(CollectorRegistry.defaultRegistry); + } + + public SimpleclientCollector register() { + return register(PrometheusRegistry.defaultRegistry); + } + + public SimpleclientCollector register(PrometheusRegistry registry) { + SimpleclientCollector result = build(); + registry.register(result); + return result; + } + } +} diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java new file mode 100644 index 000000000..7645c7296 --- /dev/null +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -0,0 +1,250 @@ +package io.prometheus.metrics.simpleclient.bridge; + +import io.prometheus.client.Collector; +import io.prometheus.client.CollectorRegistry; +import io.prometheus.client.Counter; +import io.prometheus.client.Gauge; +import io.prometheus.client.Histogram; +import io.prometheus.client.Info; +import io.prometheus.client.Summary; +import io.prometheus.client.exporter.common.TextFormat; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SimpleclientCollectorTest { + + private CollectorRegistry origRegistry; + private PrometheusRegistry newRegistry; + + @Before + public void setUp() { + origRegistry = new CollectorRegistry(); + newRegistry = new PrometheusRegistry(); + SimpleclientCollector.newBuilder() + .withCollectorRegistry(origRegistry) + .register(newRegistry); + } + + @Test + public void testCounterComplete() throws IOException, InterruptedException { + Counter counter = Counter.build() + .name("service_time_seconds_total") + .help("total time spent serving") + .labelNames("path", "status") + .register(origRegistry); + counter.labels("/hello", "200").incWithExemplar(0.8, "trace_id", "12345", "span_id", "abcde"); + Thread.sleep(3); // make timestamps a bit different + counter.labels("/hello", "500").incWithExemplar(2.4, "trace_id", "23446", "span_id", "bcdef"); + + Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics())); + } + + @Test + public void testCounterMinimal() throws IOException, InterruptedException { + Counter.build() + .name("events") + .help("total number of events") + .register(origRegistry); + + Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics())); + } + + @Test + public void testGaugeComplete() throws IOException, InterruptedException { + Gauge gauge = Gauge.build() + .name("disk_usage_ratio") + .help("percentage used") + .unit("ratio") + .labelNames("device") + .register(origRegistry); + gauge.labels("/dev/sda1").set(0.2); + Thread.sleep(3); + gauge.labels("/dev/sda2").set(0.7); + + Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + } + + @Test + public void testGaugeMinimal() throws IOException, InterruptedException { + Gauge gauge = Gauge.build() + .name("temperature_centigrade") + .help("temperature") + .unit("celsius") + .register(origRegistry); + gauge.set(22.3); + + Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + } + + @Test + public void testHistogramComplete() throws IOException, InterruptedException { + Histogram histogram = Histogram.build() + .name("response_size_bytes") + .help("response size in Bytes") + .labelNames("status") + .buckets(64, 256) + .register(origRegistry); + histogram.labels("200").observeWithExemplar(38, "trace_id", "1", "span_id", "2"); + histogram.labels("200").observeWithExemplar(127, "trace_id", "3", "span_id", "4"); + histogram.labels("200").observeWithExemplar(130, "trace_id", "5", "span_id", "6"); + histogram.labels("200").observeWithExemplar(40, "trace_id", "7", "span_id", "8"); + histogram.labels("200").observeWithExemplar(41, "trace_id", "9", "span_id", "10"); + Thread.sleep(3); // make timestamps a bit different + histogram.labels("500").observeWithExemplar(10000, "trace_id", "11", "span_id", "12"); + + Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + } + + @Test + public void testHistogramMinimal() throws IOException, InterruptedException { + Histogram.build() + .name("request_latency") + .help("request latency") + .register(origRegistry); + + Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + } + + @Test + public void testSummaryComplete() throws IOException, InterruptedException { + Summary summary = Summary.build() + .name("http_request_duration_seconds") + .help("request duration") + .labelNames("path", "status") + .quantile(0.5, 0.01) + .quantile(0.95, 0.01) + .quantile(0.99, 0.001) + .register(origRegistry); + summary.labels("/", "200").observe(0.2); + Thread.sleep(3); + summary.labels("/info", "200").observe(0.7); + summary.labels("/info", "200").observe(0.8); + summary.labels("/info", "200").observe(0.9); + Thread.sleep(3); + summary.labels("/", "500").observe(0.3); + summary.labels("/", "500").observe(0.31); + summary.labels("/", "500").observe(0.32); + + Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + } + + @Test + public void testSummaryMinimal() throws IOException, InterruptedException { + Summary summary = Summary.build() + .name("request_size") + .help("request size") + .register(origRegistry); + + Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + } + + @Test + public void testInfoComplete() throws IOException, InterruptedException { + Info info = Info.build() + .name("version") + .help("version information") + .labelNames("env") + .register(origRegistry); + info.labels("prod").info("major_version", "12", "minor_version", "3"); + Thread.sleep(3); + info.labels("dev").info("major_version", "13", "minor_version", "1"); + + Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + } + + @Test + public void testInfoMinimal() throws IOException, InterruptedException { + Info info = Info.build() + .name("jvm") + .help("JVM info") + .register(origRegistry); + info.info("version", "17"); + + Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + } + + @Test + public void testStateSetComplete() throws IOException { + Collector stateSet = new Collector() { + @Override + public List collect() { + List samples = new ArrayList<>(); + samples.add(new Collector.MetricFamilySamples.Sample("state", Arrays.asList("env", "state"), Arrays.asList("dev", "state1"), 1.0)); + samples.add(new Collector.MetricFamilySamples.Sample("state", Arrays.asList("env", "state"), Arrays.asList("dev", "state2"), 0.0)); + return Collections.singletonList(new Collector.MetricFamilySamples("state", Collector.Type.STATE_SET, "my state", samples)); + } + }; + origRegistry.register(stateSet); + + Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + } + + @Test + public void testUnknownComplete() throws IOException { + Collector unknown = new Collector() { + @Override + public List collect() { + List samples = new ArrayList<>(); + samples.add(new Collector.MetricFamilySamples.Sample("my_unknown_metric_seconds", Arrays.asList("env", "status"), Arrays.asList("dev", "ok"), 3.0)); + samples.add(new Collector.MetricFamilySamples.Sample("my_unknown_metric_seconds", Arrays.asList("env", "status"), Arrays.asList("prod", "error"), 0.0)); + return Collections.singletonList(new Collector.MetricFamilySamples("my_unknown_metric_seconds", "seconds", Type.UNKNOWN, "test metric of type unknown", samples)); + } + }; + origRegistry.register(unknown); + + Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + } + + private String fixBoolean(String s) { + return s.replaceAll(" 1.0", " 1").replaceAll(" 0.0", " 0"); + } + + private String sort(String s) { + String[] lines = s.split("\n"); + Arrays.sort(lines); + return String.join("\n", lines); + } + + private String fixTimestamps(String s) { + // Example of a "_created" timestamp in orig format: 1.694464002939E9 + // Example of a "_created" timestamp in new format: 1694464002.939 + // The following regex translates the orig timestamp to the new timestamp + return s + .replaceAll( "1\\.([0-9]{9})([0-9]{3})E9", "1$1.$2") // Example: 1.694464002939E9 + .replaceAll( "1\\.([0-9]{9})([0-9]{2})E9", "1$1.$20") // Example: 1.69460725747E9 + .replaceAll( "1\\.([0-9]{9})([0-9])E9", "1$1.$200"); // Example: 1.6946072574E9 + } + + private String fixCounts(String s) { + // Example of a "_count" or "_bucket" in orig format: 3.0 + // Example of a "_count" or "_bucket" in new format: 3 + // The following regex translates the orig bucket counts to the new bucket counts + return s.replaceAll("((_count|_bucket)(\\{[^}]*})? [0-9])\\.0", "$1"); + } + + private String origOpenMetrics() throws IOException { + StringWriter out = new StringWriter(); + TextFormat.writeOpenMetrics100(out, origRegistry.metricFamilySamples()); + return out.toString(); + } + + private String newOpenMetrics() throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, newRegistry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } +} diff --git a/prometheus-metrics-simpleclient-bridge/version-rules.xml b/prometheus-metrics-simpleclient-bridge/version-rules.xml new file mode 100644 index 000000000..904c3c3a1 --- /dev/null +++ b/prometheus-metrics-simpleclient-bridge/version-rules.xml @@ -0,0 +1,12 @@ + + + + + + [^9].* + + + + From bdc095b6bd6747bd8c0770cb74b53043ebabc0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 13 Sep 2023 22:04:54 +0200 Subject: [PATCH 206/980] Temporarily add shaded dependencies to prepare for release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index d187341fa..b10386a43 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - + prometheus-metrics-shaded-dependencies examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index d471265e0..8d646cbc4 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.0.0-alpha-4 + ${project.version} From 8371ab745d23927d584e8f209168c72007fb20d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 13 Sep 2023 22:08:12 +0200 Subject: [PATCH 207/980] [maven-release-plugin] prepare release v1.0.0-alpha-5 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 69 files changed, 71 insertions(+), 71 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 375f3fb9b..dd59c4a18 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 2cc537e79..8ac96407b 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index bcebd17d6..c5fe06c46 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 0c189b110..b25b4eaf8 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 95a91eafa..44f2dba72 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index a973a698d..a83437aa7 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 47f055161..0d0778b75 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-exporter-servlet-tomcat diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index d819f300b..003490a4b 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 787db8b08..87a864ef0 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 85f2cd2a1..b8f2c6cf7 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 3760cb018..060eb37e0 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index f078c3026..131c472bf 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 47081063e..a16f1f04a 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 442d34b3b..5eb2f2f1f 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 5f9b5f0a8..390b87d53 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-5 diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 5dc330aea..9c64ea2ec 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index e1f35cf56..d703792a9 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index fed6fbbf9..771bdec6b 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 10ff2ea46..a68c10c83 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 257e32e6e..c0ef4edb9 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index a063bcaa3..9ed25d7d6 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 8831f4713..1537c3a75 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 47717c6d1..702a911f1 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 31d756ce9..3e287d51b 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 integration_tests diff --git a/pom.xml b/pom.xml index b10386a43..fab0e2a8c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-alpha-5 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index b412a15e4..958f95156 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index c8ecd259f..fc3a41e96 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index cd3f62575..c621cc4fd 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index c2aeb4995..5338bb2c1 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 8d646cbc4..e80e521df 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 98a0c0d95..f16a1a695 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 40e3f04d0..edd9ad8c9 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 2a6e6ce41..608e6e61e 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 7e3de38aa..57786977f 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 27512cb0b..1d574eca0 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 152666cca..270968036 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 51071a8c0..aa576d666 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 0dd0a75eb..c4318cf0a 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 2ba88fa0d..4010bf74e 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index ac60addfb..4de4e7545 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index bb42f0681..b915b914b 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index a38ff4806..f19576319 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index df562046d..4fccc37ae 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 652bec540..eb2060715 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 567691996..96cee6e79 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 9fcbe8435..4d6a66b53 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index b07ae1a73..4d9e3a4cf 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 6c78f43d2..844c015bc 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 01f19b15f..e9cda7785 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 3375774d8..0df333cc7 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 833d0a797..ebb6a8c91 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 3d7ecd892..cf7b62d39 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 3954d5e31..af99ce2f2 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index b7653aecf..da4a6a64d 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 12129962d..09941f937 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index d8eb1a2a0..9756cc74b 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index eb434a61d..00348b782 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index e8c71e454..43df3e2ec 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index fcaa1ab97..79dd37394 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 3b8918b3b..04fc4acbe 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index e99a3dc80..c1d2b51e9 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 4667556d6..4799a0311 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index f335bc6b8..c8a88dc13 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 4c0a0e141..b127e2a85 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index ccdc01bd2..a14b4451c 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 7bcdd770c..c566b794a 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 3d7260323..4472075ba 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 0155f9834..44ef894aa 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 7fdb7c10e..f4d5ada9e 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5-SNAPSHOT + 1.0.0-alpha-5 simpleclient_vertx4 From 5c8ff88b5cbbdeb1c7d52b27adb8e86cb6b27a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 13 Sep 2023 22:08:16 +0200 Subject: [PATCH 208/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 69 files changed, 71 insertions(+), 71 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index dd59c4a18..acd2e797f 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 8ac96407b..fc0c0f07c 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index c5fe06c46..54c104aea 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index b25b4eaf8..6cc15447b 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 44f2dba72..10d7fe9f2 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index a83437aa7..574f38666 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 0d0778b75..79b21620f 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 003490a4b..271e7b708 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 87a864ef0..0fd00060b 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index b8f2c6cf7..eef11aa4e 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 060eb37e0..b3366d7dc 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 131c472bf..65710f98d 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index a16f1f04a..60a3560c4 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 5eb2f2f1f..aeffd089f 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 390b87d53..71f222964 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-5 + HEAD diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 9c64ea2ec..e42f5c6ea 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index d703792a9..5d986988d 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 771bdec6b..4616c634c 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index a68c10c83..55a934640 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index c0ef4edb9..ef1fd59dc 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 9ed25d7d6..02eecbc64 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 1537c3a75..3492e71ca 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 702a911f1..d476fb876 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index 3e287d51b..a29bd69ab 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index fab0e2a8c..e5bd4a9c0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-alpha-5 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 958f95156..239f8aa35 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index fc3a41e96..b417e91c1 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index c621cc4fd..d8a2dc15c 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 5338bb2c1..2c4659f94 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index e80e521df..191f0e789 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index f16a1a695..83a717400 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index edd9ad8c9..c8ce4430a 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 608e6e61e..9811b2fc5 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 57786977f..415914805 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 1d574eca0..811bd1bb5 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 270968036..14cf5b2fb 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index aa576d666..c24b0172b 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index c4318cf0a..8f9872b0f 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 4010bf74e..1ab787324 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 4de4e7545..a59c752e6 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index b915b914b..2777b661c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index f19576319..15348e957 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 4fccc37ae..bf4095386 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index eb2060715..f50bf759a 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 96cee6e79..fda594683 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index 4d6a66b53..ddfbf163e 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 4d9e3a4cf..6e91ceb9f 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 844c015bc..6912f198a 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index e9cda7785..5e84e87b3 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 0df333cc7..47a84ad14 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index ebb6a8c91..3dd9bd261 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index cf7b62d39..7e996cc9c 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index af99ce2f2..1240afed4 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index da4a6a64d..4d0eca0f2 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 09941f937..013dd7cec 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 9756cc74b..3e66c9c28 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 00348b782..7058f3de0 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 43df3e2ec..6b95c4dcc 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 79dd37394..13166d868 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 04fc4acbe..6dfc9196d 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index c1d2b51e9..63093354b 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 4799a0311..8a519de26 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index c8a88dc13..6c073cc76 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index b127e2a85..fa683d260 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index a14b4451c..841adb6b9 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index c566b794a..63109ec1b 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 4472075ba..637b46c25 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index 44ef894aa..b8d30a0a6 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index f4d5ada9e..6046d6532 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-5 + 1.0.0-alpha-6-SNAPSHOT simpleclient_vertx4 From a09edde39153f1fe0fb455b72acf21a7bfca212c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 13 Sep 2023 22:58:46 +0200 Subject: [PATCH 209/980] Exclude shaded dependencies from the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index e5bd4a9c0..6c33f85fd 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - prometheus-metrics-shaded-dependencies + examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 191f0e789..170007cd2 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - ${project.version} + 1.0.0-alpha-5 From f1cc00a21dc458d2704c4775e88704df895ca875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 14 Sep 2023 09:35:51 +0200 Subject: [PATCH 210/980] Refactor Builders to use Spring/Lombok conventions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../greeting/GreetingServlet.java | 12 +- .../otel_exemplars/greeting/Main.java | 2 +- .../otel_exemplars/app/HelloWorldServlet.java | 12 +- .../examples/otel_exemplars/app/Main.java | 2 +- .../metrics/examples/httpserver/Main.java | 14 +- .../metrics/examples/opentelemetry/Main.java | 14 +- .../ManualCompleteMetricsTest.java | 12 +- .../tomcat_servlet/HelloWorldServlet.java | 22 +- .../metrics/examples/tomcat_servlet/Main.java | 2 +- .../metrics/examples/simpleclient/Main.java | 6 +- .../exporter/httpserver/HTTPServerSample.java | 34 +- .../jetty/ExporterServletJettySample.java | 30 +- .../tomcat/ExporterServletTomcatSample.java | 30 +- .../metrics/config/ExemplarsProperties.java | 8 +- .../config/ExporterFilterProperties.java | 10 +- .../config/ExporterHttpServerProperties.java | 4 +- .../ExporterOpenTelemetryProperties.java | 25 +- .../metrics/config/ExporterProperties.java | 6 +- .../metrics/config/MetricsProperties.java | 48 +- .../core/datapoints/CounterDataPoint.java | 22 +- .../core/datapoints/StateSetDataPoint.java | 8 +- .../metrics/core/datapoints/TimerApi.java | 24 +- .../core/exemplars/ExemplarSampler.java | 16 +- .../metrics/core/metrics/Counter.java | 32 +- .../core/metrics/CounterWithCallback.java | 26 +- .../metrics/core/metrics/Gauge.java | 16 +- .../core/metrics/GaugeWithCallback.java | 19 +- .../metrics/core/metrics/Histogram.java | 80 +- .../prometheus/metrics/core/metrics/Info.java | 26 +- .../metrics/core/metrics/Metric.java | 2 +- .../core/metrics/MetricWithFixedMetadata.java | 14 +- .../metrics/core/metrics/StateSet.java | 25 +- .../metrics/core/metrics/StatefulMetric.java | 20 +- .../metrics/core/metrics/Summary.java | 68 +- .../core/metrics/SummaryWithCallback.java | 18 +- .../metrics/core/metrics/CounterTest.java | 106 +-- .../metrics/core/metrics/GaugeTest.java | 52 +- .../metrics/core/metrics/HistogramTest.java | 508 ++++++------- .../metrics/core/metrics/InfoTest.java | 59 +- .../metrics/core/metrics/StateSetTest.java | 24 +- .../core/metrics/StatefulMetricTest.java | 8 +- .../common/PrometheusScrapeHandler.java | 4 +- .../exporter/httpserver/HTTPServer.java | 29 +- .../opentelemetry/OpenTelemetryExporter.java | 29 +- .../PrometheusMetricProducer.java | 8 +- .../otelmodel/MetricDataFactory.java | 4 +- .../otelmodel/PrometheusClassicHistogram.java | 2 +- .../otelmodel/PrometheusCounter.java | 3 +- .../otelmodel/PrometheusGauge.java | 3 +- .../otelmodel/PrometheusInfo.java | 2 +- .../otelmodel/PrometheusNativeHistogram.java | 2 +- .../otelmodel/PrometheusStateSet.java | 3 +- .../otelmodel/PrometheusSummary.java | 2 +- .../otelmodel/PrometheusUnknown.java | 2 +- .../OpenMetricsTextFormatWriter.java | 18 +- .../PrometheusProtobufWriter.java | 19 +- .../PrometheusTextFormatWriter.java | 27 +- .../ExpositionFormatsTest.java | 709 +++++++++--------- .../jvm/JvmBufferPoolMetrics.java | 44 +- .../jvm/JvmClassLoadingMetrics.java | 34 +- .../jvm/JvmCompilationMetrics.java | 20 +- .../jvm/JvmGarbageCollectorMetrics.java | 22 +- .../instrumentation/jvm/JvmMemoryMetrics.java | 160 ++-- .../jvm/JvmMemoryPoolAllocationMetrics.java | 18 +- .../instrumentation/jvm/JvmMetrics.java | 24 +- .../jvm/JvmRuntimeInfoMetric.java | 22 +- .../jvm/JvmThreadsMetrics.java | 70 +- .../instrumentation/jvm/ProcessMetrics.java | 70 +- .../jvm/ExampleExporterForManualTesting.java | 6 +- .../jvm/JvmBufferPoolMetricsTest.java | 13 +- .../jvm/JvmClassLoadingMetricsTest.java | 10 +- .../jvm/JvmCompilationMetricsTest.java | 10 +- .../jvm/JvmGarbageCollectorMetricsTest.java | 10 +- .../jvm/JvmMemoryMetricsTest.java | 6 +- .../JvmMemoryPoolAllocationMetricsTest.java | 4 +- .../jvm/JvmRuntimeInfoMetricTest.java | 8 +- .../jvm/JvmThreadsMetricsTest.java | 18 +- .../jvm/ProcessMetricsTest.java | 26 +- .../model/registry/MetricNameFilter.java | 2 +- .../model/registry/MultiCollector.java | 6 +- .../model/registry/PrometheusRegistry.java | 12 +- .../snapshots/ClassicHistogramBuckets.java | 12 +- .../model/snapshots/CounterSnapshot.java | 45 +- .../model/snapshots/DataPointSnapshot.java | 8 +- .../DistributionDataPointSnapshot.java | 8 +- .../metrics/model/snapshots/Exemplar.java | 16 +- .../metrics/model/snapshots/Exemplars.java | 22 +- .../model/snapshots/GaugeSnapshot.java | 33 +- .../model/snapshots/HistogramSnapshot.java | 47 +- .../metrics/model/snapshots/InfoSnapshot.java | 34 +- .../metrics/model/snapshots/Labels.java | 13 +- .../model/snapshots/MetricSnapshot.java | 30 +- .../model/snapshots/MetricSnapshots.java | 13 +- .../snapshots/NativeHistogramBuckets.java | 11 +- .../metrics/model/snapshots/Quantiles.java | 23 +- .../model/snapshots/StateSetSnapshot.java | 40 +- .../model/snapshots/SummarySnapshot.java | 33 +- .../model/snapshots/UnknownSnapshot.java | 31 +- .../registry/PrometheusRegistryTest.java | 20 +- .../ClassicHistogramBucketsTest.java | 62 +- .../model/snapshots/CounterSnapshotTest.java | 82 +- .../metrics/model/snapshots/ExemplarTest.java | 50 +- .../model/snapshots/ExemplarsTest.java | 14 +- .../model/snapshots/GaugeSnapshotTest.java | 82 +- .../snapshots/HistogramSnapshotTest.java | 174 ++--- .../model/snapshots/InfoSnapshotTest.java | 38 +- .../model/snapshots/MetricSnapshotTest.java | 26 +- .../model/snapshots/MetricSnapshotsTest.java | 60 +- .../snapshots/NativeHistogramBucketsTest.java | 24 +- .../model/snapshots/QuantilesTest.java | 26 +- .../model/snapshots/StateSetSnapshotTest.java | 102 +-- .../model/snapshots/SummarySnapshotTest.java | 84 +-- .../model/snapshots/UnknownSnapshotTest.java | 56 +- .../pom.xml | 11 + .../bridge/SimpleclientCollector.java | 211 +++--- .../bridge/SimpleclientCollectorTest.java | 5 +- 116 files changed, 2271 insertions(+), 2222 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java index a1046e2a2..7a0870bf3 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -21,11 +21,11 @@ public class GreetingServlet extends HttpServlet { private final Histogram histogram; public GreetingServlet() { - histogram = Histogram.newBuilder() - .withName("request_duration_seconds") - .withHelp("request duration in seconds") - .withUnit(Unit.SECONDS) - .withLabelNames("http_status") + histogram = Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .labelNames("http_status") .register(); histogram.initLabelValues("200"); } @@ -41,7 +41,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } } } diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java index 691ea6a1d..731e05cf9 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java @@ -15,7 +15,7 @@ public class Main { public static void main(String[] args) throws LifecycleException { - JvmMetrics.newBuilder().register(); + JvmMetrics.builder().register(); Tomcat tomcat = new Tomcat(); tomcat.setPort(8081); diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java index cabedbce5..11c048d68 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -28,11 +28,11 @@ public class HelloWorldServlet extends HttpServlet { private final Histogram histogram; public HelloWorldServlet() { - histogram = Histogram.newBuilder() - .withName("request_duration_seconds") - .withHelp("request duration in seconds") - .withUnit(Unit.SECONDS) - .withLabelNames("http_status") + histogram = Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .labelNames("http_status") .register(); histogram.initLabelValues("200"); } @@ -49,7 +49,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se } catch (Exception e) { throw new ServletException(e); } finally { - histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } } diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java index 4a7bf0fac..5fb5114bb 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java @@ -15,7 +15,7 @@ public class Main { public static void main(String[] args) throws LifecycleException { - JvmMetrics.newBuilder().register(); + JvmMetrics.builder().register(); Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java index dc0316b06..f01874ef8 100644 --- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java +++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java @@ -14,7 +14,7 @@ public class Main { public static void main(String[] args) throws IOException, InterruptedException { - JvmMetrics.newBuilder().register(); + JvmMetrics.builder().register(); // Note: uptime_seconds_total is not a great example: // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds @@ -22,14 +22,14 @@ public static void main(String[] args) throws IOException, InterruptedException // run the Prometheus query // time() - process_start_time_seconds // rather than creating a custom uptime metric. - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) + Counter counter = Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) .register(); - HTTPServer server = HTTPServer.newBuilder() - .withPort(9400) + HTTPServer server = HTTPServer.builder() + .port(9400) .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java index 7d257e6a7..4d9b4a738 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java @@ -15,7 +15,7 @@ public static void main(String[] args) throws Exception { // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions. // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry // naming conventions rather than the Prometheus names. - JvmMetrics.newBuilder().register(); + JvmMetrics.builder().register(); // Note: uptime_seconds_total is not a great example: // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds @@ -23,14 +23,14 @@ public static void main(String[] args) throws Exception { // run the Prometheus query // time() - process_start_time_seconds // rather than creating a custom uptime metric. - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) + Counter counter = Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) .register(); - OpenTelemetryExporter.newBuilder() - .withIntervalSeconds(5) + OpenTelemetryExporter.builder() + .intervalSeconds(5) .buildAndStart(); while (true) { diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java index c0b41e8c5..72e8dd107 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java @@ -42,8 +42,8 @@ public static void main(String[] args) throws Exception { .withLabelNames("location") .register(); - gauge.withLabelValues("inside").set(23.4); - gauge.withLabelValues("outside").set(9.3); + gauge.labelValues("inside").set(23.4); + gauge.labelValues("outside").set(9.3); // By default, the histogram will be exported as an exponential histogram in OpenTelemetry. Histogram histogram = Histogram.newBuilder() @@ -55,7 +55,7 @@ public static void main(String[] args) throws Exception { Random random = new Random(0); for (int i = 0; i < 1000; i++) { - histogram.withLabelValues("200").observe(random.nextGaussian()); + histogram.labelValues("200").observe(random.nextGaussian()); } // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry @@ -69,7 +69,7 @@ public static void main(String[] args) throws Exception { .register(); for (int i = 0; i < 15; i++) { - classicHistogram.withLabelValues("200").observe(random.nextInt(3000)); + classicHistogram.labelValues("200").observe(random.nextInt(3000)); } Summary summary = Summary.newBuilder() @@ -116,8 +116,8 @@ public static void main(String[] args) throws Exception { .withStates("feature1", "feature2") .register(); - stateSet.withLabelValues("dev").setFalse("feature1"); - stateSet.withLabelValues("dev").setTrue("feature2"); + stateSet.labelValues("dev").setFalse("feature1"); + stateSet.labelValues("dev").setTrue("feature2"); PrometheusRegistry.defaultRegistry.register(() -> UnknownSnapshot.newBuilder() .withName("my_unknown_metric") diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index 42f123f16..d3d8f37e5 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -21,17 +21,17 @@ public class HelloWorldServlet extends HttpServlet { // Note: The requests_total counter is not a great example, because the // request_duration_seconds histogram below also has a count with the number of requests. - private final Counter counter = Counter.newBuilder() - .withName("requests_total") - .withHelp("total number of requests") - .withLabelNames("http_status") + private final Counter counter = Counter.builder() + .name("requests_total") + .help("total number of requests") + .labelNames("http_status") .register(); - private final Histogram histogram = Histogram.newBuilder() - .withName("request_duration_seconds") - .withHelp("request duration in seconds") - .withUnit(Unit.SECONDS) - .withLabelNames("http_status") + private final Histogram histogram = Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .labelNames("http_status") .register(); public HelloWorldServlet() { @@ -50,8 +50,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - counter.withLabelValues("200").inc(); - histogram.withLabelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); + counter.labelValues("200").inc(); + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } } } diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java index 5525ed48e..4ce6353db 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java @@ -18,7 +18,7 @@ public class Main { public static void main(String[] args) throws LifecycleException, IOException { - JvmMetrics.newBuilder().register(); + JvmMetrics.builder().register(); Tomcat tomcat = new Tomcat(); Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-"); diff --git a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java index 0a72c960b..cb0488d57 100644 --- a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java +++ b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java @@ -16,7 +16,7 @@ public static void main(String[] args) throws IOException, InterruptedException // The following call will register all metrics from the old CollectorRegistry.defaultRegistry // with the new PrometheusRegistry.defaultRegistry. - SimpleclientCollector.newBuilder().register(); + SimpleclientCollector.builder().register(); // Register a counter with the old CollectorRegistry. // It doesn't matter whether the counter is registered before or after bridging with PrometheusRegistry. @@ -30,8 +30,8 @@ public static void main(String[] args) throws IOException, InterruptedException // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric. - HTTPServer server = HTTPServer.newBuilder() - .withPort(9400) + HTTPServer server = HTTPServer.builder() + .port(9400) .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index 9cd27a42c..65cb2c27b 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -29,28 +29,28 @@ public static void main(String[] args) throws IOException, InterruptedException int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) + Counter counter = Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) .register(); counter.inc(17); - Info info = Info.newBuilder() - .withName("integration_test_info") - .withHelp("Info metric on this integration test") - .withLabelNames("test_name") + Info info = Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") .register(); info.addLabelValues("exporter-httpserver-sample"); - Gauge gauge = Gauge.newBuilder() - .withName("temperature_celsius") - .withHelp("Temperature in Celsius") - .withUnit(Unit.CELSIUS) - .withLabelNames("location") + Gauge gauge = Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") .register(); - gauge.withLabelValues("inside").set(23.0); - gauge.withLabelValues("outside").set(27.0); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { Collector failingCollector = new Collector() { @@ -69,8 +69,8 @@ public MetricSnapshot collect() { PrometheusRegistry.defaultRegistry.register(failingCollector); } - HTTPServer server = HTTPServer.newBuilder() - .withPort(port) + HTTPServer server = HTTPServer.builder() + .port(port) .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java index b46c112af..19bbddac2 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java @@ -33,28 +33,28 @@ public static void main(String[] args) throws Exception { int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) + Counter counter = Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) .register(); counter.inc(17); - Info info = Info.newBuilder() - .withName("integration_test_info") - .withHelp("Info metric on this integration test") - .withLabelNames("test_name") + Info info = Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") .register(); info.addLabelValues("exporter-servlet-jetty-sample"); - Gauge gauge = Gauge.newBuilder() - .withName("temperature_celsius") - .withHelp("Temperature in Celsius") - .withUnit(Unit.CELSIUS) - .withLabelNames("location") + Gauge gauge = Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") .register(); - gauge.withLabelValues("inside").set(23.0); - gauge.withLabelValues("outside").set(27.0); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { Collector failingCollector = new Collector() { diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java index 9a44b0153..7e2e31e04 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java @@ -37,28 +37,28 @@ public static void main(String[] args) throws LifecycleException, IOException { int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) + Counter counter = Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) .register(); counter.inc(17); - Info info = Info.newBuilder() - .withName("integration_test_info") - .withHelp("Info metric on this integration test") - .withLabelNames("test_name") + Info info = Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") .register(); info.addLabelValues("exporter-servlet-tomcat-sample"); - Gauge gauge = Gauge.newBuilder() - .withName("temperature_celsius") - .withHelp("Temperature in Celsius") - .withUnit(Unit.CELSIUS) - .withLabelNames("location") + Gauge gauge = Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") .register(); - gauge.withLabelValues("inside").set(23.0); - gauge.withLabelValues("outside").set(27.0); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { Collector failingCollector = new Collector() { diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java index 7d996f6a5..258e7f45d 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java @@ -79,7 +79,7 @@ static ExemplarsProperties load(String prefix, Map properties) t ); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -92,17 +92,17 @@ public static class Builder { private Builder() { } - public Builder withMinRetentionPeriodSeconds(int minRetentionPeriodSeconds) { + public Builder minRetentionPeriodSeconds(int minRetentionPeriodSeconds) { this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; return this; } - public Builder withMaxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) { + public Builder maxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) { this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; return this; } - public Builder withSampleIntervalMilliseconds(int sampleIntervalMilliseconds) { + public Builder sampleIntervalMilliseconds(int sampleIntervalMilliseconds) { this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; return this; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java index 250985329..1a4e3056d 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -64,7 +64,7 @@ static ExporterFilterProperties load(String prefix, Map properti return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -81,7 +81,7 @@ private Builder() { /** * Only allowed metric names will be exposed. */ - public Builder withAllowedNames(String... allowedNames) { + public Builder allowedNames(String... allowedNames) { this.allowedNames = Arrays.asList(allowedNames); return this; } @@ -89,7 +89,7 @@ public Builder withAllowedNames(String... allowedNames) { /** * Excluded metric names will not be exposed. */ - public Builder withExcludedNames(String... excludedNames) { + public Builder excludedNames(String... excludedNames) { this.excludedNames = Arrays.asList(excludedNames); return this; } @@ -97,7 +97,7 @@ public Builder withExcludedNames(String... excludedNames) { /** * Only metrics with a name starting with an allowed prefix will be exposed. */ - public Builder withAllowedPrefixes(String... allowedPrefixes) { + public Builder allowedPrefixes(String... allowedPrefixes) { this.allowedPrefixes = Arrays.asList(allowedPrefixes); return this; } @@ -105,7 +105,7 @@ public Builder withAllowedPrefixes(String... allowedPrefixes) { /** * Metrics with a name starting with an excluded prefix will not be exposed. */ - public Builder withExcludedPrefixes(String... excludedPrefixes) { + public Builder excludedPrefixes(String... excludedPrefixes) { this.excludedPrefixes = Arrays.asList(excludedPrefixes); return this; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java index 6d06746f7..fd7d9aa4b 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java @@ -30,7 +30,7 @@ static ExporterHttpServerProperties load(String prefix, Map prop return new ExporterHttpServerProperties(port); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -40,7 +40,7 @@ public static class Builder { private Builder() {} - public Builder withPort(int port) { + public Builder port(int port) { this.port = port; return this; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java index 66ed3633b..77bcc21cb 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java @@ -105,7 +105,7 @@ static ExporterOpenTelemetryProperties load(String prefix, Map p return new ExporterOpenTelemetryProperties(protocol, endpoint, headers, intervalSeconds, timeoutSeconds, serviceName, serviceNamespace, serviceInstanceId, serviceVersion, resourceAttributes); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -124,7 +124,7 @@ public static class Builder { private Builder() {} - public Builder withProtocol(String protocol) { + public Builder protocol(String protocol) { if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { throw new IllegalArgumentException(protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); } @@ -132,17 +132,20 @@ public Builder withProtocol(String protocol) { return this; } - public Builder withEndpoint(String endpoint) { + public Builder endpoint(String endpoint) { this.endpoint = endpoint; return this; } - public Builder addHeader(String name, String value) { + /** + * Add a request header. Call multiple times to add multiple headers. + */ + public Builder header(String name, String value) { this.headers.put(name, value); return this; } - public Builder withIntervalSeconds(int intervalSeconds) { + public Builder intervalSeconds(int intervalSeconds) { if (intervalSeconds <= 0) { throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); } @@ -150,7 +153,7 @@ public Builder withIntervalSeconds(int intervalSeconds) { return this; } - public Builder withTimeoutSeconds(int timeoutSeconds) { + public Builder timeoutSeconds(int timeoutSeconds) { if (timeoutSeconds <= 0) { throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); } @@ -158,27 +161,27 @@ public Builder withTimeoutSeconds(int timeoutSeconds) { return this; } - public Builder withServiceName(String serviceName) { + public Builder serviceName(String serviceName) { this.serviceName = serviceName; return this; } - public Builder withServiceNamespace(String serviceNamespace) { + public Builder serviceNamespace(String serviceNamespace) { this.serviceNamespace = serviceNamespace; return this; } - public Builder withServiceInstanceId(String serviceInstanceId) { + public Builder serviceInstanceId(String serviceInstanceId) { this.serviceInstanceId = serviceInstanceId; return this; } - public Builder withServiceVersion(String serviceVersion) { + public Builder serviceVersion(String serviceVersion) { this.serviceVersion = serviceVersion; return this; } - public Builder addResourceAttribute(String name, String value) { + public Builder resourceAttribute(String name, String value) { this.resourceAttributes.put(name, value); return this; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java index 016d399f0..e715a7a2c 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -43,7 +43,7 @@ static ExporterProperties load(String prefix, Map properties) th return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -58,7 +58,7 @@ private Builder() { /** * See {@link #getIncludeCreatedTimestamps()} */ - public Builder withIncludeCreatedTimestamps(boolean includeCreatedTimestamps) { + public Builder includeCreatedTimestamps(boolean includeCreatedTimestamps) { this.includeCreatedTimestamps = includeCreatedTimestamps; return this; } @@ -66,7 +66,7 @@ public Builder withIncludeCreatedTimestamps(boolean includeCreatedTimestamps) { /** * See {@link #getExemplarsOnAllMetricTypes()}. */ - public Builder withExemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { + public Builder exemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; return this; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java index 10966b3c8..4574d0198 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java @@ -187,56 +187,56 @@ public Boolean getHistogramClassicOnly() { } /** - * See {@code Histogram.Builder.withClassicBuckets()} + * See {@code Histogram.Builder.classicBuckets()} */ public List getHistogramClassicUpperBounds() { return histogramClassicUpperBounds; } /** - * See {@code Histogram.Builder.withNativeInitialSchema()} + * See {@code Histogram.Builder.nativeInitialSchema()} */ public Integer getHistogramNativeInitialSchema() { return histogramNativeInitialSchema; } /** - * See {@code Histogram.Builder.withNativeMinZeroThreshold()} + * See {@code Histogram.Builder.nativeMinZeroThreshold()} */ public Double getHistogramNativeMinZeroThreshold() { return histogramNativeMinZeroThreshold; } /** - * See {@code Histogram.Builder.withNativeMaxZeroThreshold()} + * See {@code Histogram.Builder.nativeMaxZeroThreshold()} */ public Double getHistogramNativeMaxZeroThreshold() { return histogramNativeMaxZeroThreshold; } /** - * See {@code Histogram.Builder.withNativeMaxNumberOfBuckets()} + * See {@code Histogram.Builder.nativeMaxNumberOfBuckets()} */ public Integer getHistogramNativeMaxNumberOfBuckets() { return histogramNativeMaxNumberOfBuckets; } /** - * See {@code Histogram.Builder.withNativeResetDuration()} + * See {@code Histogram.Builder.nativeResetDuration()} */ public Long getHistogramNativeResetDurationSeconds() { return histogramNativeResetDurationSeconds; } /** - * See {@code Summary.Builder.withQuantile()} + * See {@code Summary.Builder.quantile()} */ public List getSummaryQuantiles() { return summaryQuantiles; } /** - * See {@code Summary.Builder.withQuantile()} + * See {@code Summary.Builder.quantile()} *

    * Returns {@code null} only if {@link #getSummaryQuantiles()} is also {@code null}. * Returns an empty list if {@link #getSummaryQuantiles()} are specified without specifying errors. @@ -252,14 +252,14 @@ public List getSummaryQuantileErrors() { } /** - * See {@code Summary.Builder.withMaxAgeSeconds()} + * See {@code Summary.Builder.maxAgeSeconds()} */ public Long getSummaryMaxAgeSeconds() { return summaryMaxAgeSeconds; } /** - * See {@code Summary.Builder.withNumberOfAgeBuckets()} + * See {@code Summary.Builder.numberOfAgeBuckets()} */ public Integer getSummaryNumberOfAgeBuckets() { return summaryNumberOfAgeBuckets; @@ -287,7 +287,7 @@ static MetricsProperties load(String prefix, Map properties) thr prefix); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -328,7 +328,7 @@ public MetricsProperties build() { /** * See {@link MetricsProperties#getExemplarsEnabled()} */ - public Builder withExemplarsEnabled(Boolean exemplarsEnabled) { + public Builder exemplarsEnabled(Boolean exemplarsEnabled) { this.exemplarsEnabled = exemplarsEnabled; return this; } @@ -336,7 +336,7 @@ public Builder withExemplarsEnabled(Boolean exemplarsEnabled) { /** * See {@link MetricsProperties#getHistogramNativeOnly()} */ - public Builder withHistogramNativeOnly(Boolean histogramNativeOnly) { + public Builder histogramNativeOnly(Boolean histogramNativeOnly) { this.histogramNativeOnly = histogramNativeOnly; return this; } @@ -344,7 +344,7 @@ public Builder withHistogramNativeOnly(Boolean histogramNativeOnly) { /** * See {@link MetricsProperties#getHistogramClassicOnly()} */ - public Builder withHistogramClassicOnly(Boolean histogramClassicOnly) { + public Builder histogramClassicOnly(Boolean histogramClassicOnly) { this.histogramClassicOnly = histogramClassicOnly; return this; } @@ -352,7 +352,7 @@ public Builder withHistogramClassicOnly(Boolean histogramClassicOnly) { /** * See {@link MetricsProperties#getHistogramClassicUpperBounds()} */ - public Builder withHistogramClassicUpperBounds(double... histogramClassicUpperBounds) { + public Builder histogramClassicUpperBounds(double... histogramClassicUpperBounds) { this.histogramClassicUpperBounds = Util.toList(histogramClassicUpperBounds); return this; } @@ -360,7 +360,7 @@ public Builder withHistogramClassicUpperBounds(double... histogramClassicUpperBo /** * See {@link MetricsProperties#getHistogramNativeInitialSchema()} */ - public Builder withHistogramNativeInitialSchema(Integer histogramNativeInitialSchema) { + public Builder histogramNativeInitialSchema(Integer histogramNativeInitialSchema) { this.histogramNativeInitialSchema = histogramNativeInitialSchema; return this; } @@ -368,7 +368,7 @@ public Builder withHistogramNativeInitialSchema(Integer histogramNativeInitialSc /** * See {@link MetricsProperties#getHistogramNativeMinZeroThreshold()} */ - public Builder withHistogramNativeMinZeroThreshold(Double histogramNativeMinZeroThreshold) { + public Builder histogramNativeMinZeroThreshold(Double histogramNativeMinZeroThreshold) { this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; return this; } @@ -376,7 +376,7 @@ public Builder withHistogramNativeMinZeroThreshold(Double histogramNativeMinZero /** * See {@link MetricsProperties#getHistogramNativeMaxZeroThreshold()} */ - public Builder withHistogramNativeMaxZeroThreshold(Double histogramNativeMaxZeroThreshold) { + public Builder histogramNativeMaxZeroThreshold(Double histogramNativeMaxZeroThreshold) { this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; return this; } @@ -384,7 +384,7 @@ public Builder withHistogramNativeMaxZeroThreshold(Double histogramNativeMaxZero /** * See {@link MetricsProperties#getHistogramNativeMaxNumberOfBuckets()} */ - public Builder withHistogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxNumberOfBuckets) { + public Builder histogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxNumberOfBuckets) { this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; return this; } @@ -392,7 +392,7 @@ public Builder withHistogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxN /** * See {@link MetricsProperties#getHistogramNativeResetDurationSeconds()} */ - public Builder withHistogramNativeResetDurationSeconds(Long histogramNativeResetDurationSeconds) { + public Builder histogramNativeResetDurationSeconds(Long histogramNativeResetDurationSeconds) { this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; return this; } @@ -400,7 +400,7 @@ public Builder withHistogramNativeResetDurationSeconds(Long histogramNativeReset /** * See {@link MetricsProperties#getSummaryQuantiles()} */ - public Builder withSummaryQuantiles(double... summaryQuantiles) { + public Builder summaryQuantiles(double... summaryQuantiles) { this.summaryQuantiles = Util.toList(summaryQuantiles); return this; } @@ -408,7 +408,7 @@ public Builder withSummaryQuantiles(double... summaryQuantiles) { /** * See {@link MetricsProperties#getSummaryQuantileErrors()} */ - public Builder withSummaryQuantileErrors(double... summaryQuantileErrors) { + public Builder summaryQuantileErrors(double... summaryQuantileErrors) { this.summaryQuantileErrors = Util.toList(summaryQuantileErrors); return this; } @@ -416,7 +416,7 @@ public Builder withSummaryQuantileErrors(double... summaryQuantileErrors) { /** * See {@link MetricsProperties#getSummaryMaxAgeSeconds()} */ - public Builder withSummaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { + public Builder summaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; return this; } @@ -424,7 +424,7 @@ public Builder withSummaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { /** * See {@link MetricsProperties#getSummaryNumberOfAgeBuckets()} */ - public Builder withSummaryNumberOfAgeBuckets(Integer summaryNumberOfAgeBuckets) { + public Builder summaryNumberOfAgeBuckets(Integer summaryNumberOfAgeBuckets) { this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; return this; } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java index c2f72c30e..49cb95008 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java @@ -7,23 +7,23 @@ *

    * Example usage: *

    {@code
    - * Counter counter = Counter.newBuilder()
    - *     .withName("tasks_total")
    - *     .withLabelNames("status")
    + * Counter counter = Counter.builder()
    + *     .name("tasks_total")
    + *     .labelNames("status")
      *     .register();
    - * CounterDataPoint newTasks = counter.withLabelValues("new");
    - * CounterDataPoint pendingTasks = counter.withLabelValues("pending");
    - * CounterDataPoint completedTasks = counter.withLabelValues("completed");
    + * CounterDataPoint newTasks = counter.labelValues("new");
    + * CounterDataPoint pendingTasks = counter.labelValues("pending");
    + * CounterDataPoint completedTasks = counter.labelValues("completed");
      * }
    *

    * Using {@code DataPoint} directly improves performance. If you increment a counter like this: *

    {@code
    - * counter.withLabelValues("pending").inc();
    + * counter.labelValues("pending").inc();
      * }
    * the label value {@code "pending"} needs to be looked up every single time. * Using the {@code CounterDataPoint} like this: *
    {@code
    - * CounterDataPoint pendingTasks = counter.withLabelValues("pending");
    + * CounterDataPoint pendingTasks = counter.labelValues("pending");
      * pendingTasks.inc();
      * }
    * allows you to look up the label value only once, and then use the {@code CounterDataPoint} directly. @@ -31,13 +31,13 @@ *

    * If you have a counter without labels like this: *

    {@code
    - * Counter counterWithoutLabels = Counter.newBuilder()
    - *     .withName("events_total")
    + * Counter counterWithoutLabels = Counter.builder()
    + *     .name("events_total")
      *     .register();
      * }
    * You can use it as a {@code CounterDataPoint} directly. So the following: *
    {@code
    - * CounterDataPoint counterData = counterWithoutLabels.withLabels();
    + * CounterDataPoint counterData = counterWithoutLabels.labelValues(); // empty label values
      * }
    * is equivalent to *
    {@code
    diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java
    index 73b7dfdb3..8ad6ecf37 100644
    --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java
    +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java
    @@ -8,24 +8,24 @@
     public interface StateSetDataPoint extends DataPoint {
     
         /**
    -     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(String...)}.
    +     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}.
          */
         void setTrue(String state);
     
         /**
    -     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(String...)}.
    +     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}.
          */
         void setFalse(String state);
     
         /**
    -     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(Class>)}.
    +     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class>)}.
          */
         default void setTrue(Enum state) {
             setTrue(state.toString());
         }
     
         /**
    -     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#withStates(Class>)}.
    +     * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class>)}.
          */
         default void setFalse(Enum state) {
             setFalse(state.toString());
    diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java
    index a38c8053b..27245bbcb 100644
    --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java
    +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java
    @@ -14,14 +14,14 @@ public interface TimerApi {
         /**
          * Start a {@code Timer}. Example:
          * 
    {@code
    -     * Histogram histogram = Histogram.newBuilder()
    -     *         .withName("http_request_duration_seconds")
    -     *         .withHelp("HTTP request service time in seconds")
    -     *         .withUnit(SECONDS)
    -     *         .withLabelNames("method", "path")
    +     * Histogram histogram = Histogram.builder()
    +     *         .name("http_request_duration_seconds")
    +     *         .help("HTTP request service time in seconds")
    +     *         .unit(SECONDS)
    +     *         .labelNames("method", "path")
          *         .register();
          *
    -     * try (Timer timer = histogram.withLabelValues("GET", "/").startTimer()) {
    +     * try (Timer timer = histogram.labelValues("GET", "/").startTimer()) {
          *     // duration of this code block will be observed.
          * }
          * }
    @@ -33,14 +33,14 @@ public interface TimerApi { /** * Observe the duration of the {@code func} call. Example: *
    {@code
    -     * Histogram histogram = Histogram.newBuilder()
    -     *         .withName("request_duration_seconds")
    -     *         .withHelp("HTTP request service time in seconds")
    -     *         .withUnit(SECONDS)
    -     *         .withLabelNames("method", "path")
    +     * Histogram histogram = Histogram.builder()
    +     *         .name("request_duration_seconds")
    +     *         .help("HTTP request service time in seconds")
    +     *         .unit(SECONDS)
    +     *         .labelNames("method", "path")
          *         .register();
          *
    -     * histogram2.withLabelValues("GET", "/").time(() -> {
    +     * histogram2.labelValues("GET", "/").time(() -> {
          *     // duration of this code block will be observed.
          * });
          * }
    diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java index 0c8275356..9472b237f 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -284,10 +284,10 @@ private long updateCustomExemplar(int index, double value, Labels labels, long n if (!labels.contains(Exemplar.TRACE_ID) && !labels.contains(Exemplar.SPAN_ID)) { labels = labels.merge(doSampleExemplar()); } - customExemplars[index] = Exemplar.newBuilder() - .withValue(value) - .withLabels(labels) - .withTimestampMillis(now) + customExemplars[index] = Exemplar.builder() + .value(value) + .labels(labels) + .timestampMillis(now) .build(); return now; } @@ -295,10 +295,10 @@ private long updateCustomExemplar(int index, double value, Labels labels, long n private long updateExemplar(int index, double value, long now) { Labels traceLabels = doSampleExemplar(); if (!traceLabels.isEmpty()) { - exemplars[index] = Exemplar.newBuilder() - .withValue(value) - .withLabels(traceLabels) - .withTimestampMillis(now) + exemplars[index] = Exemplar.builder() + .value(value) + .labels(traceLabels) + .timestampMillis(now) .build(); return now; } else { diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index 57ed0c05b..4c764cf2a 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -5,11 +5,9 @@ import io.prometheus.metrics.core.datapoints.CounterDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSampler; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; -import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.model.snapshots.PrometheusNaming; import java.util.ArrayList; import java.util.Collections; @@ -17,20 +15,18 @@ import java.util.concurrent.atomic.DoubleAdder; import java.util.concurrent.atomic.LongAdder; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; - /** * Counter metric. *

    * Example usage: *

    {@code
    - * Counter requestCount = Counter.newBuilder()
    - *     .withName("requests_total")
    - *     .withHelp("Total number of requests")
    - *     .withLabelNames("path", "status")
    + * Counter requestCount = Counter.builder()
    + *     .name("requests_total")
    + *     .help("Total number of requests")
    + *     .labelNames("path", "status")
      *     .register();
    - * requestCount.withLabelValues("/hello-world", "200").inc();
    - * requestCount.withLabelValues("/hello-world", "500").inc();
    + * requestCount.labelValues("/hello-world", "200").inc();
    + * requestCount.labelValues("/hello-world", "500").inc();
      * }
    */ public class Counter extends StatefulMetric implements CounterDataPoint { @@ -207,11 +203,11 @@ private CounterSnapshot.CounterDataPointSnapshot collect(Labels labels) { } } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -224,11 +220,11 @@ private Builder(PrometheusProperties properties) { /** * The {@code _total} suffix will automatically be appended if it's missing. *
    {@code
    -         * Counter c1 = Counter.newBuilder()
    -         *     .withName("events_total")
    +         * Counter c1 = Counter.builder()
    +         *     .name("events_total")
              *     .build();
    -         * Counter c2 = Counter.newBuilder()
    -         *     .withName("events")
    +         * Counter c2 = Counter.builder()
    +         *     .name("events")
              *     .build();
              * }
    * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. @@ -238,8 +234,8 @@ private Builder(PrometheusProperties properties) { * is {@code false}. */ @Override - public Builder withName(String name) { - return super.withName(stripTotalSuffix(name)); + public Builder name(String name) { + return super.name(stripTotalSuffix(name)); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java index b4d7bc761..76ce68f23 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java @@ -13,10 +13,10 @@ *
    {@code
      * ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
      *
    - * CounterWithCallback.newBuilder()
    - *         .withName("classes_loaded_total")
    - *         .withHelp("The total number of classes that have been loaded since the JVM has started execution")
    - *         .withCallback(callback -> callback.call(classLoadingMXBean.getLoadedClassCount()))
    + * CounterWithCallback.builder()
    + *         .name("classes_loaded_total")
    + *         .help("The total number of classes that have been loaded since the JVM has started execution")
    + *         .callback(callback -> callback.call(classLoadingMXBean.getLoadedClassCount()))
      *         .register();
      * }
    */ @@ -46,11 +46,11 @@ public CounterSnapshot collect() { return new CounterSnapshot(getMetadata(), dataPoints); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties properties) { + public static Builder builder(PrometheusProperties properties) { return new Builder(properties); } @@ -58,7 +58,7 @@ public static class Builder extends CallbackMetric.Builder callback; - public Builder withCallback(Consumer callback) { + public Builder callback(Consumer callback) { this.callback = callback; return self(); } @@ -70,11 +70,11 @@ private Builder(PrometheusProperties properties) { /** * The {@code _total} suffix will automatically be appended if it's missing. *
    {@code
    -         * CounterWithCallback c1 = CounterWithCallback.newBuilder()
    -         *     .withName("events_total")
    +         * CounterWithCallback c1 = CounterWithCallback.builder()
    +         *     .name("events_total")
              *     .build();
    -         * CounterWithCallback c2 = CounterWithCallback.newBuilder()
    -         *     .withName("events")
    +         * CounterWithCallback c2 = CounterWithCallback.builder()
    +         *     .name("events")
              *     .build();
              * }
    * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. @@ -84,8 +84,8 @@ private Builder(PrometheusProperties properties) { * is {@code false}. */ @Override - public Builder withName(String name) { - return super.withName(Counter.stripTotalSuffix(name)); + public Builder name(String name) { + return super.name(Counter.stripTotalSuffix(name)); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java index 1b0edfeb1..466c31276 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java @@ -19,19 +19,19 @@ *

    * Example usage: *

    {@code
    - * Gauge currentActiveUsers = Gauge.newBuilder()
    - *     .withName("current_active_users")
    - *     .withHelp("Number of users that are currently active")
    - *     .withLabelNames("region")
    + * Gauge currentActiveUsers = Gauge.builder()
    + *     .name("current_active_users")
    + *     .help("Number of users that are currently active")
    + *     .labelNames("region")
      *     .register();
      *
      * public void login(String region) {
    - *     currentActiveUsers.withLabelValues(region).inc();
    + *     currentActiveUsers.labelValues(region).inc();
      *     // perform login
      * }
      *
      * public void logout(String region) {
    - *     currentActiveUsers.withLabelValues(region).dec();
    + *     currentActiveUsers.labelValues(region).dec();
      *     // perform logout
      * }
      * }
    @@ -186,11 +186,11 @@ private GaugeSnapshot.GaugeDataPointSnapshot collect(Labels labels) { } } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java index 7a1424d95..a88a9acca 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java @@ -1,7 +1,6 @@ package io.prometheus.metrics.core.metrics; import io.prometheus.metrics.config.PrometheusProperties; -import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import java.util.ArrayList; @@ -14,12 +13,12 @@ *
    {@code
      * MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
      *
    - * GaugeWithCallback.newBuilder()
    - *     .withName("jvm_memory_bytes_used")
    - *     .withHelp("Used bytes of a given JVM memory area.")
    - *     .withUnit(Unit.BYTES)
    - *     .withLabelNames("area")
    - *     .withCallback(callback -> {
    + * GaugeWithCallback.builder()
    + *     .name("jvm_memory_bytes_used")
    + *     .help("Used bytes of a given JVM memory area.")
    + *     .unit(Unit.BYTES)
    + *     .labelNames("area")
    + *     .callback(callback -> {
      *         callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap");
      *         callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap");
      *     })
    @@ -52,11 +51,11 @@ public GaugeSnapshot collect() {
             return new GaugeSnapshot(getMetadata(), dataPoints);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties properties) {
    +    public static Builder builder(PrometheusProperties properties) {
             return new Builder(properties);
         }
     
    @@ -64,7 +63,7 @@ public static class Builder extends CallbackMetric.Builder callback;
     
    -        public Builder withCallback(Consumer callback) {
    +        public Builder callback(Consumer callback) {
                 this.callback = callback;
                 return self();
             }
    diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
    index cfe3f2944..d88e1412d 100644
    --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
    +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
    @@ -29,16 +29,16 @@
     /**
      * Histogram metric. Example usage:
      * 
    {@code
    - * Histogram histogram = Histogram.newBuilder()
    - *         .withName("http_request_duration_seconds")
    - *         .withHelp("HTTP request service time in seconds")
    - *         .withUnit(SECONDS)
    - *         .withLabelNames("method", "path", "status_code")
    + * Histogram histogram = Histogram.builder()
    + *         .name("http_request_duration_seconds")
    + *         .help("HTTP request service time in seconds")
    + *         .unit(SECONDS)
    + *         .labelNames("method", "path", "status_code")
      *         .register();
      *
      * long start = System.nanoTime();
      * // do something
    - * histogram.withLabelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
    + * histogram.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
      * }
    * Prometheus supports two internal representations of histograms: *
      @@ -636,11 +636,11 @@ protected DataPoint newDataPoint() { } } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -669,16 +669,16 @@ public Histogram build() { @Override protected MetricsProperties toProperties() { - return MetricsProperties.newBuilder() - .withExemplarsEnabled(exemplarsEnabled) - .withHistogramNativeOnly(nativeOnly) - .withHistogramClassicOnly(classicOnly) - .withHistogramClassicUpperBounds(classicUpperBounds) - .withHistogramNativeInitialSchema(nativeInitialSchema) - .withHistogramNativeMinZeroThreshold(nativeMinZeroThreshold) - .withHistogramNativeMaxZeroThreshold(nativeMaxZeroThreshold) - .withHistogramNativeMaxNumberOfBuckets(nativeMaxNumberOfBuckets) - .withHistogramNativeResetDurationSeconds(nativeResetDurationSeconds) + return MetricsProperties.builder() + .exemplarsEnabled(exemplarsEnabled) + .histogramNativeOnly(nativeOnly) + .histogramClassicOnly(classicOnly) + .histogramClassicUpperBounds(classicUpperBounds) + .histogramNativeInitialSchema(nativeInitialSchema) + .histogramNativeMinZeroThreshold(nativeMinZeroThreshold) + .histogramNativeMaxZeroThreshold(nativeMaxZeroThreshold) + .histogramNativeMaxNumberOfBuckets(nativeMaxNumberOfBuckets) + .histogramNativeResetDurationSeconds(nativeResetDurationSeconds) .build(); } @@ -687,16 +687,16 @@ protected MetricsProperties toProperties() { */ @Override public MetricsProperties getDefaultProperties() { - return MetricsProperties.newBuilder() - .withExemplarsEnabled(true) - .withHistogramNativeOnly(false) - .withHistogramClassicOnly(false) - .withHistogramClassicUpperBounds(DEFAULT_CLASSIC_UPPER_BOUNDS) - .withHistogramNativeInitialSchema(DEFAULT_NATIVE_INITIAL_SCHEMA) - .withHistogramNativeMinZeroThreshold(DEFAULT_NATIVE_MIN_ZERO_THRESHOLD) - .withHistogramNativeMaxZeroThreshold(DEFAULT_NATIVE_MAX_ZERO_THRESHOLD) - .withHistogramNativeMaxNumberOfBuckets(DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS) - .withHistogramNativeResetDurationSeconds(DEFAULT_NATIVE_RESET_DURATION_SECONDS) + return MetricsProperties.builder() + .exemplarsEnabled(true) + .histogramNativeOnly(false) + .histogramClassicOnly(false) + .histogramClassicUpperBounds(DEFAULT_CLASSIC_UPPER_BOUNDS) + .histogramNativeInitialSchema(DEFAULT_NATIVE_INITIAL_SCHEMA) + .histogramNativeMinZeroThreshold(DEFAULT_NATIVE_MIN_ZERO_THRESHOLD) + .histogramNativeMaxZeroThreshold(DEFAULT_NATIVE_MAX_ZERO_THRESHOLD) + .histogramNativeMaxNumberOfBuckets(DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS) + .histogramNativeResetDurationSeconds(DEFAULT_NATIVE_RESET_DURATION_SECONDS) .build(); } @@ -735,7 +735,7 @@ public Builder classicOnly() { * If the +Inf bucket is missing it will be added. * If upperBounds contains duplicates the duplicates will be removed. */ - public Builder withClassicBuckets(double... upperBounds) { + public Builder classicBuckets(double... upperBounds) { this.classicUpperBounds = upperBounds; for (double bound : upperBounds) { if (Double.isNaN(bound)) { @@ -755,7 +755,7 @@ public Builder withClassicBuckets(double... upperBounds) { * @param width is the width of each bucket * @param count is the total number of buckets, including start */ - public Builder withClassicLinearBuckets(double start, double width, int count) { + public Builder classicLinearBuckets(double start, double width, int count) { this.classicUpperBounds = new double[count]; // Use BigDecimal to avoid weird bucket boundaries like 0.7000000000000001. BigDecimal s = new BigDecimal(Double.toString(start)); @@ -776,7 +776,7 @@ public Builder withClassicLinearBuckets(double start, double width, int count) { * @param factor growth factor * @param count total number of buckets, including start */ - public Builder withClassicExponentialBuckets(double start, double factor, int count) { + public Builder classicExponentialBuckets(double start, double factor, int count) { classicUpperBounds = new double[count]; for (int i = 0; i < count; i++) { classicUpperBounds[i] = start * Math.pow(factor, i); @@ -792,7 +792,7 @@ public Builder withClassicExponentialBuckets(double start, double factor, int co * Schema is Prometheus terminology. In OpenTelemetry it's called "scale". *

      * Note that the schema for a histogram may be automatically decreased at runtime if the number - * of native histogram buckets exceeds {@link #withNativeMaxNumberOfBuckets(int)}. + * of native histogram buckets exceeds {@link #nativeMaxNumberOfBuckets(int)}. *

      * The following table shows: *

        @@ -845,7 +845,7 @@ public Builder withClassicExponentialBuckets(double start, double factor, int co *
    *
    max quantile errors for different growth factors
    schemafactormax quantile error
    -465.536-465.53699%
    -3256-325699%
    -21688%
    */ - public Builder withNativeInitialSchema(int nativeSchema) { + public Builder nativeInitialSchema(int nativeSchema) { if (nativeSchema < -4 || nativeSchema > 8) { throw new IllegalArgumentException("Unsupported native histogram schema " + nativeSchema + ": expecting -4 <= schema <= 8."); } @@ -863,7 +863,7 @@ public Builder withNativeInitialSchema(int nativeSchema) { *

    * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. */ - public Builder withNativeMaxZeroThreshold(double nativeMaxZeroThreshold) { + public Builder nativeMaxZeroThreshold(double nativeMaxZeroThreshold) { if (nativeMaxZeroThreshold < 0) { throw new IllegalArgumentException("Illegal native max zero threshold " + nativeMaxZeroThreshold + ": must be >= 0"); } @@ -881,7 +881,7 @@ public Builder withNativeMaxZeroThreshold(double nativeMaxZeroThreshold) { *

    * Default is {@link Builder#DEFAULT_NATIVE_MIN_ZERO_THRESHOLD}. */ - public Builder withNativeMinZeroThreshold(double nativeMinZeroThreshold) { + public Builder nativeMinZeroThreshold(double nativeMinZeroThreshold) { if (nativeMinZeroThreshold < 0) { throw new IllegalArgumentException("Illegal native min zero threshold " + nativeMinZeroThreshold + ": must be >= 0"); } @@ -892,25 +892,25 @@ public Builder withNativeMinZeroThreshold(double nativeMinZeroThreshold) { /** * Limit the number of native buckets. *

    - * If the number of native buckets exceeds the maximum, the {@link #withNativeInitialSchema(int)} is decreased, + * If the number of native buckets exceeds the maximum, the {@link #nativeInitialSchema(int)} is decreased, * i.e. the resolution of the histogram is decreased to reduce the number of buckets. *

    * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. */ - public Builder withNativeMaxNumberOfBuckets(int nativeMaxBuckets) { + public Builder nativeMaxNumberOfBuckets(int nativeMaxBuckets) { this.nativeMaxNumberOfBuckets = nativeMaxBuckets; return this; } /** - * If the histogram needed to be scaled down because {@link #withNativeMaxNumberOfBuckets(int)} was exceeded, - * reset the histogram after a certain time interval to go back to the original {@link #withNativeInitialSchema(int)}. + * If the histogram needed to be scaled down because {@link #nativeMaxNumberOfBuckets(int)} was exceeded, + * reset the histogram after a certain time interval to go back to the original {@link #nativeInitialSchema(int)}. *

    * Reset means all values are set to zero. A good value might be 24h or 7d. *

    * Default is no reset. */ - public Builder withNativeResetDuration(long duration, TimeUnit unit) { + public Builder nativeResetDuration(long duration, TimeUnit unit) { // TODO: reset interval isn't tested yet if (duration <= 0) { throw new IllegalArgumentException(duration + ": value > 0 expected"); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java index acfed6c2f..373e7a98b 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java @@ -14,10 +14,10 @@ /** * Info metric. Example: *

    {@code
    - * Info info = Info.newBuilder()
    - *         .withName("java_runtime_info")
    - *         .withHelp("Java runtime info")
    - *         .withLabelNames("env", "version", "vendor", "runtime")
    + * Info info = Info.builder()
    + *         .name("java_runtime_info")
    + *         .help("Java runtime info")
    + *         .labelNames("env", "version", "vendor", "runtime")
      *         .register();
      *
      * String version = System.getProperty("java.runtime.version", "unknown");
    @@ -87,11 +87,11 @@ public InfoSnapshot collect() {
             return new InfoSnapshot(getMetadata(), data);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -104,11 +104,11 @@ private Builder(PrometheusProperties config) {
             /**
              * The {@code _info} suffix will automatically be appended if it's missing.
              * 
    {@code
    -         * Info info1 = Info.newBuilder()
    -         *     .withName("runtime_info")
    +         * Info info1 = Info.builder()
    +         *     .name("runtime_info")
              *     .build();
    -         * Info info2 = Info.newBuilder()
    -         *     .withName("runtime")
    +         * Info info2 = Info.builder()
    +         *     .name("runtime")
              *     .build();
              * }
    * In the example above both {@code info1} and {@code info2} will be named {@code "runtime_info"} in Prometheus. @@ -118,15 +118,15 @@ private Builder(PrometheusProperties config) { * is {@code false}. */ @Override - public Builder withName(String name) { - return super.withName(stripInfoSuffix(name)); + public Builder name(String name) { + return super.name(stripInfoSuffix(name)); } /** * Throws an {@link UnsupportedOperationException} because Info metrics cannot have a unit. */ @Override - public Builder withUnit(Unit unit) { + public Builder unit(Unit unit) { if (unit != null) { throw new UnsupportedOperationException("Info metrics cannot have a unit."); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java index d324a2700..b7db83208 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java @@ -41,7 +41,7 @@ protected Builder(List illegalLabelNames, PrometheusProperties propertie // server, or by one specific metric (e.g. a build_info or a // machine_role metric). See also // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels - public B withConstLabels(Labels constLabels) { + public B constLabels(Labels constLabels) { for (Label label : constLabels) { // NPE if constLabels is null if (illegalLabelNames.contains(label.getName())) { throw new IllegalArgumentException(label.getName() + ": illegal label name for this metric type"); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 7a3649861..9d39593eb 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -9,8 +9,6 @@ import java.util.Arrays; import java.util.List; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; - /** * Almost all metrics have fixed metadata, i.e. the metric name is known when the metric is created. *

    @@ -57,7 +55,7 @@ protected Builder(List illegalLabelNames, PrometheusProperties propertie super(illegalLabelNames, properties); } - public B withName(String name) { + public B name(String name) { if (!PrometheusNaming.isValidMetricName(name)) { throw new IllegalArgumentException("'" + name + "': Illegal metric name."); } @@ -65,17 +63,17 @@ public B withName(String name) { return self(); } - public B withUnit(Unit unit) { + public B unit(Unit unit) { this.unit = unit; return self(); } - public B withHelp(String help) { + public B help(String help) { this.help = help; return self(); } - public B withLabelNames(String... labelNames) { + public B labelNames(String... labelNames) { for (String labelName : labelNames) { if (!PrometheusNaming.isValidLabelName(labelName)) { throw new IllegalArgumentException(labelName + ": illegal label name"); @@ -91,13 +89,13 @@ public B withLabelNames(String... labelNames) { return self(); } - public B withConstLabels(Labels constLabels) { + public B constLabels(Labels constLabels) { for (String labelName : labelNames) { if (constLabels.contains(labelName)) { // Labels.contains() treats dots like underscores throw new IllegalArgumentException(labelName + ": duplicate label name"); } } - return super.withConstLabels(constLabels); + return super.constLabels(constLabels); } @Override diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java index 7348c0410..f45b91152 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -3,7 +3,6 @@ import io.prometheus.metrics.config.MetricsProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.core.datapoints.StateSetDataPoint; @@ -36,15 +35,15 @@ * * public static void main(String[] args) { * - * StateSet stateSet = StateSet.newBuilder() - * .withName("feature_flags") - * .withHelp("Feature flags") - * .withLabelNames("env") - * .withStates(Feature.class) + * StateSet stateSet = StateSet.builder() + * .name("feature_flags") + * .help("Feature flags") + * .labelNames("env") + * .states(Feature.class) * .register(); * - * stateSet.withLabelValues("dev").setFalse(FEATURE_1); - * stateSet.withLabelValues("dev").setTrue(FEATURE_2); + * stateSet.labelValues("dev").setFalse(FEATURE_1); + * stateSet.labelValues("dev").setTrue(FEATURE_2); * } * }

    * The example above shows how to use a StateSet with an enum. @@ -144,11 +143,11 @@ private void set(String name, boolean value) { } } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -163,14 +162,14 @@ private Builder(PrometheusProperties config) { /** * Declare the states that should be represented by this StateSet. */ - public Builder withStates(Class> enumClass) { - return withStates(Stream.of(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new)); + public Builder states(Class> enumClass) { + return states(Stream.of(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new)); } /** * Declare the states that should be represented by this StateSet. */ - public Builder withStates(String... stateNames) { + public Builder states(String... stateNames) { if (stateNames.length == 0) { throw new IllegalArgumentException("states cannot be empty"); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index f3636b328..96df6299e 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -50,7 +50,7 @@ protected StatefulMetric(Builder builder) { public MetricSnapshot collect() { if (labelNames.length == 0 && data.size() == 0) { // This is a metric without labels that has not been used yet. Initialize the data on the fly. - withLabelValues(); + labelValues(); } List labels = new ArrayList<>(data.size()); List metricData = new ArrayList<>(data.size()); @@ -73,7 +73,7 @@ public MetricSnapshot collect() { * Now, the data points for the {@code payment_type} label values get initialized when they are * first used, i.e. the first time you call *
    {@code
    -     * counter.withLabelValues("paypal").inc();
    +     * counter.labelValues("paypal").inc();
          * }
    * the data point with label {@code payment_type="paypal"} will go from non-existent to having value {@code 1.0}. *

    @@ -87,13 +87,13 @@ public MetricSnapshot collect() { * show up in the exposition format with an initial value of zero. */ public void initLabelValues(String... labelValues) { - withLabelValues(labelValues); + labelValues(labelValues); } - public D withLabelValues(String... labelValues) { + public D labelValues(String... labelValues) { if (labelValues.length != labelNames.length) { if (labelValues.length == 0) { - throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call withLabelValues(...) when using it."); + throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call labelValues(...) when using it."); } else { throw new IllegalArgumentException("Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); } @@ -117,7 +117,7 @@ public void remove(String... labelValues) { protected T getNoLabels() { if (noLabels == null) { // Note that this will throw an IllegalArgumentException if labelNames is not empty. - noLabels = (T) withLabelValues(); + noLabels = (T) labelValues(); } return noLabels; } @@ -175,8 +175,8 @@ public B withoutExemplars() { * Override if there are more properties than just exemplars enabled. */ protected MetricsProperties toProperties() { - return MetricsProperties.newBuilder() - .withExemplarsEnabled(exemplarsEnabled) + return MetricsProperties.builder() + .exemplarsEnabled(exemplarsEnabled) .build(); } @@ -184,8 +184,8 @@ protected MetricsProperties toProperties() { * Override if there are more properties than just exemplars enabled. */ public MetricsProperties getDefaultProperties() { - return MetricsProperties.newBuilder() - .withExemplarsEnabled(true) + return MetricsProperties.builder() + .exemplarsEnabled(true) .build(); } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java index d461162f1..090922686 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java @@ -21,19 +21,19 @@ /** * Summary metric. Example: *

    {@code
    - * Summary summary = Summary.newBuilder()
    - *         .withName("http_request_duration_seconds_hi")
    - *         .withHelp("HTTP request service time in seconds")
    - *         .withUnit(SECONDS)
    - *         .withLabelNames("method", "path", "status_code")
    - *         .withQuantile(0.5, 0.01)
    - *         .withQuantile(0.95, 0.001)
    - *         .withQuantile(0.99, 0.001)
    + * Summary summary = Summary.builder()
    + *         .name("http_request_duration_seconds_hi")
    + *         .help("HTTP request service time in seconds")
    + *         .unit(SECONDS)
    + *         .labelNames("method", "path", "status_code")
    + *         .quantile(0.5, 0.01)
    + *         .quantile(0.95, 0.001)
    + *         .quantile(0.99, 0.001)
      *         .register();
      *
      * long start = System.nanoTime();
      * // process a request, duration will be observed
    - * summary.withLabelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
    + * summary.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
      * }
    * See {@link Summary.Builder} for configuration options. */ @@ -204,23 +204,23 @@ private Quantiles makeQuantiles() { } } - public static Summary.Builder newBuilder() { + public static Summary.Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Summary.Builder newBuilder(PrometheusProperties config) { + public static Summary.Builder builder(PrometheusProperties config) { return new Builder(config); } public static class Builder extends StatefulMetric.Builder { /** - * 5 minutes. See {@link #withMaxAgeSeconds(long)}. + * 5 minutes. See {@link #maxAgeSeconds(long)}. */ public static final long DEFAULT_MAX_AGE_SECONDS = TimeUnit.MINUTES.toSeconds(5); /** - * 5. See {@link #withNumberOfAgeBuckets(int)} + * 5. See {@link #numberOfAgeBuckets(int)} */ public static final int DEFAULT_NUMBER_OF_AGE_BUCKETS = 5; private final List quantiles = new ArrayList<>(); @@ -242,7 +242,7 @@ private static double defaultError(double quantile) { } /** - * See {@link #withQuantile(double, double)}. + * Add a quantile. See {@link #quantile(double, double)}. *

    * Default errors are: *

      @@ -251,25 +251,27 @@ private static double defaultError(double quantile) { *
    • error = 0.01 else. *
    */ - public Builder withQuantile(double quantile) { - return withQuantile(quantile, defaultError(quantile)); + public Builder quantile(double quantile) { + return quantile(quantile, defaultError(quantile)); } /** + * Add a quantile. Call multiple times to add multiple quantiles. + *

    * Example: The following will track the 0.95 quantile: *

    {@code
    -         * .withQuantile(0.95, 0.001)
    +         * .quantile(0.95, 0.001)
              * }
    * The second argument is the acceptable error margin, i.e. with the code above the quantile * will not be exactly the 0.95 quantile but something between 0.949 and 0.951. *

    * There are two special cases: *

      - *
    • {@code .withQuantile(0.0, 0.0)} gives you the minimum observed value
    • - *
    • {@code .withQuantile(1.0, 0.0)} gives you the maximum observed value
    • + *
    • {@code .quantile(0.0, 0.0)} gives you the minimum observed value
    • + *
    • {@code .quantile(1.0, 0.0)} gives you the maximum observed value
    • *
    */ - public Builder withQuantile(double quantile, double error) { + public Builder quantile(double quantile, double error) { if (quantile < 0.0 || quantile > 1.0) { throw new IllegalArgumentException("Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); } @@ -285,7 +287,7 @@ public Builder withQuantile(double quantile, double error) { * {@code maxAgeSeconds} is the size of that time window. * Default is {@link #DEFAULT_MAX_AGE_SECONDS}. */ - public Builder withMaxAgeSeconds(long maxAgeSeconds) { + public Builder maxAgeSeconds(long maxAgeSeconds) { if (maxAgeSeconds <= 0) { throw new IllegalArgumentException("maxAgeSeconds cannot be " + maxAgeSeconds); } @@ -300,7 +302,7 @@ public Builder withMaxAgeSeconds(long maxAgeSeconds) { * then it is moving forward every minute by one minute. * Default is {@link #DEFAULT_NUMBER_OF_AGE_BUCKETS}. */ - public Builder withNumberOfAgeBuckets(int ageBuckets) { + public Builder numberOfAgeBuckets(int ageBuckets) { if (ageBuckets <= 0) { throw new IllegalArgumentException("ageBuckets cannot be " + ageBuckets); } @@ -320,12 +322,12 @@ protected MetricsProperties toProperties() { quantileErrors[i] = this.quantiles.get(i).epsilon; } } - return MetricsProperties.newBuilder() - .withExemplarsEnabled(exemplarsEnabled) - .withSummaryQuantiles(quantiles) - .withSummaryQuantileErrors(quantileErrors) - .withSummaryNumberOfAgeBuckets(ageBuckets) - .withSummaryMaxAgeSeconds(maxAgeSeconds) + return MetricsProperties.builder() + .exemplarsEnabled(exemplarsEnabled) + .summaryQuantiles(quantiles) + .summaryQuantileErrors(quantileErrors) + .summaryNumberOfAgeBuckets(ageBuckets) + .summaryMaxAgeSeconds(maxAgeSeconds) .build(); } @@ -334,11 +336,11 @@ protected MetricsProperties toProperties() { */ @Override public MetricsProperties getDefaultProperties() { - return MetricsProperties.newBuilder() - .withExemplarsEnabled(true) - .withSummaryQuantiles() - .withSummaryNumberOfAgeBuckets(DEFAULT_NUMBER_OF_AGE_BUCKETS) - .withSummaryMaxAgeSeconds(DEFAULT_MAX_AGE_SECONDS) + return MetricsProperties.builder() + .exemplarsEnabled(true) + .summaryQuantiles() + .summaryNumberOfAgeBuckets(DEFAULT_NUMBER_OF_AGE_BUCKETS) + .summaryMaxAgeSeconds(DEFAULT_MAX_AGE_SECONDS) .build(); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java index c9bdcfdfe..c55211636 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java @@ -15,12 +15,12 @@ *
    {@code
      * double MILLISECONDS_PER_SECOND = 1E3;
      *
    - * SummaryWithCallback.newBuilder()
    - *         .withName("jvm_gc_collection_seconds")
    - *         .withHelp("Time spent in a given JVM garbage collector in seconds.")
    - *         .withUnit(Unit.SECONDS)
    - *         .withLabelNames("gc")
    - *         .withCallback(callback -> {
    + * SummaryWithCallback.builder()
    + *         .name("jvm_gc_collection_seconds")
    + *         .help("Time spent in a given JVM garbage collector in seconds.")
    + *         .unit(Unit.SECONDS)
    + *         .labelNames("gc")
    + *         .callback(callback -> {
      *             for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
      *                 callback.call(
      *                         gc.getCollectionCount(),
    @@ -59,11 +59,11 @@ public SummarySnapshot collect() {
             return new SummarySnapshot(getMetadata(), dataPoints);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties properties) {
    +    public static Builder builder(PrometheusProperties properties) {
             return new Builder(properties);
         }
     
    @@ -71,7 +71,7 @@ public static class Builder extends CallbackMetric.Builder callback;
     
    -        public Builder withCallback(Consumer callback) {
    +        public Builder callback(Consumer callback) {
                 this.callback = callback;
                 return self();
             }
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
    index 035f21334..7311c84f6 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
    @@ -36,11 +36,11 @@ public class CounterTest {
     
         @Before
         public void setUp() throws NoSuchFieldException, IllegalAccessException {
    -        noLabels = Counter.newBuilder().withName("nolabels").build();
    -        labels = Counter.newBuilder().withName("labels")
    -                .withHelp("help")
    -                .withUnit(Unit.SECONDS)
    -                .withLabelNames("l")
    +        noLabels = Counter.builder().name("nolabels").build();
    +        labels = Counter.builder().name("labels")
    +                .help("help")
    +                .unit(Unit.SECONDS)
    +                .labelNames("l")
                     .build();
             origSpanContext = SpanContextSupplier.getSpanContext();
             ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(noLabels, exemplarSampleIntervalMillis);
    @@ -55,7 +55,7 @@ public void tearDown() {
         }
     
         private CounterSnapshot.CounterDataPointSnapshot getData(Counter counter, String... labels) {
    -        return counter.collect().getData().stream()
    +        return counter.collect().getDataPoints().stream()
                     .filter(d -> d.getLabels().equals(Labels.of(labels)))
                     .findAny()
                     .orElseThrow(() -> new RuntimeException("counter with labels " + labels + " not found"));
    @@ -67,7 +67,7 @@ private double getValue(Counter counter, String... labels) {
     
     
         private int getNumberOfLabels(Counter counter) {
    -        return ((CounterSnapshot) counter.collect()).getData().size();
    +        return ((CounterSnapshot) counter.collect()).getDataPoints().size();
         }
     
         @Test
    @@ -76,9 +76,9 @@ public void testIncrement() {
             assertEquals(1.0, getValue(noLabels), .001);
             noLabels.inc(2);
             assertEquals(3.0, getValue(noLabels), .001);
    -        noLabels.withLabelValues().inc(4);
    +        noLabels.labelValues().inc(4);
             assertEquals(7.0, getValue(noLabels), .001);
    -        noLabels.withLabelValues().inc();
    +        noLabels.labelValues().inc();
             assertEquals(8.0, getValue(noLabels), .001);
         }
     
    @@ -98,10 +98,10 @@ public void testEmptyCountersHaveNoLabels() {
         @Test
         public void testLabels() {
             assertEquals(0, getNumberOfLabels(labels));
    -        labels.withLabelValues("a").inc();
    +        labels.labelValues("a").inc();
             assertEquals(1, getNumberOfLabels(labels));
             assertEquals(1.0, getValue(labels, "l", "a"), .001);
    -        labels.withLabelValues("b").inc(3);
    +        labels.labelValues("b").inc(3);
             assertEquals(2, getNumberOfLabels(labels));
             assertEquals(1.0, getValue(labels, "l", "a"), .001);
             assertEquals(3.0, getValue(labels, "l", "b"), .001);
    @@ -114,9 +114,9 @@ public void testTotalStrippedFromName() {
                     "my_counter_seconds_total", "my.counter.seconds.total",
                     "my_counter", "my.counter",
                     "my_counter_seconds", "my.counter.seconds"}) {
    -            Counter counter = Counter.newBuilder()
    -                    .withName(name)
    -                    .withUnit(Unit.SECONDS)
    +            Counter counter = Counter.builder()
    +                    .name(name)
    +                    .unit(Unit.SECONDS)
                         .build();
                 Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect());
                 assertEquals("name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData));
    @@ -126,21 +126,21 @@ public void testTotalStrippedFromName() {
         @Test
         public void testSnapshotComplete() {
             long before = System.currentTimeMillis();
    -        Counter counter = Counter.newBuilder()
    -                .withName("test_seconds_total")
    -                .withUnit(Unit.SECONDS)
    -                .withHelp("help message")
    -                .withConstLabels(Labels.of("const1name", "const1value", "const2name", "const2value"))
    -                .withLabelNames("path", "status")
    +        Counter counter = Counter.builder()
    +                .name("test_seconds_total")
    +                .unit(Unit.SECONDS)
    +                .help("help message")
    +                .constLabels(Labels.of("const1name", "const1value", "const2name", "const2value"))
    +                .labelNames("path", "status")
                     .build();
    -        counter.withLabelValues("/", "200").inc(2);
    -        counter.withLabelValues("/", "500").inc();
    +        counter.labelValues("/", "200").inc(2);
    +        counter.labelValues("/", "500").inc();
             CounterSnapshot snapshot = (CounterSnapshot) counter.collect();
             Assert.assertEquals("test_seconds", snapshot.getMetadata().getName());
             Assert.assertEquals("seconds", snapshot.getMetadata().getUnit().toString());
             Assert.assertEquals("help message", snapshot.getMetadata().getHelp());
    -        Assert.assertEquals(2, snapshot.getData().size());
    -        Iterator iter = snapshot.getData().iterator();
    +        Assert.assertEquals(2, snapshot.getDataPoints().size());
    +        Iterator iter = snapshot.getDataPoints().iterator();
             // data is ordered by labels, so 200 comes before 500
             CounterSnapshot.CounterDataPointSnapshot data = iter.next();
             Assert.assertEquals(Labels.of("const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"), data.getLabels());
    @@ -179,26 +179,26 @@ private void assertExemplar(Counter counter, double value, String... labels) {
     
         @Test
         public void testExemplarSampler() throws Exception {
    -        final Exemplar exemplar1 = Exemplar.newBuilder()
    -                .withValue(2.0)
    -                .withTraceId("abc")
    -                .withSpanId("123")
    +        final Exemplar exemplar1 = Exemplar.builder()
    +                .value(2.0)
    +                .traceId("abc")
    +                .spanId("123")
                     .build();
    -        final Exemplar exemplar2 = Exemplar.newBuilder()
    -                .withValue(1.0)
    -                .withTraceId("def")
    -                .withSpanId("456")
    +        final Exemplar exemplar2 = Exemplar.builder()
    +                .value(1.0)
    +                .traceId("def")
    +                .spanId("456")
                     .build();
    -        final Exemplar exemplar3 = Exemplar.newBuilder()
    -                .withValue(1.0)
    -                .withTraceId("123")
    -                .withSpanId("abc")
    +        final Exemplar exemplar3 = Exemplar.builder()
    +                .value(1.0)
    +                .traceId("123")
    +                .spanId("abc")
                     .build();
    -        final Exemplar customExemplar = Exemplar.newBuilder()
    -                .withValue(1.0)
    -                .withTraceId("bab")
    -                .withSpanId("cdc")
    -                .withLabels(Labels.of("test", "test"))
    +        final Exemplar customExemplar = Exemplar.builder()
    +                .value(1.0)
    +                .traceId("bab")
    +                .spanId("cdc")
    +                .labels(Labels.of("test", "test"))
                     .build();
             SpanContext spanContext = new SpanContext() {
                 private int callNumber = 0;
    @@ -248,8 +248,8 @@ public boolean isCurrentSpanSampled() {
                 public void markCurrentSpanAsExemplar() {
                 }
             };
    -        Counter counter = Counter.newBuilder()
    -                .withName("count_total")
    +        Counter counter = Counter.builder()
    +                .name("count_total")
                     .build();
     
             SpanContextSupplier.setSpanContext(spanContext);
    @@ -287,9 +287,9 @@ public void markCurrentSpanAsExemplar() {
     
         @Test
         public void testExemplarSamplerDisabled() {
    -        Counter counter = Counter.newBuilder()
    +        Counter counter = Counter.builder()
                     //.withExemplarSampler((inc, prev) -> {throw new RuntimeException("unexpected call to exemplar sampler");})
    -                .withName("count_total")
    +                .name("count_total")
                     .withoutExemplars()
                     .build();
             counter.incWithExemplar(3.0, Labels.of("a", "b"));
    @@ -300,19 +300,19 @@ public void testExemplarSamplerDisabled() {
     
         @Test(expected = IllegalArgumentException.class)
         public void testConstLabelsFirst() {
    -        Counter.newBuilder()
    -                .withName("test_total")
    -                .withConstLabels(Labels.of("const_a", "const_b"))
    -                .withLabelNames("const.a")
    +        Counter.builder()
    +                .name("test_total")
    +                .constLabels(Labels.of("const_a", "const_b"))
    +                .labelNames("const.a")
                     .build();
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testConstLabelsSecond() {
    -        Counter.newBuilder()
    -                .withName("test_total")
    -                .withLabelNames("const.a")
    -                .withConstLabels(Labels.of("const_a", "const_b"))
    +        Counter.builder()
    +                .name("test_total")
    +                .labelNames("const.a")
    +                .constLabels(Labels.of("const_a", "const_b"))
                     .build();
         }
     }
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
    index 4c437281e..002a44545 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
    @@ -26,8 +26,8 @@ public class GaugeTest {
     
         @Before
         public void setUp() {
    -        noLabels = Gauge.newBuilder().withName("nolabels").build();
    -        labels = Gauge.newBuilder().withName("labels").withLabelNames("l").build();
    +        noLabels = Gauge.builder().name("nolabels").build();
    +        labels = Gauge.builder().name("labels").labelNames("l").build();
             origSpanContext = SpanContextSupplier.getSpanContext();
         }
     
    @@ -37,7 +37,7 @@ public void tearDown() {
         }
     
         private GaugeSnapshot.GaugeDataPointSnapshot getData(Gauge gauge, String... labels) {
    -        return ((GaugeSnapshot) gauge.collect()).getData().stream()
    +        return ((GaugeSnapshot) gauge.collect()).getDataPoints().stream()
                     .filter(data -> data.getLabels().equals(Labels.of(labels)))
                     .findAny()
                     .orElseThrow(RuntimeException::new);
    @@ -94,34 +94,34 @@ public void noLabelsDefaultZeroValue() {
     
         @Test
         public void testLabels() {
    -        labels.withLabelValues("a").inc();
    -        labels.withLabelValues("b").inc(3);
    +        labels.labelValues("a").inc();
    +        labels.labelValues("b").inc(3);
             assertEquals(1.0, getValue(labels, "l", "a"), .001);
             assertEquals(3.0, getValue(labels, "l", "b"), .001);
         }
     
         @Test
         public void testExemplarSampler() throws Exception {
    -        final Exemplar exemplar1 = Exemplar.newBuilder()
    -                .withValue(2.0)
    -                .withTraceId("abc")
    -                .withSpanId("123")
    +        final Exemplar exemplar1 = Exemplar.builder()
    +                .value(2.0)
    +                .traceId("abc")
    +                .spanId("123")
                     .build();
    -        final Exemplar exemplar2 = Exemplar.newBuilder()
    -                .withValue(6.5)
    -                .withTraceId("def")
    -                .withSpanId("456")
    +        final Exemplar exemplar2 = Exemplar.builder()
    +                .value(6.5)
    +                .traceId("def")
    +                .spanId("456")
                     .build();
    -        final Exemplar exemplar3 = Exemplar.newBuilder()
    -                .withValue(7.0)
    -                .withTraceId("123")
    -                .withSpanId("abc")
    +        final Exemplar exemplar3 = Exemplar.builder()
    +                .value(7.0)
    +                .traceId("123")
    +                .spanId("abc")
                     .build();
    -        final Exemplar customExemplar = Exemplar.newBuilder()
    -                .withValue(8.0)
    -                .withTraceId("bab")
    -                .withSpanId("cdc")
    -                .withLabels(Labels.of("test", "test"))
    +        final Exemplar customExemplar = Exemplar.builder()
    +                .value(8.0)
    +                .traceId("bab")
    +                .spanId("cdc")
    +                .labels(Labels.of("test", "test"))
                     .build();
             SpanContext spanContext = new SpanContext() {
                 private int callNumber = 0;
    @@ -171,8 +171,8 @@ public boolean isCurrentSpanSampled() {
                 public void markCurrentSpanAsExemplar() {
                 }
             };
    -        Gauge gauge = Gauge.newBuilder()
    -                .withName("my_gauge")
    +        Gauge gauge = Gauge.builder()
    +                .name("my_gauge")
                     .build();
     
             ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(gauge, exemplarMinAgeMillis);
    @@ -210,8 +210,8 @@ public void markCurrentSpanAsExemplar() {
     
         @Test
         public void testExemplarSamplerDisabled() {
    -        Gauge gauge = Gauge.newBuilder()
    -                .withName("test")
    +        Gauge gauge = Gauge.builder()
    +                .name("test")
                     .withoutExemplars()
                     .build();
             gauge.setWithExemplar(3.0, Labels.of("a", "b"));
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
    index 48a3dbd52..c937cef9e 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
    @@ -115,8 +115,8 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "bucket { cumulative_count: 3 upper_bound: 5.0 } " +
                                     "bucket { cumulative_count: 3 upper_bound: 10.0 } " +
                                     "bucket { cumulative_count: 3 upper_bound: Infinity }",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .classicOnly()
                                     .build(),
                             1.0, 2.0, 3.0),
    @@ -132,11 +132,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 1 " +
                                     "positive_delta: 0 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(3)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(3)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0.0, 1.0, 2.0, 3.0),
                     new GolangTestCase("'factor 1.2 results in schema 2' from client_golang",
    @@ -151,11 +151,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, 1, 1.2, 1.4, 1.8, 2),
                     new GolangTestCase("'factor 4 results in schema -1' from client_golang",
    @@ -171,11 +171,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -1 " +
                                     "positive_delta: -2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(-1)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(-1)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0.0156251, 0.0625, // Bucket -2: (0.015625, 0.0625)
                             0.1, 0.25, // Bucket -1: (0.0625, 0.25]
    @@ -195,11 +195,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: 3 " +
                                     "positive_delta: -6",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(-2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(-2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0.0156251, 0.0625, // Bucket -1: (0.015625, 0.0625]
                             0.1, 0.25, 0.5, 1, // Bucket 0: (0.0625, 1]
    @@ -218,11 +218,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: 2 " +
                                     "negative_delta: -2 " +
                                     "negative_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, -1, -1.2, -1.4, -1.8, -2
                     ),
    @@ -244,11 +244,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2
                     ),
    @@ -262,11 +262,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: 2 " +
                                     "positive_span { offset: 4 length: 1 } " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMinZeroThreshold(1.4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMinZeroThreshold(1.4)
                                     .build(),
                             0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2
                     ),
    @@ -284,11 +284,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    -                                .asNativeHistogram()
    -                                .withNativeSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                        Histogram.builder()
    +                                .name("test")
    +                                .nativeHistogram()
    +                                .nativeSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, 1, 1.2, 1.4, 1.8, 2, Double.NaN
                     ),
    @@ -307,11 +307,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: -2 " +
                                     "positive_delta: 2 " +
                                     "positive_delta: -1",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, 1, 1.2, 1.4, 1.8, 2, Double.POSITIVE_INFINITY
                     ),
    @@ -329,11 +329,11 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0, 1, 1.2, 1.4, 1.8, 2, Double.NEGATIVE_INFINITY
                     ),
    @@ -349,12 +349,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 2 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.2, 1.4, 1.8, 2
                     ),
    @@ -370,12 +370,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: -1 " +
                                     "positive_delta: -2 " +
                                     "positive_delta: 1",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3
                     ),
    @@ -393,12 +393,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: -2 " +
                                     "positive_delta: 0 " +
                                     "positive_delta: 1",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3
                     ),
    @@ -416,12 +416,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_delta: 0 " +
                                     "positive_delta: 1 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4),
                     new GolangTestCase("'buckets limited by reset' from client_golang",
    @@ -433,13 +433,13 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_span { offset: 7 length: 2 } " +
                                     "positive_delta: 1 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMinZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMinZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, RESET_DURATION_REACHED, 3, 4),
                     new GolangTestCase("'limited buckets but nothing triggered, negative observations' from client_golang",
    @@ -454,12 +454,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: 2 " +
                                     "negative_delta: -2 " +
                                     "negative_delta: 2",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, -1, -1.2, -1.4, -1.8, -2),
                     new GolangTestCase("'buckets limited by halving resolution, negative observations' from client_golang",
    @@ -474,12 +474,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: -1 " +
                                     "negative_delta: -2 " +
                                     "negative_delta: 1",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3),
                     new GolangTestCase("'buckets limited by widening the zero bucket, negative observations' from client_golang",
    @@ -496,12 +496,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: -2 " +
                                     "negative_delta: 0 " +
                                     "negative_delta: 1",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3),
                     new GolangTestCase("'buckets limited by widening the zero bucket twice, negative observations' from client_golang",
    @@ -518,12 +518,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_delta: 0 " +
                                     "negative_delta: 1 " +
                                     "negative_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4),
                     new GolangTestCase("'buckets limited by reset, negative observations' from client_golang",
    @@ -535,12 +535,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "negative_span { offset: 7 length: 2 } " +
                                     "negative_delta: 1 " +
                                     "negative_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, -1, -1.1, -1.2, -1.4, -1.8, -2, RESET_DURATION_REACHED, -3, -4),
                     new GolangTestCase("'buckets limited by halving resolution, then reset' from client_golang",
    @@ -552,12 +552,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_span { offset: 7 length: 2 } " +
                                     "positive_delta: 1 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(0)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(0)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4),
                     new GolangTestCase("'buckets limited by widening the zero bucket, then reset' from client_golang",
    @@ -569,12 +569,12 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio
                                     "positive_span { offset: 7 length: 2 } " +
                                     "positive_delta: 1 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(2)
    -                                .withNativeMaxZeroThreshold(1.2)
    -                                .withNativeMaxNumberOfBuckets(4)
    +                                .nativeInitialSchema(2)
    +                                .nativeMaxZeroThreshold(1.2)
    +                                .nativeMaxNumberOfBuckets(4)
                                     .build(),
                             0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4)
             };
    @@ -598,11 +598,11 @@ public void testAdditional() throws NoSuchFieldException, IllegalAccessException
                                     "positive_span { offset: -1 length: 2 } " +
                                     "positive_delta: 1 " +
                                     "positive_delta: 0",
    -                        Histogram.newBuilder()
    -                                .withName("test")
    +                        Histogram.builder()
    +                                .name("test")
                                     .nativeOnly()
    -                                .withNativeInitialSchema(0)
    -                                .withNativeMaxZeroThreshold(0)
    +                                .nativeInitialSchema(0)
    +                                .nativeMaxZeroThreshold(0)
                                     .build(),
                             0.0, 0.5, 1.0)
             };
    @@ -626,9 +626,9 @@ public void testNativeBucketIndexToUpperBound() throws NoSuchMethodException, In
             Method method = Histogram.DataPoint.class.getDeclaredMethod("nativeBucketIndexToUpperBound", int.class, int.class);
             method.setAccessible(true);
             for (int i = 0; i < indexes.length; i++) {
    -            Histogram histogram = Histogram.newBuilder()
    -                    .withName("test")
    -                    .withNativeInitialSchema(schemas[i])
    +            Histogram histogram = Histogram.builder()
    +                    .name("test")
    +                    .nativeInitialSchema(schemas[i])
                         .build();
                 Histogram.DataPoint histogramData = histogram.newDataPoint();
                 double result = (double) method.invoke(histogramData, schemas[i], indexes[i]);
    @@ -647,10 +647,10 @@ public void testFindBucketIndex() throws NoSuchMethodException, InvocationTarget
             findBucketIndex.setAccessible(true);
             nativeBucketIndexToUpperBound.setAccessible(true);
             for (int schema = -4; schema <= 8; schema++) {
    -            Histogram histogram = Histogram.newBuilder()
    +            Histogram histogram = Histogram.builder()
                         .nativeOnly()
    -                    .withName("test")
    -                    .withNativeInitialSchema(schema)
    +                    .name("test")
    +                    .nativeInitialSchema(schema)
                         .build();
                 for (int i = 0; i < 10_000; i++) {
                     for (int zeros = -5; zeros <= 10; zeros++) {
    @@ -666,7 +666,7 @@ public void testFindBucketIndex() throws NoSuchMethodException, InvocationTarget
     
         @Test
         public void testDefaults() throws IOException {
    -        Histogram histogram = Histogram.newBuilder().withName("test").build();
    +        Histogram histogram = Histogram.builder().name("test").build();
             histogram.observe(0.5);
             HistogramSnapshot snapshot = histogram.collect();
             String expectedNative = "" +
    @@ -739,70 +739,70 @@ public boolean isCurrentSpanSampled() {
                 public void markCurrentSpanAsExemplar() {
                 }
             };
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
                     // The default number of Exemplars is 4.
                     // Use 5 buckets to verify that the exemplar sample is configured with the buckets.
    -                .withClassicBuckets(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY)
    -                .withLabelNames("path")
    +                .classicBuckets(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY)
    +                .labelNames("path")
                     .build();
     
             long sampleIntervalMillis = 10;
             ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis);
             SpanContextSupplier.setSpanContext(spanContext);
     
    -        Exemplar ex1a = Exemplar.newBuilder()
    -                .withValue(0.5)
    -                .withSpanId("spanId-1")
    -                .withTraceId("traceId-1")
    +        Exemplar ex1a = Exemplar.builder()
    +                .value(0.5)
    +                .spanId("spanId-1")
    +                .traceId("traceId-1")
                     .build();
    -        Exemplar ex1b = Exemplar.newBuilder()
    -                .withValue(0.5)
    -                .withSpanId("spanId-2")
    -                .withTraceId("traceId-2")
    +        Exemplar ex1b = Exemplar.builder()
    +                .value(0.5)
    +                .spanId("spanId-2")
    +                .traceId("traceId-2")
                     .build();
    -        Exemplar ex2a = Exemplar.newBuilder()
    -                .withValue(4.5)
    -                .withSpanId("spanId-3")
    -                .withTraceId("traceId-3")
    +        Exemplar ex2a = Exemplar.builder()
    +                .value(4.5)
    +                .spanId("spanId-3")
    +                .traceId("traceId-3")
                     .build();
    -        Exemplar ex2b = Exemplar.newBuilder()
    -                .withValue(4.5)
    -                .withSpanId("spanId-4")
    -                .withTraceId("traceId-4")
    +        Exemplar ex2b = Exemplar.builder()
    +                .value(4.5)
    +                .spanId("spanId-4")
    +                .traceId("traceId-4")
                     .build();
    -        Exemplar ex3a = Exemplar.newBuilder()
    -                .withValue(1.5)
    -                .withSpanId("spanId-5")
    -                .withTraceId("traceId-5")
    +        Exemplar ex3a = Exemplar.builder()
    +                .value(1.5)
    +                .spanId("spanId-5")
    +                .traceId("traceId-5")
                     .build();
    -        Exemplar ex3b = Exemplar.newBuilder()
    -                .withValue(1.5)
    -                .withSpanId("spanId-6")
    -                .withTraceId("traceId-6")
    +        Exemplar ex3b = Exemplar.builder()
    +                .value(1.5)
    +                .spanId("spanId-6")
    +                .traceId("traceId-6")
                     .build();
    -        Exemplar ex4a = Exemplar.newBuilder()
    -                .withValue(2.5)
    -                .withSpanId("spanId-7")
    -                .withTraceId("traceId-7")
    +        Exemplar ex4a = Exemplar.builder()
    +                .value(2.5)
    +                .spanId("spanId-7")
    +                .traceId("traceId-7")
                     .build();
    -        Exemplar ex4b = Exemplar.newBuilder()
    -                .withValue(2.5)
    -                .withSpanId("spanId-8")
    -                .withTraceId("traceId-8")
    +        Exemplar ex4b = Exemplar.builder()
    +                .value(2.5)
    +                .spanId("spanId-8")
    +                .traceId("traceId-8")
                     .build();
    -        Exemplar ex5a = Exemplar.newBuilder()
    -                .withValue(3.5)
    -                .withSpanId("spanId-9")
    -                .withTraceId("traceId-9")
    +        Exemplar ex5a = Exemplar.builder()
    +                .value(3.5)
    +                .spanId("spanId-9")
    +                .traceId("traceId-9")
                     .build();
    -        Exemplar ex5b = Exemplar.newBuilder()
    -                .withValue(3.5)
    -                .withSpanId("spanId-10")
    -                .withTraceId("traceId-10")
    +        Exemplar ex5b = Exemplar.builder()
    +                .value(3.5)
    +                .spanId("spanId-10")
    +                .traceId("traceId-10")
                     .build();
    -        histogram.withLabelValues("/hello").observe(0.5);
    -        histogram.withLabelValues("/world").observe(0.5); // different labels are tracked independently, i.e. we don't need to wait for sampleIntervalMillis
    +        histogram.labelValues("/hello").observe(0.5);
    +        histogram.labelValues("/world").observe(0.5); // different labels are tracked independently, i.e. we don't need to wait for sampleIntervalMillis
     
             HistogramSnapshot snapshot = histogram.collect();
             assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello"));
    @@ -817,8 +817,8 @@ public void markCurrentSpanAsExemplar() {
             assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world"));
     
             Thread.sleep(sampleIntervalMillis + 1);
    -        histogram.withLabelValues("/hello").observe(4.5);
    -        histogram.withLabelValues("/world").observe(4.5);
    +        histogram.labelValues("/hello").observe(4.5);
    +        histogram.labelValues("/world").observe(4.5);
     
             snapshot = histogram.collect();
             assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello"));
    @@ -833,14 +833,14 @@ public void markCurrentSpanAsExemplar() {
             assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world"));
     
             Thread.sleep(sampleIntervalMillis + 1);
    -        histogram.withLabelValues("/hello").observe(1.5);
    -        histogram.withLabelValues("/world").observe(1.5);
    +        histogram.labelValues("/hello").observe(1.5);
    +        histogram.labelValues("/world").observe(1.5);
             Thread.sleep(sampleIntervalMillis + 1);
    -        histogram.withLabelValues("/hello").observe(2.5);
    -        histogram.withLabelValues("/world").observe(2.5);
    +        histogram.labelValues("/hello").observe(2.5);
    +        histogram.labelValues("/world").observe(2.5);
             Thread.sleep(sampleIntervalMillis + 1);
    -        histogram.withLabelValues("/hello").observe(3.5);
    -        histogram.withLabelValues("/world").observe(3.5);
    +        histogram.labelValues("/hello").observe(3.5);
    +        histogram.labelValues("/world").observe(3.5);
     
             snapshot = histogram.collect();
             assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello"));
    @@ -854,19 +854,19 @@ public void markCurrentSpanAsExemplar() {
             assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello"));
             assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world"));
     
    -        Exemplar custom = Exemplar.newBuilder()
    -                .withValue(3.4)
    -                .withLabels(Labels.of("key2", "value2", "key1", "value1", "trace_id", "traceId-11", "span_id", "spanId-11"))
    +        Exemplar custom = Exemplar.builder()
    +                .value(3.4)
    +                .labels(Labels.of("key2", "value2", "key1", "value1", "trace_id", "traceId-11", "span_id", "spanId-11"))
                     .build();
             Thread.sleep(sampleIntervalMillis + 1);
    -        histogram.withLabelValues("/hello").observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2"));
    +        histogram.labelValues("/hello").observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2"));
             snapshot = histogram.collect();
             // custom exemplars have preference, so the automatic exemplar is replaced
             assertExemplarEquals(custom, getExemplar(snapshot, 4.0, "path", "/hello"));
         }
     
         private Exemplar getExemplar(HistogramSnapshot snapshot, double le, String... labels) {
    -        HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream()
    +        HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream()
                     .filter(d -> d.getLabels().equals(Labels.of(labels)))
                     .findFirst()
                     .orElseThrow(() -> new RuntimeException("Labels not found"));
    @@ -886,8 +886,8 @@ public void testCustomExemplarsClassicHistogram() throws InterruptedException, N
     
             // TODO: This was copied from the old simpleclient, can probably be refactored.
     
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
                     .withExemplars()
                     .build();
     
    @@ -924,7 +924,7 @@ private void assertExemplar(Histogram histogram, double value, String... labels)
             double lowerBound = Double.NEGATIVE_INFINITY;
             double upperBound = Double.POSITIVE_INFINITY;
             HistogramSnapshot snapshot = histogram.collect();
    -        HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream()
    +        HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream()
                     .filter(d -> d.getLabels().isEmpty())
                     .findFirst()
                     .orElseThrow(() -> new RuntimeException("No data without labels found"));
    @@ -973,41 +973,41 @@ public boolean isCurrentSpanSampled() {
                 public void markCurrentSpanAsExemplar() {
                 }
             };
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
                     .nativeOnly()
    -                .withLabelNames("path")
    +                .labelNames("path")
                     .build();
     
             long sampleIntervalMillis = 10;
             ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis);
             SpanContextSupplier.setSpanContext(spanContext);
     
    -        Exemplar ex1 = Exemplar.newBuilder()
    -                .withValue(3.11)
    -                .withSpanId("spanId-1")
    -                .withTraceId("traceId-1")
    +        Exemplar ex1 = Exemplar.builder()
    +                .value(3.11)
    +                .spanId("spanId-1")
    +                .traceId("traceId-1")
                     .build();
    -        Exemplar ex2 = Exemplar.newBuilder()
    -                .withValue(3.12)
    -                .withSpanId("spanId-2")
    -                .withTraceId("traceId-2")
    +        Exemplar ex2 = Exemplar.builder()
    +                .value(3.12)
    +                .spanId("spanId-2")
    +                .traceId("traceId-2")
                     .build();
    -        Exemplar ex3 = Exemplar.newBuilder()
    -                .withValue(3.13)
    -                .withSpanId("spanId-3")
    -                .withTraceId("traceId-3")
    -                .withLabels(Labels.of("key1", "value1", "key2", "value2"))
    +        Exemplar ex3 = Exemplar.builder()
    +                .value(3.13)
    +                .spanId("spanId-3")
    +                .traceId("traceId-3")
    +                .labels(Labels.of("key1", "value1", "key2", "value2"))
                     .build();
     
    -        histogram.withLabelValues("/hello").observe(3.11);
    -        histogram.withLabelValues("/world").observe(3.12);
    +        histogram.labelValues("/hello").observe(3.11);
    +        histogram.labelValues("/world").observe(3.12);
             assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size());
             assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next());
             assertEquals(1, getData(histogram, "path", "/world").getExemplars().size());
             assertExemplarEquals(ex2, getData(histogram, "path", "/world").getExemplars().iterator().next());
     
    -        histogram.withLabelValues("/world").observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2"));
    +        histogram.labelValues("/world").observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2"));
             assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size());
             assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next());
             assertEquals(2, getData(histogram, "path", "/world").getExemplars().size());
    @@ -1024,46 +1024,46 @@ public void markCurrentSpanAsExemplar() {
     
         @Test(expected = IllegalArgumentException.class)
         public void testIllegalLabelName() {
    -        Histogram.newBuilder()
    -                .withName("test")
    -                .withLabelNames("label", "le");
    +        Histogram.builder()
    +                .name("test")
    +                .labelNames("label", "le");
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testIllegalLabelNameConstLabels() {
    -        Histogram.newBuilder()
    -                .withName("test")
    -                .withConstLabels(Labels.of("label1", "value1", "le", "0.3"));
    +        Histogram.builder()
    +                .name("test")
    +                .constLabels(Labels.of("label1", "value1", "le", "0.3"));
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testIllegalLabelNamePrefix() {
    -        Histogram.newBuilder()
    -                .withName("test")
    -                .withLabelNames("__hello");
    +        Histogram.builder()
    +                .name("test")
    +                .labelNames("__hello");
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testIllegalName() {
    -        Histogram.newBuilder().withName("my_namespace/server.durations");
    +        Histogram.builder().name("my_namespace/server.durations");
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testNoName() {
    -        Histogram.newBuilder().build();
    +        Histogram.builder().build();
         }
     
         @Test(expected = NullPointerException.class)
         public void testNullName() {
    -        Histogram.newBuilder()
    -                .withName(null);
    +        Histogram.builder()
    +                .name(null);
         }
     
         @Test
         public void testDuplicateClassicBuckets() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicBuckets(0, 3, 17, 3, 21)
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .classicBuckets(0, 3, 17, 3, 21)
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1073,9 +1073,9 @@ public void testDuplicateClassicBuckets() {
     
         @Test
         public void testUnsortedBuckets() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicBuckets(0.2, 0.1)
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .classicBuckets(0.2, 0.1)
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1085,9 +1085,9 @@ public void testUnsortedBuckets() {
     
         @Test
         public void testEmptyBuckets() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicBuckets()
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .classicBuckets()
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1097,9 +1097,9 @@ public void testEmptyBuckets() {
     
         @Test
         public void testBucketsIncludePositiveInfinity() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicBuckets(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY)
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .classicBuckets(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY)
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1109,9 +1109,9 @@ public void testBucketsIncludePositiveInfinity() {
     
         @Test
         public void testLinearBuckets() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicLinearBuckets(0.1, 0.1, 10)
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .classicLinearBuckets(0.1, 0.1, 10)
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1121,9 +1121,9 @@ public void testLinearBuckets() {
     
         @Test
         public void testExponentialBuckets() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withClassicExponentialBuckets(2, 2.5, 3)
    -                .withName("test")
    +        Histogram histogram = Histogram.builder()
    +                .classicExponentialBuckets(2, 2.5, 3)
    +                .name("test")
                     .build();
             List upperBounds = getData(histogram).getClassicBuckets().stream()
                     .map(ClassicHistogramBucket::getUpperBound)
    @@ -1133,14 +1133,14 @@ public void testExponentialBuckets() {
     
         @Test(expected = RuntimeException.class)
         public void testBucketsIncludeNaN() {
    -        Histogram.newBuilder()
    -                .withName("test")
    -                .withClassicBuckets(0.01, 0.1, 1.0, Double.NaN);
    +        Histogram.builder()
    +                .name("test")
    +                .classicBuckets(0.01, 0.1, 1.0, Double.NaN);
         }
     
         @Test
         public void testNoLabelsDefaultZeroValue() {
    -        Histogram noLabels = Histogram.newBuilder().withName("test").build();
    +        Histogram noLabels = Histogram.builder().name("test").build();
             assertEquals(0.0, getBucket(noLabels, 0.005).getCount(), 0.0);
             assertEquals(0, getData(noLabels).getCount());
             assertEquals(0.0, getData(noLabels).getSum(), 0.0);
    @@ -1155,8 +1155,8 @@ private ClassicHistogramBucket getBucket(Histogram histogram, double le, String.
     
         @Test
         public void testObserve() {
    -        Histogram noLabels = Histogram.newBuilder()
    -                .withName("test")
    +        Histogram noLabels = Histogram.builder()
    +                .name("test")
                     .build();
             noLabels.observe(2);
             assertEquals(1, getData(noLabels).getCount());
    @@ -1176,10 +1176,10 @@ public void testObserve() {
         @Test
         // See https://github.com/prometheus/client_java/issues/646
         public void testNegativeAmount() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("histogram")
    -                .withHelp("test histogram for negative values")
    -                .withClassicBuckets(-10, -5, 0, 5, 10)
    +        Histogram histogram = Histogram.builder()
    +                .name("histogram")
    +                .help("test histogram for negative values")
    +                .classicBuckets(-10, -5, 0, 5, 10)
                     .build();
             double expectedCount = 0;
             double expectedSum = 0;
    @@ -1199,8 +1199,8 @@ public void testNegativeAmount() {
     
         @Test
         public void testBoundaryConditions() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
                     .build();
             histogram.observe(2.5);
             assertEquals(0, getBucket(histogram, 1).getCount());
    @@ -1216,21 +1216,21 @@ public void testBoundaryConditions() {
     
         @Test
         public void testObserveWithLabels() {
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withConstLabels(Labels.of("env", "prod"))
    -                .withLabelNames("path", "status")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .constLabels(Labels.of("env", "prod"))
    +                .labelNames("path", "status")
                     .build();
    -        histogram.withLabelValues("/hello", "200").observe(0.11);
    -        histogram.withLabelValues("/hello", "200").observe(0.2);
    -        histogram.withLabelValues("/hello", "500").observe(0.19);
    +        histogram.labelValues("/hello", "200").observe(0.11);
    +        histogram.labelValues("/hello", "200").observe(0.2);
    +        histogram.labelValues("/hello", "500").observe(0.19);
             HistogramSnapshot.HistogramDataPointSnapshot data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200");
             HistogramSnapshot.HistogramDataPointSnapshot data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500");
             assertEquals(2, data200.getCount());
             assertEquals(0.31, data200.getSum(), 0.0000001);
             assertEquals(1, data500.getCount());
             assertEquals(0.19, data500.getSum(), 0.0000001);
    -        histogram.withLabelValues("/hello", "200").observe(0.13);
    +        histogram.labelValues("/hello", "200").observe(0.13);
             data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200");
             data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500");
             assertEquals(3, data200.getCount());
    @@ -1242,12 +1242,12 @@ public void testObserveWithLabels() {
         @Test
         public void testObserveMultithreaded() throws InterruptedException, ExecutionException, TimeoutException {
             // Hard to test concurrency, but let's run a couple of observations in parallel and assert none gets lost.
    -        Histogram histogram = Histogram.newBuilder()
    -                .withName("test")
    -                .withLabelNames("status")
    +        Histogram histogram = Histogram.builder()
    +                .name("test")
    +                .labelNames("status")
                     .build();
             int nThreads = 8;
    -        DistributionDataPoint obs = histogram.withLabelValues("200");
    +        DistributionDataPoint obs = histogram.labelValues("200");
             ExecutorService executor = Executors.newFixedThreadPool(nThreads);
             CompletionService> completionService = new ExecutorCompletionService<>(executor);
             CountDownLatch startSignal = new CountDownLatch(nThreads);
    @@ -1271,8 +1271,8 @@ public void testObserveMultithreaded() throws InterruptedException, ExecutionExc
                 List snapshots = future.get(5, TimeUnit.SECONDS);
                 long count = 0;
                 for (HistogramSnapshot snapshot : snapshots) {
    -                Assert.assertEquals(1, snapshot.getData().size());
    -                HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getData().stream().findFirst().orElseThrow(RuntimeException::new);
    +                Assert.assertEquals(1, snapshot.getDataPoints().size());
    +                HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream().findFirst().orElseThrow(RuntimeException::new);
                     Assert.assertTrue(data.getCount() >= (count + 1000)); // 1000 own observations plus the ones from other threads
                     count = data.getCount();
                 }
    @@ -1288,7 +1288,7 @@ public void testObserveMultithreaded() throws InterruptedException, ExecutionExc
     
     
         private HistogramSnapshot.HistogramDataPointSnapshot getData(Histogram histogram, String... labels) {
    -        return histogram.collect().getData().stream()
    +        return histogram.collect().getDataPoints().stream()
                     .filter(d -> d.getLabels().equals(Labels.of(labels)))
                     .findAny()
                     .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found"));
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
    index c6d5b7719..f88c98d7c 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
    @@ -11,7 +11,6 @@
     
     import java.io.ByteArrayOutputStream;
     import java.io.IOException;
    -import java.nio.charset.Charset;
     import java.nio.charset.StandardCharsets;
     
     import static org.junit.Assert.assertEquals;
    @@ -24,9 +23,9 @@ public void testInfoStrippedFromName() {
                     "jvm.runtime", "jvm_runtime",
                     "jvm.runtime.info", "jvm_runtime_info"}) {
                 for (String labelName : new String[]{"my.key", "my_key"}) {
    -                Info info = Info.newBuilder()
    -                        .withName(name)
    -                        .withLabelNames(labelName)
    +                Info info = Info.builder()
    +                        .name(name)
    +                        .labelNames(labelName)
                             .build();
                     info.addLabelValues("value");
                     Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect());
    @@ -37,62 +36,62 @@ public void testInfoStrippedFromName() {
     
         @Test
         public void testAddAndRemove() throws IOException {
    -        Info info = Info.newBuilder()
    -                .withName("test_info")
    -                .withLabelNames("a", "b")
    +        Info info = Info.builder()
    +                .name("test_info")
    +                .labelNames("a", "b")
                     .build();
    -        Assert.assertEquals(0, info.collect().getData().size());
    +        Assert.assertEquals(0, info.collect().getDataPoints().size());
             info.addLabelValues("val1", "val2");
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             info.addLabelValues("val1", "val2"); // already exist, so no change
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             info.addLabelValues("val2", "val2");
    -        Assert.assertEquals(2, info.collect().getData().size());
    +        Assert.assertEquals(2, info.collect().getDataPoints().size());
             info.remove("val1", "val3"); // does not exist, so no change
    -        Assert.assertEquals(2, info.collect().getData().size());
    +        Assert.assertEquals(2, info.collect().getDataPoints().size());
             info.remove("val1", "val2");
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             info.remove("val2", "val2");
    -        Assert.assertEquals(0, info.collect().getData().size());
    +        Assert.assertEquals(0, info.collect().getDataPoints().size());
         }
     
         @Test
         public void testSet() throws IOException {
    -        Info info = Info.newBuilder()
    -                .withName("target_info")
    -                .withConstLabels(Labels.of("service.name", "test", "service.instance.id", "123"))
    -                .withLabelNames("service.version")
    +        Info info = Info.builder()
    +                .name("target_info")
    +                .constLabels(Labels.of("service.name", "test", "service.instance.id", "123"))
    +                .labelNames("service.version")
                     .build();
             info.setLabelValues("1.0.0");
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             info.setLabelValues("2.0.0");
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info);
         }
     
         @Test
         public void testConstLabelsOnly() throws IOException {
    -        Info info = Info.newBuilder()
    -                .withName("target_info")
    -                .withConstLabels(Labels.of("service.name", "test", "service.instance.id", "123"))
    +        Info info = Info.builder()
    +                .name("target_info")
    +                .constLabels(Labels.of("service.name", "test", "service.instance.id", "123"))
                     .build();
    -        Assert.assertEquals(1, info.collect().getData().size());
    +        Assert.assertEquals(1, info.collect().getDataPoints().size());
             assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info);
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testConstLabelsDuplicate1() {
    -        Info.newBuilder()
    -                .withConstLabels(Labels.of("a_1", "val1"))
    -                .withLabelNames("a.1")
    +        Info.builder()
    +                .constLabels(Labels.of("a_1", "val1"))
    +                .labelNames("a.1")
                     .build();
         }
     
         @Test(expected = IllegalArgumentException.class)
         public void testConstLabelsDuplicate2() {
    -        Info.newBuilder()
    -                .withLabelNames("a_1")
    -                .withConstLabels(Labels.of("a.1", "val1"))
    +        Info.builder()
    +                .labelNames("a_1")
    +                .constLabels(Labels.of("a.1", "val1"))
                     .build();
         }
     
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java
    index 1babd430c..5a82cdb48 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java
    @@ -25,15 +25,15 @@ public String toString() {
     
         @Test
         public void testEnumStateSet() {
    -        StateSet stateSet = StateSet.newBuilder()
    -                .withName("feature_flags")
    -                .withLabelNames("environment")
    -                .withStates(MyFeatureFlag.class)
    +        StateSet stateSet = StateSet.builder()
    +                .name("feature_flags")
    +                .labelNames("environment")
    +                .states(MyFeatureFlag.class)
                     .build();
    -        stateSet.withLabelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2);
    -        stateSet.withLabelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2);
    +        stateSet.labelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2);
    +        stateSet.labelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2);
             StateSetSnapshot snapshot = stateSet.collect();
    -        Assert.assertEquals(2, snapshot.getData().size());
    +        Assert.assertEquals(2, snapshot.getDataPoints().size());
             Assert.assertEquals(2, getData(stateSet, "environment", "dev").size());
             Assert.assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0));
             Assert.assertFalse(getData(stateSet, "environment", "dev").isTrue(0));
    @@ -48,9 +48,9 @@ public void testEnumStateSet() {
     
         @Test
         public void testDefaultFalse() {
    -        StateSet stateSet = StateSet.newBuilder()
    -                .withName("test")
    -                .withStates("state1", "state2", "state3")
    +        StateSet stateSet = StateSet.builder()
    +                .name("test")
    +                .states("state1", "state2", "state3")
                     .build();
             Assert.assertEquals(3, getData(stateSet).size());
             Assert.assertEquals("state1", getData(stateSet).getName(0));
    @@ -62,7 +62,7 @@ public void testDefaultFalse() {
         }
     
         private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) {
    -        return stateSet.collect().getData().stream()
    +        return stateSet.collect().getDataPoints().stream()
                     .filter(d -> d.getLabels().equals(Labels.of(labels)))
                     .findAny()
                     .orElseThrow(() -> new RuntimeException("stateset with labels " + labels + " not found"));
    @@ -70,6 +70,6 @@ private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, St
     
         @Test(expected = IllegalStateException.class)
         public void testStatesCannotBeEmpty() {
    -        StateSet.newBuilder().withName("invalid").build();
    +        StateSet.builder().name("invalid").build();
         }
     }
    diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java
    index 3b947e73e..0baddd5fd 100644
    --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java
    +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java
    @@ -10,13 +10,13 @@ public class StatefulMetricTest {
     
         @Test
         public void testLabelRemoveWhileCollecting() throws Exception {
    -        Counter counter = Counter.newBuilder().withName("test").withLabelNames("label1", "label2").build();
    +        Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build();
             Field data = counter.getClass().getSuperclass().getDeclaredField("data");
             data.setAccessible(true);
     
    -        counter.withLabelValues("a", "b").inc(1.0);
    -        counter.withLabelValues("c", "d").inc(3.0);
    -        counter.withLabelValues("e", "f").inc(7.0);
    +        counter.labelValues("a", "b").inc(1.0);
    +        counter.labelValues("c", "d").inc(3.0);
    +        counter.labelValues("e", "f").inc(7.0);
     
             // collect() iterates over data.entrySet().
             // remove() removes entries from data.
    diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java
    index ff97bfbdb..61403b8ae 100644
    --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java
    +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java
    @@ -94,7 +94,7 @@ private Predicate makeNameFilter(ExporterFilterProperties props) {
             if (props.getAllowedNames() == null && props.getExcludedNames() == null && props.getAllowedPrefixes() == null && props.getExcludedPrefixes() == null) {
                 return null;
             } else {
    -            return MetricNameFilter.newBuilder()
    +            return MetricNameFilter.builder()
                         .nameMustBeEqualTo(props.getAllowedNames())
                         .nameMustNotBeEqualTo(props.getExcludedNames())
                         .nameMustStartWith(props.getAllowedPrefixes())
    @@ -115,7 +115,7 @@ private MetricSnapshots scrape(PrometheusHttpRequest request) {
         private Predicate makeNameFilter(String[] includedNames) {
             Predicate result = null;
             if (includedNames != null) {
    -            result = MetricNameFilter.newBuilder().nameMustBeEqualTo(includedNames).build();
    +            result = MetricNameFilter.builder().nameMustBeEqualTo(includedNames).build();
             }
             if (result != null && nameFilter != null) {
                 result = result.and(nameFilter);
    diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
    index 7224ff3e7..d3ef9d68e 100644
    --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
    +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
    @@ -15,7 +15,6 @@
     import java.net.InetAddress;
     import java.net.InetSocketAddress;
     import java.util.concurrent.ExecutorService;
    -import java.util.concurrent.Executors;
     import java.util.concurrent.RejectedExecutionHandler;
     import java.util.concurrent.SynchronousQueue;
     import java.util.concurrent.ThreadPoolExecutor;
    @@ -27,8 +26,8 @@
      * Example Usage:
      * 
      * {@code
    - * HTTPServer server = HTTPServer.newBuilder()
    - *     .withPort(9090)
    + * HTTPServer server = HTTPServer.builder()
    + *     .port(9090)
      *     .buildAndStart();
      * }
    * */ @@ -90,11 +89,11 @@ public int getPort() { return server.getAddress().getPort(); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -120,27 +119,27 @@ private Builder(PrometheusProperties config) { * Port to bind to. Default is 0, indicating that a random port will be selected. * You can learn the randomly selected port by calling {@link HTTPServer#getPort()}. */ - public Builder withPort(int port) { + public Builder port(int port) { this.port = port; return this; } /** * Use this hostname to resolve the IP address to bind to. - * Must not be called together with {@link #withInetAddress(InetAddress)}. + * Must not be called together with {@link #inetAddress(InetAddress)}. * Default is empty, indicating that the HTTPServer binds to the wildcard address. */ - public Builder withHostname(String hostname) { + public Builder hostname(String hostname) { this.hostname = hostname; return this; } /** * Bind to this IP address. - * Must not be called together with {@link #withHostname(String)}. + * Must not be called together with {@link #hostname(String)}. * Default is empty, indicating that the HTTPServer binds to the wildcard address. */ - public Builder withInetAddress(InetAddress address) { + public Builder inetAddress(InetAddress address) { this.inetAddress = address; return this; } @@ -148,7 +147,7 @@ public Builder withInetAddress(InetAddress address) { /** * Optional: ExecutorService used by the {@code httpServer}. */ - public Builder withExecutorService(ExecutorService executorService) { + public Builder executorService(ExecutorService executorService) { this.executorService = executorService; return this; } @@ -156,7 +155,7 @@ public Builder withExecutorService(ExecutorService executorService) { /** * Optional: Default is {@link PrometheusRegistry#defaultRegistry}. */ - public Builder withRegistry(PrometheusRegistry registry) { + public Builder registry(PrometheusRegistry registry) { this.registry = registry; return this; } @@ -164,7 +163,7 @@ public Builder withRegistry(PrometheusRegistry registry) { /** * Optional: {@link Authenticator} for authentication. */ - public Builder withAuthenticator(Authenticator authenticator) { + public Builder authenticator(Authenticator authenticator) { this.authenticator = authenticator; return this; } @@ -172,7 +171,7 @@ public Builder withAuthenticator(Authenticator authenticator) { /** * Optional: {@link HttpsConfigurator} for TLS/SSL */ - public Builder withHttpsConfigurator(HttpsConfigurator configurator) { + public Builder httpsConfigurator(HttpsConfigurator configurator) { this.httpsConfigurator = configurator; return this; } @@ -180,7 +179,7 @@ public Builder withHttpsConfigurator(HttpsConfigurator configurator) { /** * Optional: Override default handler, i.e. the handler that will be registered for the / endpoint. */ - public Builder withDefaultHandler(HttpHandler defaultHandler) { + public Builder defaultHandler(HttpHandler defaultHandler) { this.defaultHandler = defaultHandler; return this; } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index ce90e4145..9c69faf3e 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -62,11 +62,11 @@ private Resource initResourceAttributes(Builder builder, ExporterOpenTelemetryPr return resourceBuilder.build(); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -89,7 +89,7 @@ private Builder(PrometheusProperties config) { this.config = config; } - public Builder withRegistry(PrometheusRegistry registry) { + public Builder registry(PrometheusRegistry registry) { this.registry = registry; return this; } @@ -101,7 +101,7 @@ public Builder withRegistry(PrometheusRegistry registry) { *

    * See OpenTelemetry's OTEL_EXPORTER_OTLP_PROTOCOL. */ - public Builder withProtocol(String protocol) { + public Builder protocol(String protocol) { if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { throw new IllegalArgumentException(protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); } @@ -122,17 +122,18 @@ public Builder withProtocol(String protocol) { *

    * See OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_ENDPOINT. */ - public Builder withEndpoint(String endpoint) { + public Builder endpoint(String endpoint) { this.endpoint = endpoint; return this; } /** * Add an HTTP header to be applied to outgoing requests. + * Call multiple times to add multiple headers. *

    * See OpenTelemetry's OTEL_EXPORTER_OTLP_HEADERS. */ - public Builder addHeader(String name, String value) { + public Builder header(String name, String value) { this.headers.put(name, value); return this; } @@ -143,7 +144,7 @@ public Builder addHeader(String name, String value) { * Like OpenTelemetry's OTEL_METRIC_EXPORT_INTERVAL, * but in seconds rather than milliseconds. */ - public Builder withIntervalSeconds(int intervalSeconds) { + public Builder intervalSeconds(int intervalSeconds) { if (intervalSeconds <= 0) { throw new IllegalStateException(intervalSeconds + ": expecting a push interval > 0s"); } @@ -157,7 +158,7 @@ public Builder withIntervalSeconds(int intervalSeconds) { * Like OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, * but in seconds rather than milliseconds. */ - public Builder withTimeoutSeconds(int timeoutSeconds) { + public Builder timeoutSeconds(int timeoutSeconds) { if (timeoutSeconds <= 0) { throw new IllegalStateException(timeoutSeconds + ": expecting a push interval > 0s"); } @@ -172,7 +173,7 @@ public Builder withTimeoutSeconds(int timeoutSeconds) { *

    * See {@code service.name} in OpenTelemetry's Resource Semantic Conventions. */ - public Builder withServiceName(String serviceName) { + public Builder serviceName(String serviceName) { this.serviceName = serviceName; return this; } @@ -182,7 +183,7 @@ public Builder withServiceName(String serviceName) { *

    * See {@code service.namespace} in OpenTelemetry's Resource Semantic Conventions. */ - public Builder withServiceNamespace(String serviceNamespace) { + public Builder serviceNamespace(String serviceNamespace) { this.serviceNamespace = serviceNamespace; return this; } @@ -192,7 +193,7 @@ public Builder withServiceNamespace(String serviceNamespace) { *

    * See {@code service.instance.id} in OpenTelemetry's Resource Semantic Conventions. */ - public Builder withServiceInstanceId(String serviceInstanceId) { + public Builder serviceInstanceId(String serviceInstanceId) { this.serviceInstanceId = serviceInstanceId; return this; } @@ -202,17 +203,17 @@ public Builder withServiceInstanceId(String serviceInstanceId) { *

    * See {@code service.version} in OpenTelemetry's Resource Semantic Conventions. */ - public Builder withServiceVersion(String serviceVersion) { + public Builder serviceVersion(String serviceVersion) { this.serviceVersion = serviceVersion; return this; } /** - * Add a resource attribute. + * Add a resource attribute. Call multiple times to add multiple resource attributes. *

    * See OpenTelemetry's OTEL_RESOURCE_ATTRIBUTES. */ - public Builder addResourceAttribute(String name, String value) { + public Builder resourceAttribute(String name, String value) { this.resourceAttributes.put(name, value); return this; } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 762060efc..fc7e047b1 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -74,8 +74,8 @@ private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) { InfoSnapshot targetInfo = (InfoSnapshot) snapshot; - if (targetInfo.getData().size() > 0) { - InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getData().get(0); + if (targetInfo.getDataPoints().size() > 0) { + InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getDataPoints().get(0); Labels labels = data.getLabels(); for (int i = 0; i < labels.size(); i++) { result.put(labels.getName(i), labels.getValue(i)); @@ -90,8 +90,8 @@ private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo(MetricSna for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") && snapshot instanceof InfoSnapshot) { InfoSnapshot scopeInfo = (InfoSnapshot) snapshot; - if (scopeInfo.getData().size() > 0) { - Labels labels = scopeInfo.getData().get(0).getLabels(); + if (scopeInfo.getDataPoints().size() > 0) { + Labels labels = scopeInfo.getDataPoints().get(0).getLabels(); String name = null; String version = null; AttributesBuilder attributesBuilder = Attributes.builder(); diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 3e30c4a6a..8557e0a29 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -32,8 +32,8 @@ public MetricData create(GaugeSnapshot snapshot) { } public MetricData create(HistogramSnapshot snapshot) { - if (!snapshot.getData().isEmpty()) { - HistogramSnapshot.HistogramDataPointSnapshot firstDataPoint = snapshot.getData().get(0); + if (!snapshot.getDataPoints().isEmpty()) { + HistogramSnapshot.HistogramDataPointSnapshot firstDataPoint = snapshot.getDataPoints().get(0); if (firstDataPoint.hasNativeHistogramData()) { return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusNativeHistogram(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); } else if (firstDataPoint.hasClassicHistogramData()) { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index a6d4d3830..08ef9ffc1 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -19,7 +19,7 @@ class PrometheusClassicHistogram extends PrometheusData impl PrometheusClassicHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.HISTOGRAM); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .filter(Objects::nonNull) .collect(Collectors.toList()); diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java index 883b06e08..ed58fa5c7 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java @@ -8,7 +8,6 @@ import java.util.Collection; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; class PrometheusCounter extends PrometheusData implements SumData { @@ -17,7 +16,7 @@ class PrometheusCounter extends PrometheusData implements SumDa public PrometheusCounter(CounterSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_SUM); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .collect(Collectors.toList()); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java index 16c307059..1278a6af3 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -7,7 +7,6 @@ import java.util.Collection; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; class PrometheusGauge extends PrometheusData implements GaugeData { @@ -16,7 +15,7 @@ class PrometheusGauge extends PrometheusData implements GaugeDa public PrometheusGauge(GaugeSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_GAUGE); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .collect(Collectors.toList()); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index 0dce35fa6..e5244a058 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -17,7 +17,7 @@ public class PrometheusInfo extends PrometheusData implements S public PrometheusInfo(InfoSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_SUM); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .collect(Collectors.toList()); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java index 7584949f6..9610a7bf9 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -19,7 +19,7 @@ class PrometheusNativeHistogram extends PrometheusData toOtelDataPoint(dataPoint, currentTimeMillis)) .filter(Objects::nonNull) .collect(Collectors.toList()); diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java index 3d19d9e8f..9b871d50c 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java @@ -11,7 +11,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; public class PrometheusStateSet extends PrometheusData implements SumData { @@ -19,7 +18,7 @@ public class PrometheusStateSet extends PrometheusData implemen public PrometheusStateSet(StateSetSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_SUM); this.points = new ArrayList<>(); - for (StateSetSnapshot.StateSetDataPointSnapshot dataPoint : snapshot.getData()) { + for (StateSetSnapshot.StateSetDataPointSnapshot dataPoint : snapshot.getDataPoints()) { for (int i=0; i implements Summ PrometheusSummary(SummarySnapshot snapshot, long currentTimeMillis) { super(MetricDataType.SUMMARY); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .collect(Collectors.toList()); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java index 930715492..2f717a652 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -15,7 +15,7 @@ class PrometheusUnknown extends PrometheusData implements Gauge public PrometheusUnknown(UnknownSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_GAUGE); - this.points = snapshot.getData().stream() + this.points = snapshot.getDataPoints().stream() .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) .collect(Collectors.toList()); } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index bbaf0c59c..eae5c1b8c 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -63,7 +63,7 @@ public String getContentType() { public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); } else if (snapshot instanceof GaugeSnapshot) { @@ -88,7 +88,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "counter", metadata); - for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); @@ -99,7 +99,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) t private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "gauge", metadata); - for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); if (exemplarsOnAllMetricTypesEnabled) { @@ -114,10 +114,10 @@ private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapsho MetricMetadata metadata = snapshot.getMetadata(); if (snapshot.isGaugeHistogram()) { writeMetadata(writer, "gaugehistogram", metadata); - writeClassicHistogramBuckets(writer, metadata, "_gcount", "_gsum", snapshot.getData()); + writeClassicHistogramBuckets(writer, metadata, "_gcount", "_gsum", snapshot.getDataPoints()); } else { writeMetadata(writer, "histogram", metadata); - writeClassicHistogramBuckets(writer, metadata, "_count", "_sum", snapshot.getData()); + writeClassicHistogramBuckets(writer, metadata, "_count", "_sum", snapshot.getDataPoints()); } } @@ -162,7 +162,7 @@ private ClassicHistogramBuckets getClassicBuckets(HistogramSnapshot.HistogramDat private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { boolean metadataWritten = false; MetricMetadata metadata = snapshot.getMetadata(); - for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getData()) { + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { continue; } @@ -194,7 +194,7 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) t private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "info", metadata); - for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); writer.write("1"); writeScrapeTimestampAndExemplar(writer, data, null); @@ -204,7 +204,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "stateset", metadata); - for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { for (int i = 0; i < data.size(); i++) { writer.write(metadata.getPrometheusName()); writer.write('{'); @@ -237,7 +237,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "unknown", metadata); - for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); if (exemplarsOnAllMetricTypesEnabled) { diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index eea5f929a..da421a980 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -24,7 +24,6 @@ import java.io.OutputStream; import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; /** * Write the Prometheus protobuf format as defined in @@ -54,7 +53,7 @@ public String getContentType() { public String toDebugString(MetricSnapshots metricSnapshots) { StringBuilder stringBuilder = new StringBuilder(); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); } } @@ -64,7 +63,7 @@ public String toDebugString(MetricSnapshots metricSnapshots) { @Override public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { convert(snapshot).writeDelimitedTo(out); } } @@ -73,43 +72,43 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx public Metrics.MetricFamily convert(MetricSnapshot snapshot) { Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder(); if (snapshot instanceof CounterSnapshot) { - for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getData()) { + for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { builder.addMetric(convert(data)); } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_total", Metrics.MetricType.COUNTER); } else if (snapshot instanceof GaugeSnapshot) { - for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getData()) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { builder.addMetric(convert(data)); } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); } else if (snapshot instanceof HistogramSnapshot) { HistogramSnapshot histogram = (HistogramSnapshot) snapshot; - for (HistogramSnapshot.HistogramDataPointSnapshot data : histogram.getData()) { + for (HistogramSnapshot.HistogramDataPointSnapshot data : histogram.getDataPoints()) { builder.addMetric(convert(data)); } Metrics.MetricType type = histogram.isGaugeHistogram() ? Metrics.MetricType.GAUGE_HISTOGRAM : Metrics.MetricType.HISTOGRAM; setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, type); } else if (snapshot instanceof SummarySnapshot) { - for (SummarySnapshot.SummaryDataPointSnapshot data : ((SummarySnapshot) snapshot).getData()) { + for (SummarySnapshot.SummaryDataPointSnapshot data : ((SummarySnapshot) snapshot).getDataPoints()) { if (data.hasCount() || data.hasSum() || data.getQuantiles().size() > 0) { builder.addMetric(convert(data)); } } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.SUMMARY); } else if (snapshot instanceof InfoSnapshot) { - for (InfoSnapshot.InfoDataPointSnapshot data : ((InfoSnapshot) snapshot).getData()) { + for (InfoSnapshot.InfoDataPointSnapshot data : ((InfoSnapshot) snapshot).getDataPoints()) { builder.addMetric(convert(data)); } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_info", Metrics.MetricType.GAUGE); } else if (snapshot instanceof StateSetSnapshot) { - for (StateSetSnapshot.StateSetDataPointSnapshot data : ((StateSetSnapshot) snapshot).getData()) { + for (StateSetSnapshot.StateSetDataPointSnapshot data : ((StateSetSnapshot) snapshot).getDataPoints()) { for (int i = 0; i < data.size(); i++) { builder.addMetric(convert(data, snapshot.getMetadata().getPrometheusName(), i)); } } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); } else if (snapshot instanceof UnknownSnapshot) { - for (UnknownSnapshot.UnknownDataPointSnapshot data : ((UnknownSnapshot) snapshot).getData()) { + for (UnknownSnapshot.UnknownDataPointSnapshot data : ((UnknownSnapshot) snapshot).getDataPoints()) { builder.addMetric(convert(data)); } setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.UNTYPED); diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index bc187a886..cf9bc3d10 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -26,7 +26,6 @@ import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; /** * Write the Prometheus text format. This is the default if you view a Prometheus endpoint with your Web browser. @@ -60,7 +59,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and "summary". OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); } else if (snapshot instanceof GaugeSnapshot) { @@ -80,7 +79,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx } if (writeCreatedTimestamps) { for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCreated(writer, snapshot); } else if (snapshot instanceof HistogramSnapshot) { @@ -97,7 +96,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException { boolean metadataWritten = false; MetricMetadata metadata = snapshot.getMetadata(); - for (DataPointSnapshot data : snapshot.getData()) { + for (DataPointSnapshot data : snapshot.getDataPoints()) { if (data.hasCreatedTimestamp()) { if (!metadataWritten) { writeMetadata(writer, "_created", "gauge", metadata); @@ -112,10 +111,10 @@ public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) thr } private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { - if (snapshot.getData().size() > 0) { + if (snapshot.getDataPoints().size() > 0) { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "_total", "counter", metadata); - for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getData()) { + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); @@ -126,7 +125,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) t private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "gauge", metadata); - for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getData()) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); @@ -136,7 +135,7 @@ private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throw private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "histogram", metadata); - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { ClassicHistogramBuckets buckets = getClassicBuckets(data); long cumulativeCount = 0; for (int i = 0; i < buckets.size(); i++) { @@ -178,7 +177,7 @@ private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot sna // Prometheus text format does not support gaugehistogram's _gcount and _gsum. // So we append _gcount and _gsum as gauge metrics. boolean metadataWritten = false; - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { if (data.hasCount()) { if (!metadataWritten) { writeMetadata(writer, "_gcount", "gauge", metadata); @@ -190,7 +189,7 @@ private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot sna } } metadataWritten = false; - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getData()) { + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { if (data.hasSum()) { if (!metadataWritten) { writeMetadata(writer, "_gsum", "gauge", metadata); @@ -206,7 +205,7 @@ private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot sna private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { boolean metadataWritten = false; MetricMetadata metadata = snapshot.getMetadata(); - for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getData()) { + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { continue; } @@ -235,7 +234,7 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) t private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "_info", "gauge", metadata); - for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getData()) { + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); writer.write("1"); writeScrapeTimestampAndNewline(writer, data); @@ -245,7 +244,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "gauge", metadata); - for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getData()) { + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { for (int i = 0; i < data.size(); i++) { writer.write(metadata.getPrometheusName()); writer.write('{'); @@ -278,7 +277,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "", "untyped", metadata); - for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getData()) { + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); writeScrapeTimestampAndNewline(writer, data); diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 4d97b739f..fbe8ac4b7 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -23,7 +23,6 @@ import io.prometheus.metrics.model.snapshots.UnknownSnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import java.io.ByteArrayOutputStream; @@ -63,26 +62,26 @@ public class ExpositionFormatsTest { private final String scrapeTimestamp2s = "1672850585.820"; private final long scrapeTimestamp2 = (long) (1000 * Double.parseDouble(scrapeTimestamp2s)); - private final Exemplar exemplar1 = Exemplar.newBuilder() - .withSpanId("12345") - .withTraceId("abcde") - .withLabels(Labels.of("env", "prod")) - .withValue(1.7) - .withTimestampMillis(1672850685829L) + private final Exemplar exemplar1 = Exemplar.builder() + .spanId("12345") + .traceId("abcde") + .labels(Labels.of("env", "prod")) + .value(1.7) + .timestampMillis(1672850685829L) .build(); - private final Exemplar exemplar2 = Exemplar.newBuilder() - .withSpanId("23456") - .withTraceId("bcdef") - .withLabels(Labels.of("env", "dev")) - .withValue(2.4) - .withTimestampMillis(1672850685830L) + private final Exemplar exemplar2 = Exemplar.builder() + .spanId("23456") + .traceId("bcdef") + .labels(Labels.of("env", "dev")) + .value(2.4) + .timestampMillis(1672850685830L) .build(); - private final Exemplar exemplarWithDots = Exemplar.newBuilder() - .withLabels(Labels.of("some.exemplar.key", "some value")) - .withValue(3.0) - .withTimestampMillis(1690298864383L) + private final Exemplar exemplarWithDots = Exemplar.builder() + .labels(Labels.of("some.exemplar.key", "some value")) + .value(3.0) + .timestampMillis(1690298864383L) .build(); @Test @@ -142,29 +141,29 @@ public void testCounterComplete() throws IOException { "}"; //@formatter:on - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("service_time_seconds") - .withHelp("total time spent serving") - .withUnit(Unit.SECONDS) - .addDataPoint(CounterDataPointSnapshot.newBuilder() - .withValue(0.8) - .withLabels(Labels.newBuilder() - .addLabel("path", "/hello") - .addLabel("status", "200") + CounterSnapshot counter = CounterSnapshot.builder() + .name("service_time_seconds") + .help("total time spent serving") + .unit(Unit.SECONDS) + .dataPoint(CounterDataPointSnapshot.builder() + .value(0.8) + .labels(Labels.builder() + .label("path", "/hello") + .label("status", "200") .build()) - .withExemplar(exemplar1) - .withCreatedTimestampMillis(createdTimestamp1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .exemplar(exemplar1) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) - .addDataPoint(CounterDataPointSnapshot.newBuilder() - .withValue(0.9) - .withLabels(Labels.newBuilder() - .addLabel("path", "/hello") - .addLabel("status", "500") + .dataPoint(CounterDataPointSnapshot.builder() + .value(0.9) + .labels(Labels.builder() + .label("path", "/hello") + .label("status", "500") .build()) - .withExemplar(exemplar2) - .withCreatedTimestampMillis(createdTimestamp2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .exemplar(exemplar2) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) .build(); assertOpenMetricsText(openMetricsText, counter); @@ -185,9 +184,9 @@ public void testCounterMinimal() throws IOException { "my_counter_total 1.1\n"; String prometheusProtobuf = "" + "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("my_counter") - .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.1).build()) + CounterSnapshot counter = CounterSnapshot.builder() + .name("my_counter") + .dataPoint(CounterDataPointSnapshot.builder().value(1.1).build()) .build(); assertOpenMetricsText(openMetricsText, counter); assertPrometheusText(prometheusText, counter); @@ -217,14 +216,14 @@ public void testCounterWithDots() throws IOException { "}"; //@formatter:on - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("my.request.count") - .addDataPoint(CounterDataPointSnapshot.newBuilder() - .withValue(3.0) - .withLabels(Labels.newBuilder() - .addLabel("http.path", "/hello") + CounterSnapshot counter = CounterSnapshot.builder() + .name("my.request.count") + .dataPoint(CounterDataPointSnapshot.builder() + .value(3.0) + .labels(Labels.builder() + .label("http.path", "/hello") .build()) - .withExemplar(exemplarWithDots) + .exemplar(exemplarWithDots) .build()) .build(); assertOpenMetricsText(openMetricsText, counter); @@ -261,25 +260,25 @@ public void testGaugeComplete() throws IOException { "timestamp_ms: 1672850585820 " + "}"; //@formatter:on - GaugeSnapshot gauge = GaugeSnapshot.newBuilder() - .withName("disk_usage_ratio") - .withHelp("percentage used") - .withUnit(new Unit("ratio")) - .addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(0.7) - .withLabels(Labels.newBuilder() - .addLabel("device", "/dev/sda2") + GaugeSnapshot gauge = GaugeSnapshot.builder() + .name("disk_usage_ratio") + .help("percentage used") + .unit(new Unit("ratio")) + .dataPoint(GaugeDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.builder() + .label("device", "/dev/sda2") .build()) - .withExemplar(exemplar2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .exemplar(exemplar2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(0.2) - .withLabels(Labels.newBuilder() - .addLabel("device", "/dev/sda1") + .dataPoint(GaugeDataPointSnapshot.builder() + .value(0.2) + .labels(Labels.builder() + .label("device", "/dev/sda1") .build()) - .withExemplar(exemplar1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .exemplar(exemplar1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetricsText, gauge); @@ -300,10 +299,10 @@ public void testGaugeMinimal() throws IOException { "temperature_centigrade 22.3\n"; String prometheusProtobuf = "" + "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; - GaugeSnapshot gauge = GaugeSnapshot.newBuilder() - .withName("temperature_centigrade") - .addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(22.3) + GaugeSnapshot gauge = GaugeSnapshot.builder() + .name("temperature_centigrade") + .dataPoint(GaugeDataPointSnapshot.builder() + .value(22.3) .build()) .build(); assertOpenMetricsText(openMetricsText, gauge); @@ -338,16 +337,16 @@ public void testGaugeWithDots() throws IOException { "}"; //@formatter:on - GaugeSnapshot gauge = GaugeSnapshot.newBuilder() - .withName("my.temperature.celsius") - .withHelp("Temperature") - .withUnit(Unit.CELSIUS) - .addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(23.0) - .withLabels(Labels.newBuilder() - .addLabel("location.id", "data-center-1") + GaugeSnapshot gauge = GaugeSnapshot.builder() + .name("my.temperature.celsius") + .help("Temperature") + .unit(Unit.CELSIUS) + .dataPoint(GaugeDataPointSnapshot.builder() + .value(23.0) + .labels(Labels.builder() + .label("location.id", "data-center-1") .build()) - .withExemplar(exemplarWithDots) + .exemplar(exemplarWithDots) .build()) .build(); assertOpenMetricsText(openMetricsText, gauge); @@ -446,39 +445,39 @@ public void testSummaryComplete() throws IOException { "timestamp_ms: 1672850585820 " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("http_request_duration_seconds") - .withHelp("request duration") - .withUnit(Unit.SECONDS) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withCount(7) - .withSum(2.2) - .withQuantiles(Quantiles.newBuilder() - .addQuantile(0.5, 225.3) - .addQuantile(0.9, 240.7) - .addQuantile(0.95, 245.1) + SummarySnapshot summary = SummarySnapshot.builder() + .name("http_request_duration_seconds") + .help("request duration") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder() + .count(7) + .sum(2.2) + .quantiles(Quantiles.builder() + .quantile(0.5, 225.3) + .quantile(0.9, 240.7) + .quantile(0.95, 245.1) .build()) - .withLabels(Labels.newBuilder() - .addLabel("status", "500") + .labels(Labels.builder() + .label("status", "500") .build()) - .withExemplars(Exemplars.of(exemplar2)) - .withCreatedTimestampMillis(createdTimestamp2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .exemplars(Exemplars.of(exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withCount(3) - .withSum(1.2) - .withQuantiles(Quantiles.newBuilder() - .addQuantile(0.5, 225.3) - .addQuantile(0.9, 240.7) - .addQuantile(0.95, 245.1) + .dataPoint(SummaryDataPointSnapshot.builder() + .count(3) + .sum(1.2) + .quantiles(Quantiles.builder() + .quantile(0.5, 225.3) + .quantile(0.9, 240.7) + .quantile(0.95, 245.1) .build()) - .withLabels(Labels.newBuilder() - .addLabel("status", "200") + .labels(Labels.builder() + .label("status", "200") .build()) - .withExemplars(Exemplars.of(exemplar1)) - .withCreatedTimestampMillis(createdTimestamp1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .exemplars(Exemplars.of(exemplar1)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -514,13 +513,13 @@ public void testSummaryWithoutQuantiles() throws IOException { "} " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .withHelp("latency") - .withUnit(Unit.SECONDS) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withCount(3) - .withSum(1.2) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .help("latency") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder() + .count(3) + .sum(1.2) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -549,10 +548,10 @@ public void testSummaryNoCountAndSum() throws IOException { "} " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withQuantiles(Quantiles.newBuilder().addQuantile(0.95, 200.0).build()) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder() + .quantiles(Quantiles.builder().quantile(0.95, 200.0).build()) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -581,10 +580,10 @@ public void testSummaryJustCount() throws IOException { "} " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withCount(1) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder() + .count(1) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -613,10 +612,10 @@ public void testSummaryJustSum() throws IOException { "} " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withSum(12.3) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder() + .sum(12.3) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -630,11 +629,11 @@ public void testSummaryJustSum() throws IOException { public void testSummaryEmptyData() throws IOException { // SummaryData can be present but empty (no count, no sum, no quantiles). // This should be treated like no data is present. - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .withHelp("latency") - .withUnit(Unit.SECONDS) - .addDataPoint(SummaryDataPointSnapshot.newBuilder().build()) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .help("latency") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder().build()) .build(); assertOpenMetricsText("# EOF\n", summary); assertPrometheusText("", summary); @@ -666,18 +665,18 @@ public void testSummaryEmptyAndNonEmpty() throws IOException { "} " + "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withLabels(Labels.of("path", "/v1")) + SummarySnapshot summary = SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder() + .labels(Labels.of("path", "/v1")) .build()) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withLabels(Labels.of("path", "/v2")) - .withCount(2) - .withSum(10.7) + .dataPoint(SummaryDataPointSnapshot.builder() + .labels(Labels.of("path", "/v2")) + .count(2) + .sum(10.7) .build()) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withLabels(Labels.of("path", "/v3")) + .dataPoint(SummaryDataPointSnapshot.builder() + .labels(Labels.of("path", "/v3")) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -712,17 +711,17 @@ public void testSummaryWithDots() throws IOException { "}"; //@formatter:on - SummarySnapshot summary = SummarySnapshot.newBuilder() - .withName("my.request.duration.seconds") - .withHelp("Request duration in seconds") - .withUnit(Unit.SECONDS) - .addDataPoint(SummaryDataPointSnapshot.newBuilder() - .withCount(1) - .withSum(0.03) - .withLabels(Labels.newBuilder() - .addLabel("http.path", "/hello") + SummarySnapshot summary = SummarySnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder() + .count(1) + .sum(0.03) + .labels(Labels.builder() + .label("http.path", "/hello") .build()) - .withExemplars(Exemplars.of(exemplarWithDots)) + .exemplars(Exemplars.of(exemplarWithDots)) .build()) .build(); assertOpenMetricsText(openMetricsText, summary); @@ -832,32 +831,32 @@ public void testClassicHistogramComplete() throws Exception { "} " + "}"; //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.newBuilder() - .withName("response_size_bytes") - .withHelp("help") - .withUnit(Unit.BYTES) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(3.2) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(1.0, 3) - .addBucket(2.2, 2) - .addBucket(Double.POSITIVE_INFINITY, 0) + HistogramSnapshot histogram = HistogramSnapshot.builder() + .name("response_size_bytes") + .help("help") + .unit(Unit.BYTES) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(1.0, 3) + .bucket(2.2, 2) + .bucket(Double.POSITIVE_INFINITY, 0) .build()) - .withLabels(Labels.of("status", "500")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .labels(Labels.of("status", "500")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(4.1) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(2.2, 2) - .addBucket(Double.POSITIVE_INFINITY, 1) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(4.1) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(2.2, 2) + .bucket(Double.POSITIVE_INFINITY, 1) .build()) - .withLabels(Labels.of("status", "200")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .labels(Labels.of("status", "200")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); @@ -893,11 +892,11 @@ public void testClassicHistogramMinimal() throws Exception { "} " + "}"; //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.newBuilder() - .withName("request_latency_seconds") - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 2) + HistogramSnapshot histogram = HistogramSnapshot.builder() + .name("request_latency_seconds") + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 2) .build()) .build()) .build(); @@ -936,12 +935,12 @@ public void testClassicHistogramCountAndSum() throws Exception { "} " + "}"; //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.newBuilder() - .withName("request_latency_seconds") - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(3.2) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 2) + HistogramSnapshot histogram = HistogramSnapshot.builder() + .name("request_latency_seconds") + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 2) .build()) .build()) .build(); @@ -1055,33 +1054,33 @@ public void testClassicGaugeHistogramComplete() throws IOException { "} " + "}"; //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() - .asGaugeHistogram() - .withName("cache_size_bytes") - .withHelp("number of bytes in the cache") - .withUnit(Unit.BYTES) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(17) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(2.0, 3) - .addBucket(Double.POSITIVE_INFINITY, 1) + HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() + .gaugeHistogram() + .name("cache_size_bytes") + .help("number of bytes in the cache") + .unit(Unit.BYTES) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(17) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(2.0, 3) + .bucket(Double.POSITIVE_INFINITY, 1) .build()) - .withLabels(Labels.of("db", "items")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .labels(Labels.of("db", "items")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(18) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(2.0, 4) - .addBucket(Double.POSITIVE_INFINITY, 0) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(18) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(2.0, 4) + .bucket(Double.POSITIVE_INFINITY, 0) .build() ) - .withLabels(Labels.of("db", "options")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .labels(Labels.of("db", "options")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) .build(); assertOpenMetricsText(openMetricsText, gaugeHistogram); @@ -1118,12 +1117,12 @@ public void testClassicGaugeHistogramMinimal() throws IOException { "} " + "}"; //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() - .asGaugeHistogram() - .withName("queue_size_bytes") - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 130) + HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() + .gaugeHistogram() + .name("queue_size_bytes") + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) .build()) .build()) .build(); @@ -1164,13 +1163,13 @@ public void testClassicGaugeHistogramCountAndSum() throws IOException { "} " + "}"; //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.newBuilder() - .asGaugeHistogram() - .withName("queue_size_bytes") - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(27000) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 130) + HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() + .gaugeHistogram() + .name("queue_size_bytes") + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(27000) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) .build()) .build()) .build(); @@ -1212,19 +1211,19 @@ public void testClassicHistogramWithDots() throws IOException { "}"; //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.newBuilder() - .withName("my.request.duration.seconds") - .withHelp("Request duration in seconds") - .withUnit(Unit.SECONDS) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(0.01) - .withLabels(Labels.newBuilder() - .addLabel("http.path", "/hello") + HistogramSnapshot histogram = HistogramSnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(0.01) + .labels(Labels.builder() + .label("http.path", "/hello") .build()) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 130) + .classicHistogramBuckets(ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) .build()) - .withExemplars(Exemplars.of(exemplarWithDots)) + .exemplars(Exemplars.of(exemplarWithDots)) .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); @@ -1338,54 +1337,54 @@ public void testNativeHistogramComplete() throws IOException { "} " + "}"; //@formatter:on - HistogramSnapshot nativeHistogram = HistogramSnapshot.newBuilder() - .withName("response_size_bytes") - .withHelp("help") - .withUnit(Unit.BYTES) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(3.2) - .withNativeSchema(5) - .withNativeZeroCount(1) - .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() + HistogramSnapshot nativeHistogram = HistogramSnapshot.builder() + .name("response_size_bytes") + .help("help") + .unit(Unit.BYTES) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .nativeSchema(5) + .nativeZeroCount(1) + .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() // span with 3 buckets - .addBucket(2, 3) - .addBucket(3, 5) - .addBucket(4, 4) + .bucket(2, 3) + .bucket(3, 5) + .bucket(4, 4) // span with just 1 bucket - .addBucket(12, 6) + .bucket(12, 6) // span with gap of size 1 - .addBucket(22, 2) - .addBucket(24, 1) - .addBucket(25, 3) + .bucket(22, 2) + .bucket(24, 1) + .bucket(25, 3) // span with gap of size 2 - .addBucket(32, 4) - .addBucket(33, 3) - .addBucket(36, 7) + .bucket(32, 4) + .bucket(33, 3) + .bucket(36, 7) // span with gap of size 3 - .addBucket(41, 3) - .addBucket(42, 9) - .addBucket(46, 2) - .addBucket(47, 1) + .bucket(41, 3) + .bucket(42, 9) + .bucket(46, 2) + .bucket(47, 1) .build()) - .withNativeBucketsForNegativeValues(NativeHistogramBuckets.newBuilder() - .addBucket(0, 1) - .addBucket(10, 0) // bucket with count 0 + .nativeBucketsForNegativeValues(NativeHistogramBuckets.builder() + .bucket(0, 1) + .bucket(10, 0) // bucket with count 0 .build()) - .withLabels(Labels.of("status", "500")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp2) - .withScrapeTimestampMillis(scrapeTimestamp2) + .labels(Labels.of("status", "500")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withSum(4.2) - .withNativeSchema(5) - .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() - .addBucket(0, 2) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(4.2) + .nativeSchema(5) + .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() + .bucket(0, 2) .build()) - .withLabels(Labels.of("status", "200")) - .withExemplars(Exemplars.of(exemplar1, exemplar2)) - .withCreatedTimestampMillis(createdTimestamp1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .labels(Labels.of("status", "200")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetricsText, nativeHistogram); @@ -1418,10 +1417,10 @@ public void testNativeHistogramMinimal() throws IOException { "} " + "}"; //@formatter:on - HistogramSnapshot nativeHistogram = HistogramSnapshot.newBuilder() - .withName("latency_seconds") - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withNativeSchema(5) + HistogramSnapshot nativeHistogram = HistogramSnapshot.builder() + .name("latency_seconds") + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .nativeSchema(5) .build()) .build(); assertOpenMetricsText(openMetricsText, nativeHistogram); @@ -1465,22 +1464,22 @@ public void testNativeHistogramWithDots() throws IOException { "}"; //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.newBuilder() - .withName("my.request.duration.seconds") - .withHelp("Request duration in seconds") - .withUnit(Unit.SECONDS) - .addDataPoint(HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withLabels(Labels.newBuilder() - .addLabel("http.path", "/hello") + HistogramSnapshot histogram = HistogramSnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() + .labels(Labels.builder() + .label("http.path", "/hello") .build()) - .withSum(3.2) - .withNativeSchema(5) - .withNativeZeroCount(1) - .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() - .addBucket(2, 3) + .sum(3.2) + .nativeSchema(5) + .nativeZeroCount(1) + .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() + .bucket(2, 3) .build() ) - .withExemplars(Exemplars.of(exemplarWithDots)) + .exemplars(Exemplars.of(exemplarWithDots)) .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); @@ -1500,11 +1499,11 @@ public void testInfo() throws IOException { "# HELP version_info version information\n" + "# TYPE version_info gauge\n" + "version_info{version=\"1.2.3\"} 1\n"; - InfoSnapshot info = InfoSnapshot.newBuilder() - .withName("version") - .withHelp("version information") - .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of("version", "1.2.3")) + InfoSnapshot info = InfoSnapshot.builder() + .name("version") + .help("version information") + .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("version", "1.2.3")) .build()) .build(); assertOpenMetricsText(openMetrics, info); @@ -1534,11 +1533,11 @@ public void testInfoWithDots() throws IOException { "gauge { value: 1.0 } " + "}"; //@formatter:on - InfoSnapshot info = InfoSnapshot.newBuilder() - .withName("jvm.status") - .withHelp("JVM status info") - .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of("jvm.version", "1.2.3")) + InfoSnapshot info = InfoSnapshot.builder() + .name("jvm.status") + .help("JVM status info") + .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("jvm.version", "1.2.3")) .build()) .build(); assertOpenMetricsText(openMetricsText, info); @@ -1563,20 +1562,20 @@ public void testStateSetComplete() throws IOException { "state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" + "state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" + "state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n"; - StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() - .withName("state") - .withHelp("complete state set example") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("env", "prod")) - .addState("state1", false) - .addState("state2", true) - .withScrapeTimestampMillis(scrapeTimestamp2) + StateSetSnapshot stateSet = StateSetSnapshot.builder() + .name("state") + .help("complete state set example") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("env", "prod")) + .state("state1", false) + .state("state2", true) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("env", "dev")) - .addState("state2", false) - .addState("state1", true) - .withScrapeTimestampMillis(scrapeTimestamp1) + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("env", "dev")) + .state("state2", false) + .state("state1", true) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetrics, stateSet); @@ -1596,11 +1595,11 @@ public void testStateSetMinimal() throws IOException { "# TYPE state gauge\n" + "state{state=\"a\"} 1\n" + "state{state=\"bb\"} 0\n"; - StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() - .withName("state") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("a", true) - .addState("bb", false) + StateSetSnapshot stateSet = StateSetSnapshot.builder() + .name("state") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("a", true) + .state("bb", false) .build()) .build(); assertOpenMetricsText(openMetrics, stateSet); @@ -1637,13 +1636,13 @@ public void testStateSetWithDots() throws IOException { "gauge { value: 0.0 } " + "}"; //@formatter:on - StateSetSnapshot stateSet = StateSetSnapshot.newBuilder() - .withName("my.application.state") - .withHelp("My application state") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("data.center", "us east")) - .addState("feature.enabled", true) - .addState("is.alpha.version", false) + StateSetSnapshot stateSet = StateSetSnapshot.builder() + .name("my.application.state") + .help("My application state") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("data.center", "us east")) + .state("feature.enabled", true) + .state("is.alpha.version", false) .build()) .build(); assertOpenMetricsText(openMetricsText, stateSet); @@ -1665,21 +1664,21 @@ public void testUnknownComplete() throws IOException { "# TYPE my_special_thing_bytes untyped\n" + "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" + "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n"; - UnknownSnapshot unknown = UnknownSnapshot.newBuilder() - .withName("my_special_thing_bytes") - .withHelp("help message") - .withUnit(Unit.BYTES) - .addDataPoint(UnknownDataPointSnapshot.newBuilder() - .withValue(0.7) - .withLabels(Labels.of("env", "prod")) - .withExemplar(exemplar2) - .withScrapeTimestampMillis(scrapeTimestamp2) + UnknownSnapshot unknown = UnknownSnapshot.builder() + .name("my_special_thing_bytes") + .help("help message") + .unit(Unit.BYTES) + .dataPoint(UnknownDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.of("env", "prod")) + .exemplar(exemplar2) + .scrapeTimestampMillis(scrapeTimestamp2) .build()) - .addDataPoint(UnknownDataPointSnapshot.newBuilder() - .withValue(0.2) - .withLabels(Labels.of("env", "dev")) - .withExemplar(exemplar1) - .withScrapeTimestampMillis(scrapeTimestamp1) + .dataPoint(UnknownDataPointSnapshot.builder() + .value(0.2) + .labels(Labels.of("env", "dev")) + .exemplar(exemplar1) + .scrapeTimestampMillis(scrapeTimestamp1) .build()) .build(); assertOpenMetricsText(openMetrics, unknown); @@ -1697,10 +1696,10 @@ public void testUnknownMinimal() throws IOException { String prometheus = "" + "# TYPE other untyped\n" + "other 22.3\n"; - UnknownSnapshot unknown = UnknownSnapshot.newBuilder() - .withName("other") - .addDataPoint(UnknownDataPointSnapshot.newBuilder() - .withValue(22.3) + UnknownSnapshot unknown = UnknownSnapshot.builder() + .name("other") + .dataPoint(UnknownDataPointSnapshot.builder() + .value(22.3) .build()) .build(); assertOpenMetricsText(openMetrics, unknown); @@ -1731,14 +1730,14 @@ public void testUnknownWithDots() throws IOException { "untyped { value: 0.7 } " + "}"; //@formatter:on - UnknownSnapshot unknown = UnknownSnapshot.newBuilder() - .withName("some.unknown.metric") - .withHelp("help message") - .withUnit(Unit.BYTES) - .addDataPoint(UnknownDataPointSnapshot.newBuilder() - .withValue(0.7) - .withLabels(Labels.of("test.env", "7")) - .withExemplar(exemplarWithDots) + UnknownSnapshot unknown = UnknownSnapshot.builder() + .name("some.unknown.metric") + .help("help message") + .unit(Unit.BYTES) + .dataPoint(UnknownDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.of("test.env", "7")) + .exemplar(exemplarWithDots) .build()) .build(); assertOpenMetricsText(openMetrics, unknown); @@ -1757,10 +1756,10 @@ public void testHelpEscape() throws IOException { "# HELP test_total Some text and \\n some \" escaping\n" + "# TYPE test_total counter\n" + "test_total 1.0\n"; - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("test") - .withHelp("Some text and \n some \" escaping") // example from https://openMetrics.io - .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot counter = CounterSnapshot.builder() + .name("test") + .help("Some text and \n some \" escaping") // example from https://openMetrics.io + .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) .build(); assertOpenMetricsText(openMetrics, counter); assertPrometheusText(prometheus, counter); @@ -1777,12 +1776,12 @@ public void testLabelValueEscape() throws IOException { String prometheus = "" + "# TYPE test_total counter\n" + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("test") - .addDataPoint(CounterDataPointSnapshot.newBuilder() + CounterSnapshot counter = CounterSnapshot.builder() + .name("test") + .dataPoint(CounterDataPointSnapshot.builder() // example from https://openMetrics.io - .withLabels(Labels.of("a", "x", "b", "escaping\" example \n ")) - .withValue(1.0) + .labels(Labels.of("a", "x", "b", "escaping\" example \n ")) + .value(1.0) .build()) .build(); assertOpenMetricsText(openMetrics, counter); diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java index c1e66f31a..9c8cddb46 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java @@ -12,11 +12,11 @@ /** * JVM Buffer Pool metrics. The {@link JvmBufferPoolMetrics} are registered as part of the {@link JvmMetrics} like this: *

    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmBufferPoolMetrics} you can also register them directly: *
    {@code
    - *   JvmBufferPoolMetrics.newBuilder().register();
    + *   JvmBufferPoolMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -50,35 +50,35 @@ private JvmBufferPoolMetrics(List bufferPoolBeans, PrometheusP
     
         private void register(PrometheusRegistry registry) {
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_BUFFER_POOL_USED_BYTES)
    -                .withHelp("Used bytes of a given JVM buffer pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_BUFFER_POOL_USED_BYTES)
    +                .help("Used bytes of a given JVM buffer pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(callback -> {
                         for (BufferPoolMXBean pool : bufferPoolBeans) {
                             callback.call(pool.getMemoryUsed(), pool.getName());
                         }
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_BUFFER_POOL_CAPACITY_BYTES)
    -                .withHelp("Bytes capacity of a given JVM buffer pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_BUFFER_POOL_CAPACITY_BYTES)
    +                .help("Bytes capacity of a given JVM buffer pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(callback -> {
                         for (BufferPoolMXBean pool : bufferPoolBeans) {
                             callback.call(pool.getTotalCapacity(), pool.getName());
                         }
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_BUFFER_POOL_USED_BUFFERS)
    -                .withHelp("Used buffers of a given JVM buffer pool.")
    -                .withLabelNames("pool")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_BUFFER_POOL_USED_BUFFERS)
    +                .help("Used buffers of a given JVM buffer pool.")
    +                .labelNames("pool")
    +                .callback(callback -> {
                         for (BufferPoolMXBean pool : bufferPoolBeans) {
                             callback.call(pool.getCount(), pool.getName());
                         }
    @@ -86,11 +86,11 @@ private void register(PrometheusRegistry registry) {
                     .register(registry);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -106,7 +106,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withBufferPoolBeans(List bufferPoolBeans) {
    +        Builder bufferPoolBeans(List bufferPoolBeans) {
                 this.bufferPoolBeans = bufferPoolBeans;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
    index 803fb0747..69d3c4ecd 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
    @@ -11,11 +11,11 @@
     /**
      * JVM Class Loading metrics. The {@link JvmClassLoadingMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmClassLoadingMetrics} you can also register them directly: *
    {@code
    - *   JvmClassLoadingMetrics.newBuilder().register();
    + *   JvmClassLoadingMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -46,30 +46,30 @@ private JvmClassLoadingMetrics(ClassLoadingMXBean classLoadingBean, PrometheusPr
     
         private void register(PrometheusRegistry registry) {
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_CLASSES_CURRENTLY_LOADED)
    -                .withHelp("The number of classes that are currently loaded in the JVM")
    -                .withCallback(callback -> callback.call(classLoadingBean.getLoadedClassCount()))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_CLASSES_CURRENTLY_LOADED)
    +                .help("The number of classes that are currently loaded in the JVM")
    +                .callback(callback -> callback.call(classLoadingBean.getLoadedClassCount()))
                     .register(registry);
     
    -        CounterWithCallback.newBuilder(config)
    -                .withName(JVM_CLASSES_LOADED_TOTAL)
    -                .withHelp("The total number of classes that have been loaded since the JVM has started execution")
    -                .withCallback(callback -> callback.call(classLoadingBean.getTotalLoadedClassCount()))
    +        CounterWithCallback.builder(config)
    +                .name(JVM_CLASSES_LOADED_TOTAL)
    +                .help("The total number of classes that have been loaded since the JVM has started execution")
    +                .callback(callback -> callback.call(classLoadingBean.getTotalLoadedClassCount()))
                     .register(registry);
     
    -        CounterWithCallback.newBuilder(config)
    -                .withName(JVM_CLASSES_UNLOADED_TOTAL)
    -                .withHelp("The total number of classes that have been unloaded since the JVM has started execution")
    -                .withCallback(callback -> callback.call(classLoadingBean.getUnloadedClassCount()))
    +        CounterWithCallback.builder(config)
    +                .name(JVM_CLASSES_UNLOADED_TOTAL)
    +                .help("The total number of classes that have been unloaded since the JVM has started execution")
    +                .callback(callback -> callback.call(classLoadingBean.getUnloadedClassCount()))
                     .register(registry);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -85,7 +85,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withClassLoadingBean(ClassLoadingMXBean classLoadingBean) {
    +        Builder classLoadingBean(ClassLoadingMXBean classLoadingBean) {
                 this.classLoadingBean = classLoadingBean;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
    index 2e73ec1b1..0fbebf46e 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
    @@ -13,11 +13,11 @@
     /**
      * JVM Compilation metrics. The {@link JvmCompilationMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmCompilationMetrics} you can also register them directly: *
    {@code
    - *   JvmCompilationMetrics.newBuilder().register();
    + *   JvmCompilationMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -44,19 +44,19 @@ private void register(PrometheusRegistry registry) {
                 return;
             }
     
    -        CounterWithCallback.newBuilder(config)
    -                .withName(JVM_COMPILATION_TIME_SECONDS_TOTAL)
    -                .withHelp("The total time in seconds taken for HotSpot class compilation")
    -                .withUnit(Unit.SECONDS)
    -                .withCallback(callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime())))
    +        CounterWithCallback.builder(config)
    +                .name(JVM_COMPILATION_TIME_SECONDS_TOTAL)
    +                .help("The total time in seconds taken for HotSpot class compilation")
    +                .unit(Unit.SECONDS)
    +                .callback(callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime())))
                     .register(registry);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -72,7 +72,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withCompilationBean(CompilationMXBean compilationBean) {
    +        Builder compilationBean(CompilationMXBean compilationBean) {
                 this.compilationBean = compilationBean;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
    index 87b423987..ab9877a85 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
    @@ -13,11 +13,11 @@
     /**
      * JVM Garbage Collector metrics. The {@link JvmGarbageCollectorMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmGarbageCollectorMetrics} you can also register them directly: *
    {@code
    - *   JvmGarbageCollectorMetrics.newBuilder().register();
    + *   JvmGarbageCollectorMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -43,12 +43,12 @@ private JvmGarbageCollectorMetrics(List garbageCollector
     
         private void register(PrometheusRegistry registry) {
     
    -        SummaryWithCallback.newBuilder(config)
    -                .withName(JVM_GC_COLLECTION_SECONDS)
    -                .withHelp("Time spent in a given JVM garbage collector in seconds.")
    -                .withUnit(Unit.SECONDS)
    -                .withLabelNames("gc")
    -                .withCallback(callback -> {
    +        SummaryWithCallback.builder(config)
    +                .name(JVM_GC_COLLECTION_SECONDS)
    +                .help("Time spent in a given JVM garbage collector in seconds.")
    +                .unit(Unit.SECONDS)
    +                .labelNames("gc")
    +                .callback(callback -> {
                         for (GarbageCollectorMXBean gc : garbageCollectorBeans) {
                             callback.call(gc.getCollectionCount(), Unit.millisToSeconds(gc.getCollectionTime()), Quantiles.EMPTY, gc.getName());
                         }
    @@ -56,11 +56,11 @@ private void register(PrometheusRegistry registry) {
                     .register(registry);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -76,7 +76,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withGarbageCollectorBeans(List garbageCollectorBeans) {
    +        Builder garbageCollectorBeans(List garbageCollectorBeans) {
                 this.garbageCollectorBeans = garbageCollectorBeans;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
    index a9a5f2225..3e3b95efa 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
    @@ -16,11 +16,11 @@
     /**
      * JVM memory metrics. The {@link JvmMemoryMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmMemoryMetrics} you can also register them directly: *
    {@code
    - *   JvmMemoryMetrics.newBuilder().register();
    + *   JvmMemoryMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -125,118 +125,118 @@ private JvmMemoryMetrics(List poolBeans, MemoryMXBean memoryBe
     
         private void register(PrometheusRegistry registry) {
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION)
    -                .withHelp("The number of objects waiting in the finalizer queue.")
    -                .withCallback(callback -> callback.call(memoryBean.getObjectPendingFinalizationCount()))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION)
    +                .help("The number of objects waiting in the finalizer queue.")
    +                .callback(callback -> callback.call(memoryBean.getObjectPendingFinalizationCount()))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_USED_BYTES)
    -                .withHelp("Used bytes of a given JVM memory area.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("area")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_USED_BYTES)
    +                .help("Used bytes of a given JVM memory area.")
    +                .unit(Unit.BYTES)
    +                .labelNames("area")
    +                .callback(callback -> {
                         callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap");
                         callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap");
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_COMMITTED_BYTES)
    -                .withHelp("Committed (bytes) of a given JVM memory area.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("area")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_COMMITTED_BYTES)
    +                .help("Committed (bytes) of a given JVM memory area.")
    +                .unit(Unit.BYTES)
    +                .labelNames("area")
    +                .callback(callback -> {
                         callback.call(memoryBean.getHeapMemoryUsage().getCommitted(), "heap");
                         callback.call(memoryBean.getNonHeapMemoryUsage().getCommitted(), "nonheap");
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_MAX_BYTES)
    -                .withHelp("Max (bytes) of a given JVM memory area.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("area")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_MAX_BYTES)
    +                .help("Max (bytes) of a given JVM memory area.")
    +                .unit(Unit.BYTES)
    +                .labelNames("area")
    +                .callback(callback -> {
                         callback.call(memoryBean.getHeapMemoryUsage().getMax(), "heap");
                         callback.call(memoryBean.getNonHeapMemoryUsage().getMax(), "nonheap");
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_INIT_BYTES)
    -                .withHelp("Initial bytes of a given JVM memory area.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("area")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_INIT_BYTES)
    +                .help("Initial bytes of a given JVM memory area.")
    +                .unit(Unit.BYTES)
    +                .labelNames("area")
    +                .callback(callback -> {
                         callback.call(memoryBean.getHeapMemoryUsage().getInit(), "heap");
                         callback.call(memoryBean.getNonHeapMemoryUsage().getInit(), "nonheap");
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_USED_BYTES)
    -                .withHelp("Used bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getUsed))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_USED_BYTES)
    +                .help("Used bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getUsed))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_COMMITTED_BYTES)
    -                .withHelp("Committed bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getCommitted))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_COMMITTED_BYTES)
    +                .help("Committed bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getCommitted))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_MAX_BYTES)
    -                .withHelp("Max bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getMax))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_MAX_BYTES)
    +                .help("Max bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getMax))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_INIT_BYTES)
    -                .withHelp("Initial bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getInit))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_INIT_BYTES)
    +                .help("Initial bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getInit))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_COLLECTION_USED_BYTES)
    -                .withHelp("Used bytes after last collection of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getUsed))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_COLLECTION_USED_BYTES)
    +                .help("Used bytes after last collection of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getUsed))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES)
    -                .withHelp("Committed after last collection bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getCommitted))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES)
    +                .help("Committed after last collection bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getCommitted))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES)
    -                .withHelp("Max bytes after last collection of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getMax))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES)
    +                .help("Max bytes after last collection of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getMax))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES)
    -                .withHelp("Initial after last collection bytes of a given JVM memory pool.")
    -                .withUnit(Unit.BYTES)
    -                .withLabelNames("pool")
    -                .withCallback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getInit))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES)
    +                .help("Initial after last collection bytes of a given JVM memory pool.")
    +                .unit(Unit.BYTES)
    +                .labelNames("pool")
    +                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getInit))
                     .register(registry);
         }
     
    @@ -251,11 +251,11 @@ private Consumer makeCallback(List
             };
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
    index 3adf4d2dc..522a2ef81 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
    @@ -20,11 +20,11 @@
     /**
      * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them directly: *
    {@code
    - *   JvmMemoryAllocationMetrics.newBuilder().register();
    + *   JvmMemoryAllocationMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -52,10 +52,10 @@ private JvmMemoryPoolAllocationMetrics(List garbageColle
     
         private void register(PrometheusRegistry registry) {
     
    -        Counter allocatedCounter = Counter.newBuilder()
    -                .withName(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL)
    -                .withHelp("Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.")
    -                .withLabelNames("pool")
    +        Counter allocatedCounter = Counter.builder()
    +                .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL)
    +                .help("Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.")
    +                .labelNames("pool")
                     .register(registry);
     
             AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter);
    @@ -120,7 +120,7 @@ void handleMemoryPool(String memoryPool, long before, long after) {
                 }
                 long increase = diff1 + diff2;
                 if (increase > 0) {
    -                counter.withLabelValues(memoryPool).inc(increase);
    +                counter.labelValues(memoryPool).inc(increase);
                 }
             }
     
    @@ -130,11 +130,11 @@ private static long getAndSet(Map map, String key, long value) {
             }
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
    index 841fc84e2..32602bd69 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
    @@ -8,21 +8,21 @@
     /**
      * Registers all JVM metrics. Example usage:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    */ public class JvmMetrics { private static AtomicBoolean registeredWithTheDefaultRegistry = new AtomicBoolean(false); - public static Builder newBuilder() { + public static Builder builder() { return new Builder(PrometheusProperties.get()); } // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you pass a config or not. // However, we will add config options in the future, like whether you want to use Prometheus naming conventions //'or OpenTelemetry semantic conventions for JVM metrics. - public static Builder newBuilder(PrometheusProperties config) { + public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -53,15 +53,15 @@ public void register() { * throw an Exception because you are trying to register duplicate metrics. */ public void register(PrometheusRegistry registry) { - JvmThreadsMetrics.newBuilder(config).register(registry); - JvmBufferPoolMetrics.newBuilder(config).register(registry); - JvmClassLoadingMetrics.newBuilder(config).register(registry); - JvmCompilationMetrics.newBuilder(config).register(registry); - JvmGarbageCollectorMetrics.newBuilder(config).register(registry); - JvmMemoryPoolAllocationMetrics.newBuilder(config).register(registry); - JvmMemoryMetrics.newBuilder(config).register(registry); - JvmRuntimeInfoMetric.newBuilder(config).register(registry); - ProcessMetrics.newBuilder(config).register(registry); + JvmThreadsMetrics.builder(config).register(registry); + JvmBufferPoolMetrics.builder(config).register(registry); + JvmClassLoadingMetrics.builder(config).register(registry); + JvmCompilationMetrics.builder(config).register(registry); + JvmGarbageCollectorMetrics.builder(config).register(registry); + JvmMemoryPoolAllocationMetrics.builder(config).register(registry); + JvmMemoryMetrics.builder(config).register(registry); + JvmRuntimeInfoMetric.builder(config).register(registry); + ProcessMetrics.builder(config).register(registry); } } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java index 3f1771ac2..c7024b14e 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java @@ -7,11 +7,11 @@ /** * JVM Runtime Info metric. The {@link JvmRuntimeInfoMetric} is registered as part of the {@link JvmMetrics} like this: *
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmRuntimeInfoMetric} you can also register them directly: *
    {@code
    - *   JvmRuntimeInfoMetric.newBuilder().register();
    + *   JvmRuntimeInfoMetric.builder().register();
      * }
    * *
    @@ -38,20 +38,20 @@ private JvmRuntimeInfoMetric(String version, String vendor, String runtime, Prom
     
         private void register(PrometheusRegistry registry) {
     
    -        Info jvmInfo = Info.newBuilder(config)
    -                .withName(JVM_RUNTIME_INFO)
    -                .withHelp("JVM runtime info")
    -                .withLabelNames("version", "vendor", "runtime")
    +        Info jvmInfo = Info.builder(config)
    +                .name(JVM_RUNTIME_INFO)
    +                .help("JVM runtime info")
    +                .labelNames("version", "vendor", "runtime")
                     .register(registry);
     
             jvmInfo.setLabelValues(version, vendor, runtime);
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -69,7 +69,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withVersion(String version) {
    +        Builder version(String version) {
                 this.version = version;
                 return this;
             }
    @@ -77,7 +77,7 @@ Builder withVersion(String version) {
             /**
              * Package private. For testing only.
              */
    -        Builder withVendor(String vendor) {
    +        Builder vendor(String vendor) {
                 this.vendor = vendor;
                 return this;
             }
    @@ -85,7 +85,7 @@ Builder withVendor(String vendor) {
             /**
              * Package private. For testing only.
              */
    -        Builder withRuntime(String runtime) {
    +        Builder runtime(String runtime) {
                 this.runtime = runtime;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
    index 55f07133d..d38c50a54 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
    @@ -15,11 +15,11 @@
     /**
      * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link JvmMetrics} like this:
      * 
    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link JvmThreadsMetrics} you can also register them directly: *
    {@code
    - *   JvmThreadMetrics.newBuilder().register();
    + *   JvmThreadMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -75,49 +75,49 @@ private JvmThreadsMetrics(boolean isNativeImage, ThreadMXBean threadBean, Promet
     
         private void register(PrometheusRegistry registry) {
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_THREADS_CURRENT)
    -                .withHelp("Current thread count of a JVM")
    -                .withCallback(callback -> callback.call(threadBean.getThreadCount()))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_THREADS_CURRENT)
    +                .help("Current thread count of a JVM")
    +                .callback(callback -> callback.call(threadBean.getThreadCount()))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_THREADS_DAEMON)
    -                .withHelp("Daemon thread count of a JVM")
    -                .withCallback(callback -> callback.call(threadBean.getDaemonThreadCount()))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_THREADS_DAEMON)
    +                .help("Daemon thread count of a JVM")
    +                .callback(callback -> callback.call(threadBean.getDaemonThreadCount()))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(JVM_THREADS_PEAK)
    -                .withHelp("Peak thread count of a JVM")
    -                .withCallback(callback -> callback.call(threadBean.getPeakThreadCount()))
    +        GaugeWithCallback.builder(config)
    +                .name(JVM_THREADS_PEAK)
    +                .help("Peak thread count of a JVM")
    +                .callback(callback -> callback.call(threadBean.getPeakThreadCount()))
                     .register(registry);
     
    -        CounterWithCallback.newBuilder(config)
    -                .withName(JVM_THREADS_STARTED_TOTAL)
    -                .withHelp("Started thread count of a JVM")
    -                .withCallback(callback -> callback.call(threadBean.getTotalStartedThreadCount()))
    +        CounterWithCallback.builder(config)
    +                .name(JVM_THREADS_STARTED_TOTAL)
    +                .help("Started thread count of a JVM")
    +                .callback(callback -> callback.call(threadBean.getTotalStartedThreadCount()))
                     .register(registry);
     
             if (!isNativeImage) {
    -            GaugeWithCallback.newBuilder(config)
    -                    .withName(JVM_THREADS_DEADLOCKED)
    -                    .withHelp("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers")
    -                    .withCallback(callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads())))
    +            GaugeWithCallback.builder(config)
    +                    .name(JVM_THREADS_DEADLOCKED)
    +                    .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers")
    +                    .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads())))
                         .register(registry);
     
    -            GaugeWithCallback.newBuilder(config)
    -                    .withName(JVM_THREADS_DEADLOCKED_MONITOR)
    -                    .withHelp("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors")
    -                    .withCallback(callback -> callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())))
    +            GaugeWithCallback.builder(config)
    +                    .name(JVM_THREADS_DEADLOCKED_MONITOR)
    +                    .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors")
    +                    .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())))
                         .register(registry);
     
     
    -            GaugeWithCallback.newBuilder(config)
    -                    .withName(JVM_THREADS_STATE)
    -                    .withHelp("Current count of threads by state")
    -                    .withLabelNames("state")
    -                    .withCallback(callback -> {
    +            GaugeWithCallback.builder(config)
    +                    .name(JVM_THREADS_STATE)
    +                    .help("Current count of threads by state")
    +                    .labelNames("state")
    +                    .callback(callback -> {
                             Map threadStateCounts = getThreadStateCountMap(threadBean);
                             for (Map.Entry entry : threadStateCounts.entrySet()) {
                                 callback.call(entry.getValue(), entry.getKey());
    @@ -168,11 +168,11 @@ private double nullSafeArrayLength(long[] array) {
             return null == array ? 0 : array.length;
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -189,7 +189,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withThreadBean(ThreadMXBean threadBean) {
    +        Builder threadBean(ThreadMXBean threadBean) {
                 this.threadBean = threadBean;
                 return this;
             }
    @@ -197,7 +197,7 @@ Builder withThreadBean(ThreadMXBean threadBean) {
             /**
              * Package private. For testing only.
              */
    -        Builder withIsNativeImage(boolean isNativeImage) {
    +        Builder isNativeImage(boolean isNativeImage) {
                 this.isNativeImage = isNativeImage;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
    index 478a17ca7..19c9c4bb0 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
    @@ -28,11 +28,11 @@
      * 

    * The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: *

    {@code
    - *   JvmMetrics.newBuilder().register();
    + *   JvmMetrics.builder().register();
      * }
    * However, if you want only the {@link ProcessMetrics} you can also register them directly: *
    {@code
    - *   ProcessMetrics.newBuilder().register();
    + *   ProcessMetrics.builder().register();
      * }
    * Example metrics being exported: *
    @@ -83,11 +83,11 @@ private ProcessMetrics(OperatingSystemMXBean osBean, RuntimeMXBean runtimeBean,
     
         private void register(PrometheusRegistry registry) {
     
    -        CounterWithCallback.newBuilder(config)
    -                .withName(PROCESS_CPU_SECONDS_TOTAL)
    -                .withHelp("Total user and system CPU time spent in seconds.")
    -                .withUnit(Unit.SECONDS)
    -                .withCallback(callback -> {
    +        CounterWithCallback.builder(config)
    +                .name(PROCESS_CPU_SECONDS_TOTAL)
    +                .help("Total user and system CPU time spent in seconds.")
    +                .unit(Unit.SECONDS)
    +                .callback(callback -> {
                         try {
                             // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean interfaces, in
                             // com.sun.management and com.ibm.lang.management. Hence use reflection and recursively go
    @@ -101,17 +101,17 @@ private void register(PrometheusRegistry registry) {
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(PROCESS_START_TIME_SECONDS)
    -                .withHelp("Start time of the process since unix epoch in seconds.")
    -                .withUnit(Unit.SECONDS)
    -                .withCallback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime())))
    +        GaugeWithCallback.builder(config)
    +                .name(PROCESS_START_TIME_SECONDS)
    +                .help("Start time of the process since unix epoch in seconds.")
    +                .unit(Unit.SECONDS)
    +                .callback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime())))
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(PROCESS_OPEN_FDS)
    -                .withHelp("Number of open file descriptors.")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(PROCESS_OPEN_FDS)
    +                .help("Number of open file descriptors.")
    +                .callback(callback -> {
                         try {
                             Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean);
                             if (openFds != null) {
    @@ -122,10 +122,10 @@ private void register(PrometheusRegistry registry) {
                     })
                     .register(registry);
     
    -        GaugeWithCallback.newBuilder(config)
    -                .withName(PROCESS_MAX_FDS)
    -                .withHelp("Maximum number of open file descriptors.")
    -                .withCallback(callback -> {
    +        GaugeWithCallback.builder(config)
    +                .name(PROCESS_MAX_FDS)
    +                .help("Maximum number of open file descriptors.")
    +                .callback(callback -> {
                         try {
                             Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean);
                             if (maxFds != null) {
    @@ -138,11 +138,11 @@ private void register(PrometheusRegistry registry) {
     
             if (linux) {
     
    -            GaugeWithCallback.newBuilder(config)
    -                    .withName(PROCESS_VIRTUAL_MEMORY_BYTES)
    -                    .withHelp("Virtual memory size in bytes.")
    -                    .withUnit(Unit.BYTES)
    -                    .withCallback(callback -> {
    +            GaugeWithCallback.builder(config)
    +                    .name(PROCESS_VIRTUAL_MEMORY_BYTES)
    +                    .help("Virtual memory size in bytes.")
    +                    .unit(Unit.BYTES)
    +                    .callback(callback -> {
                             try {
                                 String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:");
                                 callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
    @@ -151,11 +151,11 @@ private void register(PrometheusRegistry registry) {
                         })
                         .register(registry);
     
    -            GaugeWithCallback.newBuilder(config)
    -                    .withName(PROCESS_RESIDENT_MEMORY_BYTES)
    -                    .withHelp("Resident memory size in bytes.")
    -                    .withUnit(Unit.BYTES)
    -                    .withCallback(callback -> {
    +            GaugeWithCallback.builder(config)
    +                    .name(PROCESS_RESIDENT_MEMORY_BYTES)
    +                    .help("Resident memory size in bytes.")
    +                    .unit(Unit.BYTES)
    +                    .callback(callback -> {
                             try {
                                 String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:");
                                 callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
    @@ -228,11 +228,11 @@ public String lineStartingWith(File file, String prefix) throws IOException {
             }
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder(PrometheusProperties.get());
         }
     
    -    public static Builder newBuilder(PrometheusProperties config) {
    +    public static Builder builder(PrometheusProperties config) {
             return new Builder(config);
         }
     
    @@ -250,7 +250,7 @@ private Builder(PrometheusProperties config) {
             /**
              * Package private. For testing only.
              */
    -        Builder withOsBean(OperatingSystemMXBean osBean) {
    +        Builder osBean(OperatingSystemMXBean osBean) {
                 this.osBean = osBean;
                 return this;
             }
    @@ -258,7 +258,7 @@ Builder withOsBean(OperatingSystemMXBean osBean) {
             /**
              * Package private. For testing only.
              */
    -        Builder withRuntimeBean(RuntimeMXBean runtimeBean) {
    +        Builder runtimeBean(RuntimeMXBean runtimeBean) {
                 this.runtimeBean = runtimeBean;
                 return this;
             }
    @@ -266,7 +266,7 @@ Builder withRuntimeBean(RuntimeMXBean runtimeBean) {
             /**
              * Package private. For testing only.
              */
    -        Builder withGrepper(Grepper grepper) {
    +        Builder grepper(Grepper grepper) {
                 this.grepper = grepper;
                 return this;
             }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java
    index 84aec8561..16b59b85a 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java
    @@ -9,10 +9,10 @@ public class ExampleExporterForManualTesting {
     
         public static void main(String[] args) throws IOException, InterruptedException {
     
    -        JvmMetrics.newBuilder().register();
    +        JvmMetrics.builder().register();
     
    -        HTTPServer server = HTTPServer.newBuilder()
    -                .withPort(9400)
    +        HTTPServer server = HTTPServer.builder()
    +                .port(9400)
                     .buildAndStart();
     
             System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
    index 7adc64bf0..b8aafa0ea 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
    @@ -1,6 +1,5 @@
     package io.prometheus.metrics.instrumentation.jvm;
     
    -import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
     import io.prometheus.metrics.model.registry.MetricNameFilter;
     import io.prometheus.metrics.model.registry.PrometheusRegistry;
     import io.prometheus.metrics.model.snapshots.MetricSnapshots;
    @@ -9,10 +8,8 @@
     import org.junit.Test;
     import org.mockito.Mockito;
     
    -import java.io.ByteArrayOutputStream;
     import java.io.IOException;
     import java.lang.management.BufferPoolMXBean;
    -import java.nio.charset.StandardCharsets;
     import java.util.Arrays;
     
     import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
    @@ -40,8 +37,8 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmBufferPoolMetrics.newBuilder()
    -                        .withBufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer))
    +        JvmBufferPoolMetrics.builder()
    +                        .bufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer))
                                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -67,13 +64,13 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmBufferPoolMetrics.newBuilder()
    -                .withBufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer))
    +        JvmBufferPoolMetrics.builder()
    +                .bufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer))
                     .register(registry);
             registry.scrape(filter);
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
    index fa019258c..16413b839 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
    @@ -30,8 +30,8 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmClassLoadingMetrics.newBuilder()
    -                .withClassLoadingBean(mockClassLoadingBean)
    +        JvmClassLoadingMetrics.builder()
    +                .classLoadingBean(mockClassLoadingBean)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -52,13 +52,13 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_classes_currently_loaded")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmClassLoadingMetrics.newBuilder()
    -                .withClassLoadingBean(mockClassLoadingBean)
    +        JvmClassLoadingMetrics.builder()
    +                .classLoadingBean(mockClassLoadingBean)
                     .register(registry);
             registry.scrape(filter);
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
    index 1bde4873d..75ecc8370 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
    @@ -29,8 +29,8 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmCompilationMetrics.newBuilder()
    -                .withCompilationBean(mockCompilationBean)
    +        JvmCompilationMetrics.builder()
    +                .compilationBean(mockCompilationBean)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -46,13 +46,13 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmCompilationMetrics.newBuilder()
    -                .withCompilationBean(mockCompilationBean)
    +        JvmCompilationMetrics.builder()
    +                .compilationBean(mockCompilationBean)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape(filter);
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
    index 5b00e61b3..d7dad1787 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
    @@ -37,8 +37,8 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmGarbageCollectorMetrics.newBuilder()
    -                .withGarbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2))
    +        JvmGarbageCollectorMetrics.builder()
    +                .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2))
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -57,13 +57,13 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_gc_collection_seconds")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmGarbageCollectorMetrics.newBuilder()
    -                .withGarbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2))
    +        JvmGarbageCollectorMetrics.builder()
    +                .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2))
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape(filter);
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
    index 45da976bc..b70bb0bba 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
    @@ -81,7 +81,7 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmMemoryMetrics.newBuilder()
    +        JvmMemoryMetrics.builder()
                     .withMemoryBean(mockMemoryBean)
                     .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen))
                     .register(registry);
    @@ -158,12 +158,12 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_memory_pool_used_bytes")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmMemoryMetrics.newBuilder()
    +        JvmMemoryMetrics.builder()
                     .withMemoryBean(mockMemoryBean)
                     .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen))
                     .register(registry);
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
    index 19510da32..945ac5e27 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
    @@ -16,7 +16,7 @@ public class JvmMemoryPoolAllocationMetricsTest {
         @Test
         public void testListenerLogic() {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        Counter counter = Counter.newBuilder().withName("test").withLabelNames("pool").register(registry);
    +        Counter counter = Counter.builder().name("test").labelNames("pool").register(registry);
             AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(counter);
     
             // Increase by 123
    @@ -51,7 +51,7 @@ public void testListenerLogic() {
         private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) {
             for (MetricSnapshot snapshot : snapshots) {
                 if (snapshot.getMetadata().getPrometheusName().equals(metricName)) {
    -                for (CounterSnapshot.CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getData()) {
    +                for (CounterSnapshot.CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) {
                         if (data.getLabels().get("pool").equals(poolName)) {
                             return data.getValue();
                         }
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
    index db611c4d1..0c4dd786a 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
    @@ -14,10 +14,10 @@ public class JvmRuntimeInfoMetricTest {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmRuntimeInfoMetric.newBuilder()
    -                .withVersion("1.8.0_382-b05")
    -                .withVendor("Oracle Corporation")
    -                .withRuntime("OpenJDK Runtime Environment")
    +        JvmRuntimeInfoMetric.builder()
    +                .version("1.8.0_382-b05")
    +                .vendor("Oracle Corporation")
    +                .runtime("OpenJDK Runtime Environment")
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
    index 73832c303..e88e86811 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
    @@ -49,9 +49,9 @@ public void setUp() {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmThreadsMetrics.newBuilder()
    -                .withThreadBean(mockThreadsBean)
    -                .withIsNativeImage(false)
    +        JvmThreadsMetrics.builder()
    +                .threadBean(mockThreadsBean)
    +                .isNativeImage(false)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -90,14 +90,14 @@ public void testGoodCase() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("jvm_threads_deadlocked")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmThreadsMetrics.newBuilder()
    -                .withThreadBean(mockThreadsBean)
    -                .withIsNativeImage(false)
    +        JvmThreadsMetrics.builder()
    +                .threadBean(mockThreadsBean)
    +                .isNativeImage(false)
                     .register(registry);
             registry.scrape(filter);
     
    @@ -108,7 +108,7 @@ public void testIgnoredMetricNotScraped() {
         @Test
         public void testInvalidThreadIds() {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        JvmThreadsMetrics.newBuilder().register(registry);
    +        JvmThreadsMetrics.builder().register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
             // Number of threads to create with invalid thread ids
    @@ -142,7 +142,7 @@ private Map getCountByState(MetricSnapshots snapshots) {
             Map result = new HashMap<>();
             for (MetricSnapshot snapshot : snapshots) {
                 if (snapshot.getMetadata().getName().equals("jvm_threads_state")) {
    -                for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getData()) {
    +                for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) {
                         String state = data.getLabels().get("state");
                         Assert.assertNotNull(state);
                         result.put(state, data.getValue());
    diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
    index 23e030419..e3304f4d9 100644
    --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
    +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
    @@ -40,10 +40,10 @@ public void setUp() throws IOException {
         @Test
         public void testGoodCase() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        ProcessMetrics.newBuilder()
    -                        .withOsBean(sunOsBean)
    -                                .withRuntimeBean(runtimeBean)
    -                .withGrepper(linuxGrepper)
    +        ProcessMetrics.builder()
    +                        .osBean(sunOsBean)
    +                                .runtimeBean(runtimeBean)
    +                .grepper(linuxGrepper)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -78,10 +78,10 @@ public void testGoodCase() throws IOException {
         @Test
         public void testMinimal() throws IOException {
             PrometheusRegistry registry = new PrometheusRegistry();
    -        ProcessMetrics.newBuilder()
    -                .withOsBean(javaOsBean)
    -                .withRuntimeBean(runtimeBean)
    -                .withGrepper(windowsGrepper)
    +        ProcessMetrics.builder()
    +                .osBean(javaOsBean)
    +                .runtimeBean(runtimeBean)
    +                .grepper(windowsGrepper)
                     .register(registry);
             MetricSnapshots snapshots = registry.scrape();
     
    @@ -97,15 +97,15 @@ public void testMinimal() throws IOException {
     
         @Test
         public void testIgnoredMetricNotScraped() {
    -        MetricNameFilter filter = MetricNameFilter.newBuilder()
    +        MetricNameFilter filter = MetricNameFilter.builder()
                     .nameMustNotBeEqualTo("process_max_fds")
                     .build();
     
             PrometheusRegistry registry = new PrometheusRegistry();
    -        ProcessMetrics.newBuilder()
    -                .withOsBean(sunOsBean)
    -                .withRuntimeBean(runtimeBean)
    -                .withGrepper(linuxGrepper)
    +        ProcessMetrics.builder()
    +                .osBean(sunOsBean)
    +                .runtimeBean(runtimeBean)
    +                .grepper(linuxGrepper)
                     .register(registry);
             registry.scrape(filter);
     
    diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java
    index e8e8c1621..c0c345a1b 100644
    --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java
    +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java
    @@ -89,7 +89,7 @@ private boolean matchesNameDoesNotStartWith(String metricName) {
             return false;
         }
     
    -    public static Builder newBuilder() {
    +    public static Builder builder() {
             return new Builder();
         }
     
    diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java
    index 8e5aff15f..92fcf9012 100644
    --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java
    +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java
    @@ -7,8 +7,6 @@
     import java.util.function.Predicate;
     import java.util.stream.Collectors;
     
    -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
    -
     /**
      * Like {@link Collector}, but collecting multiple Snapshots at once.
      */
    @@ -27,10 +25,10 @@ public interface MultiCollector {
          */
         default MetricSnapshots collect(Predicate includedNames) {
             MetricSnapshots allSnapshots = collect();
    -        MetricSnapshots.Builder result = MetricSnapshots.newBuilder();
    +        MetricSnapshots.Builder result = MetricSnapshots.builder();
             for (MetricSnapshot snapshot : allSnapshots) {
                 if (includedNames.test(snapshot.getMetadata().getPrometheusName())) {
    -                result.addMetricSnapshot(snapshot);
    +                result.metricSnapshot(snapshot);
                 }
             }
             return result.build();
    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 d85e87b7a..21665499d 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
    @@ -51,14 +51,14 @@ public void unregister(MultiCollector collector) {
         }
     
         public MetricSnapshots scrape() {
    -        MetricSnapshots.Builder result = MetricSnapshots.newBuilder();
    +        MetricSnapshots.Builder result = MetricSnapshots.builder();
             for (Collector collector : collectors) {
                 MetricSnapshot snapshot = collector.collect();
                 if (snapshot != null) {
                     if (result.containsMetricName(snapshot.getMetadata().getName())) {
                         throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
                     }
    -                result.addMetricSnapshot(snapshot);
    +                result.metricSnapshot(snapshot);
                 }
             }
             for (MultiCollector collector : multiCollectors) {
    @@ -66,7 +66,7 @@ public MetricSnapshots scrape() {
                     if (result.containsMetricName(snapshot.getMetadata().getName())) {
                         throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
                     }
    -                result.addMetricSnapshot(snapshot);
    +                result.metricSnapshot(snapshot);
                 }
             }
             return result.build();
    @@ -76,13 +76,13 @@ public MetricSnapshots scrape(Predicate includedNames) {
             if (includedNames == null) {
                 return scrape();
             }
    -        MetricSnapshots.Builder result = MetricSnapshots.newBuilder();
    +        MetricSnapshots.Builder result = MetricSnapshots.builder();
             for (Collector collector : collectors) {
                 String prometheusName = collector.getPrometheusName();
                 if (prometheusName == null || includedNames.test(prometheusName)) {
                     MetricSnapshot snapshot = collector.collect(includedNames);
                     if (snapshot != null) {
    -                    result.addMetricSnapshot(snapshot);
    +                    result.metricSnapshot(snapshot);
                     }
                 }
             }
    @@ -98,7 +98,7 @@ public MetricSnapshots scrape(Predicate includedNames) {
                 if (!excluded) {
                     for (MetricSnapshot snapshot : collector.collect(includedNames)) {
                         if (snapshot != null) {
    -                        result.addMetricSnapshot(snapshot);
    +                        result.metricSnapshot(snapshot);
                         }
                     }
                 }
    diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java
    index cd20eb4e8..4d7c6d279 100644
    --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java
    +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java
    @@ -28,7 +28,7 @@ private ClassicHistogramBuckets(double[] upperBounds, long[] counts) {
     
         /**
          * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods,
    -     * or use {@link ClassicHistogramBuckets#newBuilder()}.
    +     * or use {@link ClassicHistogramBuckets#builder()}.
          * 

    * This method will create a copy of upperBounds and counts. * @@ -56,7 +56,7 @@ public static ClassicHistogramBuckets of(List upperBounds, List * This method will create a copy of upperBounds and counts. * @@ -81,7 +81,7 @@ public static ClassicHistogramBuckets of(double[] upperBounds, Number[] counts) /** * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@link ClassicHistogramBuckets#newBuilder()}. + * or use {@link ClassicHistogramBuckets#builder()}. *

    * This method will create a copy of upperBounds and counts. * @@ -192,9 +192,9 @@ public Stream stream() { /** * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@code newBuilder()}. + * or use {@code builder()}. */ - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -207,7 +207,7 @@ private Builder() {} /** * Must be called at least once for the {@link Double#POSITIVE_INFINITY} bucket. */ - public Builder addBucket(double upperBound, long count) { + public Builder bucket(double upperBound, long count) { upperBounds.add(upperBound); counts.add(count); return this; diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java index e994e9513..e62aeb9f8 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -11,19 +11,19 @@ public class CounterSnapshot extends MetricSnapshot { /** * To create a new {@link CounterSnapshot}, you can either call the constructor directly or use - * the builder with {@link CounterSnapshot#newBuilder()}. + * the builder with {@link CounterSnapshot#builder()}. * - * @param metadata the metric name in metadata must not include the {@code _total} suffix. - * See {@link MetricMetadata} for more naming conventions. - * @param data the constructor will create a sorted copy of the collection. + * @param metadata the metric name in metadata must not include the {@code _total} suffix. + * See {@link MetricMetadata} for more naming conventions. + * @param dataPoints the constructor will create a sorted copy of the collection. */ - public CounterSnapshot(MetricMetadata metadata, Collection data) { - super(metadata, data); + public CounterSnapshot(MetricMetadata metadata, Collection dataPoints) { + super(metadata, dataPoints); } @Override - public List getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static class CounterDataPointSnapshot extends DataPointSnapshot { @@ -33,7 +33,7 @@ public static class CounterDataPointSnapshot extends DataPointSnapshot { /** * To create a new {@link CounterDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link CounterDataPointSnapshot#newBuilder()}. + * Builder with {@link CounterDataPointSnapshot#builder()}. * * @param value the counter value. Must not be negative. * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. @@ -75,6 +75,10 @@ protected void validate() { } } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DataPointSnapshot.Builder { private Exemplar exemplar = null; @@ -87,17 +91,17 @@ private Builder() { /** * Counter value. This is required. The value must not be negative. */ - public Builder withValue(double value) { + public Builder value(double value) { this.value = value; return this; } - public Builder withExemplar(Exemplar exemplar) { + public Builder exemplar(Exemplar exemplar) { this.exemplar = exemplar; return this; } - public Builder withCreatedTimestampMillis(long createdTimestampMillis) { + public Builder createdTimestampMillis(long createdTimestampMillis) { this.createdTimestampMillis = createdTimestampMillis; return this; } @@ -114,10 +118,10 @@ protected Builder self() { return this; } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -127,8 +131,11 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(CounterDataPointSnapshot data) { - dataPoints.add(data); + /** + * Add a data point. Can be called multiple times to add multiple data points. + */ + public Builder dataPoint(CounterDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); return this; } @@ -141,8 +148,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java index b4241e2e4..7710754e2 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java @@ -62,17 +62,17 @@ public static abstract class Builder> { protected Labels labels = Labels.EMPTY; protected long scrapeTimestampMillis = 0L; - public T withLabels(Labels labels) { + public T labels(Labels labels) { this.labels = labels; return self(); } /** - * In most cases you should not need to set a timestamp, because the timestamp of a Prometheus metric should - * usually be set by the Prometheus server during scraping. + * In most cases you should not set a scrape timestamp, + * because the scrape timestamp is set by the Prometheus server during scraping. * Exceptions include mirroring metrics with given timestamps from other metric sources. */ - public T withScrapeTimestampMillis(long scrapeTimestampMillis) { + public T scrapeTimestampMillis(long scrapeTimestampMillis) { this.scrapeTimestampMillis = scrapeTimestampMillis; return self(); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java index 5536f01e9..fe5f729c1 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java @@ -66,22 +66,22 @@ static abstract class Builder> extends DataPointSnapshot.Bu * Count can be explicitly set on summaries (this is a public method for summary metrics), * and it is set implicitly on histograms (derived from the bucket counts). */ - protected T withCount(long count) { + protected T count(long count) { this.count = count; return self(); } - public T withSum(double sum) { + public T sum(double sum) { this.sum = sum; return self(); } - public T withExemplars(Exemplars exemplars) { + public T exemplars(Exemplars exemplars) { this.exemplars = exemplars; return self(); } - public T withCreatedTimestampMillis(long createdTimestampMillis) { + public T createdTimestampMillis(long createdTimestampMillis) { this.createdTimestampMillis = createdTimestampMillis; return self(); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java index c9865aac5..aa46bd229 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java @@ -21,7 +21,7 @@ public class Exemplar { /** * To create a new {@link Exemplar}, you can either call the constructor directly - * or use the Builder with {@link Exemplar#newBuilder()}. + * or use the Builder with {@link Exemplar#builder()}. * * @param value the observed value. This is required. * @param labels in most cases the labels will contain the {@link #TRACE_ID} and {@link #SPAN_ID}. @@ -60,7 +60,7 @@ public long getTimestampMillis() { return timestampMillis; } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -75,22 +75,22 @@ public static class Builder { private Builder() { } - public Builder withValue(double value) { + public Builder value(double value) { this.value = value; return this; } - public Builder withTraceId(String traceId) { + public Builder traceId(String traceId) { this.traceId = traceId; return this; } - public Builder withSpanId(String spanId) { + public Builder spanId(String spanId) { this.spanId = spanId; return this; } - public Builder withLabels(Labels labels) { + public Builder labels(Labels labels) { if (labels == null) { throw new NullPointerException(); } @@ -98,13 +98,13 @@ public Builder withLabels(Labels labels) { return this; } - public Builder withTimestampMillis(long timestampMillis) { + public Builder timestampMillis(long timestampMillis) { this.timestampMillis = timestampMillis; return this; } /** - * @throws IllegalStateException if {@link #withValue(double)} wasn't called. + * @throws IllegalStateException if {@link #value(double)} wasn't called. */ public Exemplar build() { if (value == null) { 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 641d0e573..dc77be55a 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 @@ -27,7 +27,7 @@ private Exemplars(Collection 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#newBuilder()}. + * or you can use the {@link Exemplars#builder()}. * * @param exemplars a copy of the exemplars collection will be created. */ @@ -38,7 +38,7 @@ public static Exemplars of(Collection 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#newBuilder()}. + * or you can use the {@link Exemplars#builder()}. * * @param exemplars a copy of the exemplars array will be created. */ @@ -100,6 +100,10 @@ public Exemplar getLatest() { return latest; } + public static Builder builder() { + return new Builder(); + } + public static class Builder { private final ArrayList exemplars = new ArrayList<>(); @@ -107,12 +111,18 @@ public static class Builder { private Builder() { } - public Builder addExemplar(Exemplar exemplar) { + /** + * Add an exemplar. This can be called multiple times to add multiple exemplars. + */ + public Builder exemplar(Exemplar exemplar) { exemplars.add(exemplar); return this; } - public Builder addExemplars(List exemplars) { + /** + * Add all exemplars form the collection. + */ + public Builder exemplars(Collection exemplars) { this.exemplars.addAll(exemplars); return this; } @@ -121,8 +131,4 @@ public Exemplars build() { return Exemplars.of(exemplars); } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java index 54c033d34..f69b8d2a6 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java @@ -11,7 +11,7 @@ public final class GaugeSnapshot extends MetricSnapshot { /** * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use - * the builder with {@link GaugeSnapshot#newBuilder()}. + * the builder with {@link GaugeSnapshot#builder()}. * * @param metadata see {@link MetricMetadata} for naming conventions. * @param data the constructor will create a sorted copy of the collection. @@ -21,8 +21,8 @@ public GaugeSnapshot(MetricMetadata metadata, Collection } @Override - public List getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static final class GaugeDataPointSnapshot extends DataPointSnapshot { @@ -32,7 +32,7 @@ public static final class GaugeDataPointSnapshot extends DataPointSnapshot { /** * To create a new {@link GaugeDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link GaugeDataPointSnapshot#newBuilder()}. + * Builder with {@link GaugeDataPointSnapshot#builder()}. * * @param value the gauge value. * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. @@ -64,6 +64,10 @@ public Exemplar getExemplar() { return exemplar; } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DataPointSnapshot.Builder { private Exemplar exemplar = null; @@ -75,7 +79,7 @@ private Builder() { /** * Gauge value. This is required. */ - public Builder withValue(double value) { + public Builder value(double value) { this.value = value; return this; } @@ -83,7 +87,7 @@ public Builder withValue(double value) { /** * Optional */ - public Builder withExemplar(Exemplar exemplar) { + public Builder exemplar(Exemplar exemplar) { this.exemplar = exemplar; return this; } @@ -100,10 +104,10 @@ protected Builder self() { return this; } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -113,8 +117,11 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(GaugeDataPointSnapshot data) { - dataPoints.add(data); + /** + * Add a data point. This can be alled multiple times to add multiple data points. + */ + public Builder dataPoint(GaugeDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); return this; } @@ -127,8 +134,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index 860b291c7..742105e64 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -14,7 +14,7 @@ public final class HistogramSnapshot extends MetricSnapshot { /** * To create a new {@link HistogramSnapshot}, you can either call the constructor directly or use - * the builder with {@link HistogramSnapshot#newBuilder()}. + * the builder with {@link HistogramSnapshot#builder()}. * * @param metadata see {@link MetricMetadata} for naming conventions. * @param data the constructor will create a sorted copy of the collection. @@ -39,8 +39,8 @@ public boolean isGaugeHistogram() { } @Override - public List getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static final class HistogramDataPointSnapshot extends DistributionDataPointSnapshot { @@ -69,7 +69,7 @@ public static final class HistogramDataPointSnapshot extends DistributionDataPoi * Constructor for classic histograms (as opposed to native histograms). *

    * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#newBuilder()}. + * Builder with {@link HistogramSnapshot#builder()}. * * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. @@ -92,7 +92,7 @@ public HistogramDataPointSnapshot( * Constructor for native histograms (as opposed to classic histograms). *

    * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#newBuilder()}. + * Builder with {@link HistogramSnapshot#builder()}. * * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. * @param nativeZeroCount number of observed zero values (zero is special because there is no @@ -125,7 +125,7 @@ public HistogramDataPointSnapshot( * Constructor for a histogram with both, classic and native data. *

    * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#newBuilder()}. + * Builder with {@link HistogramSnapshot#builder()}. * * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. @@ -298,6 +298,10 @@ private void validate() { } } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DistributionDataPointSnapshot.Builder { private ClassicHistogramBuckets classicHistogramBuckets = ClassicHistogramBuckets.EMPTY; @@ -315,32 +319,32 @@ protected Builder self() { return this; } - public Builder withClassicHistogramBuckets(ClassicHistogramBuckets classicBuckets) { + public Builder classicHistogramBuckets(ClassicHistogramBuckets classicBuckets) { this.classicHistogramBuckets = classicBuckets; return this; } - public Builder withNativeSchema(int nativeSchema) { + public Builder nativeSchema(int nativeSchema) { this.nativeSchema = nativeSchema; return this; } - public Builder withNativeZeroCount(long zeroCount) { + public Builder nativeZeroCount(long zeroCount) { this.nativeZeroCount = zeroCount; return this; } - public Builder withNativeZeroThreshold(double zeroThreshold) { + public Builder nativeZeroThreshold(double zeroThreshold) { this.nativeZeroThreshold = zeroThreshold; return this; } - public Builder withNativeBucketsForPositiveValues(NativeHistogramBuckets bucketsForPositiveValues) { + public Builder nativeBucketsForPositiveValues(NativeHistogramBuckets bucketsForPositiveValues) { this.nativeBucketsForPositiveValues = bucketsForPositiveValues; return this; } - public Builder withNativeBucketsForNegativeValues(NativeHistogramBuckets bucketsForNegativeValues) { + public Builder nativeBucketsForNegativeValues(NativeHistogramBuckets bucketsForNegativeValues) { this.nativeBucketsForNegativeValues = bucketsForNegativeValues; return this; } @@ -352,10 +356,10 @@ public HistogramDataPointSnapshot build() { return new HistogramDataPointSnapshot(classicHistogramBuckets, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -366,8 +370,11 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(HistogramDataPointSnapshot data) { - dataPoints.add(data); + /** + * Add a data point. Call multiple times to add multiple data points. + */ + public Builder dataPoint(HistogramDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); return this; } @@ -376,7 +383,7 @@ public Builder addDataPoint(HistogramDataPointSnapshot data) { * except that bucket values are semantically gauges and not counters. * See openmetrics.io for more info on Gauge Histograms. */ - public Builder asGaugeHistogram() { + public Builder gaugeHistogram() { isGaugeHistogram = true; return this; } @@ -390,8 +397,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java index dac311004..e24747181 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -11,7 +11,7 @@ public final class InfoSnapshot extends MetricSnapshot { /** * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use - * the builder with {@link InfoSnapshot#newBuilder()}. + * the builder with {@link InfoSnapshot#builder()}. * * @param metadata the metric name in metadata must not include the {@code _info} suffix. * See {@link MetricMetadata} for more naming conventions. @@ -26,15 +26,15 @@ public InfoSnapshot(MetricMetadata metadata, Collection d } @Override - public List getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static class InfoDataPointSnapshot extends DataPointSnapshot { /** * To create a new {@link InfoDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link InfoDataPointSnapshot#newBuilder()}. + * Builder with {@link InfoDataPointSnapshot#builder()}. * * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. */ @@ -51,8 +51,15 @@ public InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis) { super(labels, 0L, scrapeTimestampMillis); } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DataPointSnapshot.Builder { + private Builder() { + } + public InfoDataPointSnapshot build() { return new InfoDataPointSnapshot(labels, scrapeTimestampMillis); } @@ -62,10 +69,10 @@ protected Builder self() { return this; } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -75,13 +82,16 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(InfoDataPointSnapshot data) { - dataPoints.add(data); + /** + * Add a data point. Call multiple times for adding multiple data points. + */ + public Builder dataPoint(InfoDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); return this; } @Override - public Builder withUnit(Unit unit) { + public Builder unit(Unit unit) { throw new IllegalArgumentException("Info metric cannot have a unit."); } @@ -94,8 +104,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } 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 fd0b01e2a..67a0dcf1f 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 @@ -46,7 +46,7 @@ public boolean isEmpty() { /** * 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#newBuilder()}. + * 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. @@ -88,7 +88,7 @@ static String[] makePrometheusNames(String[] names) { /** * 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#newBuilder()}. + * 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 @@ -112,7 +112,7 @@ public static Labels of(List names, List values) { /** * 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#newBuilder()}. + * 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 @@ -413,7 +413,7 @@ public int hashCode() { return result; } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -424,7 +424,10 @@ public static class Builder { private Builder() { } - public Builder addLabel(String name, String value) { + /** + * 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; diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java index 7faaa6399..273b304eb 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -13,23 +13,23 @@ public abstract class MetricSnapshot { private final MetricMetadata metadata; - protected final List data; + protected final List dataPoints; - protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... data) { - this(metadata, Arrays.asList(data)); + protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... dataPoints) { + this(metadata, Arrays.asList(dataPoints)); } - protected MetricSnapshot(MetricMetadata metadata, Collection data) { + protected MetricSnapshot(MetricMetadata metadata, Collection dataPoints) { if (metadata == null) { throw new NullPointerException("metadata"); } - if (data == null) { - throw new NullPointerException("data"); + if (dataPoints == null) { + throw new NullPointerException("dataPoints"); } this.metadata = metadata; - List dataCopy = new ArrayList<>(data); + List dataCopy = new ArrayList<>(dataPoints); dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); - this.data = Collections.unmodifiableList(dataCopy); + this.dataPoints = Collections.unmodifiableList(dataCopy); validateLabels(); } @@ -37,13 +37,13 @@ public MetricMetadata getMetadata() { return metadata; } - public abstract List getData(); + public abstract List getDataPoints(); protected void validateLabels() { // Verify that labels are unique (the same set of names/values must not be used multiple times for the same metric). - for (int i = 0; i < data.size() - 1; i++) { - if (data.get(i).getLabels().equals(data.get(i + 1).getLabels())) { - throw new IllegalArgumentException("Duplicate labels in metric data: " + data.get(i).getLabels()); + for (int i = 0; i < dataPoints.size() - 1; i++) { + if (dataPoints.get(i).getLabels().equals(dataPoints.get(i + 1).getLabels())) { + throw new IllegalArgumentException("Duplicate labels in metric data: " + dataPoints.get(i).getLabels()); } } // Should we verify that all entries in data have the same label names? @@ -61,17 +61,17 @@ public static abstract class Builder> { * If the name is missing or invalid, {@code build()} will throw an {@link IllegalArgumentException}. * See {@link PrometheusNaming#isValidMetricName(String)} for info on valid metric names. */ - public T withName(String name) { + public T name(String name) { this.name = name; return self(); } - public T withHelp(String help) { + public T help(String help) { this.help = help; return self(); } - public T withUnit(Unit unit) { + public T unit(Unit unit) { this.unit = unit; return self(); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java index 5308e6f98..6fcf3fd25 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -27,13 +27,13 @@ public MetricSnapshots(MetricSnapshot... snapshots) { /** * To create MetricSnapshots, you can either call the constructor directly - * or use {@link #newBuilder()}. + * or use {@link #builder()}. * * @param snapshots the constructor creates a sorted copy of snapshots. * @throws IllegalArgumentException if snapshots contains duplicate metric names. - * To avoid duplicate metric names use {@link #newBuilder()} and check + * To avoid duplicate metric names use {@link #builder()} and check * {@link Builder#containsMetricName(String)} before calling - * {@link Builder#addMetricSnapshot(MetricSnapshot)}. + * {@link Builder#metricSnapshot(MetricSnapshot)}. */ public MetricSnapshots(Collection snapshots) { List list = new ArrayList<>(snapshots); @@ -67,7 +67,7 @@ public Stream stream() { return snapshots.stream(); } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -87,7 +87,10 @@ public boolean containsMetricName(String name) { return false; } - public Builder addMetricSnapshot(MetricSnapshot snapshot) { + /** + * Add a metric snapshot. Call multiple times to add multiple metric snapshots. + */ + public Builder metricSnapshot(MetricSnapshot snapshot) { snapshots.add(snapshot); return this; } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java index 6cad6a6a3..e4f722168 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java @@ -31,7 +31,7 @@ private NativeHistogramBuckets(int[] bucketIndexes, long[] counts) { /** * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)} - * methods, or use {@link NativeHistogramBuckets#newBuilder()}. + * methods, or use {@link NativeHistogramBuckets#builder()}. * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty. * @param counts must have the same length as bucketIndexes */ @@ -44,7 +44,7 @@ public static NativeHistogramBuckets of(int[] bucketIndexes, long[] counts) { /** * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)} - * methods, or use {@link NativeHistogramBuckets#newBuilder()}. + * methods, or use {@link NativeHistogramBuckets#builder()}. * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty. * @param counts must have the same size as bucketIndexes */ @@ -135,7 +135,7 @@ private static void validate(int[] bucketIndexes, long[] counts) { } } - public static Builder newBuilder() { + public static Builder builder() { return new Builder(); } @@ -146,7 +146,10 @@ public static class Builder { private Builder() {} - public Builder addBucket(int bucketIndex, long count) { + /** + * Add a native histogram bucket. Call multiple times to add multiple buckets. + */ + public Builder bucket(int bucketIndex, long count) { bucketIndexes.add(bucketIndex); counts.add(count); return this; 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 1ad7002d2..e4a7b3621 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 @@ -28,7 +28,7 @@ private void validate() { /** * 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#newBuilder()}. + * or you can use the {@link Quantiles#builder()}. */ public static Quantiles of(List quantiles) { return new Quantiles(quantiles); @@ -37,7 +37,7 @@ public static Quantiles of(List 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#newBuilder()}. + * or you can use the {@link Quantiles#builder()}. */ public static Quantiles of(Quantile... quantiles) { return of(Arrays.asList(quantiles)); @@ -56,20 +56,30 @@ 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() {} - public Builder addQuantile(Quantile quantile) { + 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 addQuantile(double quantile, double value) { + public Builder quantile(double quantile, double value) { quantiles.add(new Quantile(quantile, value)); return this; } @@ -79,7 +89,4 @@ public Quantiles build() { } } - public static Builder newBuilder() { - return new Builder(); - } } 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 9b0c4f07d..2a6094354 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 @@ -15,7 +15,7 @@ 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#newBuilder()}. + * 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. @@ -29,7 +29,7 @@ private void validate() { if (getMetadata().hasUnit()) { throw new IllegalArgumentException("An state set metric cannot have a unit."); } - for (StateSetDataPointSnapshot entry : getData()) { + for (StateSetDataPointSnapshot entry : getDataPoints()) { if (entry.getLabels().contains(getMetadata().getPrometheusName())) { throw new IllegalArgumentException("Label name " + getMetadata().getPrometheusName() + " is reserved."); } @@ -37,8 +37,8 @@ private void validate() { } @Override - public List getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } @@ -48,7 +48,7 @@ public static class StateSetDataPointSnapshot extends DataPointSnapshot implemen /** * To create a new {@link StateSetDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link StateSetDataPointSnapshot#newBuilder()}. + * Builder with {@link StateSetDataPointSnapshot#builder()}. * * @param names state names. Must have at least 1 entry. * The constructor will create a copy of the array. @@ -142,6 +142,10 @@ private static void swap(int i, int j, String[] names, boolean[] values) { values[i] = tmpValue; } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DataPointSnapshot.Builder { private final ArrayList names = new ArrayList<>(); @@ -149,7 +153,10 @@ public static class Builder extends DataPointSnapshot.Builder { private Builder() {} - public Builder addState(String name, boolean value) { + /** + * 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; @@ -168,10 +175,6 @@ public StateSetDataPointSnapshot build() { return new StateSetDataPointSnapshot(names.toArray(new String[]{}), valuesArray, labels, scrapeTimestampMillis); } } - - public static Builder newBuilder() { - return new Builder(); - } } public static class State { @@ -192,6 +195,10 @@ public boolean isTrue() { } } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends MetricSnapshot.Builder { private final List dataPoints = new ArrayList<>(); @@ -199,13 +206,16 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(StateSetDataPointSnapshot data) { - dataPoints.add(data); + /** + * Add a data point. Call multiple times to add multiple data points. + */ + public Builder dataPoint(StateSetDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); return this; } @Override - public Builder withUnit(Unit unit) { + public Builder unit(Unit unit) { throw new IllegalArgumentException("StateSet metric cannot have a unit."); } @@ -218,8 +228,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java index cf84162a7..16682dbae 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java @@ -11,7 +11,7 @@ public final class SummarySnapshot extends MetricSnapshot { /** * To create a new {@link SummarySnapshot}, you can either call the constructor directly or use - * the builder with {@link SummarySnapshot#newBuilder()}. + * the builder with {@link SummarySnapshot#builder()}. * * @param metadata See {@link MetricMetadata} for more naming conventions. * @param data the constructor will create a sorted copy of the collection. @@ -21,8 +21,8 @@ public SummarySnapshot(MetricMetadata metadata, Collection getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static final class SummaryDataPointSnapshot extends DistributionDataPointSnapshot { @@ -32,7 +32,7 @@ public static final class SummaryDataPointSnapshot extends DistributionDataPoint /** * To create a new {@link SummaryDataPointSnapshot}, you can either call the constructor directly - * or use the Builder with {@link SummaryDataPointSnapshot#newBuilder()}. + * or use the Builder with {@link SummaryDataPointSnapshot#builder()}. * * @param count total number of observations. Optional, pass -1 if not available. * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. @@ -75,6 +75,10 @@ private void validate() { } } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DistributionDataPointSnapshot.Builder { private Quantiles quantiles = Quantiles.EMPTY; @@ -87,14 +91,14 @@ protected Builder self() { return this; } - public Builder withQuantiles(Quantiles quantiles) { + public Builder quantiles(Quantiles quantiles) { this.quantiles = quantiles; return this; } @Override - public Builder withCount(long count) { - super.withCount(count); + public Builder count(long count) { + super.count(count); return this; } @@ -102,10 +106,10 @@ public SummaryDataPointSnapshot build() { return new SummaryDataPointSnapshot(count, sum, quantiles, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -115,7 +119,10 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(SummaryDataPointSnapshot data) { + /** + * Add a data point. Call multiple times to add multiple data points. + */ + public Builder dataPoint(SummaryDataPointSnapshot data) { dataPoints.add(data); return this; } @@ -129,8 +136,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java index 34735823b..b02228907 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -11,7 +11,7 @@ public final class UnknownSnapshot extends MetricSnapshot { /** * To create a new {@link UnknownSnapshot}, you can either call the constructor directly or use - * the builder with {@link UnknownSnapshot#newBuilder()}. + * the builder with {@link UnknownSnapshot#builder()}. * * @param metadata required name and optional help and unit. * See {@link MetricMetadata} for naming conventions. @@ -22,8 +22,8 @@ public UnknownSnapshot(MetricMetadata metadata, Collection getData() { - return (List) data; + public List getDataPoints() { + return (List) dataPoints; } public static final class UnknownDataPointSnapshot extends DataPointSnapshot { @@ -33,7 +33,7 @@ public static final class UnknownDataPointSnapshot extends DataPointSnapshot { /** * To create a new {@link UnknownDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link UnknownDataPointSnapshot#newBuilder()}. + * Builder with {@link UnknownDataPointSnapshot#builder()}. * * @param value the value. * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. @@ -65,6 +65,10 @@ public Exemplar getExemplar() { return exemplar; } + public static Builder builder() { + return new Builder(); + } + public static class Builder extends DataPointSnapshot.Builder { private Exemplar exemplar = null; @@ -76,7 +80,7 @@ private Builder() { /** * required. */ - public Builder withValue(double value) { + public Builder value(double value) { this.value = value; return this; } @@ -84,7 +88,7 @@ public Builder withValue(double value) { /** * Optional */ - public Builder withExemplar(Exemplar exemplar) { + public Builder exemplar(Exemplar exemplar) { this.exemplar = exemplar; return this; } @@ -101,10 +105,10 @@ protected Builder self() { return this; } } + } - public static Builder newBuilder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); } public static class Builder extends MetricSnapshot.Builder { @@ -114,7 +118,10 @@ public static class Builder extends MetricSnapshot.Builder { private Builder() { } - public Builder addDataPoint(UnknownDataPointSnapshot data) { + /** + * Add a data point. Call multiple times to add multiple data points. + */ + public Builder dataPoint(UnknownDataPointSnapshot data) { dataPoints.add(data); return this; } @@ -128,8 +135,4 @@ protected Builder self() { return this; } } - - public static Builder newBuilder() { - return new Builder(); - } } 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 8519f5f27..a7626713c 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 @@ -12,8 +12,8 @@ public class PrometheusRegistryTest { Collector noName = new Collector() { @Override public MetricSnapshot collect() { - return GaugeSnapshot.newBuilder() - .withName("no_name_gauge") + return GaugeSnapshot.builder() + .name("no_name_gauge") .build(); } @@ -23,20 +23,20 @@ public String getPrometheusName() { } }; - Collector counterA1 = () -> CounterSnapshot.newBuilder() - .withName("counter_a") + Collector counterA1 = () -> CounterSnapshot.builder() + .name("counter_a") .build(); - Collector counterA2 = () -> CounterSnapshot.newBuilder() - .withName("counter.a") + Collector counterA2 = () -> CounterSnapshot.builder() + .name("counter.a") .build(); - Collector counterB = () -> CounterSnapshot.newBuilder() - .withName("counter_b") + Collector counterB = () -> CounterSnapshot.builder() + .name("counter_b") .build(); - Collector gaugeA = () -> GaugeSnapshot.newBuilder() - .withName("gauge_a") + Collector gaugeA = () -> GaugeSnapshot.builder() + .name("gauge_a") .build(); @Test diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java index 04801e133..78bf8c564 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.model.snapshots; -import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; -import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import org.junit.Assert; import org.junit.Test; @@ -11,21 +9,21 @@ public class ClassicHistogramBucketsTest { @Test public void testGoodCase() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() - .addBucket(Double.NEGATIVE_INFINITY, 0) - .addBucket(-10.0, 7) - .addBucket(1024, 3) - .addBucket(Double.POSITIVE_INFINITY, 8) + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() + .bucket(Double.NEGATIVE_INFINITY, 0) + .bucket(-10.0, 7) + .bucket(1024, 3) + .bucket(Double.POSITIVE_INFINITY, 8) .build(); Assert.assertEquals(4, buckets.size()); } @Test public void testSort() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() - .addBucket(7, 2) - .addBucket(2, 0) - .addBucket(Double.POSITIVE_INFINITY, 3) + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() + .bucket(7, 2) + .bucket(2, 0) + .bucket(Double.POSITIVE_INFINITY, 3) .build(); Assert.assertEquals(3, buckets.size()); Assert.assertEquals(2, buckets.getUpperBound(0), 0.0); @@ -38,49 +36,49 @@ public void testSort() { @Test public void testMinimalBuckets() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 0) + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 0) .build(); Assert.assertEquals(1, buckets.size()); } @Test(expected = IllegalArgumentException.class) public void testInfBucketMissing() { - ClassicHistogramBuckets.newBuilder() - .addBucket(Double.NEGATIVE_INFINITY, 0) + ClassicHistogramBuckets.builder() + .bucket(Double.NEGATIVE_INFINITY, 0) .build(); } @Test(expected = IllegalArgumentException.class) public void testNegativeCount() { - ClassicHistogramBuckets.newBuilder() - .addBucket(0.0, 10) - .addBucket(Double.POSITIVE_INFINITY, -1) + ClassicHistogramBuckets.builder() + .bucket(0.0, 10) + .bucket(Double.POSITIVE_INFINITY, -1) .build(); } @Test(expected = IllegalArgumentException.class) public void testNaNBoundary() { - ClassicHistogramBuckets.newBuilder() - .addBucket(0.0, 1) - .addBucket(Double.NaN, 2) - .addBucket(Double.POSITIVE_INFINITY, 0) + ClassicHistogramBuckets.builder() + .bucket(0.0, 1) + .bucket(Double.NaN, 2) + .bucket(Double.POSITIVE_INFINITY, 0) .build(); } @Test(expected = IllegalArgumentException.class) public void testDuplicateBoundary() { - ClassicHistogramBuckets.newBuilder() - .addBucket(1.0, 1) - .addBucket(2.0, 2) - .addBucket(1.0, 2) - .addBucket(Double.POSITIVE_INFINITY, 0) + ClassicHistogramBuckets.builder() + .bucket(1.0, 1) + .bucket(2.0, 2) + .bucket(1.0, 2) + .bucket(Double.POSITIVE_INFINITY, 0) .build(); } @Test(expected = IllegalArgumentException.class) public void testEmptyBuckets() { - ClassicHistogramBuckets.newBuilder().build(); + ClassicHistogramBuckets.builder().build(); } @Test(expected = IllegalArgumentException.class) @@ -92,10 +90,10 @@ public void testDifferentLength() { @Test(expected = UnsupportedOperationException.class) public void testImmutable() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() - .addBucket(1.0, 7) - .addBucket(2.0, 8) - .addBucket(Double.POSITIVE_INFINITY, 0) + ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() + .bucket(1.0, 7) + .bucket(2.0, 8) + .bucket(Double.POSITIVE_INFINITY, 0) .build(); Iterator iterator = buckets.iterator(); iterator.next(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java index 4f2b2d75d..b990de196 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java @@ -14,47 +14,47 @@ public void testCompleteGoodCase() { long createdTimestamp1 = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); long createdTimestamp2 = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); long exemplarTimestamp = System.currentTimeMillis(); - CounterSnapshot snapshot = CounterSnapshot.newBuilder() - .withName("http_server_requests_seconds") - .withHelp("total time spent serving requests") - .withUnit(Unit.SECONDS) - .addDataPoint(CounterDataPointSnapshot.newBuilder() - .withValue(1.0) - .withExemplar(Exemplar.newBuilder() - .withValue(3.0) - .withTraceId("abc123") - .withSpanId("123457") - .withTimestampMillis(exemplarTimestamp) + CounterSnapshot snapshot = CounterSnapshot.builder() + .name("http_server_requests_seconds") + .help("total time spent serving requests") + .unit(Unit.SECONDS) + .dataPoint(CounterDataPointSnapshot.builder() + .value(1.0) + .exemplar(Exemplar.builder() + .value(3.0) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) .build()) - .withLabels(Labels.newBuilder() - .addLabel("path", "/world") + .labels(Labels.builder() + .label("path", "/world") .build()) - .withCreatedTimestampMillis(createdTimestamp1) + .createdTimestampMillis(createdTimestamp1) .build() - ).addDataPoint(CounterDataPointSnapshot.newBuilder() - .withValue(2.0) - .withExemplar(Exemplar.newBuilder() - .withValue(4.0) - .withTraceId("def456") - .withSpanId("234567") - .withTimestampMillis(exemplarTimestamp) + ).dataPoint(CounterDataPointSnapshot.builder() + .value(2.0) + .exemplar(Exemplar.builder() + .value(4.0) + .traceId("def456") + .spanId("234567") + .timestampMillis(exemplarTimestamp) .build()) - .withLabels(Labels.newBuilder() - .addLabel("path", "/hello") + .labels(Labels.builder() + .label("path", "/hello") .build()) - .withCreatedTimestampMillis(createdTimestamp2) + .createdTimestampMillis(createdTimestamp2) .build() ) .build(); SnapshotTestUtil.assertMetadata(snapshot, "http_server_requests_seconds", "total time spent serving requests", "seconds"); - Assert.assertEquals(2, snapshot.getData().size()); - CounterDataPointSnapshot data = snapshot.getData().get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(2, snapshot.getDataPoints().size()); + CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); // data is sorted by labels, so the first one should be path="/hello" Assert.assertEquals(Labels.of("path", "/hello"), data.getLabels()); Assert.assertEquals(2.0, data.getValue(), 0.0); Assert.assertEquals(4.0, data.getExemplar().getValue(), 0.0); Assert.assertEquals(createdTimestamp2, data.getCreatedTimestampMillis()); Assert.assertFalse(data.hasScrapeTimestamp()); - data = snapshot.getData().get(1); + data = snapshot.getDataPoints().get(1); Assert.assertEquals(Labels.of("path", "/world"), data.getLabels()); Assert.assertEquals(1.0, data.getValue(), 0.0); Assert.assertEquals(3.0, data.getExemplar().getValue(), 0.0); @@ -64,13 +64,13 @@ public void testCompleteGoodCase() { @Test public void testMinimalGoodCase() { - CounterSnapshot snapshot = CounterSnapshot.newBuilder() - .withName("events") - .addDataPoint(CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot snapshot = CounterSnapshot.builder() + .name("events") + .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "events", null, null); - Assert.assertEquals(1, snapshot.getData().size()); - CounterDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertEquals(Labels.EMPTY, data.getLabels()); Assert.assertEquals(1.0, data.getValue(), 0.0); Assert.assertNull(data.getExemplar()); @@ -80,28 +80,28 @@ public void testMinimalGoodCase() { @Test public void testEmptyCounter() { - CounterSnapshot snapshot = CounterSnapshot.newBuilder().withName("events").build(); - Assert.assertEquals(0, snapshot.getData().size()); + CounterSnapshot snapshot = CounterSnapshot.builder().name("events").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test(expected = IllegalArgumentException.class) public void testTotalSuffixPresent() { - CounterSnapshot.newBuilder().withName("test_total").build(); + CounterSnapshot.builder().name("test_total").build(); } @Test(expected = IllegalArgumentException.class) public void testValueMissing() { - CounterDataPointSnapshot.newBuilder().build(); + CounterDataPointSnapshot.builder().build(); } @Test(expected = UnsupportedOperationException.class) public void testDataImmutable() { - CounterSnapshot snapshot = CounterSnapshot.newBuilder() - .withName("events") - .addDataPoint(CounterDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "a")).withValue(1.0).build()) - .addDataPoint(CounterDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "b")).withValue(2.0).build()) + CounterSnapshot snapshot = CounterSnapshot.builder() + .name("events") + .dataPoint(CounterDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(1.0).build()) + .dataPoint(CounterDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(2.0).build()) .build(); - Iterator iterator = snapshot.getData().iterator(); + Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); iterator.remove(); } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java index 385ceb029..84134b6b3 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.model.snapshots; -import io.prometheus.metrics.model.snapshots.Exemplar; -import io.prometheus.metrics.model.snapshots.Labels; import org.junit.Assert; import org.junit.Test; @@ -10,12 +8,12 @@ public class ExemplarTest { @Test public void testGoodCaseComplete() { long timestamp = System.currentTimeMillis(); - Exemplar exemplar = Exemplar.newBuilder() - .withValue(2.2) - .withTraceId("abc123abc123") - .withSpanId("def456def456") - .withTimestampMillis(timestamp) - .withLabels(Labels.of("path", "/", "error", "none")) + Exemplar exemplar = Exemplar.builder() + .value(2.2) + .traceId("abc123abc123") + .spanId("def456def456") + .timestampMillis(timestamp) + .labels(Labels.of("path", "/", "error", "none")) .build(); Assert.assertEquals(2.2, exemplar.getValue(), 0.0); Assert.assertEquals(Labels.of(Exemplar.TRACE_ID, "abc123abc123", Exemplar.SPAN_ID, "def456def456", "path", "/", "error", "none"), exemplar.getLabels()); @@ -25,12 +23,12 @@ public void testGoodCaseComplete() { @Test(expected = IllegalStateException.class) public void testValueMissing() { - Exemplar.newBuilder().build(); + Exemplar.builder().build(); } @Test public void testMinimal() { - Exemplar exemplar = Exemplar.newBuilder().withValue(0.0).build(); + Exemplar exemplar = Exemplar.builder().value(0.0).build(); Assert.assertEquals(0.0, exemplar.getValue(), 0.0); Assert.assertEquals(Labels.EMPTY, exemplar.getLabels()); Assert.assertFalse(exemplar.hasTimestamp()); @@ -38,40 +36,40 @@ public void testMinimal() { @Test public void testLabelsMergeTraceId() { - Exemplar exemplar = Exemplar.newBuilder() - .withValue(0.0) - .withLabels(Labels.of("a", "b")) - .withTraceId("abc") + Exemplar exemplar = Exemplar.builder() + .value(0.0) + .labels(Labels.of("a", "b")) + .traceId("abc") .build(); Assert.assertEquals(Labels.of("a", "b", "trace_id", "abc"), exemplar.getLabels()); } @Test public void testLabelsMergeSpanId() { - Exemplar exemplar = Exemplar.newBuilder() - .withValue(0.0) - .withLabels(Labels.of("a", "b")) - .withSpanId("abc") + Exemplar exemplar = Exemplar.builder() + .value(0.0) + .labels(Labels.of("a", "b")) + .spanId("abc") .build(); Assert.assertEquals(Labels.of("a", "b", "span_id", "abc"), exemplar.getLabels()); } @Test public void testLabelsMergeTraceIdAndSpanId() { - Exemplar exemplar = Exemplar.newBuilder() - .withValue(0.0) - .withLabels(Labels.of("a", "b")) - .withSpanId("abc") - .withTraceId("def") + Exemplar exemplar = Exemplar.builder() + .value(0.0) + .labels(Labels.of("a", "b")) + .spanId("abc") + .traceId("def") .build(); Assert.assertEquals(Labels.of("span_id", "abc", "a", "b", "trace_id", "def"), exemplar.getLabels()); } @Test public void testLabelsMergeNone() { - Exemplar exemplar = Exemplar.newBuilder() - .withValue(0.0) - .withLabels(Labels.of("a", "b")) + Exemplar exemplar = Exemplar.builder() + .value(0.0) + .labels(Labels.of("a", "b")) .build(); Assert.assertEquals(Labels.of("a", "b"), exemplar.getLabels()); } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java index 3ef9447a7..5549c0efd 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.model.snapshots; -import io.prometheus.metrics.model.snapshots.Exemplar; -import io.prometheus.metrics.model.snapshots.Exemplars; import org.junit.Assert; import org.junit.Test; @@ -12,9 +10,9 @@ public class ExemplarsTest { @Test public void testUpperBound() { Exemplars exemplars = Exemplars.of( - Exemplar.newBuilder().withValue(1.0).build(), - Exemplar.newBuilder().withValue(3.0).build(), - Exemplar.newBuilder().withValue(2.0).build() + Exemplar.builder().value(1.0).build(), + Exemplar.builder().value(3.0).build(), + Exemplar.builder().value(2.0).build() ); Assert.assertEquals(3, exemplars.size()); Assert.assertEquals(1.0, exemplars.get(0).getValue(), 0.0); @@ -31,9 +29,9 @@ public void testUpperBound() { @Test(expected = UnsupportedOperationException.class) public void testImmutable() { Exemplars exemplars = Exemplars.of( - Exemplar.newBuilder().withValue(1.0).build(), - Exemplar.newBuilder().withValue(3.0).build(), - Exemplar.newBuilder().withValue(2.0).build() + Exemplar.builder().value(1.0).build(), + Exemplar.builder().value(3.0).build(), + Exemplar.builder().value(2.0).build() ); Iterator iterator = exemplars.iterator(); iterator.next(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java index d4e2fec33..b64298529 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java @@ -12,45 +12,45 @@ public class GaugeSnapshotTest { @Test public void testCompleteGoodCase() { long exemplarTimestamp = System.currentTimeMillis(); - GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() - .withName("cache_size_bytes") - .withHelp("cache size in Bytes") - .withUnit(Unit.BYTES) - .addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(1024.0) - .withExemplar(Exemplar.newBuilder() - .withValue(1024.0) - .withTraceId("abc123") - .withSpanId("123457") - .withTimestampMillis(exemplarTimestamp) + GaugeSnapshot snapshot = GaugeSnapshot.builder() + .name("cache_size_bytes") + .help("cache size in Bytes") + .unit(Unit.BYTES) + .dataPoint(GaugeDataPointSnapshot.builder() + .value(1024.0) + .exemplar(Exemplar.builder() + .value(1024.0) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) .build()) - .withLabels(Labels.newBuilder() - .addLabel("env", "prod") + .labels(Labels.builder() + .label("env", "prod") .build()) .build() - ).addDataPoint(GaugeDataPointSnapshot.newBuilder() - .withValue(128.0) - .withExemplar(Exemplar.newBuilder() - .withValue(128.0) - .withTraceId("def456") - .withSpanId("234567") - .withTimestampMillis(exemplarTimestamp) + ).dataPoint(GaugeDataPointSnapshot.builder() + .value(128.0) + .exemplar(Exemplar.builder() + .value(128.0) + .traceId("def456") + .spanId("234567") + .timestampMillis(exemplarTimestamp) .build()) - .withLabels(Labels.newBuilder() - .addLabel("env", "dev") + .labels(Labels.builder() + .label("env", "dev") .build()) .build() ) .build(); SnapshotTestUtil.assertMetadata(snapshot, "cache_size_bytes", "cache size in Bytes", "bytes"); - Assert.assertEquals(2, snapshot.getData().size()); - GaugeDataPointSnapshot data = snapshot.getData().get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(2, snapshot.getDataPoints().size()); + GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); // data is sorted by labels, so the first one should be path="/hello" Assert.assertEquals(Labels.of("env", "dev"), data.getLabels()); Assert.assertEquals(128.0, data.getValue(), 0.0); Assert.assertEquals(128.0, data.getExemplar().getValue(), 0.0); Assert.assertFalse(data.hasCreatedTimestamp()); Assert.assertFalse(data.hasScrapeTimestamp()); - data = snapshot.getData().get(1); + data = snapshot.getDataPoints().get(1); Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); Assert.assertEquals(1024.0, data.getValue(), 0.0); Assert.assertEquals(1024.0, data.getExemplar().getValue(), 0.0); @@ -60,13 +60,13 @@ public void testCompleteGoodCase() { @Test public void testMinimalGoodCase() { - GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() - .withName("temperature") - .addDataPoint(GaugeDataPointSnapshot.newBuilder().withValue(23.0).build()) + GaugeSnapshot snapshot = GaugeSnapshot.builder() + .name("temperature") + .dataPoint(GaugeDataPointSnapshot.builder().value(23.0).build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "temperature", null, null); - Assert.assertEquals(1, snapshot.getData().size()); - GaugeDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertEquals(Labels.EMPTY, data.getLabels()); Assert.assertEquals(23.0, data.getValue(), 0.0); Assert.assertNull(data.getExemplar()); @@ -76,35 +76,35 @@ public void testMinimalGoodCase() { @Test public void testEmptyGauge() { - GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() - .withName("temperature") + GaugeSnapshot snapshot = GaugeSnapshot.builder() + .name("temperature") .build(); - Assert.assertEquals(0, snapshot.getData().size()); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test(expected = IllegalArgumentException.class) public void testTotalSuffixPresent() { - CounterSnapshot.newBuilder().withName("test_total").build(); + CounterSnapshot.builder().name("test_total").build(); } @Test(expected = IllegalArgumentException.class) public void testTotalSuffixPresentDot() { - CounterSnapshot.newBuilder().withName("test.total").build(); + CounterSnapshot.builder().name("test.total").build(); } @Test(expected = IllegalArgumentException.class) public void testValueMissing() { - CounterDataPointSnapshot.newBuilder().build(); + CounterDataPointSnapshot.builder().build(); } @Test(expected = UnsupportedOperationException.class) public void testDataImmutable() { - GaugeSnapshot snapshot = GaugeSnapshot.newBuilder() - .withName("gauge") - .addDataPoint(GaugeDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "a")).withValue(23.0).build()) - .addDataPoint(GaugeDataPointSnapshot.newBuilder().withLabels(Labels.of("a", "b")).withValue(23.0).build()) + GaugeSnapshot snapshot = GaugeSnapshot.builder() + .name("gauge") + .dataPoint(GaugeDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(23.0).build()) + .dataPoint(GaugeDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(23.0).build()) .build(); - Iterator iterator = snapshot.getData().iterator(); + Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); iterator.remove(); } 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 9dc21a235..5ff838dd7 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 @@ -14,70 +14,70 @@ 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.newBuilder() - .withValue(129.0) - .withTraceId("abcabc") - .withSpanId("defdef") - .withLabels(Labels.of("status", "200")) - .withTimestampMillis(exemplarTimestamp) + Exemplar exemplar1 = Exemplar.builder() + .value(129.0) + .traceId("abcabc") + .spanId("defdef") + .labels(Labels.of("status", "200")) + .timestampMillis(exemplarTimestamp) .build(); - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("request_size_bytes") - .withHelp("request sizes in bytes") - .withUnit(Unit.BYTES) - .addDataPoint( - HistogramDataPointSnapshot.newBuilder() - .withSum(27000.0) - .withNativeSchema(5) - .withNativeZeroCount(2) - .withNativeZeroThreshold(0.0000001) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 0) - .addBucket(128.0, 7) - .addBucket(1024.0, 15) + 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. - .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() - .addBucket(1, 12) - .addBucket(2, 3) - .addBucket(4, 2) + .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() + .bucket(1, 12) + .bucket(2, 3) + .bucket(4, 2) .build()) - .withNativeBucketsForNegativeValues(NativeHistogramBuckets.newBuilder() - .addBucket(-1, 1) - .addBucket(0, 2) + .nativeBucketsForNegativeValues(NativeHistogramBuckets.builder() + .bucket(-1, 1) + .bucket(0, 2) .build()) - .withLabels(Labels.of("path", "/")) - .withExemplars(Exemplars.of(exemplar1)) - .withCreatedTimestampMillis(createdTimestamp) - .withScrapeTimestampMillis(scrapeTimestamp) + .labels(Labels.of("path", "/")) + .exemplars(Exemplars.of(exemplar1)) + .createdTimestampMillis(createdTimestamp) + .scrapeTimestampMillis(scrapeTimestamp) .build()) - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withCount(3) // TODO how is that not a compile error? This is a protected method! - .withSum(400.2) - .withNativeSchema(5) - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(128.0, 0) - .addBucket(1024.0, 4) - .addBucket(Double.POSITIVE_INFINITY, 2) + .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()) - .withNativeBucketsForPositiveValues(NativeHistogramBuckets.newBuilder() - .addBucket(-1, 1) - .addBucket(3, 3) - .addBucket(4, 2) + .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() + .bucket(-1, 1) + .bucket(3, 3) + .bucket(4, 2) .build()) - .withLabels(Labels.of("path", "/api/v1")) - .withExemplars(Exemplars.of(exemplar1)) - .withCreatedTimestampMillis(createdTimestamp) - .withScrapeTimestampMillis(scrapeTimestamp) + .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.getData().size()); - HistogramDataPointSnapshot data = snapshot.getData().get(0); // data is sorted by labels, so the first one should be path="/" + 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()); @@ -146,7 +146,7 @@ public void testGoodCaseComplete() { } 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.getData().get(1); + 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()); @@ -156,37 +156,37 @@ public void testGoodCaseComplete() { @Test public void testEmptyHistogram() { - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("empty_histogram") + HistogramSnapshot snapshot = HistogramSnapshot.builder() + .name("empty_histogram") .build(); - Assert.assertEquals(0, snapshot.getData().size()); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test public void testMinimalClassicHistogram() { - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("minimal_histogram") - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0})) + 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.getData().get(0); + HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertFalse(data.hasSum()); - Assert.assertEquals(1, snapshot.getData().get(0).getClassicBuckets().size()); + Assert.assertEquals(1, snapshot.getDataPoints().get(0).getClassicBuckets().size()); } @Test public void testMinimalNativeHistogram() { - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("hist") - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withNativeSchema(5) + 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.getData().size()); - HistogramDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertFalse(data.hasCreatedTimestamp()); Assert.assertFalse(data.hasScrapeTimestamp()); Assert.assertTrue(data.hasCount()); @@ -198,17 +198,17 @@ public void testMinimalNativeHistogram() { @Test public void testClassicCount() { - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("test_histogram") - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withClassicHistogramBuckets(ClassicHistogramBuckets.newBuilder() - .addBucket(1.0, 3) - .addBucket(2.0, 2) - .addBucket(Double.POSITIVE_INFINITY, 0) + 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.getData().get(0); + HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertFalse(data.hasSum()); Assert.assertTrue(data.hasCount()); Assert.assertEquals(5, data.getCount()); @@ -217,13 +217,13 @@ public void testClassicCount() { @Test(expected = IllegalArgumentException.class) public void testEmptyData() { // This will fail because one of nativeSchema and classicHistogramBuckets is required - HistogramDataPointSnapshot.newBuilder().build(); + HistogramDataPointSnapshot.builder().build(); } @Test public void testEmptyNativeData() { - HistogramDataPointSnapshot data = HistogramDataPointSnapshot.newBuilder() - .withNativeSchema(5) + HistogramDataPointSnapshot data = HistogramDataPointSnapshot.builder() + .nativeSchema(5) .build(); Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size()); Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size()); @@ -231,18 +231,18 @@ public void testEmptyNativeData() { @Test(expected = UnsupportedOperationException.class) public void testDataImmutable() { - HistogramSnapshot snapshot = HistogramSnapshot.newBuilder() - .withName("test_histogram") - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withLabels(Labels.of("a", "a")) - .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0})) + 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()) - .addDataPoint(HistogramDataPointSnapshot.newBuilder() - .withLabels(Labels.of("a", "b")) - .withClassicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{2})) + .dataPoint(HistogramDataPointSnapshot.builder() + .labels(Labels.of("a", "b")) + .classicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{2})) .build()) .build(); - Iterator iterator = snapshot.getData().iterator(); + Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); iterator.remove(); } @@ -260,8 +260,8 @@ public void testMinimalNativeData() { @Test public void testMinimalClassicData() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.newBuilder() - .addBucket(Double.POSITIVE_INFINITY, 0) + 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/InfoSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java index c2fd2af63..dd4f2f0cb 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java @@ -9,52 +9,52 @@ public class InfoSnapshotTest { @Test public void testCompleteGoodCase() { - InfoSnapshot snapshot = InfoSnapshot.newBuilder() - .withName("target") - .withHelp("Target info") - .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) + InfoSnapshot snapshot = InfoSnapshot.builder() + .name("target") + .help("Target info") + .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) .build()) .build(); Assert.assertEquals("target", snapshot.getMetadata().getName()); Assert.assertEquals("Target info", snapshot.getMetadata().getHelp()); Assert.assertFalse(snapshot.getMetadata().hasUnit()); - Assert.assertEquals(1, snapshot.getData().size()); + Assert.assertEquals(1, snapshot.getDataPoints().size()); } @Test public void testEmptyInfo() { - InfoSnapshot snapshot = InfoSnapshot.newBuilder().withName("target").build(); - Assert.assertEquals(0, snapshot.getData().size()); + InfoSnapshot snapshot = InfoSnapshot.builder().name("target").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test(expected = UnsupportedOperationException.class) public void testDataImmutable() { - InfoSnapshot snapshot = InfoSnapshot.newBuilder() - .withName("target") - .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway.v1")) + InfoSnapshot snapshot = InfoSnapshot.builder() + .name("target") + .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway.v1")) .build()) - .addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of("instance_id", "127.0.0.1:9200", "service_name", "gateway.v2")) + .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("instance_id", "127.0.0.1:9200", "service_name", "gateway.v2")) .build()) .build(); - Iterator iterator = snapshot.getData().iterator(); + Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); iterator.remove(); } @Test(expected = IllegalArgumentException.class) public void testNameMustNotIncludeSuffix() { - InfoSnapshot.newBuilder() - .withName("jvm_info") + InfoSnapshot.builder() + .name("jvm_info") .build(); } @Test(expected = IllegalArgumentException.class) public void testNameMustNotIncludeSuffixDot() { - InfoSnapshot.newBuilder() - .withName("jvm.info") + InfoSnapshot.builder() + .name("jvm.info") .build(); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java index 492472c94..acd659dbf 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -7,27 +7,27 @@ public class MetricSnapshotTest { @Test(expected = IllegalArgumentException.class) public void testDuplicateLabels() { - CounterSnapshot.newBuilder() - .withName("events") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() - .withLabels(Labels.of("path", "/hello", "status", "200")) - .withValue(1.0) + CounterSnapshot.builder() + .name("events") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/hello", "status", "200")) + .value(1.0) .build()) - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() - .withLabels(Labels.of("path", "/world", "status", "200")) - .withValue(2.0) + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/world", "status", "200")) + .value(2.0) .build()) - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder() - .withLabels(Labels.of("status", "200", "path", "/hello")) - .withValue(3.0) + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("status", "200", "path", "/hello")) + .value(3.0) .build()) .build(); } @Test public void testNoData() { - MetricSnapshot snapshot = CounterSnapshot.newBuilder().withName("test").build(); - Assert.assertEquals(0, snapshot.getData().size()); + MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test(expected = NullPointerException.class) diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java index 7066146c4..61b54cb3a 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java @@ -9,23 +9,23 @@ public class MetricSnapshotsTest { @Test public void testEmpty() { - MetricSnapshots snapshots = MetricSnapshots.newBuilder().build(); + MetricSnapshots snapshots = MetricSnapshots.builder().build(); Assert.assertFalse(snapshots.stream().findAny().isPresent()); } @Test public void testSort() { - CounterSnapshot c1 = CounterSnapshot.newBuilder() - .withName("counter1") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c1 = CounterSnapshot.builder() + .name("counter1") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - CounterSnapshot c2 = CounterSnapshot.newBuilder() - .withName("counter2") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c2 = CounterSnapshot.builder() + .name("counter2") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - CounterSnapshot c3 = CounterSnapshot.newBuilder() - .withName("counter3") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c3 = CounterSnapshot.builder() + .name("counter3") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); Assert.assertEquals(3, snapshots.size()); @@ -41,42 +41,42 @@ public void testDuplicateName() { // the values "foo_total" and "foo_created" while the gauge will produce the value "foo". // So from that perspective there is no conflict. However, the name for HELP, TYPE, UNIT is the same, // and that is the conflict. Therefore, you cannot have a counter named "foo" and a gauge named "foo". - CounterSnapshot c = CounterSnapshot.newBuilder() - .withName("my_metric") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c = CounterSnapshot.builder() + .name("my_metric") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - GaugeSnapshot g = GaugeSnapshot.newBuilder() - .withName("my_metric") - .addDataPoint(GaugeSnapshot.GaugeDataPointSnapshot.newBuilder().withValue(1.0).build()) + GaugeSnapshot g = GaugeSnapshot.builder() + .name("my_metric") + .dataPoint(GaugeSnapshot.GaugeDataPointSnapshot.builder().value(1.0).build()) .build(); new MetricSnapshots(c, g); } @Test public void testBuilder() { - CounterSnapshot counter = CounterSnapshot.newBuilder() - .withName("my_metric") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot counter = CounterSnapshot.builder() + .name("my_metric") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - MetricSnapshots.Builder builder = MetricSnapshots.newBuilder(); + MetricSnapshots.Builder builder = MetricSnapshots.builder(); Assert.assertFalse(builder.containsMetricName("my_metric")); - builder.addMetricSnapshot(counter); + builder.metricSnapshot(counter); Assert.assertTrue(builder.containsMetricName("my_metric")); } @Test(expected = UnsupportedOperationException.class) public void testImmutable() { - CounterSnapshot c1 = CounterSnapshot.newBuilder() - .withName("counter1") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c1 = CounterSnapshot.builder() + .name("counter1") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - CounterSnapshot c2 = CounterSnapshot.newBuilder() - .withName("counter2") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c2 = CounterSnapshot.builder() + .name("counter2") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); - CounterSnapshot c3 = CounterSnapshot.newBuilder() - .withName("counter3") - .addDataPoint(CounterSnapshot.CounterDataPointSnapshot.newBuilder().withValue(1.0).build()) + CounterSnapshot c3 = CounterSnapshot.builder() + .name("counter3") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); Iterator iterator = snapshots.iterator(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java index 2797be556..3c031d682 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.model.snapshots; -import io.prometheus.metrics.model.snapshots.NativeHistogramBucket; -import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; import org.junit.Assert; import org.junit.Test; @@ -11,9 +9,9 @@ public class NativeHistogramBucketsTest { @Test public void testGoodCase() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() - .addBucket(-10, 12) - .addBucket(120, 17) + NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() + .bucket(-10, 12) + .bucket(120, 17) .build(); Assert.assertEquals(2, buckets.size()); Assert.assertEquals(-10, buckets.getBucketIndex(0)); @@ -24,16 +22,16 @@ public void testGoodCase() { @Test public void testEmpty() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder().build(); + NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().build(); Assert.assertEquals(0, buckets.size()); } @Test public void testSort() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() - .addBucket(7, 4) - .addBucket(2, 0) - .addBucket(5, 3) + NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() + .bucket(7, 4) + .bucket(2, 0) + .bucket(5, 3) .build(); Assert.assertEquals(3, buckets.size()); Assert.assertEquals(2, buckets.getBucketIndex(0)); @@ -53,9 +51,9 @@ public void testDifferentLength() { @Test(expected = UnsupportedOperationException.class) public void testImmutable() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.newBuilder() - .addBucket(1, 1) - .addBucket(2, 1) + NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() + .bucket(1, 1) + .bucket(2, 1) .build(); Iterator iterator = buckets.iterator(); iterator.next(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java index 43b586119..c0956361d 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.model.snapshots; -import io.prometheus.metrics.model.snapshots.Quantile; -import io.prometheus.metrics.model.snapshots.Quantiles; import org.junit.Assert; import org.junit.Test; @@ -11,10 +9,10 @@ public class QuantilesTest { @Test public void testSort() { - Quantiles quantiles = Quantiles.newBuilder() - .addQuantile(0.99, 0.23) - .addQuantile(0.5, 0.2) - .addQuantile(0.95, 0.22) + Quantiles quantiles = Quantiles.builder() + .quantile(0.99, 0.23) + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) .build(); Assert.assertEquals(3, quantiles.size()); Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0); @@ -27,10 +25,10 @@ public void testSort() { @Test(expected = UnsupportedOperationException.class) public void testImmutable() { - Quantiles quantiles = Quantiles.newBuilder() - .addQuantile(0.99, 0.23) - .addQuantile(0.5, 0.2) - .addQuantile(0.95, 0.22) + Quantiles quantiles = Quantiles.builder() + .quantile(0.99, 0.23) + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) .build(); Iterator iterator = quantiles.iterator(); iterator.next(); @@ -44,10 +42,10 @@ public void testEmpty() { @Test(expected = IllegalArgumentException.class) public void testDuplicate() { - Quantiles.newBuilder() - .addQuantile(0.95, 0.23) - .addQuantile(0.5, 0.2) - .addQuantile(0.95, 0.22) + Quantiles.builder() + .quantile(0.95, 0.23) + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) .build(); } } 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 6c4fa61d3..2795ec165 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 @@ -11,26 +11,26 @@ public class StateSetSnapshotTest { @Test public void testCompleteGoodCase() { long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); - StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() - .withName("my_feature_flags") - .withHelp("Feature Flags") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("entity", "controller")) - .withScrapeTimestampMillis(scrapeTimestamp) - .addState("feature1", true) - .addState("feature2", false) + 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() ) - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("entity", "api")) - .addState("feature1", false) - .addState("feature2", false) + .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.getData().size()); - StateSetSnapshot.StateSetDataPointSnapshot data = snapshot.getData().get(1); // data is sorted by labels, so the second one should be entity="controller" + 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)); @@ -44,11 +44,11 @@ public void testCompleteGoodCase() { @Test public void testStateSetDataSorted() { - StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("b", true) - .addState("d", false) - .addState("c", true) - .addState("a", false) + 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)); @@ -64,35 +64,35 @@ public void testStateSetDataSorted() { @Test(expected = IllegalArgumentException.class) public void testMustHaveState() { // Must have at least one state. - StateSetSnapshot.StateSetDataPointSnapshot.newBuilder().build(); + StateSetSnapshot.StateSetDataPointSnapshot.builder().build(); } @Test public void testMinimal() { - StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() - .withName("my_flag") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("flag", true) + StateSetSnapshot snapshot = StateSetSnapshot.builder() + .name("my_flag") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("flag", true) .build() ) .build(); - Assert.assertEquals(1, snapshot.data.size()); + Assert.assertEquals(1, snapshot.dataPoints.size()); } @Test public void testEmpty() { - StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() - .withName("my_flag") + StateSetSnapshot snapshot = StateSetSnapshot.builder() + .name("my_flag") .build(); - Assert.assertEquals(0, snapshot.data.size()); + Assert.assertEquals(0, snapshot.dataPoints.size()); } @Test(expected = UnsupportedOperationException.class) public void testDataImmutable() { - StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("a", true) - .addState("b", true) - .addState("c", true) + StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("a", true) + .state("b", true) + .state("c", true) .build(); Iterator iterator = data.iterator(); iterator.next(); @@ -101,43 +101,43 @@ public void testDataImmutable() { @Test(expected = IllegalArgumentException.class) public void testDuplicateState() { - StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("a", true) - .addState("b", true) - .addState("a", true) + StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("a", true) + .state("b", true) + .state("a", true) .build(); } @Test(expected = UnsupportedOperationException.class) public void testStateSetImmutable() { - StateSetSnapshot snapshot = StateSetSnapshot.newBuilder() - .withName("flags") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("entity", "controller")) - .addState("feature", true) + StateSetSnapshot snapshot = StateSetSnapshot.builder() + .name("flags") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("entity", "controller")) + .state("feature", true) .build() ) - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .withLabels(Labels.of("entity", "api")) - .addState("feature", true) + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("entity", "api")) + .state("feature", true) .build() ) .build(); - Iterator iterator = snapshot.getData().iterator(); + Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); iterator.remove(); } @Test(expected = IllegalArgumentException.class) public void testLabelsUnique() { - StateSetSnapshot.newBuilder() - .withName("flags") - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("feature", true) + StateSetSnapshot.builder() + .name("flags") + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("feature", true) .build() ) - .addDataPoint(StateSetSnapshot.StateSetDataPointSnapshot.newBuilder() - .addState("feature", true) + .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("feature", true) .build() ) .build(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java index cf65f46bf..b5067b17e 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java @@ -12,45 +12,45 @@ public void testCompleteGoodCase() { long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); long exemplarTimestamp = System.currentTimeMillis(); - SummarySnapshot snapshot = SummarySnapshot.newBuilder() - .withName("latency_seconds") - .withHelp("latency in seconds") - .withUnit(Unit.SECONDS) - .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() - .withCreatedTimestampMillis(createdTimestamp) - .withScrapeTimestampMillis(scrapeTimestamp) - .withLabels(Labels.of("endpoint", "/")) - .withQuantiles(Quantiles.newBuilder() - .addQuantile(0.5, 0.2) - .addQuantile(0.95, 0.22) - .addQuantile(0.99, 0.23) + SummarySnapshot snapshot = SummarySnapshot.builder() + .name("latency_seconds") + .help("latency in seconds") + .unit(Unit.SECONDS) + .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() + .createdTimestampMillis(createdTimestamp) + .scrapeTimestampMillis(scrapeTimestamp) + .labels(Labels.of("endpoint", "/")) + .quantiles(Quantiles.builder() + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) + .quantile(0.99, 0.23) .build()) - .withExemplars(Exemplars.newBuilder() - .addExemplar(Exemplar.newBuilder() - .withValue(0.2) - .withTraceId("abc123") - .withSpanId("123457") - .withTimestampMillis(exemplarTimestamp) + .exemplars(Exemplars.builder() + .exemplar(Exemplar.builder() + .value(0.2) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) .build()) - .addExemplar(Exemplar.newBuilder() - .withValue(0.21) - .withTraceId("abc124") - .withSpanId("123458") - .withTimestampMillis(exemplarTimestamp) + .exemplar(Exemplar.builder() + .value(0.21) + .traceId("abc124") + .spanId("123458") + .timestampMillis(exemplarTimestamp) .build()) .build()) - .withCount(1093) - .withSum(218.6) + .count(1093) + .sum(218.6) .build()) - .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() - .withLabels(Labels.of("endpoint", "/test")) - .withCount(1093) - .withSum(218.6) + .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(Labels.of("endpoint", "/test")) + .count(1093) + .sum(218.6) .build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "latency_seconds", "latency in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getData().size()); - SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getData().get(0); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getDataPoints().get(0); Assert.assertEquals(Labels.of("endpoint", "/"), data.getLabels()); Assert.assertTrue(data.hasCount()); Assert.assertEquals(1093, data.getCount()); @@ -66,7 +66,7 @@ public void testCompleteGoodCase() { Assert.assertEquals(2, data.getExemplars().size()); // exemplars are tested in ExemplarsTest already, skipping here. - data = snapshot.getData().get(1); + data = snapshot.getDataPoints().get(1); Assert.assertFalse(data.hasCreatedTimestamp()); Assert.assertFalse(data.hasScrapeTimestamp()); Assert.assertTrue(data.hasCount()); @@ -75,26 +75,26 @@ public void testCompleteGoodCase() { @Test public void testMinimal() { - SummarySnapshot snapshot = SummarySnapshot.newBuilder() - .withName("size_bytes") - .addDataPoint(SummarySnapshot.SummaryDataPointSnapshot.newBuilder() - .withCount(10) - .withSum(12.0) + SummarySnapshot snapshot = SummarySnapshot.builder() + .name("size_bytes") + .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() + .count(10) + .sum(12.0) .build()) .build(); - Assert.assertEquals(1, snapshot.getData().size()); - Assert.assertEquals(Labels.EMPTY, snapshot.getData().get(0).getLabels()); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + Assert.assertEquals(Labels.EMPTY, snapshot.getDataPoints().get(0).getLabels()); } @Test public void testEmptySnapshot() { - SummarySnapshot snapshot = SummarySnapshot.newBuilder().withName("empty_summary").build(); - Assert.assertEquals(0, snapshot.getData().size()); + SummarySnapshot snapshot = SummarySnapshot.builder().name("empty_summary").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test public void testEmptyData() { - SummarySnapshot.SummaryDataPointSnapshot data = SummarySnapshot.SummaryDataPointSnapshot.newBuilder().build(); + SummarySnapshot.SummaryDataPointSnapshot data = SummarySnapshot.SummaryDataPointSnapshot.builder().build(); Assert.assertEquals(0, data.getQuantiles().size()); Assert.assertFalse(data.hasCount()); Assert.assertFalse(data.hasSum()); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java index b8a9827d2..dfc2e62a7 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java @@ -8,33 +8,33 @@ public class UnknownSnapshotTest { @Test public void testCompleteGoodCase() { long exemplarTimestamp = System.currentTimeMillis(); - UnknownSnapshot snapshot = UnknownSnapshot.newBuilder() - .withName("my_unknown_seconds") - .withHelp("something in seconds") - .withUnit(Unit.SECONDS) - .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() - .withValue(0.3) - .withExemplar(Exemplar.newBuilder() - .withValue(0.12) - .withTraceId("abc123") - .withSpanId("123457") - .withTimestampMillis(exemplarTimestamp) + UnknownSnapshot snapshot = UnknownSnapshot.builder() + .name("my_unknown_seconds") + .help("something in seconds") + .unit(Unit.SECONDS) + .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(0.3) + .exemplar(Exemplar.builder() + .value(0.12) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) .build()) - .withLabels(Labels.newBuilder() - .addLabel("env", "prod") + .labels(Labels.builder() + .label("env", "prod") .build()) .build() - ).addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() - .withValue(0.29) - .withLabels(Labels.newBuilder() - .addLabel("env", "dev") + ).dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(0.29) + .labels(Labels.builder() + .label("env", "dev") .build()) .build() ) .build(); SnapshotTestUtil.assertMetadata(snapshot, "my_unknown_seconds", "something in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getData().size()); - UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getData().get(1); // env="prod" + Assert.assertEquals(2, snapshot.getDataPoints().size()); + UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getDataPoints().get(1); // env="prod" Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); Assert.assertEquals(0.3, data.getValue(), 0.0); Assert.assertEquals(0.12, data.getExemplar().getValue(), 0.0); @@ -44,28 +44,28 @@ public void testCompleteGoodCase() { @Test public void testMinimal() { - UnknownSnapshot snapshot = UnknownSnapshot.newBuilder() - .withName("test") - .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() - .withValue(1.0) + UnknownSnapshot snapshot = UnknownSnapshot.builder() + .name("test") + .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(1.0) .build()) .build(); - Assert.assertEquals(1, snapshot.getData().size()); + Assert.assertEquals(1, snapshot.getDataPoints().size()); } @Test public void testEmpty() { - UnknownSnapshot snapshot = UnknownSnapshot.newBuilder().withName("test").build(); - Assert.assertEquals(0, snapshot.getData().size()); + UnknownSnapshot snapshot = UnknownSnapshot.builder().name("test").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); } @Test(expected = IllegalArgumentException.class) public void testNameMissing() { - UnknownSnapshot.newBuilder().build(); + UnknownSnapshot.builder().build(); } @Test(expected = IllegalArgumentException.class) public void testValueMissing() { - UnknownSnapshot.UnknownDataPointSnapshot.newBuilder().build(); + UnknownSnapshot.UnknownDataPointSnapshot.builder().build(); } } diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 8f9872b0f..6a753d6e2 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -38,6 +38,11 @@ prometheus-metrics-model ${project.version} + + io.prometheus + prometheus-metrics-config + ${project.version} + io.prometheus simpleclient @@ -64,5 +69,11 @@ 0.16.0 test + + io.prometheus + prometheus-metrics-config + 1.0.0-alpha-6-SNAPSHOT + compile + diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index bbe82a5d1..725afc8b3 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -2,6 +2,7 @@ import io.prometheus.client.Collector; import io.prometheus.client.CollectorRegistry; +import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; @@ -35,15 +36,15 @@ * Usage: The following line will register all metrics from a {@code simpleclient} {@link CollectorRegistry#defaultRegistry} * to a {@code prometheus-metrics} {@link PrometheusRegistry#defaultRegistry}: *

    {@code
    - * SimpleclientCollector.newBuilder().register();
    + * SimpleclientCollector.builder().register();
      * }
    *

    * If you have custom registries (not the default registries), use the following snippet: *

    {@code
      * CollectorRegistry simpleclientRegistry = ...;
      * PrometheusRegistry prometheusRegistry = ...;
    - * SimpleclientCollector.newBuilder()
    - *     .withCollectorRegistry(simpleclientRegistry)
    + * SimpleclientCollector.builder()
    + *     .collectorRegistry(simpleclientRegistry)
      *     .register(prometheusRegistry);
      * }
    */ @@ -71,33 +72,33 @@ public List getPrometheusNames() { } private MetricSnapshots convert(Enumeration samples) { - MetricSnapshots.Builder result = MetricSnapshots.newBuilder(); + MetricSnapshots.Builder result = MetricSnapshots.builder(); while (samples.hasMoreElements()) { Collector.MetricFamilySamples sample = samples.nextElement(); switch (sample.type) { case COUNTER: - result.addMetricSnapshot(convertCounter(sample)); + result.metricSnapshot(convertCounter(sample)); break; case GAUGE: - result.addMetricSnapshot(convertGauge(sample)); + result.metricSnapshot(convertGauge(sample)); break; case HISTOGRAM: - result.addMetricSnapshot(convertHistogram(sample, false)); + result.metricSnapshot(convertHistogram(sample, false)); break; case GAUGE_HISTOGRAM: - result.addMetricSnapshot(convertHistogram(sample, true)); + result.metricSnapshot(convertHistogram(sample, true)); break; case SUMMARY: - result.addMetricSnapshot(convertSummary(sample)); + result.metricSnapshot(convertSummary(sample)); break; case INFO: - result.addMetricSnapshot(convertInfo(sample)); + result.metricSnapshot(convertInfo(sample)); break; case STATE_SET: - result.addMetricSnapshot(convertStateSet(sample)); + result.metricSnapshot(convertStateSet(sample)); break; case UNKNOWN: - result.addMetricSnapshot(convertUnknown(sample)); + result.metricSnapshot(convertUnknown(sample)); break; default: throw new IllegalStateException(sample.type + ": Unexpected metric type"); @@ -107,141 +108,141 @@ private MetricSnapshots convert(Enumeration sampl } private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) { - CounterSnapshot.Builder counter = CounterSnapshot.newBuilder() - .withName(stripSuffix(samples.name, "_total")) - .withHelp(samples.help) - .withUnit(convertUnit(samples)); + CounterSnapshot.Builder counter = CounterSnapshot.builder() + .name(stripSuffix(samples.name, "_total")) + .help(samples.help) + .unit(convertUnit(samples)); Map dataPoints = new HashMap<>(); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { Labels labels = Labels.of(sample.labelNames, sample.labelValues); - CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint = dataPoints.computeIfAbsent(labels, l -> CounterSnapshot.CounterDataPointSnapshot.newBuilder().withLabels(labels)); + CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint = dataPoints.computeIfAbsent(labels, l -> CounterSnapshot.CounterDataPointSnapshot.builder().labels(labels)); if (sample.name.endsWith("_created")) { - dataPoint.withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + dataPoint.createdTimestampMillis((long) Unit.secondsToMillis(sample.value)); } else { - dataPoint.withValue(sample.value).withExemplar(convertExemplar(sample.exemplar)); + dataPoint.value(sample.value).exemplar(convertExemplar(sample.exemplar)); if (sample.timestampMs != null) { - dataPoint.withScrapeTimestampMillis(sample.timestampMs); + dataPoint.scrapeTimestampMillis(sample.timestampMs); } } } for (CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint : dataPoints.values()) { - counter.addDataPoint(dataPoint.build()); + counter.dataPoint(dataPoint.build()); } return counter.build(); } private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) { - GaugeSnapshot.Builder gauge = GaugeSnapshot.newBuilder() - .withName(samples.name) - .withHelp(samples.help) - .withUnit(convertUnit(samples)); + GaugeSnapshot.Builder gauge = GaugeSnapshot.builder() + .name(samples.name) + .help(samples.help) + .unit(convertUnit(samples)); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { - GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPoint = GaugeSnapshot.GaugeDataPointSnapshot.newBuilder() - .withValue(sample.value) - .withLabels(Labels.of(sample.labelNames, sample.labelValues)) - .withExemplar(convertExemplar(sample.exemplar)); + GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPoint = GaugeSnapshot.GaugeDataPointSnapshot.builder() + .value(sample.value) + .labels(Labels.of(sample.labelNames, sample.labelValues)) + .exemplar(convertExemplar(sample.exemplar)); if (sample.timestampMs != null) { - dataPoint.withScrapeTimestampMillis(sample.timestampMs); + dataPoint.scrapeTimestampMillis(sample.timestampMs); } - gauge.addDataPoint(dataPoint.build()); + gauge.dataPoint(dataPoint.build()); } return gauge.build(); } private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, boolean isGaugeHistogram) { - HistogramSnapshot.Builder histogram = HistogramSnapshot.newBuilder() - .withName(samples.name) - .withHelp(samples.help) - .withUnit(convertUnit(samples)); + HistogramSnapshot.Builder histogram = HistogramSnapshot.builder() + .name(samples.name) + .help(samples.help) + .unit(convertUnit(samples)); if (isGaugeHistogram) { - histogram.asGaugeHistogram(); + histogram.gaugeHistogram(); } Map dataPoints = new HashMap<>(); Map> cumulativeBuckets = new HashMap<>(); Map exemplars = new HashMap<>(); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { Labels labels = labelsWithout(sample, "le"); - dataPoints.computeIfAbsent(labels, l -> HistogramSnapshot.HistogramDataPointSnapshot.newBuilder() - .withLabels(labels)); + dataPoints.computeIfAbsent(labels, l -> HistogramSnapshot.HistogramDataPointSnapshot.builder() + .labels(labels)); cumulativeBuckets.computeIfAbsent(labels, l -> new HashMap<>()); - exemplars.computeIfAbsent(labels, l -> Exemplars.newBuilder()); + exemplars.computeIfAbsent(labels, l -> Exemplars.builder()); if (sample.name.endsWith("_sum")) { - dataPoints.get(labels).withSum(sample.value); + dataPoints.get(labels).sum(sample.value); } if (sample.name.endsWith("_bucket")) { addBucket(cumulativeBuckets.get(labels), sample); } if (sample.name.endsWith("_created")) { - dataPoints.get(labels).withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value)); } if (sample.exemplar != null) { - exemplars.get(labels).addExemplar(convertExemplar(sample.exemplar)); + exemplars.get(labels).exemplar(convertExemplar(sample.exemplar)); } if (sample.timestampMs != null) { - dataPoints.get(labels).withScrapeTimestampMillis(sample.timestampMs); + dataPoints.get(labels).scrapeTimestampMillis(sample.timestampMs); } } for (Labels labels : dataPoints.keySet()) { - histogram.addDataPoint(dataPoints.get(labels) - .withClassicHistogramBuckets(makeBuckets(cumulativeBuckets.get(labels))) - .withExemplars(exemplars.get(labels).build()) + histogram.dataPoint(dataPoints.get(labels) + .classicHistogramBuckets(makeBuckets(cumulativeBuckets.get(labels))) + .exemplars(exemplars.get(labels).build()) .build()); } return histogram.build(); } private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) { - SummarySnapshot.Builder summary = SummarySnapshot.newBuilder() - .withName(samples.name) - .withHelp(samples.help) - .withUnit(convertUnit(samples)); + SummarySnapshot.Builder summary = SummarySnapshot.builder() + .name(samples.name) + .help(samples.help) + .unit(convertUnit(samples)); Map dataPoints = new HashMap<>(); Map quantiles = new HashMap<>(); Map exemplars = new HashMap<>(); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { Labels labels = labelsWithout(sample, "quantile"); - dataPoints.computeIfAbsent(labels, l -> SummarySnapshot.SummaryDataPointSnapshot.newBuilder() - .withLabels(labels)); - quantiles.computeIfAbsent(labels, l -> Quantiles.newBuilder()); - exemplars.computeIfAbsent(labels, l -> Exemplars.newBuilder()); + dataPoints.computeIfAbsent(labels, l -> SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(labels)); + quantiles.computeIfAbsent(labels, l -> Quantiles.builder()); + exemplars.computeIfAbsent(labels, l -> Exemplars.builder()); if (sample.name.endsWith("_sum")) { - dataPoints.get(labels).withSum(sample.value); + dataPoints.get(labels).sum(sample.value); } else if (sample.name.endsWith("_count")) { - dataPoints.get(labels).withCount((long) sample.value); + dataPoints.get(labels).count((long) sample.value); } else if (sample.name.endsWith("_created")) { - dataPoints.get(labels).withCreatedTimestampMillis((long) Unit.secondsToMillis(sample.value)); + dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value)); } else { for (int i=0; i dataPoints = new HashMap<>(); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { Labels labels = labelsWithout(sample, sample.name); - dataPoints.computeIfAbsent(labels, l -> StateSetSnapshot.StateSetDataPointSnapshot.newBuilder().withLabels(labels)); + dataPoints.computeIfAbsent(labels, l -> StateSetSnapshot.StateSetDataPointSnapshot.builder().labels(labels)); String stateName = null; for (int i=0; i cumulativeBuckets) List upperBounds = new ArrayList<>(cumulativeBuckets.size()); Collections.sort(upperBounds); upperBounds.addAll(cumulativeBuckets.keySet()); - ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.newBuilder(); + ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.builder(); long previousCount = 0L; for (Double upperBound : upperBounds) { long cumulativeCount = cumulativeBuckets.get(upperBound); - result.addBucket(upperBound, cumulativeCount - previousCount); + result.bucket(upperBound, cumulativeCount - previousCount); previousCount = cumulativeCount; } return result.build(); @@ -334,22 +335,22 @@ private void addBucket(Map buckets, Collector.MetricFamilySamples. private Labels labelsWithout(Collector.MetricFamilySamples.Sample sample, String excludedLabelName) { - Labels.Builder labels = Labels.newBuilder(); + Labels.Builder labels = Labels.builder(); for (int i = 0; i < sample.labelNames.size(); i++) { if (!sample.labelNames.get(i).equals(excludedLabelName)) { - labels.addLabel(sample.labelNames.get(i), sample.labelValues.get(i)); + labels.label(sample.labelNames.get(i), sample.labelValues.get(i)); } } return labels.build(); } private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) { - InfoSnapshot.Builder info = InfoSnapshot.newBuilder() - .withName(stripSuffix(samples.name, "_info")) - .withHelp(samples.help); + InfoSnapshot.Builder info = InfoSnapshot.builder() + .name(stripSuffix(samples.name, "_info")) + .help(samples.help); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { - info.addDataPoint(InfoSnapshot.InfoDataPointSnapshot.newBuilder() - .withLabels(Labels.of(sample.labelNames, sample.labelValues)) + info.dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of(sample.labelNames, sample.labelValues)) .build()); } return info.build(); @@ -359,26 +360,40 @@ private Exemplar convertExemplar(io.prometheus.client.exemplars.Exemplar exempla if (exemplar == null) { return null; } - Exemplar.Builder result = Exemplar.newBuilder().withValue(exemplar.getValue()); + Exemplar.Builder result = Exemplar.builder().value(exemplar.getValue()); if (exemplar.getTimestampMs() != null) { - result.withTimestampMillis(exemplar.getTimestampMs()); + result.timestampMillis(exemplar.getTimestampMs()); } - Labels.Builder labels = Labels.newBuilder(); + Labels.Builder labels = Labels.builder(); for (int i = 0; i < exemplar.getNumberOfLabels(); i++) { - labels.addLabel(exemplar.getLabelName(i), exemplar.getLabelValue(i)); + labels.label(exemplar.getLabelName(i), exemplar.getLabelValue(i)); } - return result.withLabels(labels.build()).build(); + return result.labels(labels.build()).build(); } - public static Builder newBuilder() { - return new Builder(); + /** + * Currently there are no configuration options for the SimpleclientCollector. + * However, we want to follow the pattern to pass the config everywhere so that + * we can introduce config options later without the need for API changes. + */ + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static Builder builder() { + return builder(PrometheusProperties.get()); } public static class Builder { + + private final PrometheusProperties config; private CollectorRegistry collectorRegistry; - private Builder() {} - public Builder withCollectorRegistry(CollectorRegistry registry) { + private Builder(PrometheusProperties config) { + this.config = config; + } + + public Builder collectorRegistry(CollectorRegistry registry) { this.collectorRegistry = registry; return this; } diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java index 7645c7296..a3445c9af 100644 --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -10,7 +10,6 @@ import io.prometheus.client.exporter.common.TextFormat; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -33,8 +32,8 @@ public class SimpleclientCollectorTest { public void setUp() { origRegistry = new CollectorRegistry(); newRegistry = new PrometheusRegistry(); - SimpleclientCollector.newBuilder() - .withCollectorRegistry(origRegistry) + SimpleclientCollector.builder() + .collectorRegistry(origRegistry) .register(newRegistry); } From 1d75a2dc79dce036fe4b4e46492df61843f85e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 14 Sep 2023 23:38:47 +0200 Subject: [PATCH 211/980] Add initial Hugo docs to be published on Github pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/.gitignore | 1 + docs/README.md | 37 +++ docs/archetypes/default.md | 5 + docs/content/_index.md | 34 +++ docs/content/getting-started/_index.md | 4 + docs/content/getting-started/callbacks.md | 57 +++++ docs/content/getting-started/labels.md | 149 ++++++++++++ docs/content/getting-started/metric-types.md | 222 ++++++++++++++++++ docs/content/getting-started/quickstart.md | 107 +++++++++ docs/content/getting-started/registry.md | 90 +++++++ docs/hugo.toml | 30 +++ docs/static/brand.svg | 50 ++++ docs/static/favicon/favicon-16x16.png | Bin 0 -> 546 bytes docs/static/favicon/favicon-32x32.png | Bin 0 -> 1137 bytes docs/static/favicon/favicon.ico | Bin 0 -> 15086 bytes docs/static/favicon/favicon.svg | 50 ++++ docs/themes/hugo-geekdoc/LICENSE | 21 ++ docs/themes/hugo-geekdoc/README.md | 46 ++++ docs/themes/hugo-geekdoc/VERSION | 1 + docs/themes/hugo-geekdoc/archetypes/docs.md | 7 + docs/themes/hugo-geekdoc/archetypes/posts.md | 4 + .../hugo-geekdoc/assets/search/config.json | 8 + .../hugo-geekdoc/assets/search/data.json | 13 + .../hugo-geekdoc/assets/sprites/geekdoc.svg | 1 + docs/themes/hugo-geekdoc/data/assets.json | 158 +++++++++++++ docs/themes/hugo-geekdoc/i18n/cs.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/de.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/en.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/es.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/it.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/ja.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/nl.yaml | 53 +++++ docs/themes/hugo-geekdoc/i18n/zh-cn.yaml | 53 +++++ docs/themes/hugo-geekdoc/images/readme.png | Bin 0 -> 205825 bytes .../themes/hugo-geekdoc/images/screenshot.png | Bin 0 -> 304489 bytes docs/themes/hugo-geekdoc/images/tn.png | Bin 0 -> 130330 bytes docs/themes/hugo-geekdoc/layouts/404.html | 40 ++++ .../_markup/render-codeblock-mermaid.html | 11 + .../_default/_markup/render-heading.html | 27 +++ .../_default/_markup/render-image.html | 6 + .../layouts/_default/_markup/render-link.html | 14 ++ .../hugo-geekdoc/layouts/_default/baseof.html | 60 +++++ .../hugo-geekdoc/layouts/_default/list.html | 11 + .../hugo-geekdoc/layouts/_default/single.html | 11 + .../layouts/_default/taxonomy.html | 49 ++++ .../hugo-geekdoc/layouts/_default/terms.html | 32 +++ .../hugo-geekdoc/layouts/partials/foot.html | 6 + .../layouts/partials/head/custom.html | 1 + .../layouts/partials/head/favicons.html | 13 + .../layouts/partials/head/meta.html | 14 ++ .../layouts/partials/head/microformats.html | 3 + .../layouts/partials/head/others.html | 73 ++++++ .../layouts/partials/head/rel-me.html | 1 + .../layouts/partials/language.html | 51 ++++ .../layouts/partials/menu-bundle.html | 87 +++++++ .../layouts/partials/menu-extra.html | 46 ++++ .../layouts/partials/menu-filetree.html | 98 ++++++++ .../layouts/partials/menu-nextprev.html | 78 ++++++ .../hugo-geekdoc/layouts/partials/menu.html | 44 ++++ .../partials/microformats/opengraph.html | 68 ++++++ .../layouts/partials/microformats/schema.html | 70 ++++++ .../partials/microformats/twitter_cards.html | 15 ++ .../layouts/partials/page-header.html | 57 +++++ .../layouts/partials/pagination.html | 22 ++ .../layouts/partials/posts/metadata.html | 48 ++++ .../hugo-geekdoc/layouts/partials/search.html | 16 ++ .../layouts/partials/site-footer.html | 45 ++++ .../layouts/partials/site-header.html | 78 ++++++ .../layouts/partials/svg-icon-symbols.html | 4 + .../layouts/partials/utils/content.html | 6 + .../layouts/partials/utils/description.html | 14 ++ .../layouts/partials/utils/featured.html | 12 + .../layouts/partials/utils/title.html | 11 + .../hugo-geekdoc/layouts/posts/list.html | 47 ++++ .../hugo-geekdoc/layouts/posts/single.html | 13 + docs/themes/hugo-geekdoc/layouts/robots.txt | 4 + .../layouts/shortcodes/button.html | 29 +++ .../layouts/shortcodes/columns.html | 14 ++ .../layouts/shortcodes/expand.html | 11 + .../hugo-geekdoc/layouts/shortcodes/hint.html | 16 ++ .../hugo-geekdoc/layouts/shortcodes/icon.html | 5 + .../hugo-geekdoc/layouts/shortcodes/img.html | 71 ++++++ .../layouts/shortcodes/include.html | 18 ++ .../layouts/shortcodes/katex.html | 18 ++ .../layouts/shortcodes/mermaid.html | 11 + .../layouts/shortcodes/progress.html | 23 ++ .../layouts/shortcodes/propertylist.html | 60 +++++ .../hugo-geekdoc/layouts/shortcodes/tab.html | 12 + .../hugo-geekdoc/layouts/shortcodes/tabs.html | 22 ++ .../layouts/shortcodes/toc-tree.html | 41 ++++ .../hugo-geekdoc/layouts/shortcodes/toc.html | 13 + docs/themes/hugo-geekdoc/static/brand.svg | 86 +++++++ docs/themes/hugo-geekdoc/static/custom.css | 1 + .../static/favicon/android-chrome-144x144.png | Bin 0 -> 4506 bytes .../static/favicon/android-chrome-192x192.png | Bin 0 -> 6247 bytes .../static/favicon/android-chrome-256x256.png | Bin 0 -> 8700 bytes .../static/favicon/android-chrome-36x36.png | Bin 0 -> 1185 bytes .../static/favicon/android-chrome-384x384.png | Bin 0 -> 14691 bytes .../static/favicon/android-chrome-48x48.png | Bin 0 -> 1454 bytes .../static/favicon/android-chrome-512x512.png | Bin 0 -> 21745 bytes .../static/favicon/android-chrome-72x72.png | Bin 0 -> 2173 bytes .../static/favicon/android-chrome-96x96.png | Bin 0 -> 2902 bytes .../favicon/apple-touch-icon-1024x1024.png | Bin 0 -> 44655 bytes .../favicon/apple-touch-icon-114x114.png | Bin 0 -> 3939 bytes .../favicon/apple-touch-icon-120x120.png | Bin 0 -> 3848 bytes .../favicon/apple-touch-icon-144x144.png | Bin 0 -> 4651 bytes .../favicon/apple-touch-icon-152x152.png | Bin 0 -> 4904 bytes .../favicon/apple-touch-icon-167x167.png | Bin 0 -> 5418 bytes .../favicon/apple-touch-icon-180x180.png | Bin 0 -> 5488 bytes .../static/favicon/apple-touch-icon-57x57.png | Bin 0 -> 1935 bytes .../static/favicon/apple-touch-icon-60x60.png | Bin 0 -> 1986 bytes .../static/favicon/apple-touch-icon-72x72.png | Bin 0 -> 2173 bytes .../static/favicon/apple-touch-icon-76x76.png | Bin 0 -> 2307 bytes .../favicon/apple-touch-icon-precomposed.png | Bin 0 -> 5488 bytes .../static/favicon/apple-touch-icon.png | Bin 0 -> 5488 bytes .../apple-touch-startup-image-1125x2436.png | Bin 0 -> 90067 bytes .../apple-touch-startup-image-1136x640.png | Bin 0 -> 35771 bytes .../apple-touch-startup-image-1170x2532.png | Bin 0 -> 96814 bytes .../apple-touch-startup-image-1242x2208.png | Bin 0 -> 99127 bytes .../apple-touch-startup-image-1242x2688.png | Bin 0 -> 105836 bytes .../apple-touch-startup-image-1284x2778.png | Bin 0 -> 109562 bytes .../apple-touch-startup-image-1334x750.png | Bin 0 -> 45112 bytes .../apple-touch-startup-image-1536x2048.png | Bin 0 -> 126468 bytes .../apple-touch-startup-image-1620x2160.png | Bin 0 -> 139509 bytes .../apple-touch-startup-image-1668x2224.png | Bin 0 -> 143774 bytes .../apple-touch-startup-image-1668x2388.png | Bin 0 -> 145114 bytes .../apple-touch-startup-image-1792x828.png | Bin 0 -> 53255 bytes .../apple-touch-startup-image-2048x1536.png | Bin 0 -> 129401 bytes .../apple-touch-startup-image-2048x2732.png | Bin 0 -> 204315 bytes .../apple-touch-startup-image-2160x1620.png | Bin 0 -> 142250 bytes .../apple-touch-startup-image-2208x1242.png | Bin 0 -> 100183 bytes .../apple-touch-startup-image-2224x1668.png | Bin 0 -> 145637 bytes .../apple-touch-startup-image-2388x1668.png | Bin 0 -> 146825 bytes .../apple-touch-startup-image-2436x1125.png | Bin 0 -> 88281 bytes .../apple-touch-startup-image-2532x1170.png | Bin 0 -> 94235 bytes .../apple-touch-startup-image-2688x1242.png | Bin 0 -> 102979 bytes .../apple-touch-startup-image-2732x2048.png | Bin 0 -> 205972 bytes .../apple-touch-startup-image-2778x1284.png | Bin 0 -> 111486 bytes .../apple-touch-startup-image-640x1136.png | Bin 0 -> 35116 bytes .../apple-touch-startup-image-750x1334.png | Bin 0 -> 45375 bytes .../apple-touch-startup-image-828x1792.png | Bin 0 -> 54274 bytes .../static/favicon/browserconfig.xml | 12 + .../static/favicon/favicon-16x16.png | Bin 0 -> 616 bytes .../static/favicon/favicon-32x32.png | Bin 0 -> 1140 bytes .../static/favicon/favicon-48x48.png | Bin 0 -> 1900 bytes .../hugo-geekdoc/static/favicon/favicon.ico | Bin 0 -> 33310 bytes .../hugo-geekdoc/static/favicon/favicon.svg | 83 +++++++ .../hugo-geekdoc/static/favicon/manifest.json | 69 ++++++ .../static/favicon/mstile-144x144.png | Bin 0 -> 4506 bytes .../static/favicon/mstile-150x150.png | Bin 0 -> 4412 bytes .../static/favicon/mstile-310x150.png | Bin 0 -> 4257 bytes .../static/favicon/mstile-310x310.png | Bin 0 -> 10949 bytes .../static/favicon/mstile-70x70.png | Bin 0 -> 2125 bytes .../static/fonts/GeekdocIcons.woff | Bin 0 -> 6140 bytes .../static/fonts/GeekdocIcons.woff2 | Bin 0 -> 5084 bytes .../static/fonts/KaTeX_AMS-Regular.woff | Bin 0 -> 33516 bytes .../static/fonts/KaTeX_AMS-Regular.woff2 | Bin 0 -> 28076 bytes .../static/fonts/KaTeX_Caligraphic-Bold.woff | Bin 0 -> 7716 bytes .../static/fonts/KaTeX_Caligraphic-Bold.woff2 | Bin 0 -> 6912 bytes .../fonts/KaTeX_Caligraphic-Regular.woff | Bin 0 -> 7656 bytes .../fonts/KaTeX_Caligraphic-Regular.woff2 | Bin 0 -> 6908 bytes .../static/fonts/KaTeX_Fraktur-Bold.woff | Bin 0 -> 13296 bytes .../static/fonts/KaTeX_Fraktur-Bold.woff2 | Bin 0 -> 11348 bytes .../static/fonts/KaTeX_Fraktur-Regular.woff | Bin 0 -> 13208 bytes .../static/fonts/KaTeX_Fraktur-Regular.woff2 | Bin 0 -> 11316 bytes .../static/fonts/KaTeX_Main-Bold.woff | Bin 0 -> 29912 bytes .../static/fonts/KaTeX_Main-Bold.woff2 | Bin 0 -> 25324 bytes .../static/fonts/KaTeX_Main-BoldItalic.woff | Bin 0 -> 19412 bytes .../static/fonts/KaTeX_Main-BoldItalic.woff2 | Bin 0 -> 16780 bytes .../static/fonts/KaTeX_Main-Italic.woff | Bin 0 -> 19676 bytes .../static/fonts/KaTeX_Main-Italic.woff2 | Bin 0 -> 16988 bytes .../static/fonts/KaTeX_Main-Regular.woff | Bin 0 -> 30772 bytes .../static/fonts/KaTeX_Main-Regular.woff2 | Bin 0 -> 26272 bytes .../static/fonts/KaTeX_Math-BoldItalic.woff | Bin 0 -> 18668 bytes .../static/fonts/KaTeX_Math-BoldItalic.woff2 | Bin 0 -> 16400 bytes .../static/fonts/KaTeX_Math-Italic.woff | Bin 0 -> 18748 bytes .../static/fonts/KaTeX_Math-Italic.woff2 | Bin 0 -> 16440 bytes .../static/fonts/KaTeX_SansSerif-Bold.woff | Bin 0 -> 14408 bytes .../static/fonts/KaTeX_SansSerif-Bold.woff2 | Bin 0 -> 12216 bytes .../static/fonts/KaTeX_SansSerif-Italic.woff | Bin 0 -> 14112 bytes .../static/fonts/KaTeX_SansSerif-Italic.woff2 | Bin 0 -> 12028 bytes .../static/fonts/KaTeX_SansSerif-Regular.woff | Bin 0 -> 12316 bytes .../fonts/KaTeX_SansSerif-Regular.woff2 | Bin 0 -> 10344 bytes .../static/fonts/KaTeX_Script-Regular.woff | Bin 0 -> 10588 bytes .../static/fonts/KaTeX_Script-Regular.woff2 | Bin 0 -> 9644 bytes .../static/fonts/KaTeX_Size1-Regular.woff | Bin 0 -> 6496 bytes .../static/fonts/KaTeX_Size1-Regular.woff2 | Bin 0 -> 5468 bytes .../static/fonts/KaTeX_Size2-Regular.woff | Bin 0 -> 6188 bytes .../static/fonts/KaTeX_Size2-Regular.woff2 | Bin 0 -> 5208 bytes .../static/fonts/KaTeX_Size3-Regular.woff | Bin 0 -> 4420 bytes .../static/fonts/KaTeX_Size3-Regular.woff2 | Bin 0 -> 3624 bytes .../static/fonts/KaTeX_Size4-Regular.woff | Bin 0 -> 5980 bytes .../static/fonts/KaTeX_Size4-Regular.woff2 | Bin 0 -> 4928 bytes .../fonts/KaTeX_Typewriter-Regular.woff | Bin 0 -> 16028 bytes .../fonts/KaTeX_Typewriter-Regular.woff2 | Bin 0 -> 13568 bytes .../static/fonts/LiberationMono.woff | Bin 0 -> 174632 bytes .../static/fonts/LiberationMono.woff2 | Bin 0 -> 123712 bytes .../static/fonts/LiberationSans-Bold.woff | Bin 0 -> 189564 bytes .../static/fonts/LiberationSans-Bold.woff2 | Bin 0 -> 134780 bytes .../fonts/LiberationSans-BoldItalic.woff | Bin 0 -> 192500 bytes .../fonts/LiberationSans-BoldItalic.woff2 | Bin 0 -> 138004 bytes .../static/fonts/LiberationSans-Italic.woff | Bin 0 -> 195116 bytes .../static/fonts/LiberationSans-Italic.woff2 | Bin 0 -> 139304 bytes .../static/fonts/LiberationSans.woff | Bin 0 -> 188280 bytes .../static/fonts/LiberationSans.woff2 | Bin 0 -> 133308 bytes .../hugo-geekdoc/static/fonts/Metropolis.woff | Bin 0 -> 16336 bytes .../static/fonts/Metropolis.woff2 | Bin 0 -> 11292 bytes .../hugo-geekdoc/static/img/geekdoc-stack.svg | 1 + .../static/js/116-341f79d9.chunk.min.js | 1 + .../static/js/118-f1de6a20.chunk.min.js | 1 + .../static/js/19-86f47ecd.chunk.min.js | 1 + .../static/js/361-f7cd601a.chunk.min.js | 1 + .../static/js/423-897d7f17.chunk.min.js | 1 + .../static/js/430-cc171d93.chunk.min.js | 1 + .../static/js/433-f2655a46.chunk.min.js | 1 + .../static/js/438-760c9ed3.chunk.min.js | 1 + .../static/js/476-86e5cf96.chunk.min.js | 1 + .../static/js/506-6950d52c.chunk.min.js | 1 + .../static/js/519-8d0cec7f.chunk.min.js | 1 + .../static/js/535-dcead599.chunk.min.js | 1 + .../static/js/545-8e970b03.chunk.min.js | 1 + .../static/js/546-560b35c2.chunk.min.js | 1 + .../static/js/579-9222afff.chunk.min.js | 1 + .../static/js/626-1706197a.chunk.min.js | 1 + .../static/js/637-86fbbecd.chunk.min.js | 2 + .../js/637-86fbbecd.chunk.min.js.LICENSE.txt | 9 + .../static/js/639-88c6538a.chunk.min.js | 1 + .../static/js/642-12e7dea2.chunk.min.js | 1 + .../static/js/662-17acb8f4.chunk.min.js | 2 + .../js/662-17acb8f4.chunk.min.js.LICENSE.txt | 9 + .../static/js/728-5df4a5e5.chunk.min.js | 1 + .../static/js/729-32b017b3.chunk.min.js | 1 + .../static/js/747-b55f0f97.chunk.min.js | 1 + .../static/js/76-732e78f1.chunk.min.js | 1 + .../static/js/771-942a62df.chunk.min.js | 1 + .../static/js/773-8f0c4fb8.chunk.min.js | 1 + .../static/js/81-4e653aac.chunk.min.js | 1 + .../static/js/813-0d3c16f5.chunk.min.js | 1 + .../static/js/940-25dfc794.chunk.min.js | 1 + .../js/colortheme-d3e4d351.bundle.min.js | 1 + .../static/js/katex-d4d5881d.bundle.min.js | 1 + .../static/js/main-924a1933.bundle.min.js | 2 + .../main-924a1933.bundle.min.js.LICENSE.txt | 6 + .../static/js/mermaid-d305d450.bundle.min.js | 1 + .../static/js/search-9719be99.bundle.min.js | 2 + .../search-9719be99.bundle.min.js.LICENSE.txt | 7 + .../static/katex-66092164.min.css | 1 + .../hugo-geekdoc/static/main-252d384c.min.css | 1 + .../static/mobile-79ddc617.min.css | 1 + .../static/print-735ccc12.min.css | 1 + docs/themes/hugo-geekdoc/theme.toml | 12 + .../metrics/examples/httpserver/Main.java | 2 + .../ExpositionFormatsTest.java | 6 +- .../model/snapshots/HistogramSnapshot.java | 9 +- .../bridge/SimpleclientCollector.java | 6 +- 255 files changed, 3538 insertions(+), 11 deletions(-) create mode 100644 docs/.gitignore create mode 100644 docs/README.md create mode 100644 docs/archetypes/default.md create mode 100644 docs/content/_index.md create mode 100644 docs/content/getting-started/_index.md create mode 100644 docs/content/getting-started/callbacks.md create mode 100644 docs/content/getting-started/labels.md create mode 100644 docs/content/getting-started/metric-types.md create mode 100644 docs/content/getting-started/quickstart.md create mode 100644 docs/content/getting-started/registry.md create mode 100644 docs/hugo.toml create mode 100644 docs/static/brand.svg create mode 100644 docs/static/favicon/favicon-16x16.png create mode 100644 docs/static/favicon/favicon-32x32.png create mode 100644 docs/static/favicon/favicon.ico create mode 100644 docs/static/favicon/favicon.svg create mode 100644 docs/themes/hugo-geekdoc/LICENSE create mode 100644 docs/themes/hugo-geekdoc/README.md create mode 100644 docs/themes/hugo-geekdoc/VERSION create mode 100644 docs/themes/hugo-geekdoc/archetypes/docs.md create mode 100644 docs/themes/hugo-geekdoc/archetypes/posts.md create mode 100644 docs/themes/hugo-geekdoc/assets/search/config.json create mode 100644 docs/themes/hugo-geekdoc/assets/search/data.json create mode 100644 docs/themes/hugo-geekdoc/assets/sprites/geekdoc.svg create mode 100644 docs/themes/hugo-geekdoc/data/assets.json create mode 100644 docs/themes/hugo-geekdoc/i18n/cs.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/de.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/en.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/es.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/it.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/ja.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/nl.yaml create mode 100644 docs/themes/hugo-geekdoc/i18n/zh-cn.yaml create mode 100644 docs/themes/hugo-geekdoc/images/readme.png create mode 100644 docs/themes/hugo-geekdoc/images/screenshot.png create mode 100644 docs/themes/hugo-geekdoc/images/tn.png create mode 100644 docs/themes/hugo-geekdoc/layouts/404.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/_markup/render-codeblock-mermaid.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/_markup/render-heading.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/_markup/render-image.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/_markup/render-link.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/baseof.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/list.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/single.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/taxonomy.html create mode 100644 docs/themes/hugo-geekdoc/layouts/_default/terms.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/foot.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/custom.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/favicons.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/meta.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/microformats.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/others.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/head/rel-me.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/language.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/menu-bundle.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/menu-extra.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/menu-filetree.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/menu-nextprev.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/menu.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/microformats/opengraph.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/microformats/schema.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/microformats/twitter_cards.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/page-header.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/pagination.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/posts/metadata.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/search.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/site-footer.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/site-header.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/svg-icon-symbols.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/utils/content.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/utils/description.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/utils/featured.html create mode 100644 docs/themes/hugo-geekdoc/layouts/partials/utils/title.html create mode 100644 docs/themes/hugo-geekdoc/layouts/posts/list.html create mode 100644 docs/themes/hugo-geekdoc/layouts/posts/single.html create mode 100644 docs/themes/hugo-geekdoc/layouts/robots.txt create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/button.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/columns.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/expand.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/hint.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/icon.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/img.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/include.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/katex.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/mermaid.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/progress.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/propertylist.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/tab.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/tabs.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/toc-tree.html create mode 100644 docs/themes/hugo-geekdoc/layouts/shortcodes/toc.html create mode 100644 docs/themes/hugo-geekdoc/static/brand.svg create mode 100644 docs/themes/hugo-geekdoc/static/custom.css create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-144x144.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-192x192.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-256x256.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-36x36.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-384x384.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-48x48.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-512x512.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-72x72.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/android-chrome-96x96.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-1024x1024.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-114x114.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-120x120.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-144x144.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-152x152.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-167x167.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-180x180.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-57x57.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-60x60.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-72x72.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-76x76.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-precomposed.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1125x2436.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1136x640.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1170x2532.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2208.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2688.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1284x2778.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1334x750.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1536x2048.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1620x2160.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1668x2224.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1668x2388.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1792x828.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2048x1536.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2048x2732.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2160x1620.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2208x1242.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2224x1668.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2388x1668.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2436x1125.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2532x1170.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2688x1242.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2732x2048.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2778x1284.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-640x1136.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-750x1334.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-828x1792.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/browserconfig.xml create mode 100644 docs/themes/hugo-geekdoc/static/favicon/favicon-16x16.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/favicon-32x32.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/favicon-48x48.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/favicon.ico create mode 100644 docs/themes/hugo-geekdoc/static/favicon/favicon.svg create mode 100644 docs/themes/hugo-geekdoc/static/favicon/manifest.json create mode 100644 docs/themes/hugo-geekdoc/static/favicon/mstile-144x144.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/mstile-150x150.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/mstile-310x150.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/mstile-310x310.png create mode 100644 docs/themes/hugo-geekdoc/static/favicon/mstile-70x70.png create mode 100644 docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_AMS-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_AMS-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Bold.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Bold.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Bold.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Bold.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-BoldItalic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-BoldItalic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-Italic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-Italic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Bold.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Bold.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Italic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Italic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Script-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Script-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size2-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size2-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size3-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size3-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size4-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size4-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Typewriter-Regular.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/KaTeX_Typewriter-Regular.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationMono.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationMono.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Bold.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Bold.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-BoldItalic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-BoldItalic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Italic.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Italic.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/fonts/Metropolis.woff create mode 100644 docs/themes/hugo-geekdoc/static/fonts/Metropolis.woff2 create mode 100644 docs/themes/hugo-geekdoc/static/img/geekdoc-stack.svg create mode 100644 docs/themes/hugo-geekdoc/static/js/116-341f79d9.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/118-f1de6a20.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/19-86f47ecd.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/361-f7cd601a.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/423-897d7f17.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/430-cc171d93.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/433-f2655a46.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/438-760c9ed3.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/476-86e5cf96.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/506-6950d52c.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/519-8d0cec7f.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/535-dcead599.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/545-8e970b03.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/546-560b35c2.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/579-9222afff.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/626-1706197a.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js.LICENSE.txt create mode 100644 docs/themes/hugo-geekdoc/static/js/639-88c6538a.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/642-12e7dea2.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/662-17acb8f4.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/662-17acb8f4.chunk.min.js.LICENSE.txt create mode 100644 docs/themes/hugo-geekdoc/static/js/728-5df4a5e5.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/729-32b017b3.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/747-b55f0f97.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/76-732e78f1.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/771-942a62df.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/773-8f0c4fb8.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/81-4e653aac.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/813-0d3c16f5.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/940-25dfc794.chunk.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/colortheme-d3e4d351.bundle.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/katex-d4d5881d.bundle.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/main-924a1933.bundle.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/main-924a1933.bundle.min.js.LICENSE.txt create mode 100644 docs/themes/hugo-geekdoc/static/js/mermaid-d305d450.bundle.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js create mode 100644 docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js.LICENSE.txt create mode 100644 docs/themes/hugo-geekdoc/static/katex-66092164.min.css create mode 100644 docs/themes/hugo-geekdoc/static/main-252d384c.min.css create mode 100644 docs/themes/hugo-geekdoc/static/mobile-79ddc617.min.css create mode 100644 docs/themes/hugo-geekdoc/static/print-735ccc12.min.css create mode 100644 docs/themes/hugo-geekdoc/theme.toml diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..2a8645fe5 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +.hugo_build.lock diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..5820df01f --- /dev/null +++ b/docs/README.md @@ -0,0 +1,37 @@ +Docs +---- + +This directory contains [hugo](https://gohugo.io) documentation to be published in Github pages. + +Run Locally +----------- + +``` +hugo server -D +``` + +This will serve the docs on [http://localhost:1313](http://localhost:1313). + +Deploy to Github Pages +---------------------- + +Changes to the `main` branch will be deployed automatically with Github actions. + +Set-up Notes +------------ + +Here's how the initial `docs/` folder was set up: + +``` +hugo new site docs +cd docs/ +mkdir -p themes/hugo-geekdoc/ +curl -L https://github.com/thegeeklab/hugo-geekdoc/releases/download/v0.41.1/hugo-geekdoc.tar.gz | tar -xz -C themes/hugo-geekdoc/ --strip-components=1 +``` + +Create the initial `hugo.toml` file as described in [https://geekdocs.de/usage/getting-started/](https://geekdocs.de/usage/getting-started/). + +Update Geekdocs +--------------- + +The docs use the [Geekdocs](https://geekdocs.de/) theme. The theme is checked in to Github in the `./docs/themes/hugo-geekdoc/` folder. To update [Geekdocs](https://geekdocs.de/), remove the current folder and create a new one with the latest [release](https://github.com/thegeeklab/hugo-geekdoc/releases). There are no local modifications in `./docs/themes/hugo-geekdoc/`. diff --git a/docs/archetypes/default.md b/docs/archetypes/default.md new file mode 100644 index 000000000..c6f3fcef6 --- /dev/null +++ b/docs/archetypes/default.md @@ -0,0 +1,5 @@ ++++ +title = '{{ replace .File.ContentBaseName "-" " " | title }}' +date = {{ .Date }} +draft = true ++++ diff --git a/docs/content/_index.md b/docs/content/_index.md new file mode 100644 index 000000000..cce8d5865 --- /dev/null +++ b/docs/content/_index.md @@ -0,0 +1,34 @@ +--- +title: "client_java" +--- + +Brainstorming of potential topics: + +* Getting started + * Quickstart + * Metrics Types + * Callbacks + * Native Histograms + * Naming conventions (unit, total, dots) + * Exposition Formats + * How to use the API for high performance applications +* Exporters + * HTTPServer + * Servlet + * Pushgateway + * OpenTelemetry +* Instrumentations + * JVM metrics + * Servlet filter +* OpenTelemetry + * OpenTelemetry exporter + * Combining Prometheus `client_java` with the OpenTelemetry instrumentation agent. + * Trace sampling and Exemplars + * API comparision: OpenTelemetry vs Prometheus + * Performance comparison: OpenTelemetry vs Prometheus +* Examples + * todo: examples directory +* Spring Boot Actuator / Micrometer +* Runtime Configuration +* Backwards Compatibility with Simpleclient +* Requirements (Java 8) diff --git a/docs/content/getting-started/_index.md b/docs/content/getting-started/_index.md new file mode 100644 index 000000000..427269117 --- /dev/null +++ b/docs/content/getting-started/_index.md @@ -0,0 +1,4 @@ +--- +title: Getting Started +weight: 1 +--- diff --git a/docs/content/getting-started/callbacks.md b/docs/content/getting-started/callbacks.md new file mode 100644 index 000000000..b94033fc5 --- /dev/null +++ b/docs/content/getting-started/callbacks.md @@ -0,0 +1,57 @@ +--- +title: Callbacks +weight: 5 +--- + +The section on [metric types](../metric-types) showed how to use metrics that actively maintain their state. + +This section shows how to create callback-based metrics, i.e. metrics that invoke a callback at scrape time to get the current values. + +For example, let's assume we have two instances of a `Cache`, a `coldCache` and a `hotCache`. The following implements a callback-based `cache_size_bytes` metric: + +```java +Cache coldCache = new Cache(); +Cache hotCache = new Cache(); + +GaugeWithCallback.builder() + .name("cache_size_bytes") + .help("Size of the cache in Bytes.") + .unit(Unit.BYTES) + .labelNames("state") + .callback(callback -> { + callback.call(coldCache.sizeInBytes(), "cold"); + callback.call(hotCache.sizeInBytes(), "hot"); + }) + .register(); +``` + +The resulting text format looks like this: + +``` +# TYPE cache_size_bytes gauge +# UNIT cache_size_bytes bytes +# HELP cache_size_bytes Size of the cache in Bytes. +cache_size_bytes{state="cold"} 78.0 +cache_size_bytes{state="hot"} 83.0 +``` + +Better examples of callback metrics can be found in the `prometheus-metrics-instrumentation-jvm` module. + +The available callback metric types are: + +* `GaugeWithCallback` for gauges. +* `CounterWithCallback` for counters. +* `SummaryWithCallback` for summaries. + +The API for gauges and counters is very similar. For summaries the callback has a few more parameters, because it accepts a count, a sum, and quantiles: + +```java +SummaryWithCallback.builder() + .name("example_callback_summary") + .help("help message.") + .labelNames("status") + .callback(callback -> { + callback.call(cache.getCount(), cache.getSum(), Quantiles.EMPTY, "ok"); + }) + .register(); +``` diff --git a/docs/content/getting-started/labels.md b/docs/content/getting-started/labels.md new file mode 100644 index 000000000..5aeb5f215 --- /dev/null +++ b/docs/content/getting-started/labels.md @@ -0,0 +1,149 @@ +--- +title: Labels +weight: 3 +--- + +The following shows an example of a Prometheus metric in text format: + +``` +# HELP payments_total total number of payments +# TYPE payments_total counter +payments_total{status="error",type="paypal"} 1.0 +payments_total{status="success",type="credit card"} 3.0 +payments_total{status="success",type="paypal"} 2.0 +``` + +The example shows a counter metric named `payments_total` with two labels: `status` and `type`. Each individual data point (each line in text format) is identified by the unique combination of its metric name and its label name/value pairs. + +Creating a Metric with Labels +----------------------------- + +Labels are supported for all metric types. We are using counters in this example, however the `labelNames()` and `labelValues()` methods are the same for other metric types. + +The following code creates the counter above. + +```java +Counter counter = Counter.builder() + .name("payments_total") + .help("total number of payments") + .labelNames("type", "status") + .register(); + +counter.labelValues("credit card", "success").inc(3.0); +counter.labelValues("paypal", "success").inc(2.0); +counter.labelValues("paypal", "error").inc(1.0); +``` + +The label names have to be specified when the metric is created and cannot change. The label values are created on demand when values are observed. + +Creating a Metric without Labels +-------------------------------- + +Labels are optional. The following example shows a metric without labels: + +```java +Counter counter = Counter.builder() + .name("payments_total") + .help("total number of payments") + .register(); + +counter.inc(3.0); +``` + +Cardinality Explosion +--------------------- + +Each combination of label names and values will result in a new data point, i.e. a new line in text format. +Therefore, a good label should have only a small number of possible values. +If you select labels with many possible values, like unique IDs or timestamps, you may end up with an enormous number of data points. +This is called cardinality explosion. + +Here's a bad example, don't do this: + +```java +Counter loginCount = Counter.builder() + .name("logins_total") + .help("total number of logins") + .labelNames("user_id", "timestamp") // not a good idea, this will result in too many data points + .register(); + +String userId = UUID.randomUUID().toString(); +String timestamp = Long.toString(System.currentTimeMillis()); + +loginCount.labelValues(userId, timestamp).inc(); +``` + +Initializing Label Values +------------------------- + +If you register a metric without labels, it will show up immediately with initial value of zero. + +However, metrics with labels only show up after the label values are first used. In the example above + +```java +counter.labelValues("paypal", "error").inc(); +``` + +The data point + +``` +payments_total{status="error",type="paypal"} 1.0 +``` + +will jump from non-existent to value 1.0. You will never see it with value 0.0. + +This is usually not an issue. However, if you find this annoying and want to see all possible label values from the start, you can initialize label values with `initLabelValues()` like this: + +```java +Counter counter = Counter.builder() + .name("payments_total") + .help("total number of payments") + .labelNames("type", "status") + .register(); + +counter.initLabelValues("credit card", "success"); +counter.initLabelValues("credit card", "error"); +counter.initLabelValues("paypal", "success"); +counter.initLabelValues("paypal", "error"); +``` + +Now the four combinations will be visible from the start with initial value zero. + +``` +# HELP payments_total total number of payments +# TYPE payments_total counter +payments_total{status="error",type="credit card"} 0.0 +payments_total{status="error",type="paypal"} 0.0 +payments_total{status="success",type="credit card"} 0.0 +payments_total{status="success",type="paypal"} 0.0 +``` + +Expiring Unused Label Values +---------------------------- + +There is no automatic expiry of unused label values (yet). Once a set of label values is used, it will remain there forever. + +However, you can programmatically remove label values like this: + +```java +counter.remove("paypal", "error"); +counter.remove("paypal", "success"); +``` + +Const Labels +------------ + +If you have labels values that never change, you can specify them in the builder as `constLabels()`: + +```java +Counter counter = Counter.builder() + .name("payments_total") + .help("total number of payments") + .constLabels(Labels.of("env", "dev")) + .labelNames("type", "status") + .register(); +``` + +However, most use cases for `constLabels()` are better covered by target labels set by the scraping Prometheus server, +or by one specific metric (e.g. a `build_info` or a `machine_role` metric). See also +[target labels, not static scraped labels](https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels). diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md new file mode 100644 index 000000000..5ffb02777 --- /dev/null +++ b/docs/content/getting-started/metric-types.md @@ -0,0 +1,222 @@ +--- +title: 'Metric Types' +weight: 4 +--- + +The Prometheus Java metrics library implements the metric types defined in the [OpenMetrics](https://openmetrics.io) standard: + +{{< toc >}} + +Counter +------- + +Counter is the most common and useful metric type. Counters can only increase, but never decrease. In the Prometheus query language, the [rate()](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) function is often used for counters to calculate the average increase per second. + +{{< hint type=note >}} +Counter values do not need to be integers. In many cases counters are used to count the number of events (like the number of requests), and in that case the counter value will be an integer. However, counters can also be used for something like "total time spent doing something" in which case the counter value is a floating point number. +{{< /hint >}} + +Here's an example of a counter: + +```java +Counter serviceTimeSeconds = Counter.builder() + .name("service_time_seconds_total") + .help("total time spent serving requests") + .unit(Unit.SECONDS) + .register(); + +serviceTimeSeconds.inc(Unit.millisToSeconds(200)); +``` + +The resulting counter has the value `0.2`. As `SECONDS` is the standard time unit in Prometheus, the `Unit` utility class has methods to convert other time units to seconds. + +As defined in [OpenMetrics](https://openmetrics.io/), counter metric names must have the `_total` suffix. If you create a counter without the `_total` suffix the suffix will be appended automatically. + +Gauge +----- + +Gauges are current measurements, such as the current temperature in Celsius. + +```java +Gauge temperature = Gauge.builder() + .name("temperature_celsius") + .help("current temperature") + .labelNames("location") + .unit(Unit.CELSIUS) + .register(); + +temperature.labelValues("Berlin").set(22.3); +``` + +Histogram +--------- + +Histograms are for observing distributions, like latency distributions for HTTP services or the distribution of request sizes. +Unlike with counters and gauges, each histogram data point has a complex data structure representing different aspects of the distribution: + +* Count: The toal number of observations. +* Sum: The sum of all observed values, e.g. the total time spent serving requests. +* Buckets: The histogram buckets representing the distribution. + +Prometheus supports two flavors of histograms: + +* Classic histograms: Bucket boundaries are explicitly defined when the histogram is created. +* Native histograms (exponential histograms): Infinitly many virtual buckets. + +By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. If the Prometheus server has native histograms enabled, it will request metrics in Prometheus protobuf format, and in that case both classic and native representation are exposed. If the Prometheus server does not have native histograms enabled, it will request OpenMetrics text format, and in that case only the classic representation is exposed. + +```java +Histogram duration = Histogram.builder() + .name("http_request_duration_seconds") + .help("HTTP request service time in seconds") + .unit(Unit.SECONDS) + .labelNames("method", "path", "status_code") + .register(); + +long start = System.nanoTime(); +// do something +duration.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start)); +``` + +Histograms implement the `TimerApi` interface, which provides convenience methods for measuring durations. + +The histogram builder provides a lot of configuration for fine-tuning the histogram behavior. In most cases you don't need them, defaults are good. The following is an incomplete list showing the most important options: + +* `nativeOnly()` / `classicOnly()`: Create a histogram with one representation only. +* `classicBuckets(...)`: Set the classic bucket boundaries. Default buckets are `.005`, `.01`, `.025`, `.05`, `.1`, `.25`, `.5`, `1`, `2.5`, `5`, `and 10`. The default bucket boundaries are designed for measuring request durations in seconds. +* `nativeMaxNumberOfBuckets()`: Upper limit for the number of native histogram buckets. Default is 160. When the maximum is reached, the native histogram automatically reduces resolution to stay below the limit. + +See Javadoc for a complete list of options. + +Histograms and summaries are both used for observing distributions. Therefore, the both implement the `DistributionDataPoint` interface. Using the `DistributionDataPoint` interface directly gives you the option to switch between histograms and summaries later with minimal code changes. + +Example of using the `DistributionDataPoint` interface for a histogram without labels: + +```java +DistributionDataPoint eventDuration = Histogram.builder() + .name("event_duration_seconds") + .help("event duration in seconds") + .unit(Unit.SECONDS) + .register(); + +// The following still works perfectly fine if eventDuration +// is backed by a summary rather than a histogram. +eventDuration.observe(0.2); +``` + +Example of using the `DistributionDataPoint` interface for a histogram with labels: + +```java +Histogram eventDuration = Histogram.builder() + .name("event_duration_seconds") + .help("event duration in seconds") + .labelNames("status") + .unit(Unit.SECONDS) + .register(); + +DistributionDataPoint successfulEvents = eventDuration.labelValues("ok"); +DistributionDataPoint erroneousEvents = eventDuration.labelValues("error"); + +// Like in the example above, the following still works perfectly fine +// if the successfulEvents and erroneousEvents are backed by a summary rather than a histogram. +successfulEvents.observe(0.7); +erroneousEvents.observe(0.2); +``` + +Summary +------- + +Like histograms, summaries are for observing distributions. Each summary data point has a count and a sum like a histogram data point. +However, rather than histogram buckets summaries maintain quantiles. + +```java +Summary requestLatency = Summary.builder() + .name("request_latency_seconds") + .help("Request latency in seconds.") + .unit(Unit.SECONDS) + .quantile(0.5, 0.01) + .quantile(0.95, 0.005) + .quantile(0.99, 0.005) + .labelNames("status") + .register(); + +requestLatency.labelValues("ok").observe(2.7); +``` + +The example above creates a summary with the 50th percentile (median), the 95th percentila, and the 99th percentile. Quantiles are optional, you can create a summary without quantiles if all you need is the count and the sum. + +{{< hint type=note >}} +The terms "percentile" and "quantile" mean the same thing. We use percentile when we express it as a number in [0, 100], and we use quantile when we express it as a number in [0.0, 1.0]. +{{< /hint >}} + +The second parameter to `quantile()` is the maximum acceptable error. The call `.quantile(0.5, 0.01)` means that the actual quantile is somewhere in [0.49, 0.51]. Higher presicion means higher memory usage. + +The 0.0 quantile (min value) and the 1.0 quantile (max value) are special cases because you can get the precise values (error 0.0) with almost no memory overhead. + +Quantile values are calculated based on a 5 minutes moving time window. The default time window can be changed with `maxAgeSeconds()` and `numberOfAgeBuckets()`. + +In general you should prefer histograms over summaries. The Prometheus query language has a function [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for calculating quantiles from histograms. The advantage of query-time quantile calculation is that you can aggregate histograms before calculating the quantile. With summaries you must use the quantile with all its labels as it is. + +Info +---- + +Info metrics are used to expose textual information which should not change during process lifetime. The value of an Info metric is always `1`. + +```java +Info info = Info.builder() + .name("jvm_runtime_info") + .help("JVM runtime info") + .labelNames("version", "vendor", "runtime") + .register(); + +String version = System.getProperty("java.runtime.version", "unknown"); +String vendor = System.getProperty("java.vm.vendor", "unknown"); +String runtime = System.getProperty("java.runtime.name", "unknown"); + +info.setLabelValues(version, vendor, runtime); +``` + +The info above looks as follows in OpenMetrics text format: + +``` +# TYPE jvm_runtime info +# HELP jvm_runtime JVM runtime info +jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1 +``` + +The example is taken from the `prometheus-metrics-instrumentation-jvm` module, so if you have `JvmMetrics` registered you should have a `jvm_runtime_info` metric out-of-the-box. + +As defined in [OpenMetrics](https://openmetrics.io/), info metric names must have the `_info` suffix. If you create a counter without the `_info` suffix the suffix will be appended automatically. + +StateSet +-------- + +StateSet are a niche metric type in the OpenMetrics standard that is rarely used. The main use case is to signal which feature flags are enabled. + +```java +StateSet stateSet = StateSet.builder() + .name("feature_flags") + .help("Feature flags") + .labelNames("env") + .states("feature1", "feature2") + .register(); + +stateSet.labelValues("dev").setFalse("feature1"); +stateSet.labelValues("dev").setTrue("feature2"); +``` + +The OpenMetrics text format looks like this: + +``` +# TYPE feature_flags stateset +# HELP feature_flags Feature flags +feature_flags{env="dev",feature_flags="feature1"} 0 +feature_flags{env="dev",feature_flags="feature2"} 1 +``` + +GaugeHistogram and Unknown +-------------------------- + +These types are defined in the [OpenMetrics](https://openmetrics.io/) standard but not implemented in the `prometheus-metrics-core` API. +However, `prometheus-metrics-model` implements the underlying data model for these types. +To use these types, you need to implement your own `Collector` where the `collect()` method returns an `UnknownSnapshot` or a `HistogramSnapshot` with `.gaugeHistogram(true)`. diff --git a/docs/content/getting-started/quickstart.md b/docs/content/getting-started/quickstart.md new file mode 100644 index 000000000..3bf5364d9 --- /dev/null +++ b/docs/content/getting-started/quickstart.md @@ -0,0 +1,107 @@ +--- +title: Quickstart +weight: 1 +--- + +This tutorial shows the quickest way to get started with the Prometheus Java metrics library. + +# Dependencies + +We use the following dependencies: + +* `prometheus-metrics-core` is the actual metrics library. +* `prometheus-metrics-instrumentation-jvm` provides out-of-the-box JVM metrics. +* `prometheus-metrics-exporter-httpserver` is a standalone HTTP server for exposing Prometheus metrics. +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-core:1.0.0' +implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm:1.0.0' +implementation 'io.prometheus:prometheus-metrics-exporter-httpserver:1.0.0' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-core + 1.0.0 + + + io.prometheus + prometheus-metrics-instrumentation-jvm + 1.0.0 + + + io.prometheus + prometheus-metrics-exporter-httpserver + 1.0.0 + +``` +{{< /tab >}} +{{< /tabs >}} + +There are alternative exporters as well, for example if you are using a Servlet container like Tomcat or Undertow you might want to use `prometheus-exporter-servlet-jakarta` rather than a standalone HTTP server. + + +# Example Application + +```java +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; + +import java.io.IOException; + +public class App { + + public static void main(String[] args) throws InterruptedException, IOException { + + JvmMetrics.builder().register(); // initialize the out-of-the-box JVM metrics + + Counter counter = Counter.builder() + .name("my_count_total") + .help("example counter") + .labelNames("status") + .register(); + + counter.labelValues("ok").inc(); + counter.labelValues("ok").inc(); + counter.labelValues("error").inc(); + + HTTPServer server = HTTPServer.builder() + .port(9400) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + Thread.currentThread().join(); // sleep forever + } +} +``` + +# Result + +Run the application and view [http://localhost:9400/metrics](http://localhost:9400/metrics) with your browser to see the raw metrics. You should see the `my_count_total` metric as shown below plus the `jvm_` and `process_` metrics coming from `JvmMetrics`. + +``` +# HELP my_count_total example counter +# TYPE my_count_total counter +my_count_total{status="error"} 1.0 +my_count_total{status="ok"} 2.0 +``` + +# Prometheus Configuration + +To scrape the metrics with a Prometheus server, download the latest Prometheus server [release](https://github.com/prometheus/prometheus/releases), and configure the `prometheus.yml` file as follows: + +```yaml +global: + scrape_interval: 10s # short interval for manual testing + +scrape_configs: + + - job_name: "java-example" + static_configs: + - targets: ["localhost:9400"] +``` diff --git a/docs/content/getting-started/registry.md b/docs/content/getting-started/registry.md new file mode 100644 index 000000000..403d834dd --- /dev/null +++ b/docs/content/getting-started/registry.md @@ -0,0 +1,90 @@ +--- +title: Registry +weight: 2 +--- + +In order to expose metrics, you need to register them with a `PrometheusRegistry`. We are using a counter as an example here, but the `register()` method is the same for all metric types. + +Registering a Metrics with the Default Registry +----------------------------------------------- + +```java +Counter eventsTotal = Counter.builder() + .name("events_total") + .help("Total number of events") + .register(); // <-- implicitly uses PrometheusRegistry.defaultRegistry +``` + +The `register()` call above builds the counter and registers it with the global static `PrometheusRegistry.defaultRegistry`. Using the default registry is recommended. + +Registering a Metrics with a Custom Registry +-------------------------------------------- + +You can also register your metric with a custom registry: + +```java +PrometheusRegistry myRegistry = new PrometheusRegistry(); + +Counter eventsTotal = Counter.builder() + .name("events_total") + .help("Total number of events") + .register(myRegistry); +``` + +Registering a Metric with Multiple Registries +--------------------------------------------- + +As an alternative to calling `register()` direclty, you can `build()` metrics without registering them, +and register them later: + +```java + +// create a counter that is not registered with any registry + +Counter eventsTotal = Counter.builder() + .name("events_total") + .help("Total number of events") + .build(); // <-- this will create the metric but not register it + +// register the counter with the default registry + +PrometheusRegistry.defaultRegistry.register(eventsTotal); + +// register the counter with a custom registry. +// This is ok, you can register a metric with multiple registries. + +PrometheusRegistry myRegistry = new PrometheusRegistry(); +myRegistry.register(eventsTotal); +``` + +Custom registries are useful if you want to maintain different scopes of metrics, like +a debug registry with a lot of metrics, and a default registry with only a few metrics. + +IllegalArgumentException: Duplicate Metric Name in Registry +----------------------------------------------------------- + +While it is ok to register the same metric with multiple registries, it is illegal to register the same metric name multiple times with the same registry. +The following code will throw an `IllegalArgumentException`: + +```java +Counter eventsTotal1 = Counter.builder() + .name("events_total") + .help("Total number of events") + .register(); + +Counter eventsTotal2 = Counter.builder() + .name("events_total") + .help("Total number of events") + .register(); // <-- IllegalArgumentException, because a metric with that name is already registered +``` + +Unregistering a Metric +---------------------- + +There is no automatic expiry of unused metrics (yet), once a metric is registered it will remain registered forever. + +However, you can programmatically unregistered an obsolete metric like this: + +```java +PrometheusRegistry.defaultRegistry.unregister(eventsTotal); +``` diff --git a/docs/hugo.toml b/docs/hugo.toml new file mode 100644 index 000000000..b453bcd2a --- /dev/null +++ b/docs/hugo.toml @@ -0,0 +1,30 @@ +baseURL = "http://localhost" +languageCode = 'en-us' +title = "client_java" +theme = "hugo-geekdoc" + +pluralizeListTitles = false + +# Geekdoc required configuration +#pygmentsUseClasses = true +pygmentsUseClasses = false +pygmentsCodeFences = true +disablePathToLower = true +# geekdocFileTreeSortBy = "linkTitle" + +# Required if you want to render robots.txt template +enableRobotsTXT = true + +# Needed for mermaid shortcodes +[markup] + [markup.goldmark.renderer] + # Needed for mermaid shortcode + unsafe = true + [markup.tableOfContents] + startLevel = 1 + endLevel = 9 + [markup.highlight] + style = 'solarized-dark' + +[taxonomies] + tag = "tags" diff --git a/docs/static/brand.svg b/docs/static/brand.svg new file mode 100644 index 000000000..5c51f66d9 --- /dev/null +++ b/docs/static/brand.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/docs/static/favicon/favicon-16x16.png b/docs/static/favicon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..7a8cc5816162163aa5e26006f27e74397b81a6c1 GIT binary patch literal 546 zcmV+-0^R+IP){gx%Wy*<#&M$=VPu28=?jvO*F4LMg6S(6n9)f z_1NuH4%9CchNb=rTQ8w}zwO+t14TNMhjxzXJ50xm$6kl@zvLEl$7tPhuIe${sUE-MY&d3H?K>|a zO#sSRE5f|E7V^gYoSplw(!TvdVaV(9&m~JC!^N08%3(1)12FmVE45R0S2=ncd8nPf zm-x3I05Uv+g`yA^!*yt8xZk@pIFERvVb%s|B}I=Sdo^;D3^%P?tDs-|WFidi@lV&kbjn$~2Gxu0C}kh5U$|-V4vD z_B0TMfi{yL)NcD&=tv6q;OtQop`FW-`1}Fv%?iOPCvg!iw9wN_S=g(fmF8|I2TVXct~q1~%sLXSz>k5@k% z1`2GP2TOHsdG9)K4{9oc2?PA>ozff5u2o^>@15Oih!i!UVebrNAWxtzamKCzjTkH= ztaY=)S|^(lT-gEMgL<&HEG~|OKSOAjsa?26{-yzRB1yX2fA1=6jq|+=@EMtzjs;<> zpG*0^dPaCgwl&BGp)jdM1K0!uh4!vh53UA}#L=+=Vs1N3Xa)`7J`5CCHBGF{lmQyG zwLD&D>HAv(Y7>VwpTErr!;^V3=}jIRiB69@s<_E)#Nn zrP^>LiK%3P6pRC8nU&AQ(p&#s>giKED?&S#gM!RfEycOTv-liM0|9(4S%QDX6u5fU zf^X(Pg!Zh4Z_ZHhaO3SSBZ^UA-7I*=cLD2z=$smQMgw@LntFFGiEhV+qmfNcb7#}HUOT?A(aDAX{|yR2b{)YyKZIW&N7T7^jRd${#O z#Ngo?&^TG}e?)_lLIG$fLh8`~GLz@fkQ^TooiHUBwC0=SUmC!-WT9rgJhGL2z8yTH zJ0uUz2GR3}p`$S$x8p*@2^IO5PlBa#YH^{GMU}J&ZeOZ5tY-Syz_(-yRK$nC(V;w? zohy;bCaJ`JP*LojiX_rsZ6y1boWW<})QgzMftc4R3JOcCK2EFhw;rc>Z&1;0^0U@l zSb#i+hQfz7!#$)q+{0R_GqeSw=MEap0GW*@<1!j1`0zu@Fj74O$@mF8cQLXh+`a@2 z-5~kYqpI)3St65n5^3dMHi6YHhhl=gLBOwV4f3$$&R2U?lgI&*ML(+gotR2opVx)R ziCyrF>n!F!PRj63>M2rA<)y?zMv&i9`hNHwDL@vG7az555lr%Xm4cI$gpZU+9+T-L z2l+-nig_cMNH?;LJR$)SQ$QTKPd1SDBn|o2%(MRomnf~A{KP=l00000NkvXXu0mjf Dv=$Vq literal 0 HcmV?d00001 diff --git a/docs/static/favicon/favicon.ico b/docs/static/favicon/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..34bd1fbf0d44900e5e6e2298c58b4b124126d3e3 GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/docs/static/favicon/favicon.svg b/docs/static/favicon/favicon.svg new file mode 100644 index 000000000..5c51f66d9 --- /dev/null +++ b/docs/static/favicon/favicon.svg @@ -0,0 +1,50 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/LICENSE b/docs/themes/hugo-geekdoc/LICENSE new file mode 100644 index 000000000..3812eb46b --- /dev/null +++ b/docs/themes/hugo-geekdoc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Robert Kaussow + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/docs/themes/hugo-geekdoc/README.md b/docs/themes/hugo-geekdoc/README.md new file mode 100644 index 000000000..99358d83c --- /dev/null +++ b/docs/themes/hugo-geekdoc/README.md @@ -0,0 +1,46 @@ +# Geekdoc + +[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/hugo-geekdoc/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/hugo-geekdoc) +[![Hugo Version](https://img.shields.io/badge/hugo-0.112-blue.svg)](https://gohugo.io) +[![GitHub release](https://img.shields.io/github/v/release/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/releases/latest) +[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/graphs/contributors) +[![License: MIT](https://img.shields.io/github/license/thegeeklab/hugo-geekdoc)](https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE) + +Geekdoc is a simple Hugo theme for documentations. It is intentionally designed as a fast and lean theme and may not fit the requirements of complex projects. If a more feature-complete theme is required there are a lot of good alternatives out there. You can find a demo and the full documentation at [https://geekdocs.de](https://geekdocs.de). + +![Desktop and mobile preview](https://raw.githubusercontent.com/thegeeklab/hugo-geekdoc/main/images/readme.png) + +## Build and release process + +This theme is subject to a CI driven build and release process common for software development. During the release build, all necessary assets are automatically built by [webpack](https://webpack.js.org/) and bundled in a release tarball. You can download the latest release from the GitHub [release page](https://github.com/thegeeklab/hugo-geekdoc/releases). + +Due to the fact that `webpack` and `npm scripts` are used as pre-processors, the theme cannot be used from the main branch by default. If you want to use the theme from a cloned branch instead of a release tarball you'll need to install `webpack` locally and run the build script once to create all required assets. + +```shell +# install required packages from package.json +npm install + +# run the build script to build required assets +npm run build + +# build release tarball +npm run pack +``` + +See the [Getting Started Guide](https://geekdocs.de/usage/getting-started/) for details about the different setup options. + +## Contributors + +Special thanks to all [contributors](https://github.com/thegeeklab/hugo-geekdoc/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/hugo-geekdoc/blob/main/CONTRIBUTING.md). + +Geekdoc is inspired and partially based on the [hugo-book](https://github.com/alex-shpak/hugo-book) theme, thanks [Alex Shpak](https://github.com/alex-shpak/) for your work. + +## License + +This project is licensed under the MIT License - see the [LICENSE](https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE) file for details. + +The used SVG icons and generated icon fonts are licensed under the license of the respective icon pack: + +- Font Awesome: [CC BY 4.0 License](https://github.com/FortAwesome/Font-Awesome#license) +- IcoMoon Free Pack: [GPL/CC BY 4.0](https://icomoon.io/#icons-icomoon) +- Material Icons: [Apache License 2.0](https://github.com/google/material-design-icons/blob/main/LICENSE) diff --git a/docs/themes/hugo-geekdoc/VERSION b/docs/themes/hugo-geekdoc/VERSION new file mode 100644 index 000000000..d0cca40aa --- /dev/null +++ b/docs/themes/hugo-geekdoc/VERSION @@ -0,0 +1 @@ +v0.41.1 diff --git a/docs/themes/hugo-geekdoc/archetypes/docs.md b/docs/themes/hugo-geekdoc/archetypes/docs.md new file mode 100644 index 000000000..aa0d88f7b --- /dev/null +++ b/docs/themes/hugo-geekdoc/archetypes/docs.md @@ -0,0 +1,7 @@ +--- +title: "{{ .Name | humanize | title }}" +weight: 1 +# geekdocFlatSection: false +# geekdocToc: 6 +# geekdocHidden: false +--- diff --git a/docs/themes/hugo-geekdoc/archetypes/posts.md b/docs/themes/hugo-geekdoc/archetypes/posts.md new file mode 100644 index 000000000..fdccff8ae --- /dev/null +++ b/docs/themes/hugo-geekdoc/archetypes/posts.md @@ -0,0 +1,4 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +--- diff --git a/docs/themes/hugo-geekdoc/assets/search/config.json b/docs/themes/hugo-geekdoc/assets/search/config.json new file mode 100644 index 000000000..1a5582a2e --- /dev/null +++ b/docs/themes/hugo-geekdoc/assets/search/config.json @@ -0,0 +1,8 @@ +{{- $searchDataFile := printf "search/%s.data.json" .Language.Lang -}} +{{- $searchData := resources.Get "search/data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify -}} +{ + "dataFile": {{ $searchData.RelPermalink | jsonify }}, + "indexConfig": {{ .Site.Params.geekdocSearchConfig | jsonify }}, + "showParent": {{ if .Site.Params.geekdocSearchShowParent }}true{{ else }}false{{ end }}, + "showDescription": {{ if .Site.Params.geekdocSearchshowDescription }}true{{ else }}false{{ end }} +} diff --git a/docs/themes/hugo-geekdoc/assets/search/data.json b/docs/themes/hugo-geekdoc/assets/search/data.json new file mode 100644 index 000000000..f1c0e804e --- /dev/null +++ b/docs/themes/hugo-geekdoc/assets/search/data.json @@ -0,0 +1,13 @@ +[ + {{ range $index, $page := (where .Site.Pages "Params.geekdocProtected" "ne" true) }} + {{ if ne $index 0 }},{{ end }} + { + "id": {{ $index }}, + "href": "{{ $page.RelPermalink }}", + "title": {{ (partial "utils/title" $page) | jsonify }}, + "parent": {{ with $page.Parent }}{{ (partial "utils/title" .) | jsonify }}{{ else }}""{{ end }}, + "content": {{ $page.Plain | jsonify }}, + "description": {{ $page.Summary | plainify | jsonify }} + } + {{ end }} +] diff --git a/docs/themes/hugo-geekdoc/assets/sprites/geekdoc.svg b/docs/themes/hugo-geekdoc/assets/sprites/geekdoc.svg new file mode 100644 index 000000000..4f3cfd291 --- /dev/null +++ b/docs/themes/hugo-geekdoc/assets/sprites/geekdoc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/data/assets.json b/docs/themes/hugo-geekdoc/data/assets.json new file mode 100644 index 000000000..9a34ed54d --- /dev/null +++ b/docs/themes/hugo-geekdoc/data/assets.json @@ -0,0 +1,158 @@ +{ + "main.js": { + "src": "js/main-924a1933.bundle.min.js", + "integrity": "sha512-0QF6awwW0WbBo491yytmULiHrc9gx94bloJ9MSXIvdJh3YHWw7CWyeX2YXu0rzOQefJp4jW/I6ZjUDYpNVFhdA==" + }, + "colortheme.js": { + "src": "js/colortheme-d3e4d351.bundle.min.js", + "integrity": "sha512-HpQogL/VeKqG/v1qYOfJOgFUzBnQvW4yO4tAJO+54IiwbLbB9feROdeaYf7dpO6o5tSHsSZhaYLhtLMRlEgpJQ==" + }, + "mermaid.js": { + "src": "js/mermaid-d305d450.bundle.min.js", + "integrity": "sha512-TASG03QptoVv1mkfOL47vm5A5kvmyOrnsi8PXhc82j1+FuHZuMOHXc2x5/jGEkOxbKi7mum0h/W7qYhrV29raw==" + }, + "katex.js": { + "src": "js/katex-d4d5881d.bundle.min.js", + "integrity": "sha512-M8CLtMTu/HVXo11Et+lv3OqPanLf5Bl+GljNAn2yQuLclg/ZpZK1KUpHDRsZJhmkhCcCH90+bVj5CW3lLlmBgg==" + }, + "search.js": { + "src": "js/search-9719be99.bundle.min.js", + "integrity": "sha512-/7NZxFUEbalC/8RKDgfAsHFDI42/Ydp33uJmCLckZgnO+kuz9LrTfmPFfVJxPJ31StMxa3MTQ5Jq049CmNK4pw==" + }, + "js/637-86fbbecd.chunk.min.js": { + "src": "js/637-86fbbecd.chunk.min.js", + "integrity": "sha512-vD1y0C4MPPV/JhEKmNVAye9SQg7mB5v87nLf63keSALdnM7P+L0ybjEn2MzYzVTzs6JnOCryM7A6/t0TkYucDA==" + }, + "js/116-341f79d9.chunk.min.js": { + "src": "js/116-341f79d9.chunk.min.js", + "integrity": "sha512-F7tq1KsF5mnJl0AAA6x2jZcx8x69kEZrUIZJJM4RZ1KlEO79yrrFHf4CZRvhNrYOxmkBpkQ84U9J0vFtRPKjTw==" + }, + "js/545-8e970b03.chunk.min.js": { + "src": "js/545-8e970b03.chunk.min.js", + "integrity": "sha512-vDOXX1FstnT8UMkRIAMn6z4ucL8LVqI5kZw+T7LrD8pGC9xtKwwhWcmNeqnngc7FHc5Ogt7ppXBNp+uFPUgrJg==" + }, + "js/728-5df4a5e5.chunk.min.js": { + "src": "js/728-5df4a5e5.chunk.min.js", + "integrity": "sha512-vX2dPV1VjOgv8DP4XbZ9xk9ZzHS9hPAUwPfHM8UG42efxXxH/qCqTpyavqob98onxR2FuiF+j1Vn56d3wqsgaw==" + }, + "js/81-4e653aac.chunk.min.js": { + "src": "js/81-4e653aac.chunk.min.js", + "integrity": "sha512-a80h3DpDlMG6HhYXv9n9Q7r1M+rQX5kfJ7sFhfmPHlDRVimult9nn7vvTHFzTzmMFM+tLcfg4pZGd+AkxPcjEw==" + }, + "js/430-cc171d93.chunk.min.js": { + "src": "js/430-cc171d93.chunk.min.js", + "integrity": "sha512-cqQyiIE22ZPo2PIPR4eb0DPSu1TWjxgJUKrIIyfVF48gc2vdLKnbHzWBZg6MpiOWYmUvJb5Ki+n5U6qEvNp2KQ==" + }, + "js/729-32b017b3.chunk.min.js": { + "src": "js/729-32b017b3.chunk.min.js", + "integrity": "sha512-KAW7lnN0NHmIzfD6aIwVaU3TcpUkO8ladLrbOE83zq80NOJH/MGS4Ep+2rIfQZTvZP+a7nqZLHkmezfs27c2pw==" + }, + "js/773-8f0c4fb8.chunk.min.js": { + "src": "js/773-8f0c4fb8.chunk.min.js", + "integrity": "sha512-HxtbZvs0J28pB9fImN8n82aprG/GW0QenIBzC7BHWhEUX6IhmxTeBqG4IZFbbAURG17VegOr2UlJg6w0qaX9gw==" + }, + "js/433-f2655a46.chunk.min.js": { + "src": "js/433-f2655a46.chunk.min.js", + "integrity": "sha512-/yMUz6rxhVpvCPpQG+f28jFgdJK+X/5/3XWVsrAE2FHC57jxnHaL7SxZluZ4klUl0YsRCrhxAQj8maNspwwH1Q==" + }, + "js/546-560b35c2.chunk.min.js": { + "src": "js/546-560b35c2.chunk.min.js", + "integrity": "sha512-am1/hYno7/cFQ8reHZqnbsth2KcphvKqLfkueVIm8I/i/6f9u+bbc0Z6zpYTLysl3oWddYXqyeO58zXoJoDVIA==" + }, + "js/118-f1de6a20.chunk.min.js": { + "src": "js/118-f1de6a20.chunk.min.js", + "integrity": "sha512-tikydCOmBT1keN0AlCqvkpvbV1gB9U8lVXX8wmrS6fQ2faNc8DnH1QV9dzAlLtGeA1p8HAXnh+AevnVKxhXVbg==" + }, + "js/19-86f47ecd.chunk.min.js": { + "src": "js/19-86f47ecd.chunk.min.js", + "integrity": "sha512-qRG0UrV25Kr/36tJTPZ49QobR6a/zv2BRAMDzSZwjlPgqSwse1HtgP9EEZtn59b1Vq7ayB1LoWfB9MZ9Gcm7Gw==" + }, + "js/361-f7cd601a.chunk.min.js": { + "src": "js/361-f7cd601a.chunk.min.js", + "integrity": "sha512-7kwaFQhXUyiM/v2v0n6vI9wz6nSAu7sz2236r+MbwT0r4aBxYqeOxij+PkGnTUqR2n1UExnbWKjuruDi9V/H5g==" + }, + "js/519-8d0cec7f.chunk.min.js": { + "src": "js/519-8d0cec7f.chunk.min.js", + "integrity": "sha512-tFsZN3iyUMIMeB/b4E1PZNOFDKqMM4Fes63RGNkHNhtRTL/AIUpqPcTKZ+Fi2ZTdyYvPSTtjc5urnzLUi196Wg==" + }, + "js/747-b55f0f97.chunk.min.js": { + "src": "js/747-b55f0f97.chunk.min.js", + "integrity": "sha512-hoyvC5SSJcX9NGij9J9l4Ov1JAFNBX0UxlFXyiB5TC7TGW3lgIvm41zyfKhLyJudVGftY/qKxIO2EYtYD2pqOQ==" + }, + "js/642-12e7dea2.chunk.min.js": { + "src": "js/642-12e7dea2.chunk.min.js", + "integrity": "sha512-ZVUj7NYSa8mMHdWaztAf3DCg7qznXTbMWWwqJaS2nfaqh0lVDOf5kVExPy6SGkXCeNu/B9gGbWLtDUa7kHFF6A==" + }, + "js/626-1706197a.chunk.min.js": { + "src": "js/626-1706197a.chunk.min.js", + "integrity": "sha512-OlpbPXiGmQJR/ISfBSsHU2UGATggZDuHbopvAhhfVpw7ObMZgc/UvE6pK1FmGCjgI9iS+qmPhQyvf9SIbLFyxQ==" + }, + "js/438-760c9ed3.chunk.min.js": { + "src": "js/438-760c9ed3.chunk.min.js", + "integrity": "sha512-Wo2DxS59Y8DVBTWNWDUmg6V+UCyLoiDd4sPs2xc7TkflQy7reGWPt/oHZCANXeGjZPpqcR3qfKYidNofUyIWEA==" + }, + "js/639-88c6538a.chunk.min.js": { + "src": "js/639-88c6538a.chunk.min.js", + "integrity": "sha512-KbTKHxx+/Xwv+GH8jQsIJ9X1CFaGSsqgeSXnR8pW27YZpFz4ly8R6K7h+yq6P2b2AzQdW7krradZzyNo7Vz26w==" + }, + "js/940-25dfc794.chunk.min.js": { + "src": "js/940-25dfc794.chunk.min.js", + "integrity": "sha512-qst5aejItmhzMvZ3CsAXyJe2F3FtLkyZwBqj422/8ViyQptcQFgP3x8bPsLwJEfiWFJVrLJkk4VhwflQuIyDtw==" + }, + "js/662-17acb8f4.chunk.min.js": { + "src": "js/662-17acb8f4.chunk.min.js", + "integrity": "sha512-S/UlqDqwt++RzVZMVqjsdCNyhe1xNQ9/Qm38yIphmXfn9VBHzGqobIQTuhloYZVfTE4/GezrH+1T7mdrUqpAKQ==" + }, + "js/579-9222afff.chunk.min.js": { + "src": "js/579-9222afff.chunk.min.js", + "integrity": "sha512-rl3bxxl/uhUFYlIuoHfVQE+VkmxfJr7TAuC/fxOBJXBCCMpdxP0XCPzms1zjEjOVjIs4bi4SUwn8r4STSl09Lg==" + }, + "js/771-942a62df.chunk.min.js": { + "src": "js/771-942a62df.chunk.min.js", + "integrity": "sha512-8WfA8U1Udlfa6uWAYbdNKJzjlJ91qZ0ZhC+ldKdhghUgilxqA6UmZxHFKGRDQydjOFDk828O28XVmZU2IEvckA==" + }, + "js/506-6950d52c.chunk.min.js": { + "src": "js/506-6950d52c.chunk.min.js", + "integrity": "sha512-h2po0SsM4N3IXiBbNWlIbasxX7zSm5XVDpgYfmsEmcfQkMcFwJtTJGppek085Mxi1XZmrhjfxq2AUtnUs03LJg==" + }, + "js/76-732e78f1.chunk.min.js": { + "src": "js/76-732e78f1.chunk.min.js", + "integrity": "sha512-ZjF2oB76jiCtdQNJZ9v1MUJSPaBcZCXmTA2T3qDBuU260uVA99wGeprrNQ3WdHQeK+VYXCq26dOE9w+I3b6Q4w==" + }, + "js/476-86e5cf96.chunk.min.js": { + "src": "js/476-86e5cf96.chunk.min.js", + "integrity": "sha512-siq24cNKFc1tXGACAQlpbXOb2gRKDnncf39INGAPlnJSiAsYewhNusq1UxhMDFA836eucVq7NzE1TqEYskI0ug==" + }, + "js/813-0d3c16f5.chunk.min.js": { + "src": "js/813-0d3c16f5.chunk.min.js", + "integrity": "sha512-gDVyQtM781xlTfyZzuEJ1tnQWyasbFKLRPwgGUF5lpdS3QpW6KTIwCnMuVn2b5XF2qKSxpei9YNIushpBI4ILA==" + }, + "js/423-897d7f17.chunk.min.js": { + "src": "js/423-897d7f17.chunk.min.js", + "integrity": "sha512-ERAmXYsLT59PDGFPLTHNgaNw5CsaTOK88orlaXr+7SOxf+Yjf5fvDmpXCNJe1odvU6OF4cajtlVM1qO9hzOqWw==" + }, + "js/535-dcead599.chunk.min.js": { + "src": "js/535-dcead599.chunk.min.js", + "integrity": "sha512-3gB2l6iJbt94EMd1Xh6udlMXjdHlAbuRKkyl87X/LSuG1fGbfTe11O5ma+un13BBX1wZ1xnHtUv6Fyc3pgbgDg==" + }, + "main.scss": { + "src": "main-252d384c.min.css", + "integrity": "sha512-WiV7BVk76Yp0EACJrwdWDk7+WNa+Jyiupi9aCKFrzZyiKkXk7BH+PL2IJcuDQpCMtMBFJEgen2fpKu9ExjjrUQ==" + }, + "katex.css": { + "src": "katex-66092164.min.css", + "integrity": "sha512-ng+uY3bZP0IENn+fO0T+jdk1v1r7HQJjsVRJgzU+UiJJadAevmo0gVNrpVxrBFGpRQqSz42q20uTre1C1Qrnow==" + }, + "mobile.scss": { + "src": "mobile-79ddc617.min.css", + "integrity": "sha512-dzw2wMOouDwhSgstQKLbXD/vIqS48Ttc2IV6DeG7yam9yvKUuChJVaworzL8s2UoGMX4x2jEm50PjFJE4R4QWw==" + }, + "print.scss": { + "src": "print-735ccc12.min.css", + "integrity": "sha512-c28KLNtBnKDW1+/bNWFhwuGBLw9octTXA2wnuaS2qlvpNFL0DytCapui9VM4YYkZg6e9TVp5LyuRQc2lTougDw==" + }, + "custom.css": { + "src": "custom.css", + "integrity": "sha512-1kALo+zc1L2u1rvyxPIew+ZDPWhnIA1Ei2rib3eHHbskQW+EMxfI9Ayyva4aV+YRrHvH0zFxvPSFIuZ3mfsbRA==" + } +} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/i18n/cs.yaml b/docs/themes/hugo-geekdoc/i18n/cs.yaml new file mode 100644 index 000000000..71dd8ed30 --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/cs.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Upravit stránku + +nav_navigation: Navigace +nav_tags: Tagy +nav_more: Více +nav_top: Zpět nahoru + +form_placeholder_search: Vyhledat + +error_page_title: Ztracen? Nic se neděje +error_message_title: Ztracen? +error_message_code: Error 404 +error_message_text: > + Vypadá to že stránka, kterou hledáte, neexistuje. Nemějte obavy, můžete + se vrátit zpět na domovskou stránku. + +button_toggle_dark: Přepnout tmavý/světlý/automatický režim +button_nav_open: Otevřít navigaci +button_nav_close: Zavřít navigaci +button_menu_open: Otevřít lištu nabídky +button_menu_close: Zavřít lištu nabídky +button_homepage: Zpět na domovskou stránku + +title_anchor_prefix: "Odkaz na:" + +posts_read_more: Přečíst celý příspěvek +posts_read_time: + one: "Doba čtení: 1 minuta" + other: "Doba čtení: {{ . }} minut(y)" +posts_update_prefix: Naposledy upraveno +posts_count: + one: "Jeden příspěvek" + other: "Příspěvků: {{ . }}" +posts_tagged_with: Všechny příspěvky označeny '{{ . }}' + +footer_build_with: > + Vytvořeno za pomocí Hugo a + +footer_legal_notice: Právní upozornění +footer_privacy_policy: Zásady ochrany soukromí +footer_content_license_prefix: > + Obsah licencovaný pod + +language_switch_no_tranlation_prefix: "Stránka není přeložena:" + +propertylist_required: povinné +propertylist_optional: volitené +propertylist_default: výchozí + +pagination_page_prev: předchozí +pagination_page_next: další +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/de.yaml b/docs/themes/hugo-geekdoc/i18n/de.yaml new file mode 100644 index 000000000..ae3dc99fc --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/de.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Seite bearbeiten + +nav_navigation: Navigation +nav_tags: Tags +nav_more: Weitere +nav_top: Nach oben + +form_placeholder_search: Suchen + +error_page_title: Verlaufen? Keine Sorge +error_message_title: Verlaufen? +error_message_code: Fehler 404 +error_message_text: > + Wir können die Seite nach der Du gesucht hast leider nicht finden. Keine Sorge, + wir bringen Dich zurück zur Startseite. + +button_toggle_dark: Wechsel zwischen Dunkel/Hell/Auto Modus +button_nav_open: Navigation öffnen +button_nav_close: Navigation schließen +button_menu_open: Menüband öffnen +button_menu_close: Menüband schließen +button_homepage: Zurück zur Startseite + +title_anchor_prefix: "Link zu:" + +posts_read_more: Ganzen Artikel lesen +posts_read_time: + one: "Eine Minute Lesedauer" + other: "{{ . }} Minuten Lesedauer" +posts_update_prefix: Aktualisiert am +posts_count: + one: "Ein Artikel" + other: "{{ . }} Artikel" +posts_tagged_with: Alle Artikel mit dem Tag '{{ . }}' + +footer_build_with: > + Entwickelt mit Hugo und + +footer_legal_notice: Impressum +footer_privacy_policy: Datenschutzerklärung +footer_content_license_prefix: > + Inhalt lizensiert unter + +language_switch_no_tranlation_prefix: "Seite nicht übersetzt:" + +propertylist_required: erforderlich +propertylist_optional: optional +propertylist_default: Standardwert + +pagination_page_prev: vorher +pagination_page_next: weiter +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/en.yaml b/docs/themes/hugo-geekdoc/i18n/en.yaml new file mode 100644 index 000000000..ff19ea4e8 --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/en.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Edit page + +nav_navigation: Navigation +nav_tags: Tags +nav_more: More +nav_top: Back to top + +form_placeholder_search: Search + +error_page_title: Lost? Don't worry +error_message_title: Lost? +error_message_code: Error 404 +error_message_text: > + Seems like what you are looking for can't be found. Don't worry, we can + bring you back to the homepage. + +button_toggle_dark: Toggle Dark/Light/Auto mode +button_nav_open: Open Navigation +button_nav_close: Close Navigation +button_menu_open: Open Menu Bar +button_menu_close: Close Menu Bar +button_homepage: Back to homepage + +title_anchor_prefix: "Anchor to:" + +posts_read_more: Read full post +posts_read_time: + one: "One minute to read" + other: "{{ . }} minutes to read" +posts_update_prefix: Updated on +posts_count: + one: "One post" + other: "{{ . }} posts" +posts_tagged_with: All posts tagged with '{{ . }}' + +footer_build_with: > + Built with Hugo and + +footer_legal_notice: Legal Notice +footer_privacy_policy: Privacy Policy +footer_content_license_prefix: > + Content licensed under + +language_switch_no_tranlation_prefix: "Page not translated:" + +propertylist_required: required +propertylist_optional: optional +propertylist_default: default + +pagination_page_prev: prev +pagination_page_next: next +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/es.yaml b/docs/themes/hugo-geekdoc/i18n/es.yaml new file mode 100644 index 000000000..8e65cec7b --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/es.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Editar página + +nav_navigation: Navegación +nav_tags: Etiquetas +nav_more: Más +nav_top: Inicio de la página + +form_placeholder_search: Buscar + +error_page_title: Perdido? No te preocupes +error_message_title: Perdido? +error_message_code: Error 404 +error_message_text: > + Al parecer, lo que estás buscando no pudo ser encontrado. No te preocupes, podemos + llevarte de vuelta al inicio. + +button_toggle_dark: Cambiar el modo Oscuro/Claro/Auto +button_nav_open: Abrir la Navegación +button_nav_close: Cerrar la Navegación +button_menu_open: Abrir el Menú Bar +button_menu_close: Cerrar el Menú Bar +button_homepage: Volver al Inicio + +title_anchor_prefix: "Anclado a:" + +posts_read_more: Lee la publicación completa +posts_read_time: + one: "Un minuto para leer" + other: "{{ . }} minutos para leer" +posts_update_prefix: Actualizado en +posts_count: + one: "Una publicación" + other: "{{ . }} publicaciones" +posts_tagged_with: Todas las publicaciones etiquetadas con '{{ . }}' + +footer_build_with: > + Creado con Hugo y + +footer_legal_notice: Aviso Legal +footer_privacy_policy: Política de Privacidad +footer_content_license_prefix: > + Contenido licenciado con + +language_switch_no_tranlation_prefix: "Página no traducida:" + +propertylist_required: requerido +propertylist_optional: opcional +propertylist_default: estándar + +pagination_page_prev: previo +pagination_page_next: siguiente +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/it.yaml b/docs/themes/hugo-geekdoc/i18n/it.yaml new file mode 100644 index 000000000..ce7c40b4e --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/it.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Modifica la pagina + +nav_navigation: Navigazione +nav_tags: Etichette +nav_more: Altro +nav_top: Torna su + +form_placeholder_search: Cerca + +error_page_title: Perso? Non ti preoccupare +error_message_title: Perso? +error_message_code: Errore 404 +error_message_text: > + Sembra che non sia possibile trovare quello che stavi cercando. Non ti preoccupare, + possiamo riportarti alla pagina iniziale. + +button_toggle_dark: Seleziona il tema Chiaro/Scuro/Automatico +button_nav_open: Apri la Navigazione +button_nav_close: Chiudi la Navigazione +button_menu_open: Apri la Barra del Menu +button_menu_close: Chiudi la Barra del Menu +button_homepage: Torna alla pagina iniziale + +title_anchor_prefix: "Ancora a:" + +posts_read_more: Leggi tutto il post +posts_read_time: + one: "Tempo di lettura: un minuto" + other: "Tempo di lettura: {{ . }} minuti" +posts_update_prefix: Aggiornato il +posts_count: + one: "Un post" + other: "{{ . }} post" +posts_tagged_with: Tutti i post etichettati con '{{ . }}' + +footer_build_with: > + Realizzato con Hugo e + +footer_legal_notice: Avviso Legale +footer_privacy_policy: Politica sulla Privacy +footer_content_license_prefix: > + Contenuto sotto licenza + +language_switch_no_tranlation_prefix: "Pagina non tradotta:" + +propertylist_required: richiesto +propertylist_optional: opzionale +propertylist_default: valore predefinito + +pagination_page_prev: precedente +pagination_page_next: prossimo +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/ja.yaml b/docs/themes/hugo-geekdoc/i18n/ja.yaml new file mode 100644 index 000000000..506e7b4e1 --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/ja.yaml @@ -0,0 +1,53 @@ +--- +edit_page: ページの編集 + +nav_navigation: ナビゲーション +nav_tags: タグ +nav_more: さらに +nav_top: トップへ戻る + +form_placeholder_search: 検索 + +error_page_title: お困りですか?ご心配なく +error_message_title: お困りですか? +error_message_code: 404 エラー +error_message_text: > + お探しのものが見つからないようです。トップページ + へ戻ることができるので、ご安心ください。 + +button_toggle_dark: モードの切替 ダーク/ライト/自動 +button_nav_open: ナビゲーションを開く +button_nav_close: ナビゲーションを閉じる +button_menu_open: メニューバーを開く +button_menu_close: メニューバーを閉じる +button_homepage: トップページへ戻る + +title_anchor_prefix: "アンカー先:" + +posts_read_more: 全投稿を閲覧 +posts_read_time: + one: "読むのに 1 分かかります" + other: "読むのに要する時間 {{ . }} (分)" +posts_update_prefix: 更新時刻 +posts_count: + one: "一件の投稿" + other: "{{ . }} 件の投稿" +posts_tagged_with: "'{{ . }}'のタグが付いた記事全部" + +footer_build_with: > + Hugo でビルドしています。 + +footer_legal_notice: 法的な告知事項 +footer_privacy_policy: プライバシーポリシー +footer_content_license_prefix: > + 提供するコンテンツのライセンス + +language_switch_no_tranlation_prefix: "未翻訳のページ:" + +propertylist_required: 必須 +propertylist_optional: 任意 +propertylist_default: 既定値 + +pagination_page_prev: 前 +pagination_page_next: 次 +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/nl.yaml b/docs/themes/hugo-geekdoc/i18n/nl.yaml new file mode 100644 index 000000000..8e24d62a4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/nl.yaml @@ -0,0 +1,53 @@ +--- +edit_page: Wijzig pagina + +nav_navigation: Navigatie +nav_tags: Markering +nav_more: Meer +nav_top: Terug naar boven + +form_placeholder_search: Zoek + +error_page_title: Verdwaald? Geen probleem +error_message_title: Verdwaald? +error_message_code: Error 404 +error_message_text: > + Het lijkt er op dat wat je zoekt niet gevonden kan worden. Geen probleem, + we kunnen je terug naar de startpagina brengen. + +button_toggle_dark: Wijzig Donker/Licht/Auto weergave +button_nav_open: Open navigatie +button_nav_close: Sluit navigatie +button_menu_open: Open menubalk +button_menu_close: Sluit menubalk +button_homepage: Terug naar startpagina + +title_anchor_prefix: "Link naar:" + +posts_read_more: Lees volledige bericht +posts_read_time: + one: "Een minuut leestijd" + other: "{{ . }} minuten leestijd" +posts_update_prefix: Bijgewerkt op +posts_count: + one: "Een bericht" + other: "{{ . }} berichten" +posts_tagged_with: Alle berichten gemarkeerd met '{{ . }}' + +footer_build_with: > + Gebouwd met Hugo en + +footer_legal_notice: Juridische mededeling +footer_privacy_policy: Privacybeleid +footer_content_license_prefix: > + Inhoud gelicenseerd onder + +language_switch_no_tranlation_prefix: "Pagina niet vertaald:" + +propertylist_required: verplicht +propertylist_optional: optioneel +propertylist_default: standaard + +pagination_page_prev: vorige +pagination_page_next: volgende +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/i18n/zh-cn.yaml b/docs/themes/hugo-geekdoc/i18n/zh-cn.yaml new file mode 100644 index 000000000..e6403acd1 --- /dev/null +++ b/docs/themes/hugo-geekdoc/i18n/zh-cn.yaml @@ -0,0 +1,53 @@ +--- +edit_page: 编辑页面 + +nav_navigation: 导航 +nav_tags: 标签 +nav_more: 更多 +nav_top: 回到顶部 + +form_placeholder_search: 搜索 + +error_page_title: 迷路了? 不用担心 +error_message_title: 迷路了? +error_message_code: 错误 404 +error_message_text: > + 好像找不到你要找的东西。 别担心,我们可以 + 带您回到主页。 + +button_toggle_dark: 切换暗/亮/自动模式 +button_nav_open: 打开导航 +button_nav_close: 关闭导航 +button_menu_open: 打开菜单栏 +button_menu_close: 关闭菜单栏 +button_homepage: 返回首页 + +title_anchor_prefix: "锚定到:" + +posts_read_more: 阅读全文 +posts_read_time: + one: "一分钟阅读时间" + other: "{{ . }} 分钟阅读时间" +posts_update_prefix: 更新时间 +posts_count: + one: 一篇文章 + other: "{{ . }} 个帖子" +posts_tagged_with: 所有带有“{{ . }}”标签的帖子。 + +footer_build_with: > + 基于 Hugo + 制作 +footer_legal_notice: "法律声明" +footer_privacy_policy: "隐私政策" +footer_content_license_prefix: > + 内容许可证 + +language_switch_no_tranlation_prefix: "页面未翻译:" + +propertylist_required: 需要 +propertylist_optional: 可选 +propertylist_default: 默认值 + +pagination_page_prev: 以前 +pagination_page_next: 下一个 +pagination_page_state: "{{ .PageNumber }}/{{ .TotalPages }}" diff --git a/docs/themes/hugo-geekdoc/images/readme.png b/docs/themes/hugo-geekdoc/images/readme.png new file mode 100644 index 0000000000000000000000000000000000000000..10c8ff15705a53529803bbe80583300653af34cf GIT binary patch literal 205825 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�^3BgZL! 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

    ;2Dhg)o}LP+7c&L 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 (W^X73>M9iy*-Usf6N3 ztB-{Lth)KOv7pr=fknoTS`bHoj#{*UF11w+Uq`Ft?LN6h`LvcGL3dpfZ z(fdG;QW2VNLUP_Gp^36pJ{+6jQbx;gKj|rWJWJV z@3+Sw(<}yXq^D>E$S%J|*d+*6Zd;1y*Ch&T|_Qd1^ zqr|v>)mzGTD`IK1{Q+^JV`G&>KE$1c!(ar6R`MN;;$-%0qMGtB^#Ykl0}KRCsvGL8 z%i%b`j!DB(pp3TGUJGv$7nNO*lugx2^Bq1#-dxV1Xyc6qqgK_qTeGNgqB4D17d@pgBRn`Qu0x>0@umZ$J}_wC91yxmzGJLFVOTtodO= z1;bVVHFA3m}-+lrXnY(N>Cw*A5u8sy3EVf8%7Pr1NhEgO$dCG4%7vXtLD0gD}MjN4|B zgR=H=&`w$zQ7|IT*pv_LtW5Wob=-od zD7r(=Hzpz#)4(CJ94$t6Bn8IC$FXxvliDU%HWMVsqLhpi8vZN0$qq2QkO~P}8$7U^ zx`rLT>pKDP7s<17$rlm6UORy^+{|_*bS{w2Wq?es_74ZM-nGM+jTH z3Ufab)qQ++;!B-uYy7Mwenj+C|yWW8h0+jtlQgMJ8dHcy5hFU!nS zckJZJAmhGG3~Xx_zSAQsdA-(lc6HOX<^$g06%Up-(HPJh2v&vxUEJC{YQpJDLj!Vi z$3-7MA!xrtX4V&_PtWgd3@T|qCMBhU%6Cxu6J%0~A=83fHH|+*|7zL(=$NfrdflE; z*bf2keoqajXBSv?cxY7jeu?wDa^(sbewo5DfA$&p&)DEj}Y1zw_iW6A)~kc4eyam*qx$2!OKY(u5Vjxv{Zvqc9*i z6{T7obl-dZmeH+iD~H4D_#Scj12bLM@zs9z7%&urcGHik8}Ure*)cJLl%}qMRE0ndUG0D)ud82G$Olh^VMuf52TI zuW9NL``rdLvVc;kMqt)Oic3_B?fbnHdn-r(BJn3_cS`IiOz+!%$nDQF6=k*M0}wJh zAK%W~RfE9X&Z5}njN?5GX9p2}iK$*YiCLkCHzJhqe7`~>F$SW>c%{%&jmGsuxuTRs zN~Nbk7j8P_c#Ema{dMU_FhRd6UJAyUE1Rfv^_R7Vp1f{ug`rC4`gVOV5&oO zK2|OWqV-XX0qBzo7M;vZv{&t~vwwH@YoVb73jq!wfXWYpW8avJQo2FLWQYr;V2kW{YuXQbgRHC)LFoz3z6<`T>iqSU*$n94KqL8iWE1b=&jY7 zo*ycYZk)fD$fGa&Yg0d*;B(8?mg)F$7Pq;+r!YPTp9hL5m}x0Mw9(F8PknZpWGPV0 z=A_24V#Bh%#B`p$TOS4<3+INsCQe__B-%bDa~5S{22u&%Fg(i-gFG zw)@{Rz1^8;jL6+KXy>J;aG3Q^ujIBeL1~%hJ$&s1?r|o*U)8ZN?u&YSSB_q--b<9( zh6LM)x#vvc2q;DP2Ahz^>Tfi%S6Bna?YKmjc%E1MJ#%|SW)?K6pq zJi>FILV|)8>v$c8C`&nlpr{J?enDGG8`jTJ;hyn%*UiS2OY>nZ9=mPsQ(c*IuwU=o zXXf7cg&q6>jf&w4&=2|8*2Iq@ZWdFiLEgRp z>dRn2$$LKPyi&>Mrl8v)x0{~B%$*chQ;uwKu1~lXVl0!X zrlut%DjNH3j0~*LE~KIWuD?CeydgSK^2Gq2JrR`0p|QvT2-X)aEuqFoZ@q7ygl#_E zn~g<@o;R5q($LY-g^xd`s2Ev=_dd*d^ajDtH#GeD{0DWsw{Wzg1f9)`ICz4K_;hpAr!a1QZHFyr62tF{I%0i7d-X zcTzhm#!&$@rx}?%BcDfFg4!^pI|fH&1fOCAVt0`NY_-g|g9#C)SFWpR)!Ubum-TXk zqAXCv04M|AA2;$5t$jRWxashgO}0~e4||nsevL8@jhd$B0Z}wjxQOds;&gyfRIsTD zBa4vtX9;(k%Oa z>;s7=wOueu5)u)K86*2jN;I|$)Kpldw>>irRGS&3bkUyV)que>@DRtU7j2UJ+lA8s zgYgmVHuhfCW4VUnhu(fS(2r5QAQbKQYKV3qhh;ZHdq1N|vb2NI)*H1Lql3)M{26<# z|E!S4={I?KZL9UX4z^oO+J4JCi-!xTPc!uStPF&4R!d>XI}vIzLii(WZ0FJE7W5#K zVL;@b6ceM6#=(`NUE2W{xMcMlcE+AgxJ{!|VwPGmv1x5yZe!eGui63QscI70NK7P7 zySAmsxU95E4}Rj=;MS+~Ijch%k1+4lW#gC;iatYtk;t8bFS10)eyTr_TMWk zYqPbtUu#W~De)oiY{pd!m>>&TACA$k-jx51R&X9`3|Q}T=@^uJzn|C1)qv zQw^P>7w!b`{s=XrwpC(%<nQu*ecUM0)|E=Ghcrq4FWGnf2bTJ5sh_N(&z%4$ z=<&nj@7PN(wS-pj@K@H*@h^R4*8T_A(25UPT@y4CHebE1pcmeF22&u*BYkR=QCj(* z-f$FgTDf0-gcPIP@%_Z|{c^p~f4BVq;xE3nJ?cZXpE(eRdg7?yrFKp0YW`)DC;tQS CvxhGL literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/images/screenshot.png b/docs/themes/hugo-geekdoc/images/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..af243606d8a7984a1bf469b947d5cf4cdf42f619 GIT binary patch literal 304489 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

    iAbrKn8L+Hvr9Jqs9!^9 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
      #t&orpLiG?5$ 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

      F*2)G|D!cllAvzTw+m!=`Zh z)&b#g*71yWt^Cb93I1>BTh7kM4glezLwkd^^@B<42501yz1ldCZXy zIy*zSu@Y>{<_>l7^xmqYWv)+lti+r}R?B;!Qq2hv7&rk_J@QvXL~g}vjiL#Ge(jfx zC$qD&uU>t&nH%{KNNQX8BPXYGVeG{xa5hBNd9ojwj=K|^5p(IV#zeoBc7y|rM& zS%=42nUIn37SPSWuvc~3$yeU~sQTwSdI@%V)#r9HW;BHi5&EvK@e?B?q`CJ+UPdRz z8ag^gTT*$BzMVZgCi`M=c=J+PdU`keJqve1vungwm81NpJ6#Y0UW8@cVvta(ps`6@ ze2gd3G`*SU+9WC2_RH}o9r3L?6<1Nw7#PpgEl|Oz>4#w*?wQ}SQt}>I$z+>^cefn% z+g%tZ@czSbaivA;9f9Hab?xQKj-Pb7Rqel99_8@UVk5S$LwW&Lqq!N`-O37NKkCp| z6cdFEmlK4r1s6;1=lbXO-8X8^|MY^O0O`>bTA7B^)B`-r1d-v00=0LtVc#=z^+crD z*4^?#*ycNNp>^MJL^$PT;=#|5i~4NShszgndgH;>+?q4|Q#7=bI17&e1F5)6FE}Fn zei-*G;vrnO9>e!n&*4Cav3TL$X^kf?s(YU;sXER_9prs$S{$66TcY>NN%Qdo8#;(-0EIjHG+`r|1 z*kkfaIZ{DgK}Jo&Cb`-xJiXJhDI() zTz50IQnOM#W#Tw(4i;F7vXWDOJOPikK}e|Te9Q&&HZ~hSzpzf79LgsM1T-N>;J77* z(6_aXPiv+gaqGhR^{Y*_=Z~)kc19I$XpW7o9r}m(SnZ2yWLqeDKjMYR*jT-SXmme0bN&=QX#s zG|G|tar(`f88?T*p1yzj5W)`lN^%WNb1P9QbPRku!Jnma~*a8QaQ06FE zRVN+>h7J+|yVxZDUA*y=W-gU{>wB>CqTF|-Dk@wc<@6c<-aLtT6!PtF;tQAbrPYmA zVb9WW(6>0=OC4A&Uw?nBT4=}sz!cNLve0?=&3aFVB4GQ*MTTsKlbsW2xeIDJ&j4op zCUo-DMMNPR{}esKCBHM`t!6ALZ)gt1%`#mXJnXg+st83<0_P|SGDRxgNFZok3+g)6bew6e8y&|cfE^^^V>Si z3oki>BIuNLi-$iVr%$HJjd)zvNI(*n|D;9lR&#O`wQM5yGXsNr-wX^Kw{LBfZAIVu z@WxcbQ!|$~M!LXZeQY_>f^A{<)hi|4QqF$)4D7+4Py z9gd0IJ>C@>b#1hFC5bA&s@d#7q`^~gi4t%n=_O7T^m0g6-FkWI+T>tyP1eqp6T zSjg?cKH`9UcJ|%{bI977xonbvZ^jRC{iDu5ef?G|Eq8-S1SIM4r(MNpYdl?tInAC) z(D2yrFf&ze5fxD7o39c<04S6@U^7|olz6r%*S)wq;=G&<{w-E5qRxMoq3Uq$*c4R~ zRNybEuWGoyHd?ja$=5i=!fD>3|Im?Nv&Itn!1nc0Gf+S&D2us2yPT~3X_Rk#e!!x} zZ(w>7HGU|Y)7Wm%kW%*jQ-8^Aa0YzPF%Ez3CtXCFOs2I#>ZRkI1(Eni$1a4V4^k^C zVqGl+FV(v5D$2(5i|{5G_W946j#b>FPDraN`dqkrzx#$!`h-J!%M2#Meeas* zql@gVFlPW=uq1(Fem0wjq!s7pq~}Y@j~EyxSIW2fH@(QZ$DEAcyC+1)&kSju;K+Dk ztXD=c2|6McZDSk6g13y$H<@^xSGetpIe>$8v;M|aPq}N8miMm0#$s*jx)psU?L|? zS8b{MUOj2@n-+6g9^Gdq+JW@ia0M?gd&3BNY2{e?`6bm}a=Y!3KxPPBJo$-jXwYkV zPl+_2u&fmXVF^@k#}9>c=vW}(wfzVUjym}&ApQ9?JzOVr!b!3BBejCE>mkvjw6Yhcap;mKzEvefB>5N??$!Bz>yM@ zi`USu+tsLO97FT{-HIcIMV6A5h95T?Op73^mIc11uKtHrx~bYb3tRVdksvcDGF+_oCdpha&44#cn96rjBR5aiL?+8TQzvakQR8(9ykRn| z;?OG|g0{Iz`An6zs({o~N)Seh{yBN~2*X#kFy~%WTSRLPGm&7SVZfF56Af0C0?^N} zycBzgNaA$~P8<`wav1?d9kV#DnYW+Oz}oC6i#$#5HFkEX;IUk|vshH$6tMcIzfVC! z&A6E*v@zEdkern2q>y{rUC-xWW#>#9Y%YcgKV@^ z!UJ2|-7meZfx&?j+lQ<&!w;|mMbSuexeBfB1X$%)Cny+o>9G=VJ8!WQbDCe^BA@C! z{P5v&=j%6G%xN)0gzmdj0p;kU#v&c2-Wr0Ued1r`qk}}DGz|gQBgt5>^ieTGJg;Q* z20C8{hRA)%AQEbz#5=sXaeN9^vl)qeQ)`)+-zs5S&>l)Dc3}g?*OBYk6TjM00sdHD zFRkD(l;JNCshV$1jpdsFMZB3As`1k`1mHYga+tkz5hg!)&5V0R_skN}+Y+xmqv#mcW{Zjbhsh&TR!WPN2=m0h>4B3Ot5B3+V;knR+uQ@Xpmy9A_5 z76Q^r3MdFjmq>|}lt@d1bc56xyzl<@+2`!_L%neE^fTui_qaoupOaIXZ$guqFe*Wg z%EisP)MJKhnLtr4nw^)keeshD3j)_s6lDz&sn}L zEG%$h(>H$!Yn|2Hu16^ibNl!a04l88sLlg@5(#v)rzQ4(k`xM7>xL5(Y`VnQ=6m|S zKhQ#gC!!>+g{z~l{=@aF1_@8~TO&@XmtV2GeSBbXmYbXVdJu^%At6ckgy9*|^yc5c zcfu$~8<($OZwp%c>RSQiUphYO45%hrQi*D4;5AMq^SCa2Q=_(`GPke*XbWb6_!ovO zIV!F%^a~_QyKPCKl?BTIXJ?9v>zRppLn`cT^LIX|GvHRB%{TNyZ)oMuABvO5@*~X2 z4_R~=2`t3ud)Is9`ZDneh)g_PIp*7ba9GoSXEo<;r|sy3sDv)NS5zv}5|Zp`H~BK| zhfRf!*>=3PBPNIvCm<#27SdQ*+bZxn*=4xz!8;_zGQ_AT2^gx`;v#Q`o0f(qqdH`i zZQwCO47WV|JVsttYw(vCeWJ0eDOJV5#8_ASJS~>>vu!PG#eC1hL~f}(72osXI0&Pt zdh3+;^b>xWW^}FLZNI8J+)oiWbE2o>`ab9KrD@R;cW(rW zk2>FMj7`?}fzno*DuE{>HcrhL+GNA3YQTX`=FMV#h#!oqP;eum>$T2Not{^8bo4uG zYxmwnLsM5A`QU~If#?o~G*s_K(&BbeZ6$~R=;4sa(y$(}mwt6Y>z>jhCas%RMNJ49d=3=6%G;Q6e_1=a<0{ z8WLJ$o%M~Nu!ue~Ra*SgF64nts>EJ-p6_gIJ$T_k&fE{DvJ4QOLMjTt5Hs)VQ}WG( zY0Ru2Q#`3LXG@eAQN5QOQ`SxN5ZM-lE@PU}fK9j%{T0n67f~yjUo>8@WBkOk^Ye-R zD=$ux<;%ZpDSX>wsd0P+!2_PHvU$qTv~t}<+G~(j&p6!zEE{}S{(AcWs^1DkS}nEn z2rliVWZ!t)+PKMd>px%L_pe)2dfjK0f3&lX(z1MAE9t7mQ9pBvmtCf*@N>nKPLXC{ntTjecFOD%~>)I5okDxATX5n5rXgK^!bnpJXA3uLWtG~sR z&7@LWtH~Jc0ONp1j|tXy%y_q5;OWR4`Z6UD=Sc^=@aswPO z%ldv%s%-5haRPEMXLUR%8$%7Kfw8xvlNLWKJ^usGi$lk1glcQ_e|CMVTl@99NaC3tZ?{e=0Y35EDxSX4K~W;0!48_ueiuG= ztQKrWrHp!1Kgt88(D##lV`#p89OWn}K3zI0(zcC>=hv=RAGLhZxwz2BY+LZ2<P}Fy2oAWLsO)KJpr_jSA-0-l3{oG6Gm} zdy^IY&I|imrqUEM8xW!ZE_+IYt3(pmmPH-Ezg%O`_$Zo0jS>=)`v^^bh=m}gR_YT7 zwtCikIAa`zip4{Uibi>CIN3Thw6qAIrxhWFylRC!5I$qY4Gz5A(YSmR@TK|vz=4qz zvJEWwi;CV3ts)TH@2m+|KZ{B$y#Na|80>D`I0sIc0;vC2UFjb_vaB>uM=63uZNcZy zj3zJX?_S|ZRTf|=xj?vFH)$_NLpke+T0GW3PQA}osLIDJ2v56rMyx7d%$O+!OaGfQ zmLtHJ7kEj)y(y=NzEQC8%phRz5>uAyk6Z@qkPuZ>)gN_DG1+s* zFil=XSO_J3P{9dtL?q0bun;0Dp&9g4rtbY!U_ZlrtDTD_& zph{8*3!bNq-5V?}RbF8Lh0U9!M+{nJ#%R+)C`lYlv-`E^D{^0J>5gpyfb2j2O9H~j zD^bUj-fk9)3SrcMFMNAN>%Fdgz0hjpb=t)#$}d0v`Q#sN!2FlMXJVAB+Np$I`|->s zY$^DJgyxqZiyHf#6K5h+FlYsO;jUJLzZ7^(pN9s#A}q2lsYle*IGC)CKXT!4>M*`e zOwKl6``G#L4kV>rb7{eZXxWH zYnC@dBoY`|f6Vlk4Oy&gZFMd`FsvM_G3zB9v_h+&>Ztp9u&~HWKuElBax!2a1#mVV zvp%$6=H2VH>OQB$&tl!Yb*r$rI48gAJ`{>XB(uh+;&K`zb>|sxt=^|b-h?P;5Mqp| zDTRhf;F7ATYihclH510T_R928{Z!zz;jyND()6@GTygvAl>8<0 z(9l~1S#L~xQ#n7EIMicfJQi_Kd{F7;25dO>k4+(#jNtNn@2coyV3r(GmFSeH{WZ|# zz>TK|E+3H45<4|Z&fMQV30InQfpWT#+ucS5G19xJ0hYQ|6v$Y&)7{w!pWecCK@>!_fJ;#g#+tsxG@k$$BmnBBE#7EHSsVxx@@L%Uq z8{q`QVSou?#>4B&fK!})ie@g8HwE_;Qb8e1r|Vs77_7P^)zk=+IFvP2U*_+WaX%Q0 z{MvTRqmqySDDUtHx8vx?i4`*9w^jL}kWuK$C+OEG2*E&lYV;OP897B7Tkr-20E0>uus z)H*bBW+Q*ppt+O_b**<@3VJ9$J|Qg5UV`2pB9y>^<(b-}yXZGwYrO7vsj;w)C@iD{ zt^fr5<>r2Vxh3E$Op>9;!O2;kTZYv*{pG^Xhu8ZI)$Ze(rM=dDOYk!ai|vzzu4X&g z?YA7lcAU*B1Wqtlu3JXi2xMZeNBc&Vn!kQjk!C0;W)5}bSE)~XJK*6l=`O$m^va8)=2uIXip8fl zG3e`2OL?+)P<^3Pc3$|VbmmWXvoTY4YKmCM`KqP*v$}*@SlFN;91sQ-5uQo3pqb&P zTq&A$A9#~5Ru4VL+$Rog@Yc(F$|%ElC#J6miD0CsIyzhqK^c(wIIwmAY$1^9!jemg z6XWE&b-+N+pR%1h_cvzxf#`;yXId)pamS2#>9n*6K3?!fFCLefz!mQuac|6If4mm+ zX8FzUNJ^9VLFzq{1@u1lEzMy4&K_Hu>>2aw3UJL*FS)-92?@3rDX+eXJ&KNrgCNo5 zv8S3<(Yw2M?{&xt`WClGjv3GXoUm^-Wdi~UTPbl@%#+U9c%@iUAvv3gn~{-`HK&;* zFvbB!4~1N86dted3Z_J3CiIsv5%)ehk645I`?jYb&<7@&xYdgj-@SV*^sAO#<@B%! z$voPFH7d83Xqi}?Rp`3m1veLD*g0R8TUTAno9u4L5~e*xvZVD|LP=&2aUVDcy0*

      zu07lc0E`k-$N8WiCe)k-cpiY|5UsMpx%Jld<1M>P26@2OU3C@lnRvvs-~OSYEr68s z{Gz(l1_8XZYTK>@4`>&XVV0Ti0x8fICZn0??DlrH)9sI9*d3o9X`kZ3c z`()*S52AmnINp3FZ`Y&kCKmQf1@t!*PB>>k42q!P!i2Vm5k%9z^oecOWzRKL#bDCq ztmK4+BP3TtmZ~Mk_mrUm@M+;$KRl@@3y;)%!zIkZ(e^I*bgae;9ZsMgq$R}nXI+pqU-5`~+UwL#Rn5%S zIP&liT~%FezL(kXdt38IHE|?U0o*En}X-(=eo8IorajQuEz*ikJN89J$&^X=aIaQFXf?g zm%O|R@IS#`2EcP(ufH7qjoa8yx|7P@eRLbJo#;NoRLn1>Yc8}R>~j5^N;6-J5o~+y zHBfP(?K$IprqpyfpS72eB_uzOya^*VG_qszrOy;+PI7Et*1w#xpPwf2a9KE()(=?r zGhbRlFwu)D4FZ>NpHI+=IwQ)LnVx=uAx@x2*njJe|IQpkPfwpQ8v(D!CW@Y*-&q&{ z=kZ1qu&hvfSxJZK3qvQOrMC8i;&V}LQzM4{DE!Ta;nsSG=HBfen2;)3v#U!$JDgM*zV50ej% z`*)>D--&Rr33C6DsTZ(Q+Z}&gr%OA zF))DT?d{DIaL9-g^V8325E?lrzIlF_iZ#Z^yIIvSM}BlY?f%gVv}UqigeB4rJOxL#`$ zZ|hX_<$kOfiNg2qzwwZim!ykPNF(sutSiA(9q+X`%;84MK3fCj#%SW=Auq%X9GGci zNm^$e$-A6Ou;TNr()ql=LJb9sDqbx_C(tD-EE8f`r^-+f_wk*%5%ciU(n0b z&Rh`F--}eplhQ3IU=pEEi7$4ks7Og&9BV(^6ih)n047v1CQP`2$HcIXrL0IA_QzY17g0F^_8SyH1P6bn%lw0n_&Ji zG1Z&tcgpVfbntGx6c6Q^=sT}-J*w=o=nw3KF;oc=lK{yJ`ao_2Ot8wDnlD>ZBzcJQ zbLJ^X@FsYng&!e?lEDbLV!8Ljxw7M+vb30+3K@JMkpIzSbjLe5P>f4ZI9_UJiO7M4 zlNWj@j{wfbhyfDX%I2RrNKB4aP{qS+cbVPB6DjO__x9O;jCR(# zEW>|ZdrB*t&gTa)ky5hV&J8CgZ$$vw^K10ee4_q=%Z7=OPi1fjr7dQ*FgNG%`HO?cl)gOKt`ILyU9;+_ zDMu{e7bvw(C;E=X!`H~CWGDCc5t&xf*yneNrfex){(~G(bAD`DNc)kd&BTe*1!1==d7O!9lu!TjV+ z2!qCR4V|>^YpjGZj1E>y&6fuOvtI&(dwS8z#u;rjn=|u*gK^N#G<(cl`OX_o#(_w< z{Ck%29tOs{LPCb5>g|sX{u!av7{)nZ!r(hDn=O2g z;Tcks&1@Q_xivjyfjcoUGKFqB*z&}jol`9l=qu0+ym>2(0H0JM%g&ST`bgpoDTP53ovfc9dx`e&%5A7ORbk8yK64%C~}k4*mCTaCL#H;K$H}B4hlQd1oa9 zo#1SQtJ@Kbsg|~uUu?NpA#k+zFpAsuUK(9{i8B7Sini{{7DGd8@6^p{e`MD}(7kK& zL(f$c2j?gtvj-|vcm)SWhGaQ#b)Kg+H++7xyX%aMpz=FEzZVnzxEmW6Xd!v>P(eai z>B`0$?Z+a|-E>BsI*v4YJ_Vm;YAQC)QJbQoPh)ob2M6pt9CF%9EQA=pKBz-98%s(w z>T-~)>yhJStWV9xA@h~H(aB~#XeXJ=Qsq+!FK8YfRB}Sc0k}T3!xLe`Gu_D0n=pSQ z*ZI78lisoBq@t!2+iFx$8t~$xCB*C&$6EyE+YhbqG+STwUD~WGpDu=)cR*F)@jv^rZ_*vJhj5N|V<}|KPyz$V@2u zE|acs%fw_}cfIa2d7V7+ZCMkTm&?;9E-j>7q4TQpt*f6@^t1xUOpQHFUthd4di`0{ z&W+mtiZ?C=X_yLO8Fk~@s%r0YDx$hp34oH*Kl`@4oVdEXeS7=1o?v6Gjm=X%H%|Sy zwC9Mn_7YhhTlFMHtEWR8p`oFxB=|jc*)%FvO*@sPpWO8rBoZR)CmYljT}u;Gt#YCtl0<)KOiW7AF&IvKO4;>r6|M4ey*=9=j6l+ ztNe=PKK8V!A0r$XYD0)^Zv?}WcH=Ub8&=oI46V&^&l{EsfxjO5m+#fv`hw(vvK=%9 z50DFeJ5pBC4;67RbasvmoSoGzWP7n&u8bl?CIyY>%rcD6Au$t)wpyu0yKKH_Xer|- z2`Ui08n6BuODf#*H-;~7nhlVC@J>46W0P)k5U?ZSxWhuu(9Ny$uo=VADpP>%_7(l+-|h;o3?gPG=F z7-Y!eI$fUeYiyqe78OOu#2BcU%b~b>3o3-o*A0yR(~4jj?F9E5XktQ-2$q-85)Zw+ z6kx7TW~1!;4;LWbmY1V+wBoIFDd2s5<}#|OPt0|J@VR^pxl;p{`Kz^~YkHq+OY_Y- zSo!&bTMWOfx*D^kJm-u7Fc|_+;NqU0$t9H)70JmdWYgcJNg#-`Fe*%i4iXCvMPd)f z3RjxkLNC!!kckQ%^nsKHt$^?1r9c~R`C5txNmOB^AEBnE#(tD4_aZ6cg9jf8`rokI zKy2t^?-y`c2d66j8|k+cP%^&YVBW%cdhVBX;~&Pu^~h}h+`q-;R0at@KNeY6rNq2s zlpVz%vaY(G2f_@*$r>-$@cP_oYph;RO}#*9ckHt6yeyl-;fcJ)^32vE+L{?{5?w{vP&T+{qGpn4gRM}MlXEa*A1cJ=-1fT zu)8Y@Dh|R%{pv5X@2s@#?MtIwrrF;d_355R~xxn6wxt(zKs zN!PS(5$H>3LaJM!BY0SpKU=QlW!XvMyHOlB%YeXC0E!^YTqOX}Y z+;ld^w0~q-I&WyQ-1|`)w?hX&mK9^bb0Y?i)%dcVxKbPTgq>NJ#{s@tM@ow)VO`x1 zhJ2z{_Y@a3wJ07wbTJ|M>tvUyXiRhmHH)*H3M;z9b1Bc@VNB;q&OZ!*_+K2@w^0FL zad~+q8bWE24=pPCTIl`_^271%#zagDWc zRsg(VYwT$F;!2#cu%d+BmHUPans@wE2Y3cJNS3I zLbrfJ(7%lza9Jw6(4K5y=4^deeyFYOpAA8!A@lt|oBa1Oh$Kc_tt6#sKMt{$&&)GOrj_)PX}!9sX>z19Vm zg8y|vd_%AFsQ=?gvP?eEP(nXKFVpvrRV<0H0vlcWzx(!856>_Be~+RJAETkkMi_=~ z$*)*k_LeXcM?^q_2zKfb{m(P~-v_L(G&@f$!^Ga1nfVF*+ZRPa zAA^oaQH@sUyeXM0iDTr7r`RjX$heH%jm<6Gxs7SeXAYaH9n9+s8kMTGv#EqCVL+xa`%rY+h#iZ0cUingP*6 z8mm=yJuEFkLp!n_$vcjM!s7paj*;Y%C>zNoEJwu}Z?dwMcRESijk#@1hJ zYd^C5e?GpoDDl2E|NZ%_fti`OY=n0EzxzMCGvHkF@2~#n zfP5oT&|i9(J;g-zufBvvQFz8gW`0T4&4jL8wdjA(7B4)hRqxsV z{LC{1DPVgoZ{N9SCcAh!PpbeU-Dep{^n}kb%E14Bx}})j8Erci%O{%wr$S-(1KK9f z8r13j>tHbd_rW|XO{f_bZo53_pMhrBQA$R}2)+0}`=3XD`f!qy<9~jdf>x;FXCtgG zx`qAXs=?sX*ce+)tupezj)vGW=--FppL4l-I5cpiadvud9W!5^-IzX3<|ZH|{VDeE z4T|Xxr1}3ZeFzrnb#b+mPO@`kvcZ(NgG1?m-`IG|pi>Q0H8eG~OGbr+B2fhKW14R5 z_JF(a$~>pqz2jDh9ecL;hmEHDC8g49=9G$$yE~pW6a5FHAz!gf#ZM{{H~P>03@mFe z+s-*)c#e<|b|QtIry)=Du7+yZk@BXnd2CFFv4>ww!}AB1gr|cB$s4L$d||#nk0znN ziFsGD>ABCxBKmmCee^QwoeSdA$wd{lgHrns{ySVk5}^E6!~63D`@HyJ>70xB0(+&^ zBzO4aVfxW{bL+s0!Qv#&QEfJ=aO<%O?jOa0CGD8zrvZ%{%jn0tfu8zDSxtXwn$Hd# zfSdE*7f2Xom0>p>Wv3TSubh3#j6+BN+P*=eMAe&K)0*@e-TO#8E=+Rlh>NbK{za)- zhsz~?9+ma|!y_w&aXpqaIgq$2K=)Ew(&yApG&~!DgNIvga>~Uvs0%=^2Blr7&i9nBsZxUClp zL=Om7t$detW<+reZGGnqdQqk`(|ejv>YE>TnVWff9xGBbbeg6VG#&Cl;^TIIADiHO zqe;Mr(vP#X7Fm?|w^`Wu{^D&_KsX<5mS_4RXcDsy*ftLQH`!{5>CQGhngFc3J~f4B zpJrmhnljRzT(*&7@k1I#!~67=m|eg*J1<7iQ|ri#Xb!x+z-y7aP9#M8-fTldaNa$) zg18%*yUg1&5~UG17ddTq(nw1y>xI>V%mwWLGMBx*tWzyh@plcMUrLhsz0_6Y(woA= zy8L!Q&TyB%TJYI3KfxiD1PJF7t`qi|9J@Lgc`9OaW8*p5>ayY?X@Pndelu!nx#&2j z%cPGVv}+?<0{u~1ejA7r$V*T%XfVzf7G&nue0tIHP9&)12W?d$Aid|QoRiIN=y=R} zqNPK7Jt~UIT1pC_Vue7Tk}VCjL~%Dxfs2(K{C#Y{(VG`5O~(aLxW2K-^pC_?`|13# z^iriWD;x2dgR{bKg8k*vGCon(4;sZ7VRWwI5aMd0f_d|q5la@#2#IFQOC=msCf!xD zKK^HsQwr|tKk?>NAQy*8x8WPv^mr>YV40F1<_sKnRY@k*`qqZIEcb!YWrTi!L$@ao z0P*p2D-Uq&tBEocjwF-$F>gDrAK&>~s@J;cY{YVQaHV&3+!((m8An3-L=YpPYrp+u zwhaH)wD7k?25>zY%PM9P?%%7-;P0GmB~yC-Dxm-TDHy^tKeMn{{sx@h&cHi{IB#wS zJ&g{*|HkY?vhvw}dy$&AtHaM`(?rSd29oM=ILdn`lMxWrW(xX1d$ieNSz1la*~QtB zhgi4K`%%`+gBKGS^42o+=jS`^5!vrigWq}X4;gsgE-aFPvkP9R5w$jLksF7{N9PQnaYSh`6cF82}|~RVk?D8YE#|+~o?#QG49GNYOsqW?c5R=+E-z7K}poZr%xNy(3J` z%pEqYddp&b{JAQckIdaMdu}?q!f%m5Ra7U@F0Tw1al3DsdoP*PmoGJ)g8FKC(cnCC+U7>UaHtChAvOMOif)6R(6plWph19M zpOPtoxZ1JF{1a6*>L-FEO0QW` zo#9sq34@P+&EOE&9t1oxdu^5iFpK&JU3m_|ccsl)n)^dJ!){2iq9GA;bzJWZQmt3g zkdZ}v_g#XJm)7IkD3p{Ypchjw(e6ENqY~68xljw=%tn-(t)24_-{<4!yN!Ayi_c$8 zje0Cou4+PF*?G|5^H~u2Zz=h_n%p--1^sPyZ#$B)m2k9F4f>a!=sfiAh>6_Smy|~Lyl(*g5}Ip9EQBWz>C^dp1u+*i3zKWGei%Xq5$QXGHD42~ zAt_??IR5#oD8ZffZ-dmb(9;uZeeCUhy4~Nq)7R8^eCBT|E`lu%T9J5598`dt?S5np^A8ZoDgEys1T+=`{cI$uDoPg8X*yaiEi;(9^CkF~je+HjQH9(W95N+4K^zOl6dH;hyyyt@Bj$7DgS-}f2D)03wzh0Y4$8j@=_^{4Bc(=yA(7z*Jt&cnQ2&UUyLFA14SR`+;W7;>Z z=9lbEv>NjsV|eTN>eAmGAo@N!G1`B2MhXz;yvf;Lo>+-^+`k_f8PKgrhud@wISA)y z18_41GlMAIbzc99aie6|m7h7^5ujn}aiLe@OarFQYQ|UJD2Egi0flc?(OaEEG!t8$*HJmwX{47!&`C-`I>FK?|q{@dy<2; zV|nyA=saP`+U#+pgS9h~p!6uT>J=E=LaioD36B}6wCb2HRv--4-3Pg5uOI5(Q=Bvfyh@k8_?9iJxEd|~9 zj4Dd;R{jcjjJnH33)`Ret!=oT=guA6ZstExtsajcva3Wy!qa5TMz~t*8edffb~jjZ z67xaw5mTm$u1HS{gY_hL4nmAiKSmvVOV;{1gm|SrJn-z}!qgZvoM#8k?s;HMmI~YO z>^d1V30V|P`fBgh^#<4XYk3ew1(6$a5lYL-ngH2Qr9feBub=umajb8;u>`ibt2c== zJhO{F(~fnU&sM2Oz6Wj8Opnerm1aVc$+Oe8a~dsm?DOS>^`ds$?52{Wj(l@(COz|? zTe4^Jy7)d$Y5w)ih7B##D+hmTX3CxmkNW9gHhubL71JNrZY(h zJU0)-)uwmWemZ>FIvVn@W5M!ytJpKZeRR3zzS!ZV0}uT9dC2Fa&WUlrP5|ooS*n-t z#=~B&6>&E1{mGq?Bc|LC{*)9FMy?NRl3xsLF%!eWyOS+hz?e>!jX?;n^1ad}fz zH38$NB>|l==NI~&iJ_rT5&1HSDdoO<7Z{XH0ovBqi}NkE`3(8+nT+LnO<4R$cXi>* zb<|wf!W46HakjL#|2pf+#>v|S`mhx;{HIDdNtK^}3{M8NTQ8QC`o+w5#sVkE($ZD} z2bH*xZhfjgEIwX|)bsasCjACzoslVPsPuxJFOSn1Dqmylc%Amsx95|*<9(U3;c|z$ zRJfcR&y|$=&dvlr7HB(Jm_dAIcXzYbV(h>|5c#Vm*Q>W)-=7qP!q2ZU-PR7UoY1`9 zn9qz_k-bT6&mIWM#ZI&~oo~HM5CesY=J4~l)>%lRbpAU`=Ut*pjdR}wm{7I85OtT5 zzQxx+*CBDUM30h_GqF7KZcyMg@HVTy-1dPfNvd2M1QK~5E(0-3<%Petjv^Z??;||@ z7gWWGd9q2*b(O!Koe^71jAOo3-+cbAnY=C|Jez4)+@EniBcTj z>o|{;G*#PHf2u2_+e4}SiI#S!XQ=O|LX!!Uq<6z= zJx^qeMXWed!zFThPR@yK1Vj8=R#nsC(vqBkpQyRN6DXH8&Uwj(2-nV-WDJ|p=XyF(`URb@|#8Jj3rU@P0}x=ga|+|n<+0Z-#IadaH)A`#Ru=63=iA&jqg?GY+T0%DM;a1LPrOAfZ)$)?2rs_z!@TR1v&h@0Q?;jpc z9f*bX8ZQRkBF)|NrR|K(BF9aDr*QDcr#F+6x~Ag!%e!WfJKXwt)Th%O8!d330}lfu ziVndD7z@NG@{V{%mPK?C`EcMyC4Nk+ewCHg2|kr%AcVc~tktQd;_VAgo6%i}hD_gB zF!XlQ6CoyR}@!sZ4@3`;tDZ#)qCR%X)qNs|#MrQlO=rEn(6 zAi1N|Y02{Z`K$i9(3`{xcnJv)(*>M@0$bj_BsZ>nQ&?J@Q>MabMNM@n{TonkVjIiGSOC6y5S__U`2K5);I>TTa0g}7Ky&5`ra*LWo>VCv^gc` z)5xeZcty%}*qV}sUNsOFAkD|6s4_9LxG_RJjGZ&2JthVy0$4F(mi#_R5CZLcQ9FS; z`*&PB>4`yKS&k%+S3ZUk<|kU}GMDB1GzBzX=Lb_zvrwhQgo+;kSr(ws&0krd3}b&1 z(=H#gu(W`E@8;@?JUgZ~_+4 zYK;2(c*kVlpk6}DiU1=D?_rcUB>UjwG3m?nD5+PZ{P|-I5pgVOPxg69iQ} zETn-+-IvMVx$^7ytMoJO2LhN`rBq7UO--aCFCa`?A&b|g)iWc$WuwH-4 z?Np-N+vM_**PjSl0GWM{XT#(a`WZjx#3wD$fCH4*{J|)YQ5CGL=)|e18SU&B+6viM z?6GuFMaa23dnq3Xe?7hRV9=|HVH3~H^ppDrp{dpqUb8nrMVAzyGT_-0c^5t2mGAFq zsncIo1}KCgLIKZabuuCISC zO6Drz~;;;L54?hIzKyc6y; zLbz^xRkq_|PSUI(fSRAn>qgMO_omFLxPIT)FVvUYI)HV&&uNE1U1cdNDUgQOB%%6_}F!HR$EFnW3R)4hF(R z+#i~k`6488Tn%c(6#LCURVpqn{;e9-2P{X9k5QNF>)xbhisDcMX9KpV`D+2W+Uy=v ztWg4Lr`DZ$+O94qc)7wIqh6DMO6Y6=3rBpmX{4BC(m6;v$*e@T_B$}=!6~L#WB!tf z;Yr@-+&8OM%o`*ms3?1&QwMTD5@xWOmbs-1;s&$k{a#oOV~g3n~o zSlMg}r;1ouUY>DR25e|)`9}KIrn#dbrU(v#o-y~s=YBa(OB&bBJZ-K#6M2@ z{vR%Y99WGB9dBcPEKo4{v4%h(48isdJx$ofHFFEt9{AGObWiB=YTj?t%yJV){Ft6@ z`SP0_1*N@RT=jJ_%-EJ&E2jO^ex4S7@82^T)IoG#?=QFu{Qd0n86r5;kPKK@SkhpE zdNjQ6O0lRU?xkhS&VZZ1>$-x;s%5^BdJ4rh7!oLC*qi+1j#4O)9bP*)`kW!yxxLL& ztnrZwWEKOGK!6Mb4f0)dbOIuxWm6jlm<&)+oD3@S>j;ZSoOQ;6fPOa4k55P{rlzXP zgr}yKm|Lr>yRng%vnL>%ng($lXFRuU{4*a23BZ6x0*Qih@`^5h<%nEd{Hc^ArJYzI zSQbC#=G6c<;d2DzIcUEGw!f&acXh!Felsj|b!7#jI(|Fyy)XJeCDjkar|jOgW}`kj~9#o{#_;#_h%v@VE~q$dT|glnM81)S$7g;H!BRU zZO03$6cmhvQLLQotKT1J+2}IdSE#(&*(M4A}@h=OSo-d0(Et?Vt?bobeV0T?%+PQ%25_P<|gwzpoFT zFNFr5!@u~xI{6}SfDz?28-n*~>;o8X%^jVBAUQfN2E@$ZpJXys=O)l-M^spNzd@gw zNrR9dcsptgNtBTkNUAy4T8JHcS6EB!k7JjF%s{80_P2 zX=oGPr3Y`|^hsUd?Q1p}^8zTDGu9LQK(K8|KFvN-vrhW=$eNRn^Lw4)r`^cBZ>%Zn zwhtyegt|Loh%Bw`A7e+nGI;*w#*wg;er%W&W9ZN#1(;0H(Gk3Ojl+L}7INi@02xbQ z9#2P4Ki5T@MbVid&p|WqTIE%)!WJbm??rwuOl^q3av+;yU{G5en-I&nosQr?0< z_@52DwJDiohNEUS68UKT*9jxYjXW*#r4_37_SySCfuRgI_hwTek*T6aPOLgr_U*Hd z*+Z*WR-^_2JK}(RhO`^ESXY&sb)R!^bJ9?VB|p*ox@Qm&|9PJy-@@FncJNn|->s|B zdX3t{JNUYy0+WITA(ARSE3LK9A}gn=Bz8=TIo|P2UU$-7TY}0)|&A^&}lebDR7Ca%Ki zoX@yCx~Rx@ye4pC!sFE+$GMD@j>M!6bmk^0S(k^|2xG34U!VL19|-NU;8uiy7d+%{ zJ1s9vj|`xPio&W4teT`;YN7fH2?>E+JXci)X#pwgmB3I*MF&rjnK~R60$n{l6vX%0 z*A6H;vr&VtL#OJE);9;T1T%X2;`fEc)Y!4V9eKQ#QtW_1Hskd0shS$nmaEEPqT|nq zlZZ{9uw*xq8t(aC4Lf_2a+T}P<(%ST^t4_H?NoF%H75&;c-v}rE-o1sOrT>UZ7Z@7 zcQFp!04@SJdi&&jVbRm`uyz^V6*L!@z4wvd$1B%x#c7!2Eis$-Hr`N))qH7;5Z=1kbXbwl|FSo0?5Ac zolS?F#0s=SDk@a8)O(esf-T<@yTQj=^NBf^!+0C}M3oWn>rzr$=DQ$nJ>x^|mJr-x zM1-liS%sw&>T&;8L9N-He!)x8IsPZ+=w2r$9Mz0Q2YyG;@clHQ z;<@rpvL;|n9gZ~{@j!5+&6n3*mZvH3NvAe|gZ(Y=SE!_}- z5(+@_ui10;nf~S4b_)wjM%4vvIX|y~Xi2>)?ZXFKQPvdI`ix~5(wCBOzs}wk%8G-v zTBgqh+Muois>s{-pI$%&$JL!d+1o>u_l&!(dHpG*?dp-D#ktGQ#wN-^7*n8xPf9}= zGv~;+V>KJYAq&WlOh*jK+%UfsYX$^r-U(H-xJUMKr$nrQMGxQ#Z zVV$CLzQw!}QqjMC>$xWKwy`m|tgK9ICKCN{9_)m7*-s9`g!#V4`JX-Xz2F5mEHYou z@S|yA&mjTd%IY|>^L>lYnf9%=RV+ZNzC4|2>MS#%ouduJL!IZo+{WEn4~PTHm)X6O zTFzWP;`@8`!VT@GWW?F!SnqZE&PFPo=5-XNQ<>k^VzP}u!mG77G!ji69LMb-CTRGU7VBEt@RR&89S2`R_m zah8yr7DYJ{NEPw^y{Cn_*GZz@@wp3h|L-25AI>+vyY&Mv%~ zE`!Njwp&|att+NPMafPgjSb-$6byTt9yf^j{e#HP7nVI6E1;t|JzWv^Q>7qc+R@q; z{Im_u|8lR-T$18OJp$&(7_-6L)X{x#rir7H=E=AZml+BL;<#HPm{8@-E;Bc_T^!vv ztkhI8P0YGDOJ1J|cySW)HXKY97)qNuic1?s5I9ET{H<~RyX@1`^$$ca!A18yeQtgF z!t#=FrS|Gtb4S1b1^W2-MA^74(0AdS2%7_J`biXd#%;MoXEDi0c)xz=_Xz$)^1HQ_ z%&1}vS9$f`-c-O}3x(=Ruywo>BIz^P!TRJLL%kC)Me0%@G;w^Z)Fb~>edd9NwjWX zU82lPhKPiv$n5Qbc$4*jEk7zHu#-p+INlV73~p)UlL$CT#ef}b5IeyOk4#OKLH5ch zD`P|17!i#k8ArC9b$NR9CNt$RCuhjv;eG$V6r2ZT3*pQV2MaUAtdye2>z%_Cu~?e`b*>9Mgman_7j zsx(gfVO;FeKL_5~W%#_Cwn>b7G7ej6hZ|Gf(WA0Z^@oxAzXT2VegEUfQ+UiudMZ$C zEMIwt={3mlV4EHI*+A0u6R2=y(Jn3 zMz+2vite~^!aGzaXlNe2HW(;D2;@fJ(t%z*n9W?7|KT<5$U~y=@$7>u*5y)s7-?>m zKNh$pe0I~*L@*LdUP9>)l*^bXr9?mFaE20L8 z@Qw2$=oo0R?^alB@xz@b^*eqHQ88BhBdLz2yL--KCzCG2!^6w3?rlHAn#`g^y5ii_A1!}xW9453)?P1L{KGy{L|qJvra(eH-ogZQ5AzFYax&HhRf#Eau`(l5-5lV*PV z{>eYxkStY?mitu*>Gf_fRHp-UR&&$x2onA%D7j(UX@Lpj{QUfHl^q5vtDe%PYpVOd zSAXpOc8@!4RhO63&=nh4JAWa)I_;tfm2p+$7_^>^m@%kc%$}d}emCE87mt%MyRtU4 z;Q~WJNl64kwxcN=`AAg0)_=!o&=Utt?S0$)DQhS>Yq|v)JXe7M30jNMt}OBV8A@wi(oK0h%5YN zW(@jd*RgN}6H&TCyfl7oUQu2)SZ!t+t+-Mctt%DgYbt6qxxzHb2w)~V0C*cAD(F>=zr++}`j+xh-^L_BG*@ra zHG62r{-Lsb8H}DmK@Xgrb>|w{Pon-wn2gai&Ho(Lg9-VM&0iry#iyy8-zVh|vutu$ zO)rOv!CnPIt^H6b;B!y+-^5Xb06Rb)N?zQ!&+^}Y*xMS6(KgkKO^@C8)vC&+ryty($$_e z?*O(f<0p|L5$sI$*&z!d2ki59eqUL^>!e;lI1+|aO^s__u00YoaP&+hu1X3f_4$&K zVdOY9e(LQ@h{wso!q=C|Z^tSi;NM|1fBlH$YfViMWYRjFNijW`o~|AquJK$(eT3m7 zTH717hTqEI4vy0Ia zc0?t5b~WFhm%C!~C1c%2d?Z)Yq~hd!hD&)qrj7pf;|=N%0q zz~B8XkA0^lDp5*S_xZy>f89F0^y1<)XLUk($m|7r{!5T|YX;4X3P!-402=bpdoAYg zlc$Kks}ZGat-1r~cqc!fHZMP41XGM>0IV8XAeLIVmDi>wq*vBPpMU6pX?cHGnh9{Q zp$!-BRo+=chySqEJw4azT%Rc7lxom#dLH2xJ$bC4uig7Hl3&i&meFo|M)ss5jE$Yq zbYz8rD`h|wsjO2UPZ$$&>%Va;VLO%e7*m0F62ieDkkOdA#CF>A)5Dj7XFZVs>WO16 z2&=)rUTQtAG%?8wYbvFy7b+;Pk~#v$tqtw%KOY`C14#fSD4+UdMCO_CJ)g8Ly60wU`r-E% z6%yZF-?Hg(8b>~xv7#|IC{f@_#Y2l7Dn)^X@n+TU{N!T>NSbwwZ17OTxf~WKww~XH za1Vll(IY0;Z&64s=+uo-cUT4jcwn6ZfJVB>Gw9|#?FIvC*pP!-FE4Jk{8j-#2U3ao z_3M^Mzia7j?V3+rBtA%>6ScKof*H-^B&lh6a@PH69e+X~ska2!-FPbn1BcANH8w`1 z-7Kghy&=`_n;!B2DBA06C5-8F8X_zscWHTbFHFB))M?QOB0}uYS|ubUA>Hxg@xXzK zn#$Z>bqM|GCxGb}pkewZVe`8T9I$y2DiNfDAXM!%dd(_G+8p<#J^N?_aCIR?6$-_< z6F>K`?2a&qBmWW`YbY<5{jK_abo2smE{-G|5j4+t~Edep6mbw;^5(d$#QLtZ*XY| zXV!CX!`Q?GSPgD&5HZ~c0ygCM-h#qqaPHF_~TgFHE zub~9%PL5pFYi@Q~VPSzX`h)8h3_yf$HN|8-rf(Eg9j8cK8%mQ}1MUIN8-)uwk&ZDI zO86YX0*xEOb5eGs{ozmeE`J4n`}TK-;C*H{3kW3KFNfezwiL}78LF=KS2mkKe((mY z)0S42T%)dWp`ngYI|T$nWw}{T?_gV;@gn>iG@*URHiPY%BVti2oe!yUvH^cxa(BG- z&YoYYsH+0bvFB-aHoY?gG2|}a_3Iu=M(5@gncm(aQ{zrctIPgmWCgU?*x2>Eo9Iwq zuL32?;@pzbA(Bo;-sL3-y6r zC{B0pUWxU1*=egV=4Xl!X$0eb%X}s<9GN2f7PJfpaiq#B7E}t?PJV>BA%g8tABcNl6(55t?KK-)hUqOPf`3f)XbP z;VJl*1}74^I5(Gq0GWmRwWRzY?m(&);43dB^)J((o6LIzi@!whtE zR#sL~`UV&6c~Hb}FKbk4LQCHv8ziN{^GZbpJe;py(X~0gd7n%i2K!!%H(57qRWvxp zrk(oyK(|46jSjWq}RZ>=hFUzO!PYN3Gq)f9SUjnC7MN~~Fcl=IYc&2P) zPjV7G#)=Tl&HWC^UrzEUT;E|B0bq z+_v9KP4uNT86^&=w`l+?3|`Jwu2%WXRlhLR>9JsL1-Nl6e-O&D%asbT*&28b#{ zU)xm8;*%AzynJ#d(YXRkzFJwWYI}7Yq_-b}t0(-PNa8>%hsXn^tz+H@TsY5n_y*_Z z$k2lWGXgG8TMdLyODCcixXYTzMZ&(*07Hcx)^ls*1d80))D#*=Ancxa8P~+vtnSq- z+U$*1li^|3-2s`W@o8PA6$Ln-UrG@qkl$U6K$p zz={wUps1=GCQKSx-`~^of?06z_ir|*gS#vD@9Iq+0YJ~fNlM1cyTLm7ENnCYSO;tC z$Foz!KwcH0;e&z(yR~4{@&yxTWJ`=?s-8+=ifCNUEOJ< zHpBN4?~95KRA#ppxP{3GQ0E~6_1^~IoD=XU?IW|^j{?lKPg@&yN?hoXX}xnKarX1LBF8}8sy}i z#%B07!M4Jsq@3_M2i`0dR>-fRnN;`b_9dhi0{~q`q#UtY40c&b&+s1HO&gTw!s^`W zF?4uy|G&&kxDyU0tm=>-z5z-ev}CCFB%&k!{rq_fqA~bD49Y3f$JUX9U*_i0KhY9Rc69)7-%{>L>63m82Ink zO%FsxqK`Ob;e!`adeFegC;(zK;DQ1p>}g3Tne$Sx=^g3yxhl!g#UeFN8LLCh@Mqkh zhym9)2JMI*W614Xg#0D@^rSCePIYiYdUQ6|fuAy9Ta%QMYPIHIWn+<&lS8LZCj0)K zrpxFxb?3>^*W~xzCl9hbK~D3Zr{{ z%klahS|0pbW82dCZw^mwe49b&L{qlmZm(NEpY=4{_tsP;{i#1h=T z?aA8MsIq) zjvNRMP_SQvLzNux6tF?4GJ#!{e0 zZ`M(k1p?huU0x$TE?JyKpSkn%l7fqS$oG0AIUukjkA|+!N)VW<7{uayYlk!pD_~wX zx3Yqu_IMnx%l7R&Rx`~~Yn0=qCHHfh=5rb?YPOMtULma4AXi&Q`7qT-Ag&h=#|R}l%V+86H~}W zpWl^g)V0`?UQ&W789Gb-)Go=r4xSNa>iDdBOc5%NVq#+6z5Cv644S@Kzb8$zk$T1A zsw(+(bfx3pLF40Kn3|tgL=FRCGzA14n3kVqfAo9u1RSBK_e29u9Ttr1_+OV6(Eg3K zz9ra^$)n|h=@^~}V{+NAA)AIhXpoavhEx)E`bLZNouqKm#dALCNN^qu?nrZKD{9Iu zMc|9xofJteg+!`+8f3J(QvW$VbYeH$7oJ7Oj<6=fS`L9}tZ=>N(_a+nG`8=>6msfb zy85&fjIBd|iHwOVdmg&@rID0kyQ#F1spUD<8|<)--2r&kF(A9)eoJ|z~516q6SFwKP^|NXtYOB-EHzk}HKbHub!Fp(dA)Qikj zUqm!_mlALyMfzjvx97WEF|#{3Gh7qz;n25|KGQ6^zS(Rr`$941vU(QQEwLkO5_h7z z)gaEvcQ+v51&R<>zXGuotNzL6cuM)|CW7DWWTcOH%hK#y!gC8z2hk^DlB~o$@9x|! z@wa9BC6qZ-S(`8GkrbPt8apHQw%zw*-zJNujY0QA%p1ED-Gse`#*^)aokp*lD$jT} zNvsxykHMrK&bn{nqm}L7Cadu}kG6Z5t2@LxSX3($-6y_#T#g@@|qDf*@xYooV- zej1ed4&^U`F11Nt@R#ibpOCoOs-?&3!BKC7mxmrBqTtaSyQ-Kf4wA5tBKwprhFlI> zdymx(Z>SI&%E#YYal67krdQ1CuCjKk5Ux^qUN^b*mMsL*Ix$1uZwz7~ z@gK-A_Ws@CpePqD)u7Pt9!o1pmdUUY3Z%NzVH5?endGSVc-^**PEs4_sjvV6ah$(= zu##~AIfDSieI6VuUqrblsj%Ce}l&5rt?8fny^lofu z>*-$_&{AeLG&H2*lw#@{a3^S`Bhb#z?f*J(r@$cXCD3aU@8n|W^6t(o3Mc|PGh z4I^LQh@q&bK(YA1_9xIpT0GV@)_8qc`}Iw_LbEYTx;Jh85}|7njB_FaY5K89%Jg`g z-z9Z;QC!OtP6krjb}&lJ2K9V*63lv5%KG{T9DUs5(GZNBagh`+RD3o(NAt)^s^dZL z4{LWuuJRGhPX<4s0;P?-L@6qLiZ$1nN|bv4*(X4tUBC0gWpYl}m|GRRc(ux;ClY7E z$B2-tQZ2;Hzi_T0?l5`^bLhL~-@kFRtL$kgcx&}?SZ8=#2;l)Eu1%*`d{XJ- zX}eCFw;lKgYnG41ZJHGOmsfReg=n(WgUHG7u|>@zUUpw^F~x2Zr*4z!KZR4XE0%3u zNLTbJa%R;mToM9^0#0P{K>KP*jCZq(GkQr+8Pu*mYdt)2Wa-JPnw`H43WGjyAg_&` zKZywV$(v?r&??i!m1y)8czf6VCuS6-WN2v`=T84NPp8o(b(CywIjTQR1)uF|u@K(n3^7o$|;JaUi&l;3ZdH^ah zUS@(;I4W~qVQw1%7nV`3$?3zR2x1_cN`KV%xiwxfd{?6j67lyI2p(M3J@S!^E}68! zLG5_L6hgE`8$3PpS>BftLc*GE7SQU?{%BubMc#xsQ}sgJuKQfK;Y7g`Bd^-pHFK-^ zf4`V*YzmVh>lQ~96fb0wJo*=5gMKOCBXBs^ZIJ&1d%)j1Gfr9AbeD!rNRo<@_^hF` z0IimPyz*3us6p#)X7(t{v8FL%3tiiX0d=%y4+7C?@rT6mtTN!^q+8>w&wC|(usp0zGbD5n^V&3fGo>E=5Xzn zei_E#4>LccIZ>->O_M0F)25N*T*cFBsCZLI3>Qzno0#;2&vBT^Z=gS_wDv!(izXv> zqODl{rhz1C`C(uk8}B~?g%xj#Zpz1i<|MnOzz+J+q(PqvOeB91ML|)&(-x2G3wd9y zL9N1_6sfEiX0uzA1?*pnX^_82Q~u1t!d}b-rr0m6BGDt$;%kNyWACWr-$=*TR4);| zmkXOv9;c9MR!438p*pcvdWh8R7X)Yg4FMGO5KV5`hwW? zbw6p8RL(eGNyv`(YMs7BunTwW%0dSk-`-M;^<>!tKoB-JA5$rk)naBUbT2ydaNFCpSb!O#FPa5C4sO$)BP#zqg(MH{EOCHwa|OL zs#cH{SM|<#_$n+^CtZhDv3mnIVyE5*3d?vjtArC>t@H@bI0^)`9fFGoC#M-S6mi_I zIH~_Om@!RO+KER~KyG!@Wyjz~f7XU@4)0Gf?Sm>p)1FTh2?{vR?(*M1P;c^0;gqWv zvyx^FMkg^I$-c`WSRU&wAkRjar9o2?FR^QPz11ZAOJg~wCpJ`X#SdSYwW2f325U!& z=wAp?eumn8q$zP~_@e^0$@q5-WMq@A8*| zol;FSrBut=6G}@-P&sn~Az_P-CC8U5c zSVgsv^A$dlzYIq&=syOav2*sklN36+!$4ypE_nUO_voip0R^>MLCaX{ddb0|GEeMW z4aVR>^^PJx^Xcn`(%2i85b_SC5F?9=x7G_g?N8DIA9>ZZpfjCv(mQs+xK#3$>xJ?D7(yX%CWVoaO(C zvLt+_!2Xx`&!XYp`kx8ZQ}4}*(%7BLa=ZWXO(lzeFtPI&6z;j*^A)UfvtIPNxs3di zvSm5TnIKcZ`1z2mNu*Js*|fr@1icU*#eu|Lb2Ql4F^~1@2J%LBc9S^e_nU6)Zmb#- z*0q4WIhY`#{>Vtr%*rdBHGyBqAs9U_Q>vkb|7a-YL}v6g+J*=t-Ezgx>zNi5Tv$b9 zuMSU+%93Rqmw&1jJ=TN1tl*nS!E>|O1qg!%dfU}{b|B$ou*`0j6-TwCXH+{&Ncwlk)MD^%CGO8; z`!2hy_4LmeeNW6W9UmzTTZf{+tBBKRVd3Z!EmVa4C`bHhv$1_q$m4h@>Mmp6m) zC9+we`EL{bQHJFAhc^`;25kE0{`^e+xy-^@&~F7{!4f9r^jX6nGn$K1c>h*7@dkV) z0v2HR;(k13NSRK{)-e#t-yJ^)c(|a;yd$2 zOB&nyrh?qwn&S}!N5T(wsD!3&%b}C_KZYf#YB zeBI!-{1<9OB5brh_V>DIdU1<%o-Z(6|10*`>3as95I#OWUzUH?-jS7e!$v%;Ooqe@eX_J$)cn`4 za;MtK$z69JiRd5mcQaLJpGGn$Fe1k5>`38#{G3x|)PL4)T2c02mmF;@>d@Jl%fRu^ zehTD!Vw#O~mN_4Sk;)%LcJ=NLW33AEb*;7I)Oh<}H~Pv%zo+>)iWbdZLV>Mn0Kir{M@hoCl@=RO*vVvJYMGM?gf|k zDVY!dbQ%F=pd?O67aruBR_id*h6ZRxb9wLHk@q?4^{kAnJQq^VRT>z#Rzp&>Dv$Y$bU%)giL%6!r$`OW{K@8gA)TWsXNLUnlFxpL zxqqIy$2oiA2d5AuZg)h>xxHp)R%mdxwVu82OWGAlVt5i^LxG35?K!zQ9=v`YgS`mC z9}uPPX*`ahDRbFSgH=m|apVtiCn@r0xhw)w(x!sVwjQ4nj-CBu{S->XG;s1F(*y$N5vU@ZOe+hpCjW_@ctU4cQ62bKB9QOUD&A|NgZ?Nzn;AX$pr}mb z!QF)rq&-pMw823kJNzIel)BNM|3wP4`d?kxb8Yg>I*zKXBbx6qB8ZgP*F_aojyI=T zGBE_9^JeMiFLwA+-vj|`yz1%HX74^aql$x@B_*wxr-Cd_{`Wgi*8O`BwXO)r$Cq~x z+55~06BUXVhW;Q;T3s&>50mTJ#r~5jTKlc;OKMs!N{`n@o8!X5;`f2n#`StdTLY2mvhA+O;nAZ*0$gTUtZk?DZPyvy}L^jJ+pc*mO6pew1Jq zJc^Xg!g|v-w*AU5iyNzD-JV%JYvNw_@;+=1*8BztxvXbki%eha`dj942ikWT5!85L zoR4LOg;KjnxLOg7hXndQ+t2iTwp<`t$X#CN!0k&gjgi~mS8<1?11?uOdC)g%9`PRb zM$mDB_!l%>M?N~Vh-wd~_gZ*$U0c}&1%V+wul7ejWP#B{B)$3cv|3NIab6njgu?G` z!@@zJ6Fyh9A1QC8U7P7hd2uEhnz2*O`D=ymdY{`mQIybg?pIBA9QHYIyKR+n3BP$)NeoH2Xlf+4|2QE!u4#RCa1bYVR@u5ovLR>espg zBF#8SGZvRwW2ms=oaK|GP02sj!dCl02#QmaGRvLwiwpPTgxN(pd7lIj7vbR<5&f(y zEDVR|XR`YN1=Gzx)d*sN_ap1M#Ua--dSG5vAIdal(S(y_uz-3&g8}d7vi23Git6%t zf6|krjG61rZ>9D1eMdx`G_g`h_wSN;oC-HyR}_=0;{d7hZxCE9cd|0<_ZCc|dvL@f z)&xF4h-_aU_}wA5JRNqSVu6dtg8~O^h=;)tqFHdP8oqC)tWO$1#>~sBo(A5mgvhs= zA4iwWkS3mZyBZi*`=P^Rj9|iGDY0O^uU)yj>7;KmnEFbJGG%dM>ln+zmMX0m4q>${ z(`Wx#T1MMUx{)W!7%N$P=OBVqYI+8SgJa&Ee>yRt0VB%`YeSFhxpnKkw%?Q`(91?K zi$@X*;~+_88S!uAn*Oz{DzYlyx9qeqH1zLiC-*wu?l3KfdmRiC8ijbFM9vE8?BNnl ztQdml1Yr3a{mPGY?=BQ3TRLWt)VuMdz^;KDCbqg((2ZMZGZ|6vQ*sk*PI##BQ;qve z*vY(phOv9!(-r6yX%XfY7V{7;2zj2YIz%K3b1i|ye!DM3(#hbN3_%oA6F=Ablj=`e zJirM!-r&ZhU1if{&7n*iyX#)>={m86UV86I5~A=2Yprn*ukl{tC6QsK7p*N)+3~~&CTr3y{xRP;qRJf z8tT^9*B3W0b{wu&x}UR7TRGFV+MxFZ{L-)mg$>W^mhOHc>*>lAvotS&BtB3`LOD%F zKC1e|M?J=4BkySPLo;aH8w5zWTxFP^(Z?42r+LQbBY=b?lhM8Oo9(~D9WoO2`aU;!wz8xF#%*uVbmmImF%L;@w-;^Z5 zuIHE39B|D`H6*I7&5OZ*3Cw%E^{C_)qiqOYjwy)z^Q@ zwqWC|g5uZ%rvskZmsLbJonE3NY~bWL?c5QR&r(XS%fYYFF?Bc3m8*e=e!2p7(@pDG zl(b1=t04p@wY^c7%pQho4O#xjWgfk1sra%m_`vOWbw5c{OK0h@&g^5yBE9IU#m?GX z-Rw10htb`tuCS5i3>A9Y`cBcPtPaZk8e&L=1}Ik!B)dv^p9fbVpZ!H;iGthdhE?Tx zAV89iHKMtBA%f?D_#luP!Fc`sMAAhOg$QYq7XEb*P25H@$in_n0YMQW$N|lNY_wnD zq9ya6%onEKPdm~0kR8=yENM3E>~`|G-{fq!RgAxyvU#_{Fx5RHW+l#apz%ha#~4c( zvwIm0(6eXcQOJV=7xd*LBj)#hR8~UoE%(8I#qaqIYaBGa1fSpL)8!(ZVFAr^bGSTp zwH}buJYMTU2W2_eviEUNd6+z0hSn&n;JPkRoasbB9+}~5ZH0U`XA{k$jSzRfqLKB( z8HN;C($a{}L7Q3aoXv zpJEiKQFC%0g>`^dTNp?7iOY`RanZ=6u^FGy=}etg7NPvowzn zOZ(8dmjIQ^#x;Gxt4u<+K{pD|)i@B;F$2H;%(N)Od2Y=SI6dEPTF$=v=6x+)$#n%A zV{%h-Tw!gR%W;ESPx0mv)#lpAYXPZ{EA;t;yg^G?zqA6JA`SvL4+{B~$@LHoJ*ty8Q*KS%biNS66yN^B)!Q^zA9_+ps zgdd-h+PQHsG}aW-i(ty2p#=gCknIR!pLZ*!4K@EU{}vUC+t?W&8t+MMxPXEHE4254v8KH|oXvzuF>qrE#_RUAc+LiE2-mj}ly;I`U6&3sl9P=+|{- zU;8#lY1+t$DNWK}9B&%#jf-9HHC3SF3*{#xEfVmqxWA+<12Z~=UK zrrBqbfF_89J8AOp+~?DWHfUTM|{|4OQM9&T0Qu~=RPdoGz`_zRUz$z zfY1ze1McVO9Cq7g&eoq=S_=L?cQrLz&HoY0VLL;d7x`RxZsKSI>C(5hmS;ofh#d&& zO55?)g5s-(1*3173CN!68`}y<m+t=w3^OdCasu%74 z=~3Q~kBdWIsNmUDts_8vcu0}ZtG>3iH4ksB{$l2WZ~s>ykncERhUVrUQ@4v~ z@qHF$3pmfF2K292n+&-V@;P=Z)K**jV1Vuuyd3dc1n^|t+%8jr#_>4NiJ0HJWM(is zCx<9Ta;Y^a%=t%^GA)9Dq){*DaX~*qCvR$Rm@8K5;EMF}b8rM{W?daNoF5P&UDy9s zTU(ny0YHcFhzQr~0}S8p`@tA<&RiR#9xq>JUjC~XJ8Q#lifG#wQas}4_%$0mTda@u zcay`k82vSycX)r&BXb*@c`&S80vcXASqQNMc=(9Z-AgejwvvUKm_J^os>`H2(=(Pn znO**Dfmr>`JDAx_-Cn3`qOogXy;K40vC(kr8qC7?X{3XFIHuNpsD!H6-6mg zeTsSI2x{Iwd?>;~4LW?N%xQkqI9??3C@M%)Ts#(~om!LyDn$6-*z^%HS^eEVN+;)hYo z^sFp+ROGxMl=3IGsP5>8W2K&C!(7GmtL$(YYzSXZYINNRPELyhqK;(NXEA*MJ zz0bzt7~^gP5huvDh%hw#fta3^Lp1cJNc(RIYnQ}rZDTM^b3Jzr0Ns<&ouui3(=`Iu zq}ZMwNeG9CqAN=cA$h#u%-v(cT7Pz2hiv(vNl+*^55=z;LapGt{iWP&Fj~e;f{}X9 zqd_$B<>(puyN7M+k30?vl~ul=*12tcgEFJ>gl8+6XjS~gmWgj^Fv)OG*B6_7eN^9O z^joG^`%hRWt^OlR26I7_pk^(1680d1ezZR9xv>je_m#>OXKNi|Ly$d zO>sW0Z}B70O>}LTSXhLJ8bxgv$$@t%K4m27T$90+pI2Me<7QK{LHOT33nQHDTry+? z?HdP*G&o!b+q|D-W!4|1*<-`!fid7CRHO4YTINSZB{(^tj`fSlGgamBhW~h>iIIrY zt|VFNHFO?*<$2U%fC;=ERmw^Ot66+fnjMXNSVtcmu2j_2ApUt-Q~!Q!;{}!l73Sjw zjE4%iL39YFJy;-$oc0gDnm$bHdZWxG0%sNGZ*ClM+nKrW*<_(Sm9>qnbn@O$5uboF zei3?)1QAnN$?+k$C|X0Ob?4wIdTOP>2o3tq(SkQ$q)d`siCPqpp_h&)CHwQ>BF5>n=g$m{r0fzc z<0v>VtW6DH{QR}MTiZw3kQ4Z6aP=kT8_=DA;#DriH)kL!QAcigax$>PdSz<7{HQr);3oB+Y*tnUt{>Ug4LSpN^N-4Q zO(V<-K(e=3KHTXD!|z!>c;EISnGqiV_ZP|y&L|H8-vGsBtXOe>cDnL1X6Majld03wch4XKBxWXLd~>@b~{76GMHR~Uo;#mUgq zx0g&7!iji!eFsX>tlHYDljVwLs|UQ&X;Z|o9s~&U#}hw(50ngy{4+i$Y%wF{ zIH6*2AV4(R)5jl>KR~&fS~e9m$p2+ggYH4+&`c`H0vZ|^(_X66!oJOMbn=>m=jZRk zA4QQq0&uEA-Pk92nYAZhVp08tN^E0v7&%8`l#@^ULq2GZBj3xVovgAGFN=rj%)%4A z^{sy*s<;my6-O5dwp})UQ2p4sK%|E?=?oNzO zoo5^^%J;TZW9eV4FxDQDKryIQC78cmJb>#EMa1d8u_TGwL7wMK$QHZuk8pIEmYL5v z78-tD^x`5Z8eIG-6wN#Uhn8ZlnmbG#BI%f^mJjD!FZqJJQ-jRE4DF#LzBGhEY^>-B zwr)#7)9{}hWeZ5Ske&Z1fNu*&G&XRD{0kvs)7KvS=hu4|C0aJ$qI*ZBvvAZIF_akb z0QRi4K@ZwJyC2_=g<#ZOQW}lZq`;PyHLNFLaui$X8+XES)SP0(pD)?g_u?Y~YLe^f z*kUCEEnYM#HPtpWh#XO@^EQsIIvG7NDXGV#Jo#dm53l?gqD|P!s-RJjiaPvG=gz(Y z9Wq5~NtA8%8FR=ccUv$`*%=FA9)G0%Yj z-thGX-+=$W)cZ7Xp&tW;^!1sbF-{T3!D~vRA8HYkJC<*0eV9g}zN*}11CQ-c4@oU7 zXnTA6gDQ_F`zPNP9)8xgeI+c(XfDT7C|3$hC26Rg+_)uf%BpiOrhS_t+a6(HA)j`C z8(|YC_q<^!Pw2m&^iSAXRq=4?yTQAGV^_#@iCRGxiM`HlD73+~(c;%EP-v!?JbIX$ zm>t!>f*cfZcXh)o*x#W4*_0FfNb^ho!7S;py0-IF`ovEZq6b#e0a z@hQlpvdhcw!)t>g95CXdZWs%T(W;XuLxjlQ8M8bMABd5le?f=qx;-WAR2^cYU8TZ$ zmBPju9MZ8Unu#V_VAk{~l3&Qm3XLizPb)pEv;^}dVsL0S=aKizDCRwlA#F zFBKLwyd8h~!O)@a_f7m;HZeVY3e@!iTCi(c|eMJKlnmg=LA%hL9dt#Exm<0&5 z%1YTuPOr-r<#$&HX$d)`YC4S6x?5WS0!wvZq3v-wp*c{*keuqRf3XN?&Q7)Ev*jGu zi5Lp$8J&s?5YjFu!PNfPq4}}n?%KvW44tg(te}`OKFIdPL*ONZb?#p9IlDT83n`(1 zkW~@q+1dsrVvrSI_ZNn5I;Lyz^T=K?jwH&Mp4;8@sfF!46f?=IJNOkn{vAt)>ZAMo zeZXBd=p5z3W-WKIwNf21M+pvjpQNFqWh_7_uBdwMSqmFaJ9e1NV80lqSL(^ViL%}4Lp zdugLZ_p~2H?S1GefG3;(wH}@k3YN6AXHRv9h@V~L_2hvfAP~bi8QfS@cwww{n3)Y( z&x*&|rl$DTts^9qVdw1w;&XKK-ma&Pvx_T~{UyXF4w(RMSWz_(9<&bZ_5}wBlWSkt zXDK}`G}VQ-E)gA4b4Jsf$7Z5QHFp5wmk;CCRHfDJhnvJk>?2ZxTtjQ?*3<;QJ^Uef zf^~?-GzQ81M}_F_#TDQiQ9q5h;~V}Rc$(W;QKrbj6>F06Wv}U22y4g3AIiUMF6@5_ zA~?>jP8Z(;OB8o?aU%bBX-1_G(S;Law0B%z5+LLz&TCthR8!+oRzsY0ei07@xyY`Ew-D6$O={ZaDKiweoJ*bg$QP=6=Hg+o4tW3+bugckQf49)PL z;ZMK=SQ{w~mZ+;%+K~uBcGT($4PyDEgz?wgUMIaS8p-Wx9rom32 zL9Up?w!UpnO@OSRh_jNZxPrG3FPr_r>PH;P==2b9q#Dz`DA_A3pYvHZx6N-)c}~(o zGijdZ=$>A+&^|~W(?5Suy}r5j>-q39j^BR6&hX4o50mdP>%tz?2w?-C_5a0vt2r|~ zppWt0i9GAyD0YC27mhL@e-e^YDb>4Y7i`s3MPou{iU#r{`dC;vLh@;ke2P?bM$L;Jbg0EvQn*o!1mu(=i(7i2c3?z z4GTAiG9~uR5+F;-&t@UjH4wlnp3HeWhOpbW8#8S>c*5!kbe%38(oW~+pQop*Gu}lDk_>^ zAjc+aV(A%Y%+rwZ^v4I(Ls!?i6OSHzRM_nlX=7g}IBV5^ofUVY5HWIy3Ubf59_8=6tE?>YJqoNa8JR({1R0lE;Sn~GmOF(E3|}q!#4_nA@S;RZQ|B9O4ors=*qnwm zQf8-&I5q^*#`~r&`9PLa83z$8YzL)W>F?5x|ER&(A(_QWgv8H|r1-TVD)F+HN}8W?Vu-%6|^rHTg`DBlAEr z1}-^9oAX6v&zr#UGn$Yr$~zn`m3z~6S9gQa zH>n{5tb95{ogUGtg`QER(9gJaZETgYD_%O zNA+HSq8HH%qCj|v3#1jR`AWOD(fo!c9S4FmYJ>e&sc`Dt;Wx4qQ6bZo7Zd`d|T~|!+GVs5a(gpn=oC5ofV>hxDXx8wbtI@gEHC$iQb?MT^ z{@WkD5X%KML1>3jgGCXABv7TsHJ?CA9!(*&%yOn9x5K&UYR8pxP7wMIQUiyX1VY95 zNaS_#U{)PmeWkXpwh4h>7yo{KpV;}B@vdtzFH#UOs7xD&i3GhFe{GIkp0Zrog}(cG z(~nxKpjq^}cUeL8LC#3XsHIq(3BQ0so=Q!hjf-deBqRp^)W149@z@Vxaxl1QbitQ~ z*BCI)?RLBpF|aup0XDsnFsVd!l_6H{zw&XY_u~oIrc(BaAe&SNtzuVJ+ExiJPhg-Fej;M93>JGX58gRPbJnVr?3%W} zx9b167jf8qb@B+cLchq*N2p9QR!^>Zg=VNF&7l-@swZ_#@D@IHFZlOw?~j1?#emiF z6m{yJ zuFjD-JIP->q_ZwN@YaBCp3Pkb)sp19Rp7tZzI(!{w^+d`x5l@8k7!_CYMhOS?Drp) zEzTd72PS*yj^Ed%9I{gL`xmvY@}?Get$(Eb!$;a^%=zwlGr5JrUtqdC({$l;@U?$Z?& z{Nbn=QY$Zh{KU9A>MHk)_Q}}Nqnlh8cQvb@R;3#5E9*t}b8{r#X9sDU?8+l80nqii z)nPz*^XEChNB5iSZ&*xY)+1aTv-)(-YRWfX`v+be+8$^8P*c0O!y$x%h(}l~VNZvL z=TB6GTelZp3?ENJeZAQqD?Cja?Zy6#f|Y zA{|0p5{zE#Bcdp;TV3lK6Vg2I%(hz}+cq?;;)Z5?>RtYq+6gS0ozuJC6Vk)}T{rtx z)xsn5K=Jx`$GZh8<{+t;+NKS*Ye4?(6Ln|%eh^Fvu*0Z&u&R#H`qyP>1eG-V?W{&f zoQR+Z8lGv}59cYEfKH`sFZew_>|E^;ZTi}ZeEZaY(6>HhA9RhAK}|dpNCLY8^R#!5 zRXh1iw!bS`&VlU`eZjih?92H4>$=8LJQLq(xi`NhXSFUSCie=xa>{S&2hGCAKAeVh z?zvbgr&-O<9JkwC*A>?U1U}x+WM8eGo~az#nb~#^U&$K$Emv`d@NiEGAI);>-ye5l z;=-#R5S|^rDJ&G^9xc(qw_#6@U;f=#J=N_|sPjgYjP>YAU4^PzsGowJf_u?L=kTsa zc4QgVcG>GXWEbbmN0HT9sM(PPG214BFsy!H?O5}*ggftl5pbz+InG?Gj@)RT+HR^G zyx}M_@!Ku-qK=U^wl<6|-AVf=d4_BPv)$#2xWK{o_NwBz0wKrElI`&_VszDJ);&cR zlk-y7Mi*>sgifzkadF0Bfu8SL?$*YAQSjg|hn$g<577fu0@8$D$Bm`D>S)BIt9hCH zj_K931rz6={3lmG`A#K>Ce(B;UhK^vzMnp`K2N!vubwcv@BP56+M}$~b&?GKY6an$ z@pt`aVgR?#-k8rT&a~CaoV4sb8e`ey+jpNZ^LvIT_#DyZ$p+5)%v+^}JpS%R-?r}B zZ$IBeG5Pl|x10XWcNwg^_feE>*05Wd<{!7sUu*b-XR^F}RJWO_AAqD`OcOM+-g>uUN*+g z&0+NLH$239ivR6mgrpoW8gE)d7)gS2_x`AGbPt@#><`xr-c?nP?M=)^qDeff z@9*v-;2W>EWAYWABcn*gJ@ss!v*)5VL76fe$P*YC+GBrWb5FqU-__$V!zKD&;NyK& zxvC7OCAGv5f&V;B-n=W`|n5pFo0f>|NGki`5_HY z#xWpf$E(BVGJogbdIFU?q5HpA3X>m8vSIo^@BRP1Yd23+QKe6paH0QtLCE1e#kF(w z;Qzh>{r~v}u_5*!5g!kVZnpY)+&64sr*7P|{m=ImbY+Is;=ecX|GS&Bc&1qBmuaAv z+xKQs??$NR_#B@c{UO=f|9m>v|MSy% zmqMFvj&gkZ`hCvO*-A?#2mbpdJsJNs(_E^872x{q~dvh0ZppI0iS)2p45CQD(cWGT>& zjos9CLF=M*Q!Ds^o*KU&g|hvL8uT_c|WRr(W#6lg0_7s02<6{ z5A4@I%XHR%s{$NZpazJ$$5`h)&XdwM=5T=+9qHr*0WMnXi9LpH-rucII*Kc=0? zBNp&HIQgv~zti&Hl&^m3rikvm2-<;@I)+Lsd8qjpNhj`}vHJ5DrZFMvq>W}g0NA|e zzIRq+bO&o;Z+2b1C%T0UmB8%c7efnHMr_w|^`uli!e3t_K1wz_vi7>dZlY&M?~Jvb z$n928Z`bKCdj>VTn=a%NfQAFOxS$AuhMDQ=-!2D~X=Tn&w`beo)2M#^6s}WXkG(KM z0@*C&VC}co3;?;WxXrTbUO^qVe6D#}hG-7c^NKhg#lphIrb!5&n`#fx&a*ea(FLo# zXGrWB#p6^9R<|JIt@m!pz|Wf~BuhdWx?fdjLrc=@(=7lubxbYwl!z27EQ$$Z`}K{y zilQGRJ!B?VZIzDZ;k(pKNSgLDVyP?oxilXio#&j@M`ZNjKN5t&C33!{2iD zH(=xAq3yc6?~dQ)Kg()gM{L8=7z3a9_sW&YWA1W}BXokDq4$|+%iKf4w z-QnV#h2HzQxy#qy`!P6Z4>B6i6>ib0I2~8kYjCjt_MM$EkWvKwZo{^K2XaueYh2zB z3%p*?9!3zF9E=u1pXZ0y1ADvf{98h9!4VPi zDff;qG3DTg3G2qiBVc=OE0csr7!m(9S4%DVxv_?ZTVF%i!8`DcpfF@2)SSecF*hY)Ol@UI=qf*z|+n0i(5_6{is|84#clHScPjsB|n#9_R zr%>PZn*m~cDKgKDxsTAiQ*hs(}%d%VqGIKj0c`P_jngLfVt6Rx{xIw?BJv|UtH z*M#1OEXRo1$Z1O`ADw%6aJww+239GlaQw2J?E{~0rR-l93gjvJP=4eXJbMTNr$CPE}vdKl2H8Za79_~ef5_1Bt5kXduiWYQc|kZxRmIk z0s^p`-N>7iZngW0DsiIe4fSXBH+o=qaaio*0U)5~c6AbY%9FbjJ|~$zb4^*@CvpMq zyeTUy9n^`k$FBRAP-oS<%&7-4=5bx=5hO1_&NS9<1Df8Lm^ZG7v?WLP>lHhnmP#ig zyyLcp_CVv{hK8IK)Qnlyl`xZAJ<)logXK!|d0!;+l(Q8Wp`QCR3A2Bsb;izB;;Un;i!F0#LGt(<@nEwXE_bQH;BuS z%Y{?YTReo^T=q(Y@cq=7ei`PcUQ@5)63HS@%y4NKdflLFw?*kskdIwum` zvD#KBcj_*l`=t+%wSn0I8P3z^VN?pV#<`d>puarl^YkT_3Ahs?E=r6+nu<2~9fNvl zpXnYKxNbJue|SkBAxbHc`R*qrAh{n0ev(0oeRQu;;WJnbD3M5|ywjch8QT7aLKfXT zHZ(SwJk{KoqPw?c@Y@Pf12!^xNGr=mnMI&6IryDMWQ=`(hD4GwLnvE3Jo4zCOsoIS z$JPb6yCR30Pa5sHJ7-37pFMwwz9&BU1Y6>n9dYn`;Xq2lBs+Vr{t?lN<#Sht1>n7+R^Xh<5M4qF%}$mGF9k^{s!UVYVuZ9sq1PO z7?^}_4bR3{QKBOUA-5amE;$Z&NsVb@v@YR&AS2!#$9sX|OgWMKP_cyw<=IDZg$`r$ zSX5&kfwbapHSh$!2h~LmpRGL(U@_-dcMWY_JVpJyn6sF_fY#|mj}t*kn&B-T7_)lm zHG%v=^g{+qEGv&?+`_Z?J+De+aZ+MGO`6xKuTD-(H$EzKn2@8BW>AwpL!#}HvDjP# z5zNOU1}a?3qs((sJPDGx3{`@!OiE@VntIfjkw5dF=Q$dt$JTV3lzbDs(%$7IjC_tP z6)bKwi$!uM_17Mfa=j4^Qgb@o0F6tdr5Eu$` zhstN3H(4hE{zC{yev-Zz=OK&xC{+v6NoK2bWhnY1Dn#PNzWq&daQot^*!*xR=3Y?K z`}eAGWgNE*2XXoe<H2n(e1;#>1ckt`agz#sj!F2l1l$IevS8+kg14+ z(~wometQeeg;$X#&Vm37IVhxMfqI!nl4HWbAFmM%d7>bO#=Dt=UJp0N@Q4K z3<;S^v_uB}?TZgDpx{QR?Q{m1yH$X8qAi;&9-tsC-EAf-F&gXncXhmwLuKT*~gk_mFl(c+ArR-NZ7zX(FuP)Bi8bCAfpSElP zuAqpBr=g*tQ7iP##z@dId$m5;6YfT^Ydp;dvC^jS6`g~xM=nTMy6JLNA5Dyrg}H)7lv z3r+3yq*Qb<3A*n>s=d5WX7EV}BaJxmPDh>kGnDeq^6RhoKE4xRO5=~vENonNR?^aH z9~ii$_G6ZmYDi`*ow2K%PJtE^p6&hf9adh!kO}jp;m+sIguEZM8CQKS!@!W!4)l|3 zHTzxNQ}~40C$>T%;&8m2uKb&k@5EwYI~;Fm#A5+>w27Ua zGed#;b6VPJ+Y$cnlasWysWnzsXh+EagUVXn$iE0vXXg*|^UwU!(Ns%ADxmp7fw~1$ z`zbm)IN_3<|B8k?%zQ$T;-u2?f*TuOE3+`mC7U<8Se;6p^pHn^NYlM`bib;)I#Ews zk|bg8LHz~aXE{pm>w~o7U-QC@2@dRMV`8YWAdRaxw7)E?omyrBXKlf4U1&)vqLND>3en5fw^#4ITWisRlwj@$7GkM|)m zM|o%E?wO~ooV;Vs4r870T*%6|3FC#esOH$%c+!|oduwZEX66Ps9o-pF*K3a=lhV-8 zUGR_e3DBk_BaA%2_Bn3{F8+Z_BlOD@zDVy*<YCVpO+yvDMsk0&^c>0e{EMZo=b4G4 z(}CM&;p|+?9*6hY^~L&EJuf*-f`3JKRe*X#zWopW=ypt4Gg z{9=3KTX}hSq~LXMKr02v1yXDn%3NJa*y|glu!XM5scnw*x?cv9W=RCVBvDjQcrQ-c zIB);&_Vn~@k&VS;VDF!g=~2+pC8bOgyz_YX`Q6%=sV(cL1RFA@Q4ioheDn3!Dfc}D(ROU)|ceg3R?WuLI9;bjQo<;%4*Z_sB3zYS>FFafVs zz!r-XEry%*85Mtq*?q0G0CDT#Mi`TVs;)e!d|l5Upz`|<(_&KbP3GknNm0hJa0mow z|8S$vRnycK*RsMt3%D1Y(Xqe($ji%BebycT1Lg(!>7@r~P6tl8%Cz9qC`~Tj)+V{W zxzoOR^ekKg+=zSnne>M@-8Z#nDcR^AzrQ*1xjunZV0ilA-rbWL@Hc<*uI?hm&Zq)r z&(%NXzNLIr>V_&NV2rEpiL9$_wMb`{mAUp*JxxQ_zu={D{*tRekTuuC_DEs67g(2nZM3 zncr=_e+6!#9)6OK>_!+`JIC_Tc+5$QWvV)@I75e@ig~%_@$vC*E_T_Q0W?^*N;^9e zhjOC2jY0E0I5H9d48P*_x#PmW^hG~NLpw{}GsrzDD}VcSXcO|HZ969<-uK$v91Nh! zNC51qXOHfKRyFIQj{x?ZJ#oL9Ef^D%)G#LUluF7gTT|-z;6|Z^wHJSp^Stq>@2qQY zhED221j4*bQ#C$eeSO>X?ev~{B2Iv4-{$P;eeeu5UUR;@-nk*%w93C+p1l;{(NLY# z)XK{(5HD0MMNFCM+rQ6SPh`KVN*m|+J3r<;@V+xIfmV{%6k^B7)A5TNX=BB#=UxBC zh7me74Ru`+(r19(U6?RSTUI0T>X~Y~^C-Zt?ff0slQC=cfWf7yS-PJ3nTg?Nhj zz&f`xbzZj$Ek_?>X@-apS4@_inud06IBy6PE5vHlx%v5Gj0tR9eC^A0YTh=lD6Urh z5R(3>J6hNRJ;#|PM9~?);7#@($jC(Hg?R+ z5R#n);u7MLV1*gMSA4gHtdXbzuBJgh#DbWUdaZ42{`?(kKHTD0%ENd@O~;s#nRz#9 zTAmu?-w495sE#pyrr2W135p3xcL@raEWhyZC)1fhxYYCEi+kOdk zjrZ_p-Q)atzZtvl>avM6)5r+W!|aw%;^HusRaA)q)T?Sk*w5^JBOi+Uph?aAQobds?fT_7v&0TtBmbK=>??aQ=vbo*L{PH0U88-1z&N z7SN$}17Ot5f-E6J>n+xtLxVGt*(2x1yQ(kmw~UT)frP37;R3;k7}$kjg;97V_OBYb z8OO#gn}{p6*j5ZpO?}YKxe(=KbX>w=uJZyyw>dk%Y0p2x(9lPS`xK9&oA0^YQq%P0}{ z+%VAS;TO<;4;WWqKadVt%FU8tJaVuzjs>L?#v`7Qk&%`Ky;N!9TYKt&c%*?96YeUY zRENeDA~g$5!E>Sf=q>N$Yvm@?~r zQ4;)wIy`+*0V_MdEHzHX_Y!og?6~!H3z(|K>OHWW_VqEk0`06?01UE#=G+FPaGr?? zkYWouTuZgLC8niOp@&B&CQ8GT(MU|x`)!wypoW8s-;8h}OXviU`L{}*#H=aT3Zgu>+g3*c(}X-;ZKgV>mB_4{O&w@w12i$+O1vh{y0%t zh8#UTztn$gi=O}DVyc>}X=4&kDI~V5>(Pd#)u$X}Vn0CCex9i00lT*l@r>An1VuHi zFx7nb4QBxYJ$L@X`D^FP&G!h+CqVniDlH95NwIqA3qij&cH7&tES-NV3Z<~NQ*hUA$#Jkdo2peVQEQ;sFTs%)xI>UC^QW{ zEi$~Y!GUpc7Z)s8&Vxze8N5-OZP=QkkLc}b1cH^H8#b&iqwt~Vrxs6`YWG?Fhz*>Ee3i1Y^NJsON!|y=S8PJuZqsAE zX4BHrs*GA1ITvtwWvS+hKJ ziXR`QSY@RK$mKu1{Fcn`6nIpwqB=I(0Z8%9S+|s}trsgRE5h$fN*ueo|4nI>CrIU-3Saf---Eoud^0<nV{^K6LONrm>l-@^hf`_MHuPNN#MVHD?ohI;w?>8Zy^i#?tPBO3Q}*}Kb<-ka z+9MrSw%Ei;4OHXfL&8YIX?86g416alr5aDn+1t{8Fv@gw+1uKd)RcsF=B{QX=u+}g z1;HA_`Qj-n0~TD-#|gvb{gHeK59cOUQ>F3;f7aBr)Q!D*EBAzBWQ2Qk4BFhm!q(yN z)PdC*H+R_bSF${0{w-wgkxEKQhO`*g9QE2on^gc_uXn$T6;ijL;R;0{Y~V*RQkN`9Bf$f;o35DH|N_1PH&l?x}^rFHYfd_!GfU<7HQaWCoV1NaAFD?0~QX*I&w z%oW>T_qCM=J}j3gC{Lqfpc(5;PVwi$e-m+e%3HH!CGDOgj@v=6ogt@|x}KJaon7Qs zvNkw5t7~YIz5vLzqKJsWZ9hmMqLHH^1KC;B#f9^)me%hnTSuo7_tokh{oWo!3x}vH zFVuSh0bun!Kl9h5xmZHQC11wkF~iuM_IIb0K5y25kdlE6PuJT-)VK< zond}c!p+aO!jY4Nv-Uu4tZZ+Ol6l1exXl`tsH^Mfwk^B7QC1Qa^Agz1&)=#Ph{eR- zn>y%^F{>!8Df`fk$S5dCzVy3ueC(2#no5cB)M3Bnp?r#@ znTy8e!!_p{bg{8n3-@Vzbl6{EJMLmv&#?Wn_F93bK~k# znInIuru=Xsq5Lvn$pPHJBxO~V(yFSaUqd0C#@WSrxZyI5OFdggU#rDQ=f{f|;ef;{ z$SFyTBaR_q`JL8cXRE2aqP;dsvF_}AY@OfvgI8qGNF3&{B}Xp?@~%#{Nc2t^IO}Ubj9i^pDacFCU9WPp5vCQB1)W{dcR) z;J{}3tUCy$kcQzycIb~Pkfj6c_ZDK?-p)KYE>5MUPOATfA_jQFi`g+77Hc|GPQifN zx905X>QdL!F)?$EtlFSW^_ag`FbY|dcp!}`E2}Cht9O9?!?iFttv|JP=LEa3hXK*D z>*ternt%D=R6Mm&+kDWUynHxO+Oh}>k!rAn5qmkiQFphIgZF&H`;U@Y8M(QiA!-FQ zHyhi~R^?R9(F#6v`7b)#7O&ew$O-v@R%_7ovbgKpcs@JrtMK+eZ$%7(1C6Y6?oIFAMu)S6#0)rS%{OijH| z%8RY4dKW8$nH2FvvYm?1X#26Bu%d|I?D=TLpm`bWWF&E&uxOCN6r0->fP~Ylj zx%yU4F$f!~0Et$xFE1(n)wP}aIA*XRTFr%6Rcq&3{=j?eYtVTg5 z21}}Vp&}bUdk46E05=;u)yH@8oHtoZ%etT_CM8J>5Ep~?pO4-?U`>pLd$kCg#&2y# zZ4VFQW#cz*bo^&4`kT7&`cr%Yx2CkQR#wNIZONV?fz1ey%Ow(YvO-|;XI!Dbv|k`n z2u=U3NdOY*$VfS`p;=PyoCp=gIBPN#)$j3+aBvj-C@85#w3xFFj*ov3r8O{o7oXAO zS@o2lEj8^me`-T{MUZILw_iU9VFx`pIJn8~3S4u>O&0VD1VdwGT8Q_94`j)Lg#7B}a@y{(h#(LWVa73j`}Q8vLx#e_wYRwROiWP2u`tig$*a7Vq8q79 zYXWyYWF2?rd}Y(wg|G?XQd;*bR5c0Olkka4ii>?Uvof->;wI0Hh0Q$7sBqWl=*Z~k z_-xcL$E|C?*ePSs+`-zKIO?T^rEOb$Li5@AcF=QD7Hewd{s4Si-{nmRS5 zJ#2}|WjDQ&BXo05H4HOp8u}_(0UDz&OIcD{8lA;}g?$$3bL9#i-({9h94r0sE2P`p>Vo$~EPfaTc(5>iY+F1>p3~ zj1zu1QyJ!D71rd}L}iKu&^9nuzmsY790Ox%@!+D;`+(AqSV8lj$=Uo&t)lnd^@D#1 zV3|-24V}ef1mPAZJ}jD$s$rVBd0!ktliWuD6gWfCCGZ2H#&iV2`X@RJYin+G4XxD) zvpywNRX@qXmDQcv{-*s$z*z|XbV(TZ1;4`fAFIvU-5r{spmSrbc1X%Wkpw;&&N97P z)9}ACuRDboT|j9fgGJdk4(tUSeqiV$q{kbGE# z+(K;C7s~=wE4&vst#D{@Gycey^P2ECC4`!nr_*UA^*dSLzCjCkL-~IisWGsYauO%g z#;`9g2$TQvCG)x`@0Tcn4Im(omJ^6PgJ+4pR%M5((>KE5cyHSyuYg(#4Jlqt^|ZSF z<^iy-G#`t?Txm(Mef(7fx{Lg47x&q=z%Uefv<8tS#A237)6_Tron9hF4dyPr(`$9h`>f z7)VlI+8<3mIX*d|VWI<4L11DfkLH&oV6e6ZNL-jWqao9H{ zW1{NMlj_?IITaxSV8;1&(WisAVaYu_0?uThTsQ!uL3=x6jOuB57-8qVTGD#OWwDT> zJxZFk=H>(&8HjdWTux38|Cp4NvUc`$onxD+URJQCj@tWl+57Nb$NdY0<>VM(5=07J z2P0B+XuG;Py1T^+RmnopA|!ddHc%!}2n4354^dGdSqv^r$zCh`pygQjGh+2|3LlK2 zkbo!wmGksZGQQswGX7T!kXKmPy6C_L>A~F&YRb&p{xiaFpzs)8OS5{0v{*IVUn=*!#O+e1X1QT`wq>kR++qXG6Ie#v%k`cTRPl)nuG;b-d2op!k{r+7t zPvH*~YOe13zcf)Ioo8;BPj0a7H|wqx<5$_HUOREx9A!x6 zLuflw6+n#4&dEgw|2L8YLyIw&N>0od>II3Ohw~RO_(5L*h_LL<0R#Co z-cD5S(@ZHD9sULC?;k^Hs-OtyD{GkCX;L|f?WZRv5}Gd zm1E=f`&@n4a4#n(4NYC*|8m*dZ!JmprSPOoQbEt>x`~_f7ESe48Vfp2I|)~R+caOT z_T?cPB<@WpS|PDCe{eBW^7IZglxkJjK7SN+*1JwIb=Hq$Kk?#Y3g*-TgpVo`JzLv(3o$L)XB@>uy53|FkVtzv-f_9?`+8Zeue| z9>*nQSdG2+pgL1lC8^=?Y&Fdz6(S91Tuu2D-jGJ)1(;QbhsV)i2RJ$DHs6{6>3Qlm zPB$SL3#4G@mG}h*8sr7V(U2lu@QTaX*x=n_OOpL(m0MUS_d~a`smds(CfPdGYnx|d zV*_`Mh#WoqQ%Z`zm0bcDg%z(l#@KadX8*!U_#eWHXQs)R zsFEPX|03zBxHzm*)HF1i6&IXbwo}HltC^L>sb+mb|4y)JI<5@J7$)&i8jW? zpC{f{4p_1;EiIEEGjnqbi`j6rQeqAKn-dOoPjOqQ zJbdrE$D=?`=AYUAnmDHO>~KLsb!-gMfDQ3x&7bb*qd)v-1dzdn^Vhu`4)i-an+TjE|_Cwdisav{k zx^2QNHN7s~H#Jq4laq_+LN`%alAq*X{WE-%YkXol>qqt%uKFW}h&2AbhF$ybNcwl6 zbUM@bwAS?;>Pz(})%9ZT?)MT$`5+j>OZuWnjj4UMOwmS}^YgPT?0LhZT>Oavfcl(9A{Lw>#bAKD^Guktm3W= zjCgG9v$ZBEw;EmA?pN-MNp|3P)!eg14-l}vzGjHy?U(~#>z&|^k zM0``baKAVq;nN^Vh)GHcQp#Fb3E%8tpf?=Y%q=V=!3y^!7W}2F6!M|#`=jsQzgIft zB+#k-SU5V%Eh=2TEbad@Ff9IhRtNpzvk-9^=AZp*YsiluhZ&oh?&Hs%Jq?hMpk88a zit4B*@rsRAj2V>m(IfJ5y@1R*U@euglsO}M<rlnPLGk-sM!+>Xii3w|Xy%%bnPLO0H5~lx_hQ1hU0pgVmiO9{?BHP6 zx;vnN_Y7)pP-tak_XHS#`(`0m@hY~0vU1DRA6C7K$uZ_HJ(n9zK`4`iY)UcSKZn-Jz%FL`G82CxBJ{?{mGJ~QJ?H89QI1-pfr*(Wb$*>acF9|1Ip!t z_=m$|ss}#TdN-(ES6A?BidUeMc!~6IBrcAfgEQOOE$T6mSJOeiKv?JDx9kW~^t=yW zHY_2@jD~bOY@#L7=iDiRNFa2=I-|NeD1Xd$7u)9;s_=roV2^u!a$Q zwyHHPpk3=7b2Hz6ja1z$&y7wwWNF}O82zJ9p8tZ-`*J7^8d!V6nD~Q~@}QO)U4K=5 z)8bL@nKpZc*vTBRe1_y($Up^zdab496=)=9`SKCc%A#s&064vu#DJRFD6C;Y137L8 zE69}|vXwert`prT{+U&wao~PYb2Bf+@3D>2pUf8~%a{Xhnnah2LU0~h065KPFI(cRRjhqmFyTT9}CP zB+_%e4%}HFZL{xDeii4ZD*jUURIu?1%6r!l6so?Weqq`?KUc1% zD|`0+!9C$Sz~TbaUPUrdfCwZR7?^gsC4jfF38oX!JOP%MZU^CZ`mA_+@4PM#S9gl5wuRBQ z9~8Y?C&B?B^yO=6Mp{ywN9js*XIouIRHpbny}eEcs$6hWxu}_#q+p>`_|!jp(=7DI zwIVH}sp+l{7Y|48WZV6l?ebYFCawf?c1eihbkk5PwM9hgQtGa~A;${GGuy}qrL9fd zKf;8&C^crsiSa_B6B2@;PEQ#_@)9Xl252QuVj6>cQ_kZ0Y02Jj62$Q; zfihWbUo1>KJi?x|V?}|}R-T2+uascJKkI${y^Ya{^apc$TQNy70NycmbxnZVWubv9 z+LivC$dMnU%+1XwzfU`<3JQKe85z#c)^>b~v>2W53~%nyiV`}*?CvbnELJb1XJBOI z5{m5KF>|p^J@LL~WAr?|9rzKY0E=$$<%dRJV1yBYfMG>fkrQcA=q*9>pf2h*E>nXq5KB)QQI zx+{B6$8q@62Sa6PP1a_R!JsdU1H2f;4HTbUqI>w@0 zpBX3GqUm`I_#Og1$lqTq_+gY^Mh3>F1Ua<%@bPs6tbj4$!WRu0&OjQF$;TzcTUsgn zd+JYOSj=rjM`u248Ii&*Vo;YNOnlbs-`xD5OPn<7YevQ+MU2Fx6qDIa$gdTblr+_~ z%c-hj?H6gbZ>Rr#l}hY0=$6c%6b_}nrlva{jQ?D_vzARDcL;#O&%N30qi1vi*Vk|T z-p{TY+1sNfv^V$tc%0TBq)Z7R1IaU_4Sf7y$$wy=lF|~0G$v+esa`w<{cY=WkIi6d zF>6Q1=t6`I41mo|EAW4Zyd(xIE>J&(i5pJGxvLqmK|u!DiWm6!>ZK)+$o7HLVktCW$LZ)TEnXjAnmH9O`8INhvU7Erqh0Cz(1%!9)#d30A!^v;$ETOK{Tj*b z@gCiWa=&mEWG^Y+c$%4+?VWo9$9MbqMY zslt|xum1gKw9fL0XyW}2WDi>|NHcV|`)MRdXo6?-jmUU9!hnm%A)oVH1PzX&(#L0q7{vB#y9VFTA5utw>t_7?(e@A&SAm2VC?7etN%7*T zQGd5s(GVb}Kgwif{LEbwMsHf>s0)56CPsi49v`yj0Fh`&n_p7rip6SY15YW`pGpjuP%Bagj{gb60xTepg;hT3Yfy zbZeVHPx6xD4h+ulqqpcG+`K8<&-f_t!X2S9F3jA~v`;&8WpI>?*{}+=!#LCOtb>4Pgwj;|IfLm7iO zM$eyH^KvpL_Qu9zWQ}SXTMac%Y42-K!wR;uN37Q2gRs1HlYrxQ3#Kfv2Y>DymDEKBIZEJG8|?rCou52$920udV2N3g|NmWM7co3Lxz>{pEv={yqoxG$qq#CIYbh%f4$NG<35%F2eFQJ( z?t1Ud^oO(>K?!=v@m^mcgY3JzXPo#R9*h~q)b}JL)EP`&PF%p1uNuw&ymQ|Yt1cHFvPxzG+8?Gh;Uip`mY|863RPV?P<;+P4>L{#YHd%!+2F=-x zO*P*fxA}in)se$giHkF5w^XLZgis6?Ds;V1BP7}0W5eo^l9`f)s)|ZVqS>uY*Vo=M z?edvQR-fpW!0H?F)kq?uy1I;X`S}k_!vTx3V!8^Camm;$b1;_$4<(u30nB2rY#?oY z0bqCj3n!PS6{?EGkA(KGwi6)>4szXM zPV9jcxdA&KOl5dC&e1zOd_0Bxkq#49c(wue0zO7WQu#~hu|mdD1PwGfTOPF_9`Ysr zI%r-wJuOE5qOEvdzkfOVcP?_FY79~Us2>F#K8i1dm0BAs(Y%FHgNX^qI0iP~Lbv`3 zcD%aYEaXL#&Z{)f9|YQaM6)t8bGM{+%UMXTKlj}z`Ga1!H<=IarzFumw|=S917&kz zZ``*^$!$rGGtauBasC;UK#Mi$^UM`LTY%>!kdOpgsfAsaoo$O&ZQSEGOvP3TU#Yy-?&pc5_*e#;bCl^q=Ftw&sBH$IZ7c`hcWQwydE^?r+gNs-L!^`)taG**V9*bU`2N#1bX z!WD(zdzRJ(Fc(LCzyC7!CAlAj4LL(u>dJQ@&JbokR5%z=?;?4g`un>L!lrZoo~2wB zqhp|a&|ic+AN0PUKa>I=i4LW5%Arp%%EnBH<7D>EE|J9MosHh4^ODiXZ@{5EK@ zArpu9WxDp8CUIgnLH^*2KxXVp9{6C~{vq2*f~h{q{*X2r+>67c#bb(RDQcvF;pfrau!S5?US)Qi7gB$b^HBy9`zK-`d+!?+rxIcF!-htDGOE&Ax^@1c()Y z?FllUN}%_8Fk<6{2a1!X-v5_AUqwZK8UVmo9F)MjxN8x;3=nb90EyFl0L*{~&C93o z@nksV#!SB|(E#OqefBYI_e3G$umW6}#p%f08GM8!;@4fC@H97&Op$cnUXv2Tkq4Tp zUs8*czmPB5^%BTa&41&eL7e&$_=H1=G#Q^?7E8bJ72Z>PcD7pcmi)_b+=)oU#T$1$ zrX^z&rwv)9*Rw?g^fBFo-_9T3f+Pd00EdKwgETr$XBW9xj*+J`QpH%1WT6OS!r=I@ ztjgP7vU4rcD1COE=+!?7vDeTtA2#8qObdmaESoxj@WEw7vkq_EO|i>UZW_##qM<7i zE>w*9ZO4R%@>}PJR6~zCePDOYWIJ+;;oee3_HnstCIuQ4#FN$8CF##w-$`T+&bd?* z4ywVKlg{7T6!i~51bfl-Jfp+ z?H!Gyd&%Ba^E(o(NHR+FHD_KJ;F>8O>@B- z&G?Fp_}i@?KKYHy#+?uBx=_(2o<({HP3(vkd3;4RbbuWP)Wa=?#pL6;pN1yh2Ct0% z3i9jf+zgjoGO3$$9Gj{JPnZ;W&G~$oE#@8FM4C+WuXdPiL6L;% zwWVZNT8Zp=^}~1!x@k;tI_Oj{BEB7&iPog)kbko#q7h7sG-v;E*pL2@lQX4&?-w9- zI*c8ml*&|h>G-HjrtZx?{p>$EdDXAJfD<3-S6X~UHOF|x>an%c0^2i)#ZiRq^>Nxv z>*mq^(U>mDtnCARyM76fon$EqiqthDp{by2UU~KRlfrjJGiqpj$nS4SzmKJs8MX8%;O^vRGisOS=aG)+ zmz7`XNlaurAQOsq;+Ibzk0*U?EFD2ELn`tK1)~g?LkHQzp{w9KUH9NyFRAgz za$(OyB%yUdKAb9=eBK`7suycjzF1sbsB9G!JaQ2ZnwNvTjfqjk%_1$bD?fI4ZdR6; zZKXT%EgT%3N?p1C0;v2><|_*O}D(@=%JD`%lX^J1d)c zqRU!4$L&kL%X*)4A_ud|Jyo@X{RuVwhQA?}4 zr3I;pezlnqxfGYEI^U9yTHu z>PO#A9a=(R@lg1+D;MCANn@E?C?6vE^I@-j4*P-H?ExvzirU0883i?PPaX-Lcq z9!K)|CE*xZZy+!F^Er^JlPM6Dh<|dvbEc(YsT&x%rtj zHGXH6JpYHOuMCK4UE4-cECdBakWy)+K{`aGOQfV5q@^2FN?Jg=q?M5F?#`iW=x(Iz zyV?7k_k4f!$IL9&de#$nT%mC0YH68|ZTglCi7iSKp7xyNu6Hrs5d!}dUa1-pk-f1I zhy4*_K|w)U$#1RP!u)n_{!30Ux`EQ?cfjmJi}bh)d4_gXjzwVPJQn@>iOPS5t@tmd zynOBly5({K4lL1^J@eX}O5P!4yn{(f;bgOUrG~A+^K{MODbFZC;!K7=v5)hijF_0t ze82U5I${IJ@oJ7Q4k0E|xq&q?Qd{m#=}jg&j*H*cWEESQmPi2l^kBJHT*w*I6@B|o z7$aF3^Y84;2BW+OchNW<=Wn~9q9**dFRqa&cXGOd%R`-WH=h|0kM;{;3=hU`Gv`tt z?}S^_jwt5@f4p%@@#c?KWK4`g=Ah~~6HMcx@lsQ~#Scc2e$8FylnpZ|ch1(n3^+fd zWJ?bwlM}2nE74g_3l>9k?bMqUq)sj6j?3V14n8LByA8UvRyj4@%ge3F=07Cd{gE|Z zlSa^-^oIgL{)8D1F=l|IB#+bVjf@P-i!+C><2-F-cPP?bXyf>M7Q`c{=;_n`cqF1> z{1*%GC;t2v=Io~thtrJ`AHif15f$7+sMHI}e=~kE)7Y%d^=7xqi5F0dh~CKC9XBU7 zmuvO&9{33Pw9KkB6Oth`ji0>J8L!tB`R)1M2z6@2rO#7Kvt(4(-6JWIz|3-%n^jWW zgF&X)Ifk}lWZjnK&UD(&=+P14c#fh^%`IO!n~=}a!^r$TJG}3LIr<&@SOW~g>CVvt z>L`zfhbO1R?-dn=^#sXp-W2@hTVFM$zOLXm+CBRu&Teaa<`&6%`VPAc`_kb8>CvalmWqu+jXStPWoUfh*@TF&h_Qh=UC`noZ3}K6(^X|B?pI;X?^bv zD0aNwksq5eKG{y}*Yustp(9qmKsj&Rl$MsxYPZosSsB#Djy^*Z^kIMy$kv@*Ks8>Y zw81-VZCRP8NZ`krs#1tR2-II1XY+pW#i8$gXARfak7V*=4_Cx86&ZWqoc-(xIsl@N zmXrN}ND%=D93vy6kH|yxoaz%nn5j{IT7LApPs|@FjgB5Zx=HuvVPItUz2sG|F;OTZq3!rVS$!%In}R)% zbmsOX5fLC97G!wIPmr_y`AXq$FGUV0l|sPM2rw+=+*_7=&0TV86!%x5saUEO6+|>K z8y(MlVeabHWz=L=0PV~^n>Y{wn{wPE48;x&@~_Tc@hB+OHG49-v7VAslK{9ZU2qfujJFP!Wb9FdM>kqjw*@B`#`HQTOAW~GpJ7% zjBLon81W?VMbs>EfqWe0Lksz@*Jn|$Ox5Y??B;Z-l%-^=TvrYC(Zl3s%fy0$@ zv+hwgf`dk`7sSKG%hw4K11Oa{yc&Xugj{0=qd#GJV)fA$4}A7IJ> znld-PydAW7`HxrDfC{wNbGe)_Yt8lXR}S!1Jm5&q&!51-jba)||Dy&jr(b|3a^bS^ zA-;C{57k`|{{HydZDIn0Rnlp|yiq`>j^XyqYsw=zn7}YIpkzoErV z1}WB;qRZuhX@*o8Vp39phO9*&01?3Uc-VCcoGp zIs1v3n$kIxIo!cS^%3cuAZxWQ0|~{}da<_kQiS^M#}zAViJO;UK@b!=27tQ?(SK(b$34_ybD^Jr+Kfh8J3$-q*-$8 zNJ{q&o_-$nys1k6SmaJ}2R5Ivt%VPCYP4jY9XphXgm}DQaUVN5;SCe>%jlh)bRRTo zf=((AG3EE$r-0yp>!3#ttGl!F=$)=7#3XEAuYq8GYCM*R{ez*wNMVe03QAc5oRva4 z(U8c5n1%jSKh+x7u&-y=1BrRX%mN*FinCLrW|LmyhKDb&Y=A1ql!5NY2X+ct+)s!YW4ggz52chA%=Zp6d6WLUL=n0%`Kj$G$iz zGvDV0m6aZVGvTJZCH^|9yQ?iRDe0@`)7JXg{!n9Xv~mAS>0UF|IN%r~KB7Sdl6fWO z8DT)$k8?G412V+B;E04ELHS@kd;=l03?rrna}QE*8l2dqt(=M;sAmUw6EMxbetA0c z>4v<#p^?c?V7r1%2LgeR)U$cXQ2mLks5O7w1ZRF>Gvn7?;s7Q+V$809wBZ#1ohq77 zfb#+Ws}OP;n#}lLroVhmDC`SAe5#o63DAy$2s0L63KtjmeGGZU%chhWr4T)~*Py$D zLJm-z`6cobd0dU7`WKad`^8Ju=!ec+nOW3y$$7fLe-(~tXi-v7P~J8%d4PTc#4rK5 z7C9`!ys?ozvaY{O-N3kgtlv9pL6bqVlatNFw4r0`dQHA4BrL4UvEF`ksQ*x>{IV6O;k2 zV^dNF-YdZ!#Fu`m@f=@xvR__bUS2e5oT&CZLiuC9S1f6}2ANk&qBVW9{aRMdb?!x>7pXPosgh=G3t`Zxsww@0ZP?LghgDy)cvt$la$+)1vbFZz5 ziHYtB;_|@ZwI*OS^RS8_ryuP3i9?9M%*-PDOd;Ny=Yz6pqfyapd*|B_GG><8D{8eh z$KiwYy4n8c_)$^1WolHuul0q{Cq z@%+pXJK`g0N$9sQg*2r)3>!HwYY1j1E=`Nfd= zPQN%q0Tv_gTT@$Z`iOgXK5-Ea3=O5l-jfqdZC*=Fto|}6&tHW}47r2~`rpGDO9L4t zr7|5-4&33$*x0u+k5*SnJPCgNp`v79NZ8+h+1%XXCK>8RfD`d!nwnlJTL93;aK!qw z`4H`iB^f&d2`LlhkMJM8WBp>Z#0DRAfA~e@^g87b zfZak#Ge~ez5(eyy9orojT%JXMQ_T!Db>dTg%!D3c+8Mk@elh739X#arnVAU_9M1u- zW>Ap7x+I|CW;ADGY3WN+b$|`L!zhgpn)f<{h6 zyKp{OmbPaktgq8Tox7=t+~*)Es#&+f&|2ezssyLb#>mg253LNXElYdQ=YkCPBdeH( z8-LDu<3uC89k3Gz!;Y?U=~&lzaeLG8bvFB1KGS&JzL&hF7{5{~Odq`xiNUN{aOFEh6fzSwYd+-6UrIT_|qYL+VHg5ECA&2U2 zW@e_x>%_vn&sun3m(I-19+Y*Jg7-~KG%8k~k*B%vEiOKOCm*&ROY2-v@OR4Xd+YcT z1$z%V(EyVFGb~-QzomsqAt3~qi-h5!p?*E=;!rOcwt?REAqn5Sx$BWmc!XlSeKIiN zzzj_A8-CrCvG}v=b?J4@&1l$ja{x!$JzD|30{!g%&@?q2`GXJaRTQiN;C*9pa{QRn zdS0a69h4|MSB)5EfYIlKNt`wtBNiEt=jSJW!~L3=7!Tn@4YE^PO~c&L9|f4hS;t^m zlPQ8l$YK9kvsX1Y!d{HsL582pGV%$>ORH(?vWazLQ!QYv7QNE!AS3Z>0m%}IbYP7n z3kQWHBnYdk^O>F=F!6DTebRBy%aZ|o8>h>O18s&FKvcJ9NSC9VdtdRt$aG~U42(lt zw8j>!ce39r>Zb@QO00VpNX*?G#bN*r3{Vt#|3OaIYgNSF0-Ri+QVNl;WNWiIePEVC zQeW%PsLEK{H=tvPV?nt7v0Uh?QGK{YS@`fdC3i&hDh*KdAVCMI5Da3DR~l|^&pW>; zxlS_TktAq>sTQel&_lnbk&)Z)WmSapTHYYtPXX>Bqfo5a8~L}UHKY^xd3_=tSV7)% z!Wdd5C_&VKv+GBitPEcdBwz<;K&Q?N&xf)aCZa<7HzNZU_&&^ z@{(!iqXk*2MlGduh^qY|Di3)o*f}xtvkTivV=}mGT4{p53cHeqMnhbfpsUt1ApQYn zfBgtUG-P>YRT~Kv=d(tukqr#1ovDGhLi!X$c3av7%8~I0dFA=90f@m6>l(PfZv$`T zJ=0|^>uOeZHc%PrelJNeax&E|A2s5Vi^$_ZVO><#>K@b$1;feNz7p6Q8(VP2f*ss( zA4Rv>xi*6NJI}=jZ1yuWV{N*gP7i7d}!vcjelgShUJ<{-VkF%AiFJr%5#y10BOc z(<~g$@a|ZLhseLIHZnT)XIgRi612P;k2qi_pI>DxJfb}vr1C|);b`}dGN9(`Cvd=|&(Vi&E9j4H4#g$x3wENv&lcQ{6@-thW$yr@ti37OGj4VbCB24ri8 znWo2h%Op?P*&~|M7U{G)i<8&T4$CVX_Wd+wn^+7Sj<&B|L0mZOzXN^2*=i5A+t0tT zi6&~qWMm#LEG&S0!S3!oh#^2NFumjYUy;!f1W%ETS$uSCJp{h81*19V#>T8{FK0e+ zfia1ut5)BDzzOmDjeX16Mp1w-{mL}|S(p{u7yQs9zw>N@P<~JyY@A^yoL^j=>24Qu z*yAR`xJq%qkCqsWS)%5zRF{?s+PX1*J=`G>YAO z_f|I7HBH)uWwZp6h_>Xa`7+b&8&D#~1!cwWu~iVIBkHPMPCtBzG%&JUmHF^X64mp0 z$6rhg7EVr47aeSadaY(5p-;LToVM$uKP+gXDmluyAT5hO#T;?lep+N><9uP2pkr@; z8#0@gpaif~+SRB&-*}t9)z#qhC4(!`g^Djmnk8a^Nq{ZyTKwqe0=UGj~`lW_i8=wqcXmD znNg+A5(Ttx)pBP~myHcVeut32zzX0EqP|mB7UCe(x72=Kl$X51W$tDT=_CK;Uy{op zh_{YM%l1kOCVu?*5gDHkZlBc$Y=|=QGJ%hHPEQ7OmC{m5zZo19S?sUAw6wC!Rmz^I zbn%7?fr%}Pv$U1~A8`sX8{p}9R9B#F&ko0~&{nv^T9}jOjE}^EQpeK5U_2d@X@$#%-_0E2d#dhsQ zp){Yv?2R{X8l0_H?)I!38|aWWa`V@GPEU!P$TFezZGXX#a3z*7oAmtd?jAlqkskQb z<~SdVFH%sf8@)oFv8N*h$guQuO>pGpJMW7(j6BDNkc^gAQ$yt*@ByDQFhqd!v7-|S zXnM3EFDH?88&?*=vZC>!%>DbqdQ>#Dv$Yp4s@0B(!)u;``dI5<>IBfdy{Kqfkp_=^DOUH9=J3R-TFGFWKfBtFi7&+pYo5O}Pev{w%TNV}cOaK|u3bQCo92Uv4nd%&-NIO3+P7L-S=~%5E=H?y3$OxdQsBAo+t`5fAO;aftzFF_ zYKHk#%AY@heR(o)XR_%Z$V6w40HZ#M=m0VlXp{3_6xqgNC$x>bpP!0g*)!DZ{DERX@39RCi-2|-afJ^703t_ zZPr}BvNDpgtK!PJ5TQr?O@7uk$T!0_me`5cAj5})_MwkZZpK}5s3OqO4GawA7Z*1- z1@Wa+R>u0ai?Oj?hk*ARt$?2VBlvuNX^Dk{<1^Uu9XSIw`g_z$N?u;@%*?YiXFhZ_ zO70gipz$OoCI+dTSW}Oy?sV7{d62S0Qobkx81Z-S`N1dC!u%IZc^}Y`owPe2J$!w| z#>TE9v)2l`^y+8dRP4BVZHUqv1Y~8g=X7-Z1EhbhpkY)5K$n1wj0>B|B!++hg7L&U zfyKw29M=0b`*2h;^0IU^3q80467w_=a)7ppuH%^Zq&_Jj2BL3JkONC7sD+A}9tZ?J zZ~%c=MN~pe6F8KfpWHWLdm$h82*vtvg7iti^NzcqPWHo*2XKy%*-AjeEP_G(tzXN| zkFfXe-qnT~v$uA1C4vgYSUJ~U`&h$-pz>(t=9U(G0(R`&z@UKHeFenWn2?qDi$4;N zF-aztiW1InP~B-uVt|>Ai@WGB!vFnUBbjov%6Bp!i0@MaD^t;!np9H^IEdt&j3GL1 znxjt5%=Cku4oI)RvodtStQk(T=fR96W=Q5BU4nOtb4~hokosR00z*SX?S1`rh6Z{^ zM&3e71h`*P28JLYiU|p~^kXuk0b%5woT|iD74as&{VNVaf!FCEBy_n-v(#M^#%zWj z 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≫ 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

      FpY4bJe-pwE;UW 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

      tFkny$TndMp5Rk4lxvXt5w1uU4t) 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 + + + {{ partial "head/meta" . }} + {{ i18n "error_page_title" }} + + {{ partial "head/favicons" . }} + {{ partial "head/others" . }} + + + + {{ partial "svg-icon-symbols" . }} + + +

      + + + {{ partial "site-header" (dict "Root" . "MenuEnabled" false) }} + + +
      +
      +
      + +
      +
      +
      {{ i18n "error_message_title" }}
      +
      {{ i18n "error_message_code" }}
      +
      + {{ i18n "error_message_text" .Site.BaseURL | safeHTML }} +
      +
      +
      +
      + + {{ partial "site-footer" . }} + +
      + + diff --git a/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-codeblock-mermaid.html b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-codeblock-mermaid.html new file mode 100644 index 000000000..b5deb66b4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-codeblock-mermaid.html @@ -0,0 +1,11 @@ + +{{ if not (.Page.Scratch.Get "mermaid") }} + + + {{ .Page.Scratch.Set "mermaid" true }} +{{ end }} + + +
      +  {{- .Inner -}}
      +
      diff --git a/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-heading.html b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-heading.html new file mode 100644 index 000000000..3e7a270f3 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-heading.html @@ -0,0 +1,27 @@ +{{- $showAnchor := (and (default true .Page.Params.geekdocAnchor) (default true .Page.Site.Params.geekdocAnchor)) -}} + + + +{{- if $showAnchor -}} +
      + + {{ .Text | safeHTML }} + + + + +
      +{{- else -}} +
      + + {{ .Text | safeHTML }} + +
      +{{- end -}} + diff --git a/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-image.html b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-image.html new file mode 100644 index 000000000..99a311367 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-image.html @@ -0,0 +1,6 @@ +{{ .Text }} +{{- /* Drop trailing newlines */ -}} diff --git a/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-link.html b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-link.html new file mode 100644 index 000000000..cec8a9530 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/_markup/render-link.html @@ -0,0 +1,14 @@ +{{- $raw := or (hasPrefix .Text " + {{- .Text | safeHTML -}} + +{{- /* Drop trailing newlines */ -}} diff --git a/docs/themes/hugo-geekdoc/layouts/_default/baseof.html b/docs/themes/hugo-geekdoc/layouts/_default/baseof.html new file mode 100644 index 000000000..ebc39cfcf --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/baseof.html @@ -0,0 +1,60 @@ + + + + {{ partial "head/meta" . }} + + {{- if eq .Kind "home" -}} + {{ .Site.Title }} + {{- else -}} + {{ printf "%s | %s" (partial "utils/title" .) .Site.Title }} + {{- end -}} + + + {{ partial "head/favicons" . }} + {{ partial "head/rel-me" . }} + {{ partial "head/microformats" . }} + {{ partial "head/others" . }} + {{ partial "head/custom" . }} + + + + {{ partial "svg-icon-symbols" . }} + + +
      + + + {{ $navEnabled := default true .Page.Params.geekdocNav }} + {{ partial "site-header" (dict "Root" . "MenuEnabled" $navEnabled) }} + + +
      + {{ if $navEnabled }} + + {{ end }} + + +
      + {{ template "main" . }} + + + +
      +
      + + {{ partial "site-footer" . }} +
      + + {{ partial "foot" . }} + + diff --git a/docs/themes/hugo-geekdoc/layouts/_default/list.html b/docs/themes/hugo-geekdoc/layouts/_default/list.html new file mode 100644 index 000000000..94172f65d --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/list.html @@ -0,0 +1,11 @@ +{{ define "main" }} + {{ partial "page-header" . }} + + +
      +

      {{ partial "utils/title" . }}

      + {{ partial "utils/content" . }} +
      +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/_default/single.html b/docs/themes/hugo-geekdoc/layouts/_default/single.html new file mode 100644 index 000000000..94172f65d --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/single.html @@ -0,0 +1,11 @@ +{{ define "main" }} + {{ partial "page-header" . }} + + +
      +

      {{ partial "utils/title" . }}

      + {{ partial "utils/content" . }} +
      +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/_default/taxonomy.html b/docs/themes/hugo-geekdoc/layouts/_default/taxonomy.html new file mode 100644 index 000000000..bb97e8ed4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/taxonomy.html @@ -0,0 +1,49 @@ +{{ define "main" }} + {{ range .Paginator.Pages }} + + {{ end }} + {{ partial "pagination.html" . }} +{{ end }} + +{{ define "post-tag" }} + +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/_default/terms.html b/docs/themes/hugo-geekdoc/layouts/_default/terms.html new file mode 100644 index 000000000..2316ef56d --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/_default/terms.html @@ -0,0 +1,32 @@ +{{ define "main" }} + {{ range .Paginator.Pages.ByTitle }} + + {{ end }} + {{ partial "pagination.html" . }} +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/foot.html b/docs/themes/hugo-geekdoc/layouts/partials/foot.html new file mode 100644 index 000000000..2a115e562 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/foot.html @@ -0,0 +1,6 @@ +{{ if default true .Site.Params.geekdocSearch }} + + {{- $searchConfigFile := printf "search/%s.config.json" .Language.Lang -}} + {{- $searchConfig := resources.Get "search/config.json" | resources.ExecuteAsTemplate $searchConfigFile . | resources.Minify -}} + {{- $searchConfig.Publish -}} +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/custom.html b/docs/themes/hugo-geekdoc/layouts/partials/head/custom.html new file mode 100644 index 000000000..44862c7b6 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/custom.html @@ -0,0 +1 @@ + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/favicons.html b/docs/themes/hugo-geekdoc/layouts/partials/head/favicons.html new file mode 100644 index 000000000..40a8c91d2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/favicons.html @@ -0,0 +1,13 @@ + + + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/meta.html b/docs/themes/hugo-geekdoc/layouts/partials/head/meta.html new file mode 100644 index 000000000..4cc4ddb44 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/meta.html @@ -0,0 +1,14 @@ + + + + +{{ hugo.Generator }} + +{{ $keywords := default .Site.Params.Keywords .Keywords }} + +{{- with partial "utils/description" . }} + +{{- end }} +{{- with $keywords }} + +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/microformats.html b/docs/themes/hugo-geekdoc/layouts/partials/head/microformats.html new file mode 100644 index 000000000..8b6038ac2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/microformats.html @@ -0,0 +1,3 @@ +{{ partial "microformats/opengraph.html" . }} +{{ partial "microformats/twitter_cards.html" . }} +{{ partial "microformats/schema" . }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/others.html b/docs/themes/hugo-geekdoc/layouts/partials/head/others.html new file mode 100644 index 000000000..537c2ff85 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/others.html @@ -0,0 +1,73 @@ +{{- if default true .Site.Params.geekdocDarkModeToggle }} + +{{- end }} + + + + + + + + + + + + + + + + + +{{- with .OutputFormats.Get "html" }} + {{ printf `` .Permalink .Rel .MediaType.Type | safeHTML }} +{{- end }} + +{{- if (default false $.Site.Params.geekdocOverwriteHTMLBase) }} + +{{- end }} + +{{ printf "" "Made with Geekdoc theme https://github.com/thegeeklab/hugo-geekdoc" | safeHTML }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/head/rel-me.html b/docs/themes/hugo-geekdoc/layouts/partials/head/rel-me.html new file mode 100644 index 000000000..59a346168 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/head/rel-me.html @@ -0,0 +1 @@ + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/language.html b/docs/themes/hugo-geekdoc/layouts/partials/language.html new file mode 100644 index 000000000..fdcafd2b2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/language.html @@ -0,0 +1,51 @@ +{{ if .Site.IsMultiLingual }} + +
        +
      • + {{ range .Site.Languages }} + {{ if eq . $.Site.Language }} + + + {{ .Lang | upper }} + + {{ end }} + {{ end }} + + + +
      • +
      +
      +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/menu-bundle.html b/docs/themes/hugo-geekdoc/layouts/partials/menu-bundle.html new file mode 100644 index 000000000..bb323875b --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/menu-bundle.html @@ -0,0 +1,87 @@ +{{ $current := .current }} +{{ template "menu-file" dict "sect" .source "current" $current "site" $current.Site }} + + + +{{ define "menu-file" }} + {{ $current := .current }} + {{ $site := .site }} + + +
        + {{ range sort (default (seq 0) .sect) "weight" }} + {{ $name := .name }} + {{ if reflect.IsMap .name }} + {{ $name = (index .name $site.Language.Lang) }} + {{ end }} + + +
      • + {{ $ref := default false .ref }} + {{ if $ref }} + {{ $this := $site.GetPage .ref }} + {{ $icon := default false .icon }} + {{ $numberOfPages := (add (len $this.Pages) (len $this.Sections)) }} + {{ $isCurrent := eq $current $this }} + {{ $isAncestor := $this.IsAncestor $current }} + {{ $id := substr (sha1 $this.Permalink) 0 8 }} + {{ $doCollapse := and (isset . "sub") (or $this.Params.geekdocCollapseSection (default false .Site.Params.geekdocCollapseAllSections)) }} + + {{ $anchor := default "" .anchor }} + {{ if $anchor }} + {{ $anchor = printf "#%s" $anchor }} + {{ end }} + + {{ if or .external ($this.RelPermalink) }} + + + {{ end }} + {{ else }} + {{ $name }} + {{ end }} + + {{ with .sub }} + {{ template "menu-file" dict "sect" . "current" $current "site" $site }} + {{ end }} +
      • + {{ end }} +
      +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/menu-extra.html b/docs/themes/hugo-geekdoc/layouts/partials/menu-extra.html new file mode 100644 index 000000000..a1984f8b2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/menu-extra.html @@ -0,0 +1,46 @@ +{{ $current := .current }} +{{ template "menu-extra" dict "sect" .source "current" $current "site" $current.Site "target" .target }} + + + +{{ define "menu-extra" }} + {{ $current := .current }} + {{ $site := .site }} + {{ $target := .target }} + {{ $sect := .sect }} + + {{ range sort (default (seq 0) $sect) "weight" }} + {{ if isset . "ref" }} + {{ $this := $site.GetPage .ref }} + {{ $isCurrent := eq $current $this }} + {{ $icon := default false .icon }} + + {{ $name := .name }} + {{ if reflect.IsMap .name }} + {{ $name = (index .name $site.Language.Lang) }} + {{ end }} + + {{ if not .icon }} + {{ errorf "Missing 'icon' attribute in data file for '%s' menu item '%s'" $target $name }} + {{ end }} + + {{ if eq $target "header" }} + + + + {{ $name }} + + + + + {{ end }} + {{ end }} + {{ end }} +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/menu-filetree.html b/docs/themes/hugo-geekdoc/layouts/partials/menu-filetree.html new file mode 100644 index 000000000..e51a5de0c --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/menu-filetree.html @@ -0,0 +1,98 @@ +{{ $current := . }} +{{ template "tree-nav" dict "sect" .Site.Home.Sections "current" $current }} + + + +{{ define "tree-nav" }} + {{ $current := .current }} + + +
        + {{ $sortBy := (default "title" .current.Site.Params.geekdocFileTreeSortBy | lower) }} + {{ range .sect.GroupBy "Weight" }} + {{ $rangeBy := .ByTitle }} + + {{ if eq $sortBy "title" }} + {{ $rangeBy = .ByTitle }} + {{ else if eq $sortBy "linktitle" }} + {{ $rangeBy = .ByLinkTitle }} + {{ else if eq $sortBy "date" }} + {{ $rangeBy = .ByDate }} + {{ else if eq $sortBy "publishdate" }} + {{ $rangeBy = .ByPublishDate }} + {{ else if eq $sortBy "expirydate" }} + {{ $rangeBy = .ByExpiryDate }} + {{ else if eq $sortBy "lastmod" }} + {{ $rangeBy = .ByLastmod }} + {{ else if eq $sortBy "title_reverse" }} + {{ $rangeBy = .ByTitle.Reverse }} + {{ else if eq $sortBy "linktitle_reverse" }} + {{ $rangeBy = .ByLinkTitle.Reverse }} + {{ else if eq $sortBy "date_reverse" }} + {{ $rangeBy = .ByDate.Reverse }} + {{ else if eq $sortBy "publishdate_reverse" }} + {{ $rangeBy = .ByPublishDate.Reverse }} + {{ else if eq $sortBy "expirydate_reverse" }} + {{ $rangeBy = .ByExpiryDate.Reverse }} + {{ else if eq $sortBy "lastmod_reverse" }} + {{ $rangeBy = .ByLastmod.Reverse }} + {{ end }} + + {{ range $rangeBy }} + {{ if not .Params.geekdocHidden }} + {{ $numberOfPages := (add (len .Pages) (len .Sections)) }} + {{ $isParent := and (ne $numberOfPages 0) (not .Params.geekdocFlatSection) }} + {{ $isCurrent := eq $current . }} + {{ $isAncestor := .IsAncestor $current }} + {{ $id := substr (sha1 .Permalink) 0 8 }} + {{ $doCollapse := and $isParent (or .Params.geekdocCollapseSection (default false .Site.Params.geekdocCollapseAllSections)) }} + + +
      • + + + + {{ if $isParent }} + {{ template "tree-nav" dict "sect" .Pages "current" $current }} + {{ end }} +
      • + {{ end }} + {{ end }} + {{ end }} +
      +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/menu-nextprev.html b/docs/themes/hugo-geekdoc/layouts/partials/menu-nextprev.html new file mode 100644 index 000000000..6126f9517 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/menu-nextprev.html @@ -0,0 +1,78 @@ +{{ $current := . }} +{{ $site := .Site }} +{{ $current.Scratch.Set "prev" false }} +{{ $current.Scratch.Set "getNext" false }} + +{{ $current.Scratch.Set "nextPage" false }} +{{ $current.Scratch.Set "prevPage" false }} + +{{ template "menu_nextprev" dict "sect" $.Site.Data.menu.main.main "current" $current "site" $site }} + +{{ define "menu_nextprev" }} + {{ $current := .current }} + {{ $site := .site }} + + {{ range sort (default (seq 0) .sect) "weight" }} + {{ $current.Scratch.Set "current" $current }} + {{ $current.Scratch.Set "site" $site }} + + {{ $ref := default false .ref }} + {{ if $ref }} + {{ $site := $current.Scratch.Get "site" }} + {{ $this := $site.GetPage .ref }} + {{ $current := $current.Scratch.Get "current" }} + + {{ if reflect.IsMap .name }} + {{ $current.Scratch.Set "refName" (index .name $site.Language.Lang) }} + {{ else }} + {{ $current.Scratch.Set "refName" .name }} + {{ end }} + {{ $name := $current.Scratch.Get "refName" }} + + {{ if $current.Scratch.Get "getNext" }} + {{ $current.Scratch.Set "nextPage" (dict "name" $name "this" $this) }} + {{ $current.Scratch.Set "getNext" false }} + {{ end }} + + {{ if eq $current $this }} + {{ $current.Scratch.Set "prevPage" ($current.Scratch.Get "prev") }} + {{ $current.Scratch.Set "getNext" true }} + {{ end }} + + {{ $current.Scratch.Set "prev" (dict "name" $name "this" $this) }} + {{ end }} + + {{ $sub := default false .sub }} + {{ if $sub }} + {{ template "menu_nextprev" dict "sect" $sub "current" ($current.Scratch.Get "current") "site" ($current.Scratch.Get "site") }} + {{ end }} + {{ end }} +{{ end }} + +{{ $showPrevNext := (and (default true .Site.Params.geekdocNextPrev) .Site.Params.geekdocMenuBundle) }} +{{ if $showPrevNext }} + + {{ with ($current.Scratch.Get "prevPage") }} + + gdoc_arrow_left_alt + {{ .name }} + + {{ end }} + + + {{ with ($current.Scratch.Get "nextPage") }} + + {{ .name }} + gdoc_arrow_right_alt + + {{ end }} + +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/menu.html b/docs/themes/hugo-geekdoc/layouts/partials/menu.html new file mode 100644 index 000000000..7963eacdc --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/menu.html @@ -0,0 +1,44 @@ + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/microformats/opengraph.html b/docs/themes/hugo-geekdoc/layouts/partials/microformats/opengraph.html new file mode 100644 index 000000000..97716ca9e --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/microformats/opengraph.html @@ -0,0 +1,68 @@ +{{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} + +{{- if ne .Kind "home" }} + +{{- end }} +{{- with .Site.Title }} + +{{- end }} +{{- with partial "utils/featured" . }} + +{{- end }} +{{- with partial "utils/description" . }} + +{{- end }} + + +{{- with .Params.audio }} + +{{- end }} +{{- with .Params.locale }} + +{{- end }} +{{- with .Params.videos }} + {{- range . }} + + {{- end }} +{{- end }} + +{{- /* If it is part of a series, link to related articles */}} +{{- if .Site.Taxonomies.series }} + {{- $permalink := .Permalink -}} + {{- $siteSeries := .Site.Taxonomies.series -}} + {{- with .Params.series }} + {{- range $name := . }} + {{- $series := index $siteSeries ($name | urlize) }} + {{- range $page := first 6 $series.Pages }} + {{- if ne $page.Permalink $permalink }} + + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{ if $isPage -}} + {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}} + + {{- with .PublishDate }} + + {{- end }} + {{- with .Lastmod }} + + {{- end }} +{{- end }} + +{{- /* Facebook Page Admin ID for Domain Insights */}} +{{- with .Site.Social.facebook_admin }} + +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/microformats/schema.html b/docs/themes/hugo-geekdoc/layouts/partials/microformats/schema.html new file mode 100644 index 000000000..e4a71eb4e --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/microformats/schema.html @@ -0,0 +1,70 @@ +{{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} +{{- if eq .Kind "home" }} + +{{- else if $isPage }} + +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/microformats/twitter_cards.html b/docs/themes/hugo-geekdoc/layouts/partials/microformats/twitter_cards.html new file mode 100644 index 000000000..a2cc08c45 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/microformats/twitter_cards.html @@ -0,0 +1,15 @@ +{{- with partial "utils/featured" . }} + +{{- else }} + +{{- end }} + +{{- with partial "utils/featured" . }} + +{{- end }} +{{- with partial "utils/description" . }} + +{{- end }} +{{- with .Site.Social.twitter -}} + +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/page-header.html b/docs/themes/hugo-geekdoc/layouts/partials/page-header.html new file mode 100644 index 000000000..8f146d7e9 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/page-header.html @@ -0,0 +1,57 @@ +{{ $geekdocRepo := default (default false .Site.Params.geekdocRepo) .Page.Params.geekdocRepo }} +{{ $geekdocEditPath := default (default false .Site.Params.geekdocEditPath) .Page.Params.geekdocEditPath }} +{{ if .File }} + {{ $.Scratch.Set "geekdocFilePath" (default (strings.TrimPrefix hugo.WorkingDir .File.Filename) .Page.Params.geekdocFilePath) }} +{{ else }} + {{ $.Scratch.Set "geekdocFilePath" false }} +{{ end }} + +{{ define "breadcrumb" }} + {{ $parent := .page.Parent }} + {{ if $parent }} + {{ $name := (partial "utils/title" $parent) }} + {{ $position := (sub .position 1) }} + {{ $value := (printf "
    • %s
    • /
    • %s" $parent.RelPermalink $parent.RelPermalink $name $position .value) }} + {{ template "breadcrumb" dict "page" $parent "value" $value "position" $position }} + {{ else }} + {{ .value | safeHTML }} + {{ end }} +{{ end }} + +{{ $showBreadcrumb := (and (default true .Page.Params.geekdocBreadcrumb) (default true .Site.Params.geekdocBreadcrumb)) }} +{{ $showEdit := (and ($.Scratch.Get "geekdocFilePath") $geekdocRepo $geekdocEditPath) }} +
      + {{ if $showBreadcrumb }} +
      + + +
      + {{ end }} + {{ if $showEdit }} + + {{ end }} +
      diff --git a/docs/themes/hugo-geekdoc/layouts/partials/pagination.html b/docs/themes/hugo-geekdoc/layouts/partials/pagination.html new file mode 100644 index 000000000..aa615d8ad --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/pagination.html @@ -0,0 +1,22 @@ +{{ $pag := $.Paginator }} + + + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/posts/metadata.html b/docs/themes/hugo-geekdoc/layouts/partials/posts/metadata.html new file mode 100644 index 000000000..bf9d84527 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/posts/metadata.html @@ -0,0 +1,48 @@ + + + + + + + + + + +{{ $tc := 0 }} +{{ with .Params.tags }} + {{ range sort . }} + {{ $name := . }} + {{ with $.Site.GetPage (printf "/tags/%s" $name | urlize) }} + {{ if eq $tc 0 }} + + + {{ template "post-tag" dict "name" $name "page" . }} + + {{ else }} + + {{ template "post-tag" dict "name" $name "page" . }} + + {{ end }} + {{ end }} + {{ $tc = (add $tc 1) }} + {{ end }} +{{ end }} + +{{ define "post-tag" }} + +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/search.html b/docs/themes/hugo-geekdoc/layouts/partials/search.html new file mode 100644 index 000000000..62b2e6fb9 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/search.html @@ -0,0 +1,16 @@ +{{ if default true .Site.Params.geekdocSearch }} + +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/site-footer.html b/docs/themes/hugo-geekdoc/layouts/partials/site-footer.html new file mode 100644 index 000000000..31ae8e1be --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/site-footer.html @@ -0,0 +1,45 @@ + diff --git a/docs/themes/hugo-geekdoc/layouts/partials/site-header.html b/docs/themes/hugo-geekdoc/layouts/partials/site-header.html new file mode 100644 index 000000000..022c10a0a --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/site-header.html @@ -0,0 +1,78 @@ +
      +
      + {{ if .MenuEnabled }} + + {{ end }} + +
      + + {{ if .Root.Site.Data.menu.extra.header }} + {{ partial "menu-extra" (dict "current" .Root "source" .Root.Site.Data.menu.extra.header "target" "header") }} + {{ end }} + + + + + {{ i18n "button_toggle_dark" }} + + + + {{ i18n "button_toggle_dark" }} + + + + {{ i18n "button_toggle_dark" }} + + + + + + + + {{ i18n "button_homepage" }} + + + + + + {{ partial "language" .Root }} + + + + + + + +
      +
      +
      diff --git a/docs/themes/hugo-geekdoc/layouts/partials/svg-icon-symbols.html b/docs/themes/hugo-geekdoc/layouts/partials/svg-icon-symbols.html new file mode 100644 index 000000000..801bee81a --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/svg-icon-symbols.html @@ -0,0 +1,4 @@ +{{ range resources.Match "sprites/*.svg" }} + {{ printf "" . | safeHTML }} + {{ .Content | safeHTML }} +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/utils/content.html b/docs/themes/hugo-geekdoc/layouts/partials/utils/content.html new file mode 100644 index 000000000..c2085a903 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/utils/content.html @@ -0,0 +1,6 @@ +{{ $content := .Content }} + +{{ $content = $content | replaceRE `` `
    ` | safeHTML }} +{{ $content = $content | replaceRE `((?:.|\n)+?
    )` `
    ${1}
    ` | safeHTML }} + +{{ return $content }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/utils/description.html b/docs/themes/hugo-geekdoc/layouts/partials/utils/description.html new file mode 100644 index 000000000..f5eafb2df --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/utils/description.html @@ -0,0 +1,14 @@ +{{ $isPage := or (and (ne .Type "posts") (in "section page" .Kind )) (and (eq .Type "posts") (eq .Kind "page")) }} +{{ $description := "" }} + +{{ if .Description }} + {{ $description = .Description }} +{{ else }} + {{ if $isPage }} + {{ $description = .Summary }} + {{ else if .Site.Params.description }} + {{ $description = .Site.Params.description }} + {{ end }} +{{ end }} + +{{ return $description }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/utils/featured.html b/docs/themes/hugo-geekdoc/layouts/partials/utils/featured.html new file mode 100644 index 000000000..33c4be812 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/utils/featured.html @@ -0,0 +1,12 @@ +{{ $img := "" }} + +{{ with $source := ($.Resources.ByType "image").GetMatch "{*feature*,*cover*,*thumbnail*}" }} + {{ $featured := .Fill (printf "1200x630 %s" (default "Smart" .Params.anchor)) }} + {{ $img = $featured.Permalink }} +{{ else }} + {{ with default $.Site.Params.images $.Params.images }} + {{ $img = index . 0 | absURL }} + {{ end }} +{{ end }} + +{{ return $img }} diff --git a/docs/themes/hugo-geekdoc/layouts/partials/utils/title.html b/docs/themes/hugo-geekdoc/layouts/partials/utils/title.html new file mode 100644 index 000000000..a792c0486 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/partials/utils/title.html @@ -0,0 +1,11 @@ +{{ $title := "" }} + +{{ if .Title }} + {{ $title = .Title }} +{{ else if and .IsSection .File }} + {{ $title = path.Base .File.Dir | humanize | title }} +{{ else if and .IsPage .File }} + {{ $title = .File.BaseFileName | humanize | title }} +{{ end }} + +{{ return $title }} diff --git a/docs/themes/hugo-geekdoc/layouts/posts/list.html b/docs/themes/hugo-geekdoc/layouts/posts/list.html new file mode 100644 index 000000000..ca0ea73a4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/posts/list.html @@ -0,0 +1,47 @@ +{{ define "main" }} + {{ range .Paginator.Pages }} + + {{ end }} + {{ partial "pagination.html" . }} +{{ end }} + +{{ define "post-tag" }} + +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/posts/single.html b/docs/themes/hugo-geekdoc/layouts/posts/single.html new file mode 100644 index 000000000..dea2a8c13 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/posts/single.html @@ -0,0 +1,13 @@ +{{ define "main" }} +
    +
    +

    {{ partial "utils/title" . }}

    + +
    +
    + {{ partial "utils/content" . }} +
    +
    +{{ end }} diff --git a/docs/themes/hugo-geekdoc/layouts/robots.txt b/docs/themes/hugo-geekdoc/layouts/robots.txt new file mode 100644 index 000000000..fb3345bb6 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Disallow: /tags/* + +Sitemap: {{ "sitemap.xml" | absURL }} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/button.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/button.html new file mode 100644 index 000000000..7c000a323 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/button.html @@ -0,0 +1,29 @@ +{{- $ref := "" }} +{{- $class := "" }} +{{- $size := default "regular" (.Get "size" | lower) }} + +{{- if not (in (slice "regular" "large") $size) }} + {{- $size = "regular" }} +{{- end }} + +{{- with .Get "href" }} + {{- $ref = . }} +{{- end }} + +{{- with .Get "relref" }} + {{- $ref = relref $ . }} +{{- end }} + +{{- with .Get "class" }} + {{- $class = . }} +{{- end }} + + + + + {{ $.Inner }} + + diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/columns.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/columns.html new file mode 100644 index 000000000..a359e4146 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/columns.html @@ -0,0 +1,14 @@ +{{- $size := default "regular" (.Get "size" | lower) }} + +{{- if not (in (slice "regular" "large" "small") $size) }} + {{- $size = "regular" }} +{{- end }} + + +
    + {{- range split .Inner "<--->" }} +
    + {{ . | $.Page.RenderString -}} +
    + {{- end }} +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/expand.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/expand.html new file mode 100644 index 000000000..0ab3d2a3c --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/expand.html @@ -0,0 +1,11 @@ +{{ $id := substr (sha1 .Inner) 0 8 }} +
    + + +
    + {{ .Inner | $.Page.RenderString }} +
    +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/hint.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/hint.html new file mode 100644 index 000000000..15149b6f0 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/hint.html @@ -0,0 +1,16 @@ +{{ $type := default "note" (.Get "type") }} +{{ $icon := .Get "icon" }} +{{ $title := default ($type | title) (.Get "title") }} + + +
    +
    + {{- with $icon -}} + + {{ $title }} + {{- else -}} + + {{- end -}} +
    +
    {{ .Inner | $.Page.RenderString }}
    +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/icon.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/icon.html new file mode 100644 index 000000000..080b144a2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/icon.html @@ -0,0 +1,5 @@ +{{ $id := .Get 0 }} + +{{- with $id -}} + +{{- end -}} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/img.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/img.html new file mode 100644 index 000000000..70f38c3f6 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/img.html @@ -0,0 +1,71 @@ +{{- $source := ($.Page.Resources.ByType "image").GetMatch (printf "%s" (.Get "name")) }} +{{- $customAlt := .Get "alt" }} +{{- $customSize := .Get "size" | lower }} +{{- $lazyLoad := default (default true $.Site.Params.geekdocImageLazyLoading) (.Get "lazy") }} +{{- $data := newScratch }} + +{{- with $source }} + {{- $caption := default .Title $customAlt }} + {{- $isSVG := (eq .MediaType.SubType "svg") }} + + {{- $origin := .Permalink }} + {{- if $isSVG }} + {{- $data.SetInMap "size" "profile" "180" }} + {{- $data.SetInMap "size" "tiny" "320" }} + {{- $data.SetInMap "size" "small" "600" }} + {{- $data.SetInMap "size" "medium" "1200" }} + {{- $data.SetInMap "size" "large" "1800" }} + {{- else }} + {{- $data.SetInMap "size" "profile" (.Fill "180x180 Center").Permalink }} + {{- $data.SetInMap "size" "tiny" (.Resize "320x").Permalink }} + {{- $data.SetInMap "size" "small" (.Resize "600x").Permalink }} + {{- $data.SetInMap "size" "medium" (.Resize "1200x").Permalink }} + {{- $data.SetInMap "size" "large" (.Resize "1800x").Permalink }} + {{- end }} + + +
    +
    + + + {{- $size := $data.Get "size" }} + {{- if not $isSVG }} + + {{- end }} + {{ $caption }} + + + {{- if not (eq $customSize "profile") }} + {{- with $caption }} +
    + {{ . }} + {{- with $source.Params.credits }} + {{ printf " (%s)" . | $.Page.RenderString }} + {{- end }} +
    + {{- end }} + {{- end }} +
    +
    +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/include.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/include.html new file mode 100644 index 000000000..4c395b3e9 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/include.html @@ -0,0 +1,18 @@ +{{ $file := .Get "file" }} +{{ $page := .Site.GetPage $file }} +{{ $type := .Get "type" }} +{{ $language := .Get "language" }} +{{ $options :=.Get "options" }} + + +
    + {{- if (.Get "language") -}} + {{- highlight ($file | readFile) $language (default "linenos=table" $options) -}} + {{- else if eq $type "html" -}} + {{- $file | readFile | safeHTML -}} + {{- else if eq $type "page" -}} + {{- with $page }}{{ .Content }}{{ end -}} + {{- else -}} + {{- $file | readFile | $.Page.RenderString -}} + {{- end -}} +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/katex.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/katex.html new file mode 100644 index 000000000..559acb687 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/katex.html @@ -0,0 +1,18 @@ + +{{ if not (.Page.Scratch.Get "katex") }} + + + + {{ .Page.Scratch.Set "katex" true }} +{{ end }} + + + + {{ cond (in .Params "display") "\\[" "\\(" -}} + {{- trim .Inner "\n" -}} + {{- cond (in .Params "display") "\\]" "\\)" -}} + +{{- /* Drop trailing newlines */ -}} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/mermaid.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/mermaid.html new file mode 100644 index 000000000..71330163c --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/mermaid.html @@ -0,0 +1,11 @@ + +{{ if not (.Page.Scratch.Get "mermaid") }} + + + {{ .Page.Scratch.Set "mermaid" true }} +{{ end }} + + +
    +  {{- .Inner -}}
    +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/progress.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/progress.html new file mode 100644 index 000000000..244f92e91 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/progress.html @@ -0,0 +1,23 @@ +{{- $value := default 0 (.Get "value") -}} +{{- $title := .Get "title" -}} +{{- $icon := .Get "icon" -}} + + +
    +
    +
    + {{ with $icon -}} + + {{- end }} + {{ with $title }}{{ . }}{{ end }} +
    +
    {{ $value }}%
    +
    +
    +
    +
    +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/propertylist.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/propertylist.html new file mode 100644 index 000000000..ec62a48e1 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/propertylist.html @@ -0,0 +1,60 @@ +{{- $name := .Get "name" -}} +{{- $sort := .Get "sort" -}} +{{- $order := default "asc" (.Get "order") -}} +{{- $showAnchor := (and (default true .Page.Params.geekdocAnchor) (default true .Page.Site.Params.geekdocAnchor)) -}} + +{{- if .Site.Data.properties }} +
    + {{- with (index .Site.Data.properties (split $name ".")) }} + {{- $properties := .properties }} + {{- with $sort }} + {{- $properties = (sort $properties . $order) }} + {{- end }} + {{- range $properties }} +
    + {{ .name }} + {{- if .required }} + {{ i18n "propertylist_required" | lower }} + {{- else }} + {{ i18n "propertylist_optional" | lower }} + {{- end }} + {{- with .type }} + {{ . }} + {{- end }} + + {{- with .tags }} + {{- $tags := . }} + {{- if reflect.IsMap $tags }} + {{- $tags = (index $tags $.Site.Language.Lang) }} + {{- end }} + {{- range $tags }} + {{ . }} + {{- end }} + {{- end }} + {{- if $showAnchor }} + + + + {{- end }} +
    +
    +
    + {{- with .description }} + {{- $desc := . }} + {{- if reflect.IsMap $desc }} + {{- $desc = (index $desc $.Site.Language.Lang) }} + {{- end }} + {{ $desc | $.Page.RenderString }} + {{- end }} +
    +
    + {{- with default "none" (.defaultValue | string) }} + {{ i18n "propertylist_default" | title }}: + {{ . }} + {{- end }} +
    +
    + {{- end }} + {{- end }} +
    +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/tab.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/tab.html new file mode 100644 index 000000000..90b27274d --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/tab.html @@ -0,0 +1,12 @@ +{{- if .Parent }} + {{- $name := .Get 0 }} + {{- $group := printf "tabs-%s" (.Parent.Get 0) }} + + {{- if not (.Parent.Scratch.Get $group) }} + {{- .Parent.Scratch.Set $group slice }} + {{- end }} + + {{- .Parent.Scratch.Add $group (dict "Name" $name "Content" .Inner) }} +{{- else }} + {{ errorf "%q: 'tab' shortcode must be inside 'tabs' shortcode" .Page.Path }} +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/tabs.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/tabs.html new file mode 100644 index 000000000..7d8671ec4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/tabs.html @@ -0,0 +1,22 @@ +{{- if .Inner }}{{ end }} +{{- $id := .Get 0 }} +{{- $group := printf "tabs-%s" $id }} + + +
    + {{- range $index, $tab := .Scratch.Get $group }} + + +
    + {{ .Content | $.Page.RenderString }} +
    + {{- end }} +
    diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/toc-tree.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/toc-tree.html new file mode 100644 index 000000000..13148ba17 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/toc-tree.html @@ -0,0 +1,41 @@ +{{- $tocLevels := default (default 6 .Site.Params.geekdocToC) .Page.Params.geekdocToC }} + +{{- if $tocLevels }} +
    + {{ template "toc-tree" dict "sect" .Page.Pages }} +
    +{{- end }} + + + +{{- define "toc-tree" }} +
      + {{- range .sect.GroupBy "Weight" }} + {{- range .ByTitle }} + {{- if or (not .Params.geekdocHidden) (not (default true .Params.geekdocHiddenTocTree)) }} +
    • + {{- if or .Content .Params.geekdocFlatSection }} + + + {{- partial "utils/title" . }}{{ with .Params.geekdocDescription }}:{{ end }} + + {{- with .Params.geekdocDescription }}{{ . }}{{ end }} + + {{- else -}} + + {{- partial "utils/title" . }}{{ with .Params.geekdocDescription }} + : {{ . }} + {{ end }} + + {{- end -}} + + {{- $numberOfPages := (add (len .Pages) (len .Sections)) }} + {{- if and (ne $numberOfPages 0) (not .Params.geekdocFlatSection) }} + {{- template "toc-tree" dict "sect" .Pages }} + {{- end }} +
    • + {{- end }} + {{- end }} + {{- end }} +
    +{{- end }} diff --git a/docs/themes/hugo-geekdoc/layouts/shortcodes/toc.html b/docs/themes/hugo-geekdoc/layouts/shortcodes/toc.html new file mode 100644 index 000000000..5d875eee2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/layouts/shortcodes/toc.html @@ -0,0 +1,13 @@ +{{- $format := default "html" (.Get "format") }} +{{- $tocLevels := default (default 6 .Site.Params.geekdocToC) .Page.Params.geekdocToC }} + +{{- if and $tocLevels .Page.TableOfContents -}} + {{- if not (eq ($format | lower) "raw") -}} +
    + {{ .Page.TableOfContents }} +
    +
    + {{- else -}} + {{ .Page.TableOfContents }} + {{- end -}} +{{- end -}} diff --git a/docs/themes/hugo-geekdoc/static/brand.svg b/docs/themes/hugo-geekdoc/static/brand.svg new file mode 100644 index 000000000..3a09f01db --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/brand.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/themes/hugo-geekdoc/static/custom.css b/docs/themes/hugo-geekdoc/static/custom.css new file mode 100644 index 000000000..e488c91ae --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/custom.css @@ -0,0 +1 @@ +/* You can add custom styles here. */ diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-144x144.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e648100af29fa964ac9e3423d71e3b8edec416 GIT binary patch literal 4506 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 bOCycc<8$wamdxL0%LRRHV?^~`hiCr-_3?$D literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-192x192.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..b96ba6eaf58f1f3eb333fa143000d483250fb73e GIT binary patch literal 6247 zcmb7pS5OmN)NK+#nzRUnngG&72q;aZgf2yjA|jzHy*B}+BtYmO(nLWzf>NaSk{CXk zNJlynKq-bQ2muoK`R~kqzjx;BvtIU|^RQ>uUTdFt6Qlb~3_J_~0DwtPSL@Lw;{G@2 zu3X-a7CdM#f!;^g!XE&j+W6l9HikTM2LQOZ^|aI<2Y=YM4y*JqH_JaBGxu~Jv0k4| zV85kP(pA6C77>og3v)|Fx+6^D8O$u{<}kz1s0aeA;Gsw4yP_M$k)mdTPbNyxkKLlA zZc$5cn%Z8gm3KpaOf~13M9$@@Y`5EvY;{hnI*%;09uN1uKWGgf7+z31{`tN&q*H6JVvI2K~Q-{SyF$76gTT?@F;@wjzUk_G589QMh6;!KAzh6J-{Aa_G^_ zQR;9XBd+H{&GrK(oJ@=B`8{jZ8>IhytXwQtl zCyX!>`(9eb+bL9)u%e+LoCzJCj@isE&`gq5YJ zy}DgF|KT1W_#DhuaN`QxOE=oqJ&f3#Mp$=ZYWT-Kmuc148U`CyYSrM_JCPnMy(>R< zl!`$Z8`#m;HqNg~KbW1X9q8V!8o#@~f(QT<;XaBzXhA5> zPuPTw8?fd7a7Pt}q5Qd=77XF4zhD|*2942Xi#%Kp{p30Cuk*@B2hOqauJ7I_dec~a zNFk~@14Y;fP%C!+wCl&tBFLqWX-}8$Yi#VB1~TcML0%WYp3^-J9b>bzPxt!XM!83L zRzddoE|DbX>cd#?q!_^IDM2nIiO61jilcL66JWQshykp5HyRUl3$RA8d1cWZ>N||M z;y!eu;tJ23z3E)Q=hBJ9p`JwCDs_v?NsT`%rZ!UMRAFy}i0cWvHy9|DG;;eOzj(gb zVHeGF#GEa-XxC6Cjsd_&7DJ`Im^Jnj(0zqn|Fkr%=&Z=Nx!OENu>4P_2=D#0p_wA!OeOP~)@()H__jk}!O)u}(JW;CaorBN_xizr?_u^F9t zZ?0s7jIDRhEt%&xxdW2rO*ESdQPZp%b+Q8mXDn_w_^s;J5opnv0O&FAH-FO%2bdoZ zg8OKyYBZ=hQ#3L>V{!XC&y0OIe71>)r*J9IK^LW9Hy%Pc(oTv4ykI-u$wkIJT=hmO z_A%_2jP5Ed?7D$nE0$YzuoFlyE6}a*1mQ?+<{rlWY_lM49ak(^EZy0YZyr)L(Qnr`!LFA28Gqo1_ z6&)5Cv9}r%91^SKpxBF@X1L6i5GQv(!=Q}84L#sWAr8=naEs4Sb%4WtB=9JfGJ9Ta zuRE#}B)-uXdtem9c)I^$O@1@RR1lx9tGrdW{D6N-Zh1)fh4by(qj|WBE6WXt@QdFI zk^l%I4Vft|MYwXu+whop?hN;2ZZl{;9sm6 zpRZl>3T&VB_$5V-*Nc^DRYi_oJkblxP1{<}aImeXb@AXwHQk~AZb5yfyS*rQC(kAl zmFqRJ%1D0Hhz<@Ex$REHPW)-VYq*r7TeBOZXrW6AF~T8MtN$@Z?X=$Gc-0_IALxNw2jnj=d_GMTxQXWI6!Q#?h}>=7wU_~I2}InWbaEW_xJuTZi(|5?8XJ#> z+!peF$}Jx+t($xi=1O6H?;i%Jkp04oN*$w9P(4cmC?wnHobM>Hi;QX_( zKS-2ycG*fL#hM1nlTcn>+10iC`1}h1-t6KJZ-n|%b zBVbz%Io=G8k`GdGHU$>J&n0J-+ zxt>Ysd_8aA7Ja2OB1=i`t%Bg}J!DMCKjQ214j9@*c_k?PhCWFOXjR5txMZ15C>Ont z`K!Fl|67>cj*Kjy0o7qzgE{>|$@3y2e%gB=vdMl9xIU%`?u6k250Hk@| z(C6{6=pA?L;R9UH;GV2m(8Q!nv$K2E`u-2+kQRy7d|_p2rz!)@YIpKQ?|SQW2rY_R`T82%m9* z?ViIySKCGc%CBzB*If7Ul@AmR&>Bsy^~5--XZ2HZYbA6x77x~1m8MR!_&xBwLFFUW z(J)z2=c*}%AM4T&Ntq67ZXQCjzb`p4?SlLG4Do@nL^!0#^hL{zl8f>y)+We1htz+4Rh9Q)4Va z*;~64`IP?q@5_qTVq^GM#ny5GGH-pU){HE`^jX+ohApg)s3h-|K{*}-3)DkbUZGa4 zohu(4R10+4L&az3HA&Vqo1Lo{tAZwh65KVlqUhWvNN>3k@X6aB7QRE(PIrL4HB~#( zg#OTwveyOUaYF{)PaF5zmj>G=Y9N^oh?&pV;{gAL|45E+?_0wx#l%GpWA|SWo%iDb zLxbBEAJ>9-S1WrS9gjh-tmh@~KE&$6*z6$7uo~m^`H7sQ>dk$S@X(Yw&>0nlR?t4St-Jct^(XL}WxSnGw2$oLywAwL!`8K1#4%) z3#UtF+Vau0^U}4WPto$IV$6~oMILTLV@1A;(NKp|fQKr8P^OS-!UNU>RG>UsuKW$x zG;%phw)dp0RmJdHIALYIkx({gnWb;hhCl~KbcE125ooxfVV8Pj_(l$O)r*i{mH4H_ z&nF`8Nqg->J4#|_RHR7k_hcFD2*4(OVR9P2?Z~~K+4#Kn?k&k~{%?jP-gh&ly~Hqu zk!@c9)Vi)7p>}RoL}~AN%7#}MxD?KgRtd)`8+r%Fq8P-@gdBc9*P$hu<@~sRS+g)g z-#5SL?97>7zfrOU{ePeFDFgn=XinuI`_BGvKAVmwl`>Q72@N2I_N}P(DS?? zuHL{gvV6*cF{p*qviZwJ|N0yIF1G{d&>eRrMBX}Sj6Ky zJE#{qJHv%2hyzMu#IuflLg0XI;Z6HOX5yaB|S+!N43e zyw)YY{ckqxEawMn$4o~hd_?~t+w7tQ9RiZ@qj`-<@C%Ws8ow28vFaC|kV zp6lE6Y^eg*aaShPN9o?XwUF_cbxWCq$2BM)fAT3yS| z$DmMhoia~2=-*WA4bl(gGax*Jok45`PcN(R^ZbzT5ExqSqC)`0ejmMnvE8X%7HN*9 zGtq{)$g84QqL+Rjy_uI)><3lm0d8Ik*Awe7h@z`Og0@2NO772cK9rugb{kMXtztZ! ze-amRU#I)$*O#$8HT8Z2e==hThQtF?@Iy!fgFA!c$6w?5A;H+TeVbbaEHh^N_IOMp%iz zpoid%&S>X^me>lo3$C2BcE$BB7VXxTLR*FCdll6F8ddexO-_H zV@;HEZQhLCC6oRwbiY-q&9dK`=AA1Cq*PZ~-V1pD-0hRUZZ-k}C{-`+y?7fG;W*(E zp3{dVMRNrKOQjzv>YEo+!FQe#ZP$)?qLGpJ*z873%7llo>Wy~jDMj0Kl7J9`fJA_`Xb#c>TLo`wIfMsEv&HWxWo4TzBT84@la3{OBO%_mPZW z$X`r6Y2)ukN6C2HPSaB^m1{oxbwUdN-Q!nBNX&LlD5WKW2Hkfzy0rmmk zQbyVJ0B2p#cu&VfW3;{H@&}aSZ8&WBzHr}6*9~NW>UKH|=H(dHZeMG9cDqHhCMgt2 z3L(B9Nx>Tz4*vkQkephnxhh!P+-Nu+-g+h+5(6k!XUW)7jf^gm11d1UP90`c+n$u1 zHnhA~X)V7(*K>V}|3;y9+N?hv0vupgm?}`Y^+9*atnRGrUDoQ(7^h;)R#N=_{Nx(y zab3ub@UHh9Kp%Vkp$&mZ=&4Wr*0^jVS~a<+`%7|B6)qSBNTs&wsN3Ty3@`Q=ut~q# zhAk9s4-pPQsqh@_$fs2Bb^q*an?|Q?VSc7RIJ%Ydj~ylLB9xKoZ}t)ZnO0vSUb3x6 zBI|j)%m!ucfS`gY;&r;2bkz)4f5?aKy2HvhvZimoz^HKx-9?h|*=M8csRlx(E2ASn zVom+7csa89_=1aN9FJ&ac)M;7HE}9$2NLc)UD)6s=UueO@kERD&PX0+t zR4H9RtA)1SV)(gKtG21=VY1R0)jO`R9pODIXc#GQZjDMi-?vf2KXc;>$b?iV-K7bG zx)GBPK4-?m-LVm^Pl)i7QK#jEzKHwPeOM9jot8mqT=DUPBicRUskF%9y(w>eE?$X@ zU*obr6vvG5z~O9m-phyr*mQ8{e>RVAXErtB%C@Vlx;RSn%KVenX=w^u-s#rNQ*5Dn zsB6kq4}1Oa(&LgQ3&AM*;DEg9Svpy3Q_8iRI=In%(&DBUaYp4Te9BiPj~b3J zn`g8`L?@1%DdOG|S?tCu4EwK5q&9Ju z4IzDeL(F!Z%o)CtGW(}NkX<8|Z=7A=O$)&Pb$|&EB)?EDzC~9#n;E^onfTIN`4wji z2^y;6r&M-G+mCm*3Y}fzTOWhr(vllSDn|v454aK-3t*IdQ{98Dp+K!g{D!ENZ5^oH zQ`HR?~yaR3oCoe4iHP#?fna8CdvC(I$VF`oxeN2nS=utm3sd|IWS^Nj4M7^0?9 z0Iob#3|yaoX9qsEpd0N&N|fd(f*LwbRG0Rx4;?oINyLz>N=Gf{e^0Byx^ z$cD5}?xreEHOOSwms-3y7@kaC1N3@hD5(~<9Vho^asgr;Kkc>9Jn7&{ky;gk#y+v7 zOABo+iN5*nMZK+Z^OklAo3uE2^JB0_2roqrjP_dJ4r8;Nrq`e6${g23>!{Ab#)X_U zfGJ&&>G$7?wrJ^k5X-`U(s;Dc*{R@~m1c7?iSd0*J ziwy|Hb(tBed#8?mC?~XR3a&Vd>X`9%>dnVu+pyqF3i`gS?dpn^A8M@%%CCcUWHBlF zx0p~n{%ML2O~l_VrS!Dxo=F1;`?I*!zR?oSaos2#C?1w0u|!&kN~{bcrtZ*a_|{IV zb-S0S3x5Jz2o7QYR;X!>sM~fhG$L}(;bXe1o;HfymA7?5BK7GJ%_>09#0^o;tbpGR zG(PwbKL37Mhw;c&H069xvq+Hp%Ssk^e>-N(`)s2>w>3^nJKkRnP5FpUg#GBGGUEuqnw5rJa)@{4IQD7LHjbc-FsPt zyyn?l(FZ}_zu?8JApV6hO&%eLJj`tlI^PZi|NmC&5o#M5(HFFZ4DQ^95#9m=k0meytHrDf`;c4X`uk%E_ zo)}_`z+l+*PqHPaM9MtthD9V!#N!No{lBHu%16$=XxM7G8jR`5j@)XEUYXEBea~S= zrKLx1Ewx7a_MFJ71Z`*Ooy@JT_`;z?9u$WkH5p^qfqtgRsJGfTZX0) zM*n6BN98ienV%MQ^_iw=jC7l{T%>84`?oFDtkVXKYe%5Jz`K*!aXZJFqn7qMv&%

    @iecPP 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-36x36.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..5624fe0c5cdfd2b3fb40d83364e0edeeba6fe8d0 GIT binary patch literal 1185 zcmV;S1YY}zP)t0L0O87(Td z-MCajwOSQT-dwA;RMZNk!KDiq-6*;c6#Neq*SZmOCxYNc6f3W_lKAE&%}erRe%$vn zY3_aPG6RQ6?hNxj_dDm;9U9sm+v6q=kTl|Fq)8C;JqWc5f>y(v{k@r~RW7IjNKHWc z=;lG8+5`NoyRb!BI8Be0>9{RzT9KhZ6L#JMZ}6$&xk6h&60@Kp=W8zU6Y9 zn;>-)WHxVRZk^mqIG8Gzw6FK6Uv6b>AYgp4(*n&0e?eIJq&V7X- z=*=!5)XYDZdK9ECfuvHH+r}l8ZWWJ~@S#Ua=a20lbNj7fCml#VO~`-cF|VYfKtFh8q!07;ppu7sI;@AZ zu+gw4>4S+s{&H08$y%knoIS6Z^69OC1T6;$wdSwQg>(4-Ex#^xsUXaYaeZfmdfXaT z_3M@LVh)9922fpz;kyRt6>?X|@ob!=_P`jx)DsxBp-KN(-mvV2mHP?*&4Y-$7egcVUodN+A66t?I_ciI!Z?j+n`X*u=isouG^H|*Lg-COd4TKL71Qt zo$Uzwzo8GPMRI9M1 z=tt37F#l9%!M7pb%t|f(*HiXF-LT{JG`a_z9-9iK2KB6i;gYTasuj2amAYG4)V>2OIsoaJR--3% z9i+ZHzF1Kp^=@_$mwJJteuoR11Jr3A<4C6f^(%n%g%1ef{cs5+dA|Z#_{x-tK6EX7 z0_FV->i#713cHWT5VijT(w#Tp*y?Jl$Re#oAINEOulv%Kv>KiIb9Xl1pr^X-;H^(- zMS%1h&!R2%*LkfgWeEBzORR;}*&f?tsMz=)EaDZGQ;9{+00000NkvXXu0mjf4zWUG literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-384x384.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-384x384.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c6a30f76bda58ce3ff86960fd42116726fbac9 GIT binary patch literal 14691 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 IM6N<$f|ts*5&!@I literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-512x512.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..847c31465dd9ffc812bb488a7737fd52172aa660 GIT binary patch literal 21745 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 YB-!iML1kCBDbBQx+PT?2w#NSZABHvpFaQ7m literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-72x72.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..592f66fb1536ff2c6500f1824fdef584e5b2c599 GIT binary patch literal 2173 zcmV-@2!i*CP)+o>A0{?4Pa|K|Q!+;KLE$Ghc8@X5=3otrGVp$0Y^RI z4G2XSLeaO1bgWAA&krIz9&im3K2395Z4?|J8Uq(sTjpR7xagTHX(o>SD%q2;aD76197J!rB)Rqq6h- zShl+FLaj%D<4t;Ar$;$BDq$;~#2+y?CH?9d=3jF406;|XexSk9K7zLo2V6uDw)Y1i zUR8;5+y`7-0bHD{=X6E^oKE6r=V{E&RgztN+kteZ;KQPMk-#@>^uWG9(1lC3twps0PT9v4LIJ=&?4uV{|N#PF}U z0FGqOE6FxHiBFoJ>*tkZpDF2`Lt}T>4iH4`n+c#=B8qmzh4a@4gbl--*z2V+>!-2T zPbJ$>iGRWZvy!-e@#2H|zi#9DPThrm%99LYAES!pxVK+%{Sq?mnMHb`dy$7gh*=rUSjk`C`Z zT_*v@4}s&pDl^+T!08f8epWHND~;LvO8T2B@z?DbwwWeuy(34Mw0+h?i01(p-;*QG zz%goSvH_FRdS9`2s~w!!`%OvjGB;L()ENe;U~Z{orr_PS02l8P7{@c_WDK&YKe1_@ zj(?V2Wl!@t!{DTn?bYMbn3-H@B1nlxj+=eD(BvQ#$Ff2(bm@L^*rF0ts2VgFSp zIL@yW6T?(`A6SrBmm;14j2!rb+Xsl_(SgWSG_hiZZAt-j03D?FuGC{z>{lgOG|uS` zfaH7uWFw$uUSo!PQpz3p(J~O z04n57?09PtS>s{_LUAu}@%x~;74jgCuK~w%N(E<&K4+4263d`evPZ3nWtn!581&_K z=i4g!5#adsC_oC;h#0wMl2l1b+d`)%NO;Z|y~GV+``9P%i0YzBRc8NX<;3LMV{j$Z(u zQHz-{uaib`r+MENB3Vs7Co`*5`i40j>6cQ;zcnpUESysF+cycInPz1d!U}m#h2T_GYN(k2dBTiK*d9GLS8JM6 z9kMNIt7lG?#j2XkAd?u5lbNABDLKz+V!1;N0py}s=7VDIDJ8wTm1OrS$?ma7^Z41q zlEqN8svrrRSJpUgalvf*EuTW7m_;$A7qD~$(`z*bgmKCobNWSa^yAun&caKsd|H?v zWsn1gqL{tMK28U~$(Agd0ViLy$5I#V3k>t?Do-6j*E*7|xDVcr{uwoPvC8;6cXY3yCAB>PI4 zW~UjNFlEoZZ`?}YPlsUlnR~}GwU+*AsPNXaN{C4@+tW$>^Of|^o24De&R5he_TvLV zvGe2x?GAv8H(h_gJabqaps?EJh3)nY9*g~z)FCe;We&z`%YS+ohf{hl5ZL^U{Te}^@3W&nlwSe9bsDM!~dokwT^;x+8$@EdOf z9%&0csmLG)5S2h(njbN!L4cs4Msg<*;=`i=iJb#bQ0G>Jf~76 z@{HOx)J@uCM@Ky;cW%v1Z~oQuOlaP#4Q|O4*^R`e)D_WCOkzXvo2~$8{=4ej)cXQ7 zvZ;5*W?vI5vJ6`5{WR~@|HZcOVC+_LlfmcDWjhkZ;YK$5!r&hZ+(aAvYx-k>iGMVp z3)B;KAH8@JLcF{YaF()^r7UGBOIb?mKPdkKl-3EVK>k1300000NkvXXu0mjf@Zt}x literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/android-chrome-96x96.png b/docs/themes/hugo-geekdoc/static/favicon/android-chrome-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..12c9988c1c534655ab49698493f34130a8df315d GIT binary patch literal 2902 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 A8~^|S literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-1024x1024.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..ba47abecd0d5a0cb174f9c261134982ba586e897 GIT binary patch literal 44655 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 bFC%he_o<~ip8pjCf7>?g+L-zS`TYL^@hjq< literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-114x114.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-114x114.png new file mode 100644 index 0000000000000000000000000000000000000000..bdab2978ac8945ab5009c26d7543b6b02e0ae79e GIT binary patch literal 3939 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-120x120.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..3dd618d17e20991be830e86bc6fb1b728a6da839 GIT binary patch literal 3848 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 O6vhS+{R&;@sQ&>cagI3v literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-180x180.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..d34586ff7eae9ee52dd81524d757b3af9bfb7b48 GIT binary patch literal 5488 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-57x57.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-57x57.png new file mode 100644 index 0000000000000000000000000000000000000000..eda66bd3d559ca5b5d7769364ec66182f604eb63 GIT binary patch literal 1935 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 Ub0KP=lK=n!07*qoM6N<$f~|nF8~^|S literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-72x72.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..b4abb3777f274f2afce9354e45d53997a7dcbf9c GIT binary patch literal 2173 zcmV-@2!i*CP)to()=AGTy zo!!|v+PFVFd1r^|%sZd?KF|BS7Xt)AfS3tE84QTQ5kd+i21tkjf@r)XrXV2(2x1Bn z`hbghJRb4*z>yO$dqFWgH~w`AK9Q$6Y=lz%8j^AE|<$%KyC`BuHhW6VB(88($~ZlH%>V+6;ai)=g)DJ_6-HO zDWLb3e1?IbSYTrnMqibJB1XQpzQ)uRA(Aw{8cItB2s0CjYB!pLd)T+o!%LLg-ss37iHsaY^;dOlPi zIT;8C9V@w;+hsl=JGDd#Ywf1(_=}!Aa~A4bZD<_uHxUk}81LCV&{HuPe8oe+x5y5@!esD$k^x=&mxIvx zShJdRQBc*d$HePU<&8A4UL2h6oyE}Wh=V82cxuuyI^VNmJP7x0k?UQZ<^%er_P8l6 ziXxot4h*4pkqvyvobljuAd3T^GXZ)FlQ1ZxCM}S{0`#c8T@etoeKkkT1H{Amfx;=U zV;~p=QVj-W!{^YyBbU<(DI_2l_rj?4;1e|)r=Y`iXGEo$t{e)d7sE*q-3qxG0)?+} z@{rOaf~2aTzuNA?(lzUFN0HBHabA*^gUea-7eifRld+kt8k|Ko0-*F6@HXs(p7n1* zuOl9M3lixyao{Vk!xQ9wWt@^!0(VG2SFYcLw25zuEtag4%Cczg-?r@BYfLXYTsS2| z!F&CzcrAkT#2=E(-EK#xpgE3G{PKfFPLPx%Du^ape>}&0SMvQw+5r+S7R3>NS;t~y}>EdQ#yVbBjILu^_XiTDkn+5cqHIuXha(uiZ zw2RT-DVY=S@$-3a!2Jggqj#}LVooqPN|3&qK~sSQDJ>`(tR2w5_aDHtxeIXbT`@@G z@gZ{lsh1{0?TORTtH|j{ozET96tqh9jc%%Ml)^N74emi)(*(cz3k{$-wv869zE5FuX)_jVT@Zj z!i+g8a8UB-VIO3su_mb!oB+#x#=G587bv5*iIsR~JDv5HOEHKAO_xoVDlrZ*L zKpq3#s^*J8I8Jgubl!WRTD5+!e~eKAAfR4T*4=iZmE`)4e!AEeh^=f3zyB>LtT0mA(4uaEE72f^S0Nrl81Fy_@N1WOT+83iu{_g79 z0OhHfDKUq4E2bPhhCALZS{5`>w9EQpWGV(_-gp1Gr>-RWGTpmM%#Aq_!che@oaR1? zaJWpG?`p8&*Ptq5=Wm{u4{~wiIr_ti(*(yNKrUQ*n-9>T(gfN!qKRAS2%Te2TtqR) z7#GVRF81vBFkFnjl=s3RGI)iPH{@Ok^kw$bm+6QSPFz&Vu`Wovse&$4)8SB>_ET8i ztEc3ys7F(-5soS#!H8yF1awe*5e5h==<b&<)yxDVSnYPV*)`0&?FN?r_Tiu~v)$>e^QZ z-i95}Rkszo>c7V&`i+Jq#374-)=GcnST|tib_cX#c)W+cC;}zTvGYb}Bt%FA4*IQU z%&~sR)g7oH28PUAC6FP}0JHnSp)tomIAIRjXX!g=&lJ>hNa}~-Br#syxOsM?VvhCG zJ{}70;T_zqz}*WrSEXj$k`^8gzdT0o1r+*B9HwTAfWn$MWGcFN1bpSApm%YKy1hRT zdeNe&vP^L#(BtY1s#LvZcCDLw_IRXxr>zx)wku&+tGHUs!;J*i9IwaWV17xNxIREH zNY*Z1aBG|*;#Qlj+_0I9C~)-f+d7Zc1{{(}A{T;o2#xt2e~`XCjf<-r3piP|@A z+l8-*HYWA21yq8(USDqhku(r=aXatsOhwVI5$JzQ@C4~Ot2S)GfY9C%HgJcIQEHOE zutd9}`}-nJ7k$p^jay|Y2C7q1MlNnu(YC2R1E|WxWx&W-pN}a>28gMbULUJ*BOzUNdf`owW zP}wGKhYGz-ianovJftR4KQtp_cpfD9Z>UQnIfvcU4Rzruh&A&m8F{!|xAiA;0o5sP z$&`0DtS~YqMe4!o_Vn24xCdaGi@7PJ;^h@$P&8{(Z)lUcKBy&Q%HF(Vk1pzoCo3`nqoQMH=xCf#wk*Jk0>pvC*Wkw#}M~{X&8k<{mg`-J9 z!vD--fP@$zh$%>jxfsM^kYIg4jsx>6CT=vA|RqbK>-U96(fiOA`&ph7{r!G1?&SUi!wgcAu*9eYlLRIvfq|J`lT?_P z1O`ckiPjm(lP)Qm46M7mo3y`PZi2Gv4Uk_t8?r`CfPr~MkV(u515Ge;-25VPo~)5Y zP&jK596NbNbxoF2m>>wG-MPO3GV%(+mhAw0P606+X#=m#GMnNYc>d46{#JEumI3DR zcu2ed$d@uG>}_`8_H1kmz%KpG+wdGV#owqlJon>IEwo+?W0Jqw(h3ian?f#>C=7d= zfihWHDwQdejn~t3tvPP4nG%hz!{kDBrUse2F`qA>UBVRZXr4MBhDGn)_%vD zz~(HgB5^7s&nd?%3d;fZ+(O96cS1(KvgK`o<7bjib3l2`ChNs8)^ii*y+|No@5*k7 zv4uf1DSidik2kF4O9UY3R3sjd5`aJ@pef(tAC> z90Tv}#o${%9{g{N24CG|@E)xJvF&=ucjFE$Q;H=^Us*@K({Zm8y1G23n<{28)p$C= zyK5ozxl*C8EDio8mP%V!D)=i0L+_6t$D}ka!0g!$SibtrxCY-4SX~|9tDQvP^to-& z=eC2tY(T(Pq|?t_snGk~j($Un3RrO%mt4APUHpN`uWObRIK!$;ZvCHqaQ8-mYz_+Q0zRwAoA%)?PK6Gp;&4F@g4x}nmr1yt8pM)b{ zePga`8iiFc2zq{}vl-rl6%sUCD6}#qG$D3idmBDi0CH&7jR*_#F$VDLg`drVrh-KS zyx*+>Yh@PnG)j4zq;?tF3cI$_&h6u)urW`}4;0(kQaPlfFr25t_ZC-Ht74y7uv9Ti zsVoM|)1^vey$35bltyEnf8{_BTN+~rHfU6_492Dar8R@VV%wDGUNTQvb*1{Sl*&R_ z?Eh8JDneo!IaXOJcn?+aRhV64dPS)^RG5vo!Xk}^dddnujuP5|a+T7UYx-Xw6+5s! zpB_~!D?7ZpxW=$xWx2vAtLdCREG0DQntbn0laC?0XL)Aqz|gSRePGNaIab+q6h=qM zll);ZWw~{fWdxS;nC;ErugNE6lPa;T9Lxt8T1#6yjGO*!Xdae}b7KWCclpcw@~|+< z(j5&W!D64^xj|fy!m>f1D-igxWA499Ux*^liUAg;7YK`{8ua+Rr{3qMut?K8OL^3i z(WDMW-H?5L`;UOKh-=fC4F3u{QLt}gp`i&zL%Vgu7V{T>;Oj)u{=Av>nh4VAFm zc6!V;!$EAlYUny60#hocRKq2i!dz=M$lr@PhVe=rw2rB#EO)vB))n>t#Huh1_%*fL zVd!I%L-H_YIVDfS*4>|w$-Stcu@2#>EUf^q32Ow1EltLbX%txVjax9XbdGdqyC4)6 zs{kaMzNpN2;Ac=f?}o&zm;-!7WsL|Z%OEU6z!p_h6EIni7Hig$N*gq40{QH%9ebjR zXTEnZiA*&obqIl#+An1p2KL}MwHw-WGJR$FG-I(lvRg{=qUYjad1&`DSgatnkg_ZT ztoL{wy+Pp~ASIDfT~{>(dK%AiR8|`JUmMnMWkv0hgLu27KtJ=I*g_LXY4!kHoH^*Z z&>;P=P7b3Xy5aDcVQ~-owrGMrQ`m{k#3e})jJL#4W$v^B@l1@My;h0 zdahk03ru*HJEka%`vjs87$q^@1b_uHeN>FfmiB?@N-_q?l!$n;-(q^lNDzhBKh#PBb-gH%HefR2sA5qpZZ=W)pI|1PK#)rJd^b4q50 zgbtQeql@;d6aQCBHpM{4G+w$s*8fVmB27$1dZCb#RuE^ z!wCXbVzFiCVSy2aNx%}Nuo4SxY(Tr$NvE$bHD1vMmg^*gl%;@WBzWr#8gBnn#xP4O zEIp2!vw{uJwRQIaSo`)iRYj8U7^c1b&k^VCe-SpF23H`&CFv-M+pgmZOufOhKwXH( zb%Uw?rc~z;KC~?O+z78|_VaMH`3ASx)h}RT*hk4YO?{M1 zxJS%n<W@qV^Y;p_3(d?r2d>FnHmQkhzFSx=iBD4} zEtlo>=iGa2*r={?`0PT`Anv`7 zGAaH?z?4p;31uXHK%B&s%k9vQL+H@bh!c|VA}I*l7+8fskGiQR02%CTHpG zG8ozHUAYf~e5U>dH=(bl@>8@Wb(5qy$7L{Ir|a#mF6_GH>^=u^G+qRX^7W@6G2^47ILM%L{! zt-1ldT||A2i8|(+P`1Y{NIvQ!!B$i=JAce)cQAVzsmk{Wm(!bG) zw;tYc=se~-SR(?lyX!MtD_*@x9-{VH!t#Qe5|1S91xW)#*6WuvN^QRJm?E8v!~OOZ z!T`Da{>&nD8h1UsIQ|U94jh-xs?(Z2Lu5+s2W`u12FDHSGe|h{-3Wok+xTP}(RU9==m3}mWAavm{m>e%TbTQjPw4 zND7?0eRg!fY_Xii9FfJ|@X}Y~Ow1-D?`eHv$}qLcwAEhTzg{l7w!;ri-pUm-OWeLUoP!E@5; zh|DEpU2{nHMAmUEU0C?2*I4CZDz^xDSCKR-j;|{tu_Y5|+u<&(hzt3|=Kpqw zgNRpGpclKA7||JoT5t7>w-h?wQ!PqcoOlYSrhZuYw_jJ%_r{azm!2{mF?cpDQc1J+ z%?HwdGBpOZGL3e0*V}f3OAlv^?Ex=oQ&Hon{=dzC ze<&Odf}rT~$w;nny8|IsrSp%k3>mQ$kwNG0TG@@G@2sjDUcihz@>%&F;BAWj;FhIM z_v6Ak&7n0~?Xd_s@FmA!ELX<|qU?PyCZA$e-a-8zM&b|7*?o)>d{Bip70JeoSZzem zwZC~(Z9tN4h6qV3y@#mwIm{?{?TOU!S6hvJU8qS3_D0&NlLSti@q>31P5MzOE4s~^ z4y9ehNC02f%BGrrDvzRYi-K)30={^v6$kNjikSr-^aDkTq znK^UfJ5@Hz3fj#O63L@w+8_I(t4y728{VV^9^24}er@$Ief{^mF^3&Y8?em~S;=2F zd+vt+YI^?N+3)*bVLiCgvG~#O~gh^ zy3gk55F9~NbJpQ8?_@13)z&*J<|jtt=5`$1Rw|1pZY$&tTCMh)MjV5gZRt0&urgI{ zEsR?jAex;jk}5iWsmneE0TIAU9hRMHbWNQCZL<*by<^`v>@HS;*gKUg9Ot|t>$^u9 zPUy5NAC%;56R~cqQ1yx5IGAhc;&}s7+(O1x>5C{%L1d%nz@QfWq{3OP@%hDMZI^1- z=_T-B5{^N!zEs@Y2(#R%l<%{2>`SbD$%0Uyn&KpTa#+&S5uo8dI3*B4(;O!dA*ym( zOIuxbdKW)}8^yg%hTWB9K~>p1w*R9-P2{{Ry`bcHOjPIXmwg@mbnE(OVQD)pY2gAp z`4k3lecVX4d#yqku$Fadk)VD5HEtCrdB-zV7LIx94Eb@jAnU)uSg>gO+WZr@IFrN8 z`OWaM3MFz9uTCOL|CWj^p`omQt<=5{=JLac9A0+$C@r5QJ2YzkDYW~>T$G8mH8|E^ zpKDg&k`&}URK}JQ$FQAzv{jMiqjoX~nDWOySOaVt8)kV3x(JH|R|E3X&0crZ_0HyB zkb+JbbO(#)dbWED6}jv#b{yf<7Q<7c7f25mbE>K743!R?nkYT1mA?@+BBfh=RuHKy zPp~uMHx?v1qN8dXbP=KBT^qLL9^KP*W2J&D|0!M)YyB#LD?Xu5?|{L}pgW ztzouAx^Ne64nF6}3R_*V4*g!`=f(6icGG+X{?HIOEqLtc8zxSjZBRD#?DxPB^V0D9 zArJPMo`d-+&|Zs)7`%R$yx~|7-*WXMb6{=B%YwYo9xiiAN_>PeRHVTi+6K+VSdj6m zC~2u6mxx60R-){xp})U0Zo{kevxr1o?T?$!BiT2Q6h}8lsiL}x6O)D)u9%IIOS;gi z>q!iC=*V?f>yH4%BpGM?0tx)j_Aa)4(=vJTEaHTtWqErWCO-RcU77Ppe>&Lr+dWr% z?(GHr_WqinOO#KQ16j6V-jMd=>%7t){vqbyWP~ zV@RF?#MH!HPGHjkyDUTf&e-T_LzmAE;w!ACT?0Q?acNFYKjoBC>s9;~NuOAjO0o#U za{zZ+=`BEPTIPCZCr9rl^{5@jfyD5XEYr+cPENA$u6RUBhANq?Te0n!jr~6gUV)2| z{-1~Lm~ee#e4T^%Dq*g{8|lKID<#XF&q@XQsXTMayE3E4)G}uj!-BJoVKE zoNW(wkHQm}J=j1I#pqV@;Up*`)3B(oW*d^=97_qWp&UzPtT`;v1`EvK-a$Fil`Ysa zTCKNo8CUoyvqMSR218B7d*17odlbSmo_hq+zl3KU{lv}@JmzL!6wUx|%USeikmQ~Wt7{}nEoc<#KSw7k}$1oa((8AW*M%g8^sWMbzGs8aKSh0!ROkBBVON11V-)n*)&#US=v^EEGaoWhKdLZ zaCyeXyrDt#rl=EC&W`e^>r4qu{Htcs_s3MFMsw`XO0cEa8zZwlPXmusClz=LB`w%s4*KQ<-V2l_-1Jnk$bJ4%ddEzLjI;^nu%SmpW=^R?TNRBWpxmYC zF=I0>XbhE#Y=tm8YdS!I%ExZfzO-e+*q# zBILp@QNN)BA*B@G8Qe+)&UdJr03uJa(NJJJv91M@#>)MRAL;y{MuP(39uBE(5Hga4 zMaT{JL*ucE~&Ir!s z76Qu^DTfzbq`L)OW(;u=96=*nt}SPP>OT1ryLMSbJ>fjcYsrJ;DP%i1k6V6UEkxXZ zS}LHUVYq|Y8Ew(FIT{0&L?$l=HfkcxP@U0jYOp;M=nEOPO(;U{73_H}WipU7C`so< zO1|kPXEVU9MVgGTX)x zpKluZupP93?LHSNc3Sj3&D~9JGLN+OO;tdf4@IU;herktq*^RpxAo!AJxTFje3sL5 ztkFd92xSXGM_QM6)ri)a+}1mNEzFcnS}l*w&F~%O!;8pLf-9L_=vo3SJ~9sD*lPL9M2(6aq5hU|S{>KRQUQh0D?1avX_))7SROO@w! zW^|mODSy*lqSaww5OspV=LnpQb3R5(lWjxTn7?i(GbXGC-Jja;8alHY8sl)SfV18Q z7BBfrHhiYJ-8GEwj{fj$L9L30vz(`ig(a(&&)yF_oAi60tjaRQ`T|3!))mScds>ZH zT?!xu250tS{{=f7l!lJGqJAp6>K^}N-xsm-q`%NCYx7@_EmjS#zpi|sZdI}jrSlFG z{Yzymc>#Hk>K<#d59!BXL<=thd&d$T{`+O%Bw8uU?821g_b)CoIZhe%^Tf(ah}qV{ zaUpp`t}k|6=%R^DJO(2&;4U`zY8rg%8dpig*DC4T07jZh|Gt`FPfLHym=a3;+HSGZ zRXbu4Z;p9%-Sslz=c3kxUwi81q(sd)S-jucShjlC;6UoWt%Pr!NnlN@q!YjY!Kwat z^}j#75a96mIceTlhQaj*)1m2fO@V$~W@gK|`BMznGlRKW=Id*iIJpHdj@EQ|3eX(P|oxw4i5p%^1lPO!r=qBI>1-tsEP7)()2iIJ)=uY}=jgX?rR>))eI{bScFZbHR7 zLh!P)LH?E#FDoJQ!B}LCfUsmSHy&imdJLZq;< z+w$u2X&nrezK{B!>z1jQW-#UQk-2?Zya(DxIoX^QaPu00_izhx+(z0EbMw!y%uA zNm6c9RbUGC`SMFx%|^u=-WX68@7o`*e8p>R^6>0JIyi2zXygpv3*YxDLVnuFPkYO_ ztv>>HU+X0{qZ-|xl|M92AAeL%PnfeazaRz*Z6d~gW*TvBwid%O6>W0&UF#c$%sXC7 zw6vq0i`(~}CtmeMN%WpKmdy|GKu<8*CJE=ei#H&EE&1uB)4=EW_$vM~tTdTWU-9{I zi~B*Ag_^Hla+GS7@b&cX{kdi!2$1RZ zIyYa4>BqgEV#WPbvuk!r?4i-gc>8`&^!UAZ_Mn8*w8};%Hc-#sqmj60^3uSE*lms! zYhZ~&Y95I1Ek}dkd}oDB%5Z`*cURaE-7_+{8&o#~;(Po*iegsIFg3aIrh?EBT;s*Y zuJBg@U>mQqA2ht32C-5V`Vt2&O|lPG@;E|#dLkbESEbFB!v^9CF}NHMuph)R<Fx<-PoG5h{VUhQ2yl)gki#0Gx7~kN^Mx literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d34586ff7eae9ee52dd81524d757b3af9bfb7b48 GIT binary patch literal 5488 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1125x2436.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1125x2436.png new file mode 100644 index 0000000000000000000000000000000000000000..642d0254e54f117e1829f5f23117c066c3b95224 GIT binary patch literal 90067 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 E4~HDtpa1{> literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1136x640.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1136x640.png new file mode 100644 index 0000000000000000000000000000000000000000..103e015bf783158d903d490e203c9680b1e5dd7e GIT binary patch literal 35771 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 RU_#)};e!?ja`rji`X3{M>ahR- literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1170x2532.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1170x2532.png new file mode 100644 index 0000000000000000000000000000000000000000..b01493ba7a713ba14cb76cae4dbaa20bd45dfe0f GIT binary patch literal 96814 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

    m}i96s57j%@2)wfv2Q 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 LpLO0gkDvboa(KrY literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2208.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2208.png new file mode 100644 index 0000000000000000000000000000000000000000..8defb8724cc793eaca704309c166f9c44e4b8e98 GIT binary patch literal 99127 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

    pPZ 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2688.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1242x2688.png new file mode 100644 index 0000000000000000000000000000000000000000..4f750f5f5472afa6ee44eb284781c5ca898b6e1d GIT binary patch literal 105836 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1284x2778.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1284x2778.png new file mode 100644 index 0000000000000000000000000000000000000000..10e452f540cfca982de8a54607e9e12a7a04155b GIT binary patch literal 109562 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 O-)~!YZAsgV#{CB*q{?Fe literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1334x750.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1334x750.png new file mode 100644 index 0000000000000000000000000000000000000000..c6eefd607a0a61ce517db98eda5cb6f4a470fb33 GIT binary patch literal 45112 zcmeFZXH-*J8#b(iQUt^i6_jcj#fl1{7$B5!a7HN(Dxg3>G-&7s2`wN+umW~Ts1`Z| zM0yEDM1=rS15yMep(ca?p#<{oL!0=#^M3!owdTh&&sqZe>~rtCT=#Wf``k4))EC{b zW5b#?YefG%_50sz)~r`qv*s7NAV2t*r{Dja0RJcCa>^XDW)0r}^uM*)-hbP#StGyZ z&);>)uS>cX+fKcG4r|aBx?1{Lkd|HRM(?{<*D{lr{ zth@EkT?g2OUG|+np1?T7L)8HdeEgEux7Pk&|M`S&3gn)jB;ERd{=z!KCNsf*|Jxm1 zd~g+U$#ri9M2?oO;rrkJTnR7`JhbkA|8?;xt0X5!T|r2><(!%wKz3SD}6hjGg!wOIY9XKa(NkfBWBml=@XO z!&b>($Jpy%Ui4_G_FhU*sqVl3sAWKwk{MAdub}yF2VgBP?x1VE^WT4D?)c>;FHa6(#jwurB4@ z|8g)?B((p_!K(%4ztRe!Ao>4F>nd*e4>3X5HT*xsw1O1>1Hy~h^3#t0fbepX_zwvG z8xZzyD76jK+?M0ew%PvO{Sa9%wGP+T;IRsB{t=&X7E;I#Io2~q&FYpiwDdMqo4T10 zB2h9f+Ef49NVLx5>%np*WMu1~ph1(o=WqJKlb!k^atrPIulq>HB9FVfdsHF()O>m| z$cV0H36J~qZ{8#GX{aQ4|L5|l#+dK?3@ipoGkM?7Z)i&1B zkTULPJo*Q|RV0**J#(pwBE^iq*nXakcmDPhVG!mOUE& zz(3D6D=Vd-BXc`nozD?PWOLhBa}G_>bMo4Bmsl&dm9J1W1^N2fa{nFP94`>C%01NA zYO`|SbP-0u*gKa`zwX;+gW9*noYHnXg0bcx*5P^C9YCs}(XmP)_Ydy5XW2S~w0KII zN`~20!QwiKBZv~`iRS;<^K=pK(ms5}{?sT^w`6Vp_uV~p(evf>C?DbHY4`L^tJl2g zV4nAsd_8f?f4i8PH`a~H(h^f+MYYa^j#iVVo9P#OT;qmXomOa>D}S=JGgb)*ynQT| z*4)YNlBg{lYZ&`Mlm4pyx7Oycx9$}ib>cUjy+hdn{K&j^hJ*P!-W(-I6eN0o^Dd{7 zE0Mu!c&qsn=_}?x)FvyqO8;mpi9Rj+-701#j2IHAA39X>yeJXVR5W+*2F(O8HKWJt z=Y=2E+ReO>35goRXY|m$`(}4`r21-_E;B0H&##EBTcw0z&H2Y=@cl=~mz+tvrMa_8 z1!evIQT4AnGOxctO_n`w2;3s#CdYTbP}Q^&cDYU1aGDe z%0gr}5T$Y6SXGoPdaCQ~zM9RbW2L3<`Nu5@QJo$4pQnY|(7KBzo{p6Uid9Zl2I`jB z&ESNWxvDGft8CB9hf#RMT>s%7BJ#$K4%eI3v}56Ud?~E`^_#DO1?i$^I43`eNBf#t zAgmTXD&e}varajUyic><-xUh}wE256EsZ4j-wnN=)yGN7il9}+kOn> zTc6GYiv$yj5lFwzhoNug7W&yoms3x8TjmN|W=#qtb6A0Lb7z>Zn2)zY(fx~o&hw*B z{3CFOi&+wTXJ|Hxeh(RzCD>yt92xJ^L-36GG13Rq+BrF{%ZvEMr-}pdi**~m#P(t&>!ckFu=KwkmU=x@gn{;tz5%KmM;rs&HO+cmx$aX>owg| zLb`HxmANw)_WsU{U11Q7<@gAy5^+>0(dA+OO5FcxGwS$J5kA(5!ZL}EmW16loh08( zhT_G4T%x6%*YS&W$qdeSl7QCG&hMLDz{xpCDR7VXgDjtYNy(ofyb|J{4vhL+H||ju z+76+MsZ#CygF_z)P8SADsMF+}(<$D^*(KkCI@mg&7hF)xU%^tb8EZcF;D4v{{0 zCw!G4{&bPTSGLNcp5j`O6@5nGu2^dM)yfJPcl!;Q>mo$XVWn}GMGI#4wNA~if57v% zO}u~GsJ(qlhkI3250^9gt0w&IJ#YHDOVBx;m;BTkbAvX0k~`j(XQ&=(HP04VO=o%x z@B$x{m`g8!$)#oz;hM7Q$fw=*`a`_uRbrzjPWQ z7p9&ukC1PluHHRR`KvMX4C811y;mo8Q8XrAnjAzbuH^nw?F(mt{m0C2Ej~B?SjKf0 z6;xK__KKSIr&*o&0BOi%??p5mC%^V|&Cwa(uCAm?z*;|_;K{)a9ceQQH(ykB;_r_O z1oj#l6v9$Ax`K_?JAXIg&aUry-px@-HxD2Wk^EL@V|ghwc>La|KdYelt+$O8;iu;f zvwJ?*sbAiuZC3P(#*|;&ewzRI)d@~IdDwTMI?pNJu92-oO0Zd^wg1P3iaYVZbKe3~ z@Tj*eRubKww&?ufRv8g~3qNLKDsP_7FrQ~{`p5E+2ftAoT(rR6(Uu~H7&{~(-RF8o zT)w>6#vuH&5H;XuFSRHZAYTL+bXVgP?UtVWK9i@sg||47#gGg6lG}b1!fZV<%o6vU zyL`)E8KjY$6T`k#1+V6A#LBsapKstRi~nplzL-1CcnQr%C~751N#>bm&92c0wWV>p zq!4$`JR}6!>E&%f(vbZz7t!6ggj~b3Q+c0T>qJ(>vF_!Gqiq&8d)etfg*@|AUFjD| z2d$g^)#V?(=?{lrK=Jb1YPYop~KIa;a*?dVu@-$?JE(Rl>aI2bt3|<^2aMG!)~6p9b9%d2`L$mHFZb(>1Gd zcMr%rRgcLhwtsxL(x#Lqs&GfF>ce^N@@m%81FaM7B zxs&=|k(^}Js@>7Ta7EFBP`o|`2j|x#)DssX$DFTV>|A=Fwfy^h9=|bmOq`i3WC#gp zvVX%BzDnMB6f&BWXkoGuQgdna@wma1ELb_s+TE+T}$V*XP*6c}&k7%^51 zUxS^GsLE9m*N6c;>1#I_y5km8U28T(25BL5eXgL!>E zm%Ux_#4(L`*Pk$?d>JcsSqCJUrGcOSHYtTba$~I;QOcn`(;OEL**etUFfoF7+A|{p zAv-b3;3hiH|NYOy@AJ;r5X1;pJzM z6@>Tg{>~O%0Trtgtx=e9Fn+PTeY_9K8%rYO#Rk`Po`9zb_Md)nh)M5mX3|oOJPcIp zC#;PpyY*HaKK!?@Jmagl>6WCoXPiwOoO|9~xWWTa6;3P0c4FcW*Kg8WeB>O zaR9v8S-bjWnDgUVCrCN7L9Ib@^AofC?H9B4Qbv(yd2CwQh~+4yCeQ$`vfevDlON@V zMfo~2dVA?LK3Hmi(@XOrpJ?uEBXW9t>~0;d?TA75YmV0K<>P%<%P*`FFmD)EsMhCLXQ?)g(D&Sr0bvk-`Uu~O7T~22AIqD1Zbrd) z`xPpNaW_N*A?-Dh)YBp6qs;kH5Hp#kPj8r*TSF3CNu~cxskJlmhmBc6A=2BT3&!8} zB<)rd6(Fkp1xlil_4lM1+NaZf9T$Bl$9lqd8;YcaA`VARh}qp{9Vt@w=^5@8C2=Ml zO5J9uuv#gFpdll9*IZ&{R=|gX+?59wzXBO8^vBtAu2Uf6jUW^E?%7{;6Tcpc7&^^k#_v9?>6VE+txsf~$%{ zUwcWWlcd6x1w-c`cCkE*ZhUgu~toQBwVi8yna;yy_Vax}HtoP%TG zZ025c|C;01Gm$Z0Z5QI$?d42y@2_Mcy1mFR%3Cg_Z)^)D=;aK?m2nHN)?YW>$7<1p z;DCSqd!Bj*lAEB)dIB{n`-T6`;D{%FxN2&~Bvv)p5ixs?ve2d)BqO1PctG;LF6s9z z=62L;OnL3s{2pc|2V=v2Y3c}2yPpSKBRs=_EJ zEf*>E?l6I$J13|}fXxs*k@p7p^xGp{RvTSC3_pzH&)0 zEfv)VB>O)p3wKS*a~Q~rBSRgXq}MBFq#NbMQ{O670PgNTUUvgd`TKdYYqRz*3f9qAfiAeV?>qfaQGTdGfgtm3Ved;A5_pc(_@!*Jl z&6hK-<36faJMOk6)jncX*=3*LB3$+Dm|Oy5!(lAuIo31OZ(zO6w@GBg?7IT>SIc6Z zpeEiF6+oUjeW3<@_+rU{8l=W%!|mSs6FDa{u6LPxZ>PxdJqdMoE@l#Jsst_=bUcZW zJ6Ojk8<9O6Bd9D#jCG&lcyFm{xnG(sl@VGi1lOA8WK7z1(}f&0k6($(FkGTe@A8sR zP^=8!x_QgLU2;G(9XFS4Q>Aa!j>}6>Ls^Z~M&=1;;g4e4!=>m!~+s7{BA3`?-7e*NWL3#D|zD~HvOfS>+i*d74NgWmAKh5-09Se$yUS;ioj~? z^o&=vwCFiy@t$_0SFMfo$ag0%&$V`U3aw?Wanb2cq26qJt8Q88tqMmPaSB?F4Dd&O zD`AH5%`J8sP!`}V0fS8WMN6&|b!fBjS#Z^(xPCre5H|V)`?q1xt>%!&N;_N(wW6)) zU7Sy6cY1%1UMN{@DbKY5sI>OI;8KFMu8Nn@KQDF8E4;|Rw)R6>?!5AY7*6F>9M&1m?rdDTXRax%Z1X1C>5_FZZZ zsx55S_s*%n({r=&D~{%n2)&)#UYXUm6I^_|D|+OEiqRgDiL_Hwwd;QQh^`<ND3 z6#7XyqhC(X&L*s`a1C0)Wv}$=3TqZucq5`Qdrh_JLD;&eOxRFS70OluLoAte4rFcpUfqED$1J5X}@KR;b(NX9V)(2w-{ePH-i5Zu-t5Z zcb2hnGuyN!Gl(FRcVRK(2C4A&zW>ykH0AGc@;xZ%0GHlRsTK6-LRWQ{92qJK7aWZT z%j!i1VJU6-gE~8hqb5Tat9H!=;8QN<)=(Hhey~Ah(WN5bF#Y>6rntz${rzSI`Hr|n z+Tv4i3$(6X`Twp9Ock=j!OQqlM^1?nR28r24FhTVef_|)Ga2IOdE|1S8l*BW3tz3RY5kA{;kLQ(Zn=;Lx!nPiwl zYi3;rOkf`^hhh0+l64}8V2aCAa%#C^{|feK(Qw~F0P-ly^neVWrYujH2pLEgJ)rrr z8CXtp%ek8`2h9r9ouZcPh5~icK%D%$EqIZO*P*1G3gvK&NQ=~N7oleAMe6kyoHG;M{?L8{C+`?Wt37SRa?PvIxHZcNf zP~zfyo@jDQKowU<5n9%DODw%(F>t5G564{p=N%ck24d^a%V=y+C7Tbc04tYjKj)o? z`~z1nNiA-`H?0LCC*0MHMzL9T5f*Tvf&%d59L*x8*aEJN*=fr!+?)|omJIGwP zN{VXYgf&B#Jf*Sa+&a%nJKqn!MdD*O4|20P1320=&Lr%+xACVPJ#*_8w~+Gk|yZjE6^i+T}?+_tZ%;G%K^`!}%1i_ZFwruLIwkH%IeLs1>nL6_kGlhrz+o&SB9it}iYxz_!Hzhzw&DAY>7Jr5Sz2 zelqSB9v&2CSlxy`XLDs{U3x_KfD2|UP#05?lcLq(+G|#j{e^uHoRqx%P2L_q%T8Ww zWUpLd39SSXbTHjYPHUQ37xaR}tf3o{_X-fMy3Cn|$cWc^a`nqe3pCYoqEj*MFOu}x zTv_w5%^P4O>{*W@JND(wKw?rHO7<`J&{*POT{06BeX--9C&O7U=Pl)`9DJRyqFr&RI5=hh8 zF1>_W5kJp?N5_5)iykLPqYZs$7sVA-wqQ0jK!m8kLsE(-FM=x%V#Lc;PrU=kC!jJf#{dFSEvVPRaWbRxL zA!_$*6#SH?!qd{oB{&^)0L0q5`dv`mE7xi}E3jF}`4bPKusR-p$)c!bU5_8pH-6-M zK@9D&+KyI1bkvaOTce2H%^&=>1=eouIhjzj--n*kO_x1gS7D>yl)_HEIBi^iD+=Eq z`r(fd{7h|iX1-0;+bY9}E7kGg1|?!@T+fB!s2Ildz}HIGi3?y)L}EvN1nIeN|8F?o zmFPP>#DlzRd}2L^N3lVzF_Y2L*9=7tNl38I92r{Y)t_D|=|(M-6c>~Y$+FL)*)uv0 z?~vPe&)>N#Y-^7*aw>UjhKNh}R!t_%+q6k%8=B6}dg|#F^q#`yntBXqNou7tL>{I)5) z+N(cvI1pAw3;~ViQbm99359S_`XgGMGRn zVY09^6!UQrNF>+nm7yG*ox#)BWccxa>1%*SlQxyE30v2qe1v=^KOCuCr~BbbN=N1n zY)1OPx5@~)X3_vs>)U8{p=z3GOG=y9Jm+x|9M*SiG+)$DAyEVt7Txfqc+`eaPVODX zb1r)M(&9nxJX>M}WlQrE-bQW?6^oVVA>n2SO!_B{MEKF*8{#^a`KL`r+cws|v+LK4 zoFPU{$LHP_ko8fRx|nyJ{0=4BGd*J_CA*cMl|&PZz)PunZKoG3x=_f`VITH(vb6{aS6uJYlBd^bBzx z(2YUJZg>5WVqoSY_N^kFN$UGS0;l@c9PWt+|Aw+x0vp}b&N~sKNH;9+8Y3Se_XH9A<{z87GddN;nbGK3r+9UQi zN#DrJ_c-Y>BUP8$5!4XaKH9|TI@u{vCgqnv9f*a)!bS%_9};kUQbFc)Cp{C}K%Ttl z)yzUJwho(6DPY;WL(ptlJ1sPZrXS0#>n>6VcC0MMSIUIDqc_^*qU)jvGl9CEc^qhT z=IXkqcvk%tdNbNRln}<&Ol&MQ#(Xy$1#2UMv(JXnsP+>IT3FIYl5C5{jM}yB-Tr$t@qanjVn@r#3sbkA6TAXmeyyhb~Q<8K`d7t65-q%g|BQ?zMeq6 zS|utX74rAtj(l}j8p`iZ$z;3Y)?&)LHjV5Hizw`8a>U&+wnKC}f;;UcqIBOIrr+y& zt&BPr*y~q9${KptO6k|9Y*f|1oEO39 zE#e3xANKt?RWMoOrLw>25WqfL&=+L9$g@#+`^}W3d;lmE?N8>J2SrqB65y@12kGv( zITKxXhRpQ`cb6K0e>%=<8UDu==1L3dK6FM1909*NVP;&Z{{s$3^=T&DHx1GYRfA>< zCjC}VW%pn?KJU44vB!V6=jiDqjWk6bR~aqBWEI(Ad`1J*3;|P6bT`^<;g_>Z4W#yk z3f`+S?!}i_3ka=E+vMEO7$rXU^E#S1REVgC8%i9$v>kz%nIV2)zO!${w+zA3q|jE! zuO^^O{#82y$X zAu!xu42&kd>7f(Uyt=PG1@r@}{LM&vsj$^duw>-3wfMgh1Ux@QhSbhbe#CII7w~}b zIF*~8JsTJMyvWz8sKD}d6u$96+wXbmxlF8+dzFKOm554JotD}au`ZK|vPTm`1_u@? z$f@>Q*5W&a1)yyA-hbGSnL^*KQ+awIG&aFZ7+&?Ydz>!z!4)H2Je&Xe03|5`u|*l6 z@8pWqw!~gDT%DfI&9Exqh21%oCHelV`K z9RLQxw4#hCoEizzE)CA7-DfVfw$B(FU$R0#nM3(&NC2wW%*$sw$-K{uE>D;JQ;r~> z)8%$D#%{SAH#gwT{f$x{ZQaCCeu9;*QT89R?#&Am!N?Dp80pUTmV(y0Z=2Ae8!1Vi zZLX7|umqg3g4q1FEpgOqtdCjVF9ytH9RR<#FjGHNrM>J#Ic%uOR@=J~GEAy}A){E4 z(~k*z;NKQtcgA!+S9AdOfBb9Om)c}k`%p`ePlRT_fxM)jPN z{-DlzI84s@N}~FpAvrTR7+<(SRcbc2{)3*brQ+EyP(^bz)3bf(bp@Z8*13E+&=g95xVo7@H9M_K{)#X0EeW&L z9Mg&8zfE8c4~f$1E^U6NFPmDzUFOc-X+mA_m1E{hHYr+2W!V}(XHZf#@=Uy4q&2zH zLPi=tW_r>^u~o->YFs~lp*_Oij>0?oC?wtmd9UYX?#>QrMrZcSYonVbzJ)3WL4yIg zqhKLeSbVea`lT}!?{-6}Qrxx_^Y@_lQGjCbeBR*mOMQ}{nUB#&^XrirmddcE5ovvA z{lvBaD4uX^GcV`7ws3*ly=UjTBpMJI$+IOZzCHys0tQbiuRs$EVCi=xq&Q#JIQ@@j z?qXg<;k>DjgkDLl_UB`IFp$i2;-D<^1p!B1@=>^!`ZkX023M^XxV>ZIqE|=ucD`D^ z-q!5N=W;oi)Fp$*Iq_EEGX7An$wcd{;4;*LC;1`ij;#XaeFoiP#u^s-6-;h|^fn6Ta_Q-6!E{QhuWS-dEQ9|x z0No!y-o`VtXod!G820*ZA_wT~RK4Z4BxgS4*xzkEm>OZKvCFMb^#n4@lF)Lt`!wVv zKWPX{t@)h2yH7H8@F%NHZ_37>{X7**^Cc%pdtJ$6EFeA}+v0Gs8$EAqEPJsMzNK2m zQ4~O*aXlS(G`;0hX={U&3ynIB_he$KNL)SI@K%QlB}bOVHRW#L49ac%mt(1?8X*y; zN-IM#DwGe9JMsOyjY4EGXi8C=Tu@3h0~Uu+1*1^c=4eZvE!;`G`4q-C5%fFuOsAJ#3oWO#Su z^as6Y(-Fb4_{r3q5ZrJe7tJL>~w38=jlJn%iqpu5<*`m>_CI8cd`yannNN&ZSAV! zv(wzG>I6ob94e#my5#N0nsPB1M;z!dYwLGWI(%oYH`kqAPU&qEP|}s(E4WmRa-;oh zeAKS>+)#XNDq~GQKsn^cd9kc`P;-~vnC!cdi1SlW2sUvPglTS3R${%e5!)~-4UZL^ z;m*{DJGMC-&Wv7~H=W~k_C~3^-l54#Lo&w(&uL62@3HTB=i_rB=t&3hx|ZtqY0pmG z#9~cfdR**1*)7SRYXR8IE&Mi7gAi?-ClP&1mP)7OCw^dy>o;CXLx8h^A4mirjZH|D z6pep3G|0MyX_&{y%njxCvH8#*?jqeEdp$)dc({rQE zOcv#Qy2(EW`4^WFFu{FKQ=7db(O|OSqPKhf0_nVd$Q+$(E3H&jpJty;Nm6eK4GFl{ ziPaQa-(OV+%<#sAMY$VAfE8erxL6q^M!SPtG}+Eg^zHh$eZS)ePk}T5(bE¬^&R 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1536x2048.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1536x2048.png new file mode 100644 index 0000000000000000000000000000000000000000..5e9b9cb6b837a4c3d77e95edb0943b13d95b0c44 GIT binary patch literal 126468 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�}d(zCyx?arjO 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

    (&NXhqOm=)ioFX3izZfK?CZVO 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К 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

    9B!P}fw7T$8$`T=3x}6UcG1TfRPrH#l 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

  • @*JGY4S$TrpT=VmIUPHA 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 Kx)r(j$NU@6QC7qN literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1792x828.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1792x828.png new file mode 100644 index 0000000000000000000000000000000000000000..dd39a3ff209c2cb2e0d6c8229504ecf228dd78d3 GIT binary patch literal 53255 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2048x1536.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2048x1536.png new file mode 100644 index 0000000000000000000000000000000000000000..6210c86978271e55ac54025ee14f090864bc97b6 GIT binary patch literal 129401 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�$ci)K{GsgITpynfK$iZW0s}$0fSvVZm<%9ClG`{ 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


    *5_b-4%Vlk;r|Y- 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
      5*SIh;HgXo^K~n8MEj1dx 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 L-l2?x7B~MF)&%6} literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2224x1668.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2224x1668.png new file mode 100644 index 0000000000000000000000000000000000000000..a8cb52a7ac3aa866e374547cd5878c5bad94cdf1 GIT binary patch literal 145637 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

      +<}UyF>&nD1TPD!@ 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�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%0Aw$-;yUe9&M>@p~^ixXpJUHm&$7I_snO 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2778x1284.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2778x1284.png new file mode 100644 index 0000000000000000000000000000000000000000..5ec7c9438e1555b64d983987c4bb7e5cbb70d634 GIT binary patch literal 111486 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

      {`Ng_ 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-640x1136.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-640x1136.png new file mode 100644 index 0000000000000000000000000000000000000000..0da1acff068c6b61eb5cd76d09f55e6e3614d592 GIT binary patch literal 35116 zcmeFZc{J4h8$Uc_7}-+EZ7iXUvhPyXD1;V~BxaC(-?I)WDQn5TRhBFv`)*NVA8f+v&WxaXuY2yZkzH{ ztp!YbB>L7(UWNreRN?yV@*PF1^tG#tYi`#E3irw1y{~)O&B*0X)-So;8OYm1o_ZS! zYXmX={S!FH2R%S z3;{p;hem+d#|nRt^@fi6_Y>~FoltgVheQT#AdVan|My*vF!COWKJ@RKBb0MMRKGvu zEP|K!=r0WWK>G(-QbC~KPl)_>LPNy7QCy6hk?IumUxq#UlU=OJe>{Ym@plQ}|0Ij= z$nPh5X?{D=VZnF-+7_(xi(Hk({$v-`A7YLR{9OVcx&I)mmzwH#vTA-i!CM^;Zf|@j zcIX!kI|TiMU3!0r`QtIM-z6~or}iZ&2mY=YY`>j26EFS^24jYTk3#-c*``0)MgNDG z?@~d3S6JUa$hypO=y$RfemfC3CjsSx%r^1zn*FP?ys$smb@NX#Yc>9E6{gI8kY!B; z{+%r2-%do|ZwoX>$it}B82?q-|L2XB@ZkT2hraCm&qMs{8v%#4CntD>wm`jcj5M5?)`5X{hzV^ueAQJQ2xD4d-GqR z{4W4<=)XewA6P69{3ojQ|DBpu`A_&`@elYz^8YvR$A9_KfBDk?b@>wS@-xK#-gb@S zL=86*UcIEXzYv4ox`95>LHc9&FJkLDx4#=&Es@)M`dprJ71iEQxNOv>GlVH7wkL&z zs#Gzq82U_@t_Qon(|o#+5FGhM6&X;I=F%bUgI(wOfgfXc74J~)KVB#qb`!jX zII?+8axpVLJ5IeX~m{7Fto{KV`-%9SMdWS+G59>{DV`WBHD)orCM= zPptN=&3CqSSrV5!SdRv4OCaK(XAHGfU4$hzJ>n*Y;oJ$I_3?%)4F*R52s`?YZCDLW(TQn<`J4(9vu2X=P9JBvS4qo#5aVw-!m^>9eQ&1%dKnnZx$+3~$4M zC_ZLw+O{uRP&1YbLX#{Hw{o#tIhfOw7t{XvV%D*!Ct>jm*JBQs$9$3*i!$vP+HQ#q zZMq{Cy>?heb|t}})Jt~X{?{XiuJMINDH-LA-MDb>;^f&hwU=l4!Vg`ghL-f5NLisB zH(z?82U7S12t95^1U)WwDo%x65abvBX|+VOBq)bX-}I``Yq0e`;wiPvpdYK zm#x>fwhsc}p47Vb@&FF^&LD*=)mnwp!C0V> zlj1ki^VZOE>#oF=+hF(fr$@yp9l@$=)GUXIiPHXAZOloE_iqe_!t^qz61Zq3w--iW z${4P$caK>h0u&<|%tK-jcT2a72Dih2W+ruqvKfehc<|Nx@MVC{l;(`%v8E+yJNK5y zkmoF_u47M^HR%B}&p8Z<*l=sWWvVVvw*`vtT)QCtnrfkm_d)L7&KQyB8M9wx;j@`+ z=5V$)L1*Z_w;2e}VIuFo>$WYn`VerQLgrV+qsO!NrAFDljz$vP6vR)P-E2Pl?F2u! zeN@1yb+bl<@}tn7uP!)%Qcn+%S)&hkr2UpB%Xo-S$`7i|_Q88lea$NqcmFX!I;B%* zi~NoYXzzKJq@=wa<&W&)w^U=y>kcHmjn@P5b9=w+hHycG>CDNoyk^QYy}>G<9ubHL z^1GVu!{%=_gL>c;Rp4QiitPc*Z*+wLUS#fp8Y6`X<@d?;_)1i1o6|xle)pTzMP%xY zo>17=*HjmzCO2IsR(Im&DP1jPi4#BhYI!)|`icEV1YW4v5gACw(Hri3?L(Dv7L}JP$biAKp2sx! zAOLB+&d?<7a+EuDSMv>p+xV;>&bq5Tkp4Ao@V8pebk~ROWOyChC&C)pONwM!NJ#3(P6r#NwUf|nlKk0sv-=t4uv1Q^Uo78DlS>kI!V!Yz`!AZ zChgjToEnHKmyUioV4e*kFs27(c22qPCmY~M?{Hws2b=!>V9uH8bkB`}*5xT}gV)P+ zKh%>7k~^FFQq&i-a%0H*ABC%01f>O#&fkKBCLX^_)#is#4t~(+zL$+Ws62r$!y>cY ze%$*%g7+0O-tn-c(hl~o`MsnVL>_{y8@oR@80E|3|5@?CZm48y`6Am-Th8$~B{oI! zn%dE*r5+Ciw@|J(=badi<=P79^Qaugru!qi|&z2*P{xAq8N|Z zkw=SKc>#SJ*EiT|vmd1)w{;X;K|fg2_LJwyFXvFs8^=ye%8U>)pHSqQH)F7bmsYP& z7 z^T+Y5k6=?3kX^E{8y)(LIh05?c?ZNM+_y>}lQ9b)hAjA)Oyef#9UlGzu%aav?0f27?y+i+c@pvSEOGY_ft}7}o>M zYMxDoisglT^~w+DH9Nux*_dod8&`+>k0jMLTsp+ZBcdq ze8XyKkqw@)vp*fR*Tfb0_sP{t6(<%@f3o<80!@tL^XI^)scUYK*LQr*jE?R(o(A~TqP z_tAqF0nWT;7zbTluk{{xH{PCKDnUP`c=?t-y!cbB)N;1b;V%*BgRAplg!u#iaNh816+hG1 zU#^Ftita478LWTNspKv+euos5a40sFyy}QsIXOCTt0>uO$j+c0VYm7IMd|YhV<8-> z6j_O4ejaYRiCTy0N=3C^n?8S#ohp01H2d});q&$Uc!rO84+^Grw%0gDeCv9ufZ}46&KrY4w}fYCJ#cFJ z57Ha3Z(e4$8KSv#Jm077zDHI(yx?el#KxGeey@l)zb`|~yeST6*z7UOP#Lc{R8ziY z4!FZDZXhdTR%bpZ7I=m+jRBTZO&~65O}MxB-Qq74_b%QD!(*zY{f)*&6P93;^0g-m z4;?P)K2ezQO@_qPTa>R+GEn8Mhr9q0bQB^4Ai4W4oaqg3-N`2Es)n;q?A(Uf z&ZeIH#edS|J_oKxR$D8^=IFj>s!8y^P5#b7BbzR z4@cw)SZjaly0}{B%pc3jka3~+&DZxc`-UE zvau|rXsH0nZzJdTE`(b2_|!|M5J+HTtU}pa{p5phut@4Pt?W{9L;5{2-~2 zXx|oNfaPZb7nq^L za*RhA5oB9)s+hKDYq{YRmJ3uYpK$MhVX?*zwQ%r*P3%Z8SODoL5R{;tra+lLysz^S zraasXu%NR+BrZ6EQ&%iV9;q7)0|xYZ0kQ+9gM%6*l`EYrbP(gP%V(qg&QM0r=n=_> z*>mn)9iapOkAe97PJt9kHB8erHNVQWt=rvp1W&!0LJzd?5p*y}sLg5Shx!D&X41g7 zw&+4!)umy%onvWtsqhrf>HE{+C*H-UCay0}*m{_U?sGo9Qj3LuJO%~Q$~H=X#@V9YoDBYbF`K-hDUT=|jJYxls^mz3Y6NZe~JGwI3-NNy9Vx9}3vW4oN_13(-1VhjV&4 z0!lN-xN1kS!C>GxBR?ax1G#1LFR(Kv8lGB$XBPajYCQP>udEV_j}vJSti$S%q-kxj;Jby+1% zAdu_V1Z+CU7nvu$rUZiKWkV2D9X6D?&^^iG0yxTKsKCg|A^=`tmUY-E**-!~RmlR6Hg7pDW?ZfGfr<@3j=LJ)40S< zOR~@8YI6DV#4#4Dh{=_`1*cL@k1r1DOKn(W2B(SdO{g6cQz0YQTI>Zr$Ft$NzmXX+_>miQ%eNNj@g?JI7Mn7ub;1kQfF4@DhQ z6@(60YQV?yd%Ke8_*T9XJZg-t<=CRrwM;x`acsy)!{9PpO@}}S&R)^UtF?G|Yb@Pz ziaLoNQK=AQj4jutbKg&ShWZG?XfFy3)ki62)#}K}%Upe7%5m|nG3PyX8`V(~s}2IM z=Oh?UL$nQttK!a`7#%H)I6WGsuY;3o=Xw~fNWh}-9Q^7j9x7?S*I@X9 zT{|x*q9CKJxV+w)nmOGgI{;5O#mTSz+Sl<#up^u~TsyrhUE1bWYl#V@a5sx5*3Fq?*|8(`nlCvXzi$zN4IEeZ+ulx z3#hP8S^UcrEtdC!(79FOq&n3N|G@VlzWJ>UbUt+I(M{0ULj#D#Q?`vMHh~zHlym`=?C)5My>=UbCbiQ z5z*)Rs873(8@`SW*&@bw&GLeZpx0CG$QZx%RWRwktW6c+CjMjg1KqtQobR$%zl8c@*J`SH@&n5?aun z*JLXfDK!ZXvZA*Q5X(eqoh6Kby{p z4_cwsp0O(YBx(7tdT#VT9srP5B&* zPN^LMg51)Lr~zt82Z*ZcW4ZyDRg9&f_D^Zn%h$9 z1J|n2^^X9#>yzchkZ;mhtbwGvJY$kP={nX#5%j*{7Vi zd#d0n5S)VoJ=S7n4OJ!VTdb3m^6UdM`~&;;8@&{^sv?w#pa~^NlVI6rxDPs=z-2ii zt`&O0K1`+T%`N+nD{e24n7^* zw_IC5HAv{AI|~>m%d2?OJOW7Dn5-wgbZJ&d1Kew~&&xO{rcE{YHN$Ew3+_wJc%o6i z5L7Xegh)@EGR>^1voUG(5rs(~2#z|slLr{|PrR$dGFDxFCfhuHf zsMu1tN&UE(mggzh9Ra#=VfHd75=g79crVOPr=X5>!+H6{~1Qo&4!lg{*d1n3TE!E zdc_UQa`y^Ow#EIPEbCV7rHG*@MPtM)THkpsJxE)yN&)%8<(w>%h#4YT3{ziiZ&D-5 z$nLLU*UbO9D5g5b^P#D0M~$FfqFu?lU60$kDxA;slCqESxD83wCd=Lsdnc=)VS_rLZF!3~Zu( z>#Gg%3e3(LVdBDi;QVq@El%;NE&&%v_}&GV>e!Pa?4YKDKf}-QiE#`y;VH#;Eixeb z&MAs^C|`>^dE?@;nGu20_VD9K^n15@dyYr;SIX}i3oo$BP8t5?rN#(#B)@eVl9>2z z8t0FjTs1n%lCUR%h=Zp_xfs`F!rvv6oePNxCkrU8pP;~3LaGhhYjvAvwekX4C4#bS zm!hs-?{9?*m2YGdhZKk>R|(6XGYOn}miKZak6f$s+V`-f+m(o3`Gzm|||@(oX)xj1G@w7%&M*k56+Vj?CSAKTO07#rl9^@GKhUnL5O=Y2{PGM)!%sJa!WeU=PansrS32pt z294Mm)I1#u-ne0cwmG#!^O6Y2Rg?yG(8s^mtiX3g=cEnGrwuWq_j_lHfaab9a?&Eb z*?r`BtV|l$-b&i)5e`Ma;h_O9+>isB2TRhAN-wu7TON;-n4RxF_WjDGT4cjdj&UV4 zR$_a;@T@5IB_)~`bfh(2c1M)aM*P)~^B^*Uz-g}Y4T$H(wD#|2pM|QVqX~j*1l;WX z${=aKgwInC1ds#vRNgxWGs0BC_207IGwjkQDW8ev0x;40c0*TV`o@_tcFVhv=bcT9 zS>Nh-SiaN?B#mduV_utkbo5)u1OQ06kkw`H5nOwT)BK30gYaUVtNm81=^b}s2oJPZ z=*o}_WBB9KjEG3>Z~Yd6?gz8iBa=8^j$L*g=XzPVd$yaqW4%2!AfRu{lsqn(QvVq) ziX~YLk`iY%s-`pUV4S`v@W-B@t{;K?_4)8#!?yDdn&XESCa^^J^I?{Z)&?CaqLMhn zISP&n$*NV01-Q_By+fLze{Cp$!tF${nzyDY?W|aSCi(AMz-0Y0`N=ILV}RI!?kWG$ z*#x2okF&vZtWH$QD%o50hg)%@)*bDt+nM%LaL2F%tyB^JBuR)mE4ntU@P$@#RyZY< z(^9;x>i5BICt3HpJnocnm9>jF@WwS(GH#glP5eqSYEl51fErCijRYj3=KNu|Z4-uf zhZgwGoJouVvJ&h-BOBcR3rEvJLc&WMTYHDf&puarIT{~y_^Q>)RFuVQo4TnSm}575 zKC-hdB_BL28rlW$98p~S#kmowLI7BKK*k&&(PXS*_5$%=lNEJHAX;s{ef)w=JWwt+ z*V&`!kcsE)>P7sw*{w@T>_&MB7XF48WRO{TmMWDK7LTr{iQlHomFz8kM0bYs=qv5m zTULz8E@MO!SE{EoDlqGlkuzzimjv9?RH;tmQcnFizd7>A-~2hO>vh_CtBG`DoB4*) zyLToJV+5S$*D0~lH+GDl;aaw+c)-fG8`?|*BG&wW1Y# z6K?|@`Em+&*j8hF!Z3oTMf2|ehGiWQk)(C%{`^rJqHGNpy z;wz}lmitn~m^`9>34?wrIkx9W*6nP-q{s>&rR{gWkC6;z-p@dzT7l3>rImn|6B28v8B%x}1FOu;ukdCV8xoj&h>_^@~3KpJWdgTCR}MHE;& zSk5sp+-2U(ejFn!{y&uPRnYQ;L_OB&=Aus}Ks?d4SzRa2e|aXuq~Cn{-RGh}&SkQk z+Pw}SqJi^hj{^uC6S{Tq4w+Oi=~qfvp8Vdl?dTZizi-K3f8aEmUMPg*j;16glpfE| z7RBZnC=l!L!#MT%q6#3#KZz!nnrp*HHbm3Ws~gqP4=8<)|9zSlsv_&xvQtyCV$|$L zerW+We-9-%kXI%K`WlpQ0hfwWhiBbRcK89Y=wGOF?gF%Fm5?u3L>dWU#*+p-M`Wuf zg&}okSe4B|-J9$AJF!Y^8mgh-UtltMNu*^_O76@9#MGS|0PN{eBkOnO>XTr9>Gg?* z`a1_NF;NU&A9pnqWyaS z+dy?BFB5Qe_aiSDYyJzUs4oX?n*83^O}a&JbFLqI9bU}h@1k+of9+!BlQ!lK^}}sH zfWRM3kejUL(Fv#`NcD8H9=TuLtLs{g|14UQ_1!g$({;QcQZwFlQ?_)ANXE^h>H2R1 z)$YHorPmyKWDzHHz`RqKdOZ*}oyaxo1kP7-o{XZ#xmi;{qvn`@n}=P8%CP|MU!NE& zh-@QSkbNovIHhJ&y;Z2(OJ~rW!SybbnZll!CLDtR6a33a<5r^l+?Gn zj6kR7k_IgLNe*j+K(H9}9@sUT#5P)W=#YOs0ThWdOgt0aQ%tw5cXI$!7%{=?Ag7A+cWj0%989JB+^29}&0k;MGNmf&za=Uu>Ho>C zn!x#>l5rS~DD*Mf(909sN&IphxFIRIQ!A%KjsE?5Ky9uPP=QoUg z+Wjp`rz(d-y`J&&o$U|{ICG>=6X`|RnPI@^{M*UOi4t!lHE9pT`Ip`yNUC!dW23kP zrZ|AhV}ya0KuM~Q>ZQ5F&*`+C4I3w_4b5qBSVbO9&%a@5Rthj)ApzARBeHBe8$7@( zgt16R_-3x-dBFL616mu(GCI^4^gfK*oLmyntnSp=FqSKn#O8lJ(#HjzvdjPDHQi{O zYhT28Xt*UGw&7+)S!xUS+2N{eYL+?&EYg`RE^7oGq3Y-M2Rkf}%y_PQg0Z&t=#+2BgVzZya2t+GCQ9(>mNG!^} zSalv9?005_^~VKQmIn(2law+B>;@OUS7cHR$4$^9ZYM`3I4eh?ZRajx{^k-gJ^6kL z;BTW+1dL7qXh9FZ>20QE$HxHLP~M>6l{Wcs2(p)YqJ4z^o_`FjWg(BmfEI3Ve*!;P z%k6U?8}R*B6xuG}oj?K@$a|txZpNa7roK0&DPgrW@lU{Axiy?9%AnxWbf2qHO8Zm} zCy;?MNoS{q<(}T03t( zeHW>CWf^??Scq7loZjeyUxo9FG_L`jQF+fKX&=q3qK0Z6&U<5F7|~MJ#ukz^8wFKe zS-*PehN50k&AfphxZMN$RqQjR&fY;!2Qj8o8&h2-?RHMJ@2ZXi zeGj!~=l7CAn6c(Z$J0>u{w_d2r190`vy6!AuN>DNk`l425>93zT_rh-al-nb(pv2L z7?bIn_f*z-DXQvaZ24)Ycaq{&#Z^{T^Q&qSO>2e5 z^?GyF(Szl785e+ANYb|VVx(%C!V=!YX#tQT_R1MpWA90guFspX`R@smsUK``@rxP8 zc{%QWAtMjV7r&Zgj?aEhYZP$pEGfd(9W|LpuWUM`>URAg-i=8}aQ8b((S>$2xDyy%9AdoY3BYv#RO>w# zg^XlYicC_t&zYy4XEd(O1qVieIpKK7ozRgwu1ylUDkddzlS7|8jKlhfT%Pd<0w4Ii zVcPv-*I1cVIpK@g!YqXaxBa{Vps<{1^5ynR!MPm13S>EL>q9a;?ovS9>A3E!UcUtZ z1rrTDZm%8-Ga>>9P^BWZlOo$!wNP!JZi2b0=!AyHRJHZLQ*eSX*(G(xm)GuwVw_|! zXyaz}zq)zU>!Vd^fYB645xJW(kK*;tE!&`(G_8V{GszAB{D24GEHW}e1<@W%=!|rXb z_b(SrbK2s`t!=H<-t?FIBx)QEy`jH*)bbLt9$9A~BB3)Pg$(w|CFwMg^e0Fj52i?l zfZh76z2ag3riZ%{kp~ls(k7eI0|IdYf;LnU8>PMi$@CX7jpnIQUU5774nA`$RZ9T! ztpXM%>JsuB2wEJ95;ZHy&gP2h>bB^qx88l&%uTGKf#&W5t=&Feo~hAX+%r#5_xN9U1YKB?6bz&)2gPrV0f zqOCNgu5_H-ZC4QhUA+g)xI2ux9lSI(B~;oH!JPNro;GcBJ)@nTkK}|`%gS8u^LFr* zV4O}-5&BwUDTKeedeBU(ay>AftK2&VS&P2Y$Q+FV{i1N{>GoB10in zu`xc_0pBYzyYHJkFL${&(|Qr_43VDnu4*+u#d#m?kZlV*`%RfQ(e>+lvtTOXL7p*K zh`mt`YwS3Sz9lv#ky~`{t+Ca?1sVO33-~O*k@yhiN+3h7{o%}Ur;jlrJ{<|aG`CxF zSYI!h{u?^L`y}*x@~}3(O?bD~)8ng^rNp{RbNl;;Bk_(?9LXsARn}FHks%qs4_Ndz z*RxD@pd$vQff}-xcc3R20ijPmOXR-8Gst_I$L&W%05DX@^9@+a@ZCH z2`+dWOgxzFQD_{I3~Y0@zdp6vnTFy>Lakv*)w1sXl1L$9P13`Eob8v(0F z#Uk+MU~xhD10XYaGQ-|x^7?R<8-oU(5mEfyd@^bgpEaFv(fgSKvIk2;naPDIQg<2@ z_8&N=bBG@3(!B2>qdYmM#A&&g{puu7rV9q1=u2%$!5QRdm`G64I!c}ImTn%6m!&ip zgZK?YbHPhSHLKYK4;pWm^ z@DD(0=+eVeeWR3%(umo!N^!;_Ym`y7U#fHmo@agg3{x(x>`z$AmYE3n2(GcDAdd1Z zo1>tl9SIHD23IGNi8zjx9rvvZ?!?41zPc=5$$P>Y2r(z`fJJL3IpT8eT~T+o!0)rV zTifaFOInF!&qkEkf-)fKz-c(igdM$SZz{R#Um3? z0TKW}d83IE?f|lN*#HS)Ky~h4KH9Ju>r2V2c9Ui7JYUYE>)27lB#!a~%f!A`P9>4r z4ZK;G7!vZ083Ox2NDc;O?74wOjRS!8t`5j68SyA3TwO(^((Ai~u<#r1_qAP}-E%BI zRJDuB_+)c%2=81Cah?m1+{zl75?R|ZM^Ax9nnBQpmE;LGa>ej!?e6}9TmR~Enq1~U zIAE{pf$WkodJqHu>U-$gCB6yIq59{t#!~krj|&Hl&QF8z^w~@W`|=&!N~MgGT*ASe z`$IYB@d@!Q-(9|HJ*jF2g}k{hL^LC(xP_F(QC{&#RarH`e)<$Jr_g>~OCOYBn~)nB zTVp0^3+i^QELgh&mEHHsNZpb9HGhXtNTFroS#$Di0y1p6{`Y{86K-ea2VI31niMcA zZHIFs_h>x5tHd3TX^JLW>J}49i|{vB`f7k>26udQ{Nfj+cdif=h7$M?0`97yR2RS; zYc6HMLk?M0!>N)X4fii_LZ`lyo!kx#uxfWnoMcHz7+PPisGQvHoxQjd9OdI@g1h9q zpVtC|iuJmY@8Ufa6+>a48UfEacTzy|@}lL7pCwmEkIs1D*JHqPi}r=rPZu+041%ej zgBib4Y8k)qBR|$T^e!Ad!}tAXnKzeXG$=$@E918R^6xREpLO0q1Bap{@WptXic3@% z<`RKABjuzAWfuYXwxQ=Oyu$a()G9d>^+4(tl~lvy+1<0*BR$wHtg18s5Q)vkDw!u; zSZXCy@&4FK$tea)0YKMl2_ta$lozgQ5vI%*a|qaR0>&!%1d*O2NuSew3#0cqe(XB@ zoDK{|JO+1#xVrRAd2(&8BuQo}0(_^8@&A|vJaiS-7%oE07DNUmpswKFqB{TyC8{o| z0!;k}+xl?>VqUZ!EBY9yD$?D0qW56G3={LhOhJ-&37p4!DTx*3w?MJ}@2D~5xBGg| zz5p85lXy9){MS;y=@2BLX?dc=k|GGe?uCHCqTfhkJh83&6fh4!MjERW83iqaX`s<( zfLAgCz&Rj10vHqJATZed%Ryj_Ukd34+)1&kP~sntTzEt1+}n1P^1A>yj6=U7D36Xp zdmTu@%Xo{CA%bLt)T=*F0y7k*=qcwyFSq^h)7`dzFllQc8tdNt)K~Q>0r!odmW2KD z_%y&=rV|)+uoa8VBw+3TVp-HcXTo7NHB14BloyeOFG2t;B)$&#)wXQ?|UJE48vGhX&(`f zw*Or-OgI~JsH&#RX~)}hqn5nujg%)EfU3anWCtab{7-S`fSw)eyC!_SyGdD?=cJha zrJ}@4;~|0|kzAPmHZ{KdiZA9O^r>4D_PSf4U91Yb!6N#CiG{`}wKZ z7DqRAe*_Z`MM!sEV1DQ1W;GQo`2{e_lHu=Ox>QiSsoz1AT$g>nJOOBa`t3|_zybb? z;2sH=mk#{&gfMowQq-3`uJld=_m4>p0>g)JCByI4josEaV0$+8052fLF3ew)JoH8Ir)ClMMi3REcqtx+Qlq%j18LjmgR-n;Z_Z{wd+XM- z9|6b_q9|Q9*Ygx3ufB=^at`eJW)2v*ZcORaYpyY9QA{|p=|F`+FlodK@(u@H{Y_`VRU%ZG1dkc7mRD6K769D5Lm+Pn_5v4TmZVi zCP>e=Cwpy|+(!#R-K&--1wfdjk zzsW{$2{10=_$ddd8&H5(dP<3;%0P1y6W-*`-#DyZl@~R`ehj5xdn(eHrID+ni*jdb6 zb}jdZ>{cnMx%r3j&)4a+SDCbX)TInMOsR;CXILA*eSJc3OT+$T%hnwNakumdJ|xU! zr{Yb3bjV%E@VI6CSA!zLb82}I#G3K39ZT?@5dlC{%r80aB1BH{U&8~7i()| zNn&`67PA?;;1+R@GL|<3JenP3dW2}4>cQjRdt&yA3_V7r^CvkDG2X>%=Sch33ll|> z*dnBdYUR=)l*|GV(48)~X`!KIcCRZ4oq+nRr=aCR>ieWw1E6;@lTwfEv%o1t?57Lv zj1}!6RWg#+pjcF-9sv4d<#&LcxBYMcZBzcHnRg2qSt~9eCoWICs< zy(vtggfV)NnA2`?ewoIoU1qy;HS%K8)`7m{9FiP*Clp3m_dIsU5h$zlV)MSXJ{S1P z$|ai5$zpAi?mazUGVfJ35BsqsQD==E1|?Y_@&Xgb0Q@7Dw2>0C420a9e-GzefoKdl z#YTo`rsjXD4m9e(>{%!JeL2yt2K|sRSzWCH)Ra9#Kc6Q6Zer_<1Hkqw4 zVJWR+rM(A15lRz{M#aqEJF`Z&J6C6B5qF{ZNm4Nu?QH@qndAY^8ko$RfK8G5hVRu7 zAo^%(J|ZaHCo)-OuZ)q@n7bkIJ$fOwK5+6A7aC}wt+~koi**@*-+%mP(zX=;!CF*(O89>|~KauWK1N57FNy}rQME#xZSgTZez z!Y8xo=SPpv+o9nP$TgO-nQ;ItW%@Azd6t#}M~1fX_)tN6gZ|#;-Ioq>+HXo?9%CK9 z1;771Q#=!j5jAnGY#WoA`)W#-|1|qk%zN}r0qtECvPh}6iCjHUem(7n2@#rfpQcz? zV^9jy?&$ul0rU#ZN+_B(JmU2-yCeoiHUs6`fnp5YAYsn{B3Z?PEH!syeamq(6K~Ic8(#6~&Wq|o zsQc@k2rp-kZRLHYX&7!f)IL!kZ0-hQU+Up}w-^!yzY)>og9Vmj0Ax1_NUdO>RCjvD zcRIuAyub!d2k=cC^G?Epb%e|YR-g(jVb7@Hcem`>e8>=Y8DG}&*Y&$!UM4hcTIlS= z%1o72S6)NtUQr;n*DR*R0EnPy_RRGGw8t8d7;sSv`9pqo4SUzTQXV>YDEHy|RODbVwk8!+ix6Ds8-0{e7$SNC>y-umh$`sIBp zFVJfZiPCIX-_UCB`Et#}Y_I0PzuN%5Y{kH~Si6qQbRzi|Hjprv@Z0sw*yTr8!nT*o z?R-g2V!>mRlDLEP&6XN8?}$>JJu zZZT5^MJ5^O{Z;Au-5Mj0Js19E5h7Q%(zw4_**iJ%j73qcJ$sfChn%KYy6a~HEro*(iUb>V*};OB5L)8dsv*W^m6gT2jA$V_~ZF3taG@5=w7?85$x z(V)gs@)!{+Q6W>dvQEom2`y5RZL*}0A+nS)Gqj65BtocEsHCY-G&3b+CxszKwjr{O zWh^uEo*TVS{Q>Xi^FE)Ce(*#0eV_X}_c`Y}-|ITp_d6Iyiwo}!W7wNV@LF@Y8gCkq zlJ%U%^%}N?wof&<&!sEc^w^Hwc-dJo=D5<%!sq$^F|)C5^W4R z*1BsNt8+qM$P<3-^o!RxUvuNTs?PC}=k|_wZt}U8JFUzf5_JYrEPf_*juREYI+2hC z^ME8CVdo_ChKcgx#a=YqV@A{`K3I-(c_gkkswL}sJN}!0G-YMP_}O6sk@J9un=&tP zceH8W5xcY z;x@b9kewqQw5v%C;561bGkf--R*rJg!|&a+CY!ph1GIDwFH>-AZeI<+ohTdgv-%)= z_pD!&S~6L9ox{s6M3~JG03O>3F#tT2N9Gwn%{2v?YfkB!J=SA6 zB)@3cFTAnKqZ4QO;@W%hz_iSp2HdAn(q$$EENS;a%uJ8!c-ha{77x`54W68db5W&! zj=+%K^a!Om3nZa8Wz47!pa{Wfv^jngF*s4*dV1?lX2ZArF73wlhQW;+O`#Ad)Vx`ZI5+f< z%DK*!D)F&_KkP5`Hz)4a5yg$BGcw-V>52O#r`@RUS4p`K(xRbu-aC{U4IgZ>-v+p$ zcl;*@Lx_PI&uEWDn+;;JtyBGbqTJIEVDxq^%f&(nV_^56vco5AAM8;+_Ow+d34G-?v8m}43|9tE`@nmf$ zMM|~ONPInV6_nEkDF!c@t_H*YJ8qnDe~lkgfo-a-$Xte+sZ>DliRRZRYZ;}SXy786ajVs{(oGNh~AA0Nu#C=Dkw+vf?1ul zbnZyqT=Gl5z%#Z`DD1zJW}udyt1dacK6GKpf%;e|(NP$hx<@FI8RX2$)b3 zb?32UxYG2910Cy(>Hu0@El0VR^GuG=)ylQ5*mboy)K%iC#bNSdS1uEO4dXAKGv$`* zBYDHtq%6u4Cgr}ezxK&j*1n)NwWW5?vN}V1vuucgo_=Oq)=NRlRh`p7+UNxC@wF?> z?}+tLyBSYl%JvS*`~c;u;-X(Y`X#PlcY;3njGI<}xa(cOkf?!c$I7!E}OgoiiKQ)auzX*oU`J zZsy-w$@NHv7KxDq(*YG!HBzxjVBrhRfW3aM{LpXtFF*_r z^#G|rNNXSlq-zkuSTq)mTTh0g6s53Zq;A#4cg)viT}5+hVDsfuSIH=7?f?q(2biP? z_(=%x8X+a;#gyGI0&fs9bAf#B1_M_FBtUIeq8ZqG&6dR&C{F(>SF~B6G6Tl+vUxcO zMFc<|5`adHq3;zyps`y>-SBeTMWgQv%-cG07rtddq~c#jvGOXAM7M@3iJMWuXv`;0 z7i}Fz9b6DV_ymK-NfEHaG5>(0vY6$HA=t5Bsuzp4hI#<~6^H~7lG=~_Ac1kp^sQJe>(|WfeRyq5td5eKr2JQOg<*`SC)0rR;COPT3Y(l z9myZEVJ6SPK}P@eBToid$7x~jxHljwJYVKmzRz7ks*!zx8L?n?uQoFK{RF%Hz@4cm zFo08vS*O7?z)BauwT27R)w{&&KsA!c3gD76rGHkfHZY5KAq;2K7>(vyC0o6{`3)#&bYA2aOg+^zNK-d(WE5*KKbEM?um+v+Jzx zd>k!+!np{nIL>rKc_;H&Tf5G+I!=8)6LeRC209p)R1g_*2j>VUVB1Jl-0R>bxGepr$&jn0 z=TY4t6)BNf&)X5z)`37q2Z8R>MO0_8vNq4e#(!OoyS1SO>_%LMYE@BI$Tj!{Xc|5j zO=lpQ-Kq|oOu-<7FuCz4trM`jwZ>-PJ9V_fwgUVrrf~Z0EX5wa7lbM}oL3(>1!ooxE16X*0fbQkEigZO#0R*SF(pMWV)9jWkc{)fO%U^A5`4ZZa8!nL{?P zJHFc-F%oKs-o7NaOI;+%{pyv_yXhc#*9^oCUe99VW{!ra8P8HyYj)$fgatq z6YTbu*FbK~NyKPD@hMHTqdLg=)bn6Kf$$J;7q|pR3rE9U=c?qf?3oTp;+92w=8J8O zwwRM3YH5+_qc&x;rt*a@R@|X|HZ1L(_?pilaPkN`w^!q{cwno2f|}#e+kD`jNsGrpO+$yp@|%>jODmOX;&g!M4-6rd1^erj z-`+xQxc+ozpD-G#-Vidkn%|VvKm4N>F*o7)LmGAQBZ<+zJz(#6$z+Nu z{?&9eQUaCO4N5Pd?PQ8T3NjcGN>;oQjZ*-cT=UCoHR2Kl83RNo--Fnqygg=+uOHfYN2m4>*Wb8FF$;p$u>2#H^d@Fl+RsGIS$A)ioU#NW98M-b z)g^r_vp3}IVDYy}?;Bcl_D3mlW8cfte$amAdTjHfpa#PP_JA2bgXhJj0hH9Jaa&!Z zG6+l>vBd{$V^>e<2k!4b3KGYbR5S+tX%k}d*b@$q*|lGv*{kcr_k}E(cR5qfVwA3p z);~^DSKiOAaKcVW%771FXNt7eB_?W6G^jI=s_}#TVv>2yLhF=_4?JUaoe0b*&IkuX zQcAG_uibCaCILaYSNnEYTdlg8Cxk>gCbE_X&mwNN;Hy(a`oh-Fn|z8_)hOjZ>0A`m zGwQ*!zRd(54?^-_y}FruHHJO}nvS{0mc6Q0929a}UwY#`X&Ch}WQ*N9G=UCQ+UE7h zP7pLaJLE;9=;wzA8;``3IxLT!-+F^F!0Df{VphLa}K5xRkS@ z+4%e-x~0K=WCdhSWVe}s39W$m^zCs70CeC?>r=K!ihp~LP8PVPrzfYk|JD2hoDU?s zAuCo^WKQ8jwVR7!DRg^M>;_5d%#2r?``8Jca+9(xiDLRwB2bh~0=ie5RJ2QNk3}1g z3$msqfh^F%)Lj?3k7`H*>65Gq=g(4A-4Spy9PR5oZNa)vY(4RmIY`JBf*{Jc#CR~Se zWRszUfwkbWWuqDQ?`MA5lJuzD?f%XJ;)mEN0;}ypt(N*yAyh8 z_LtXWjIKEaQ%$_c&0YJAkan_Z?p?o`be^l^j@b|A_K2c!I8&5dlHv5{yR!p49^KXX zr+>vWW*ff>V{Ij>MUt}o;3Us>zBis)o@Ep)?jx6%CpCz0ZYZPIs9foKHoG0gL+30(6 z@7%4O^n#q&kH53+6jVtPg9jx!H;H%E@fVm^X0b-W)e}ir1x}I?GB2bD&tZ3H7vG@` z7zf+#q~+ypPJmvL?1@{^EM9Vidk>9oK1U02&Y!8b63^X_7qS=qB60dEy5M@XGp(!c z*_^tQtxwW7`>l>M`MtFs$(J>rJ0e8W6=KiWi#RybY=#Ub>c-6zhb)>6S9V1>v&-oG zHqHbq^5%pnGe&ifCTFzPNY8Mkb0MDxuq@U$HC!?cHnE zA)WADy0bN-JWAPTU&e#VTlmzF-s{t@nQ+7l0pa&Gy5z2xD~x&lwUxf>@n!9rQVuA^1PwN#s-u#taG zcj+2^?f8DmiewT)wl!wuPq$vWJjK0yc_hv`IP^TDSU2<(C$y1u?kimeYpkW;A{hOI z+;(`IYq~-oHIp#YcDL<~{DIO_SGD#&lSSv9FT<}sp4#*Ao@-BEbzFZovoUnr7m)0S zt;>e`0Z z+QP)scGyuz$2A+iQgcRM_7u)CeB2H+(wF0w#nrVW^3QO4R(SP99x!xlr_Ax9O7Wa$ z#730QQ(@2LLEK`-!H6?noL;JSUzCNatQB*RsU}Z*9m;KG4io)~tfSGMbgUMbEm4Yn zVP0v*Fa0OKRrZXFr>W`^y4&xqOd&G8PCrz;p&(4yvm?wG#c$nruXL~faTVHZOQKZGgJcVTd`d&mO#4ap`sB8rt%+t)HmbWGVV`<$Dt*z61C%S_m(whg?Q& zOk?-k!gXtqVhZbvg+7juUs#K&sV7`2Zu9(J;F9amUPoJzH~JWi)L;>L$ir{$rPqj# z4^KnRZb-u~fcB-D&u_~nPDMIQ;iJQF)<*n~aXr&azTe@k%|mV6A|1+e&vf`x+^QRP z8ww^24os~Zc{XflKeS`w;Lfp})|nvMNmWu;A+A_9f~}xb%oNqe;et@!ywbGMpVVnK zp^Y{`eftxvPK~%(`K^zMBM#F)6?m`uMQOH`%Ya+Bij)ZFN(;6L(c^2To;o^c5W~Kg z@Fty`R=4v%NxGk9vMPSGrEMK9>PihO85z0OTG2WBl@eV1V`Q;QvOelpqMuLFUabX7 zww=H-?CCBW(ug}?=wQU|OPDoHCXPiq$J2^NT=-GD?1_zqX~dg5hr|AoWi)B$3IHbu zh75*4VZfhy*ltB(G>!yEfMG68|=Y`nXZzcaNG+`nQ=FWv>pI#O2EGA#^zZ z9&|BoVYkcay>us`@G zes%dBFQQie2`&9Z1b@S%tN#G7I!gc++K&GGU`tpW#8lWnXV_AN^j{11y0tw=oEdF$ V`dimhXJFu;`QQ8Z=Iq9W{}23iG`|1< literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-750x1334.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-750x1334.png new file mode 100644 index 0000000000000000000000000000000000000000..720a857adc354912ea52808ad44e83c059616d90 GIT binary patch literal 45375 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 z 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/browserconfig.xml b/docs/themes/hugo-geekdoc/static/favicon/browserconfig.xml new file mode 100644 index 000000000..3bdb582ca --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/favicon/browserconfig.xml @@ -0,0 +1,12 @@ + + + + + + + + + #efefef + + + \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/favicon/favicon-16x16.png b/docs/themes/hugo-geekdoc/static/favicon/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd6f540d539ae84ad13ae705a034040ca3c3172 GIT binary patch literal 616 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 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/themes/hugo-geekdoc/static/favicon/manifest.json b/docs/themes/hugo-geekdoc/static/favicon/manifest.json new file mode 100644 index 000000000..aada2c128 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/favicon/manifest.json @@ -0,0 +1,69 @@ +{ + "name": null, + "short_name": null, + "description": null, + "dir": "auto", + "lang": "en-US", + "display": "standalone", + "orientation": "any", + "scope": "", + "start_url": "/?homescreen=1", + "background_color": "#efefef", + "theme_color": "#efefef", + "icons": [ + { + "src": "/favicon/android-chrome-36x36.png", + "sizes": "36x36", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-48x48.png", + "sizes": "48x48", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "any" + }, + { + "src": "/favicon/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + } + ] +} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/favicon/mstile-144x144.png b/docs/themes/hugo-geekdoc/static/favicon/mstile-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e648100af29fa964ac9e3423d71e3b8edec416 GIT binary patch literal 4506 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 bOCycc<8$wamdxL0%LRRHV?^~`hiCr-_3?$D literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/mstile-150x150.png b/docs/themes/hugo-geekdoc/static/favicon/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..8a50201dac13c3109f14395d1e366dcff49ac5a1 GIT binary patch literal 4412 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/mstile-310x150.png b/docs/themes/hugo-geekdoc/static/favicon/mstile-310x150.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f80ff083a393c4eca54cd2be359dd7cd322ee8 GIT binary patch literal 4257 zcmb_f`#;l-7ypn;cwBS)B2;coOXU_qGRiF$VdVZGo4Mqc+lVgAttXmWF3++WZF1d= z5Isx9sKvtOUW7(Prp@?z{)gwhUgz?|d7aleuXEn#bxy9^<%^QyD&hbDNIG1CTmb+9 zlYJX=P-I_ve5%{nS7I@jU~vF&;OoCE(4Kk)0RS@Y4iFoUn~&I42!atuZ6Gxzxw@f> z9j#t(nu8eIG4J%+VLJvB?XPN3uHHKS4kT4RS6y2qEuW zKZnO$@oD&TscnQ}`LlQE+qboEzrLASv@UHp>`qvAS+p8fF8yBQ@b;p@9|`Pd^B+;n zrVMW6#JLOtggb@Zbk(9KIn|kJ!=pO~8i-p@^wN9VHm9(Y0ZKT7(;OMnq^dsOMj)^~ zhaUcWAkJ>N=#qSm+?ds264%KmWp=%RFrQG4P{g@9)y+h$iN+o{JCCWrZ_i=pXB-1g zk+jfBT4)Z7zS|6c7UKt+mcwxf9mn}-?DYdLWo=4GYZZE6?50Eb?|+^?y5zk&ApW|6 z*i!H5J7=zqCi4;GY7IX$UO>&bZfuKDv0KqPnlAw-9!7`}eVP^(JBCsQiKOlMIle7$ zR_-Jo^+e$oCNV19h0vCZsiZUgYirimWd|i^^<=h)?W>~KIx5gUiR?A*uSW8C^~$N+-ru=ohClROR}5U+n;vj8@9I_GD3i}X{MXG6qyeEy#I2~)xjrj%1Y7X z6n#>We;JwR#3r;O_?Gi`1=UUmrP^D2yG0R0v0)l)xL1tAjfo*+5dT*4&vANG+%cC5 ztxZ8fZj&XVp(z<6AaI@UnU2i*jMOZ>S(xzhq>+*v>I2O;c+L$ji zT`F`_9AdWKrwSbg81!KG6pOZHO}0TbG&aB10g)yY-^y%T$2r8HCdD2YiS;m7g_7zV zHhPRAc6Hf8x*zL)j2T6|FtQL?l?*%#HmNzJNSX{V8My6ObGTv49v^>)@wwY*Aw{t| zpeiw|_o+inN-Hyd(2A3xOZ&Lk-FAreNXLeG_~Spu!rrDqhKj!9@Qk-=hZrZ`oz;SC z3=4tTCgc={rm0n<#8ihS=4#p4I6EPm-KHAJ9Pz$|xVBJe#{xh!s4VFSly|#%DF6De z2Y~}Qo(2)$a8-c@E<^B+FS}Mqh=CGW>t?ov=)8yRNT8%BL^$i^3!5TG>}YgT%ZJ0T1zJ7?*o-x;q}bSW^^hSI|)|c+;!2etr*)er~k% z?nG~cFT5KHW!}K}ENFCV-AtQ1=arvRSx_SNtxwhsz{}m3!>P(Gs}=|=lG-8!dJMDm zJC{zFAUne!{d`^?rO5_unpbLbmxYm#QMy*gdyS;XR_3_@>kMf97ZV0p(toMwSzW4B z(^d}sliA=Px?(lJliqN>O=eo!DYjA( zG;l8mzrA&WZk8wEGg(PI>#j+6wTR3^VoD0HIMFCI?siD5Zv~}h(V_(;9Nqrw!E3Vg zHbbEH4=A@dD7Ge2Y7neC5dP8n5rXRqHQ!vC!e`-37<{$XrzZD0{GdC9gdKQo@R5j3 zsjnn~Ksjt1NJw(1E~)hO>E`UHo~L19N0pt}0@lvI(-$8Ft;Re^5QPvej<}sN`Pqw=VT-|b;){;Zp%EO zA=@66%wB4-qiG}!SzCR2n)Js(-y`gh=v?w2fW(kox3kAioW+>KZ;wJTMPDnJB|RyZ zzHYX6R2P14E~~IEew?tEO&(>%mg`TZIU7Xmj-`>8nHXc7(F`-mE}N}AZ2}D0#;RxP z@j>C;6Q7x}{fkTSq~4D=(`Fnk;-RWi@>(#<@LW7ing0kjYTh?P!2h<2qDZV{iS}GL z;+^cT@$xTwk4R2|^RJg`Q&esQQ#r`=X}~9ENRl;=J*Xei55X zmIioV2e!VMb*BDlC_QW*57nP=*H>sab2op2_K{bKkh`g&xz+*z!CiDpxHDeu zpK2cpK0#!~j>CORY4n!|JTG0ngM2bMGK_|RTStdDlZfk4lr6iyfuY#YSET}h#{G#C zFB-qvJanZUg?B6D`iw}Yy%iME0j=swTe&ClfhNHgAQQh`A15RoDLU0OW|cZ2`{53+ z{;>CE+*Pq&H$>qfn9*?3+hk8|DLK&qADi7~FoS#wtWwhgD1Nr3pqXC5np z{P;*58>3q=sBMas$Dg)nyD!|Ky{O5n>6uabkP+4KAV}S$>+*Pt!}lMA=M!_Is9_M? z<_IoC&+WaWjB#dzCTRBwd6=XNi#UX^--y!SW?<*<83eb7ZV2o{-key0!z|Sc3qui# zk85&N&Of}5=|N0eMSf|OjyDlngyq#`M(Uhg(s#+y=&Ep?A)Izvj={DFIwAGkGVuZ) z8c=SvwgfXYZ;|xNyzhsR7^>7Y9b^=vrW}?we*7@?YxrrmS*kJsx~s?M-|>SQe@27S zd-eF<8Pk-#k58)>f6(fZpUsqv+@bj*qf}CLJ3{I)lVx9*a_|#x-49^z^2FS(4%LQe zoEv}Vo5p+D_j&f#A!FZLGRvYntEOdfcZt+1RxhZDh*->dtJ?7=p5AlGF3l4QHYE-P zXqC5Qpxw4)_kvARm@DU$!wYZ~O}^W!1eI?+bD`fPvRP7$S*S$vI%%GN^GVhgs%)@~8$(c7JAK=kyB~792SXfdK zjPd={0&3H+%tPl6PpnC*%tMlgZku$P!s^Mhi?Dk|x9YD#)9&H7U+}NF8i=9h z;s%Fyy{$~+{cYlS@K=W7cb8DX^#TO#u!ByXdl3-intd@S+K961qf9O3ZVW#>^Op{d zV7#6BO{TOixmSriWmnqHWuYb+Z}J7jCj}Tvx$``9Rm_r-Ni^lRyi99A_()f+MMYxP zLbuj-gt@Y$-*rhl59_OoC^S5}3?b=@?1C)gq%%Y^ZS9Yy$IS#+vKp^H!b=)edHg75 zCoAcpM_&JXy6rb^-NmAyk{aZF+e;$>pQwTg;aMfUTn6*h}q{`B$*s_D?#0c z{IIZFUe%@t$l_+S9j)J??Ag|)(tziA{QL%Fd4^|HB-$d?>CSBqO^&n|N*DD*5dA0` zrfquXC#soeluwpPUp)zb{@10auxytkjolUW&=@mcASQJ|?|o`XR(#X4!z$wO{eLhW2U zb_}50kJwFjmf6Z&XD)pSjgB4}d_{N|Ms!UIC`S-CXY8mh8P4D}N#Go{00nJM#NPdK#-8|_-z)IG-_XbPbcy(R0wqZogXr~*^bNJ9rs}!13U=X zYe#${r*iwlz$QpRvDbbH{fveIOTm{=1yY1!rISfwKgKt*0}Het2+}`9O6&`^9S0cx z<7wXmX<(DvlCy6_q*q$@w1~pD!Etto8%019p1Nqtcy&SD_i)GTh0;GQ9%VE#ra3OnL9zBYRfX;|=cc1jlAATnn zqyOiRfDVE^(<}A(n!C-wXc>x=xBc#xl#;}-EuIOI%G$cXL2abI*HH^}xqoTz{a(2B zLs1FF=nYjB?Xq9NynA}-{kw{r!3Vr6HT#cgqxX<|8$6qLD8qClft(hVU5WFNH*T$7 z&yda%0T7E1tY9TQy79|$7A9A&b85L*w{QuXH1_mJQe;qu4jh{HusdVLR)FEbI?6u< zqui`8CUzj9YzhD*uEf96qPrea$QZ86+60qQI_ntxZ(WT2 x_sjx2UutY{@fFek=ojA)b2cPlN5cz!`sFrn;qAX+9qcYc8ZQK9{U5OM74rZ9 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/mstile-310x310.png b/docs/themes/hugo-geekdoc/static/favicon/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..26074c1549be476de95b34270f7b21f0c6df544e GIT binary patch literal 10949 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 UqbBeD{@<6>RkW3>U%rF?AE=rO(*OVf literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/mstile-70x70.png b/docs/themes/hugo-geekdoc/static/favicon/mstile-70x70.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d47bda988932cf1cfeef105dd10882624800db GIT binary patch literal 2125 zcmV-T2(tHyP)@;?_@vd_lPK>4fK7B2`V z55^i${*G=WzW_d40-tqs;ifL5m}gVghJY{OO99Gm>{fB*1~lBDYxba4ih|Mse1q6% z$~$GLB~gk3!#f!;_Zcv%Z4)uiNEThlG;%3vtd@4iqrB}=*4A~A#Xgg@l|l^|kMcdL zZIe_C8c^;4<-aQ+*hp%ipklCACCt=C7X3`!$Kc=RFZJtVq#!d=xEpjKGZl5ZYzO%4 zbP5LjUPJMGz6gGJ3Me}XG(4&6B1`zQuK8C$`H}8^MG7*|omTp;6fmCdfZIma-+KYy z?oqbMqv6HH7KZf}to!vR4dE(C=c283DM%=Vdq_q^NI`CEL}U|w*NpWwm4Sgk^#dsF zZ-IuY5oMbfq;Sp&SACX(+%ARlxfEo%DcohL3R!Ll=Lads{di3?b`e~?YQ=o(1>wb2 z#unI*s5){EDj>0f(QXK`Buz2D!}2s<`)`qOAPwwx4pdCQzk?v$TC2$VL1_rGs8kX; zZ7fo z;pp$x2z5`;3Pm1(6SWH&EtTPI?AWOJP`=yTH#0Vrm>fb7qqxrs&)RIRxl_4M zOcqlx&V|}I20p(5D1SXW-O#0&^Ej&plxF?zjHX^BF z1Ua?VcGm3Z;$FLV(@MEgdi~m6XceQ+C{Wb18p7Q!h5Lnqf&n0Qz_EFjAg>e=`ChtW zu0%sp<&Zowl!$zZP-N^Tqf#b^x~UW}kj<6G08<7ODco(TQVbMf(*p(OvD!EWi7V~9 z2$wGgDCVp5`fz4~eM*l~a!^zUuAm$#FfCvYU?-dFbW_Eg2FmYEuN`f@r?ft$8wx%% zB5G7ip^TYCg37A-``uA*CIwJwf+=s>#js&!XVq2{(XPpTH0Zoi1Q|cO2Fj0S){*kV zbP5IMep}}AQ^Q6lJ5enKIbb@$&ZrUXXroUT6g{h#fl`bMoyo21nA%3XNdlRs1Rss^ z+=d`qF^)(knKJV!g}F~Rl(--$Wq`2~#(!K!&ROF^N-;($KS@EZE(A(k5|q@H_!?ZP zeI!{d^3u=5M-bFK6YpAIy8PBIwWUJ%gH>4mhNd)`LqF&o|Ykfyh;Vw?dEuXML zmQRw*T9D^#W<6>#3ulM%{@)Km{qAs2E^Y9F)y)U3+XXj?8FuU*YsT);VMPk^k`!dW zz4wVbu2B#?%C`Vz0Z_iZR+YgzSfcH=g=nsR7r$OX0m=`6&wc`*H*q%xP_A|~RAR8| zMg7rz9T&yY4TZxB*>FB4GnZet&up*d`+Hs#D%fX-D|0JY2irh;x7V__%nQ={j(xUh z-1#@4yxfgUu+BCPrR`#~*wNd$pmbnB*ACAC<@4G0m(T#d?zWnt&G~F2Q2t2*M(;be zk@#5%!ue8P6s)t&iMBm+eqJ%T7p6|cRHhiVF1E8;b9V2oXBDH{vrfQxm280SyCHfr zQ04;VpXI^W7Zq0NN_^+!w#@fzq1Sa1RGNwUDqU&dAq#uBqLM=vD;&DW##9!JPG&DD z9gH{dSPrk?Sk8*abTUv>&Su+nyjF#Q3GdZGu0E@h-BS@&6|+KN_Xg^A=|f(R>K9t! zAupK7(Z2yl0n@*^gzYh~J_gD+Rtcn@S!b&BuxMYk=$Dhvktq8R=cY|NXC`&L_@U~K z7q4{en4iOCVW9kx)a5699B^t=o7&W-HnpkMDzg6o02EMKF*Y9X00000NkvXXu0mjf DwoB$R literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff b/docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff new file mode 100644 index 0000000000000000000000000000000000000000..5e4a90b3b7f5c080b76414a58e19b32edc050031 GIT binary patch literal 6140 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff2 b/docs/themes/hugo-geekdoc/static/fonts/GeekdocIcons.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e8a885e10eb990bc6ad2f2c16f6a2c3e48a5c971 GIT binary patch literal 5084 zcmV<26C><*Pew8T0RR9102AB*3jhEB04Hn!027J;0RR9100000000000000000000 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 y@RUJS*CSE4&$;P&A+qP}nwr$(?#xDf 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_AMS-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0acaaff03d4bb7606de02a827aeee338e5a86910 GIT binary patch literal 28076 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 G2<`xUL{2yW literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..9bdd534fd2beb9b878f0219da9d63ffba56677e2 GIT binary patch literal 7656 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 Mepdy)y#Y}F4=Hd9=l}o! literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..75344a1f98e37e2c631e178065854c3a81fb842f GIT binary patch literal 6908 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 CFgb+) literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..e7730f66275c87c28f26530d89264cffecf90be0 GIT binary patch literal 13296 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..395f28beac23c7b0f7f3a1e714bd8dac253dd3bc GIT binary patch literal 11348 zcmV-aEUVLZPew8T0RR9104!7h4gdfE08HQj04x0f0RR9100000000000000000000 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 bnfbLfgSm6Day;iB;wah|00962|Nj6Fv8wea literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Bold.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ab2ad21da6fbe6c171bb869240954d0ead8f68fd GIT binary patch literal 25324 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 PaX`&K^keg1Ja!Xc;UkM5@@HSxAD!R_q>yYN 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..6f43b594b6c1d863a0e3f93b001f8dd503316464 GIT binary patch literal 19676 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b50920e138807f385d0b0359f4f0f09891f18406 GIT binary patch literal 16988 zcmV(>K-j-`Pew8T0RR91076^<4gdfE0E4su073x(0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..21f5812968c42392a3eaea9b0c6320870b6b8b38 GIT binary patch literal 30772 zcmY&;Q;;r9tnD|p_t>^=+qP}nwr$(?9^1C|*tX7p>YkU|Rjay_TB|yF>U1UU@?v5D zAi#gig9QNpzx#sB|Fi%1{Qoa`WqKw6z~bmXukwE|5bcxVG`2N#001mG003Yt002aV zZ0}US*v*9i0C1}KkHhsJw190f+07ixZ2@XBpBBLOzc5i3*0K1{`Clx<|JelpfdmQz z0^Y*b#p6F-%zv@`#{+elC*ydxu{ZvYXM*vckNZFH^=qeE+ZuZOcdzl=|7i(;=HTb; z3~f#Si}}CYfb##-dgxdCCOFtTy8r+#A^+u71^_^asJbaN9Tqy4u;eOgen$MYFMjKr&ti>na+jqz-Ybx;jUT7rpi=M zufa(yA-TkdCn1q)EGvM2_hiax`gmi(0EflrdclzrY4)wlE?XoOGM65Zbzu31KryOv zDKlP~=VUIvYc(&_n4V2Nx|(ZkU{Ya`SLxl|_7eInvM;JKdC-~hF59%J{8gZ8s*xA(-Zy@VkPzVn;oDCiUoZ~y zd`=a4_!T~VIKf`-zr{LHRR`Z6oArG{z)^ZL&nGLA+uSoxbS8Ol`V7aokBT3Xo(hP( z+9AA$K0@4d8K?G(+Z{kE=#z$hPB}TJAG|HIE* zTQ)h#44y8HVIs_R_t=|UHjp!==565A(?KYTQlro?#(5^lyUz(WLb73Dy7B!}-xD1P zBH1c+Te}vNYtBs%bFya8%x)LtSejr>!emav;;Tc**d7miFAk0r&T!Ij7OY$jnucxy z%HMehZ4oCYujr8myR;h2H!=^$hH>=^?wg_l19r=c?+gwXnd~g$Cboc^n#T;Gt@e15 zn;uQUSO<7RPYBQesCs?#bF7jh#u$!u`;-2GfOQ>eAgjw|dNTNpOt#&dof28b+4b-D z1fmEtM39qlX9b~H_kRdEv@cz%FS=d&YVOA|qbvJy8))2-CdMgS5Wl}~c^%9v&l3l- zS+#zbDbs7Mcu{2*_CV!qJn2B{UA9m%FVT}&&KZ`nx4;WB%$(@KPfUVSfPtjFo-EwJfkt27^E z8Z)JXmXhG|m;gy3`tV#s08jr&+bll_DV@5LksaIScMWbwYM|7_m z*q7eiB(rN%wd`+50sA4=p8%zW24;l;l4=}Qre-<E_K3s81mK+|tN8@qM z@~FGC@FbM5wrjISp(V$f=I=6`o)0`4&8lfVAS#R~s{pImvBny$#a@WXCicNcM3rwr z`-uMJHht8Q6Am=sG#SWExcG^#6K@)Ywm`%UXh>yIZIxgkcN<5=Rp4C$Hy4XsKO|q6 z8Ah@dL1L9~vD(b4?ty|*nqYZL65V+vT2wCqWK=vUKmSi}pA38d*ZRRP<9Ny^nKR_g zJ!Mr2PCX~Dn0GYi;7d{_r@d3urdBG|ab=$i%To_h)LHWcu9_x}06{$Beo8A2s6@(^4B_=o#4

      Yqh7OdB% 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�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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..eb24a7ba282b03d830fa6c63ee897d92a5188736 GIT binary patch literal 26272 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�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 bkH82T%!~T~dOL3iZSfI!+IWoKhyte*`46Vs literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..0ae390d74c9f665cf8b1e5ea5483395da7513444 GIT binary patch literal 18668 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�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 J00IC101u*7EU^Fp literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..29657023adc09956249f6295746c8ce4469b50d3 GIT binary patch literal 16400 zcmV+rK<~eIPew8T0RR9106-7`4gdfE0D43K06(+<0RR9100000000000000000000 z00006U;u$k2x2I17PZ00bZfi3|sWeGGvz8}4HTsSn}h_&&m_g4$s+7>x}(e0b|zhiFmih3+Y z_JHa$ux;c|a`FyO&iVK5;5haj2M0Us5CRDY31pB2cF2N2#x@CA?hH+IC$1T5oL#Oi zTm8l{f35!3j;S46ZTBB`{Z8%g_kYV-Npt*qbNf{)Q`HU6L<5cyhmJv2>TM?E4I!B; zTrs$#{npsIL(Zb)U1m1L)1HRv;hxQZYYB2DMJ06qtE=2;?F$=%RNirU)ujURtb7>?5s{7KnM;^!<)4(Fm5+BJ{pbl7Y+ig#pY8WtNs@R;Tv}Vb2zWA1jQzm*#o`3DI zY!Lj&klRuUKmwu&j_kk{H`eCp-_vbX8mEgy4^o9{Y;D`8bQQe5ncy0wN9SLFsawuhEI@!jD6#EQ9wi)K3zoxV;?`!a^soM1A0#+O2q9KiRK~gx40mr#h`^il zZVIM5HcJKuSG5?>jK5AE+syVBx&R<)q*ZxDgS_aq3?!Y?rd;$kJ} zznvM-#jF)AbEqu~X<-Qmg2H62$`k9B)$6!d`Tf6NKjrJ0h5H=%>B@|McT8H*%y`vb z(%rk>@RCE*6N6rnrAbrV{r!LUjAD%&0?-v-O(btVFYk|g>A9-v%&i0jKer!j?XGS& z<+bDDY`-WK+F91kb{WD=t*O*|E9?6lh zmQXXHp!8Y@NHBUw0BY;l5r$Z?jtJ14BAd4+e3v8LqOKEP;%_?Ao?k!C_D5stN`Qb#dilpsL~Lt7xl?!e&&4S2=E zR{2+JNlWaH`b0~xsXo`8-vLLO+@wrgzj0rcEa>Pjcu^EFD>bx0qSJ`!4s=W)SB7DX zyeW+chsOzOWsuXMyNTP2sw-^>J9!)tN(MreuiV;}0bNt7IZIc#j3n1`#guNA&>Xg4INZAV3h}GAY<`bg8ox+~@ zEJqxB2|yuNW{M9&^Gdu^OA0)0gm8&_rxmUklFo)kf)TlsEy77;Lqu5J3xzT2=~ME@ za^gr%^4no`_dRXwz8N{T7zGk__bri%5HwFB)V2_IUxXhTJ|DrhfQVmM{8&nc`@9M2 zXW;`Y>&Y(L$PqX$=~u5($l+$x_;fizt0k1976`f_JpvLcZ9z((ubTuD1zh$5Mds0` zz&!azxO&7(+3ute6E`Nj_ec=&1{1U*o(*p996V7+3I&pM9Hm+ZM5e<;t|LUDGl)`W z5|xe;way|M9U~b!dwMn`4h@Oc)x9972tJC&*aY9UL5<3vTYEF-@6WWD;D@_Uf_DBs z#D|;c(4t2%pcqk1C}xyQ6bnigiWNO`fSS0@6sQ>5_QONDm4#ZS})jb=GnDsb<++9`MP5Y5ABCCsK6# z1OcgPe*jTu&{d@OP3B5o+H(0WaRW7mZg_-({3&wupt@5#7L1uiz|q?Lg($F4&rmf* z$WS!B%X!n#M3@kc4ExS+zAZ>;>*i}1Sp-59rFWX)PddDH;Yom8c8+t70d+3;Or*FI z)w110%}-KbC%4S+y9uWZomHd4JiD)+af=)x8zy=(h%+`qq zmZ*8+O%8%Zp*R`>iz92bPPMa`3&xBf%8CvUVcQ{1?HmCwk#{g3!1tVj8kNlHDUYCV zCf$!chN=Cl7$!5g27GqiTIP&Rn~YVsBsv``>Y&5RP2xNK$2M`Sg*GAhZ2!et{QvfwD0HP(pY?U`~n}OR6++i?h=qBvW(Wt8fh;DSXe-#52$2u#kmt|A1y7QWd-)-cPnK@ma;NS8P8HC zHlbAow7S5)rnEBFW*O_UjP+T@hD~T=0c|R9ZnmA|9&rCZfhtcjU?kjR&?$Az&4KI_ zSnmnMm{_!G_h+6R0wTPR5NfxX2gN>xR`3V}X}clF^apfh;T(gnCpvu?0v`_i$`RIJ z+Ei@jh**$?k( zrfOsK`lg4QEV~?;Acltu=zD_V2Gcbn0mUMMVXrW?ONwM8CNz}N%W`~)Fa2-mI?xqH z!=N}Tl>ha&5U`|`{o@E=_R_WwIpVYF@9)~n#%%{z+rHfnV>?n^r`pF48%*NN(_bN4xTXWen6;A%fKBKh1AkiwDiLZ5&f>9 zg6qVZ=o(X4(&5o8S8@M0zKaYHDqr?5a=E zEK_S6$4%#%s)VqJaa^@Wc2!dE(cH(>hnNPUfp4xOAMInBCg>BMxNJH>Vx6eEDN|;k zWsNxONPv6#KWMji)PKrkuxR;KDvp3|cq2+8OEhoN0yNqtEY33b$_ElD0u4qA8=%$w zrdX|JEL;}($`?0GP9_Y4R3IJ4_z#+i!Z&M|Cbq^qQ3x!+n}|Nqk6ZrHqX!R`N~Ii4 zD7-q8SgYl}cH)xD{2a1TONpR}Mqp5s^kiCvHD!ZaZO|>_#-ti&1=q5@&qQ&tkVxIl?8Z4h|EbuVLwU+pt@owAm0E^WOR5=hOs!SOS zzo8!zCdTiapnT20---od64lN*=@I5;d^zd~UOhY51+b^!Y4-`-{PgMza2~SCY|?}- ziWU^4tah0Mo|cbXAB;O~U~nrmvYx_@S~m}jRc*f5oo*DLdJ%FCmh2w{u|@%=#s4LH zuz-N8_2!GfNKk?7&sfh5&W6yEVtNgvS5W`T_^ekX-cR+KtghXko+AH|f3eI(a$I4V z-$?PV=3h6i(*|nqd5=Qs328S_{l>p?b(wGOGEKf9drHgyIC99<0tT*Dd=xMLMALs4 zz~ZI|RQt*5Dw(pa6)s1w*#dg<{{j$IV{8_*zaddF@mwSDtR$a5!siYB!5jaZ_!2+l z!GLS2*Rhz}ED=hmEUj$0f%`%wFW>3wl5ON@gn+Z$C|{wi;Xe1gFebxk3{!{ICZ}x5 zy6}uB%p!i68ptk%+5c|NWSubWzH?q!Ur;VE7Fz9b zU#Y}Tf{TQ~*=rojW{X*8c9z>Wh+uZP19(*Xk5I%S6VFfB$SXr5>|bN|he758U|MC1>v`4Kuj+J5F5e=O??MH`ZIJS3 zP`wEK?CCHbTC%q?E3Z+e+Inww88OH?d&7t^n{C?>;U0gb9bD`y<0~?sC`A51fIQuP zjpSp0f+q@#eWQEcr8pkTz-BwjdC@XgWwYRfN`t%1My+#D6v3pjAbl2=FUT3K^~_X; z-)IRK3&;npTt)lwr~Mkw83e=JpAF&P2&i(%_q{I-9wNP6x^Hm_T*K$A`&v`qr72NI zAT#W*r374hzJySJ=EeRmYcp?SLp8c=C1gpvw7P9iNfD!OvU_WbrzG-%o9(0`_u3WDGFa2TGgpJ(A z$gPglL(;}e=q)r5p z$C&ZESV}y}fXdDSBS$Tq#l4Uo6w|`O-S#&P!yA!Xtd`P$;ZwWnf_d zCPTWG$P9uqtUnC)sO^n~XLTIotH33S6oNm{sx1*t3HGAV|Adx}?W8^PrScYg!g`C5NLJZnUXz zjkx(TKcyL9VuAB0#5mUJ^cW=&%2B)4JHSt#7w<4FGE9XwW1e2l#4$Qi<-9n(Ndbq> zDA1>pu#v21wC_<6Z)9dssviDd!Plha?NOTdBUG$;%&LOS#8SJ8^C5^_&O zZFfZ+rPymKad?K45-M|L>?8*G%?14%aRexz3Xef%&~Qze=aUy2x26^Fd7#`-@81lw ztb&CD#SN~Qv*+|TZDJlv{mdJ1`Z8c`e61a894SihH5^)_htbfyD|5`boYb!7d5Pq! zR8ms_BZ(+_IO|0h8hXSu!De&hVR?+DHYGrL-`$e!iLPP+yzCnT*EQIw``4Im5yIfo zHwm_9N(T2vHL!fcYXwbK=0g{+KuaGHa7D=Rt&>ouMP|TMt+SDjx^u%D;Rd=Jm#hm} z9Wkw}<4w!_DTn$Ikm2^1=n3pLLy%fyWk&mC4Rsr*wedJ*a*eqnZF!5cT+QXIuB=Aq z^nqRh;hf5^;-J|F4iAO;Fz5p{&X1ejZHCObnYNyp;x0tFGFc@P^-pPuARS#X41}la z#yzkwF1#5ge%dZk75)UGbA#BubbLSl=PDr;*tRIjd+`RioSg)Up-}G5_9TUx0;g>? zpMi;hvTL*62<32`S2^s&Qw-DoXfIQy)EdRo`Iwk1LI3r5*!&BPoM5l4OJgL{u+ItB zmksAdF5DI_yKMF0T%norSxNWfvVj`HgSuuLfgVuB4agXWSf%fQyA6PS&@ zYy`e31PHvlZF#G$W!A(?)`>qRFO}PE5OZcDIhQn!FDOp-a}^hXqpRj!&J>a5XlN2n z(!Mk8&{Vd!&@$hm3d65bph~~cv4oQ~Z^RwlU9C|7dr!n&I)@79of-(sss6QKrCv7O zxpQ@TB0lgeu1>bhD%x zCRsyN+PlK=A{E&666s=KU8n)e%ysM2HF5cvJ5=lCVZcd75wD7?DyNU~k{!xe3_ z_tnCtqhWQMmiMS2C^sy-OJ@Y}P?5BBJpuX_e0w4t*tTVZICA{oTg8MjI|2ReT<@7s zbe^vKsJiSluHja24Zox_G_e!Vd(NBFrsc6($Tp8sF4GPB*I3 z-Eu@eJc4}B>#{hqAS=mMGK@-w6FQUx@f3%SpLFYMwfyk@qxEV$psgl>mhTC$snT%g z!aD2L8J~qt^f)l5W}My7{l548+*C1aZlp`^Cor15-g5Prw%n0OS&R;yno~ow0gNay z?SR5dGgdLRJzO>oTJtu&2voqcAcdW`1an$ylZzD*N@NCwfmp}e8VyP$IwZPZt*-gL zhibS@3G3AknSHpHW?no!$pSw_E42yJQ0lDRgTb(#-t^#Ia zE>Ibs7ZwbJr9IW1RRfC^EQFfVvRg5+o7PM#nuosWc1Ke-jzFWWT8p$eCQBQ;CD9Tl zhT?vr81M8BT{U(Zww$@4*RRj$AnMOFk)9F?-;_TzMP~xGX=9A>3mCglYeWj$WsuiU zNG-9RE7zF$1gUDU9%95iXmhMHl@$ekaWa(EGKuE+@S9vMRJ(ZHL<5UNqzG&ILeSPQcPQVt0G1u<%snZ#+RfxNC5_a#ZkrUB z%?xOP5$)#JjE#`_iBGGZWsf{#N)0rHCx90dMT`2FjYEdR zu`Uu&rm;daO4$z)8~j6LMH?v#E)#I{z zs5<7Er7N#oLZg(I=Xsvd{m&%$&nUn|G5`w|G}#2pd3YQrG0>-^=R`JY_&%-pu#x}A zh+YjFRJZnGiqn4EeRcI}#b#10@;4T|%AAZz?0G-F5A1S+O>zHZPml=&W-X_1B<0!^ zE#AsNMnGUuEYBC_IaayCi>ZYCBwD%jolp!Rg(>{_6!PS|&gL$Hu1JOdY#u=7tr#H) z3NA(xs0}Py(t71K=N1WImneZ{RuMd94IX7EMK^wVD@88x-?0|n50D#-VqX9iqQ#l! zDa5$E{<}U)kX!$>6|2LCIRI*w-N88K_7c{cWw#l}dkq(^L_iq5U*<-{)2~WgILP7K z_&R+ek5G)t)*r%!8ZKHQk(kjdl~YpFHQcYjtIXA&#(vq*pdlp|fUzuQ>v_6m>Y~;6 zD&To@qjl#nrVluR^Y?geX0iv4@3gx3p9t{HolhNn^QF$d9~a*mRKQAegth8RSlfcr z@az+Qm5pu_U9r*(*6n;AElIu8B#K+RSt5(5bVcXNAU~t!62n+#3KywdzrJNtdzqVD z7yIE&xb_U&cQ(wcB-ZJR=rH`9Bpsu^N}q=tyR3)eP`67rnCFwBHGj~oMt72Z-~vK1 zVu%yZy+$V7nUJN+Z&HBjoF32xB8sz<*r;)!`*M*EIu%8 zc`n~x_Pu5BjKhR<1w>-K0n-2KPPFG>I9@EZ2^Av?ydwkIa;#J|=fgg($eMzR* z7;=_JQ|NZWsruzoiTeWVP(kKN9ppq4bAf7)ke|Bs*r1c5d&B9;!;+j-?=;w&her@D zMx1?W9A}feTCxkevkf4Xpt|sK=gn+>v$Kn$xi;1{E8kemsH=SYOh2+&MUN60iM2Xn~Y7jKc2U5Xo0+k%r zd5ib#1`h;~9|tkhP76AfnFkcAw+A+OPxN#DN_#Q_<115kEiIij>rv=Bclm&JH%ZWI zSS-zcu_Q^q_PVaSkf4ID!BE=!!}pNU8<+fHwXp!Pl~kZ77Qqfff2dzil)l>^sHmRh zXgjZ_?|%5ysW0oqONVkpCx4!6@z;-6aQsZJ@nN&^?|SPCP#^%M=`-E=;p|aQ<-9AK ze#te{Jz}u-C*t&W)~F?yWwoOpUft;-*@Crx2fb$9S~_VGNhwcaGp$D$jO(aEmo$>s zUNC3UQ;sP*)4axzeFOJ3L@P8srBr*ni z)Pd6O+$SR8-l^fC)>m(Pb^QiEtCWzQ_|PxXuXi>%%2(W}?>r~YtshvjMkuWiJ=0e2 zhd{s-QPjn&mG7Wai9&{pYYS!xTj72IG1q48Jif25I+%{V7bzbZthlw!*BI^Hz$J=* z2xcTSE^nSPlXWBDmo>e9sV|V4_p2dreP9HN^Zf{=BA>_c5D)npfym@NVreFH3=D?keIqZr`w&dacO7X^{_t`i|h3w&rbM?4Ygh8z_NKe+XC2=mWvusAs^1c3oaP1LRGg9fmJCCsoiM8Hk{ z?kq-GeK-B}HR#9R8u={aceaKl8e~WdqeDm{&X2cQO>l;PbxkvK{LVLri)cpue@s_@ zTX3Qa>Q;|w#^AaXbg%_CG#zj$!-svdp;_8B+BFc|(*sR=0~LF;9Nx2HTW71_@Qo|l zS_FFuWt2f8&s-L{@Kw(a0(OY1i^3#_^{ z#;{O{ZOc1lm-2h|hH5NzjoB@pkx#dw_B`#6ZjH}mEg#@@Vp<6*eE8)LcFMl`>@sxI zg1?S!4}~g%Ae0h^)=}%z zN8wo0m$eu)X6-UoiFzhERHF&73f5e{Os?)S?2Ktt_XNK8SFI;1qWqqAD2X7NG4+_? z`mfL8QO9mEL9b<@K8DymgiE8I+*u-}`?NEmSu{)FD=USIigZUfBpsHxzQEcK#6*qS z?|&yPmWqf8gOfHG5Z7xU#9{~a8?c_FG{er;F%yyM?amzMg8cqi~5=UZApsGcaP8&Y?H91(Mw z$c6i9TD3s65KK+ov%#w`$y~#g%mkU{G$5t#7>ZloW~Zmny6)uU?98-sLO7k5r^@MY;{$Wzz{lghuQ}X@QhpaIembKa zkmy(>5PDo?FaEjoF7#6ze)cuD^^Y16has{&kXb9pFep_&G$X(9v+Ntbp%#Ay18>Ru zY=u!tE$UhIjPfdHq2~izVH55|J5l<51`CE*7ompfhQHyf>|CDIdTnI53l%j2#N^p*b3Kscl1Y{iw>PjYJ|=C$+GBh=VZuA z#xz4fA-h;`am&g)^)!tUVl!28Y{5D)J{%D2N3mG{TdPhkF@A7 zNr?BAphkZoG#3u?dki+Bkc^*^8HzhW&_>+N#MA%=CkRz@}8}W_% z){c`*-p16tlGNq&*ysa2WJ`}aD2?PFovfb~IC-}+kt%m|WRaJ(!`emu>guNQ$j7O| z>~TdEw{j*MckNCNQc_k>tNY|j2*x`@?7GT;|DwNPjg-*~bt>jH{kxGq&A%6%B$FpQd&3vafE2R@r;eN}(8#7uAmyy}TzyHIh6KCLs;5Sq?jYFTQbzh zzp8C``r4tpy{cdk=d#iuUol@j1zchEOj5MG@zuSoVo~H*WEV_xp?QwtDeXF^n0QR z5hJ1>twUe{QwR7zPbeTH5WfuXEg)F{24iqoLe!ka^CJ+0D4>2 z7zw1DJ!mNTjPf9tRohKQKOS114nb?XNwGg^D7=Dfy0z(Mh*-D^muL^8lsV6w$1s}c z>YPb^Exscyp8=$@jjSq}G6Lqg_A_!T3tI=CY;A{)#`VwDk?1hY*emH0+^l$eJOq%{ z@Azj0W=$0;2u4X+bXc1}-zVUnK9YpLU}Bvo1x4nmbFd)^joUI*RI9D_$KU>{$g(ZP ztL=7rCkM@jO9*#j68ouN(FbHiDWfd-coEJpC5=e{;)z9zhP#9ZF;9uX`V=&|sT4cL zZw=qV>kz_z1?gdrdfE1Myp&%!XM+{qQ&IOOy?amRl&pce6rJM<5Y*Cr; zZY8FL=Q6>M(6axIO}wL);jH;apif(g_qj+NM?|jXlO)Ismcjk~5B~R9_~Dm7Y*@WD zQU!Hhn~}&g&hzdPi9;zi9Jod1`*chc8sTKaQZXPg6{h+u`FuUQrBl;_6eDhJHygdl zs_(9=)$PQ~yXS>uw;g^*9+9e%OJAkfnk9zKc}$^NBw4_0jHd0#%8WRYQ?4GR77xA(~^ z3}*F=HZ%>Snrq_|Y}}j}4b3dkIG)za?oe4@FNDomX1~6;Mc6Y(8Sj|*>-*trJl3W1 zsGXaGnz3hmR>8L^AnlfQ!`cQXD-ofZz;`^-Y_rd!%Tw(u0wt=)$C37-YIY@)Xv;5; z4?M!9hrBgT2M;;>{fm#95$n$TugUjk(3_S?0woZzG(jETU@xUiszEONrH|<*n%LR|;674!$p*ILlQhMnBQ&KiA3sBhzl^1Iz@+U$LZyjnt+fWb=E)(BYL) z7?Ld0oVcu6u}=Ts1eyD%MgO^8b_e~kzPlkV*5f@}*AHN{zo0z?0|JNQeP6+prgiIe zYcD^mRYkHEE<$c8^tTQ2n~Kb=aj(l2SOCBE3;?IEcFa-P)y2ohp0pg=JaYGu9NJj&n`G@w+dVNaqKc}$U2inV1IYR%RVG8XxLK6(lzrhn9fQT? zC!9CGkN4uJ|A&Sk%%Q^YG~0A5<|Mx?eh3A$>`h7)Tekz1-;rrc({r7XTpK0_U4Mcg zN62G8SO1^ev!sPT6{wBmS-*P3B6Kp<`9H|d6D(9`O$77xYkttm@5t4k>7;)Nb}F*h zn=;M*zrLs$toDvxI|Rc{^7!w9`5MV$s@6gCnyi!9ryJK}BciOT!eXL}bR1 zwFhM(%frGfXE1ArgbCZS7_$P} zk39=RXZ}-fn8%ATHtZF0^sA{l1*M$%qN&>@60nuxkNgWmcX}9`=(-A5F}+SF`pVFL zXSLLsox8Q=S+e-&!njj%SHjL%ty_=CMXH2}lQ@**HR^4t(=BF*<0ee0-(H=mS*BSk ziKBn9(j(1{a~tb?WogkGa*&O7E^4gTjEhsNM_LHx*xF>v?5x2#+$tt6AG^5QS$S-Y zD1iqsJ1c)FWSoMPs@-k?AzlF#@*CXe|6-cBgskZMHKMA29k-Xj>;dl+k<1G4r`ZO; zFS$hOyX$NDCB)2!wmVzYABerOQ1udjk?<>g=m)ZjOk$s~xKJNNUnr1@54(SQeep#W z`VtrRl7i^hl&9eW<40~Q{V7zylPZe#t zW}GtZ63s*RdLAlte|F7EyeNBNFm(v*r_9+mZPEFb&Ps09N+M&ET5?{Z42{8S6Y^?) z0f)cuKe7P#AIYNJkKJ|Kmo^`wj5mz(n~DPTIkc#P&K2r5>NkR%TzV&mI9KO(5#>aA ztR+YKF~ue#rK@E!(Drm!C7gD-#JbJ8b+Ak*S}sTi7K`SUV>!z0ACC8<)FsJX3CpmH zh!PPR#mE0U`7Z`PmU_LoBmTg+ zG3Ufa32PR;YI(#zK0H00SkIKDqE1&Z&m{WV(7a|J`v0M5NV_lN``O~UQh{m5kIUw^ z2((56zqU83UhnvFApZ?hum0!<#yLL<3OPi~x#p-L!&N`U0CXWLU1+-bHm?6e5KrB{^07#wixzbShT z#LOV>l>8y)rzZ=Wd+PuD7kb~>F4kW$$nHpW-=9=awfp=P!ll3;xR3tv4+oDtS-Ij+Om^sB z@4Vs=$ifB$Jw9^#yL5GJXHveOToPP;-V5c0nV5%On*mwEcHcZT81y2q7A@$` z1VplhAUnSKG!|R~*a=iK=8`0@?SNUk9)TX&5HY9@>Bp+Pp!Chs>!7l|b@=hOzJ{<~ zeCwe#D>WFWA@#@~3kRO&N?j+eNOC4Wb@a7e2o!P_&hQ?&wqRPh}g>$Z3%hri-?ekpg-wI_~0`Y=@ekkjuqEX9ZWMo*N<%sYY zkO!|gfFyUhj`X?o%je=74pG7byQQ$(6b9v@*HbGnc2D|Pc9pVaIGl3`>?`if3a)$$ zKp?O~ZWGGypg+e35saz7cN=;eac_GR*nkJ=X0y0x03`1?8L4$TO;nrcoz!1k%+_$lMsNUZG zsEfFYa+vmuH~fki{NtSNi26 zr;l*4dT^y9JmO&7Y(5f6>q} zGa)>ep+6elLHe8q4x8*M(-^C%{JFz>CHn39^#Cp`4IBbO*MB=P`5qU|x*PVgQl??6 zaVOZ4D`*tQDsn!qFWN~{zBGmwOS)^&A4_C2*Z{kc!sZm-n<37fQ{8x)Bp5J^L$V$i z6cu^{4w9~wy1{UX7fdy?v`iSD07SS^87}B$a1}Qzll2AbIoGc~58$GrZ6o{a`j~A9 zP@?frc4#LA^GBnisku2C!N1;vwZQxHV_%?}rAI%CfQ0Y&VBoTp(hqWqt{F&dKTGw6 zuGs6}P^6xDMr{wwalA;sG%-Q=5=b&MuAL9$g4NqaYF9X}1$*SFklIjv{jqgd81e}felRvCH9SlCWcp02g_|A$_x7LtN#*e*2Bq%z1k6zgq+R%SbEqXN`&AcfTK(YOmGbMd92PbiWS*M z+kz~>;W8vUV#1u7&xQUnm@G^u9!Up8EWv3ub9>#Cch^2XBdQp<|J6Ulg5L=7hg6d^ zloq5~{co-AYo2kmD~mw?V0DbN)R+0k{u}iRTUxUl3q4<|SUg6l0fl-gITSuH$Sk~^O zIDfL4Lp3M@9XzRM%aMH6AB44^Kzo>VV_p&6R+W+5mOT_yM@aNonLk(CAX$>f;^a=U z+?$TR^o3>`*5WW=%A`NDJWC~8O&awenW!c!DCD`iYyYIVbp_wLUiTEy($^^Vg11<* zd`Z2_O12EQ4_KF)X9db@YFjzTbwK_7sY8Z@3jovk_y=F z#-fjkc}76qxkyF9r?b$mWeq#qc1F@5X&9-LQ-4tW58gq*9mA7x-^UB2t&o{HGQye0b#J^gR)*Q8$*Qh&*1`7Zs}fGFAE z8E^cnlt<+k#Z0FO!<+KOoDs}ygIBt2<^yA=CqM9-*;j7Drzffgbnhv(%= z?n;CeYFUni40S$YM!)g}v;)a{#(oab8zs?(l*6T81@IrQL=mA_$jm-vKmB!!u{_e! zs2z69?zU2&Q0#1FUn;e0*Kal-UzT2rmhTqh>@~XALb9-qTVwG_n&PD&FN(M=9(&7} zg$C&VqD_XRC6o1(TN8R$>>JC!jXMCC z`sva?tvt#7n~U+=)%Y)k9L7RR!2}iCzgm{TWto@HenWOReLWXNdIe0Z6HV;+N`n0Y z5RT^h?t7V~%6P_HaETYrhaEHmW`EH56xFy_(z9GjaV6XW>cjGNGT)bs*a5@QqX|me zgE1dY&QD^{$H#mlZ3^megChz>l$dUoqv8OrDMG=XptagE9%9#~qN(}~Kl_b|qJk8F z2(n(<>M3$aKc=wGwY8>xt3Xks3U5-fEarz`^ya>t3VpySN)ll`CeM39z}uVGnd8eK z3^@_2yDa@l%-Mm7;_oSNL6Z>8E{%2(-Z>um5Gk5CsnGwe!T+F(u1e*Rf38bY_j%}{ z_oV3OtcHO^jcS>6#)gSr43Ix&<;ho#kF+VQweOea!}%5_H5!lC)@G^=577CG?klRC zvD!Lwd`dMJd+{Q4@j~qlGoD?0WV$vDL*h-6NmKnch4fVk8)3Ba3SbvS-wSO`A|}$X2$;)I?G>(tl5h)MDZDz?PefA z&5$$ruWg*OY;FsBZh!tGen&vqQGG#1sb{H2=HGVU5?TJNC-*60GGB&x`CFRo+(e#ch# zW3OO^R}~uW&AUG*sjQijcF0U2g3Irz=}2m2JGg>x8mku{d|nYt`Y*g7roy*F+d6I(lM z+3QDCrhU6-S#P2HPktnAOb&MCTtrX=_I3VuUl33*33Lbyh^sIpCClR*KbVMV=*p(d z6IPjA$)GxrBQ|0aOZo-^!?N3xHu|p1;d9!)S=e$j1!mF zZl9OoWv-^D?#|2RGB!jFJGtEoVB^BlOXx#wxbHxf5o+6VF_}QrMUy zw{Ez(s|FzO&Q3BbV2?CeH+;WN4LI(uYPkxR_K}H!@n2q1hw88ca03LwEluKHh5e7S zl{11}QHlMI9x}$qtbtmVUcE~fAI`gMw?V&pTRhTighe>RB7e3(JE1c;zKYeqoqa?? z1Qvv8Y)>9@AxH81x2fq+FZ5EqN5-G;Sg_#!8SKd>i~9abJr*`2{Svg z7X;7c8IMTXUG0m*crb_ylC(duxVW4F28FJLV**dpkJ=qIJY{q>3fekwvq-tecLm;n zUVPpSO&qc;z?bs7;}vawAd%q3oaxgqJFXREF0QPOZ=FN9q(=Yrj#N2^!Jj%r1teW- zu^ec9=6EK9U_r1m`;>wQ6s)L~!7ZIBE>aLgSiU*wwr5b5Tejz%KcCK2@)7btj$XFw zOmjT}!F8rGQtZiEJLO~ZCml95Uvvlnsbm6+7?pgOc@V*7CY*doA%kk3(Mj15YSLe7 z6SUP<7Un826>5H80R+vNFhNTsBomhhErc2tIhb&FS-vW;%dLV1saRRY;bd+m#YIg< zF;b#sZ^FP+RsoCJbn`G6Hf9t-24xgUh(4s3a*D}Vp*pBRd<2!*C9Rap`~TYL>Ngzap7zOP~KKw;VsGl zh?d`DW5ZnJh%60Wga8CBKjpP%em6tt{S_0Iu^$3K%btg~(tG`j<(|JP0%6cw5Mc)F zz;uU}8x3iW(82y$a~}7!l@_Sh?(M*3a{lQF-K9HpZKiNb_Zf~G>SeE6b~H~%^|V#C z(^F##dcVH=G!|*?wYm07;YK4oE1kpgeMh=p`3)5N8D%amhuF7^Y#;2GYx@MiS9uuASL`vFHt(OcSrWFLRJcb;dLI(s_+{G7h#nYyemTSDnI?dpnf2 z&K73CRF3|Oi)aP2qkdm`QVa&+)Y%#HAZa<0#ReAu=geD`2g_h)??q~q%mR6xE?GgG zm#q)UDX+1`#@JjtTx&kJh=S^Ev9=KK_NzQ-(I@k4rl{fJj56?l~7EUsyz^LI7zo6UoZ7>c<^96@cSc z32DO`o`jR5uqwU}=yEUFm95emI9kRT(FOKt_Lc!Yf)kR#{0KZ(_#@iz_^}xv#wt3t zUf=U4;shGkh0Kof{+Cn7ymt}bNRpTYMM_3aK}p5P#4M9V7OQMFb~$n%((kX6OP+jg z9t8>&DdtrogeMS5WD1o=XE0f84wuIl2t{IvR3;B3O0uGAx?x(j<9Y}pBryq!l#HB$ zk}5n%O(TPrj-G*$iCHF#ELPcUb>URb{wbmygPV_a7UnVQdi@x+S^ev#MKVip)try* z?^n;7ZgsgeVi$csj4wRWp-D?D1O>iV=}fb0>F{=-pTg@6*|1up@(uT9+@hFVlK^Y` z-=0c`uTqR2p8JXyyj!rgeBJt262GDyc`M^%3yZnhI34tsG|h0hG eto0caMqseOdLG;#8C$2}qx2NB2Zcf*0001K|EysE literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-Italic.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Math-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..eb5159d4c1ca83fb92b3190223698427df0e010c GIT binary patch literal 18748 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Bold.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..cfaa3bda59246b49e94298478d6de3b3208066c8 GIT binary patch literal 12216 zcmV;pFGtXKPew8T0RR91057-z4gdfE0AMHp054wv0RR9100000000000000000000 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 G>;nKVNojrn literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Italic.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Italic.woff new file mode 100644 index 0000000000000000000000000000000000000000..7e02df963621a5e26d53d510f0b4992eebde1c60 GIT binary patch literal 14112 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 ZM6wWJ659DkbG}7@mjJD1@jO-Eqc8pH1xbNXy>V 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 DqysK0 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_SansSerif-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a90eea85f6f7bded69ff5d40114447a6d8b48cfe GIT binary patch literal 10344 zcmV-uD3{lFPew8T0RR9104Qhx4gdfE08C&204NXu0RR9100000000000000000000 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 GG{*pT{>~Tx literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Script-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Script-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..0e7da821eee0dd05a0a6f0b16c2c1345dc573a84 GIT binary patch literal 10588 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..7f292d91184f257054ef77cc1cd3443db757c9cc GIT binary patch literal 6496 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c5a8462fbfe2c39a7c1857b9e296e62500a8a8a5 GIT binary patch literal 5468 zcmV-i6{G5RPew8T0RR9102N#S4gdfE059|a02KrP0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size2-Regular.woff2 b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size2-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..e1bccfe2403a4ed770c1697ae7c15b9e1cd9bc4e GIT binary patch literal 5208 zcmV-e6sPNVPew8T0RR9102EjN4gdfE04)>%02BcL0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size4-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Size4-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..e1ec5457664f438ce5a1cc6dd8409bf60ca7804b GIT binary patch literal 5980 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Typewriter-Regular.woff b/docs/themes/hugo-geekdoc/static/fonts/KaTeX_Typewriter-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..2432419f28936aff53ddfa2a732d027e6a6648fd GIT binary patch literal 16028 zcmY*W81cE+qS*2ooqJA$@`t}$2ry4J>7Rrb@xp5kLj8& z4+U{?01)6u__G1<|J63d|Cj&Q{{KZmg@G9WV3GaNs{FuEOeSW)#Lmd^N0uC zTO6m;#NCw;0N{!L;oLva1~$d;Gk3JG0{~cg0RZrB0017=nEunp!pP;PFMsln4dnj< z(Zbft8~^|k1ppX^001Q)?SV2@OEV)=0DzhC$ATK*`1=B54N1V11JqXfdT zv~%_Rv9tW)gFj=yqUs|6Y#mH~?3gHjIQW0yxF8&p{$vhmv&I<$h#_ASemq4~1pc;yo9=Rw9hsSZ^ucI`aM(n4PH;fzKo zE3$_WRb~Ux3~iu?mRtYjsOC9pug1EO_=y{H>xU88h9A`HuaQ2Iq` zCLCr6`B$SW(k0qf276D6_OuESlvBMFQ^W-heJ8jze=}SSvw3oh8)cKm<}%l^A5RgO z;J#6FFm4d>&FB30YjISr-mga^*K0X+YRrpt&3?7$JpZbi`Kl93Pyp`pR<8@mS<)UB zD>@Ds#&Ai7(WZwWFWhEa5$|$(#!@j%=NS2X4+=#@bJGN|Feb)IIJc5gPGByOR4GIGwO$%SR? zv!YZRx__@ryQt(sk&5=7T#wQG&&GjJ|^QuDjsxl5c zp1#64eS(nGn`18v;W}ULUer-zU=nC*akV6$+q-ec>ZCKE~~=2+}rty}YRSL|+WG7X;Z)->M8 zdORJGJHNd^ATm1kKi5YO>=o$_Q78`NCixC-(9CrB&@h+AT$oS=sepK^hQ3xTfMB@l zo-qWDKRLBSEqsJCIVKjhBHvLQ?*b?xDv>l0EGtWo0T8OXhup3Dh~*zYtO$K8<>S1L zsWK205-49p?|%RTeWII3i&tty)ff5e)dYhL9%Er?EG6ZA$Y}#+jb3p7(R#BwN7?q2 z_ozjw zx$nlX4&g`O!{;$#Eda+4~fpP8KDn$&}5hsCFJp| zriyzcHP&g4x!`ZLYXQ5!hc}IQ;c&o=O>Zkuy=v z9WqI_I)LyQ@UD)~hEpS+Gy_#KOS{~{b~^>XVfXfGQ!P@oXsMoAQ-?+j3a~U*SB}W3 zFK%M2qM)lM)=7BYXdGt{PsP(;k>MrL--DUR&6t^tEr=i{&FD?Qu`Gw8GN$gl6-S;3 zC5+5G7~iNqeqVEkSFf$)UB5m~@|Kr#hT)K|u&3>%>V7x|J>L5*nHWRNam7*he7>bh@ zqq}GuNEtJTqc#L<8(bX}7>qbLd+ZR-nzV=->UsNZMmlP;f(YmxR`gHc^AC5=-SgtL zP}$*()5n7}u zDw*eM?a2|*#`dF3v%PkSd0w$~>PWGX%^Aq=s1=?WL}Z6#*TYH5bJsa~fA}{`b=4jL zo8<9(M!9e1Pfy@PmRje-X#POi`4{dA-_;Di-rRoB8eW&OTN8LU(Wp}G$Wl?Y>k@T> z(qSML!TIARX2uE-7Q*gZ@CRBlT+nZ3*QEv`voThDIunHf^M-Q<&Wsdy^z=%vw-Mn= zCJK;!-;m!o_IdFro~E(wP+nvA*Dl-1dnN92wBSr-OJ)W3h^{dQCgdCTn$TUA2ouU3?g&YGEShc`P3&A*$lJ zAG$as`F(U)+|VmXQS#CE=We#f#e=m`2MB0+I=m1K?`X8S0ONgA>7XV}5No?`>13To zPvK$PZ05;5k*fO$Zbt!QrzbLYgxV%2t?4_?+GpAs*s19q6QF0X<;s=L;%ucSZSQ`1 z$!Lcj#+QsYgRCwucg?mniSnCH%_Km02pP}#pU`X#ATi7czyV7x{KcDa%d#%WvlWFt zW6kLxAp;3cTAO`d-fm@h6ScT%iv9=o#4rF;ig=)LxcL_iJni=(d(u^xD>YBjRB$ah zkq&hFGeuXfI)*#bB?H^2iRoDoibmPx2d}W@{6Y}~j@}6dh(v@UI4%>%MW?|rpN{@!_M z)BbY9C`nKo2yGF~M2Q4$<-LAO1nlyC zK{qI)8=PWzPgjc(%xzx&`R&Xjf%HDV;m5~DB`>~^-s4cY&SkL0!&5WhUU`TI-3Pqc zfGStX$^G9~*tA^Gu#E5&WTgXZrc|3$tK#1}`p7zA!DiVhGI0B1ZVa7SL-3;Q=-Vz- zCaN~b&qJLVQe{%~r$?vcUYNGalQG#tT2eKmiqd1mVHaT#a4{1-^0aaUiE%E@)xhHK z`*8>u5zDtO!;_?aU7_8pbGCZEf}hJ~Z^t$_pZ)=rz!GdZqc@vGp={9sg5$f~g4+|i zkJcOToQI7~v&M!{lpI<(m&?_}ty^LUw%AK}hFEw?g&i;+Gb?J>WFfcG*QOQ7;7-^O zj}S5Z>sj;l2s+SnH;FweG^28-?v6ozwq4tAx}~Ke#9hyW2OXc|T%3GqRQQ$VjY`BK z%?H|6aXK`ys>&azX3H>(CR=n^@$iSX%z9h$NljB5J1`KtD8X}@dCgc`cyWy#iY?8u zkMaS9T3qP}|CF>UPNw^nTkkrUaZ1Z$4oZE@U@TV#fY9 zaUkOxRUd`E<(j$AjrZQmR$0xksx_S{THO`DTEo0wEItLg zuQV%DyG52lGLax{-f^*Fx!}P#@vlG~6r{_;J!gQ768X@xhRd?=5?f`0O4QS46~wal zf|~qgn!*@ikk*z*>7$hHHM=-F^;bI8RtrWLBp8Z=Y20V2kqsHvcGFTIyC|i7Bcayv z6ryi&GN8_qlO%X|q=uN2WTG#o6euW8gx2&^-XV4PJy8XPD<`8ne{euw2Umi5OeP(R z6Bue}dIXbcF`3*imsl%<<3QAWeacFnYrcVxp*?rDh#{6R(K!hF0QE#_By0JgWwv-7 z*WXWPm1g{^j-3OQsAn!T-W8fNl)~fC-o~b_))Ryeyb&v`GO!?$`diV{%0jeBWy1nZ zh4ylJe87O-E`xS<7S+toM{44fHY2m6(cf8(y*?(4WC`-2BSvOII6L|yrFa4x)APPr|~E6Cqd704kWi<_3$VRzlfO%_d{eznx1<~e?3}{ zvRN^^{FxYYpAxdsR0vD7V13a{h{$_WZg0vSt)wb@IBrgkXIAunQ;HdRN`Xifhi8o< zfgn)!z4BX|z{ztcNQ^9ZID^vzy|$CE*H=j}y~4z^_$H3ANkIa9h2Hm=8Rb~D*vJGC zp2X;RFnHY8%+yzFmy!}bYxhL?`xYD8j$QxhT?gZc_DQH2F){npPCADokm9a&y%P)% zKha9|<0v5{o>_u~hR09Vr8pPz)*q(N80saRZ9Av|oCmwMB}>+A8EK2NT1a6Z3u=s? z!axG8kkZhQaN%u2;)6)FdO{B-a^QQzBL2e#%k-KUk`;MAz;LnkNRRCsYws_vC%iIQ z@3m`T$Admp+a5WeVf{xNZQjW^htwy-U7>kETe?!Pg&+1WedP{)RsH%dgD?`f(6|`$ zZZYk$nbm@;g{h`jqNP>ATB_4zYZ97HP8EGY7U_1QL#9C+Jbc4BZ?9iMtXjHt$}2ED zc|x~=we!UI`NW-_t+$-;Pmu?(^2NyZ@@QNPt>GJHeeMOUL<&;qvwwem??7Sl1La5w z|KKC7)E-Zh_z+?e_%vwZtvL?;V1m%t54M)8Px57Y!{<9W)n;X#($eZ^tNs)f?9?)lRD+z|Jy z{nmbC{?|YJTwt)t+xN3>1s}rCK%#cSO2lpA;o^eX3FI8EP9icK=vg~Gc-VE(nbv?? z0tiVoTzZi?DYT`XJ0=6;bm(e=Eq5>9iQcjvR5S;o(Sq+wxo5<<=4iIDY0L+z zG%lAcz+Jwk8gE6B9NJmg$&@UpKwadW3_4g7TclK>x4}%7PBspSCu2rD(khmkrS2P) z(Mz|t)cgVWP-|r!c@2m7D&n}Vur}v!qcZl1l81Qh@GesfBwQyF6E+tv2j7KgeJ?}3 z*;-gp8)vD^s=L#{2H;kgCJxV$?<#nX8Fh$;&P>}1zIlLLc4jiaY<;5VBWypntKpob z$eoSnm#f?N6d*ozoYJ-$L`JvM#l6PW{~ukcK_b?tLg&jY;K^AlC$I-ynySgGdxZrO zRGx+6E-80h1^D=&?tyI^an)r0-?ARe5vYn%u{2QzEv2d`YK~ap_Mr$rySyhyH41zJ zK(f$Ts1%i7dIM-R!}f{+Io+0nX=7B9VGK9vR{l=3Maa4f$5eir?E|KSU8Mk9Wf}e< zp0K?&NCn1@pe@yxSWO)0L^ztwu0%?gr@4CGy~J*d%n!DiQ}&502Nr|Mwl{#-6ih49 zHHZJvtQS=IuZ8<1HQ96p2#g);#!7RvqR)$WUV(`RpNoxWJ=#R^5O^#wIy-=9H`;*wp1vw=4Z2|b@`5Www2wDljs%R)Lw0PtD1*U~3 zgceyvcCw=7Tl_480RJ%Is>$A{O)1;k{xf0_?kW<+C!M3a`j+O!5DfCky7rgL89cg< zNwf{>kUo5ie%G(_Sel^gTp{ja?G9F-h3ys^Hnx=Y=WM+Qs`5*dqDvG|E7lx2QfxM{ zAcJm#G=(Zsk8hFam6?#mx5L`Sc^L-h{1sQtLxavStKK zUQ7@ey*xPn@WJ9Hx0YnPvSO#b&;CN5 z(JbzTnTPFszlSO!G$XM(MvW{?uSAAGfM3Cgs`Lh%f(-bIeIMqP7)D*{ zMk{jf=+nV3YyMV(zJBU>XhJhN%?WpRNg&J$4&InNvpsalI)BK)bN{y$ss7RIJggZ&la_J1DLdJMuMhyFQ?PR_Zhv7jLDGj`9}mmp6}nE5`KERe>@(HyGg&1It87xk(TJi+!p3J2rYM9w#GD42Gx}z4Zj6JbOiqO*Nm_{MwGL%XPNHRF zg-&T4z61nf5EtgxoXbw5sICfAXVSrt2hL$ln|nVCzV(ToT&wa->u{sVc*APjE;Zj1 z>%J-S0`8uvfTr0u9;jgJZMtZ92kNk2w@3b`A=Id9J2|?H5U;>;`|lX%5|lu`*72%T zb~&QkGp33=N}GIlNQf7jWK`6MD{-67Lu^`TgPJOMGY&p%{jvOA*2ga`_8yO;2GYRF zPffze0~!@wKm4#|SIzX{YF)MgxxS!QNX|`M*Y`XmJ3n8@aib0UqZV^5J_QS^~BZUDEpzj z>=QE~&sx1u`jvqp8cAQ=F3K9^xUPF@u$wLYV*X)m7v6gsyV!ca$Ii-DgUdt#jypSky0n7B<6Gm{eEqJiI+8Ps%8>FlI0{u7m|Q$d)EDAESqan*-4KX> z`Fj`q-vM2DNZ{zdAWmH7D3dxyZqOfm17fGw=)Q=<=IN9ag!81XrPsNpJ!Tg8h-XZx zl&_|W=-URc-q<{8aQcAz3_M!U#JQHI_+8+~`jb_?xss;}Wj(gk5LCsKAfEb*@=0|*^SKPEJ7pVheSC- z_ehOD=)&JZHT3)?TC(UBimB^2l;JY6IvbU!8=l$OA~_+0Q%dp&_p>m& zi)O_5Wgzx{LlE%y_}1U;9Qh76oN(emr}zpM9rwT$gj zMzcqw)w!U~)t?0j6jJYLjy9D^4usulRJA|RlNz2tf<|0?atRwYTAGMSW(jstkGSUf z2Zpo6WE6Y8oc#nk%+j@@&l)N3)vwjz_gUmQE|ql)HAb6y2{g2YV~iWiZ9ar0R^K=d zqF{Aft1uTLo8faZzB&88_?v2D$s{Jol(?9g*a-@AURNC)-?dDkDNNx?L4$cQwc%pf zfqs`cyA(lzHO?__eU$VIwp$_HoTTREasHlg%;r*`&#_7S!s6m0>(Nt@|7GxGn+{p* zW*c2#zw4B`IAy%rfvc_L2ASrLR3V3Wj?=~Rk{wR)^|x*M92h3R3IbgnfrA!I$>33e z@#8o{VSL&zW!>+2p)jITjnDSijxBfD?%tZE`@3Ejjb_(|4E4!vuUSdy6KvUJl~H>m zb%(T#P0RYG`_b&*SRy5G3oQ>;-lk_6i98KLhKr1u4MB0{B0?_Zv-F&9-`7F9t_TYL zmXkHU|P%)*KWkcJS z(CdVJN9n~o@!j!rFE3D`wIl3qxh zzQn-OB-$v!s_*XQY&zeq>P;N7c)-t@Ox#O?w(~RdvUnS!|LKyUqM2-YX_=)QhwtBU znk*t!8~?k33Kl=5vNgM|nUcdw2$0%qXl|^P+M-#~xlGK)laIDaX-LS>F5zZ*YP*<**W@4_wD>V%N#hcT=fnQlXlR!y7_P- zXF4ZeRw?sjIc^wq8P5~M0HxbisuW$j-j2#~(`^%G3LOo^`T9kLlq#dt_=Y>;dEQ!M z1ZknbL#(YInRD|@lo{*%PB?waao8RnKtG~`S?8@cHe-ofgXKw`Bp8!mW*+VgMVOjT z0!Sha=U&*fc5f){i@geQ(B)aQ1d1htPAVaYYjkE3D}#geehn_5v@SiRc%opwulF|h zw;L#pk2uDm`NPo1N`Ne=K4ks5JSI5n&aVA+b{k~pt(4w6Z5kNYN(Ar;i+Mp}-}HXy zNs-P=Q<>!-qP)mS)msz00AcA` ze5FYa#+gH4QtOM05$yIZS;q-iIgci`;PN$>r(v1We}@241l~of3sB~q%?kF#Y1Huu zSGT3Kuk}+xhshA)eb$5+i}(LG_(;OzsbxxmJ2oQE$}J45%P>nearWSdsRRhq`}Pk_ zEC{ERZ=lxOtB;+I*GZ%ZBFSx1upxGOQ1N8NS}8u|XX%|buBF}ea9XZEkr091tsRL)Gu|1Kx8v?NR3!*2|AgMS zLurtn&Ft&jf63U}LI)9}R(%%RI~!ZmmLhs^U+ekA`#;(U((yXZ3jSOr*|{`0jSESJ z*>!Er?AW+$q-KObXaxNQY3*WkTNNo8CG#HF@8k4;8-01GFlJpia5Q^^@oZxxqOG@R zE0dwd)}%Fbc{fLDkNIr_7hGrTgy%wajgjNbWun8KH+w*3))eArh!PStBjzhRIo9fq zxg|$ENg%MmF~1hz_e~BS7QC3kOwH^yc3AD^%^b*+U7>e5Paf+ObU5pWmu0w8_m*P0N zeM+VWI8*qQCz{i;AKO#~l?c_H40?GzMa5L4*V)T9I&2LPf)u0-@0Yp-B& zzKGC#bXQ2Mp@EI?^ek}=5BMJP;Lce43F{-0RG<;>TKk>!enCfBL|clMU%9h09;*wO%d$IB5jXxTds81&@Am7p z)(T5hDbLWiJQ3DZxTs}he1T1m{t9a@uD)v8L=|Dpyg?qTCzVa+6>g-oHBl!8PwTnt z!YW#7|KPZEDw=3x>)oDU=_PF;y?$O~=zzcHf`Y=Ncb)7*x54kYhQKWc+>g>KZ?Bh8 zmzp<9fr=gV=ZU!sXMCw7{pZQ;>Qug8ICq++#w@W$j&Z#Y znEybM8YWoaoJKjKuTjeottwP&-CIp-XI@9KT7^Pi+Xfj^tefKxt12rhdw*-ks4_p? zCy+SZtig~|1Pz<+k45Nt1_uFm-#jNq0oBv=e7Ol?RS51h-^dtrHhz}`$=1%8`b1B7 zrcSg+3HsOUoWcs(mZ^6=e&-WrtmUwplx`oR?NFBR6M>MLzZR12(*@g1;ZWDi!x!T? z5Hh(-av~6hGA9zxm2}c3fbz`EV;YWM9`UWpq9f_O2)mPzfd&N22DuKBrKS`(?m~HH zvXCQJ49DoGF>L%Bz`#!%rLXSbf|WzhF_lU;bP~q8!h_atIWaf+ENCWZ)wj^>Y4Cymsm@{ zyHt)|IoXfFBThvJ+0FXd?L>-8cNOTEFj)BF46qyIWB{3hF>x`{MqF)xbQIWqUbNWj zr|6Klk)e1q?^*0^YT4Xfow=#eCy!_`fbE_&PUp5@Vi&fne3#@0U@=B}YbnQk-`IIvU z2opbBNNZ+&yX|k4T$pzedLNnlFj1}1D6!*(r}LReX`N!HfdB6UvHg$MJ3SZ@~2vLnjR9BMO zw20X6OPu3tEF90^p%dH;r;W3Ogza@Mfh6@V`*n{zOGEg(+<0w(ng>9pK(Eg&FQg=n zO6Gshn;~tOn4UbRN6Coy6=0?zkpU0A6!>DJfXnay1>{d8r%dkpbfJ3jzXd!#D;olV#|H5 zh}$rZqMG{;WO;$Z&Z_SjGRYcmwUAm`Iy$8w>Ch71HD97u*JX7SCDaLHdAJ5vF0w<# ziTjTmqsKFd4PUw5En-*d)yg2Lr|4SXszA>iVN1yG0J$^s(X z+F`td2pWoBZ|xSfwd8tp3MdPX2IttY(ooz6*zS64cZs!B+Q^CP1bV37Xk9AbUJHIO zKH$4Cv)>XX4BQ`Y>mUA}=$C4Vvy459dOfvuqvuO;V>Kk7Pi5?BhdyrY(`is?_VP=Y zm6CN8!x0+-gKIxWmwi-YeF!c;N9NRzSE1~cm0OG19X8IwBVxNlUTy@%)|=jJwVmCKbr@SZeL>7JZL zn=0a@&%^EtaW`hFsDF1m>yN%-LXp{!uo;;`!Z+EPYihF8L5JOn1exiQc>84D4veUV zwCwZ^Nvvp)Shx(>=Vt-2igM(){zZb9`~N>m<7u_N}jfz)f^ zS@}Fite$oeM}ynllwFuxtQeA(M)0~i?t=tTsF_c$8rHz9WE!uDs!&~Oq>zAs7$Wc_ zX`H={bpWb{Dm9iu3XsrI{bLR_5Oendu00^q!&faZMkB%M{`5ZfM*n~qrw-*KGbxnt zA(MUq!ME=<)4xgU&uHJ5nOTEM99G*MSEk;jm~e&!5S*6H{RPIKE)^Uf?PM`p;>oIO z_P-9Zk;{afk_Z~5MS4mj35bc=(oczUVXqSK$$uT@@;D+Ohs95kgfxjWOB>J9%tlhp zx|${pWgJz4V>~=FtB+7L)7TJ>W+()p%=7OtuDpVcUOaP>LrF!@*?R~YJ`Mi*4IlME z9N60TmBK!@`CslmE)G3AaMsfYvDXekE*&7G!%xYEX?H{1$6+9i-pN||s;JkoSl_2R z&EW|Fk^7bE=0FQHVh!~wQQAs?3LMoT;Z=XI-#{V#9Uu_0WTP|CQ(3p%rpNl5Ce4*J zdf5|}evl$Kdd5WS8&qT)BK0Y8HmiA2xtg=ZMfl_oSprdeFV0dRWPv)lBP!N3*f#l2 z7R#AZB2~gw0~~6p;5##*zbHKZf~G$XO4mE{Amfu(67h%V@K6x6%Y4XSrgnlSl`KzJ z(}5J#R5Ya95|2UPAt~$C!0!R+ykZ*uudOL2Z>f03cHdmJuOcVe_N?*6UNCY)XW%$!d#O`u=9r4pBWlxw-Z$; zJwyM5u6<<+znJ1S5_f1peS9Ta9ell1Ao=IlQQV{l8yS;EJE|g?f7t&Pgq2rZ)#NG; zdkzPU7dh6MUZ;(6X)Ic~Cq_Lj`p42^>IlG%s?l7=gnZmsnsSICa~pB~y{XnE-)lph z^{Y|njs3kPphhm09!wz2ffnI(iA3<`hAYf+L?RyfNo9uB@4Uu1P~;q3@w!;97IP%QbvXzybB;vdYox%pAcND2Zclxdw>@4f0D2tTr-{S zsQ+CIRYv*GKZ_Zj^(VdmC!7B_zy|>KQv(3NKfnaU{9Fm)VgFP72=f0H5kL?SB~S;j zAn+ClB!~cr3n(}!C#V^yH)t|w7w88V4_Fd76u1HSI0OrX2gDJi6r>AeE#xi~I20>X zIMgGw8T1AW1&lS!HmopgEgU_Z4O|mE3A_{hC4wG85yA(eHR3ChE7BM;9dZH+GD-r< zUsO%hDAY#OO*9lVN;GY>VRSrnQ}j*@7>u9XUQ9*I1k4jGeXJyG1Z+#}QtU4r4V)re zY+QTXemrEnTzoS8T>NhWBLXjiV?umFg`W~YSWS3OL_}mpluI;8bVdwE%tUNV>_J>a zyiFoWl0>pXDot8L#!r?{_Cc;eeof&-@kmKVsZ8lj+56*#|NQiW%#NoA0|ee@00PL_ zf6n=T<@@Oy2bc)B^+yN!Kc4()cy8iNu?VyMwDxa}J`(J-`mXAzE!TQ!%s0W-*Y?a%tYog{DLy7pT7RFifphEt{YV@v>9- z4>+Nm)bPJ|FflYWG~9eK$Rvu4c>PZMc1TAJBrXpC17wSUi~P@h<3qFT{{G4S{^gP8 zu)x3q2w@g}Lq=0mV?kgzSlC-I%-!ygdyqw46--=ARMq4Rv@ab-Q6@VR&&vM(d4e(6 z<(^zBta8!7KqSDzB*Nm)n5xoj#=n(dXY*Wdl=rM{c4F6fmUr}=@*K6C(ro@9;lnS? z0RYd5yH>t2vv~pKUzhde3#7P%AU*+5x})g$hM*|vW5_x4V0ueI(r;;ksK=ddR#HO#hN-+Oj<)5dU&qDu6R-aK1{4rirOm^z` zNAeL5IQWGxTytn{epbcJ$!5b3#v$H* zq*qA@e2Dc~w)_dS(xL=L)wXvHCUQOFwxkTcD+=NwqqE{l*O>pxu2T)EYN#fH-67Rj zuveb5nLh7P2pCF4=e9O6x>TV^n_6J9#M^Dq+`_8CzQM~capf^9l4XxDo)Uol$#CJr zqothQ(p=#`9m-tQgFx8~_}&^ETsGiY8V!HZ#!uzl8}#8@f6r2wHNOI}w@a{&>2`|M za1jDXoyeidB~^BTWSf1^dM#G)BjPxLa<(6b6$7=xJzRj*=?9x*f(A<29@N_xtlukj z8(BoXoZxhiRe3uU5*!td;0r_^5<+e&1%%>(>VX0^L&dp*Ktw^8{}$#Wmi7HLHO7B# z+~-;Wf{M(oDSb{(o}crC*WNE4YGZ!<$Z;ZE7czns6^(5iPNl)DQ;j0B<=1W|&J)N0 zLIcpcW7yLvbuxL#SC8s#?zFG{k~iNao-dA6%ghr50115qUO5=kJi|q;DgFqO8S27OhTN zlE^SQOL6iSQwk|zfW=gz&Yvb2CA?BbQPmiRhI-19b!3NKTMi94iPZu)OAQ`@n)Bfg zIB(r8IdWfYgcqpEz`}#j%|@Z{gmHo85$)jRD>=OVlr0@V5uE-g`Z?EE@7jJixU-a4 zCG=)r&`={K{n}F?r(nZQh(dAik9T(Cz&fgP`YT*S9vE-?4z(oVxx)!A&%1y08Jgf;RVhmByqg=Bv2108`=KarvinNrBb^Z-v4;^9!%H(?d?RNSsn^7JQ>pKZc z2nx4}VMHpw*IW_nRLTea0HpE~=)i;uieM@%IL<8Rt|6P)hxS|aO;a9)Kh>Yyht>j; zU@G)?iK`(2m9#etD4kVRM+s@e01HpmT|!LU89%=|K(4(wi#aptpJCtPkm-}cFFJW~ z8T_BvJ69@FeC5$12=#a=I+w;bm&!9&{Yy8ZHqL{e0-Jrsxj}!q7xHUMGr?torD#&q z0Fhw6yVwtvJJaQ^#CluP+3|*3gVi-^`?Nx=P(2KsRY|g!uI{j%DvKHTJK#-Fq%((W zs9Zh#08Gs60M40a`8=nSY-n(V$c|tX4yqn?DI=D9kQG46kKEcRoStGCt4M!h{&=4<8vv z#aJSNqu^ax$EI zaYi~Rvz;yMFk79_&b5|-lUSn9_`tuA_aFUw2@9Z?VuRFJ@UZ71aMe9@|9x zGoP5!t!pMyN?iP_!dUtkE;k8GWPv0+H;wOh2ONPFi&$|v5knU^RHyf?m_AMD5hlvkZuPAWq_jsW{>CT0 zg|blYDpwbHW_}}-~*wAp_l+xJH+|cv@v=IY{DR^c)AMi(L zT^7~{HjL1g5Ubx2Xwuw>(NHy@Q41>@6C~f3ozzLc6nIohk)0q23I-)#tx+)nGa&G6 zzurLUX?tg92Z3)@@6z8tuHL;in01LUCs?Ybs1rLfLt9lJ%u5zqRa<1)N)A~Dn}t=3 zds9ul*2$)Or=NDQLa7P6#KqK8H=-_iA?uo&VUZ^=iFJieQ_4)S`r#Am4gFs^g>^MJ zC##x*)&<*Kw~t!#AG^E?HZOIZrzUp0ZFd9mK4l#5idU1b9yh1)7f03-CugufNL-x! zEw#YW+FMEeno)nEL;XAx76`UM@oK1>F~_!wd7osKC6Da-R@t87+Pt|Mw#~^txERRe zsDYX+y}3@RZT!G_SzI^Qz;cQdOFo{(-Z3I{T(*4+oIoZ6g}ZRI?ZiVOJ?gh#bPd?3 ztqt8-Zs2-zl^JY}uR|WrVZiL~2K<@6jGNM2@W{~O#Xg#pdC#9alA0rQI+?Gmu;}Q; zSo=|eqpfd|i{U2vo?p?d&|63#5fh8kS04kv0%jVK{%Uj)c%a-gT z@4;9-ku@F*YQM1LoLUDGN{Y$~ON+}3OpMG7O^wYBZcW!?NUm+$eN69l`?X&rj`w9) zWsdiCP^PZ?WmM<3`*lDf&*w#KNn_9Fbx5J_-^-Z6_rJALy)b#b&gZk0vb_Kyk8CN9CW*AUKZRb(vF-L12^-sRp4kkW?yS(-j4&mT7M`-Mm+~H|D|J~(s zx%geq;*D1(>ArFW~rrE6envo%`l% zO&%1KVbFMCgu$9D>Vhor_p7zu_xgZnQd6^Hr;Yl38vs1CA)z7xl?8(x!jsR-@WGX-^qjEyCu_uh7 z*I^gY?D-X??S9Ph4`*u;DbmS24lMp0i)^I~rpgtodMf)%0pM!zD=q+k>MsCRbH@(- z*djQscm())^5fs_Q}OsZfs<}Ca@=XAhI-RiE3ozs0|0$%4*;FwG9?G4Rt|A9A}!%eLthL~ z5hhYIlz9=7#fhLTpzK79Hts?j8WWCQfh6zi7&fdo>H*Dy^`wGqe+Zaua-BoP^#*kY z3z_^znGb}NHKj3Pq9&3}l9gHI(a{W=QeL@bkbp*+=_Htdm(o$X9YqGJ01gn@2p|*y z0zI{2&_qe=)m}fd*%BKaA=oLEO*l8gqOn_# zPoOow3G4Z`O&=u8PbWhJ6^9~s9Uvh}A{)1{B_X$fDlVHsH-j^5HaNj%bZ6Q!;-^Gl z@?y|!gCyYAg>S@lK9Oa$%UVw{mh~uOoA__b- z6Qm;q`)u5Tut+)VDp`kkf-+s%4T>DP@&Mu^AIgYq-U=%_>xi*s5^~9uDv;S;Q1m`XrT zUKx2RO&Bu;GwG|9CQf0Q^!16R(*mvNZ8Mo$umL-4#15OV!)ENT1v?y# z9ge{c$6|-$uuCQ>RcVWovm@ji>M+YXk%gtmk}~&QV^t(aB&QBGB^nT=E~i<3zZWmZ z3(a6 zn$mj_ystCK!Iic{wgNEU*eQa98yRh@2y8{6%}jEVC#rHLtU^u=m7s%xdaoh~;lfhY zc_TE4yXZ`VBp0XR%WbQ`C>zym?nl~OTeK{eJoRH!1;pZ*!L>9dg^MJEES9^1it)tc z=`G=Ynl%i8^*?UOFQRJ)BQ=Z}WGnSRRR=aIBx7ZC(wAzvO zD6-?cnO;Rs%(?|KZAa$J30Xj`gw=<9QNU!Wk>GD9h-Nhau@L^+B=dhxp&yyn@<-O}{5 zE5*kHssQR=MuxChqR4tt=>lLfj@8u9Y0O-irgcmcXAYHX4Zzuq3Wg{s5D;SKDqIf#!G+&Gn$%yuHMM`PzX6+JO=6 zz(T`lkq6OY56Ufpl6)-H`2b#~^RZm#W7IHO;X$<0gO*n%>=%B1`{CoLYCi&Ve04^> zN?%{^jvvRm#yO^n;SbrjB!&SXP*3XQFH#LP+;ad>%>ZaGr#2M8Il(O4_Md}`1B${N z-~vY}DarsO*_nHD?kZ#;jShxR0XaWF2-x}U&vQCcwd4Frw7gBEB9iQtl!^qTgpx@E zxJ0Fo>eDGP5k<>lazl2sG?hw75J(dlkw_$0@Wi*OsOd) z<;h}WbWmEG?f29*1e`jG)nnRhNxZ}wEsGW8dW4iuq!A`n85;6gNung4NDbv=rnk4( z_?&`5lb8?_5@CWSNw1Jnqz01+O@%gvlvJ3!@j8{);i!;GTAH*fCRxZ8B0EJGxDkCR zuH(ssrD<->mdv;jZU)8?Cn2tv#FRr{Rtw9-MP#yS#O8yXIv>O_R0#w+uR|0Rj(&T> zeJ4$=5U6IbCfYkh10Xvefi$Mz)$xvVQTs$8DI-oYVT!v3=Gv@&v?9tdulZMlFHSQ% zwUGgRMEXf!_YI8z%St;C1VAvHmZ`6r?x{Jj3xxh?bMI zLt79$Y|&_S#X<4jUp2)QmJ{)8sD0tpBi$=WsXa}-&L|?js#Zgs6pAON4`IY#lIlrW zmTQ54S=XP#5FBzsvZW3@T<4R+rDtHpb5k)Pa;N;%uV=KuS?|6 z^i1#RRV-+FB%2;#K00n^4BMito@X{Rebt~&fY_3z+qWQYv$qZd?3Aq9m0#{w&7X?G zbfeW|jzTxXH_*Tq>C|;8UB{viS47ym=GyGh$`~TiAB31FaGf3}5b;Kd?rh1RPz8k> z)8{InUV2()n@t9K1WM#eaV96(b{V6H=2Ymed9yuzJz~nCo~JuWnxypK>3-ioHKk(2 z9x}kj0sLRdCWSLDdIo#L?c^$bIdf{eFhq=Jg$hQ9n^j4sLHjn18LwQf3z2C>>DltQ91-pXfi zjPe)p*t7t|uVXEE8d)1Ns$GA?wLE&Ylwd`;!xpRe>;{i!yxx7g%Bil&OS%owo|yMJf)CgRgbF%6aG@`kjCX{ZWw~H4 zxT$E=PdMKt#G_ZE)?mtr4Tp~;+x}3B!>-*s8hmyLL{75bc{ej0BcVSX{q+svv#xha z-t*lF)}DwMt{K~~auT|#?7n4*dGHoucJiC7+{^`7NwaDe>{u}eOB)1vgW|v=*t5Iu zGVpC!q4@QF1^wu9qTk4kTz&hpwH!L^6*D|m*WbU8jB%5bq4wyJVrOwM!o*ik1a^lGY}TY*E7$)Hpj6c(POo|?!PdkhQa zKYD)m z)$q&rA#NQQzPC_FMZ+jQcKfg$Lr=pyXrO+@)2}GFqb%vZbBN1J0lLc*6I%mt!bQFi z8=zx_#){UwFOzpPQY;t#(115RPD-M%WTeYHphHbu8Cwj27^zVQwFW%Y_f}JVuj$#$^@%6vJ3V@FAy(l}<#PD+lW71S{lKw+lLaE6h4N5dsYTLP?krv*Bd4hl9`=Vp;B z71E1lm4q~52G|=#UwPX`1J#7Zyi`>J9!los7cl71fg~|NH@=jRG^X!KgKCtVNS#x( zO-U|#`_%|Ev{9dhFn}|Y(;HjdysA^6U)omF?&^9jNc)6tuPUs)oE!EmfXGW8p)prT zpB^pPmn2i6?m!UOW(ijn1=Q0cfI1Lnavm-ORV%;)CV*AI{4vB(ut6;(WjiB{xXlGY z+oDFzKv11HX;1&Sl{V@`g?GnZ&s67rGK*=*D*fd%sB9KoJ|5b!58`n3(n9-2)gW3c z6A{n*ynO_sZCI`Oq!~7g@`rr*i+&d%qoMXrE1m6%c(+h)4AQFa4_gFDCg;vYasE+X zH4}tZk?$I7U~uuAvxaC9^?bg)lj*d>RdO66bL?EcZg;rhD3Jc}Y%aiddGVCH7`0Y_ zp79O>JdaMKD>FX?W-;G4mX)@O*Txbavf)&rt0CeG*^B$j$8I+(h<9d$)qPzol}yI$ z5tL%j{RoY~LZnL4Lpl>9z5thU%b)Y~h(3+LQG%B{C8)CNLy3%pY6F5S(TmlH@CM4; zo;&h+&~MP---F~o-IPc=vAKrIT$y=}j@AbJln&iZ&KuuvS0m=$lv2D@g$mw>Q95d+ zP(ei}KRM2k?Jnx7Ky3dDSD&>bKLACf*v>L%rs0IOt{IuAV9Wl82qX0Ft&9zo%WmO#X9X)@LOyJ z0uv67m&>@XujfPv7M{eJK>QJ>;<+^I_ru}=i$*|by3GPj6#}cKQu9m#D5DqdxgUA6 zE<>I)ck>-dr3u(r8qqz|_`iY;k})m1uu>!wY47Jl0E`!vzc8tn{^mu{Y2|d(TI=4` z;QnBlvYFhv)eTW)WU5aysv^W+tt%G<&!vbtMQTCLsD&-SQOIw?S=L=zybq(99>_&k zR3i?(1TG^lP#I0%Pm)EKt6X-gY8-%|GAZj2h1+Yu%WA0Qu)VXal%&x?d3H7B5fEst zc=@(18SOa{nj&-r0YkZ$YSMA>G?GvE6Bc)VHVjPBNw;Li?}M}l$CY?W3D^`|pdG=jFB|2Gx5GDDse``9o{6}tPd4*Zb6so!Z$ z{>q(|MU~gfn&$3l=tbQW-wNf894!R*$zJ^om+tN(Ik3&Jo*vJJ zRlhh6Gl9!KqoLAE>*1Ipj@$SplvO$g)T_{_74YLqEpry2q?N?|h{P`Q9{lbtsOx&T znWvIXc!Ye~U%Z?>>Xul|B#)CwWr%u(Fj==58#MQ!*3RuB0p%aKk z%NGW`Im2PO!J}ZhVc4E0qgGwR z=tcUJPy=7;KL#tRW5jp@3F8>m#Bd_R%6K(EX#6ubv{)9<{%p&dJR7diKe6jeEhbkv z3J~mKs>g+~yqEOcOa7UJ&W+=nVIU7-rXi+J7Ll|)9WkAHT zD3V33(M;v@ktQ*yD>K#Vz^g?Y)PPHy2yA4*7`98L!Jbie&E}UKv7TV%&>qB|X4%Me?xUUl=>zE`0cQT_Qw-(bOpL*!;i`%=Y>-PR*(^R+sQe{U-xQvaeY? zlNy|FW320hn66!Nx<6?j8K5)51PHASPYy+`sJv}{3u)*qfM~1Ejc3WGq}W$Bv<^vo zohsqlaxbJB(+Qw~&d18nnhn|SxHlX2g@$r_! zjHggV#BdlCaA15Cf)mD9G0I3VIoXlQ_fd-y7Uf7K)3|VIim-J9Ew-!LVO8qjkb>Hx zGfb`=p8z_DDt#KoMHEAS3`v3k>LhMflGFZnLn*1^oXlWEdmc_ntu^jRgIzhPdQZu` z%Tkxqfgson8aLEaafQ_h{?HMpNT)Ka7^1aZLiG+Jx;?LYFopS)!S6;ax+^=Dy!%&L zX<}tnn(j3I=&nX(UZ~a$ts@?rQ0Q52^Zqf$EgjJbpQ7mLLW0P ze0hn@Qk1E~)ZUrJNk;#JHjz4IW~3wqEe%G-Sx?FX)TxX?VHe zmjl+qXqp21Pa3}dN5UEk=jl!4&^nyKkfPY;fmjPjoG9Y4MJxL zRyH&5l8Q>TKW?BS|2uTr>@zC`+GweM*Fg_z{IU9Epx^5ETjOz>U{;=4*r3|k8s8CD z7h8q?!PB*CG$M=;2{{}Hf{%!88&UiT8U4L2oC^4d)_e>7K*=IFfBGSjnFB!_j!;Bk zB8|3PidRlw8=3EPt*QD8p+RG&Cp`)0uT-o`R938fzp;7etloV=X+>Pcluzkjr#9cy%dsi$r4^mV z!q{Lo-?_^9Ons?iapDy*Hu|FMc9Vqu%ytF&)Lb@p!baFO_4CuyLX2A3kT@xm38keU zI|}LTtIqcc%WH-=8Gk>OO@ z#n;*nHAswE^#=;6&Nm`i6j^2>qLamz3RoMt9XaGGC3>q z3^!EOO?NL>q3i{Qe#i3l_2#U(VwSVBwcEE09y zQ@^Ei7F~eb0QQG7v)Y}NY;_jy$4mMrAC$>ld$KrNw{V*8auJ*!*P4juK_}snnGqhM zY?ue;y#{R>%Z}E1e4TCymtQ=mt7%zM^Sjnh82SfBHk*Y1GZT8q?TjnT31p?q-;s-~ zxfX5BR{0;ydjYD$}$t< z<{c6(Bn`ocDJ=@E_LgH4{5X3;lj4Kv&kqcJEtHK8DJa`mfJ#UtJB`Y{rNU@NC@p&Y zU-a{DbALfaJg5)NnsCkxmznzgg4X(+1c&>5TxZhF0b7d?m^31G%X=c61!?H5& zvu>9G2UdLG%|)MjbS7U)yWeJs3E1iawxQOn5?7MQIp#}F&MNgJF^dcZg5~hK_W0qq z385QR*yf&h`a46jN=o0PX?$K;;Kv0=^c9odiD%EV^7j})%PVHPsxX!4u>lZc*-~sS zk6N;LG`dg~=eGPb50T10z>ZEz_ig)-)GsjnAWbivk{wl`iJqEVwk)C&e)6gE*_#0L zaIDz1dTFH?9Sl|7OnF87iam7GJsp!&N+s_Q(eK2*_YP{Fr#!ptw*8qk&!~5tRVs$9 zr%!FA6t}U4bg{=p#(H0o;sy!U{v_ue^*brAdo0wB=KYx4lOG&x8nIc!Psf$T#mgny z`G2#_%{5x1hiRJS_+~YQQ&kaPq(@9&OuDe(S%p;j(eELd`WY5)o3ngxL{K4Seaj60 zJ@L+vEv2aR`ns6%>RI_}#kJ0b>dMJaHdoaz@k<8ibk|!d#%7_!6Dftl|FaTjM6mMp zo=}a!_p(bMnf`*-6B{o)2yAlO+t{gqLdvLETX|WHR!TPP(R~iVeZA{?`(TIz3w3)M zNU6qOUT$Mmj8s9wApJomC%TLYX1dZH(I_968_26~^8mzCD_5|yv*3O>i=C|;#lp+! zKO&l)VCm4NA`+LaISE#+2KzyqeC|)c5Nq?TAB!!l&d@yjy*vBt4msK8bsunCZj2AE$7ju%d!SMHE9Nk7E+|}oTfz)d4UJUJUzB2a znNVf^F(d7KVZq#iT;D(WiP^3sSuP{jGMvElDQHEFR(`*oq$ViY;C;Ea1}vBd7P=+( ze2ptt6jVQOiq}tzuMaF;QITSuNOitfI17{IYHLuGR#(JW*-Ih|HB1G@Y?NXsqK-0r zc5o)n5^`B+EI_Ru>@v#YGbjFR#|JB9+Fq(rs_DkzS`FT`JH*N-eMn)h7}96vx)?Mn)+@(-miKjsr%2eVYR=H$!II+k{d zK7aiD_LD_hz^N^SiVfxEPvqx?Se3TG`r;m9souv`pw&GtTXh;er_HTFI3nE1sKnEk zcC`rQf5o}{o;b#Fq)@u&q8&#^B3ij1*4LVB7sxf; zpd=7b%I^=#sKHVbsOzukLq4HYY^cBwd<(Qww71SzmlRu4x(e611afuV$jQ|tebJ!G z=^0P+?U<1>IT}A2A9hXd{s`b0%@ZHR<0d03oW3BeXwIv}d;?EySwm$3f|Y)Z9+R+T0%7 z{mTEpicZ$`nnvml=N_(m$;|#vMz8*VY~uvFJ>Vn`gtUQ%U6oJEmBq8$--tUwlY@lK zI_KsKWJ1-){hLBct#!s|N9(Ncc-%=@EmGgcu7I;k;x7X%rV#s%V`0BU!2I0?<( znratT;d4JHXWNm!qh8+?H+4nD(cG_ck5;Uhik+G%JnL+W5O1BcJHd>%i_VFfpaSnt z9~V<}Bg?lI-3i~h^UgSADdkDO#C2Lb@Nd`!n?4X0YjR6ed9o>Q&xm{?4n#T16b^0= zKT5>h`5Q8Ic=HdwygME0q>y;$6A@?x-C<_fup8DJ{vB zzwG(qR1j5kPz?eZQ6k|!M9#zPPm!l&x%c|49iC#mLI#R4(zC3aNH56qu6|pw?^;lBdJCQOr z{p=+AZ@UMb_p5u+mV&m*A9O_nJ!lBs`>M(6L1Vo~TvAp(u8ac%4tU`5nV>Fs=JG&3 z08fqY{-Yxu5^lr$pp$_|UBAjKjm zN!BDOE;(3mutZWUYf6GdEjmTh>_t%AQqP59vu3CEO@mXr)4EyOGNPrWj9(1naSR^2 zef!0am-2rz602{Omf)$PRk5~iYd7MUl|LuU#DGu6R#sM{HC`P7<}!B8fNJBVq=w+%K73Me&<734gPI32j(!oXWxSO#3f3)6<&CA3n3S@ z(@fa8?beq)^5rW4H&&B4g~Yz++xMvpoEMi%DsW>weT3K}s}*2-8-GqnC_oWkK^i~$ zWAOKmsnf`^6Ry5K_<5z(OsFC_5UdEX>Gf#V28ju$$9jtPQ7j@(ldzlSGo29@%@0n> z+hV@w3Z~VJ67Hq}^YezQS+zsZ>2fcaF?wgxN)(Y^=`V|Fe zW_A1V;pT5qCds8^uRM-#_ITcT&W4TOyCCS;9)Ys%1#|pJ2#DNV`E?05JGGZ`V(KO4QcNdwk5qL={p{=zf zx(usm%*6HNn59$ zvJ9Ky&C3IhW?4>u7kGo*(-7RrP=vy zL1zlt@-0o;ER=9#Vk4@(Ro}O`))BRI6!*hsQ~%@qCWX4rk#A#J{<3;kw6xAOwbGyM ztx543{pLY<7&^9}5IX;MmScavxlVvqLE&z+1{D!o-h3838+)%lH#aAvSiko;OA5w{ z8myUtSrrQRl~{*s+8o`hFRd&stdQFx&+fqDR)UphdbQEP@0&9m$7^Aho}gu?q7Z@i zHb<-RxSH{eTpl(jyV(8@=(@35reZ_cIc!FHh(&VN^Vz zkZ?wOlDn-n5L><^3nP@$unUrYPWi#c2W6gIM|Yq=uvovq>-HtP7I`v6W_fHw7ZMwj z9Ao~~5-ly0f}i{Q4Nu*RXxM8Nf%I0>Dw@mw>KCM`rZ^^abP3v8VTsFpWudy0sdIy% zhMcXw(EByzfE3d|1BpKzl~Ho6TLGF|_S{-mBIvm!RwHMUXhzE_Bny8h)|_6&x}BgV zw+6JeiY(Ob-FdluH#gK^$dP+7E{aiTx6fcNGHAbE*>>+l8F%b_aUrPHXlpnep+rZ? zMcpC`_4V&v!qr+-N^HL0D^`4f$=c&rw0m;;I1h~<=y9JLT})r ztGX#A@qTKe$-!4kMjAXiO^jR~D{Ch0TRRE_4D>mqF&uxJ5+ z4*m4I&A6X8y-VKoB%z;_!ELVJekV}QsA`HMH^kBi^j7{fL#!#XXcN`??=v>)^9VY9 z*zG8@&FHktW=6@f*I2`oWxq;tY~?9qFzUvs9W;^qW~y&s0+ zE^Qxet|y!x`eJjcI#jn^pYox`CS3T>?cKC7Y%iPsX5+NsG7P?q_zGtVWrUpmt|dwN z=AGr?+1dine9l`wZJMZ*7g9LNLut~1cRwD{uu^TfhF?=uid}pI@4~$@GY>;$9#32T z>}C=D9!+kx!(+wmHh&4%<#6VQSe3?~8PO`IwzD?y$IXIrd~R-enU#Hv8-41K;vwy7uk&Pk4b9wvX}07Ls{t#|wAtZl|4_L1?Am4< zA1+*iT2MEo2SJ_LIf621*$~PzC!q13axUS!r!oFAX3B`~ferTdJa~4VBQR2|uAll4 zGy+$9ckj+`LO*#!{u5rOOc_htO)gAbCy)r%r7k2nnIB#`647YWU6qxUhC|W`D=)j0 zEh)7$RXOyR*3SGwYYVJZ!H^+tB`B+0`xeawf@HdUmMo)(l(iq2lU~JEnlK24xtw^_ z%iSDEe^zJ@ME*AY!h8;?#?&v84TlCvCRk80O1H^*D2#~MuDLyaRlmGJQYEQYjX`1b za+}?g?16Y!jVd-2tSo!yq0=Wjtxg!awLaaC>jpS?+$*&j>XKdv#k;Oe{`qGoPyZ>c z@xO9%jZEB9x!Ijom|6(+?6SEGx;D0^G6Wj>-p@mS0FZsDd+&YKI++fts)X4SmEjOg zFU#^C33B6Ja-W0pVeZS-^)E4XzsQwP`HGjR=uW@f&lrERu;&^24$YBK7J`?$DpMXn z`>)TVc|3$en25;3AFD6Z>S@ibV3qb?L%F09m=frBi6sUfE#L|GaE%N+`stM~Rr(d9 zt)!Kj1_T~vucIn0tFgFr{U@eKNv{HQMojmLF>46lP(;ZHs%QfqvKC|a%w3?1YfU>xvx9zpXvWN;*VuN@aS8qM`4QwZ>PFh4gd?c;fK4Ah@yy4|q24ARrvB)S*Egx1-``*;q&b~G@(`Fxfo$lx| zem_k;yquy(tI^Bwdam)vaYTCmKXG30$pwiZ;&kqed*i1NZOV;`d3smx)Pauyq? za||!z!$e}zZ?F>rqW)Vi9P0Hf-Ou zO`R=bYI)>}_43z#0(Y-pxATccy%A3O!$nF5|K$pH4HPd>5G?KO6&}b!{pO6bx1t>l zS!PUBS(yXr&+>V<-aLON^Tgfu3j*fu;zbFvWr^;)4F5f}_4k8YfIiK&XZNzIKB2lE z{qnBVh?8G09gTrTI7BTjJhaGAMEeI*~KyLu}cMi<2&)c1=2lsp39XZyC`fsF0Pb{7juPEzLKfHr`N@6JM@?|_2hIz||Pg0XBx<^PDIzR-isrRE%0HNm8 zM^++u0D{R8_T(N438v3^g46T@$|8yRZdGXTTn_) zvG8)JCMt(#nL=_`a{t+O`p&SJ78>UCpjHK5!7bMt%?1;v>2E>5z0*GXbU?J~iQ^N! zPZ#Y_`nf2j)v5rSh{?OkHh-@z>HG&HgGICP!DS6bUBtXKg^>j)DDfb`C6ih7>p6 zL{M_aBo4w#ftpyrN1!L4RIMu)Ga%ez^3Zlw_|+heVgarZDB+;k6doF-WS8zbIEiUd zo-%R~7Y;l3=wX<6#0On?xE2e>*tR&D#i*Wor6Jn`t-QA*SD-gVTu%* zOvDdh64-yNqN3}KBoQSo5UW()rxt57@{6&3;xxZwTLPh7{FKV8zAyFQ#DuTwpRI_6 zTC6adgcJ#*>$bdZ?Jq&U^1H}S@qRO}<}l}(sD~M15x14w5M2-%&<#WiqPY#+O7ydt z{U=s@-3(r?l__YUfJ;JpFe(;~ra%Ur>1*fLGC3u{Ob|hg%0~&0kkEtEorfr?0EX@H zhqSbitAC=eO8L5nTbjyB-D-|K-YE(eyR+i-YDU84wp(;H*OX<#iw8uRKH(}jBm^QE zKxB}J3xbNmd_E2xQqdyHB1(yvc%tD4DRu_99JMIOO^t_q792U8m!6WO&^>f0tMbJX zP?EBgvG~*hsi;m%D#coam`+KQNiKQ&R-|6?Pg7ABkGLoHWCnO*dD7D+J+9w+Y_d7m zBBqc)5u)S?4nz$}9O^R2s;FnY+d7nCxnY3~2BH1`hxVD7%^KLEhMfLct9^%gah*g`)h#3xT%i2LlU6gqr(_&>O4Hj`{dYJ2Tb%gf?5S&qpT zr$ed)8mST`NR;H5y|P$jaY&#>h=C(9EO3Rg$S8Z{vWu$>9WF?l;|A0t^Fpw*xfRMv!C>hw@Wm9Vs046!)dDTxH)~?8LGnC76NG%%$ zqfAbxi^Y0E^7U1pq+u9=SCD(2aG}8+?N}o8Kz5(+CIRP*+veQ`(`^T4)QFXr=;H zGI}Th)0BMDqRe;IUMow%&r#FFU3xHbgvPTtq9`Tv9R&PLef>N|ssVSQskO?P-g7p~ zCP68+rc(M)Q)A_{PG0t4uk``s=9Ky|tHj?!fYT&uyr%rH2Oug$86&l;xQbg%1sU$h z((YsLY{=2FbrpL6OANW^RGADzoFi2Ao-%5GAY(ZK3+XjQ*)r_%_0uA87vTg4I&Pv$ zoo6EjC|)u+L-Od-3K^M5dE#Df0?|i}8RpUlfSMeYDo)~Pn%b!ioPy+FA=Igdonyr> zddn5~@*@l?7Ly%D*}m?zrvP$*^Z7LsK`I4|IOrYw z%mma?KlxW&tQ{4jgu_m2`QKu8p+*0;IPm|AA2Tp~0zx8U5>hyV42eQxu;dh!RMa%I zqUh)u7@3$^M2itCPW;COo}7PvyA-L?q<`J@XH1rCIdbK3$mitZ=Hca2z^_n|VgV&e zl_^&tD5O%AYBg%rsn?)UlV&Yig|!7{4o_O_Q@4`G|9p`Gi!9+IAN#~@pQX$StE{ok z2AgcL%?`VG)8X{kFCnoNzFO_9xoKwAS?i6?bc^0(v$pf-24xvVl^VTf^vTf{#*Uqy z2?|4BK6K@y51!RkerYBzsY>|D@!>0@POF>sV*j)k?p}&|v)%}_ZsiD^4F!exS-wI4 z&a1bt3V0_?49+3t+y79NTY0JW^O%c+a~}T5DG&LNQM9%p;XJ@uIIA854zN}e-)`N9 z^KD&^4pNLb!qCDvSBysY87J7A0?M0fJ8nOQ(}aI$%AE_+Opl<`rO1C$>3SRP;Zm{g G0ssIWHN-z~T~JWaM^I3(Gz^Wl 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

      09E7K+> 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%0Adx?p%dKuR>Vai7z_%yDOkd0 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/LiberationMono.woff2 b/docs/themes/hugo-geekdoc/static/fonts/LiberationMono.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3f4bb063748877e99d5c2c91c878a834ac9dab2f GIT binary patch literal 123712 zcmV)7K*zs#Pew8T0RR910pmab5&!@I1jrNs0pivG0RR9100000000000000000000 z0000#Mn+Uk92$WJ8|FS7h9U-F0E{jOg)Rw?G!YOAkBv-?t6>YuWB>s+0we>adRvDuv;jVS(<7|5R++ z3O+)v`;Am|oQ`eoYA<|rXq^53|NsC0|NsByWFfXSyRoyIq)jXG779Ly9-=3p;=O_< z-HnVy$~6e0F)MBEA`I^vDuC&LevGch*Y@?E&qJGBl@=#JV6#93LJbR1!bXx_Re^;t7zglO>H zP0)j++)K)P7rPXRUNTa~D|nh?Vlb@Ds8N1QVY(~6CwzJQ6t3))$r2^#>v0=0)4s5& z$V1pz5|0dI1+u#G8TGx^!z;4**z$et_(UX=pa}|^nIJX>BgK;Xih9miGGksm^m0~7 zB}RA6%#>BU=E4qygR&7*oUWfvBI@sggNgZhlaMBea4lK>*7m_0r4y7CldW(^xh*&* zWV}Ra2m0vO%`*;2!tgE(!x$8H>LYr5!$s$K9F3Ab%wTeb?_kp};m6r!ev(PJLi+hj zMtD+8t|f!>?=040inS>Q*9Zn2HM_b+5|UAQ? zQc8)X6g0tqsggQ%>i^WXZChC*Rd}wC7n+$>ZsoyCubk=eRWtMI{;%#?^~xQ^U%52J zrc+lVaYx+!+qrt6#`?9>qC9Bxsy_x47`Ltn3^`2Gl2ejPwj{T0Kg%nh{QC7cwYR%p z_LoBnV429H!*s5?o=eC{k>P-B{jW_`Qb0QRIsF5FlWZ$&kbz`U(raHQwXjPeopk9=99uwrv_BkH|(_zrADF$-7b z=bzOmRxY}AQRS*}(Vs;X22{DMx+IM>8n<@VxHrbLB{V~Tp!4)G`ClIR=ED9Y-N_V) zk^%__q<~4t+A4aUzygx5qI2wyci=x-`_FT$x~6*;-!iL^0$>*lWPufd&8mcr0aD14 z>HiJjpRS8jb7_Gp3?=`y?{!+wh1gVjS7kPozw`5Fy*S~-4|zZXnzhjAG?F=7mjADJ zT6IgAy*sru9zgH_a)ThXwgW>BduJW{ef=yjBzzEpmRhzB9IiWho%L0>0;ozYS>qRC z{=UnLB=zd!rLAV>%&LJ~sc zBm@d=@LQ_6N=G|l9c$;=nE4a4_HkMB<@QXx|JU#H%ij?@h)=}fdpS`lrSzb>)Fh1z zcvD81GEMlZyA52=gypq7^T>lquWIx2C*$F8MLFc#EAIhT(w_0)eE} zrf?yBhuFGx<)ZEU|C^b;x9YumRsI=U#`o7t6B(C<{d_43%OVLAHi+E|Xsq zWD1hCoCQap|NA-f9Y^w+@wtyR&wep^v;-kB)4J5Qx@2EP?i?*?qFH=sf4nJ9r7ne) zyxgS&AIvZE{QJA&ygRa1wXBJnmV`wPwvTBFT}xaKEn z57flKoT&5@E=br8q(6oL3hIn|O#uf4ZOr!^t4yH3?`M9VbI-X1k0m{ItI6#Tw$+A7 zGT0hIE8z~wA+)O;V0Ume`Rx$eQ+tmSR@q^yJ&^x)W|iH*Pn-Jp-n)Z9HiX$d$Tj_g zren;<8!@7Sy#Qa-Pu&^j4ol~y9c$I{dF`3* z3A=lH_kPMMuBzw6znG~Fg@ouU?hsi5RAwmZK@v-;w^Qg3t)rtDp^MKxLEBbO+ zmUIG--uZW~`py?Y7zBhJ-q}Ff*)9z|DU*7u{YcV^QrD)xB%F(B=NR>+apM zp+Z7F;cQ>%$q6$d{nfq)|5H`Lv`S^t1t}l*M<%D$rBVc4;7;WZa3$qNW%88tvBKGg z2fJ@svuu4dy!1n7b)Bp>Rbq`n!p}P>g@*pGA4l(-%U-|L`ikt``ycTFSOKJ@^x`zF zQziKh@W4y}3=DvoY>iPC=%1D9gg23FeCKS#p#1>`{-eUC2B&zlLrrH!Ub!d>E^01hG{Xy(7B+I7C&L~>CI%4rwaJ*~6b zcXyY7-~DSwwgxPFW@N=9DM}vEvLbX>f`^;G8bd5?R#5})?%^|JqeuWGe@pA;-mR+TBKs>Lc-pu5}EaI1nU zoV`S=`Z#rRPY8K8=K$}%_b>21K1hC$G6|3}2}(T@DBBb$*%U~*{(T>GfuP(&(XKg? zJ)vT-JSj}Rpvj{mi^q}%HK zr@fT%0eFCoHM_cyu@SMSHF~9;8p$yi4++Kn{kuo4)@U|3M8cezO%pmJb7VjaxbB=} zXP*C>_V3fPT+`)gCx8v80Sg(zrzw>zS$kaLx&q|q!0p^G1pvqgi2eUd)#?gJR$JYD z@ua*lA5QMs7*2cM%L(;=6^i(U0!V;V07!`jB?roO+p?S_cMky4^9mGuA0`8Q4nB$9 z0b~-OEP<3{@0NMpfCpuGC>ExVVA5vGk>Fmx`>;Kc4wev0gWW1KWl!Js1 zsJfS;+h-k9c`r@nnLp#%vGlzpg}e^%0f6P8eCQm|>#->SOKh5}x+ADvT5uR7uy7#I zOy_AJ4`M%W@I3L2X*Mull*{7t2n5tDcMs zASBU6IqDUz?1G=~X8(MgxWDdaVR4bmATo#q2_h0C1mD{&+C5~>|DKYltiuP1mzZ4ZZ$l}~f}%*2zT0PV*=DoQmZ}^oL9Ak@z}e%oN#X&J z6*n$4>AKPB+2yBM=TGFDNFrPW=17J@G^S1gsm>xoO8sUTkP^#~Qj79Kx>VMr>t$WK zQ8px!(2Y!U+n#vc&>kh8YEz)}r;#i(9mZ4frqk%mcNyJ~GTp%e2nqnpq!fw|g&C+G zH#gNF1^?w0O-O|%rQ3q^Gsh^=qLWCSFC#7L|Fx9ycA$WU2_M1`jtE2|K_F*A6`7lJ zqNK`kTbX-WP2ia$1{;tJqyTMYD+q+oLA+W}CwT@fYFw%^pX0LxGg8UCa6#coS(8um zUPbX=(>6iQ!|1$rR{x@lg&eGH9JL$8bt(bl@;5piYsn62t*OyMc{khYx zBMZy7U_|;jz@KY^aF!Jfc;}_%}2nCOl_zy50c*DrhNISwpGwo`}&`O8fBs)7c z7|B@o87YVl2_6u`5e$Tkj+;Stdyxf_8Ad(ngvg{z;I{OnGH^aRF&u~p3(9Oca^vF+ zsxUDUq{{SfN)z+gWpvzHWnAxJ@irH7^mXGIE~#pMqiOJ?$=YNOrj4-!vh3*}m~qdQ7v3*}m~liK9_ zRqNDq=_S>$J^x5vwZpuf&o4@gx*M1MI^>SD1!4)ecwn+5a?##PB8{|=72cM?K$A5Y zX&eYU$F9&+wp(+qutx@anr@A^8m-$|S4ZdwZ4t9@$YZCpVasrZI~iL zaZH`{RGg{Dgl^m2z9A7X&4*qI4NW+g6ArbC8|zb%X! z7iA2!mxh{atFxYLKXVK;+*p&%{NsEOmMW|D{J+_UFoWjaL19!h!vBi@{dk-VFiFD% zyiZQzAY$YLf1FKB5;4j(Z7Yf+w6IB!#Lcs)=`1$ATiOxb;MglZt_Fo zf@aWOvb@fEe^g{qhA{v%ut@|rtm7VWaaE1*pX#hSuGvwXq*-1K<1{bpwjY<=w3Us~ zWpo|gP#xX`Zj(AT+G@9hjyvnJo9?smsiz>kRv$Cn2LJvF?LP&-yN726vF?X@dpU|N z*PrznKa0qg9@+B?l(=z0LDV<84>S+8BhSp2Aq7T8k}txZera+xFL|aZ3eXN3THHU4 zoXvph>#oXbD7h)|bW(h(k7wR<&JdL{H`zs1Z*aKk{$57O2AVCpaoqdL7%HjjZ$fmx zAjjC`$x2iYnT6x(`a(A$rgmtPDjPh{e&)}}#v$j8Q?#uAyhFBF4*!{zKR)DVwB>#e z$1MwFiXYAf;uF)t(|Z>`pN}Z8?xq<82vyj<+#kUlWbTQH#aCHyovFa%>m#uPRn3uK zEvmmvm2XG^h+HaeJ!L^+)+B|~zEq0V{SzyD+^tl_>hyr_w#v*RVKjE&)K<~jYea;1 zTB6?uNA9HqhR+(Ka#KjrK@EkeS6xl5#yv>gT>_)2xdudMxJ8$71pyi#hk`^1Nw6 zx-7k`XEP!J6}Rr0p!4Z@LR7nIV)a;)eC}@YyEEJ50CZ1x=Ja%T=DYc`n?2ne=;l~A z$CIK5vxEI;g0ou~&sI#Bmf-C$lp{%abDJwL3#-}1jMZ9U!J$kCaE>w&0X|!rZ0Nl$ z+g4?7qY(xa&jYyI`;7^1IB>wa>k%{__9<0g4dk+U9*7V*;B;~%!d5g_V2K5ouXxOk zcKy>r9$4B}Z?@5{JH|>A=GJg2{@5o@)niJl5_4HLZnXIQUPbL%{o?H@B8JSTe-EH9 zfc~cs1~3x9cnQ|2%WMlRw^o|%_B!mO^RBw>q37QE%&Jevp8z6Lj=oA2H(%I``@8-{ z5C5q(K6>9q+0EKu9<@*Qj~AP2k?b#JN~;^I{XbEj65!iH9cI70=cuZO-S0!pVo{ZE zwCdMISj0K)VYSm;s?j;&uS?iD=#NVz(OHytFHYkI+wI@C%r)k#;G6$BxFQk8Xs{Z* z0(Bb0dM50`+9L=^STutEhBLQN!{dr4`1Rj+=n>aL2%}NqSGtwX?0dz-nfYL4H~(ULz859UFsE)8k2+&$qsWn11Zdw;b=-0I4Ud2uAx1 zq5;v{^mkkO`ybJuXh<|H8i^eZR~D9&E&`DpnT{c)mW%ND8ev&(9mGRZj+Z z)|u%d1ReV9KLDzH)B+&ud;kPUYQ_{sU*IFGW&P z3Q&%eGZjPSPz9>4DxL~q76#14JZz7}SdJaA3--c+xD=1Vq2hyQ*IGs)B(S>vgUExyZ(%>dqkJeAKnQgHJ+JbFiw#;_l5ipz*4zl`O z`1&uN;ORciXZUJw4b_+yt%3Dt!%`gO3S|>ufj0m_42Um#a9Lm!*ayyn+rSFGf}fBJ z`$EwVI5pHkKVYsu3pUjfzGe_gLTRE|fL~uiDeGoa`R@o6#lLA5Zo-?uMQ~T-FD;>|--MyI)OOY3{lAA(EvB!hkXobwd6Y1A$}yuyNhXWR zujNusrBa&3_Oh4UcgL}tuG_a|#X0?_LBIOZTMunCQC|%mHK|ptSh_w|xWeQhU!E$m zo{eYietVS;+EJ~POT~hxo;AThr-TCpSC6P)OZ1F@SX@j0==wrjh5{K1bWou|4+D%a z!3+zmgXqpV?}Cdix$Fvy&EW!bJRI@`LXi}bmXVc{ClnNwNb?pfT5^IJa~4P}S+Qor zmK}R1kvVX5iW6rpT)A=Q!IKwnK73L5@pl@)Xj!hf>V^VkDlstKbJu-r4^*jEqZUV< zhw3%pYSiShR!=3TcK9aQ=1X@ zC6!*Vw4gaFEbURtcAypDflJjCXQavSU$9qvy;9%S(K=QK>k!SUk^h5f{n#+FKkCo+ zuIc~WPV5SnKiV0C!ww%bK(3aRz5{fcgW|QJ_AY5vZ zAhiK_FY?uUa3x{oFR9V6)<_xja;9SmnZRSR7((H%TrYxoSlsm}t|;eU9JV9Ja#3TLAx*VT6(sx+ zz9>~r?%ZX4vLseT`XT)q!xtWcbN}J8D{|fb*fx?kr%1ZB=$3y{3HXbnVLNRCxb>{_ zN^3Rt`UB+m;3RVH`c9y62dho(B@~A!k;rR{CC^D{k?bUL?$;<-5P~rF&agBim@eZy zivMrT1zSZyZDn`pL!P1iN(Yqw-=6$zOhNbW&S69`j93-B;uIJ8MOrBW-{IVY?J#zu zr*PT0DlN)Wq1vmL_{GyFj~|_i`@7ql(^?7qDd{3XH5p4~$y4vHz54DJ{C%f?4r& zCY5qc>nT(Z&UULIFYa{+Ne{z+(B0KUw@mJA@m95J!Mnb>_I#}0xX!6b z(8`(R-u>HWUcHUsoM{Y`m}!>sa5Cx^Nd$j9X7c|67Wjg{RjUgLK#eZ)faQVHts3xU z&UxuKP8{W4S-Q?V`>OOGv+t>_+}N#40+<%)o5~f7L4BVMt*oP;U9tK3l0n_#N)TsK zOLg^-o6bjB^-0yhmuMl&Mj)6+pmtfMsvu|ImEw|93)t=U4ADKv1CXu6ffbOoZ!O#K zqPDGM0V*&llydx`Zl1jX`rC=G1Z2&FJ$r2FgTNkb4Yt- z*dcj%iDzAA$&0ovxWThFYikEo$}Q;S4q2%n9k9!>-F9dNN8I`gy`h{;D(F~KuvuKT zeOX|0%-5iNaqRg&?D*RlBPWw2>qAjA>czVl`9=R#)(UBDvBykCT}z}ZSrS?LzX}5 zuy|VmBiUrUfGlsbnvIW6nEebcPUS`7AkdCZ~5ZF-I z4I7|clN!6_mp9~1d52Z8SirBu0lK_`Ai@TRl~{!?#ExC+&_%l^Eaktz&XBHHCo3*z zE!!Lb*dso>i%D&tKhw>c%_T*rX^SN`A6)GVPH8z1by$25M8Lr#0!&RJAPZDFk-^(3 zDh8*&#f&a98WTW*5SeI{i`z)&7c@$~=M}3shW_xUnras$(X*2g?pgnL4==DqXW5jy z{zy^4?Aqj4TByvxNJTSfLeE@x5PD}JOb zQAvh4KZp(F*c$SY@5td^6cqGsMP7jC-xzS-My?Q)#LJlJNs+Z>yaVY=NnKEcwRWH^9xf&!7tU&T2g{kfM4P4 zi-Trl4N!;nV+`qYfjv}sIw!>>+QvJwQcL5yU=8BOyxq=3>kMOexKue*dCY^xSwXIQ zAXh&7dD*Z?i18P;>AWOz|64p;t>9W2Tn=5WM~V9?ge_e~$id+Tr4Ty&GHHOi_04T| z)$7)wdPA7uiRF&|?S+HbYAtjIdhisWkg7pGB)JBwLSl%|e#BBycshlm)D!eE0Sy)7 zeVpBlq8GZ1M2GtpmFUl&Xo~&}YdQL00nmEmZOk2((&bd#;!NE2J4{v@f}K#Ww`{$gFaU{f!+1})T)uJPMmt2({qC6iH zj_Hur>t&nwDXq)=JZ+cP=!ht*TJ2nqP>zu)lBUQAwXVl|!0)7;KbdNs>n-EcGtT#- z!v%P_htE0Tff*OoleNKYR@q7DH~-qzlDrhnM5`g1CTi}8Bx~AiU(S9)#R2VrE%qp; z@JaqOrs*Emr2f6Gw?rL|Rl39D{&PC^&6O058OLQjgb+l+pQq!rx^Z0Xw_A!WRkufN ztyL(E>5(0QR~!zLZoc)Z8#$-D{NVS?ZoC)SKlkK^VG5=uRSlt5V^oQlrz9o7Q70lG z&CJ2S)dyHan8gsOnywDOWOJAMae-wKD7WT8_kJiPE0ml zVh`dVx`wHb?Wj!Tx7)$4jKe=w3a!X z?qL`TL=yA=z#eFJgZK8fo6TTXe2s%0sn`Lv}oHqaaY=zFduFEC)s4=xX zv~M?D+)!H{v+7WYNsy3quo3I9_97u1j*r`4{#NTeElU|=4B>Qmb$8sKK3ZpQRlc70(D_WNWC!&#l8!%j)@}XnTTW)>FG_eRxCWON_{B7 zVID*lXBOv!v)+0u%R=-zKi*m9EF39_3?gcQ9jFH{J^(YE2_mUpa6!crWjK<9OFc$<~!-$CA5-+1|`2KJfG9^now`ar@in=@4+lFZRY1d$Cs>ary}@ z{^@@6hd1QjGqXrC#!OVG5P_Abr>pa>5jA$~CO1c&#Y{#=ofCyD^cbONQt%NwhyJ;e zwLwG@Hip8uKQh0jkGCx*-ssupV6R(ZV-BtHS=w-gw)*f#y$~+H{~QEQX&Xs2!V`%pS3o!;%Y;`XzQFsXnaolY$17yO>E@+ zn~Utwp(1LHepA7cP@XRXt4~aykL&De>FbdC1u->4h#Dhd>f9-2ck`C(=UVr%n{7@- zRL+nw7IQpjlo%{B1iKmguT3wLCB_%8*+y2=2|6;_rjQM3D)lu;i>jiK9{Pp5xWJ@f z-6=HsK0}|eH`r4p^eUj?|^mr2#toK4sd>k7rb z2n#NUAdrrC%ch_hczW#6T3DYp0>dymS5+n}zfN%}bgc|z+mDfBC70k0cuBINv>>fq z)|3DUs+3=mb)Yx}kBR=plIOoEv8Y*X#ES#`v{GsK#9E#|mb9>qbsBz*TqK=?*ggU` zGxrQA*cZhja0vK!lAgAlu0?Jop)^!p06DK|Jvz(O#yydN_l-ml6jF;%imVt=_(L3R z%k8{7psgKS+Y7_~I~t>P6ay_t=1&F+UX5IqFM9j^cQnOwW#Jt1buTcL<3&g!k2cXo z@B4mB|IZ!bg(g}Cn_GGDH@=Z9A>vdLbS6_%qhW9LBYxUS%w!-aKfg!59VQkak9K66 ztfxnEtF?IXJ0A##qF{g7&QD`w2B)$_ukcT;o$|u+LPqL{~KFXd)A( zh3KXX>f9SfnX*|A)SLZA0Y6GCvQ!`giUWy57kyz~#1h$NDZ+iIjV+;nPXh&wlYKvm zANlJ4kZ?M_xjhnziJ9w6Kc#1=qCb_?hVp4M7cx%S{LFF}>KVY9d+xA7?hqgOi5{L$DrQ9AIv)cMz{a7G+^<3HDhokkR^$ z)@)xvw=(spc&W_)_d|v*F{EdHS}5mUX<(`@kxkHbr6o7iqv&l5>T35}(~K;7do$HG zUTVr(2~{AEiJzhdwf}t7FDcfmReoUJ+cw=^yw%m)TM0ts z&}N}1X7-5p5lOeHVuNVkEuIAt!5&8c5xdQkx5P^%t$XhutR8}0kF?m(4bHZuSP z@L29b(A21f7B`3T(vaDg7pr*yPDZ+(7{hc$C)WR?1#NgA7S(vTOc4A*M0SE;SjX`( z`lzad0wxrTUtQEKO(|-BW6w?$9nr}*Z^?+9AZ0hR%C^fBlHoMLa68zpJcI!g)F=$~ zK!tLLI}&se=Im^sC`15E=3~HphddPIl+H61xMz(Pm1_i?@{={O6a*X8bXdV#XZ1ID zWUEBve-N^CVjQwN@wyCwO}uVjWv+h5@kMBppmgU%OWtqs0jrd!5F zB06L%bATYRcpqLG_|iI21Y#F9Wz)0?Dkq{em`C*8G^W=hc)XAgP+TPx1LQuv0uN^m z1Z1d73d1xLb|-JxTdY7tMPTfg2Fs5t!*KTsM7X~NE=YD^NrdjH9N8oU(Op<=ofqfk zrVNySJw#_srNv1vnEADnNz2B@$`qVju@Zz_YhGNJLJHJab@Lh$_AYAENP3-RUs)^d z50TN3Sty@FGHUL1H~g5nNBf3*S(vg)Xc)T*&8_NHoy59x6L5iI4|Cn$@NXdTP-KsT z77$ZkDiew-dMlw<=cj<=A@z?(+hcksJwKaq*qaK%+1lLL#{DOo(`br ztHO1s3P$%$!SHT`ba_vDt9;$n9Aq1nN`_j9b#;)!cr=gva+C%j-Xyn+8hj-9U9mR` zkujYx-OU#r>zUK0PTpj7KW=EVX-NfPr5QNmqoVQwdw6-O2l!Z{-Ek~q$EXo}JTJ!y z7q3l*22?)WL=T7C*#?G>`ik_GgX=+IQ~$v%X%Fn_hnbz;LLv8t_%U{`VswK- zOAojFgy^uA3DpZk1X~LHtq6{Yp8wZ#LRd-$y`?1ma0cN-GXS zPJMEz%R$!wNMzfH#EUAh6T3)k=%dD9CI_OxzU>eZo}vW)8^znjK9cVOs@j=fYN3cA zkc$)W>%0#IRNiU;*vqlH>Pm%^%8Voc$CQ*~N1Ft8J-f(ag$ifyk@Xq!lD`oUIP+Oh zlxI6=Tp5Q3Gno@mlYOc&5S;MrVW`r;*%+|VL(QIpMDMs3FUMz-@L2&MU3v=4TOz0t zkSOjshdhbZFbCkCVy5u3)i6ZyypP*DC0kD2pesoIJg_B!WYgC-w?af=-FaxQ>0uqp=S;^Y_)^ zhjCzoHcZ#akEL0v$5lApAwQ0FMkmaqJ6y~~-jo(d{E2|&2phjp?@3iQcR}Ka7{+AR zKh(OP!%;?^g?PP`YV+FxC7rvVS$sT~vvjsjuHjTsNw3m-ky>5K{;897iHZTiUj6=C zF?S+>+>+_df^Vm$#o)$#0P@#ySs*t!fMO7U$ndeA9nEp*7{M3tZF9tMETEslYcdLI z*oVJHm_jE9v$0}%MOd!|0fI&;N*-v1-unAwH9d0CZb&NJ(Ot4JC!UtwVQwU>EVn zsLj=?c9XDr>`Fnx;Ix4$%$V+P7j!TE#vOP@JaG=6-=z zdT|3mn2`%u_iM|zFkAq%?rWia@QH?6Bc7;4K@i@{2mYhzx0hb%R0iqw#IM{{8X0K5}i|hpSuzJC{&s z02sLws8!w_T8i)Lbt_TG3nJ<17!`8!11RSu(sW|~sclC46jB*lvX`eUl=MshP*xiO zi2^by7nGo0<1oQTud>jgAtIr`HbvIaSgNpJKM70;{4|78<$jZLJV;*~9X}tt8O9^A zXI1`sRdwxk=3LiNAm(k51y}*l6ueQN&Z8o>uXe-3q;)@ArZ#*9SEU|?$xZQqw827Ka=GcJ$6hCH@+7qjjK@9n$JUAPH;kLi~91k zpGbUmZ?peY3aWFrbmiZQ4Iyj5GvY>YlNak7B>ogL#+{SXxpwW@*K85qe1)znZ8mBSlOGFRko!eOA zP!o5b=c#SaIV)(NlafaP zcNeOz@>!#nYDCoYnBhnu$s+vD-I^H|NgdtN>3qo4VNv^vF~M8oU){?#S`N2P=AovEqJwd#&iNeY;Tc-k2(3Wy{bW}6}!5wQ#mu>~^Nm$6VP_}%uQqR~i1JJ#9^7Di3tOvO6_ zF*U1&zBeH>O*3!W{aK=Qe;Iu_zDD5}#mp)61($NdWdTa z6{Cf{MOlOhD>{PpykHN-)D1SB#Q0hDy@|kX++_%&S2> zwj%vfv?z$DK+>Iz+)}*KVpEaLk}qp?U1oaS$z2*gB!Z8y@QCZ^;v)p|@fL%_zcDi$T7z8|4$EGn?k$KLMp(%;Ap+4aa6 z+Bn71@Vz}{u?V4L4}~8F!Gp((nyx%+Ha8_|?O z4t0}Tc`>_H>&*7O7-xw>6Rz!3hgKJTcSy$UYJR2c>GEvj*UeJ=bz_pwKxn{W~nPWMe+bck3mVD(zY-1V#RiUz&;0Bgp+fz+*i_SFUyZxGC=T~vWY zkMcjCT{H1)w8jO#o~v0eUs&ef5bMJ=YUR}bENJBr*ZP{WxQ0~h&V}>px|RIBZGAG2 zi9h<7NK-3TF}1L|Zq>J};6u^rp88Vqb+YLE*je2LqoDpJfSHq7v(%}GG0 zzN_xlpA_w5qA{lp&@pU^4OkZ@5y#ktO9Bcl55O{i+Jb}6vp!`L7jMzV@3O8klJF!Z zcx~Tz=>uAdl|!F}lZ)a285^1GPa0F=53S6wVRATPTTzqoN?#4!HWc#&@jI59w1R5=B zjmtPO3z$!xu4@mq9us+-zcJcTA7Dz-MZx7Xly_F=CqpW~FbEyp5O(!NRkE*&ST~Nt zZ@b$5gWeGFaZDcj$qffb#4-;Pwg-_@?V@jp-p-b9sZ=1eR8XP*o57eppqd3WKbor! zNyQ_>SbpgGAx=sU;>@V?d+EcEU$F(435FC!&TTT!?Ia&X4%%AEM?TQ!5Yu{a9fO#S zdi`~@I+Z-76{uN0-ahf_EdQ}m@wgk01C2BFTv8BZcDRdUxo0!Jj+7P%i2)L+KocXd zn0@zAU#J2t+N=!4LX3YUhZsF3N-yrpqd_PN;f<8p$QOI{cX~z@)wvu2sq zOext{g%pjSlP*rrU%ND$zyni)f1WxbmJ5sdt0VDW zsCWkYmH(@zQgUEi$p?tKW$dwYN>c{oj8(&7kwPFk5eVYH0FWN=&cb=_$7C5x z(I8N2E+n7IA|1t1fnLxgad@5*dJVQBKsB@h1veVckvU{>I)kT!ZgOdIa3W(wptL0U z-*SW80$(X4REyW~NOV%+aGitGED+3(PHJuTdLHi&)}2?{Sn^!d(ZU&wLWnT+bNp8D zR;Q_fzb@=t=C8a$rD<5(xDX}dy1?sJ8Yf*&0?LOg)~7<)YoStcRnp*5xbTO5f*uAH zmA(T*2<7r$`G7pCE z3F?+H_y52OT)RA2SJOVWn8bZZb!&KJxM`o{Dx}mml<+dA+5Z(p>fmk>-_R&R_^%dp z&$@)J!3SxTn~Mj+1vV}sjEUSL6m6^YF(Y*y!=oaVt~E+s>o~U*CLucD*lRpdf2?w( zD43wk!QNn#wE|2)!=t!R&$2XRLM!zONP+wt3jw7DKLvbMiP;Wwq*S8BLq#gaWSnxE z3-hyGwf^J!K5|xf$(H1eY)Gu&vp?F*+j}-iF$~>xmp~4)@_tZ*?7`qwZ#vkzgDtcZQf{)4pg40)`8 zjY6qGpMv}}PnpT5bWH3WlUT?cAS#ZSXcc0=#4D?LQ*@OrGE7nUb~Cl$WJ}xC4B_cq zi(iGl)N9(SZ;cz&c189Z7=8T%?qfR;16m1rJe^DyZPl4i_2ztw-H{mJ*%?%}9uUrp z)nVg%akj#I_F97@z4ypN0~u{NA}uYD$(xAv$(<%x%)AezVI zwH6lypeO*(6R&1A&4g6_OIT=-^dwb&4xrd%d0xP-A$MHoE=>)Z;V7 zI5U7Csvp6nzFE2hOJb1SJ!I%_E$0)34CCvX)!IQy3Y>ojOZB&mp1}ls3NQa7xU#O$3!01lB@1&89BVeV1~Wn>qX^Nk zmcT@|=g3>ZwI=fNenb&D#tgBXq5r@XYN}1miIoc|QMD~6SfpO`%oZ}eXznWox1EqT z?=*c`Q;hDOK4aOip{f`b&+FL3^mHg*>Z>TBY)(&FDQJ6K3p0fh6x;8((8(;b_buO0 zZNsC&mylqzjVnI>E0T@Yl0=6Vk;p^sr*%lf(D_!ff`j*YMy;989I_Wmz*&dYU3Rl z$`Y$tnE_P;;IOJn@Y7Rip(ZXwM@w~qFDQuAMLV7FoGI#3sC~vJxkt5Z9SU@?g zg{?JwSpi+I5jsl2pmwAq127&D#nwfYcd{jaf8_#!iyr%@L#lS_(!uZBrO>*$Z`leC zZVz0FXZ{I`$k`)<9tB7=Rv%C!Kl&J}?DZV^Jk4a8j!&9~& zltzb9qZVh5LdK0|l!ycAMK*eC(b8mtDJ&l z^@4t0TcvpNjxn5r=DBri5|7lf+h*XdL z#0DsolRgtdgQUy2hS%A&f=v1|F#Sd{cl`1UC0dwztJm6B>RcS%&c=l`nkWnm8I)RfFT@_lz!{T!I6I`>m6z>?B__{Z@m() zG%dQPci6wh6Y&-$GHMxwv~~ORM=P{hAGZOsMi}y;PT2D$u>zzt0f0Cs)@b#u2g!J-FmwSvfs+)^wZjG<`nK ziScg_6I}=Xy;i|rgt2p!w{v&mjDC8xgYs{07r3ng^B`H6BBOHoDVz0Xx?z77^G&l6Q>s`ELH;c)vI*3IZF#(I z@pS5c6N&6uDlg6)SLG!kjqczgYW+T5?pD0tE!}hc_Zu-(a!*DZo*1e9iUfT=5-|c% z9skHDU~U9VF+^Mbk-*Y|&;siyNyTEU!h zYG3G5YmVvkTpYPH{%mtbYV{Dk&K?ILlp`$HN)$;w{@%9v^7bMW1zHZ5`Xm4;Y5M^f zZywe-oJVxe5;+5lY}zeT=!JjMHaR3`AAB1fLM3lgH_7ji^KOU4dP3II2pntVmQpZa z>V@D-2~0N@FaD$(V;QANs|)`}6xUA4EjAUTyD@+gdMihK9+0*8Jw%xQ0rb-@K~#*7 z;$`Brup4&CMys8@F-KWpz65mzG2h{qMe-Tyd0nFQ;@Ugr&5>iQpa&0^9UzovanB$( zkF?3S`&ikFnAR50bM)o(*Ku`_eSGG|$%gMdgPQq7QiI&z{52;`O%)*Bx2C{%@7@C9 zP}Y3X^V?}IW}``7XoqsIRC~jjW0#@6&gidE+@z{VO9^eX(4nz> z3Y(c-w;THLNe4kPJfk!8m(z1V*@+7;_#QEnwa4%P&1a{xA%xN84W7=6P)*zo2hzRx z?{dQr%P&^a&Rxu0^JAL0x43rtVQ7dWcXM|fcqDhp5gvFs;H?JPBw%!6@Yx@a*Bk{M zHGI}-(e;q$DTt_PDJQ{06>DSNK&7^Z;0!oKys0$-L-pX%2K%EBLK6<#MXkrSLv$~y z*ty8;)?XUa{1TKa{c(^+!j5LfJJe6_%r+Z6c z89G-W&s4K9tpX=11!p7l6k81&v1U|dSHm&B4S_oxXwb$D(uDiK*yDbjH3sa^mi3i> zO-Rg#0qqQn5wpz`f!jN1)^mCa{GAX6780csWR;0uih&ZDHGDLDlka9<>u|MOBNTZQ}3AGy<(^ehkf6 zygz?aK|yAbJf_-$tIl*{7$>`ML+ifk&kar&+p*j<_MXk>hlup9j|xnTNM9J#YDqRq zQSI)}(0?m6CiRm#vvRkoaW`4*iJ!Ya3OpJ56a||$Zv(UlE-Get1HIAf_d1}t5Wk04@npp*$pV!bO^;Js$%Jf;5-O~E_TCVB~Hcx)2Pk%BEZ zFytKwO_I~%RDoVnjSJ?lFzWFCH~z8g+F}ayf0RQ~oz$l3pUb+kXTgatvk7rAGgn8o?Fw@2y{itwcGh-RzlMg3N-%>(=Y>R%FEUM%ukS|tmvEg7(4rO7AmP)H{~;TIFhJ;EPwS} z2b_Ykdlu`n62J!~idyohf?theR$aTBvo8D)%T%Jk@6_Rj8@{s@S zM*Bo#NNPS6=RIVJ3EkhVvxOG;CMm}`G!N%-8CkobPEvW=Rd2PN zk(MhWYcuo|H`K>&^vj2F2VIqhbFM|NF&JXV-RI!fyShA*+a>Ce(5^s%JF{S+oKIQg z9<2KvOa=vk$AXtMNcL3E%<*foGZLTwjNG$=Ygcdj8M6b~>SgT9Oh?S+zf`FC`flDJ zTPzm2s9ZwTtYGzvK4UnLwL;r5hDD2aC@sh(3dqpY=oDnWk2tFZjS*hq*3b^#1OVAT47M z^`hhM&={2_k0XGkV{&|A4UTFu(NMl$z4g{>$n@7Wv#76!#`Z|`sp>2&r$XI+i#=V7>J_W zow1)mTZ4Q?ga#DLg?Qygs|!SX!UJF?^#BhHVbm*xwWshU!@J{Wuj(7(^*|3i@K6ls zg$p&0wUQi;GTyVGma1K>m0_&s$;h-<^8{)$x zewF;I8Jk_vr@O9dbC+^hj{;uh7!3u5^iNwnsc?}ab{#e#`+_!PL&qP*UQ%riY9Xf{ zeZRpRpgYeJ`*Jg>@HzY1Re8}rlHL2yWj+RjU!7si;tBU*rCvTO7EL&s5=Vw$FF6rN zur9k#>qHLH#>)a{=vgPS%{6ZR)rF<|o=NWf`je;{HSOcwwen=nWG+GSH}thz$4c)i z>N}m(Xs$L++}U$T>K+ZqVi>jN?KX*;k)31}@buWW7xx8(lsHP78w)ezVE-Oq7XZbG zp*|2sh1j1ZralWI4kmByU>e3$ZU|C@f?Mg^>qCbvD(KYmexuzzvyTn1q>P|&LBQNN zh6sz_!TzIDTS>`Dwe;~sxg>Lbo`P;p;?zTTn)CKduDXXV7T;a#;-3MIdy4VbVNBsf zDA8y5qBbyA)g=L#=Sf6^NQ!WcTtQ_2xjk#sX8e+o{K5$9$3N27lHMh}uKMM4fEBe&yTmjdu{T>G7kDP$@ys5 z?WM=^Q0|c~8FK23>M;V!#Tmk_4(BX6I!yfyi4z)z|V9Q%3IH6j``Ym=3EQ&KBw32 z7|^orQATU^ z1;Ha<6rk8)@M3-DcgizFSvrV6xZRGdT&0se-;WQpgIRK|EXST0_#%WptsQ=C1RwZY zj6=^F_PrWk8l6dD{rNM0KnUw1%!Q^8(h@=^m*DMZf?A+q@s3(*eSZ`CnwG7UQmc!dr+bFUuI2%1dx61*{=QoFaP$yw!LA_C5IFSKQ32tDDplEY zTC`C;`$Gss7-Azd%2!yX4JEachdfz7n_ukL!`{Q<_H+c^cLP)o$vx^K%; zz&}OD2Jn>J`T#i|()M&;Id3WGUd~iQybkIKC0J;3JDdvkx>=A`1$3`VDt(Y_C}aw= zMt@}}zNRHvN~u&57NZ3-i*C5 z{SLvgpVuhR5Xt?Bj=>+(A@J3ozM6_qq{xCUKarD`>{OQ8QFbfR>sZuU0&rgNb{$8o zQ-a5@=eQgDnL?Dx#L3(kYqd{wot>Fpa&?=bD|cpjg9pP|WZVfoCAF3Yr}4to!(@_- z#OHqqd7suF+X7)qfNmXQ%)Yh-B_0gz@Dv$b2k*FXus=&{O7wYcBoRVmHKW3@y>OAg ztI{YCcgz-&YK+z^eeRqb+kIBYD%ypXL^ql*rUCVD@^@HvU>)o)muRhvj^NJw;VO3a z?b3A|7b36pCmSZg!+ZN%a>tze{H*$Mp`F0;x$lnruQPxIne{LcBh;EX_0yTKQS8CZPUnRx7;u>P*AIS6}hKU+1&>O96yeB&Wg$OF=T-Pl#F3 zzf^{oa;b*nl;_=CEniWmEIw+jg<0@naE}?ETE2N7nD~a~{Bxg?-e|R?XH?<36^mPiu=Zl#TvG7^E+Xq~eBCE#(cxKK$)0?C%byAbANLa0trm?_Vc+>o zif2LgJE-+VlapOm|Ld*56uMqJX$8jQVgW75_qu1Au-*qGg5Qel`~RZkwV~dGoqn-gRX3UQdUd6&w_nT-5rAxg(Zg z>G=5(v_)iXUppqdDAX!rH!|GrLe40Dx?&(5nfdpJxikK zgG_P_iv{KMhE7kFt6~uXxG>`xJA;{@>^LdaGnfP zUxeYJXSPKOaNaoaor;?}cm)#=?ZhivvF#H@k9=|iq2@889YK4@qPY_@484p6#zLty zy75;f6CM{3w|+V>HqL`|iuA>iN0q9WmQ3qt7EQ*7Hd)R;QgOs0f%6Lz+!_MOSh?3A7GW}r>0Rn*Xf_8!Q0kNx z2%SM|3GplU>N}5d*s+7nazB2V7X_teho8B3m3=Ko?h-FIk8pF@W8YF=zbv(U*sK|;{ojho zO^(N>LJby$NvfN%Tzu?t{aYhQJMVjvR%`Me5@S|UASh5~d#=0`zGg4^n)aq-6hX(E{MU?qk*hqjLZw(7q9Bi*p{G zap1I#XW^Ma0>f@FcTO}Y3Jd4?zk98tuJt|lvg!GrILf+d5KENK;u2cABc;_a>rR7e zUxB1fTn{0197LBWv#T~a!*fiUH`R-grWZn>d8LLgLZu4cza!98r6_kKsp~rK;=#J< z_68x_ftH@_Wf}yR|_dX z30y@DMNV=M2<5-iCA_mu65t*v&>Dn-&0xt0tTd&`lJ_p7&V6&JYrl504n|Zg{jWE~ zu455qnI@f06Vw7{!uISROZCm~!NjLSkxnhTtev%CO#9+^B+iBGfF2KVjjB)b^9}KR z?5kfF?W2XixM2KrqMN`5ZZZU{2PP;80Fqs6Md2(>W5eN1t zK;hJiQqvl@$DX($%L0lF-ysRIXKiI2#n2iAmRZjZ%v%cR17%StJ^DC`gkRILy8I5= zadN_LplS;QE@&tU4zM4?#-_|0N))Yh)TzT=MX-({e!(tE>rxC_ANzotf|zO5Rz~Is zW}|dc3u(2i!3%^|99o~pfVishtHB^oWD#})BQ2s2SoD^ztZ3v*r9c z8>9i!_3~!+0}&$chx^_7ybgvs*Mp2+Y8~0*Pyxq!sn$;w7{{(MtWU%1Ujekn=;?<2 zB*M|ckiALgetZMxpShm9u#AiIBu}g96`U=9q%Yk;JwvX>eRnm%J@mxkGA2?cZR9-? zSS#r|EMD?JIg%|$E?S6eTu`HhMj8bg8|V!*%`+K{q1F1pk8nd$8%_UCH4 zwj&9hm|8YW&Fk0M)Fb`&Ve){ndR&|jo|}}a@C!tQE$$vUx~hvih6zE?nIr4LdX>e+ zF8V88hZc%iJWFM$$Zu^R!Wj55ZasA9EshoVyIgR}xSidA&Q}k15!(C#wyyGRbLD%F z#Axx>AQvO^QEZEkQ!t;u(F8!&JJPxA2(veUt%D_1B(P)4^Z|y~7S|=!FIpj^G9TV% zmPY&1$)_MB9D&TXir^{Ssm$LgWB#D#u0=e(%l?Rqg=!}P)vza`N|-N$k5 zmHlODB&udie2Ccgth~YH2=Ga{q|`6ar)@r|(a^lEx9pAttbj&lD@z&5?3&%E(p(VH zYAJ1Gqwwvp&y{$1S2DZ_QW<;Es@{Yg%x-|SY2xd-!J&PMon>ik@%^5-Yeqkkf_K?@`Rjd8q0iQpA_H*RD zaQnaf#&e7v)=%29QvN?4I7-<(k7DSU`}z8(W5dY!-#bdvt$${dj2%C_%FMmaQD z{>h`E(#FibQ!Z6K^#)aclVkO`D{$@Y%Hr``;$ZyFCpAg8S{v&GOz&4}8g8jh{f}H@+<_9^FoLB+VTt z;vuhb9UDr7j_BxY>mWhmw(jBS^rn_%W`NMapna`$Ft*2G>9uV zv&T!naZPJkx#N9^vg-b9%T6>!C%7ZEj3X|f6AQKs^&H!&ceE?{c<3!{g~d7*T-4w; zdMb;`z;*0#mA0apG&!rMrW|rNG5!9Sd|Sf+@Uxjz4WopMP~>3=(fKw9%#Ea#)M7ri zl7b{evCGH1M&#QXFQHBf_X1PgVQ)XKUm zlQ^Hi6?`y`!|-HV2Tvpj{}tOebWNcOWBy@%=tvm5K1s{}N9ASghIb!ET!<}D3BPbl z+Vk&1e#A>Y%oO;;Oyes;2666G7)G82t7wP6%HxV7)}G1G7@~zYgSs;=@jo|u$nS)S zL?1b7c)zB7xA(Jysd*E@ZS~6oKwz-Ho1_jcrTMI|j193|h1YO)e&765+O|ctRe$i^ z1#RteGA(nJrJH#$aH(6pyis>dO||u_U~c(1v{3iLfz`9d;C;&^fyRu3q*QT`%8UY| zMnK}vk#>CZ;e86j;-}j*I~PSzwX+Y}v31yOl9ECnkF|IBMm(6PqM9~KM&HSQhQ9d) zj3aVw^JzG7#PxKWXM0`Ezqy3+(IYWWY(;iIu??@Xuc9>*A+)NAm%EN_nDkjq2F=+h z(9E0#{Qmxnxt`4-A>tGtORYxFzRN}9&-YdS^^1&_)nh(S3wN8Je!qK%X@`Hi8p*Y0 zEPq!(mxUgwNaq%x>n$FU6M`fMCgHN*qrwl>!_ja9~q8r;35`||0}m$O@v^F-#&gvM!HPV15JT*Uecf3?vy5LrQx z6ZpJXl~fM!x?o-L*Pa=W92|R&H$C}UV(%RWBg`3_LjxwG>j^(xawO&S0mFCJg2~?q zx!JU#&Tu0|XtLS%FzkGO8>*?vzI8r74BOUSGBG`kfBa_~>Zcao(uP6Gl& zgis(q_c`%li+eI8^&EWv>K%v^eJ7gRCdR-87r>EPS5d-~4^|j=HTBeZT_*oYcBm~> zrKu}t+7(W_%7iyuU7H#@u$7=iSo@&3^eG1Wj3tz$Q4TF+Fp5NCbXZuxb*|YjZsQj6 zHo-jmoz`9uI`k~LcXU35WPRgnzu`Wr;B{abMaD*Kf_wz{1st!_`&!3 z^+&Lv&)53}_5I{%ygx1vh}zg7^im>ixNgn&JT+~1tQ|QTqmz?XBqW#f?0-Qj1?^qk zg!5#Nb21aFX~lovT_iOu+pN%jJVwgye~}i6ZI{NESO(c5vwED?q1T7cNVnWxsD1>4 zr=0!1R{ z5|xc4?_G_@h)t1a{OxSriYMCKnoPR&v9D`tabM1GG>GM2fw!-|2{UrM<9zkyE!zy& zY0)93zU=hypzN%?sq|RfFf0tx{mpUQT5VUyD1ha9{sBuxD?d&v1?e=u`QruVN#3iJ zd01`!*~M}G{p$RbYwCg?#MUX-WWGg^O{T?x{3jcu<76Ec%9V5Crt7nuY>-d+j|x|+ z3X*R;d7QEdLlr+%(PK_jxr-Mrf1Lh9n6>n~#p$;%3QiSGky0g)wt??SC9W|@MB4PL z{+*qZY=PoNKGysu>Q3h#cqvuvW2;+AASs!q`)%uk`*~cM3jkV^Btre$T1|T#*Rw8Y zQ4DEC*H9fE_aeJBxU_x;k%J{REK+Ibq9D9ero9DMRMn)){wbs%>#J>P9Uo|pKT=P^ zoT|m*hC|DPTk0{w<}nWldY$f>mC`YxgveUJN9)SJwvZ?4>!QUSY@2j3kVBsQ5L@lY zd69ySg`7_Q5HDGfts5PmE?->CKgd~zpF*Cx&?r^HuquU@z^|9kwI*nWubTUHIVI-x z)+QO4!Q!OzR5Z@_k>Uz~$o(vD9>n$MxmgVqToNUkgRtz0Z57=`s3?5YmD}1`a8EW; zZ?J;5l9x9~OL`XC@@NpBdDs-nI70ncnU6&vhoLfd1BX21S*%CsZmr1AxX@ z?)Ztgha#WImSfu-N<iUpLOp@=-GRMO*;wEyMMRA1cE9;j;1LZW7QIlgvj#rMBAVpXCV_H}e6D2id)C)%WrlV`tH^70n_lk! zUX6JeK90VgFlNhSHD|DL>R0z9)~)V^)~@VL)~@V{s3Vt^lSpM1M545UKrEMn_IDsq zh|Y@6VpQ=&Yb)}T)a#0n%vAFrKD1shBbFcvYqE2(L?XHnZ;Q&arI)oDGuwtUt4X{L z0jjN7#I3nO5^R`h;z^j+4+il+Dx_!W!Z%mJXSE_TX zk(%0;_Jp4$!(cmQo;vuToeGwEHK4jfNL9|cEr1h!e1$;D8LH#5!mDC8DvH<`9 zZ?BGen}L~5zCg^(q}_hp1nzDsI%3!iMz(B~2N>zt0G_^{F)6Uxn%^~E=&?6HY8RY* zLt*iC7BSQlP*&w<%}PrJg7Pw636C$8^0)$lL|RfJ5(2@g$FnTBW`+mvKkdC44k}F# zv+~u~s`Z_`w{}$k503p%)9IOPMR7#htpvt@c+fIVsk=4p6@Ym~$d3Q`EUL!$ABKK% z`3u85$p_+QL2DKMo9;hMd!4H3A7bd)p3a`=Wb@WxjIdF0DL)TImx{8v5Kc2ACqq;` z4|YhUbQCMbdYfAQ63DJ^pTC;BY%VH}5o2>_gd`E@y1b$+{&;~Wz&9+&d*vGoc^rXM z#B;&H;|)HDQ;HO!4WNcGMQN*{wb6@UwPJaesbtR>P#=WfGh4xPF zJ3g?3TlVUrOt_#ZZNin^U`ZvR$t8&9$c*Am3rxk1^}^X6IyL~nI|vY#6p6YI_kyx6 z6r@E?GqfH$^tsI2j3Lq_JfD$Ys6q#FngFqn$a!YOpI5LLW=zMHpDTabJ`fDQ1z zg)^h4XBP;EvQ;(aNEYC0Fn%O0cr}7t{v;^$>tfQE#UUQ=-{W2EfvwBLW!lo(T-E%R z81UgQHe1z-xbJ8`dH~1v4N@?vylNU8K7z4#+TO^6<#{$NCuabX%#x-Q!3ga&>0Chw zf3TN^Y4#TGaQ)d#=S1(F^; zM9YNBY^|7}CHo>?-#$#$sq)<==P+n%)9u{_;DccVB`lB+6&rK4ij1Otn8?ID!l@r{ z@OWd>z>zUb*0um`O_+);&hTbbblVbS4Z)?hzORAe(|2s7hLeVMhqPtzXfro^SQ@m}L>nYKR2I=Ej)$7f9R+Tr=thLn-)gL0}4zjC#@ET%v_N_CoQ=}7tszvN4*1Gw^~@^wMV9iTx{H*Jyz0X9#|L?9HHFD{ zf{2mO6NV@V6fVVknwc4%-BDMARR3U-I=Gnb8z*7sp{F{N7wzQzn90U9?rx4R_Wee< zXp*Gf7uL+RfQcER=h(mf7YvW*@Pc=)sH-Ah{o5oGQq$ z6;mlvyWZ}GR0zU(?jtFa94zHI#gl61t@`RupxHF%cf}`VP3TA=A@4nPFK|^AIPGAD3Y=^T?xA{rG?h9-U0EXe||9;|7`b^a_=z$czH4YX4o2?}0FZQws z$_&Z64-?noPx6;*&UO>S(ICJ$&>PrJU196*`fYzmp`4R{uQPnJU@G<>uGuOg>nk?2 z!)ML6v31z?2iRHwjE)^aNz#0oSZ_aMLl1pF$WOb_(g0T#SNyvGs8V6z{b<@B8($mU z1H1(7jpY-@OISFNk6S6WA1-~bH`&^&3pVz}G`3GBmw)YNGKRZOOm40|*p8-3WSS-y zoZ8XEqQWBEREDgDY1sk7W(4j?=gb^xoGr-s%*}@871d==W|6W1e7|m4PNN)?@+SmQ z6MwjKfAiJ~V}>&+@w4Wq)MD-}R}<2vTg~>_Zal3KvMs+ntT>jVA`HwP8jMPDis-uhdw*)sIs?F5;^J7vz6&Js+uRIJ2(2=3j)o$Zi;aE)m z=FZGDGdH_(Q%fu<{i7+>`_2STg5t7s!S$w-UE4VZ1YPU8-O}9`BpvZ$o8vl7pIp5+Q-D)4agzhOZc9M4c8#{QRcaQPj{CQ^cx!hki*56BFow}S&j+Y4D+{Z# zP5c&T)#E3mK-@2>%2~_aQTW3WnoQ4C745wkc7%%zZMoVTvn$Rta$r+xsO2MD^K}y^ zIK+cwotBfpWD?;}t*=l`YUi6C-3Gd#|A^Snh`|bBac2B~1VDjSMyR@Rb)CMy|CZdz z%oU(=wz>ddhg~`+rR-jO6kthyYF`yAn+cCK<6er5#_j6gd2~{IQmtES29yP%v8HGw za;{KSRK*dKQY-*Z84?+7(pGtq?0tAesTip#Qw_$gsI!~LoXJzlrb}8P8lU+%>3)7b z1I-bgj3>A4E|;AWCMmt3rnj58ntm}Gs{i>TZe?{ANhGJIw(xno3A-Z-1uz$!#_U1b53=ylo3ujhOf4QyP^cVUAV5vQVtCDvb>!M*}2j6T3Nbd=b6Fs4HV zx(>2;4xZIII=y9gSBm+aZMATKWHgirg=FtCbVOwLqs#u@F7P;(myua1r{on*Dah|r zlt1M_icDVB@4bP6>+aap>@)X;E? zxxfg`(U-T^+c%`=iOf48b=?*53!fX$<*>Iy`Wu|;>l%6vHpL(5w+q9RbMkjqtvlW& z9|jhVvoO_8wsL)PaBJT&(Bmzi0pLuZ>7q-D3)T*|!C zhu7FO=>+>l`6m9f2Oknu1bF%A$6tRU^K9eBXq0K%oEki5J-~tb+F+3mRI@YQ+KiUZ zm!oB{X&jg$e$kci@N{&qb^p?<)n^uaqOw0N;VL0>L z!O84`!JSvz_g}95G`9e~k~M!x{&8z*^=LeQCQq}t*_?UAwRMeLFWlmzsH~a!{SEFB zmg@6cbKS>%V?{aT_KU}68t}LoIE(OqgLLdCf6qQV`@eCzdrjNslTmT7f`m0lqNeG) z?iHU{gmf3@u@qyJ)!1%{SQ?agL307&AEW9Q*Y_c|97lVT7*tsg?m%pjpicq_o=oVY zcf0Fdbx3^^T2yC{cPWhPhmV0)->fb@xSj4R3RRDH@O_@k&=gix{9M@!O>O?@)f{Tw z-H?9%A??0M-x$Nj&RWW$p98)(QT@n0WJolBx#+0G zv;WyY^W&Gj9sO4e`-{(;?{xLiv6Sqru5iHdUL5yjhN4(;EWoS?3}QuyDTU8JYJc?j zZQh-dMn3L>Jv38Cp>;`$k`$*3Cc5haTNt^9d+MESXpcjbwYM-MbeMW+fLZ)A-r(3H z0FS$9Ld>l=YcH3!K2P2ZWVfab4sAYQKrEm1Mtr4151_b7unZ`Uh&E6)p4{?N-?1tA zxPJwSK`O&cHupD|U`mur3=&pSJf!0~3zJUjv3}V8<%`#v{d)A(1e3aS9_H$?@|!g5 zTN=5Ok4WY4Rfi&yW0^;3_NJH<6x^B;SKD#l2e=Oq?%kWmP9~Mn_k13=LtHNc8h>QN z=XOjBE}-P{Rkp^%7xL1?0vg1!FgFf0za6%m>7R!2{zI}Aw%3%1Gx{hw#94_QEVc&lnU)r$cG7^G396Urq^Pd5hn~H66 z?KCs5GytF*T!B?KF;2QRmzx35Gal*z3kS+}$i4xZ+F6aM-SS=2n~U6bD_?C(Tm9uH z$m|*i?P5~>RCfazJ{eIJ$MGK3Ts<7;@NE17U0;5`g#f=wR8*xnd~M&$uY;EKKh!AF zI~M>z-yO@&%^p}fRN@@rPzzC*WRwd}GKaUYpbuzN$;!v2xqp< zTzROEA^2R-;Y{0u|N9OU@*|w|3?Ax10|0hV1BM2KPGy;IZA;nka=McyRmbuG0N_5f zEGrg=gQ*6)>)Im2A}WJYG)rbMtq=vsk^$CK{>5^wPtFf+H0R9fwKsC>rH z`sJNyY9IAPr!`_-@kwax%IQW#Hz6Y(nGg|a>GX`l(~|PDSIUZPl6h9h(%KIpYcZ}X z;h(J$H}m#_5?;z>Gl@2n1D#{#eSr$pi^k~Q8ohd!nIoH|vWEW5?aW(tkJwwmh4vfa z{?Y{s7Nv^j~I;^cgx-|>r3|Qdm4Qpe^mRgu=7YJ`j%HUqv21G#;6IZRvA)cU~ z#-UgZ3XOJECiuE9`bSryqEUM1>S6Hx)JV<+}pxU*vW5Bns zUi^J|R9?H1!%rT?r{6Th=r(%|@YVP*S~I<+yEEO`*VYbisB5mR#o(|m_}*SCEPims z_$*R^ucLT)gs8Fl-j3B@5u`pY0tC0C=YY z0Fg(w05O2_&SDfjJIg1qA;tWI)%fp~K=eqW-jSM1tARjt1=P8FUmv z@GT)r`22W_n1FV!G=dlrO1Cht#_h(D#E|arOcNSiGsqjOHt$$eZzc2AJ018ycgF;G zxT(nmdH>_dvEH$%i24Z57;)1}av7q>x6D{-$xU=k3Nu^v#{^R>%&R7MPm)BF29ry$ zd1gX#wXSV=)kGxVsC%T@Y1X2TgF{8BO~Mp$!?wZ!$8k=Tq~>+7tfefiLvGNY z^Iw`^;2J;aZQVZGUn*-^uMvS{fP%)`G^Zmcc~;hC|E}AwLwLYm-jxCq%9DY*_ckAs z9|jAV^ruI!$dX`FFxPWMsYPdlKxe@ruALNxCQwxZ68E{!ld=Jw-Hf*y1xWD8kM%pU z=TRO1{Vj8BGSE`-BzeW4w;k`x+P>jqkeQeTPo5;tvt4B;Pd5tup$ikcXYF&O2D!64 zSrmX^xHw$lipu48CmqTSAqhQB8M^oso0^2Pqx1Ahp#+{|7Bhx`IS{fjR z3_)5HF>cyis{X(}Jc*%da*AcPg-YcdNB;?tjU6(WHeZk?wg|GV1owsgT6NTHME=*p zW8P#KL-icOH*4WZH=bN4FBM?m5B1PJ8>7=w(-L!sam}d|?f>F79>en^VnQh};s*GT0623-`I^70_?oqC`lCMW!_VH8^8H6rAR_i{mSZ)+ zz!E()V(uSsWoM`a#fAb;>Rh~}{#F)-lgF*`^)%2Lh#@0muBafKpd^aSrhBa=+Gg4e*B<=srMiQ@Vn!Pcpk5?N}wqj;P9%rRED&e zzZtYS%mmuG-q}(-84$|t_U17#8ptA3BR*z^jAnoUM?kp0^0|7gZ&gU^h-xxG-=jiC zjOm>(y=T<+sn`q!vo4YA<}^KDwts$a=8P7Ke7$koR6Ka5odnQpReZ(H>-ITL|21sO z05Iz9C=VR4_i@Eqq{z$`qkw(oikk);PQkWcrP~LNx-Z~p0}ixUqrWptd(StNVE(im z)%CcCw`PKYk)2Q>pP0NjI>Icqm4+g}`DygEn%80ZmjBPlpPOK^)|PLfkxhD8Ws_bJ z?ZpOi|2%cD=py#e6GgxXA?CnmY#9A$($RUH9ZoMC-ZlKHWtkwITcb43<-o!(1>`0w z^610#%BFgmy((1}*Gwo0-a}=c}&2NWs(u(9jXqA^J4HWdyvSMK`|j)66gViX|0rT?a@DloaCQ43xL}> zKhM80K#T1S4x>Q33`~0H$!0DY_vmqY~>Mvo*r+oA8u)d^aaF?K|pGsoK+@MG3aBKU^9<9gc~T+NW+T66il=h z5OE(%T1>&py%s#(_f#huIIi7KOj3`wW{N+HlUqVH^oG@AwYlf;fA4ZdXCUhSEK7}D z1HIX61teHDq1PcDYf~v9SesJ4sWpf^Hmt_j8+J9{hXm&v=iB&Mz4mh9^ozn^Fmlhf z?kwY>^@fKB>(=AGu6y*mL8Ii#i&g_v7WVM5SL-BC&#qB?oiI7XqEZfA46`<)iX}z8 z!u_f7ZR_Aj^=ZpZ=g!Rj{U|0yLOZQa&#>>XlKn&|!0@?;z(o)lpeDYKq4mmY@Omte zRP8DK#BzQj;C3hvTIMUfVLiTtyHoD{gpdRq<>{%z1caaFZj=AT!>tn}0 zzmF`&zV=x}2&V7SkA2cIa|j`rAr7ya;{nk5vee9(7LaP3S9HU!pe+NF@?fR&KA3Nw z#K&A`#Eh(Dfe&9zZ<>JD?u)XWRuM9PxC@-QTRaAXmy6n0ZG^jzX{g@dc9afn)(}wP zTYG8st%y=XAECBiR=4k?i{aXVMtAcqIVZYHx{bX~^~c=oBR(=vLaa@d^^7yXh!PUg ze(#pc;#6lpZ;*FEBRKO|vtQyd`9QXIO`*XQGR3r0=gf53_-a;NZ&!{k$~!K@^F}|y z2X)=Fq+C2dkCL1TO@lLXKk7tC7P+e>C{AS0Vo+E0YKQE9-yhwN$d|tdPv%Jr?~vW) zGPpRIMi>0u6 zwE-8KEak-YoPFny_df2N{UmjKGMy8ycr`iEvKHqKOUrjSy((?J1w1U4DXS8 z3XeO1O<%^wKfMRi|F{u2W6p(`8y_=YGDsb4`tvdyHGDI~hn`?aS$evq^7!$!mSdbz zN)R;i@>b3LHB@R=kNtoDhMsls*AW@SE}k^jNkfoRpynrnhqH9-(;ucLNk7GE=^G0* z4Y=j6ojYGTH&DMIU17T2=iFG;%A-@;xw@B5-%d%H$1WkE4 z6Db*$%!F!b9sMBcCf`)M^u~(LQc%{5 zmaGun_v;@=C|bK}5@L3mpQ!RAnkS)9?_pGv){J-M^a*^Hx=Whs%MwV+gvHOe--26p zSda9I;#UnN7~vy{qycVb3tl1wJN!D$sL9?cB=n>cs--O#MiV z^>JycF;)P)GE5XA?wkgHYLl17#3(~LMAFCz1%nxndsc6qg~%+mc&+VpaqzLA+GL=I?5#`l7&@=C~M zC$5XV8C7?7$^-)#1p+)jB3<3yBrBpDb{i`?M3q=S3&Dc& z0681I8Lbu zE0?FB{Z_R9UCPF=&UE6Y+}u%$-mi=Q8QW)7F;U^Q7AYKP5LwZe8h;>6__dH``Vvk4 zpb$zZe{L~7KOL=>Hl3cQmgTOzhYfb%ItPIk#`jV__PrX-jY^0gLrIns7A2n%dJmm?CZUJaZKu0SO;xL-Cy?rFm+r!H~8{#nGqu!(b zLgHJJ!6_+avH2{qq_9w2#`25RX!Awo1%)C>etv9ON=kWbpv{fnBgxRB(JrKOyR^q6 zFT)N{KBlVPwL~0iLoC5)e;64({{f@L2)B*4&Ns%IRDkkkJCAmFNJ0Bxq3dWx>;pd| zO!bQn&tzK-Z|fhkpAL{`@{v(9?z^$S*63U&{$nn z-CA9^?$bAI;kwRVz)7hY{@F6LLXwYW7;(`ZpY79;u`V)@E28qiElCGpUOX8X?t4#Z zAlhCaTS`xZ#s6Jt0x&e9#SRza(j!zP`HT&LcHT{crJinlos0t4PtSySyBG|lQo(sq zF$UN7B!Hb-VxFc|{qMNRoW&gS+q-P4x$)`0#hI%KTN}1<7U-iPnbwJ0RB>pmg zPFgBCvtmfzqZ=%A7b=`Qq*F|4DkPc?cgyqCh7_cMnB>&0+xr?T8hPYJf5#Rc6B`wS z|BRvTfw@kY!CH4d;nesOHd2KXApmA$)D~Ii4&~#EmV=fl5g;q zV;}jDBFYE_DxX#Ru!sHjv*K45VFAzWk`y#ry|Qs#r=T-x6@t8k6&abMh#a5zDqlaN zpl9IiK|YY5@Vn~7&KT|E3_^Mrd{({Rh8p<`O40#HiN^wi(|O%odx@NsmJN&lGdMIb zNbFiy>}v9_4+&wt-(A|J-zTf4QBuj1?(tc!?Sv24k*ykA<7XgFklWgG#D+3cGawQ?d;YX;w+(Xxekzg`;UZEHZtTisD$~yPGbVc5~ zn|Z$f8cK`}VQcG#0WbZrlk}`J)FZ|cuSs;SmH|iRfdyCS?~dLgdX+2v zZZf=se07oma3|}hyIE2zUicaj$wK_e3g^0pett@a*PUSz17f<3ysnm_Z#XE8wtnaH zP(0r{cg;NJrcoa;9J1<9?{vrHXv_n~VasEz8~Aq@c&sK^-sE6);s@6pt$q{xB`!K( z!MsYfErR&yAn&pJWg7myuQ-@%b$j2uS9O*FaHunB#&>ur>3vHo(I#fZpih^rXfD7TAt_utqi`=|Ie}< zMZ`+HA2rQdE7NUXfh}l5MI1DQ^jAB*J6)1Hd)A+>7umkzW2+^D(R{8!UP?|tCZ@v) zm|_f^ke--;B9+Ry2EHm;yn6G=JGPK-i%HLlLp>wmCeH`*k;k~FYj9iQ$m#1BUoq!~ zo)6n8$s{Ua9cvPe`d1nRetV}s1jTndTQM_HiZoN6qO@+ z^|LhRM|U>FMX-)#U1h}Kv&v_XUE75sI(qFAwW7br(?upl$J1Yf<=U}4EomGC2f~9Q zlES+K1I+v5O@mNaBS5aRJjl6A+7M;qB$j^Z*d8;rT0!ZJw$8wfn%;CfJ&IcY2^#x2 zQ&dkyBGHw3oE&2ZQ||ETb=Y;7cJi5;Bt3)}i3$mVc-2(8 z8UiYrpY{@ZM?Q~Zt8dR*Xf5nLpe)-x1UT2X)x+7}vW3g){=`2M#i6V35(fu$KgkY-G@%K9vYowAJ;&2L z%%+=xJ8YT!ftE-s-KSspefcQTjDoMdX%)E{byQ!db~FfTxSjtUPDM{4LYKNVsdpC5{zVsT5R2Dr$f_R|_Sl5EKtC z{~z0NoP6`^tM#(jI66-=zVlKe!ByxGs6Gtg&)yVDZm#bU(%)N<+271d?)TzB;;kb-GO9~dtllg5TAm^&aRBJqfQ%-#P?{0ZJZ&G4lhgsGE@dLnZ>>Yb zRCX#p70=Eq7gIM@#Yw@X;5hc_6wqa9>5VU?FW)FWdC{cLZ}s-AfgJ*T6!5v0Kz@po zPhnv`ua!{y>l<@uJ?dcBveYe}fEu5H&Gkgj%)63L^Svnl!>;*}ngR^FlQ(OSuVw~v zJK|9bEotnVV&&3|PTkY$1ERJb7rkO`LpE^RI7svw#0qJ)Hd_;zc5# z^qZI{ZKZaqdC3BAAt@kJ=yX!1QtuFai;CV4%fM$I7YDNPV&kz;k`1BTF1Xly>QWm?l72RPqOLW{PT-*H+hNyVjcx$K5hY?6p1$9=l9y zrEs&nT$s|(U~8KDo$^~2gp&4?r`H$P5#}4y%USmu-3Ke>f{~dTubpK|{%9)gv**vE z^jL+3Wew_+x+2R(jb*Ea1WAEnH7Z&L-)Yb($>UDy=i}{3X|_)Cn)am0<+bIx=B@g; z(RzTa+0L^E?w8+%JtYn!D05l;tqUt=l3vTE*I6vkx_MIG_*|`5 ze|a&Zk7VCo^P3!dqiZ!U6Z-sFxLP5V%8gG|EEd&P0$~dgiWo^|m0$ow3uO6hjJRd+ zUCKTaB#+9et2;^EXbxVhCQZF>)-!GVb@Jkbui3A6dv*Vy#uMjvRnzc!1?{g~+y}Y# zL!kcAkX*Tyn@8JqlVAo17p*Lu-m$6Ds z%MJ}fPQP0dMzaqc_4ZfyF}WlI%O~(GdreI z?vWngd#0wR@ulz9zq@{QT{r(|w0+-mi~h|0n$^VR23~ikgm0gC6}x+x=3f7P_O#(c zRaMiwhqFoV(mWpSV%KE7?RSco;Wvje+#aJO-MlvS^PR_6xx6_IrmqM*B7EUfK7QdCFQ$m@kw!Y-^P^HAOV@+X$x>?EJ#jfQgFF)g2;ytK6Oe)e| zbv3RT|M<<-qwxYS8|xa^m~DWK7uV-k_xHxy|6Vww0=hQoOoiGirO8m&A^!_6Z#S?L zQ&_g$a35JiTR&pu@&>|Ke%owQ!7*(>N3OSa+BoB{WjYZx^0Q1B zSt`madE;CE`FU$?#PoQgy+tK`N0(p6kM+w{2TuAzePJSY7*%1YV-bta7QQG1Jbr=P zwqjnLj;a!>yc+{1g{n-jLb!y{-<+-trU!sJ%npV12~Bu&hj?cw-$dTEF`>xcK?)Vq zed2fMa@B_*)=K*Nj>@U>DB-sm@8h3c-liwK+<$)&0~S3mgE5oygkT6#@Q!=Q7Gan;-zzz~fMhP8XC)%5 zSXeNKh<^G^%|Jvwe1CG`vYQJJnFWnBS4|XIFLlXBZh?HF&-!Y#XP;y?dy)>?FC!Bw zhxK#5)Po-a6y$eBq3rHrko0%1HtVf7U=u#D@a)`)O2$^u-B~Y zrA;MdCr5~~;B0h!xIB>>gF{nTYDHXA@M*chDAuZB5Uzezhl)K;$sttNsG3ly(qBH3 z%Rl|_-^Z3F4(OFMSdXG0XJ(-8%_O`@+jX0|eX`mhS=%r#&jr}9H%0Gdt2@ZVjjr^J zJi9hYjZ=mpvCeQ!-Vm7;^pE`O>j$S#YDXJHnb3VFH@T*%(Uj9*XeJK3G9)p;(euryzo2R2T3Yzjh?;gD&xwX6cHA&ym z=R90NPwL1#`9`z$*nFMG5dw~QXKpd*jSp8)M?L?z{*OO!0?2^2QH~@lZ*BXC|G*;u z&lh9*vmtyPKE7o?uFjg@HL>6vo%+*c@9PTy06exOMfH;~HE`ZhPUW}n&$o9zU7ht_ z)kNfkHolJ{SvXdhsyfczR{l^eb!OcMr~1eD zA}{JEVvQWVf_JfZad>ADWiOD;E}}dKdc?ry}WiZ28=*7j$cdRHLM4U*gn_ zk?!RkQF4LO{{hdz{wD6Mr@hJb!FqBK!kA(A))oE8I1-~USe@n}#s99njW$2S*CG#^ z(bt?>nEg}cPaIwK6$M&yAAN0a<=7(4?|0FA>59zE-B1Vd1V(gpM=B0a-I(*8FP)`r zG9jYiFm%<`=AeFS9I z5ci+!+>6}x3}jazaYr*HCI9b0*Yv-C3d+1`yKOPpw^ui^cBWand-ML>DsFZF@{mYW zS1}~Te(o+TbD!euvMH-e+ZX3%3I1dFO(#Ew$iT$Ttf-wgtzJZ`Hi@uuAM*scdx{! z^kgRmrnwb7dueVI_73=a@g?F`0eErorNiwV6U3bWmHqZ2$j&w6i}@htV}i~9G}G>~ zu{6ghZUZ$N@35Ka=0sBAQW-^~l9!KspImtYd|QX}N9?YAAVadCqU!haj#P#J24=AN zWPBpFy74%6sA~Hzm3Q|($C-<>TedLBbHd9d`-g;(DHuwpEN%9r5}8i7t<1?%6!q-l z!11x7ORB#gXBaetfPnYfywmJG_?M1$C&$DzHzr_E{g#`WiiXLBEVP0Aua z(}BjMa}MQoohJ-ztBL#KKiq$#1s$`AlT}uNN(T1z)qaOugsHv2`Uis)3?maeqjyk` zt6r9tSGXPY?H6JH@lqVPWBmA?tmI`2&Y{t_-aArv!?tZ!^?4vl7`~BysuWng(7zKZTc45W0X=apLp82#D$$k7;1b`%W9^I`tzoEEoqt9A2Ch zjELZ}A&XboYgU^U82~~!V_&*Lh43=>?bn~QuN@3aAkWRdey4jm4S}404PT0+hT)-? zYjDuZq5dBZGT|}ST8%N#hZWW%X_sjd37#>2U(LBy2;T&FPcQeTBtq$g#>x} zx_Yq_0UjDkj_T)l&;~>dok7 z9itT8DYNhSyFbG0_NvahG}BfYH4&8aRCn_To4eMrhs{;hC0X@)#T`)TC~4omeoH%k`qfX`3Uqk zvikc=f;%+ItAfs0DRpEawwC;%LKTlYW!L@pYX%kfw``wdTFE&S>(1ico2CaR3xsu8 zHteSSH0q9_j&ZHzO5|+deFeMWuM1Whno8GC_uvQUR>X#>+T-VM7^Thr)z1z}&JZu6f$b<6o=U%AJfwo{ch3sWl5&y_#G`(^j=C)t>U~nm#?QUgyunQ z&2tjRUeHxch|iKJucX?@OVpPXPUgBqv1(Wcq#?Y3UH$05;LK$YX4Vw|E%Eru2nF&$ zuzUH6W~Qg2lEcESr*HEd_jGcUw};Ix7q4p7rk%(W6@X^IBX{wG(!PAHE4gob3pW^1 z+rdfsRl{A;MNYVEq+9GD2Ruy*m_le+FoVIt3Gl$jbNfg|zlIMP<)&c#@~W5vJOK`! zYcUmoZV!7~MbIo}4UDgV_Gk=p_O$M4568jHY7WRYqr)b5%O(}8rTC!N`hPv!#>M0t zLSDJ5;x+yRFF^+x@MrR5=FXO+&(+gDRE~HMzZB)dZRVm}R(OIpywAlK^MJ#lw7x(o=eUX(OF^kV&+tNDhgVxv0Y9`-$e0Q$S#* zQo{Gx=L=C}7p$-gFt=0WiESAVijOooW)u>KLR(8uo3A{twgnAsDYY_vQzn5_y_>MT z2Fp`~Ht04*wUqDL?^J=bKiQlbR-O}hd7Jb_{$wtso=bo%>Q8V_&gF-l66%Mpu2)+C z2|5!ZRkTAMGo`=!_YplSRj}#Gn|0=4o^4oCE-Su-;%DM>z$rcBfcM!I5JC?;_s?Ie zxY19hM!#CMO{aU=Z9y-M?oVo8iI8Olsn2{W)@hzL-n3z0v_WnBh-odB}0r zcWSem@MZqhRj@Coz}`h_n=frA*R~A%oG{DtGE4v5fX!7mRn4z07B5!g5L2H{F80Y~ z?EWF0`}RuD+D4}TbaYJ=&izgRx6K9Ptm8o$FqP2<$;uM4t`*rwYoJ$G5ioCcVoPVAP{Hn#GgUF@|<5>H@OmI1WQXYM>#Op-8WdZ3r0jx>r-!-n{^Z z_^m3kgyu%KiY8I?iW`#msy9Y0d>`-i7WM%5^$ssn-}}uE znKFXjz2$uh!qlUmvVIi!{r5f3H87_>=a%&uNIld#lRcK&4}kA26PNP$N?5Giqp4nK z=&|49gmDy4E7}1H@puBMv=%cz>EOGKj~ls3ToGSg&~d}4)0xwSEVIk{3>B}GUtQ2L zd*IWxImEcfO+tha(mot@)cXTsaDk82%=wbC=9)I==soMeC_z=LMoa_LQ!Q;Rwp*qy zRAP_Rg+p}W8~@Tv_(Jk$^YiE~*QeXRJBGI9NU5%gj}7mzQoQYWi-+JH0&he;2?onUxTb~x}5w_BCr0UdUr5naJxfz{L12{_ZDp4XiRCD62W3)m13;) zGU(-jq%ClKkL)|7O9A}hUxjzdFJ zw1a!gS`e?Aqq;f^yV;&W#+gSdEBcDA#~H~+8B<*1&RMyXJTHKYewkQ323{$ubc?vP ziQ0_wE7kUPyg3V!FhZ!1L`d?u-P-SHYIrbke`P?150L!VuO07rNypzNdL=vlOL?53 zL{5Q~BsWi{8(p61gRfm^(JQWdL3|I^lyx6pQ{Q}xT7R>aPz97rO-O50eMbG;xT3=5 zhbue;f80%Xv;J?abfTT3s+WP5?Owr>OV+F>sBKh7<+fEonS;FBfpvOj1U0rrf_)vj zxIPWc1r2~QP665l_io?L=E%W2A=C#(Ru3f8LYhcj*UF+BtCy=aeO1?aK+w-*^r+YP zU1CNLRVOU2SZueTf%iNXK^~KUmS*4-D1wh8CvMiNo2^$B0qy*8um@B}A8@*O@X9lO z_>o#sKLXb4_QFFNW2#uyQ`K}u)lyUS*Rgmg-q>2EWJxjV)Ky2k|74qRu&9R0H_}yQ6XnCQ5(Q;sIAiW2jGgfB2j{Sf1 z`~gtK`hgk+%Bi=Ke0hK!7P|FWjze`4H?Jr$ft29Yfe ztPNO@(n6Y#VArwJ>8(?z0}{dqKBwiVGPh9qM5xg4$Iv4iiH)*hU02IKO=|0qrfT?xvXM&MrKN~hV~Tl*Rpr@=XoRR_URdD{o2EDsBXa=F*g*qyZW!oXKzSu%~yw;x6!EK8_q z#Xv_K#|81@@MvQY?>}tswCl|GA2-Z}97Y$&drB6OwZ#L}6Zl{VxFCcQO$dnyf}N*r z=;$khBhbuEk98EOA;c(az~9=?k$rJQCB^Nsjk`JsS#L5Gg4cbjH{aR0@QE8?lbKh~u+QbBc zf}ZEh(I;3owrAC&VS2T#?TU5bIwOR07sorcr%L{*U~q-k^UHI#*Gf^zY2Y&Nmv-)f zsUZQWzP;>KC^&5+aEz@-$ubq3#_&AS-oZvtbWBN0qk0`<77h&WKW%cr3fBNbZX4;I z`RQp87DTo`t>42l@QCHUlu#xJ1Y&?HHd6>zS9#Lr^h-HfcMbv~|^8kd}$ zmsq&w|w58B;Rv;z_Q_g}`G{7w^i1Ijq;NxH&VeCE!LM5XVM;$=wNrPa! z^nxsPa{5u>M>$;h(UCmO)C55mH`5@e*PJ^l^f+x|wC3rp02AK|umkDOC}Z@kbg=Tf z+zLFcsZ2Ze-HqcMFGrL0^=i&~xEX4x0~!yqaB)PB~(Q!~N9z>ck`m>O6-*hfF8(%Qd!7xTJ8yw-{`}u)rGfs6X*4&Hd$sdb9uV z*(d#lo@xgj2M46r)&V@xJYnXxAC8J%=-xjIfYUjAY9;eVxn z=FN>$Us?^ff5zR=eNUv*$9)^>0YWl)pJ%7Fq72oceT$Ea5rs6;>~}MI{FeRo2QL8dN8hwg6eW0BrnWqd{590%VjG|4_swMG0uvN z-$5pSboP$vUpVb8QB4^GQdT5BK)V=#itS;`bSp%nZHcGV5jB8n@>?USahtfkidsEs z22GUcxCbyvm`rM`4{;QWx>+bsZF7HC^+}Li^smj0UJqg1YU=cr0&Qy@W-n2}(KXR3 zUS2CJ5y~cu(Tp%pUSDa2h|Lohq&58OG;OW6*g*iW*_*%LQr;>MXeB3_D{j4dpRP6R zDrF%*T+7Zqi#aY_$GA4swum|W@~~1xb_7PeZT5E(0nj3=1W5Ggl7M$4pb~ zV#?~OwdKr^cIQwkd;@0TNm6t=G(XY1zvK_(MrUlJC2JWX!Z)f%yoOz;ai3W8ETM%O zcT}MF?SLRQ)#cAsZCWq*DVkWdZa#%5K7;L}Ax5kSM8x4_O+<@VDDqe`O~KE;?H@b} zKS`V%M~#z2N6925DhT_ec61N6S4pV6gk3t=ZbEO8Fk_g$#!66?JAZ~xb6_G#2MI-z?4{7s;jc3#BVwSXZG+&XQh zK^p5>&w9N43s{0=7&6WSRFs20Jc=~>OUtlk)u%@H1edTo+z2A$(1H2D`sd_Y7L1Q& zH|>AvWSZh4+yA(~)%vi`$O2`BeE=OEd779q`0X$a-1N!t+iX%Dq)S!~)RRz=cK-TM zdGa2q%(x8j9kD@emONa;dYT8^{7-u6O2d0z&$-BSY#$Z_aSX{O(1IAe3rAc4y{b&uk(CrrcFQLV3 zJJ}pbx-764v7|KJs%t&7Jm^>niPWX;hnBqkB>HV{y-i0hskVe1i4Mb$0TpcZUE%NK!$nP&+>itd3 z${l%zV`AxL8Qkvo7r>HCet%$_aU-(q?I$IA`MMUP9%|pfNfq)OoKpUQT;ELEI@vud zdy4jHW2WT0GY1CYPiTcEv`-Olz0beR6tCv_wikF)=i)s-Sl@U_C-cGm@KcMSgOggV zvjIGO`Fe$@!+8?U(5;_ssO{ZPhUVjbe_#~8M_%m|*(v;hX+(*RFTB+U zlh(jau2^$GLM^&>Yw>6hfDQd$e zMntl{9^EBIgp;qWGNM+Znt7}qdRRxEFe4`vbex?&HKYRKBxEav{shy#aB8A@sFKX{w)H4Bw!4&zBKoE%jSR+F!mUKnNQzHweF7n7j54chmRc95%YU zO}xE*y#aC2?P@|?!-~fiO8&t|Q6e!A`In$S<5Bn(H{NL9EWFEZH>1X}dPV7)smm@c z-TNVl33hk|AUkvImJyvmV9HZWzSEj8Ka%Zb;$vDW$Shb$L_UaE=v*GDEdb?|*O6R{ zDk2s>**t7YK5VwtH8SC;5#b!g>SdWbrxvrNqMWWUFdgvMqUcaNPN|gYEnl{}_hj*2 z^{oY5;K@Ot&$#7O7&aZ>q0MvUN_mZs)+bTOf@-C@!&8q)6CKvgL-egt%e{Q91Oy^e z-FdfVcQ=2sZd3>9FnF(L`e8e~$Z_BR-Shk%f^BxNqTbwT6c z3~YltDG~We10Qoa&>kK%wWxEN1;8*cxA~;HV|{U zX(_S_lATr2AQr1CsWrG*YQF8OmXHo*%q==^HDTO z>9V45a!W@;nOKD%*mqgTnahVNp5CyL{8g|rK?I9iJts%;n(Db#GcMMee)cpr%Xz1` zv!b%BYpQ#6dVB3~j<|WUp-Do3inl??nly7QE%kHrE2B5_x6g=kH_wTpkZdvFCHM2G z?4FitAX2cXD!D?l^p!i}%D+~l%`HvEHhgqr*K|yI?MC$x+yL%6F}kJxP!Esnq>uF)o>RTZ1e%QrU7AflHnZT*6N4mj36Ke-Wy&X*cWabs9QLbxu;-!-DK96HR0 z5_Nr8d_u4;&Qst2AsafLiA}FG6_qXBymB^Qn=^Xm&fOq4rtknaYFbuisxqbX>4Mmqo10JV3#;?9_HA2;LKk6T%JAVSDIb#ClhIQvW>}_g%0#VTD?d^Hz4UtCfF1o z8p`qiWn_}Xt2fsNYZ~Okfngy{FC?{Rm*|rJD`2SN!u)~xQtcz=CYWwioK9Wg%+$F z#c4rxMQBV)s+)JNOCzCO#7eVQQ<3fcCE80*tll^t+flmXB}I*{+4f2P6+HsBAu3J| zGnfrrZCYKq*Y zf_T3|;i^Vqx9-Mq!P#!6?rCY$6M>WRt>B6MiK^Q1!|r2$Eh-_)o0EN2xHO({5hH;6 zkAdcyD-(@jw6>DqeAQWqM(W)Vtqg+4H&^$K_U@#N1>p7J7mmY;ZMYIT9#zpYAb?%D z+H;u?58}fQQnGvCSSaz`23e5E(~`SB=gFVs(b~$Hun&+-O3OZS!zzk+<>&~4ucOZ% zIXD(O9y^#dT!({LUdE=MfJr@PeSWM@YQx*TNH_DBj(oM<$C;e26wqPWo9xYm4YQ=Bvcd@P07ahk&5ArI zFS0fZz^$OfgX`VRm9D7kff=7cQ2k6gD5UjH#P`frczrRY?`fnvr5s1DKIi2kZ#%c;|?r*yL z`?WMKbkDX;4sRS?_Zd)*J`5IUxx14%dU#~%YdGGLP;f72%^&ks>4kH99D>r;!>c?G z+)0}b`fHwx-Tkw*vkNIz^w#>Of??>>bP9?9+US_;c|io7G3KR}2JyM!umdJuOW?+d zM#VnL@4JIr+}59ilkV?%U0UxIBuIvwwZ1vg$~@moDW!66W`o19x6!#E6Q{Y{rVNfT z$SKwR`1-wwuQ>O$=@)b;gcFwU*fvs~$3C00b+HOP*UbU??UrSC(wC+ajmAYhB>Qex zqrBwsay24cW7E@}`V*L~{io%})70V~{+(wTtMyuNUp)8#mmzf3sA=YA&6e)GiDk^F z#RdLnkbXoejM>ZNnm{BLHxD_XK%}XtgW-~6Y3-K-Q^yVE0YuE+UIc@5F=+ID?Z(an zs07WqA&|~sD;PCSU)sD+31l%ClKciG>QDmE&(|pmqKrOHyU|Nno)DfMAKMTIS9M*F z5_fWb-HSq1U4m8nWAR6iU6*RsOAu;txdJW!`C>|2LBa}}y zHU*x2tU8NhHW;$5$8GF~aL&uAoM%V?j>>gzW(LS+Z{4c2u9sM{L)j|rNj{SKH!s^i z@7@Z0>>JzbnQ!=JE;sTT8h1(_ogNogx9k>+iXIkvuv-ZCDL2TR9gfU^CZF_P^SuMI z1pRi|-g8#N!!W^is)(%^I+K+oO<{AV=#no~E!z9pINbh;{PT79I4NiE)!sbY-)3?= zyiy*y81yXe7C*AgWqBw6V5{H1Yp2A`7HO<#FW2W3*8e3s=SXvpyXfB5o@>wmt3|mFw6qtBnD1*~YEvMgYcHG~TVd zWwbW8tkNo8Y&difzqKzT>-b{&ae4>{1I^YPRprxQo7=d5E-AlSeW0T`{;*$Rsx;W+ z^2XA^N`K1;HNmc$<*lmC{o(z_Rkz=Wizl;+?yYySh$HJRolb_Ui2L^46uRc@B_*ua zqEC8k&+WULT$V?Nm*%r}gS)$cd;=SmwH*u9g$Yyr*%aw6%heRjuiS88p$5`YsIp-z zC4^x^jh@EgAu~>9m%-?T=E;erMwCHjj~V+3eGxSphlVAvK{hUNgDOZ-VFNak17Sf} z8Eh>sE&UP%7I|zN0)~U3(CzX4{kovAlj_bl;hAUZMVsLIp#gl>mVVDxce8Sze?#M$ zUqZ1EZE07_kp?0I9l4DVSd9u9<%C^fIfWmAfs)j*L|B0i{-%9qlXDi zkVI7->V^wj@lCEt&4wlno?Z$Nb@`O zTItQ$+}v32zxC$v1Lc1=S7!-UkO)--qe8>|{3aokaU6Ld6wTLHUNjdkKmDTq*18s_ zq-%>7XZBM7Pe8E0D;M@{PEU@W;#_w@^bZ6j?PlXB4?Xgq0#@2W+nBIr0k0rS{D?Icm5!y@MS)7ey&8!5!0}j}O;&sHuK*oAMCq*_`U?#o}{3dSFLE zANjnrL_JCn&GOIRTIU_bT`2v3z>} zm+mtkq3Cm8Obu_N8e!LPa*c@$^O!FkX|Dt3lwP6R2bxPtW*+{|BDt@v z_R;M(j6j_SS^cH(+JZ>kgv`Ua`^aM7u}lz1P{n7(UUrS@SK>7RnuL;X#tzp8k_QwW zhT?QXS9wvufNcAVJsGX7TYNk8l#?AJ)6zu0uNT;Z?ywS4SyN82jwUCZdwSb_Q0pV;D_jI3F#ALlw|TD`Bd;M9CCE#zn)&A7o<$ zwe0%bj_E6h7_K%tlC+k!@nN$ZkiYZ8-u{&_0pd467pZErmD-u+b&D1YNdbw%U{KTS z^s^oKZ!tbVmeNY6G2?DIpgfW+(lR@04hjv!R=_i4*_Loc+qeRu8JqbzT-g=m{s?z3 zwpu0lEY&3=;XUE;vY
        1}B266i$Ihu455O4z84sv9VxLOM;1&qYX;Q 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

        Q}LUWZ{wbP=EdHR`_!hD3&pD(c;;cV!gg0oKU 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

        ?!q>cpMI?MHx2w&>L(8I;f*87C*Z4 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Italic.woff2 b/docs/themes/hugo-geekdoc/static/fonts/LiberationSans-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..86f6521c04884f81c9a48e50e3ae383b3aaa3ddf GIT binary patch literal 139304 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 -i+FKf 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⪚)=A6l_-KZ@^(mY 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff b/docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff new file mode 100644 index 0000000000000000000000000000000000000000..bb582d51fb75d2f4d125f15e6e089d319af6e7d5 GIT binary patch literal 188280 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff2 b/docs/themes/hugo-geekdoc/static/fonts/LiberationSans.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..796cb17b55771e8282b4554a86f145a6193f39a5 GIT binary patch literal 133308 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 #*I7^s-J}Y4IY1hQvRfTBA1kd`2zbAK}odo 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/Metropolis.woff b/docs/themes/hugo-geekdoc/static/fonts/Metropolis.woff new file mode 100644 index 0000000000000000000000000000000000000000..6b1342c2f125825ee1967d00c5e863ba5e4597e4 GIT binary patch literal 16336 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 \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/116-341f79d9.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/116-341f79d9.chunk.min.js new file mode 100644 index 000000000..efc09abb1 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/116-341f79d9.chunk.min.js @@ -0,0 +1 @@ +(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[116],{2116:function(e,t,r){var n;"undefined"!=typeof self&&self,n=function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var a=r[e];if(void 0!==a)return a.exports;var i=r[e]={exports:{}};return t[e](i,i.exports,n),i.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var a={};return function(){n.d(a,{default:function(){return l}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,a=0,i=e.length;n0&&(a.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var s=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[s].right,e,t[s].left.length)))break;var l=e.slice(0,n+t[s].right.length),h=i.test(l)?l:e.slice(t[s].left.length,n);a.push({type:"math",data:h,rawData:l,display:t[s].display}),e=e.slice(n+t[s].right.length)}return""!==e&&a.push({type:"text",data:e}),a}(e,n.delimiters);if(1===a.length&&"text"===a[0].type)return null;for(var o=document.createDocumentFragment(),s=0;s15?"…"+s.slice(n-15,n):s.slice(0,n))+l+(a+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g,s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l=function(e,t){return-1!==e.indexOf(t)},h=function(e,t){return void 0===e?t:e},c=function(e){return String(e).replace(o,(function(e){return i[e]}))},m=function(e){return e.replace(a,"-$1").toLowerCase()},u=s,p=function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},d=function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"},f={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:function(e){return"#"+e}},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:function(e,t){return t.push(e),t}},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:function(e){return Math.max(0,e)},cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:function(e){return Math.max(0,e)},cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:function(e){return Math.max(0,e)},cli:"-e, --max-expand ",cliProcessor:function(e){return"Infinity"===e?1/0:parseInt(e)}},globalGroup:{type:"boolean",cli:!1}};function g(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}var v=function(){function e(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},f)if(f.hasOwnProperty(t)){var r=f[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:g(r)}}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n||!0!==n&&"error"!==n&&("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=d(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),y=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return b[x[this.id]]},t.sub=function(){return b[w[this.id]]},t.fracNum=function(){return b[k[this.id]]},t.fracDen=function(){return b[S[this.id]]},t.cramp=function(){return b[M[this.id]]},t.text=function(){return b[z[this.id]]},t.isTight=function(){return this.size>=2},e}(),b=[new y(0,0,!1),new y(1,0,!0),new y(2,1,!1),new y(3,1,!0),new y(4,2,!1),new y(5,2,!0),new y(6,3,!1),new y(7,3,!0)],x=[4,5,4,5,6,7,6,7],w=[5,5,5,5,7,7,7,7],k=[2,3,4,5,6,7,6,7],S=[3,3,5,5,7,7,7,7],M=[1,1,3,3,5,5,7,7],z=[0,1,2,3,2,3,2,3],A={DISPLAY:b[0],TEXT:b[2],SCRIPT:b[4],SCRIPTSCRIPT:b[6]},T=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}],B=[];function N(e){for(var t=0;t=B[t]&&e<=B[t+1])return!0;return!1}T.forEach((function(e){return e.blocks.forEach((function(e){return B.push.apply(B,e)}))}));var C={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},q=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=E[t]={cssEmPerMu:R.quad[t]/18};for(var n in R)R.hasOwnProperty(n)&&(r[n]=R[n][t])}return E[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();V.BASESIZE=6;var F=V,G={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},U={ex:!0,em:!0,mu:!0},Y=function(e){return"string"!=typeof e&&(e=e.unit),e in G||e in U||"ex"===e},X=function(e,t){var r;if(e.unit in G)r=G[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},W=function(e){return+e.toFixed(4)+"em"},_=function(e){return e.filter((function(e){return e})).join(" ")},j=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},$=function(e){var t=document.createElement(e);for(var r in t.className=_(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},K=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,j.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l(this.classes,e)},t.toNode=function(){return $.call(this,"span")},t.toMarkup=function(){return Z.call(this,"span")},e}(),J=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,j.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l(this.classes,e)},t.toNode=function(){return $.call(this,"a")},t.toMarkup=function(){return Z.call(this,"a")},e}(),Q=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+""},e}(),ee={"î":"ı̂","ï":"ı̈","í":"ı́","ì":"ı̀"},te=function(){function e(e,t,r,n,a,i,o,s){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=e,this.height=t||0,this.depth=r||0,this.italic=n||0,this.skew=a||0,this.width=i||0,this.classes=o||[],this.style=s||{},this.maxFontSize=0;var l=function(e){for(var t=0;t=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[îïíì]/.test(this.text)&&(this.text=ee[this.text])}var t=e.prototype;return t.hasClass=function(e){return l(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=W(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=_(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=m(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+c(r)+'"');var a=c(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),re=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r"},e}(),ne=function(){function e(e,t){this.pathName=void 0,this.alternate=void 0,this.pathName=e,this.alternate=t}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","path");return this.alternate?e.setAttribute("d",this.alternate):e.setAttribute("d",C[this.pathName]),e},t.toMarkup=function(){return this.alternate?"":""},e}(),ae=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e=""},e}();function ie(e){if(e instanceof te)return e;throw new Error("Expected symbolNode but got "+String(e)+".")}var oe={bin:1,close:1,inner:1,open:1,punct:1,rel:1},se={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},le={math:{},text:{}},he=le;function ce(e,t,r,n,a,i){le[e][a]={font:t,group:r,replace:n},i&&n&&(le[e][n]=le[e][a])}var me="math",ue="text",pe="main",de="ams",fe="accent-token",ge="bin",ve="close",ye="inner",be="mathord",xe="op-token",we="open",ke="punct",Se="rel",Me="spacing",ze="textord";ce(me,pe,Se,"≡","\\equiv",!0),ce(me,pe,Se,"≺","\\prec",!0),ce(me,pe,Se,"≻","\\succ",!0),ce(me,pe,Se,"∼","\\sim",!0),ce(me,pe,Se,"⊥","\\perp"),ce(me,pe,Se,"⪯","\\preceq",!0),ce(me,pe,Se,"⪰","\\succeq",!0),ce(me,pe,Se,"≃","\\simeq",!0),ce(me,pe,Se,"∣","\\mid",!0),ce(me,pe,Se,"≪","\\ll",!0),ce(me,pe,Se,"≫","\\gg",!0),ce(me,pe,Se,"≍","\\asymp",!0),ce(me,pe,Se,"∥","\\parallel"),ce(me,pe,Se,"⋈","\\bowtie",!0),ce(me,pe,Se,"⌣","\\smile",!0),ce(me,pe,Se,"⊑","\\sqsubseteq",!0),ce(me,pe,Se,"⊒","\\sqsupseteq",!0),ce(me,pe,Se,"≐","\\doteq",!0),ce(me,pe,Se,"⌢","\\frown",!0),ce(me,pe,Se,"∋","\\ni",!0),ce(me,pe,Se,"∝","\\propto",!0),ce(me,pe,Se,"⊢","\\vdash",!0),ce(me,pe,Se,"⊣","\\dashv",!0),ce(me,pe,Se,"∋","\\owns"),ce(me,pe,ke,".","\\ldotp"),ce(me,pe,ke,"⋅","\\cdotp"),ce(me,pe,ze,"#","\\#"),ce(ue,pe,ze,"#","\\#"),ce(me,pe,ze,"&","\\&"),ce(ue,pe,ze,"&","\\&"),ce(me,pe,ze,"ℵ","\\aleph",!0),ce(me,pe,ze,"∀","\\forall",!0),ce(me,pe,ze,"ℏ","\\hbar",!0),ce(me,pe,ze,"∃","\\exists",!0),ce(me,pe,ze,"∇","\\nabla",!0),ce(me,pe,ze,"♭","\\flat",!0),ce(me,pe,ze,"ℓ","\\ell",!0),ce(me,pe,ze,"♮","\\natural",!0),ce(me,pe,ze,"♣","\\clubsuit",!0),ce(me,pe,ze,"℘","\\wp",!0),ce(me,pe,ze,"♯","\\sharp",!0),ce(me,pe,ze,"♢","\\diamondsuit",!0),ce(me,pe,ze,"ℜ","\\Re",!0),ce(me,pe,ze,"♡","\\heartsuit",!0),ce(me,pe,ze,"ℑ","\\Im",!0),ce(me,pe,ze,"♠","\\spadesuit",!0),ce(me,pe,ze,"§","\\S",!0),ce(ue,pe,ze,"§","\\S"),ce(me,pe,ze,"¶","\\P",!0),ce(ue,pe,ze,"¶","\\P"),ce(me,pe,ze,"†","\\dag"),ce(ue,pe,ze,"†","\\dag"),ce(ue,pe,ze,"†","\\textdagger"),ce(me,pe,ze,"‡","\\ddag"),ce(ue,pe,ze,"‡","\\ddag"),ce(ue,pe,ze,"‡","\\textdaggerdbl"),ce(me,pe,ve,"⎱","\\rmoustache",!0),ce(me,pe,we,"⎰","\\lmoustache",!0),ce(me,pe,ve,"⟯","\\rgroup",!0),ce(me,pe,we,"⟮","\\lgroup",!0),ce(me,pe,ge,"∓","\\mp",!0),ce(me,pe,ge,"⊖","\\ominus",!0),ce(me,pe,ge,"⊎","\\uplus",!0),ce(me,pe,ge,"⊓","\\sqcap",!0),ce(me,pe,ge,"∗","\\ast"),ce(me,pe,ge,"⊔","\\sqcup",!0),ce(me,pe,ge,"◯","\\bigcirc",!0),ce(me,pe,ge,"∙","\\bullet",!0),ce(me,pe,ge,"‡","\\ddagger"),ce(me,pe,ge,"≀","\\wr",!0),ce(me,pe,ge,"⨿","\\amalg"),ce(me,pe,ge,"&","\\And"),ce(me,pe,Se,"⟵","\\longleftarrow",!0),ce(me,pe,Se,"⇐","\\Leftarrow",!0),ce(me,pe,Se,"⟸","\\Longleftarrow",!0),ce(me,pe,Se,"⟶","\\longrightarrow",!0),ce(me,pe,Se,"⇒","\\Rightarrow",!0),ce(me,pe,Se,"⟹","\\Longrightarrow",!0),ce(me,pe,Se,"↔","\\leftrightarrow",!0),ce(me,pe,Se,"⟷","\\longleftrightarrow",!0),ce(me,pe,Se,"⇔","\\Leftrightarrow",!0),ce(me,pe,Se,"⟺","\\Longleftrightarrow",!0),ce(me,pe,Se,"↦","\\mapsto",!0),ce(me,pe,Se,"⟼","\\longmapsto",!0),ce(me,pe,Se,"↗","\\nearrow",!0),ce(me,pe,Se,"↩","\\hookleftarrow",!0),ce(me,pe,Se,"↪","\\hookrightarrow",!0),ce(me,pe,Se,"↘","\\searrow",!0),ce(me,pe,Se,"↼","\\leftharpoonup",!0),ce(me,pe,Se,"⇀","\\rightharpoonup",!0),ce(me,pe,Se,"↙","\\swarrow",!0),ce(me,pe,Se,"↽","\\leftharpoondown",!0),ce(me,pe,Se,"⇁","\\rightharpoondown",!0),ce(me,pe,Se,"↖","\\nwarrow",!0),ce(me,pe,Se,"⇌","\\rightleftharpoons",!0),ce(me,de,Se,"≮","\\nless",!0),ce(me,de,Se,"","\\@nleqslant"),ce(me,de,Se,"","\\@nleqq"),ce(me,de,Se,"⪇","\\lneq",!0),ce(me,de,Se,"≨","\\lneqq",!0),ce(me,de,Se,"","\\@lvertneqq"),ce(me,de,Se,"⋦","\\lnsim",!0),ce(me,de,Se,"⪉","\\lnapprox",!0),ce(me,de,Se,"⊀","\\nprec",!0),ce(me,de,Se,"⋠","\\npreceq",!0),ce(me,de,Se,"⋨","\\precnsim",!0),ce(me,de,Se,"⪹","\\precnapprox",!0),ce(me,de,Se,"≁","\\nsim",!0),ce(me,de,Se,"","\\@nshortmid"),ce(me,de,Se,"∤","\\nmid",!0),ce(me,de,Se,"⊬","\\nvdash",!0),ce(me,de,Se,"⊭","\\nvDash",!0),ce(me,de,Se,"⋪","\\ntriangleleft"),ce(me,de,Se,"⋬","\\ntrianglelefteq",!0),ce(me,de,Se,"⊊","\\subsetneq",!0),ce(me,de,Se,"","\\@varsubsetneq"),ce(me,de,Se,"⫋","\\subsetneqq",!0),ce(me,de,Se,"","\\@varsubsetneqq"),ce(me,de,Se,"≯","\\ngtr",!0),ce(me,de,Se,"","\\@ngeqslant"),ce(me,de,Se,"","\\@ngeqq"),ce(me,de,Se,"⪈","\\gneq",!0),ce(me,de,Se,"≩","\\gneqq",!0),ce(me,de,Se,"","\\@gvertneqq"),ce(me,de,Se,"⋧","\\gnsim",!0),ce(me,de,Se,"⪊","\\gnapprox",!0),ce(me,de,Se,"⊁","\\nsucc",!0),ce(me,de,Se,"⋡","\\nsucceq",!0),ce(me,de,Se,"⋩","\\succnsim",!0),ce(me,de,Se,"⪺","\\succnapprox",!0),ce(me,de,Se,"≆","\\ncong",!0),ce(me,de,Se,"","\\@nshortparallel"),ce(me,de,Se,"∦","\\nparallel",!0),ce(me,de,Se,"⊯","\\nVDash",!0),ce(me,de,Se,"⋫","\\ntriangleright"),ce(me,de,Se,"⋭","\\ntrianglerighteq",!0),ce(me,de,Se,"","\\@nsupseteqq"),ce(me,de,Se,"⊋","\\supsetneq",!0),ce(me,de,Se,"","\\@varsupsetneq"),ce(me,de,Se,"⫌","\\supsetneqq",!0),ce(me,de,Se,"","\\@varsupsetneqq"),ce(me,de,Se,"⊮","\\nVdash",!0),ce(me,de,Se,"⪵","\\precneqq",!0),ce(me,de,Se,"⪶","\\succneqq",!0),ce(me,de,Se,"","\\@nsubseteqq"),ce(me,de,ge,"⊴","\\unlhd"),ce(me,de,ge,"⊵","\\unrhd"),ce(me,de,Se,"↚","\\nleftarrow",!0),ce(me,de,Se,"↛","\\nrightarrow",!0),ce(me,de,Se,"⇍","\\nLeftarrow",!0),ce(me,de,Se,"⇏","\\nRightarrow",!0),ce(me,de,Se,"↮","\\nleftrightarrow",!0),ce(me,de,Se,"⇎","\\nLeftrightarrow",!0),ce(me,de,Se,"△","\\vartriangle"),ce(me,de,ze,"ℏ","\\hslash"),ce(me,de,ze,"▽","\\triangledown"),ce(me,de,ze,"◊","\\lozenge"),ce(me,de,ze,"Ⓢ","\\circledS"),ce(me,de,ze,"®","\\circledR"),ce(ue,de,ze,"®","\\circledR"),ce(me,de,ze,"∡","\\measuredangle",!0),ce(me,de,ze,"∄","\\nexists"),ce(me,de,ze,"℧","\\mho"),ce(me,de,ze,"Ⅎ","\\Finv",!0),ce(me,de,ze,"⅁","\\Game",!0),ce(me,de,ze,"‵","\\backprime"),ce(me,de,ze,"▲","\\blacktriangle"),ce(me,de,ze,"▼","\\blacktriangledown"),ce(me,de,ze,"■","\\blacksquare"),ce(me,de,ze,"⧫","\\blacklozenge"),ce(me,de,ze,"★","\\bigstar"),ce(me,de,ze,"∢","\\sphericalangle",!0),ce(me,de,ze,"∁","\\complement",!0),ce(me,de,ze,"ð","\\eth",!0),ce(ue,pe,ze,"ð","ð"),ce(me,de,ze,"╱","\\diagup"),ce(me,de,ze,"╲","\\diagdown"),ce(me,de,ze,"□","\\square"),ce(me,de,ze,"□","\\Box"),ce(me,de,ze,"◊","\\Diamond"),ce(me,de,ze,"¥","\\yen",!0),ce(ue,de,ze,"¥","\\yen",!0),ce(me,de,ze,"✓","\\checkmark",!0),ce(ue,de,ze,"✓","\\checkmark"),ce(me,de,ze,"ℶ","\\beth",!0),ce(me,de,ze,"ℸ","\\daleth",!0),ce(me,de,ze,"ℷ","\\gimel",!0),ce(me,de,ze,"ϝ","\\digamma",!0),ce(me,de,ze,"ϰ","\\varkappa"),ce(me,de,we,"┌","\\@ulcorner",!0),ce(me,de,ve,"┐","\\@urcorner",!0),ce(me,de,we,"└","\\@llcorner",!0),ce(me,de,ve,"┘","\\@lrcorner",!0),ce(me,de,Se,"≦","\\leqq",!0),ce(me,de,Se,"⩽","\\leqslant",!0),ce(me,de,Se,"⪕","\\eqslantless",!0),ce(me,de,Se,"≲","\\lesssim",!0),ce(me,de,Se,"⪅","\\lessapprox",!0),ce(me,de,Se,"≊","\\approxeq",!0),ce(me,de,ge,"⋖","\\lessdot"),ce(me,de,Se,"⋘","\\lll",!0),ce(me,de,Se,"≶","\\lessgtr",!0),ce(me,de,Se,"⋚","\\lesseqgtr",!0),ce(me,de,Se,"⪋","\\lesseqqgtr",!0),ce(me,de,Se,"≑","\\doteqdot"),ce(me,de,Se,"≓","\\risingdotseq",!0),ce(me,de,Se,"≒","\\fallingdotseq",!0),ce(me,de,Se,"∽","\\backsim",!0),ce(me,de,Se,"⋍","\\backsimeq",!0),ce(me,de,Se,"⫅","\\subseteqq",!0),ce(me,de,Se,"⋐","\\Subset",!0),ce(me,de,Se,"⊏","\\sqsubset",!0),ce(me,de,Se,"≼","\\preccurlyeq",!0),ce(me,de,Se,"⋞","\\curlyeqprec",!0),ce(me,de,Se,"≾","\\precsim",!0),ce(me,de,Se,"⪷","\\precapprox",!0),ce(me,de,Se,"⊲","\\vartriangleleft"),ce(me,de,Se,"⊴","\\trianglelefteq"),ce(me,de,Se,"⊨","\\vDash",!0),ce(me,de,Se,"⊪","\\Vvdash",!0),ce(me,de,Se,"⌣","\\smallsmile"),ce(me,de,Se,"⌢","\\smallfrown"),ce(me,de,Se,"≏","\\bumpeq",!0),ce(me,de,Se,"≎","\\Bumpeq",!0),ce(me,de,Se,"≧","\\geqq",!0),ce(me,de,Se,"⩾","\\geqslant",!0),ce(me,de,Se,"⪖","\\eqslantgtr",!0),ce(me,de,Se,"≳","\\gtrsim",!0),ce(me,de,Se,"⪆","\\gtrapprox",!0),ce(me,de,ge,"⋗","\\gtrdot"),ce(me,de,Se,"⋙","\\ggg",!0),ce(me,de,Se,"≷","\\gtrless",!0),ce(me,de,Se,"⋛","\\gtreqless",!0),ce(me,de,Se,"⪌","\\gtreqqless",!0),ce(me,de,Se,"≖","\\eqcirc",!0),ce(me,de,Se,"≗","\\circeq",!0),ce(me,de,Se,"≜","\\triangleq",!0),ce(me,de,Se,"∼","\\thicksim"),ce(me,de,Se,"≈","\\thickapprox"),ce(me,de,Se,"⫆","\\supseteqq",!0),ce(me,de,Se,"⋑","\\Supset",!0),ce(me,de,Se,"⊐","\\sqsupset",!0),ce(me,de,Se,"≽","\\succcurlyeq",!0),ce(me,de,Se,"⋟","\\curlyeqsucc",!0),ce(me,de,Se,"≿","\\succsim",!0),ce(me,de,Se,"⪸","\\succapprox",!0),ce(me,de,Se,"⊳","\\vartriangleright"),ce(me,de,Se,"⊵","\\trianglerighteq"),ce(me,de,Se,"⊩","\\Vdash",!0),ce(me,de,Se,"∣","\\shortmid"),ce(me,de,Se,"∥","\\shortparallel"),ce(me,de,Se,"≬","\\between",!0),ce(me,de,Se,"⋔","\\pitchfork",!0),ce(me,de,Se,"∝","\\varpropto"),ce(me,de,Se,"◀","\\blacktriangleleft"),ce(me,de,Se,"∴","\\therefore",!0),ce(me,de,Se,"∍","\\backepsilon"),ce(me,de,Se,"▶","\\blacktriangleright"),ce(me,de,Se,"∵","\\because",!0),ce(me,de,Se,"⋘","\\llless"),ce(me,de,Se,"⋙","\\gggtr"),ce(me,de,ge,"⊲","\\lhd"),ce(me,de,ge,"⊳","\\rhd"),ce(me,de,Se,"≂","\\eqsim",!0),ce(me,pe,Se,"⋈","\\Join"),ce(me,de,Se,"≑","\\Doteq",!0),ce(me,de,ge,"∔","\\dotplus",!0),ce(me,de,ge,"∖","\\smallsetminus"),ce(me,de,ge,"⋒","\\Cap",!0),ce(me,de,ge,"⋓","\\Cup",!0),ce(me,de,ge,"⩞","\\doublebarwedge",!0),ce(me,de,ge,"⊟","\\boxminus",!0),ce(me,de,ge,"⊞","\\boxplus",!0),ce(me,de,ge,"⋇","\\divideontimes",!0),ce(me,de,ge,"⋉","\\ltimes",!0),ce(me,de,ge,"⋊","\\rtimes",!0),ce(me,de,ge,"⋋","\\leftthreetimes",!0),ce(me,de,ge,"⋌","\\rightthreetimes",!0),ce(me,de,ge,"⋏","\\curlywedge",!0),ce(me,de,ge,"⋎","\\curlyvee",!0),ce(me,de,ge,"⊝","\\circleddash",!0),ce(me,de,ge,"⊛","\\circledast",!0),ce(me,de,ge,"⋅","\\centerdot"),ce(me,de,ge,"⊺","\\intercal",!0),ce(me,de,ge,"⋒","\\doublecap"),ce(me,de,ge,"⋓","\\doublecup"),ce(me,de,ge,"⊠","\\boxtimes",!0),ce(me,de,Se,"⇢","\\dashrightarrow",!0),ce(me,de,Se,"⇠","\\dashleftarrow",!0),ce(me,de,Se,"⇇","\\leftleftarrows",!0),ce(me,de,Se,"⇆","\\leftrightarrows",!0),ce(me,de,Se,"⇚","\\Lleftarrow",!0),ce(me,de,Se,"↞","\\twoheadleftarrow",!0),ce(me,de,Se,"↢","\\leftarrowtail",!0),ce(me,de,Se,"↫","\\looparrowleft",!0),ce(me,de,Se,"⇋","\\leftrightharpoons",!0),ce(me,de,Se,"↶","\\curvearrowleft",!0),ce(me,de,Se,"↺","\\circlearrowleft",!0),ce(me,de,Se,"↰","\\Lsh",!0),ce(me,de,Se,"⇈","\\upuparrows",!0),ce(me,de,Se,"↿","\\upharpoonleft",!0),ce(me,de,Se,"⇃","\\downharpoonleft",!0),ce(me,pe,Se,"⊶","\\origof",!0),ce(me,pe,Se,"⊷","\\imageof",!0),ce(me,de,Se,"⊸","\\multimap",!0),ce(me,de,Se,"↭","\\leftrightsquigarrow",!0),ce(me,de,Se,"⇉","\\rightrightarrows",!0),ce(me,de,Se,"⇄","\\rightleftarrows",!0),ce(me,de,Se,"↠","\\twoheadrightarrow",!0),ce(me,de,Se,"↣","\\rightarrowtail",!0),ce(me,de,Se,"↬","\\looparrowright",!0),ce(me,de,Se,"↷","\\curvearrowright",!0),ce(me,de,Se,"↻","\\circlearrowright",!0),ce(me,de,Se,"↱","\\Rsh",!0),ce(me,de,Se,"⇊","\\downdownarrows",!0),ce(me,de,Se,"↾","\\upharpoonright",!0),ce(me,de,Se,"⇂","\\downharpoonright",!0),ce(me,de,Se,"⇝","\\rightsquigarrow",!0),ce(me,de,Se,"⇝","\\leadsto"),ce(me,de,Se,"⇛","\\Rrightarrow",!0),ce(me,de,Se,"↾","\\restriction"),ce(me,pe,ze,"‘","`"),ce(me,pe,ze,"$","\\$"),ce(ue,pe,ze,"$","\\$"),ce(ue,pe,ze,"$","\\textdollar"),ce(me,pe,ze,"%","\\%"),ce(ue,pe,ze,"%","\\%"),ce(me,pe,ze,"_","\\_"),ce(ue,pe,ze,"_","\\_"),ce(ue,pe,ze,"_","\\textunderscore"),ce(me,pe,ze,"∠","\\angle",!0),ce(me,pe,ze,"∞","\\infty",!0),ce(me,pe,ze,"′","\\prime"),ce(me,pe,ze,"△","\\triangle"),ce(me,pe,ze,"Γ","\\Gamma",!0),ce(me,pe,ze,"Δ","\\Delta",!0),ce(me,pe,ze,"Θ","\\Theta",!0),ce(me,pe,ze,"Λ","\\Lambda",!0),ce(me,pe,ze,"Ξ","\\Xi",!0),ce(me,pe,ze,"Π","\\Pi",!0),ce(me,pe,ze,"Σ","\\Sigma",!0),ce(me,pe,ze,"Υ","\\Upsilon",!0),ce(me,pe,ze,"Φ","\\Phi",!0),ce(me,pe,ze,"Ψ","\\Psi",!0),ce(me,pe,ze,"Ω","\\Omega",!0),ce(me,pe,ze,"A","Α"),ce(me,pe,ze,"B","Β"),ce(me,pe,ze,"E","Ε"),ce(me,pe,ze,"Z","Ζ"),ce(me,pe,ze,"H","Η"),ce(me,pe,ze,"I","Ι"),ce(me,pe,ze,"K","Κ"),ce(me,pe,ze,"M","Μ"),ce(me,pe,ze,"N","Ν"),ce(me,pe,ze,"O","Ο"),ce(me,pe,ze,"P","Ρ"),ce(me,pe,ze,"T","Τ"),ce(me,pe,ze,"X","Χ"),ce(me,pe,ze,"¬","\\neg",!0),ce(me,pe,ze,"¬","\\lnot"),ce(me,pe,ze,"⊤","\\top"),ce(me,pe,ze,"⊥","\\bot"),ce(me,pe,ze,"∅","\\emptyset"),ce(me,de,ze,"∅","\\varnothing"),ce(me,pe,be,"α","\\alpha",!0),ce(me,pe,be,"β","\\beta",!0),ce(me,pe,be,"γ","\\gamma",!0),ce(me,pe,be,"δ","\\delta",!0),ce(me,pe,be,"ϵ","\\epsilon",!0),ce(me,pe,be,"ζ","\\zeta",!0),ce(me,pe,be,"η","\\eta",!0),ce(me,pe,be,"θ","\\theta",!0),ce(me,pe,be,"ι","\\iota",!0),ce(me,pe,be,"κ","\\kappa",!0),ce(me,pe,be,"λ","\\lambda",!0),ce(me,pe,be,"μ","\\mu",!0),ce(me,pe,be,"ν","\\nu",!0),ce(me,pe,be,"ξ","\\xi",!0),ce(me,pe,be,"ο","\\omicron",!0),ce(me,pe,be,"π","\\pi",!0),ce(me,pe,be,"ρ","\\rho",!0),ce(me,pe,be,"σ","\\sigma",!0),ce(me,pe,be,"τ","\\tau",!0),ce(me,pe,be,"υ","\\upsilon",!0),ce(me,pe,be,"ϕ","\\phi",!0),ce(me,pe,be,"χ","\\chi",!0),ce(me,pe,be,"ψ","\\psi",!0),ce(me,pe,be,"ω","\\omega",!0),ce(me,pe,be,"ε","\\varepsilon",!0),ce(me,pe,be,"ϑ","\\vartheta",!0),ce(me,pe,be,"ϖ","\\varpi",!0),ce(me,pe,be,"ϱ","\\varrho",!0),ce(me,pe,be,"ς","\\varsigma",!0),ce(me,pe,be,"φ","\\varphi",!0),ce(me,pe,ge,"∗","*",!0),ce(me,pe,ge,"+","+"),ce(me,pe,ge,"−","-",!0),ce(me,pe,ge,"⋅","\\cdot",!0),ce(me,pe,ge,"∘","\\circ",!0),ce(me,pe,ge,"÷","\\div",!0),ce(me,pe,ge,"±","\\pm",!0),ce(me,pe,ge,"×","\\times",!0),ce(me,pe,ge,"∩","\\cap",!0),ce(me,pe,ge,"∪","\\cup",!0),ce(me,pe,ge,"∖","\\setminus",!0),ce(me,pe,ge,"∧","\\land"),ce(me,pe,ge,"∨","\\lor"),ce(me,pe,ge,"∧","\\wedge",!0),ce(me,pe,ge,"∨","\\vee",!0),ce(me,pe,ze,"√","\\surd"),ce(me,pe,we,"⟨","\\langle",!0),ce(me,pe,we,"∣","\\lvert"),ce(me,pe,we,"∥","\\lVert"),ce(me,pe,ve,"?","?"),ce(me,pe,ve,"!","!"),ce(me,pe,ve,"⟩","\\rangle",!0),ce(me,pe,ve,"∣","\\rvert"),ce(me,pe,ve,"∥","\\rVert"),ce(me,pe,Se,"=","="),ce(me,pe,Se,":",":"),ce(me,pe,Se,"≈","\\approx",!0),ce(me,pe,Se,"≅","\\cong",!0),ce(me,pe,Se,"≥","\\ge"),ce(me,pe,Se,"≥","\\geq",!0),ce(me,pe,Se,"←","\\gets"),ce(me,pe,Se,">","\\gt",!0),ce(me,pe,Se,"∈","\\in",!0),ce(me,pe,Se,"","\\@not"),ce(me,pe,Se,"⊂","\\subset",!0),ce(me,pe,Se,"⊃","\\supset",!0),ce(me,pe,Se,"⊆","\\subseteq",!0),ce(me,pe,Se,"⊇","\\supseteq",!0),ce(me,de,Se,"⊈","\\nsubseteq",!0),ce(me,de,Se,"⊉","\\nsupseteq",!0),ce(me,pe,Se,"⊨","\\models"),ce(me,pe,Se,"←","\\leftarrow",!0),ce(me,pe,Se,"≤","\\le"),ce(me,pe,Se,"≤","\\leq",!0),ce(me,pe,Se,"<","\\lt",!0),ce(me,pe,Se,"→","\\rightarrow",!0),ce(me,pe,Se,"→","\\to"),ce(me,de,Se,"≱","\\ngeq",!0),ce(me,de,Se,"≰","\\nleq",!0),ce(me,pe,Me," ","\\ "),ce(me,pe,Me," ","\\space"),ce(me,pe,Me," ","\\nobreakspace"),ce(ue,pe,Me," ","\\ "),ce(ue,pe,Me," "," "),ce(ue,pe,Me," ","\\space"),ce(ue,pe,Me," ","\\nobreakspace"),ce(me,pe,Me,null,"\\nobreak"),ce(me,pe,Me,null,"\\allowbreak"),ce(me,pe,ke,",",","),ce(me,pe,ke,";",";"),ce(me,de,ge,"⊼","\\barwedge",!0),ce(me,de,ge,"⊻","\\veebar",!0),ce(me,pe,ge,"⊙","\\odot",!0),ce(me,pe,ge,"⊕","\\oplus",!0),ce(me,pe,ge,"⊗","\\otimes",!0),ce(me,pe,ze,"∂","\\partial",!0),ce(me,pe,ge,"⊘","\\oslash",!0),ce(me,de,ge,"⊚","\\circledcirc",!0),ce(me,de,ge,"⊡","\\boxdot",!0),ce(me,pe,ge,"△","\\bigtriangleup"),ce(me,pe,ge,"▽","\\bigtriangledown"),ce(me,pe,ge,"†","\\dagger"),ce(me,pe,ge,"⋄","\\diamond"),ce(me,pe,ge,"⋆","\\star"),ce(me,pe,ge,"◃","\\triangleleft"),ce(me,pe,ge,"▹","\\triangleright"),ce(me,pe,we,"{","\\{"),ce(ue,pe,ze,"{","\\{"),ce(ue,pe,ze,"{","\\textbraceleft"),ce(me,pe,ve,"}","\\}"),ce(ue,pe,ze,"}","\\}"),ce(ue,pe,ze,"}","\\textbraceright"),ce(me,pe,we,"{","\\lbrace"),ce(me,pe,ve,"}","\\rbrace"),ce(me,pe,we,"[","\\lbrack",!0),ce(ue,pe,ze,"[","\\lbrack",!0),ce(me,pe,ve,"]","\\rbrack",!0),ce(ue,pe,ze,"]","\\rbrack",!0),ce(me,pe,we,"(","\\lparen",!0),ce(me,pe,ve,")","\\rparen",!0),ce(ue,pe,ze,"<","\\textless",!0),ce(ue,pe,ze,">","\\textgreater",!0),ce(me,pe,we,"⌊","\\lfloor",!0),ce(me,pe,ve,"⌋","\\rfloor",!0),ce(me,pe,we,"⌈","\\lceil",!0),ce(me,pe,ve,"⌉","\\rceil",!0),ce(me,pe,ze,"\\","\\backslash"),ce(me,pe,ze,"∣","|"),ce(me,pe,ze,"∣","\\vert"),ce(ue,pe,ze,"|","\\textbar",!0),ce(me,pe,ze,"∥","\\|"),ce(me,pe,ze,"∥","\\Vert"),ce(ue,pe,ze,"∥","\\textbardbl"),ce(ue,pe,ze,"~","\\textasciitilde"),ce(ue,pe,ze,"\\","\\textbackslash"),ce(ue,pe,ze,"^","\\textasciicircum"),ce(me,pe,Se,"↑","\\uparrow",!0),ce(me,pe,Se,"⇑","\\Uparrow",!0),ce(me,pe,Se,"↓","\\downarrow",!0),ce(me,pe,Se,"⇓","\\Downarrow",!0),ce(me,pe,Se,"↕","\\updownarrow",!0),ce(me,pe,Se,"⇕","\\Updownarrow",!0),ce(me,pe,xe,"∐","\\coprod"),ce(me,pe,xe,"⋁","\\bigvee"),ce(me,pe,xe,"⋀","\\bigwedge"),ce(me,pe,xe,"⨄","\\biguplus"),ce(me,pe,xe,"⋂","\\bigcap"),ce(me,pe,xe,"⋃","\\bigcup"),ce(me,pe,xe,"∫","\\int"),ce(me,pe,xe,"∫","\\intop"),ce(me,pe,xe,"∬","\\iint"),ce(me,pe,xe,"∭","\\iiint"),ce(me,pe,xe,"∏","\\prod"),ce(me,pe,xe,"∑","\\sum"),ce(me,pe,xe,"⨂","\\bigotimes"),ce(me,pe,xe,"⨁","\\bigoplus"),ce(me,pe,xe,"⨀","\\bigodot"),ce(me,pe,xe,"∮","\\oint"),ce(me,pe,xe,"∯","\\oiint"),ce(me,pe,xe,"∰","\\oiiint"),ce(me,pe,xe,"⨆","\\bigsqcup"),ce(me,pe,xe,"∫","\\smallint"),ce(ue,pe,ye,"…","\\textellipsis"),ce(me,pe,ye,"…","\\mathellipsis"),ce(ue,pe,ye,"…","\\ldots",!0),ce(me,pe,ye,"…","\\ldots",!0),ce(me,pe,ye,"⋯","\\@cdots",!0),ce(me,pe,ye,"⋱","\\ddots",!0),ce(me,pe,ze,"⋮","\\varvdots"),ce(me,pe,fe,"ˊ","\\acute"),ce(me,pe,fe,"ˋ","\\grave"),ce(me,pe,fe,"¨","\\ddot"),ce(me,pe,fe,"~","\\tilde"),ce(me,pe,fe,"ˉ","\\bar"),ce(me,pe,fe,"˘","\\breve"),ce(me,pe,fe,"ˇ","\\check"),ce(me,pe,fe,"^","\\hat"),ce(me,pe,fe,"⃗","\\vec"),ce(me,pe,fe,"˙","\\dot"),ce(me,pe,fe,"˚","\\mathring"),ce(me,pe,be,"","\\@imath"),ce(me,pe,be,"","\\@jmath"),ce(me,pe,ze,"ı","ı"),ce(me,pe,ze,"ȷ","ȷ"),ce(ue,pe,ze,"ı","\\i",!0),ce(ue,pe,ze,"ȷ","\\j",!0),ce(ue,pe,ze,"ß","\\ss",!0),ce(ue,pe,ze,"æ","\\ae",!0),ce(ue,pe,ze,"œ","\\oe",!0),ce(ue,pe,ze,"ø","\\o",!0),ce(ue,pe,ze,"Æ","\\AE",!0),ce(ue,pe,ze,"Œ","\\OE",!0),ce(ue,pe,ze,"Ø","\\O",!0),ce(ue,pe,fe,"ˊ","\\'"),ce(ue,pe,fe,"ˋ","\\`"),ce(ue,pe,fe,"ˆ","\\^"),ce(ue,pe,fe,"˜","\\~"),ce(ue,pe,fe,"ˉ","\\="),ce(ue,pe,fe,"˘","\\u"),ce(ue,pe,fe,"˙","\\."),ce(ue,pe,fe,"¸","\\c"),ce(ue,pe,fe,"˚","\\r"),ce(ue,pe,fe,"ˇ","\\v"),ce(ue,pe,fe,"¨",'\\"'),ce(ue,pe,fe,"˝","\\H"),ce(ue,pe,fe,"◯","\\textcircled");var Ae={"--":!0,"---":!0,"``":!0,"''":!0};ce(ue,pe,ze,"–","--",!0),ce(ue,pe,ze,"–","\\textendash"),ce(ue,pe,ze,"—","---",!0),ce(ue,pe,ze,"—","\\textemdash"),ce(ue,pe,ze,"‘","`",!0),ce(ue,pe,ze,"‘","\\textquoteleft"),ce(ue,pe,ze,"’","'",!0),ce(ue,pe,ze,"’","\\textquoteright"),ce(ue,pe,ze,"“","``",!0),ce(ue,pe,ze,"“","\\textquotedblleft"),ce(ue,pe,ze,"”","''",!0),ce(ue,pe,ze,"”","\\textquotedblright"),ce(me,pe,ze,"°","\\degree",!0),ce(ue,pe,ze,"°","\\degree"),ce(ue,pe,ze,"°","\\textdegree",!0),ce(me,pe,ze,"£","\\pounds"),ce(me,pe,ze,"£","\\mathsterling",!0),ce(ue,pe,ze,"£","\\pounds"),ce(ue,pe,ze,"£","\\textsterling",!0),ce(me,de,ze,"✠","\\maltese"),ce(ue,de,ze,"✠","\\maltese");for(var Te=0;Te<14;Te++){var Be='0123456789/@."'.charAt(Te);ce(me,pe,ze,Be,Be)}for(var Ne=0;Ne<25;Ne++){var Ce='0123456789!@*()-=+";:?/.,'.charAt(Ne);ce(ue,pe,ze,Ce,Ce)}for(var qe="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ie=0;Ie<52;Ie++){var Re=qe.charAt(Ie);ce(me,pe,be,Re,Re),ce(ue,pe,ze,Re,Re)}ce(me,de,ze,"C","ℂ"),ce(ue,de,ze,"C","ℂ"),ce(me,de,ze,"H","ℍ"),ce(ue,de,ze,"H","ℍ"),ce(me,de,ze,"N","ℕ"),ce(ue,de,ze,"N","ℕ"),ce(me,de,ze,"P","ℙ"),ce(ue,de,ze,"P","ℙ"),ce(me,de,ze,"Q","ℚ"),ce(ue,de,ze,"Q","ℚ"),ce(me,de,ze,"R","ℝ"),ce(ue,de,ze,"R","ℝ"),ce(me,de,ze,"Z","ℤ"),ce(ue,de,ze,"Z","ℤ"),ce(me,pe,be,"h","ℎ"),ce(ue,pe,be,"h","ℎ");for(var He="",Oe=0;Oe<52;Oe++){var Ee=qe.charAt(Oe);ce(me,pe,be,Ee,He=String.fromCharCode(55349,56320+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56372+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56424+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56580+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56736+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56788+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56840+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56944+Oe)),ce(ue,pe,ze,Ee,He),Oe<26&&(ce(me,pe,be,Ee,He=String.fromCharCode(55349,56632+Oe)),ce(ue,pe,ze,Ee,He),ce(me,pe,be,Ee,He=String.fromCharCode(55349,56476+Oe)),ce(ue,pe,ze,Ee,He))}ce(me,pe,be,"k",He=String.fromCharCode(55349,56668)),ce(ue,pe,ze,"k",He);for(var Le=0;Le<10;Le++){var De=Le.toString();ce(me,pe,be,De,He=String.fromCharCode(55349,57294+Le)),ce(ue,pe,ze,De,He),ce(me,pe,be,De,He=String.fromCharCode(55349,57314+Le)),ce(ue,pe,ze,De,He),ce(me,pe,be,De,He=String.fromCharCode(55349,57324+Le)),ce(ue,pe,ze,De,He),ce(me,pe,be,De,He=String.fromCharCode(55349,57334+Le)),ce(ue,pe,ze,De,He)}for(var Pe=0;Pe<3;Pe++){var Ve="ÐÞþ".charAt(Pe);ce(me,pe,be,Ve,Ve),ce(ue,pe,ze,Ve,Ve)}var Fe=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["","",""],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Ge=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Ue=function(e,t,r){return he[r][e]&&he[r][e].replace&&(e=he[r][e].replace),{value:e,metrics:O(e,t,r)}},Ye=function(e,t,r,n,a){var i,o=Ue(e,t,r),s=o.metrics;if(e=o.value,s){var l=s.italic;("text"===r||n&&"mathit"===n.font)&&(l=0),i=new te(e,s.height,s.depth,l,s.skew,s.width,a)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),i=new te(e,0,0,0,0,0,a);if(n){i.maxFontSize=n.sizeMultiplier,n.style.isTight()&&i.classes.push("mtight");var h=n.getColor();h&&(i.style.color=h)}return i},Xe=function(e,t){if(_(e.classes)!==_(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){var r=e.classes[0];if("mbin"===r||"mord"===r)return!1}for(var n in e.style)if(e.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;for(var a in t.style)if(t.style.hasOwnProperty(a)&&e.style[a]!==t.style[a])return!1;return!0},We=function(e){for(var t=0,r=0,n=0,a=0;at&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},_e=function(e,t,r,n){var a=new K(e,t,r,n);return We(a),a},je=function(e,t,r,n){return new K(e,t,r,n)},$e=function(e){var t=new q(e);return We(t),t},Ze=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},Ke={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Je={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Qe={fontMap:Ke,makeSymbol:Ye,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Ue(e,"Main-Bold",t).metrics?Ye(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===he[t][e].font?Ye(e,"Main-Regular",t,r,n):Ye(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:_e,makeSvgSpan:je,makeLineSpan:function(e,t,r){var n=_e([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=W(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new J(e,t,r,n);return We(a),a},makeFragment:$e,wrapFragment:function(e,t){return e instanceof q?_e([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(Mt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(Mt(s,t)),r?((i=Mt(vt(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var c=ut(["katex-html"],o);if(c.setAttribute("aria-hidden","true"),i){var m=i.children[0];m.style.height=W(c.height+c.depth),c.depth&&(m.style.verticalAlign=W(-c.depth))}return c}function At(e){return new q(e)}var Tt=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=_(this.classes));for(var r=0;r0&&(e+=' class ="'+c(_(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),Bt=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return c(this.toText())},t.toText=function(){return this.text},e}(),Nt={MathNode:Tt,TextNode:Bt,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?" ":e>=.1666&&e<=.1667?" ":e>=.2222&&e<=.2223?" ":e>=.2777&&e<=.2778?"  ":e>=-.05556&&e<=-.05555?" ⁣":e>=-.1667&&e<=-.1666?" ⁣":e>=-.2223&&e<=-.2222?" ⁣":e>=-.2778&&e<=-.2777?" ⁣":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",W(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:At},Ct=function(e,t,r){return!he[t][e]||!he[t][e].replace||55349===e.charCodeAt(0)||Ae.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=he[t][e].replace),new Nt.TextNode(e)},qt=function(e){return 1===e.length?e[0]:new Nt.MathNode("mrow",e)},It=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l(["\\imath","\\jmath"],a)?null:(he[n][a]&&he[n][a].replace&&(a=he[n][a].replace),O(a,Qe.fontMap[r].fontName,n)?Qe.fontMap[r].variant:null)},Rt=function(e,t,r){if(1===e.length){var n=Ot(e[0],t);return r&&n instanceof Tt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"̸"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},Ht=function(e,t,r){return qt(Rt(e,t,r))},Ot=function(e,t){if(!e)return new Nt.MathNode("mrow");if(st[e.type])return st[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function Et(e,t,r,n,a){var i,o=Rt(e,r);i=1===o.length&&o[0]instanceof Tt&&l(["mrow","mtable"],o[0].type)?o[0]:new Nt.MathNode("mrow",o);var s=new Nt.MathNode("annotation",[new Nt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new Nt.MathNode("semantics",[i,s]),c=new Nt.MathNode("math",[h]);return c.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&c.setAttribute("display","block"),Qe.makeSpan([a?"katex":"katex-mathml"],[c])}var Lt=function(e){return new F({style:e.displayMode?A.DISPLAY:A.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Dt=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Qe.makeSpan(r,[e])}return e},Pt={widehat:"^",widecheck:"ˇ",widetilde:"~",utilde:"~",overleftarrow:"←",underleftarrow:"←",xleftarrow:"←",overrightarrow:"→",underrightarrow:"→",xrightarrow:"→",underbrace:"⏟",overbrace:"⏞",overgroup:"⏠",undergroup:"⏡",overleftrightarrow:"↔",underleftrightarrow:"↔",xleftrightarrow:"↔",Overrightarrow:"⇒",xRightarrow:"⇒",overleftharpoon:"↼",xleftharpoonup:"↼",overrightharpoon:"⇀",xrightharpoonup:"⇀",xLeftarrow:"⇐",xLeftrightarrow:"⇔",xhookleftarrow:"↩",xhookrightarrow:"↪",xmapsto:"↦",xrightharpoondown:"⇁",xleftharpoondown:"↽",xrightleftharpoons:"⇌",xleftrightharpoons:"⇋",xtwoheadleftarrow:"↞",xtwoheadrightarrow:"↠",xlongequal:"=",xtofrom:"⇄",xrightleftarrows:"⇄",xrightequilibrium:"⇌",xleftequilibrium:"⇋","\\cdrightarrow":"→","\\cdleftarrow":"←","\\cdlongequal":"="},Vt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ft=function(e){var t=new Nt.MathNode("mo",[new Nt.TextNode(Pt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Gt=function(e,t){var r=function(){var r=4e5,n=e.label.slice(1);if(l(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var c=new ne(i),m=new re([c],{width:"100%",height:W(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:Qe.makeSvgSpan([],[m],t),minWidth:0,height:o}}var u,p,d,f=[],g=Vt[n],v=g[0],y=g[1],b=g[2],x=b/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=W(a)),n};function Ut(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Yt(e){var t=Xt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Xt(e){return e&&("atom"===e.type||se.hasOwnProperty(e.type))?e:null}var Wt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Ut(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof K)return e;throw new Error("Expected span but got "+String(e)+".")}(St(e,t)),e.base=n):r=(n=Ut(e,"accent")).base;var i=St(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&p(r)){var s=u(r);o=ie(St(s,t.havingCrampedStyle())).skew}var l,h="\\c"===n.label,c=h?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)l=Gt(n,t),l=Qe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+W(2*o)+")",marginLeft:W(2*o)}:void 0}]},t);else{var m,d;"\\vec"===n.label?(m=Qe.staticSvg("vec",t),d=Qe.svgData.vec[1]):((m=ie(m=Qe.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,d=m.width,h&&(c+=m.depth)),l=Qe.makeSpan(["accent-body"],[m]);var f="\\textcircled"===n.label;f&&(l.classes.push("accent-full"),c=i.height);var g=o;f||(g-=d/2),l.style.left=W(g),"\\textcircled"===n.label&&(l.style.top=".2em"),l=Qe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:l}]},t)}var v=Qe.makeSpan(["mord","accent"],[l],t);return a?(a.children[0]=v,a.height=Math.max(v.height,a.height),a.classes[0]="mord",a):v},_t=function(e,t){var r=e.isStretchy?Ft(e.label):new Nt.MathNode("mo",[Ct(e.label,e.mode)]),n=new Nt.MathNode("mover",[Ot(e.base,t),r]);return n.setAttribute("accent","true"),n},jt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));lt({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=ct(t[0]),n=!jt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),lt({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),lt({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=St(e.base,t),n=Gt(e,t),a="\\utilde"===e.label?.12:0,i=Qe.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return Qe.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Ft(e.label),n=new Nt.MathNode("munder",[Ot(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var $t=function(e){var t=new Nt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};lt({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=Qe.wrapFragment(St(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=Qe.wrapFragment(St(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Gt(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,c=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(c-=i.depth),r){var m=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Qe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:c},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:m}]},t)}else s=Qe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:c},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Qe.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Ft(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=$t(Ot(e.body,t));if(e.below){var i=$t(Ot(e.below,t));r=new Nt.MathNode("munderover",[n,i,a])}else r=new Nt.MathNode("mover",[n,a])}else if(e.below){var o=$t(Ot(e.below,t));r=new Nt.MathNode("munder",[n,o])}else r=$t(),r=new Nt.MathNode("mover",[n,r]);return r}});var Zt=Qe.makeSpan;function Kt(e,t){var r=vt(e.body,t,!0);return Zt([e.mclass],r,t)}function Jt(e,t){var r,n=Rt(e.body,t);return"minner"===e.mclass?r=new Nt.MathNode("mpadded",n):"mord"===e.mclass?e.isCharacterBox?(r=n[0]).type="mi":r=new Nt.MathNode("mi",n):(e.isCharacterBox?(r=n[0]).type="mo":r=new Nt.MathNode("mo",n),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}lt({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+n.slice(5),body:mt(a),isCharacterBox:p(a)}},htmlBuilder:Kt,mathmlBuilder:Jt});var Qt=function(e){var t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};lt({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler:function(e,t){return{type:"mclass",mode:e.parser.mode,mclass:Qt(t[0]),body:mt(t[1]),isCharacterBox:p(t[1])}}}),lt({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler:function(e,t){var r,n=e.parser,a=e.funcName,i=t[1],o=t[0];r="\\stackrel"!==a?Qt(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==a,body:mt(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===a?null:o,sub:"\\underset"===a?o:null};return{type:"mclass",mode:n.mode,mclass:r,body:[l],isCharacterBox:p(l)}},htmlBuilder:Kt,mathmlBuilder:Jt}),lt({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"pmb",mode:e.parser.mode,mclass:Qt(t[0]),body:mt(t[0])}},htmlBuilder:function(e,t){var r=vt(e.body,t,!0),n=Qe.makeSpan([e.mclass],r,t);return n.style.textShadow="0.02em 0.01em 0.04px",n},mathmlBuilder:function(e,t){var r=Rt(e.body,t),n=new Nt.MathNode("mstyle",r);return n.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),n}});var er={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},tr=function(e){return"textord"===e.type&&"@"===e.text};function rr(e,t,r){var n=er[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}lt({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=Qe.wrapFragment(St(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=W(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mrow",[Ot(e.label,t)]);return(r=new Nt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Nt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),lt({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=Qe.wrapFragment(St(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new Nt.MathNode("mrow",[Ot(e.fragment,t)])}}),lt({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Ut(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var nr=function(e,t){var r=vt(e.body,t.withColor(e.color),!1);return Qe.makeFragment(r)},ar=function(e,t){var r=Rt(e.body,t.withColor(e.color)),n=new Nt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};lt({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Ut(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:mt(a)}},htmlBuilder:nr,mathmlBuilder:ar}),lt({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Ut(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:nr,mathmlBuilder:ar}),lt({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a="["===n.gullet.future().text?n.parseSizeGroup(!0):null,i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Ut(a,"size").value}},htmlBuilder:function(e,t){var r=Qe.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=W(X(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",W(X(e.size,t)))),r}});var ir={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},or=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},sr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};lt({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(ir[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=ir[a.text]),Ut(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),lt({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===ir[r]),{type:"internal",mode:t.mode}}}),lt({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=or(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return sr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),lt({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=or(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return sr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var lr=function(e,t,r){var n=O(he.math[e]&&he.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},hr=function(e,t,r,n){var a=r.havingBaseStyle(t),i=Qe.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},cr=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=W(a),e.height-=a,e.depth+=a},mr=function(e,t,r,n,a,i){var o=function(e,t,r,n){return Qe.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=hr(Qe.makeSpan(["delimsizing","size"+t],[o],n),A.TEXT,n,i);return r&&cr(s,n,A.TEXT),s},ur=function(e,t,r){return{type:"elem",elem:Qe.makeSpan(["delimsizinginner","Size1-Regular"===t?"delim-size1":"delim-size4"],[Qe.makeSpan([],[Qe.makeSymbol(e,t,r)])])}},pr=function(e,t,r){var n=I["Size4-Regular"][e.charCodeAt(0)]?I["Size4-Regular"][e.charCodeAt(0)][4]:I["Size1-Regular"][e.charCodeAt(0)][4],a=new ne("inner",function(e,t){switch(e){case"⎜":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"∣":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"∥":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"⎟":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"⎢":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"⎥":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"⎪":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"⏐":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"‖":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new re([a],{width:W(n),height:W(t),style:"width:"+W(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Qe.makeSvgSpan([],[i],r);return o.height=t,o.style.height=W(t),o.style.width=W(n),{type:"elem",elem:o}},dr={type:"kern",size:-.008},fr=["|","\\lvert","\\rvert","\\vert"],gr=["\\|","\\lVert","\\rVert","\\Vert"],vr=function(e,t,r,n,a,i){var o,s,h,c,m="",u=0;o=h=c=e,s=null;var p="Size1-Regular";"\\uparrow"===e?h=c="⏐":"\\Uparrow"===e?h=c="‖":"\\downarrow"===e?o=h="⏐":"\\Downarrow"===e?o=h="‖":"\\updownarrow"===e?(o="\\uparrow",h="⏐",c="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="‖",c="\\Downarrow"):l(fr,e)?(h="∣",m="vert",u=333):l(gr,e)?(h="∥",m="doublevert",u=556):"["===e||"\\lbrack"===e?(o="⎡",h="⎢",c="⎣",p="Size4-Regular",m="lbrack",u=667):"]"===e||"\\rbrack"===e?(o="⎤",h="⎥",c="⎦",p="Size4-Regular",m="rbrack",u=667):"\\lfloor"===e||"⌊"===e?(h=o="⎢",c="⎣",p="Size4-Regular",m="lfloor",u=667):"\\lceil"===e||"⌈"===e?(o="⎡",h=c="⎢",p="Size4-Regular",m="lceil",u=667):"\\rfloor"===e||"⌋"===e?(h=o="⎥",c="⎦",p="Size4-Regular",m="rfloor",u=667):"\\rceil"===e||"⌉"===e?(o="⎤",h=c="⎥",p="Size4-Regular",m="rceil",u=667):"("===e||"\\lparen"===e?(o="⎛",h="⎜",c="⎝",p="Size4-Regular",m="lparen",u=875):")"===e||"\\rparen"===e?(o="⎞",h="⎟",c="⎠",p="Size4-Regular",m="rparen",u=875):"\\{"===e||"\\lbrace"===e?(o="⎧",s="⎨",c="⎩",h="⎪",p="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="⎫",s="⎬",c="⎭",h="⎪",p="Size4-Regular"):"\\lgroup"===e||"⟮"===e?(o="⎧",c="⎩",h="⎪",p="Size4-Regular"):"\\rgroup"===e||"⟯"===e?(o="⎫",c="⎭",h="⎪",p="Size4-Regular"):"\\lmoustache"===e||"⎰"===e?(o="⎧",c="⎭",h="⎪",p="Size4-Regular"):"\\rmoustache"!==e&&"⎱"!==e||(o="⎫",c="⎩",h="⎪",p="Size4-Regular");var d=lr(o,p,a),f=d.height+d.depth,g=lr(h,p,a),v=g.height+g.depth,y=lr(c,p,a),b=y.height+y.depth,x=0,w=1;if(null!==s){var k=lr(s,p,a);x=k.height+k.depth,w=2}var S=f+b+x,M=S+Math.max(0,Math.ceil((t-S)/(w*v)))*w*v,z=n.fontMetrics().axisHeight;r&&(z*=n.sizeMultiplier);var T=M/2-z,B=[];if(m.length>0){var N=M-f-b,C=Math.round(1e3*M),q=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(m,Math.round(1e3*N)),I=new ne(m,q),R=(u/1e3).toFixed(3)+"em",H=(C/1e3).toFixed(3)+"em",O=new re([I],{width:R,height:H,viewBox:"0 0 "+u+" "+C}),E=Qe.makeSvgSpan([],[O],n);E.height=C/1e3,E.style.width=R,E.style.height=H,B.push({type:"elem",elem:E})}else{if(B.push(ur(c,p,a)),B.push(dr),null===s){var L=M-f-b+.016;B.push(pr(h,L,n))}else{var D=(M-f-b-x)/2+.016;B.push(pr(h,D,n)),B.push(dr),B.push(ur(s,p,a)),B.push(dr),B.push(pr(h,D,n))}B.push(dr),B.push(ur(o,p,a))}var P=n.havingBaseStyle(A.TEXT),V=Qe.makeVList({positionType:"bottom",positionData:T,children:B},P);return hr(Qe.makeSpan(["delimsizing","mult"],[V],P),A.TEXT,n,i)},yr=.08,br=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+80)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" 80h400000v"+(40+e)+"h-400000z"}(t);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+80)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" 80h400000v"+(40+e)+"h-400000z"}(t);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+80)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" 80h400000v"+(40+e)+"h-400000z"}(t);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+80)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" 80\nh400000v"+(40+e)+"h-400000z"}(t);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+80)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" 80h400000v"+(40+e)+"H1017.7z"}(t);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+80)+"H400000"+(40+e)+"\nH742v"+(r-54-80-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 80H400000v"+(40+e)+"H742z"}(t,0,r)}return n}(e,n,r),o=new ne(e,i),s=new re([o],{width:"400em",height:W(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Qe.makeSvgSpan(["hide-tail"],[s],a)},xr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","\\surd"],wr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱"],kr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],Sr=[0,1.2,1.8,2.4,3],Mr=[{type:"small",style:A.SCRIPTSCRIPT},{type:"small",style:A.SCRIPT},{type:"small",style:A.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],zr=[{type:"small",style:A.SCRIPTSCRIPT},{type:"small",style:A.SCRIPT},{type:"small",style:A.TEXT},{type:"stack"}],Ar=[{type:"small",style:A.SCRIPTSCRIPT},{type:"small",style:A.SCRIPT},{type:"small",style:A.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Tr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Br=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},Nr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"⟨"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),o=l(kr,e)?Mr:l(xr,e)?Ar:zr;var s=Br(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=Qe.makeSymbol(e,"Main-Regular",a,n),s=hr(o,t,n,i);return r&&cr(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?mr(e,s.size,r,n,a,i):vr(e,t,r,n,a,i)},Cr={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=Br("\\surd",e*a.sizeMultiplier,Ar,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,c=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=br("sqrtMain",l=(1+s+yr)/o,c=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(c=1080*Sr[i.size],h=(Sr[i.size]+s)/o,l=(Sr[i.size]+s+yr)/o,(r=br("sqrtSize"+i.size,l,c,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+yr,h=e+s,c=Math.floor(1e3*e+s)+80,(r=br("sqrtTall",l,c,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=W(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"⟨"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"⟩"!==e||(e="\\rangle"),l(xr,e)||l(kr,e))return mr(e,t,!1,r,a,i);if(l(wr,e))return vr(e,Sr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:Sr,customSizedDelim:Nr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Nr(e,h,!0,n,a,i)}},qr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Ir=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","⌊","⌋","\\lceil","\\rceil","⌈","⌉","<",">","\\langle","⟨","\\rangle","⟩","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","⟮","⟯","\\lmoustache","\\rmoustache","⎰","⎱","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Rr(e,t){var r=Xt(e);if(r&&l(Ir,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Hr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}lt({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Rr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:qr[e.funcName].size,mclass:qr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?Qe.makeSpan([e.mclass]):Cr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(Ct(e.delim,e.mode));var r=new Nt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=W(Cr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),lt({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Rr(t[0],e).text,color:r}}}),lt({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Rr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Ut(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){Hr(e);for(var r,n,a=vt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Ot(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};lt({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:Or,mathmlBuilder:Er}),lt({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=Ut(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Or,mathmlBuilder:Er}),lt({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),lt({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:Or,mathmlBuilder:Er}),lt({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Lr={};function Dr(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!m)&&g.pop(),y.length0&&(b+=.25),c.push({pos:b,isDashed:e[t]})}for(x(o[0]),r=0;r0&&(S<(B+=y)&&(S=B),B=0),e.addJot&&(S+=f),M.height=k,M.depth=S,b+=k,M.pos=b,b+=S+B,l[r]=M,x(o[r+1])}var N,C,q=b/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],H=[];if(e.tags&&e.tags.some((function(e){return e})))for(r=0;r=s)){var Y=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(Y=h(P.pregap,p))&&((N=Qe.makeSpan(["arraycolsep"],[])).style.width=W(Y),R.push(N));var _=[];for(r=0;r0){for(var K=Qe.makeLineSpan("hline",t,m),J=Qe.makeLineSpan("hdashline",t,m),Q=[{type:"elem",elem:l,shift:0}];c.length>0;){var ee=c.pop(),te=ee.pos-q;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}l=Qe.makeVList({positionType:"individualShift",children:Q},t)}if(0===H.length)return Qe.makeSpan(["mord"],[l],t);var re=Qe.makeVList({positionType:"individualShift",children:H},t);return re=Qe.makeSpan(["tag"],[re],t),Qe.makeFragment([l,re])},$r={c:"center ",l:"left ",r:"right "},Zr=function(e,t){for(var r=[],n=new Nt.MathNode("mtd",[],["mtr-glue"]),a=new Nt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(m+="top ",g=1),"separator"===p[p.length-1].type&&(m+="bottom ",v-=1);for(var y=g;y0?"left ":"",m+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Wr(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Xr(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var c="",m=0;m0&&u&&(f=1),a[p]={type:"align",align:d,pregap:f,postgap:0}}return s.colSeparationType=u?"align":"alignat",s};Dr({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Wr(e.parser,a,_r(e.envName))},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Wr(e.parser,a,_r(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Wr(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Wr(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Wr(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},_r(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:Kr,htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l(["gather","gather*"],e.envName)&&Yr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Xr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Wr(e.parser,t,"display")},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:Kr,htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Yr(e);var t={autoTag:Xr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Wr(e.parser,t,"display")},htmlBuilder:jr,mathmlBuilder:Zr}),Dr({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Yr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[m]);for(var d=0;d<2;d++){for(var f=!0,g=m+1;g=A.SCRIPT.id?r.text():A.DISPLAY:"text"===e&&r.size===A.DISPLAY.size?r=A.TEXT:"script"===e?r=A.SCRIPT:"scriptscript"===e&&(r=A.SCRIPTSCRIPT),r},nn=function(e,t){var r,n=rn(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=St(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*m:7*m,d=t.fontMetrics().denom1):(c>0?(u=t.fontMetrics().num2,p=m):(u=t.fontMetrics().num3,p=3*m),d=t.fontMetrics().denom2),h){var x=t.fontMetrics().axisHeight;u-o.depth-(x+.5*c)0&&(t="."===(t=e)?null:t),t};lt({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=ct(t[0]),s="atom"===o.type&&"open"===o.family?sn(o.text):null,l=ct(t[1]),h="atom"===l.type&&"close"===l.family?sn(l.text):null,c=Ut(t[2],"size"),m=null;r=!!c.isBlank||(m=c.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Ut(p.body[0],"textord");u=on[Number(d.text)]}}else p=Ut(p,"textord"),u=on[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:m,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:nn,mathmlBuilder:an}),lt({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Ut(t[0],"size").value,token:n}}}),lt({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Ut(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:nn,mathmlBuilder:an});var ln=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?St(e.sup,t.havingStyle(a.sup()),t):St(e.sub,t.havingStyle(a.sub()),t),n=Ut(e.base,"horizBrace")):n=Ut(e,"horizBrace");var i,o=St(n.base,t.havingBaseStyle(A.DISPLAY)),s=Gt(n,t);if(n.isOver?(i=Qe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Qe.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Qe.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?Qe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Qe.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Qe.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};lt({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:ln,mathmlBuilder:function(e,t){var r=Ft(e.label);return new Nt.MathNode(e.isOver?"mover":"munder",[Ot(e.base,t),r])}}),lt({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Ut(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:mt(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=vt(e.body,t,!1);return Qe.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=Ht(e.body,t);return r instanceof Tt||(r=new Tt("mrow",[r])),r.setAttribute("href",e.href),r}}),lt({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Ut(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=X(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=X(e.width,t));var i={height:W(r+n)};a>0&&(i.width=W(a)),n>0&&(i.verticalAlign=W(-n));var o=new Q(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=X(e.height,t),a=0;if(e.totalheight.number>0&&(a=X(e.totalheight,t)-n,r.setAttribute("valign",W(-a))),r.setAttribute("height",W(n+a)),e.width.number>0){var i=X(e.width,t);r.setAttribute("width",W(i))}return r.setAttribute("src",e.src),r}}),lt({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Ut(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return Qe.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=X(e.dimension,t);return new Nt.SpaceNode(r)}}),lt({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=Qe.makeSpan([],[St(e.body,t)]),r=Qe.makeSpan(["inner"],[r],t)):r=Qe.makeSpan(["inner"],[St(e.body,t)]);var n=Qe.makeSpan(["fix"],[]),a=Qe.makeSpan([e.alignment],[r,n],t),i=Qe.makeSpan(["strut"]);return i.style.height=W(a.height+a.depth),a.depth&&(i.style.verticalAlign=W(-a.depth)),a.children.unshift(i),a=Qe.makeSpan(["thinbox"],[a],t),Qe.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mpadded",[Ot(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),lt({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),lt({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var cn=function(e,t){switch(t.style.size){case A.DISPLAY.size:return e.display;case A.TEXT.size:return e.text;case A.SCRIPT.size:return e.script;case A.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};lt({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:mt(t[0]),text:mt(t[1]),script:mt(t[2]),scriptscript:mt(t[3])}},htmlBuilder:function(e,t){var r=cn(e,t),n=vt(r,t,!1);return Qe.makeFragment(n)},mathmlBuilder:function(e,t){var r=cn(e,t);return Ht(r,t)}});var mn=function(e,t,r,n,a,i,o){e=Qe.makeSpan([],[e]);var s,l,h,c=r&&p(r);if(t){var m=St(t,n.havingStyle(a.sup()),n);l={elem:m,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-m.depth)}}if(r){var u=St(r,n.havingStyle(a.sub()),n);s={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-u.height)}}if(l&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;h=Qe.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:W(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:W(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;h=Qe.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:W(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!l)return e;var g=e.depth+o;h=Qe.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:W(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[h];if(s&&0!==i&&!c){var y=Qe.makeSpan(["mspace"],[],n);y.style.marginRight=W(i),v.unshift(y)}return Qe.makeSpan(["mop","op-limits"],v,n)},un=["\\smallint"],pn=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Ut(e.base,"op"),i=!0):a=Ut(e,"op");var o,s=t.style,h=!1;if(s.size===A.DISPLAY.size&&a.symbol&&!l(un,a.name)&&(h=!0),a.symbol){var c=h?"Size2-Regular":"Size1-Regular",m="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(m=a.name.slice(1),a.name="oiint"===m?"\\iint":"\\iiint"),o=Qe.makeSymbol(a.name,c,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),m.length>0){var u=o.italic,p=Qe.staticSvg(m+"Size"+(h?"2":"1"),t);o=Qe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+m,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=vt(a.body,t,!0);1===d.length&&d[0]instanceof te?(o=d[0]).classes[0]="mop":o=Qe.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=vt(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",W(a)):(s.setAttribute("height",W(a)),s.setAttribute("depth",W(-a))),s.setAttribute("voffset",W(a)),s}});var bn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];lt({type:"sizing",names:bn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:bn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return yn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=Rt(e.body,r),a=new Nt.MathNode("mstyle",n);return a.setAttribute("mathsize",W(r.sizeMultiplier)),a}}),lt({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Ut(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+m-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=W(c);var p=Qe.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(A.SCRIPTSCRIPT),f=St(e.index,d,t),g=.6*(p.height-p.depth),v=Qe.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),y=Qe.makeSpan(["root"],[v]);return Qe.makeSpan(["mord","sqrt"],[y,p],t)}return Qe.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new Nt.MathNode("mroot",[Ot(r,t),Ot(n,t)]):new Nt.MathNode("msqrt",[Ot(r,t)])}});var xn={display:A.DISPLAY,text:A.TEXT,script:A.SCRIPT,scriptscript:A.SCRIPTSCRIPT};lt({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r).withFont("");return yn(e.body,n,t)},mathmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r),a=Rt(e.body,n),i=new Nt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});ht({type:"supsub",htmlBuilder:function(e,t){var r=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===A.DISPLAY.size||r.alwaysHandleSupSub)?pn:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===A.DISPLAY.size||r.limits)?vn:null:"accent"===r.type?p(r.base)?Wt:null:"horizBrace"===r.type&&!e.sub===r.isOver?ln:null:null}(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,l=e.sub,h=St(o,t),c=t.fontMetrics(),m=0,u=0,d=o&&p(o);if(s){var f=t.havingStyle(t.style.sup());n=St(s,f,t),d||(m=h.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(l){var g=t.havingStyle(t.style.sub());a=St(l,g,t),d||(u=h.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===A.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,y=t.sizeMultiplier,b=W(.5/c.ptPerEm/y),x=null;if(a){var w=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(h instanceof te||w)&&(x=W(-h.italic))}if(n&&a){m=Math.max(m,i,n.depth+.25*c.xHeight),u=Math.max(u,c.sub2);var k=4*c.defaultRuleThickness;if(m-n.depth-(a.height-u)0&&(m+=S,u-=S)}v=Qe.makeVList({positionType:"individualShift",children:[{type:"elem",elem:a,shift:u,marginRight:b,marginLeft:x},{type:"elem",elem:n,shift:-m,marginRight:b}]},t)}else if(a){u=Math.max(u,c.sub1,a.height-.8*c.xHeight),v=Qe.makeVList({positionType:"shift",positionData:u,children:[{type:"elem",elem:a,marginLeft:x,marginRight:b}]},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");m=Math.max(m,i,n.depth+.25*c.xHeight),v=Qe.makeVList({positionType:"shift",positionData:-m,children:[{type:"elem",elem:n,marginRight:b}]},t)}var M=wt(h,"right")||"mord";return Qe.makeSpan([M],[h,Qe.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Ot(e.base,t)];if(e.sub&&i.push(Ot(e.sub,t)),e.sup&&i.push(Ot(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===A.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===A.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===A.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===A.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===A.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===A.DISPLAY)?"mover":"msup"}return new Nt.MathNode(a,i)}}),ht({type:"atom",htmlBuilder:function(e,t){return Qe.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mo",[Ct(e.text,e.mode)]);if("bin"===e.family){var n=It(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var wn={mi:"italic",mn:"normal",mtext:"normal"};ht({type:"mathord",htmlBuilder:function(e,t){return Qe.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mi",[Ct(e.text,e.mode,t)]),n=It(e,t)||"italic";return n!==wn[r.type]&&r.setAttribute("mathvariant",n),r}}),ht({type:"textord",htmlBuilder:function(e,t){return Qe.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=Ct(e.text,e.mode,t),a=It(e,t)||"normal";return r="text"===e.mode?new Nt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new Nt.MathNode("mn",[n]):"\\prime"===e.text?new Nt.MathNode("mo",[n]):new Nt.MathNode("mi",[n]),a!==wn[r.type]&&r.setAttribute("mathvariant",a),r}});var kn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Sn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};ht({type:"spacing",htmlBuilder:function(e,t){if(Sn.hasOwnProperty(e.text)){var r=Sn[e.text].className||"";if("text"===e.mode){var a=Qe.makeOrd(e,t,"textord");return a.classes.push(r),a}return Qe.makeSpan(["mspace",r],[Qe.mathsym(e.text,e.mode,t)],t)}if(kn.hasOwnProperty(e.text))return Qe.makeSpan(["mspace",kn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!Sn.hasOwnProperty(e.text)){if(kn.hasOwnProperty(e.text))return new Nt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new Nt.MathNode("mtext",[new Nt.TextNode(" ")])}});var Mn=function(){var e=new Nt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};ht({type:"tag",mathmlBuilder:function(e,t){var r=new Nt.MathNode("mtable",[new Nt.MathNode("mtr",[Mn(),new Nt.MathNode("mtd",[Ht(e.body,t)]),Mn(),new Nt.MathNode("mtd",[Ht(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var zn={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},An={"\\textbf":"textbf","\\textmd":"textmd"},Tn={"\\textit":"textit","\\textup":"textup"},Bn=function(e,t){var r=e.font;return r?zn[r]?t.withTextFontFamily(zn[r]):An[r]?t.withTextFontWeight(An[r]):t.withTextFontShape(Tn[r]):t};lt({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:mt(a),font:n}},htmlBuilder:function(e,t){var r=Bn(e,t),n=vt(e.body,r,!0);return Qe.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Bn(e,t);return Ht(e.body,r)}}),lt({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=St(e.body,t),n=Qe.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=Qe.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return Qe.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new Nt.MathNode("mo",[new Nt.TextNode("‾")]);r.setAttribute("stretchy","true");var n=new Nt.MathNode("munder",[Ot(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),lt({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=St(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return Qe.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new Nt.MathNode("mpadded",[Ot(e.body,t)],["vcenter"])}}),lt({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=Nn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t},e}(),Dn=Pr;Vr("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Vr("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Vr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Vr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Vr("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Vr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Vr("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Pn={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Vr("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Pn[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=Pn[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Vr("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in Fn?t=Fn[r]:("\\not"===r.slice(0,4)||r in he.math&&l(["bin","rel"],he.math[r].group))&&(t="\\dotsb"),t}));var Gn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Vr("\\dotso",(function(e){return e.future().text in Gn?"\\ldots\\,":"\\ldots"})),Vr("\\dotsc",(function(e){var t=e.future().text;return t in Gn&&","!==t?"\\ldots\\,":"\\ldots"})),Vr("\\cdots",(function(e){return e.future().text in Gn?"\\@cdots\\,":"\\@cdots"})),Vr("\\dotsb","\\cdots"),Vr("\\dotsm","\\cdots"),Vr("\\dotsi","\\!\\cdots"),Vr("\\dotsx","\\ldots\\,"),Vr("\\DOTSI","\\relax"),Vr("\\DOTSB","\\relax"),Vr("\\DOTSX","\\relax"),Vr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Vr("\\,","\\tmspace+{3mu}{.1667em}"),Vr("\\thinspace","\\,"),Vr("\\>","\\mskip{4mu}"),Vr("\\:","\\tmspace+{4mu}{.2222em}"),Vr("\\medspace","\\:"),Vr("\\;","\\tmspace+{5mu}{.2777em}"),Vr("\\thickspace","\\;"),Vr("\\!","\\tmspace-{3mu}{.1667em}"),Vr("\\negthinspace","\\!"),Vr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Vr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Vr("\\enspace","\\kern.5em "),Vr("\\enskip","\\hskip.5em\\relax"),Vr("\\quad","\\hskip1em\\relax"),Vr("\\qquad","\\hskip2em\\relax"),Vr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Vr("\\tag@paren","\\tag@literal{({#1})}"),Vr("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Vr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Vr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Vr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Vr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Vr("\\newline","\\\\\\relax"),Vr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Un=W(I["Main-Regular"]["T".charCodeAt(0)][1]-.7*I["Main-Regular"]["A".charCodeAt(0)][1]);Vr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Un+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Vr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Un+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Vr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Vr("\\@hspace","\\hskip #1\\relax"),Vr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Vr("\\ordinarycolon",":"),Vr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Vr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Vr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Vr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Vr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Vr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Vr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Vr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Vr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Vr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Vr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Vr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Vr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Vr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Vr("∷","\\dblcolon"),Vr("∹","\\eqcolon"),Vr("≔","\\coloneqq"),Vr("≕","\\eqqcolon"),Vr("⩴","\\Coloneqq"),Vr("\\ratio","\\vcentcolon"),Vr("\\coloncolon","\\dblcolon"),Vr("\\colonequals","\\coloneqq"),Vr("\\coloncolonequals","\\Coloneqq"),Vr("\\equalscolon","\\eqqcolon"),Vr("\\equalscoloncolon","\\Eqqcolon"),Vr("\\colonminus","\\coloneq"),Vr("\\coloncolonminus","\\Coloneq"),Vr("\\minuscolon","\\eqcolon"),Vr("\\minuscoloncolon","\\Eqcolon"),Vr("\\coloncolonapprox","\\Colonapprox"),Vr("\\coloncolonsim","\\Colonsim"),Vr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`∌}}"),Vr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Vr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Vr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Vr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Vr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Vr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Vr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Vr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Vr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{≩}"),Vr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{≨}"),Vr("\\ngeqq","\\html@mathml{\\@ngeqq}{≱}"),Vr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{≱}"),Vr("\\nleqq","\\html@mathml{\\@nleqq}{≰}"),Vr("\\nleqslant","\\html@mathml{\\@nleqslant}{≰}"),Vr("\\nshortmid","\\html@mathml{\\@nshortmid}{∤}"),Vr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{∦}"),Vr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{⊈}"),Vr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{⊉}"),Vr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{⊊}"),Vr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{⫋}"),Vr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{⊋}"),Vr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{⫌}"),Vr("\\imath","\\html@mathml{\\@imath}{ı}"),Vr("\\jmath","\\html@mathml{\\@jmath}{ȷ}"),Vr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`⟦}}"),Vr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`⟧}}"),Vr("⟦","\\llbracket"),Vr("⟧","\\rrbracket"),Vr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`⦃}}"),Vr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`⦄}}"),Vr("⦃","\\lBrace"),Vr("⦄","\\rBrace"),Vr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`⦵}}"),Vr("⦵","\\minuso"),Vr("\\darr","\\downarrow"),Vr("\\dArr","\\Downarrow"),Vr("\\Darr","\\Downarrow"),Vr("\\lang","\\langle"),Vr("\\rang","\\rangle"),Vr("\\uarr","\\uparrow"),Vr("\\uArr","\\Uparrow"),Vr("\\Uarr","\\Uparrow"),Vr("\\N","\\mathbb{N}"),Vr("\\R","\\mathbb{R}"),Vr("\\Z","\\mathbb{Z}"),Vr("\\alef","\\aleph"),Vr("\\alefsym","\\aleph"),Vr("\\Alpha","\\mathrm{A}"),Vr("\\Beta","\\mathrm{B}"),Vr("\\bull","\\bullet"),Vr("\\Chi","\\mathrm{X}"),Vr("\\clubs","\\clubsuit"),Vr("\\cnums","\\mathbb{C}"),Vr("\\Complex","\\mathbb{C}"),Vr("\\Dagger","\\ddagger"),Vr("\\diamonds","\\diamondsuit"),Vr("\\empty","\\emptyset"),Vr("\\Epsilon","\\mathrm{E}"),Vr("\\Eta","\\mathrm{H}"),Vr("\\exist","\\exists"),Vr("\\harr","\\leftrightarrow"),Vr("\\hArr","\\Leftrightarrow"),Vr("\\Harr","\\Leftrightarrow"),Vr("\\hearts","\\heartsuit"),Vr("\\image","\\Im"),Vr("\\infin","\\infty"),Vr("\\Iota","\\mathrm{I}"),Vr("\\isin","\\in"),Vr("\\Kappa","\\mathrm{K}"),Vr("\\larr","\\leftarrow"),Vr("\\lArr","\\Leftarrow"),Vr("\\Larr","\\Leftarrow"),Vr("\\lrarr","\\leftrightarrow"),Vr("\\lrArr","\\Leftrightarrow"),Vr("\\Lrarr","\\Leftrightarrow"),Vr("\\Mu","\\mathrm{M}"),Vr("\\natnums","\\mathbb{N}"),Vr("\\Nu","\\mathrm{N}"),Vr("\\Omicron","\\mathrm{O}"),Vr("\\plusmn","\\pm"),Vr("\\rarr","\\rightarrow"),Vr("\\rArr","\\Rightarrow"),Vr("\\Rarr","\\Rightarrow"),Vr("\\real","\\Re"),Vr("\\reals","\\mathbb{R}"),Vr("\\Reals","\\mathbb{R}"),Vr("\\Rho","\\mathrm{P}"),Vr("\\sdot","\\cdot"),Vr("\\sect","\\S"),Vr("\\spades","\\spadesuit"),Vr("\\sub","\\subset"),Vr("\\sube","\\subseteq"),Vr("\\supe","\\supseteq"),Vr("\\Tau","\\mathrm{T}"),Vr("\\thetasym","\\vartheta"),Vr("\\weierp","\\wp"),Vr("\\Zeta","\\mathrm{Z}"),Vr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Vr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Vr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Vr("\\bra","\\mathinner{\\langle{#1}|}"),Vr("\\ket","\\mathinner{|{#1}\\rangle}"),Vr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Vr("\\Bra","\\left\\langle#1\\right|"),Vr("\\Ket","\\left|#1\\right\\rangle");var Yn=function(e){return function(t){var r=t.consumeArg().tokens,n=t.consumeArg().tokens,a=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=function(t){return function(r){e&&(r.macros.set("|",o),a.length&&r.macros.set("\\|",s));var i=t;return!t&&a.length&&"|"===r.future().text&&(r.popToken(),i=!0),{tokens:i?a:n,numArgs:0}}};t.macros.set("|",l(!1)),a.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,c=t.expandTokens([].concat(i,h,r));return t.macros.endGroup(),{tokens:c.reverse(),numArgs:0}}};Vr("\\bra@ket",Yn(!1)),Vr("\\bra@set",Yn(!0)),Vr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Vr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Vr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Vr("\\angln","{\\angl n}"),Vr("\\blue","\\textcolor{##6495ed}{#1}"),Vr("\\orange","\\textcolor{##ffa500}{#1}"),Vr("\\pink","\\textcolor{##ff00af}{#1}"),Vr("\\red","\\textcolor{##df0030}{#1}"),Vr("\\green","\\textcolor{##28ae7b}{#1}"),Vr("\\gray","\\textcolor{gray}{#1}"),Vr("\\purple","\\textcolor{##9d38bd}{#1}"),Vr("\\blueA","\\textcolor{##ccfaff}{#1}"),Vr("\\blueB","\\textcolor{##80f6ff}{#1}"),Vr("\\blueC","\\textcolor{##63d9ea}{#1}"),Vr("\\blueD","\\textcolor{##11accd}{#1}"),Vr("\\blueE","\\textcolor{##0c7f99}{#1}"),Vr("\\tealA","\\textcolor{##94fff5}{#1}"),Vr("\\tealB","\\textcolor{##26edd5}{#1}"),Vr("\\tealC","\\textcolor{##01d1c1}{#1}"),Vr("\\tealD","\\textcolor{##01a995}{#1}"),Vr("\\tealE","\\textcolor{##208170}{#1}"),Vr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Vr("\\greenB","\\textcolor{##8af281}{#1}"),Vr("\\greenC","\\textcolor{##74cf70}{#1}"),Vr("\\greenD","\\textcolor{##1fab54}{#1}"),Vr("\\greenE","\\textcolor{##0d923f}{#1}"),Vr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Vr("\\goldB","\\textcolor{##ffbb71}{#1}"),Vr("\\goldC","\\textcolor{##ff9c39}{#1}"),Vr("\\goldD","\\textcolor{##e07d10}{#1}"),Vr("\\goldE","\\textcolor{##a75a05}{#1}"),Vr("\\redA","\\textcolor{##fca9a9}{#1}"),Vr("\\redB","\\textcolor{##ff8482}{#1}"),Vr("\\redC","\\textcolor{##f9685d}{#1}"),Vr("\\redD","\\textcolor{##e84d39}{#1}"),Vr("\\redE","\\textcolor{##bc2612}{#1}"),Vr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Vr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Vr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Vr("\\maroonD","\\textcolor{##ca337c}{#1}"),Vr("\\maroonE","\\textcolor{##9e034e}{#1}"),Vr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Vr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Vr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Vr("\\purpleD","\\textcolor{##7854ab}{#1}"),Vr("\\purpleE","\\textcolor{##543b78}{#1}"),Vr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Vr("\\mintB","\\textcolor{##edf2df}{#1}"),Vr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Vr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Vr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Vr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Vr("\\grayD","\\textcolor{##d6d8da}{#1}"),Vr("\\grayE","\\textcolor{##babec2}{#1}"),Vr("\\grayF","\\textcolor{##888d93}{#1}"),Vr("\\grayG","\\textcolor{##626569}{#1}"),Vr("\\grayH","\\textcolor{##3b3e40}{#1}"),Vr("\\grayI","\\textcolor{##21242c}{#1}"),Vr("\\kaBlue","\\textcolor{##314453}{#1}"),Vr("\\kaGreen","\\textcolor{##71B307}{#1}");var Xn={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Wn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Ln(Dn,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new En(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Gr("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;" "===this.future().text;)this.stack.pop()},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1==--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i.length},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;)if(!1===this.expandOnce()){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Gr(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){var n=this.stack.pop();n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(n)}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new En(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||Cn.hasOwnProperty(e)||he.math.hasOwnProperty(e)||he.text.hasOwnProperty(e)||Xn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Cn.hasOwnProperty(e)&&!Cn[e].primitive},e}(),_n=/^[₊₋₌₍₎₀₁₂₃₄₅₆₇₈₉ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ]/,jn=Object.freeze({"₊":"+","₋":"-","₌":"=","₍":"(","₎":")","₀":"0","₁":"1","₂":"2","₃":"3","₄":"4","₅":"5","₆":"6","₇":"7","₈":"8","₉":"9","ₐ":"a","ₑ":"e","ₕ":"h","ᵢ":"i","ⱼ":"j","ₖ":"k","ₗ":"l","ₘ":"m","ₙ":"n","ₒ":"o","ₚ":"p","ᵣ":"r","ₛ":"s","ₜ":"t","ᵤ":"u","ᵥ":"v","ₓ":"x","ᵦ":"β","ᵧ":"γ","ᵨ":"ρ","ᵩ":"ϕ","ᵪ":"χ","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")","⁰":"0","¹":"1","²":"2","³":"3","⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᴬ":"A","ᴮ":"B","ᴰ":"D","ᴱ":"E","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","ᴿ":"R","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g","ʰ":"h","ⁱ":"i","ʲ":"j","ᵏ":"k","ˡ":"l","ᵐ":"m","ⁿ":"n","ᵒ":"o","ᵖ":"p","ʳ":"r","ˢ":"s","ᵗ":"t","ᵘ":"u","ᵛ":"v","ʷ":"w","ˣ":"x","ʸ":"y","ᶻ":"z","ᵝ":"β","ᵞ":"γ","ᵟ":"δ","ᵠ":"ϕ","ᵡ":"χ","ᶿ":"θ"}),$n={"́":{text:"\\'",math:"\\acute"},"̀":{text:"\\`",math:"\\grave"},"̈":{text:'\\"',math:"\\ddot"},"̃":{text:"\\~",math:"\\tilde"},"̄":{text:"\\=",math:"\\bar"},"̆":{text:"\\u",math:"\\breve"},"̌":{text:"\\v",math:"\\check"},"̂":{text:"\\^",math:"\\hat"},"̇":{text:"\\.",math:"\\dot"},"̊":{text:"\\r",math:"\\mathring"},"̋":{text:"\\H"},"̧":{text:"\\c"}},Zn={"á":"á","à":"à","ä":"ä","ǟ":"ǟ","ã":"ã","ā":"ā","ă":"ă","ắ":"ắ","ằ":"ằ","ẵ":"ẵ","ǎ":"ǎ","â":"â","ấ":"ấ","ầ":"ầ","ẫ":"ẫ","ȧ":"ȧ","ǡ":"ǡ","å":"å","ǻ":"ǻ","ḃ":"ḃ","ć":"ć","ḉ":"ḉ","č":"č","ĉ":"ĉ","ċ":"ċ","ç":"ç","ď":"ď","ḋ":"ḋ","ḑ":"ḑ","é":"é","è":"è","ë":"ë","ẽ":"ẽ","ē":"ē","ḗ":"ḗ","ḕ":"ḕ","ĕ":"ĕ","ḝ":"ḝ","ě":"ě","ê":"ê","ế":"ế","ề":"ề","ễ":"ễ","ė":"ė","ȩ":"ȩ","ḟ":"ḟ","ǵ":"ǵ","ḡ":"ḡ","ğ":"ğ","ǧ":"ǧ","ĝ":"ĝ","ġ":"ġ","ģ":"ģ","ḧ":"ḧ","ȟ":"ȟ","ĥ":"ĥ","ḣ":"ḣ","ḩ":"ḩ","í":"í","ì":"ì","ï":"ï","ḯ":"ḯ","ĩ":"ĩ","ī":"ī","ĭ":"ĭ","ǐ":"ǐ","î":"î","ǰ":"ǰ","ĵ":"ĵ","ḱ":"ḱ","ǩ":"ǩ","ķ":"ķ","ĺ":"ĺ","ľ":"ľ","ļ":"ļ","ḿ":"ḿ","ṁ":"ṁ","ń":"ń","ǹ":"ǹ","ñ":"ñ","ň":"ň","ṅ":"ṅ","ņ":"ņ","ó":"ó","ò":"ò","ö":"ö","ȫ":"ȫ","õ":"õ","ṍ":"ṍ","ṏ":"ṏ","ȭ":"ȭ","ō":"ō","ṓ":"ṓ","ṑ":"ṑ","ŏ":"ŏ","ǒ":"ǒ","ô":"ô","ố":"ố","ồ":"ồ","ỗ":"ỗ","ȯ":"ȯ","ȱ":"ȱ","ő":"ő","ṕ":"ṕ","ṗ":"ṗ","ŕ":"ŕ","ř":"ř","ṙ":"ṙ","ŗ":"ŗ","ś":"ś","ṥ":"ṥ","š":"š","ṧ":"ṧ","ŝ":"ŝ","ṡ":"ṡ","ş":"ş","ẗ":"ẗ","ť":"ť","ṫ":"ṫ","ţ":"ţ","ú":"ú","ù":"ù","ü":"ü","ǘ":"ǘ","ǜ":"ǜ","ǖ":"ǖ","ǚ":"ǚ","ũ":"ũ","ṹ":"ṹ","ū":"ū","ṻ":"ṻ","ŭ":"ŭ","ǔ":"ǔ","û":"û","ů":"ů","ű":"ű","ṽ":"ṽ","ẃ":"ẃ","ẁ":"ẁ","ẅ":"ẅ","ŵ":"ŵ","ẇ":"ẇ","ẘ":"ẘ","ẍ":"ẍ","ẋ":"ẋ","ý":"ý","ỳ":"ỳ","ÿ":"ÿ","ỹ":"ỹ","ȳ":"ȳ","ŷ":"ŷ","ẏ":"ẏ","ẙ":"ẙ","ź":"ź","ž":"ž","ẑ":"ẑ","ż":"ż","Á":"Á","À":"À","Ä":"Ä","Ǟ":"Ǟ","Ã":"Ã","Ā":"Ā","Ă":"Ă","Ắ":"Ắ","Ằ":"Ằ","Ẵ":"Ẵ","Ǎ":"Ǎ","Â":"Â","Ấ":"Ấ","Ầ":"Ầ","Ẫ":"Ẫ","Ȧ":"Ȧ","Ǡ":"Ǡ","Å":"Å","Ǻ":"Ǻ","Ḃ":"Ḃ","Ć":"Ć","Ḉ":"Ḉ","Č":"Č","Ĉ":"Ĉ","Ċ":"Ċ","Ç":"Ç","Ď":"Ď","Ḋ":"Ḋ","Ḑ":"Ḑ","É":"É","È":"È","Ë":"Ë","Ẽ":"Ẽ","Ē":"Ē","Ḗ":"Ḗ","Ḕ":"Ḕ","Ĕ":"Ĕ","Ḝ":"Ḝ","Ě":"Ě","Ê":"Ê","Ế":"Ế","Ề":"Ề","Ễ":"Ễ","Ė":"Ė","Ȩ":"Ȩ","Ḟ":"Ḟ","Ǵ":"Ǵ","Ḡ":"Ḡ","Ğ":"Ğ","Ǧ":"Ǧ","Ĝ":"Ĝ","Ġ":"Ġ","Ģ":"Ģ","Ḧ":"Ḧ","Ȟ":"Ȟ","Ĥ":"Ĥ","Ḣ":"Ḣ","Ḩ":"Ḩ","Í":"Í","Ì":"Ì","Ï":"Ï","Ḯ":"Ḯ","Ĩ":"Ĩ","Ī":"Ī","Ĭ":"Ĭ","Ǐ":"Ǐ","Î":"Î","İ":"İ","Ĵ":"Ĵ","Ḱ":"Ḱ","Ǩ":"Ǩ","Ķ":"Ķ","Ĺ":"Ĺ","Ľ":"Ľ","Ļ":"Ļ","Ḿ":"Ḿ","Ṁ":"Ṁ","Ń":"Ń","Ǹ":"Ǹ","Ñ":"Ñ","Ň":"Ň","Ṅ":"Ṅ","Ņ":"Ņ","Ó":"Ó","Ò":"Ò","Ö":"Ö","Ȫ":"Ȫ","Õ":"Õ","Ṍ":"Ṍ","Ṏ":"Ṏ","Ȭ":"Ȭ","Ō":"Ō","Ṓ":"Ṓ","Ṑ":"Ṑ","Ŏ":"Ŏ","Ǒ":"Ǒ","Ô":"Ô","Ố":"Ố","Ồ":"Ồ","Ỗ":"Ỗ","Ȯ":"Ȯ","Ȱ":"Ȱ","Ő":"Ő","Ṕ":"Ṕ","Ṗ":"Ṗ","Ŕ":"Ŕ","Ř":"Ř","Ṙ":"Ṙ","Ŗ":"Ŗ","Ś":"Ś","Ṥ":"Ṥ","Š":"Š","Ṧ":"Ṧ","Ŝ":"Ŝ","Ṡ":"Ṡ","Ş":"Ş","Ť":"Ť","Ṫ":"Ṫ","Ţ":"Ţ","Ú":"Ú","Ù":"Ù","Ü":"Ü","Ǘ":"Ǘ","Ǜ":"Ǜ","Ǖ":"Ǖ","Ǚ":"Ǚ","Ũ":"Ũ","Ṹ":"Ṹ","Ū":"Ū","Ṻ":"Ṻ","Ŭ":"Ŭ","Ǔ":"Ǔ","Û":"Û","Ů":"Ů","Ű":"Ű","Ṽ":"Ṽ","Ẃ":"Ẃ","Ẁ":"Ẁ","Ẅ":"Ẅ","Ŵ":"Ŵ","Ẇ":"Ẇ","Ẍ":"Ẍ","Ẋ":"Ẋ","Ý":"Ý","Ỳ":"Ỳ","Ÿ":"Ÿ","Ỹ":"Ỹ","Ȳ":"Ȳ","Ŷ":"Ŷ","Ẏ":"Ẏ","Ź":"Ź","Ž":"Ž","Ẑ":"Ẑ","Ż":"Ż","ά":"ά","ὰ":"ὰ","ᾱ":"ᾱ","ᾰ":"ᾰ","έ":"έ","ὲ":"ὲ","ή":"ή","ὴ":"ὴ","ί":"ί","ὶ":"ὶ","ϊ":"ϊ","ΐ":"ΐ","ῒ":"ῒ","ῑ":"ῑ","ῐ":"ῐ","ό":"ό","ὸ":"ὸ","ύ":"ύ","ὺ":"ὺ","ϋ":"ϋ","ΰ":"ΰ","ῢ":"ῢ","ῡ":"ῡ","ῠ":"ῠ","ώ":"ώ","ὼ":"ὼ","Ύ":"Ύ","Ὺ":"Ὺ","Ϋ":"Ϋ","Ῡ":"Ῡ","Ῠ":"Ῠ","Ώ":"Ώ","Ὼ":"Ὼ"},Kn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Wn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.subparse=function(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new Gr("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&Cn[a.text]&&Cn[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=he[this.mode][t].group,h=Fr.range(e);if(oe.hasOwnProperty(l)){var c=l;s={type:"atom",mode:this.mode,family:c,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(N(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Fr.range(e),text:t}}if(this.consume(),o)for(var m=0;m2&&A.push("'"+this.terminals_[T]+"'");k=c.showPosition?"Parse error on line "+(l+1)+":\n"+c.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(k,{text:c.match,token:this.terminals_[f]||f,line:c.yylineno,loc:x,expected:A})}if(p[0]instanceof Array&&p.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+f);switch(p[0]){case 1:i.push(f),a.push(c.yytext),n.push(c.yylloc),i.push(p[1]),f=null,o=c.yyleng,s=c.yytext,l=c.yylineno,x=c.yylloc;break;case 2:if(_=this.productions_[p[1]][1],S.$=a[a.length-_],S._$={first_line:n[n.length-(_||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(_||1)].first_column,last_column:n[n.length-1].last_column},g&&(S._$.range=[n[n.length-(_||1)].range[0],n[n.length-1].range[1]]),void 0!==(q=this.performAction.apply(S,[s,o,l,d.yy,p[1],a,n].concat(h))))return q;_&&(i=i.slice(0,-1*_*2),a=a.slice(0,-1*_),n=n.slice(0,-1*_)),i.push(this.productions_[p[1]][0]),a.push(S.$),n.push(S._$),m=r[i[i.length-2]][i[i.length-1]],i.push(m);break;case 3:return!0}}return!0}},H={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;ri[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:return this.begin("open_directive"),41;case 1:return this.begin("type_directive"),42;case 2:return this.popState(),this.begin("arg_directive"),36;case 3:return this.popState(),this.popState(),44;case 4:return 43;case 5:case 6:case 8:break;case 7:return 38;case 9:return this.begin("title"),14;case 10:return this.popState(),"title_value";case 11:return this.begin("acc_title"),16;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),18;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 27:case 29:case 33:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 26;case 19:return 28;case 20:return 27;case 21:return 29;case 22:return 30;case 23:return 31;case 24:return 32;case 25:this.begin("md_string");break;case 26:return"MD_STR";case 28:this.begin("string");break;case 30:return"STR";case 31:return this.begin("point_start"),23;case 32:return this.begin("point_x"),24;case 34:this.popState(),this.begin("point_y");break;case 35:return this.popState(),25;case 36:return 7;case 37:return 53;case 38:return"COLON";case 39:return 55;case 40:return 54;case 41:case 42:return 56;case 43:return 57;case 44:return 59;case 45:return 60;case 46:return 58;case 47:return 51;case 48:return 61;case 49:return 52;case 50:return 5;case 51:return 39;case 52:return 50;case 53:return 40}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[35],inclusive:!1},point_x:{rules:[34],inclusive:!1},point_start:{rules:[32,33],inclusive:!1},acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[10],inclusive:!1},md_string:{rules:[26,27],inclusive:!1},string:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,11,13,15,18,19,20,21,22,23,24,25,28,31,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],inclusive:!0}}};function $(){this.yy={}}return Q.lexer=H,$.prototype=Q,Q.Parser=$,new $}());r.parser=r;const s=r,l=(0,a.G)(),o=(0,a.c)();function h(t){return(0,a.d)(t.trim(),o)}const c=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,n,r,s,l,o,h,c,d,u,x,g,f,y,p,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=a.C.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=a.C.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=a.C.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(n=a.C.quadrantChart)?void 0:n.titleFontSize)||20,quadrantPadding:(null==(r=a.C.quadrantChart)?void 0:r.quadrantPadding)||5,xAxisLabelPadding:(null==(s=a.C.quadrantChart)?void 0:s.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(l=a.C.quadrantChart)?void 0:l.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=a.C.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=a.C.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=a.C.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=a.C.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=a.C.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=a.C.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=a.C.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=a.C.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(y=a.C.quadrantChart)?void 0:y.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(p=a.C.quadrantChart)?void 0:p.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=a.C.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:l.quadrant1Fill,quadrant2Fill:l.quadrant2Fill,quadrant3Fill:l.quadrant3Fill,quadrant4Fill:l.quadrant4Fill,quadrant1TextFill:l.quadrant1TextFill,quadrant2TextFill:l.quadrant2TextFill,quadrant3TextFill:l.quadrant3TextFill,quadrant4TextFill:l.quadrant4TextFill,quadrantPointFill:l.quadrantPointFill,quadrantPointTextFill:l.quadrantPointTextFill,quadrantXAxisTextFill:l.quadrantXAxisTextFill,quadrantYAxisTextFill:l.quadrantYAxisTextFill,quadrantTitleFill:l.quadrantTitleFill,quadrantInternalBorderStrokeFill:l.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:l.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),a.l.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){a.l.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){a.l.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,l={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},o=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?o:0},c=this.config.quadrantPadding+l.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-l.left-l.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:l,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:l,quadrantLeft:o,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=0===this.data.points.length,x=[];return this.data.xAxisLeftText&&i&&x.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&x.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&x.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+l-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&x.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+s-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),x}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const t of s)t.text.x=t.x+t.width/2,0===this.data.points.length?(t.text.y=t.y+t.height/2,t.text.horizontalPos="middle"):(t.text.y=t.y+this.config.quadrantTextTopPadding,t.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:r,quadrantWidth:s}=i,l=(0,n.BYU)().domain([0,1]).range([a,s+a]),o=(0,n.BYU)().domain([0,1]).range([e+r,r]);return this.data.points.map((t=>({x:l(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:l(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:l,quadrantWidth:o}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l,x2:r+o+i,y2:l},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+o,y1:l+i,x2:r+o,y2:l+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l+n,x2:r+o+i,y2:l+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:l+i,x2:r,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:l+i,x2:r+s,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:l+a,x2:r+o-i,y2:l+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}},d={parser:s,db:{setWidth:function(t){c.setConfig({chartWidth:t})},setHeight:function(t){c.setConfig({chartHeight:t})},setQuadrant1Text:function(t){c.setData({quadrant1Text:h(t.text)})},setQuadrant2Text:function(t){c.setData({quadrant2Text:h(t.text)})},setQuadrant3Text:function(t){c.setData({quadrant3Text:h(t.text)})},setQuadrant4Text:function(t){c.setData({quadrant4Text:h(t.text)})},setXAxisLeftText:function(t){c.setData({xAxisLeftText:h(t.text)})},setXAxisRightText:function(t){c.setData({xAxisRightText:h(t.text)})},setYAxisTopText:function(t){c.setData({yAxisTopText:h(t.text)})},setYAxisBottomText:function(t){c.setData({yAxisBottomText:h(t.text)})},addPoint:function(t,i,e){c.addPoints([{x:i,y:e,text:h(t.text)}])},getQuadrantData:function(){const t=(0,a.c)(),{themeVariables:i,quadrantChart:e}=t;return e&&c.setConfig(e),c.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),c.setData({titleText:(0,a.t)()}),c.build()},parseDirective:function(t,i,e){a.m.parseDirective(this,t,i,e)},clear:function(){c.clear(),(0,a.v)()},setAccTitle:a.s,getAccTitle:a.g,setDiagramTitle:a.r,getDiagramTitle:a.t,getAccDescription:a.a,setAccDescription:a.b},renderer:{draw:(t,i,e,r)=>{var s,l,o;function h(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=(0,a.c)();a.l.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=(0,n.Ys)("#i"+i));const f=("sandbox"===x?(0,n.Ys)(g.nodes()[0].contentDocument.body):(0,n.Ys)("body")).select(`[id="${i}"]`),y=f.append("g").attr("class","main"),p=(null==(s=u.quadrantChart)?void 0:s.chartWidth)||500,q=(null==(l=u.quadrantChart)?void 0:l.chartHeight)||500;(0,a.i)(f,q,p,(null==(o=u.quadrantChart)?void 0:o.useMaxWidth)||!0),f.attr("viewBox","0 0 "+p+" "+q),r.db.setHeight(q),r.db.setWidth(p);const T=r.db.getQuadrantData(),_=y.append("g").attr("class","quadrants"),m=y.append("g").attr("class","border"),A=y.append("g").attr("class","data-points"),b=y.append("g").attr("class","labels"),S=y.append("g").attr("class","title");T.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",T.title.fill).attr("font-size",T.title.fontSize).attr("dominant-baseline",h(T.title.horizontalPos)).attr("text-anchor",c(T.title.verticalPos)).attr("transform",d(T.title)).text(T.title.text),T.borderLines&&m.selectAll("line").data(T.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const k=_.selectAll("g.quadrant").data(T.quadrants).enter().append("g").attr("class","quadrant");k.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),k.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text)),b.selectAll("g.label").data(T.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>h(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const v=A.selectAll("g.data-point").data(T.points).enter().append("g").attr("class","data-point");v.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),v.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/19-86f47ecd.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/19-86f47ecd.chunk.min.js new file mode 100644 index 000000000..de649f804 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/19-86f47ecd.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[19],{4019:function(e,t,i){i.d(t,{diagram:function(){return k}});var n=i(9339),r=i(7274),s=i(3771),a=i(5625),c=(i(7484),i(7967),i(7856),function(){var e=function(e,t,i,n){for(i=i||{},n=e.length;n--;i[e[n]]=t);return i},t=[1,3],i=[1,5],n=[1,6],r=[1,7],s=[1,8],a=[5,6,8,14,16,18,19,40,41,42,43,44,45,53,71,72],c=[1,22],l=[2,13],o=[1,26],h=[1,27],u=[1,28],d=[1,29],y=[1,30],p=[1,31],_=[1,24],g=[1,32],E=[1,33],R=[1,36],f=[71,72],m=[5,8,14,16,18,19,40,41,42,43,44,45,53,60,62,71,72],I=[1,56],b=[1,57],k=[1,58],S=[1,59],T=[1,60],N=[1,61],v=[1,62],x=[62,63],A=[1,74],q=[1,70],$=[1,71],O=[1,72],w=[1,73],C=[1,75],D=[1,79],L=[1,80],F=[1,77],M=[1,78],P=[5,8,14,16,18,19,40,41,42,43,44,45,53,71,72],V={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,openDirective:9,typeDirective:10,closeDirective:11,":":12,argDirective:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,requirementDef:23,elementDef:24,relationshipDef:25,requirementType:26,requirementName:27,STRUCT_START:28,requirementBody:29,ID:30,COLONSEP:31,id:32,TEXT:33,text:34,RISK:35,riskLevel:36,VERIFYMTHD:37,verifyType:38,STRUCT_STOP:39,REQUIREMENT:40,FUNCTIONAL_REQUIREMENT:41,INTERFACE_REQUIREMENT:42,PERFORMANCE_REQUIREMENT:43,PHYSICAL_REQUIREMENT:44,DESIGN_CONSTRAINT:45,LOW_RISK:46,MED_RISK:47,HIGH_RISK:48,VERIFY_ANALYSIS:49,VERIFY_DEMONSTRATION:50,VERIFY_INSPECTION:51,VERIFY_TEST:52,ELEMENT:53,elementName:54,elementBody:55,TYPE:56,type:57,DOCREF:58,ref:59,END_ARROW_L:60,relationship:61,LINE:62,END_ARROW_R:63,CONTAINS:64,COPIES:65,DERIVES:66,SATISFIES:67,VERIFIES:68,REFINES:69,TRACES:70,unqString:71,qString:72,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",12:":",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",28:"STRUCT_START",30:"ID",31:"COLONSEP",33:"TEXT",35:"RISK",37:"VERIFYMTHD",39:"STRUCT_STOP",40:"REQUIREMENT",41:"FUNCTIONAL_REQUIREMENT",42:"INTERFACE_REQUIREMENT",43:"PERFORMANCE_REQUIREMENT",44:"PHYSICAL_REQUIREMENT",45:"DESIGN_CONSTRAINT",46:"LOW_RISK",47:"MED_RISK",48:"HIGH_RISK",49:"VERIFY_ANALYSIS",50:"VERIFY_DEMONSTRATION",51:"VERIFY_INSPECTION",52:"VERIFY_TEST",53:"ELEMENT",56:"TYPE",58:"DOCREF",60:"END_ARROW_L",62:"LINE",63:"END_ARROW_R",64:"CONTAINS",65:"COPIES",66:"DERIVES",67:"SATISFIES",68:"VERIFIES",69:"REFINES",70:"TRACES",71:"unqString",72:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,3],[4,5],[4,2],[4,2],[4,1],[9,1],[10,1],[13,1],[11,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[23,5],[29,5],[29,5],[29,5],[29,5],[29,2],[29,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[24,5],[55,5],[55,5],[55,2],[55,1],[25,5],[25,5],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[27,1],[27,1],[32,1],[32,1],[34,1],[34,1],[54,1],[54,1],[57,1],[57,1],[59,1],[59,1]],performAction:function(e,t,i,n,r,s,a){var c=s.length-1;switch(r){case 6:this.$=s[c].trim(),n.setAccTitle(this.$);break;case 7:case 8:this.$=s[c].trim(),n.setAccDescription(this.$);break;case 9:n.parseDirective("%%{","open_directive");break;case 10:n.parseDirective(s[c],"type_directive");break;case 11:s[c]=s[c].trim().replace(/'/g,'"'),n.parseDirective(s[c],"arg_directive");break;case 12:n.parseDirective("}%%","close_directive","pie");break;case 13:this.$=[];break;case 19:n.addRequirement(s[c-3],s[c-4]);break;case 20:n.setNewReqId(s[c-2]);break;case 21:n.setNewReqText(s[c-2]);break;case 22:n.setNewReqRisk(s[c-2]);break;case 23:n.setNewReqVerifyMethod(s[c-2]);break;case 26:this.$=n.RequirementType.REQUIREMENT;break;case 27:this.$=n.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 28:this.$=n.RequirementType.INTERFACE_REQUIREMENT;break;case 29:this.$=n.RequirementType.PERFORMANCE_REQUIREMENT;break;case 30:this.$=n.RequirementType.PHYSICAL_REQUIREMENT;break;case 31:this.$=n.RequirementType.DESIGN_CONSTRAINT;break;case 32:this.$=n.RiskLevel.LOW_RISK;break;case 33:this.$=n.RiskLevel.MED_RISK;break;case 34:this.$=n.RiskLevel.HIGH_RISK;break;case 35:this.$=n.VerifyType.VERIFY_ANALYSIS;break;case 36:this.$=n.VerifyType.VERIFY_DEMONSTRATION;break;case 37:this.$=n.VerifyType.VERIFY_INSPECTION;break;case 38:this.$=n.VerifyType.VERIFY_TEST;break;case 39:n.addElement(s[c-3]);break;case 40:n.setNewElementType(s[c-2]);break;case 41:n.setNewElementDocRef(s[c-2]);break;case 44:n.addRelationship(s[c-2],s[c],s[c-4]);break;case 45:n.addRelationship(s[c-2],s[c-4],s[c]);break;case 46:this.$=n.Relationships.CONTAINS;break;case 47:this.$=n.Relationships.COPIES;break;case 48:this.$=n.Relationships.DERIVES;break;case 49:this.$=n.Relationships.SATISFIES;break;case 50:this.$=n.Relationships.VERIFIES;break;case 51:this.$=n.Relationships.REFINES;break;case 52:this.$=n.Relationships.TRACES}},table:[{3:1,4:2,6:t,9:4,14:i,16:n,18:r,19:s},{1:[3]},{3:10,4:2,5:[1,9],6:t,9:4,14:i,16:n,18:r,19:s},{5:[1,11]},{10:12,20:[1,13]},{15:[1,14]},{17:[1,15]},e(a,[2,8]),{20:[2,9]},{3:16,4:2,6:t,9:4,14:i,16:n,18:r,19:s},{1:[2,2]},{4:21,5:c,7:17,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{11:34,12:[1,35],22:R},e([12,22],[2,10]),e(a,[2,6]),e(a,[2,7]),{1:[2,1]},{8:[1,37]},{4:21,5:c,7:38,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{4:21,5:c,7:39,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{4:21,5:c,7:40,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{4:21,5:c,7:41,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{4:21,5:c,7:42,8:l,9:4,14:i,16:n,18:r,19:s,23:18,24:19,25:20,26:23,32:25,40:o,41:h,42:u,43:d,44:y,45:p,53:_,71:g,72:E},{27:43,71:[1,44],72:[1,45]},{54:46,71:[1,47],72:[1,48]},{60:[1,49],62:[1,50]},e(f,[2,26]),e(f,[2,27]),e(f,[2,28]),e(f,[2,29]),e(f,[2,30]),e(f,[2,31]),e(m,[2,55]),e(m,[2,56]),e(a,[2,4]),{13:51,21:[1,52]},e(a,[2,12]),{1:[2,3]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{8:[2,17]},{8:[2,18]},{28:[1,53]},{28:[2,53]},{28:[2,54]},{28:[1,54]},{28:[2,59]},{28:[2,60]},{61:55,64:I,65:b,66:k,67:S,68:T,69:N,70:v},{61:63,64:I,65:b,66:k,67:S,68:T,69:N,70:v},{11:64,22:R},{22:[2,11]},{5:[1,65]},{5:[1,66]},{62:[1,67]},e(x,[2,46]),e(x,[2,47]),e(x,[2,48]),e(x,[2,49]),e(x,[2,50]),e(x,[2,51]),e(x,[2,52]),{63:[1,68]},e(a,[2,5]),{5:A,29:69,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:76,56:F,58:M},{32:81,71:g,72:E},{32:82,71:g,72:E},e(P,[2,19]),{31:[1,83]},{31:[1,84]},{31:[1,85]},{31:[1,86]},{5:A,29:87,30:q,33:$,35:O,37:w,39:C},e(P,[2,25]),e(P,[2,39]),{31:[1,88]},{31:[1,89]},{5:D,39:L,55:90,56:F,58:M},e(P,[2,43]),e(P,[2,44]),e(P,[2,45]),{32:91,71:g,72:E},{34:92,71:[1,93],72:[1,94]},{36:95,46:[1,96],47:[1,97],48:[1,98]},{38:99,49:[1,100],50:[1,101],51:[1,102],52:[1,103]},e(P,[2,24]),{57:104,71:[1,105],72:[1,106]},{59:107,71:[1,108],72:[1,109]},e(P,[2,42]),{5:[1,110]},{5:[1,111]},{5:[2,57]},{5:[2,58]},{5:[1,112]},{5:[2,32]},{5:[2,33]},{5:[2,34]},{5:[1,113]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[2,38]},{5:[1,114]},{5:[2,61]},{5:[2,62]},{5:[1,115]},{5:[2,63]},{5:[2,64]},{5:A,29:116,30:q,33:$,35:O,37:w,39:C},{5:A,29:117,30:q,33:$,35:O,37:w,39:C},{5:A,29:118,30:q,33:$,35:O,37:w,39:C},{5:A,29:119,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:120,56:F,58:M},{5:D,39:L,55:121,56:F,58:M},e(P,[2,20]),e(P,[2,21]),e(P,[2,22]),e(P,[2,23]),e(P,[2,40]),e(P,[2,41])],defaultActions:{8:[2,9],10:[2,2],16:[2,1],37:[2,3],38:[2,14],39:[2,15],40:[2,16],41:[2,17],42:[2,18],44:[2,53],45:[2,54],47:[2,59],48:[2,60],52:[2,11],93:[2,57],94:[2,58],96:[2,32],97:[2,33],98:[2,34],100:[2,35],101:[2,36],102:[2,37],103:[2,38],105:[2,61],106:[2,62],108:[2,63],109:[2,64]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=[0],i=[],n=[null],r=[],s=this.table,a="",c=0,l=0,o=r.slice.call(arguments,1),h=Object.create(this.lexer),u={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(u.yy[d]=this.yy[d]);h.setInput(e,u.yy),u.yy.lexer=h,u.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var y=h.yylloc;r.push(y);var p=h.options&&h.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,g,E,R,f,m,I,b,k,S={};;){if(g=t[t.length-1],this.defaultActions[g]?E=this.defaultActions[g]:(null==_&&(k=void 0,"number"!=typeof(k=i.pop()||h.lex()||1)&&(k instanceof Array&&(k=(i=k).pop()),k=this.symbols_[k]||k),_=k),E=s[g]&&s[g][_]),void 0===E||!E.length||!E[0]){var T;for(f in b=[],s[g])this.terminals_[f]&&f>2&&b.push("'"+this.terminals_[f]+"'");T=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(T,{text:h.match,token:this.terminals_[_]||_,line:h.yylineno,loc:y,expected:b})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+_);switch(E[0]){case 1:t.push(_),n.push(h.yytext),r.push(h.yylloc),t.push(E[1]),_=null,l=h.yyleng,a=h.yytext,c=h.yylineno,y=h.yylloc;break;case 2:if(m=this.productions_[E[1]][1],S.$=n[n.length-m],S._$={first_line:r[r.length-(m||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(m||1)].first_column,last_column:r[r.length-1].last_column},p&&(S._$.range=[r[r.length-(m||1)].range[0],r[r.length-1].range[1]]),void 0!==(R=this.performAction.apply(S,[a,l,c,u.yy,E[1],n,r].concat(o))))return R;m&&(t=t.slice(0,-1*m*2),n=n.slice(0,-1*m),r=r.slice(0,-1*m)),t.push(this.productions_[E[1]][0]),n.push(S.$),r.push(S._$),I=s[t[t.length-2]][t[t.length-1]],t.push(I);break;case 3:return!0}}return!0}},Y={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;st[0].length)){if(t=i,n=s,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,r[s])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,r[n]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,i,n){switch(i){case 0:return this.begin("open_directive"),19;case 1:return this.begin("type_directive"),20;case 2:return this.popState(),this.begin("arg_directive"),12;case 3:return this.popState(),this.popState(),22;case 4:return 21;case 5:return"title";case 6:return this.begin("acc_title"),14;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),16;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 53:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 5;case 14:case 15:case 16:break;case 17:return 8;case 18:return 6;case 19:return 28;case 20:return 39;case 21:return 31;case 22:return 30;case 23:return 33;case 24:return 35;case 25:return 37;case 26:return 40;case 27:return 41;case 28:return 42;case 29:return 43;case 30:return 44;case 31:return 45;case 32:return 46;case 33:return 47;case 34:return 48;case 35:return 49;case 36:return 50;case 37:return 51;case 38:return 52;case 39:return 53;case 40:return 64;case 41:return 65;case 42:return 66;case 43:return 67;case 44:return 68;case 45:return 69;case 46:return 70;case 47:return 56;case 48:return 58;case 49:return 60;case 50:return 63;case 51:return 62;case 52:this.begin("string");break;case 54:return"qString";case 55:return t.yytext=t.yytext.trim(),71}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[53,54],inclusive:!1},INITIAL:{rules:[0,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,55],inclusive:!0}}};function U(){this.yy={}}return V.lexer=Y,U.prototype=V,V.Parser=U,new U}());c.parser=c;const l=c;let o=[],h={},u={},d={},y={};const p={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},parseDirective:function(e,t,i){n.m.parseDirective(this,e,t,i)},getConfig:()=>(0,n.c)().req,addRequirement:(e,t)=>(void 0===u[e]&&(u[e]={name:e,type:t,id:h.id,text:h.text,risk:h.risk,verifyMethod:h.verifyMethod}),h={},u[e]),getRequirements:()=>u,setNewReqId:e=>{void 0!==h&&(h.id=e)},setNewReqText:e=>{void 0!==h&&(h.text=e)},setNewReqRisk:e=>{void 0!==h&&(h.risk=e)},setNewReqVerifyMethod:e=>{void 0!==h&&(h.verifyMethod=e)},setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addElement:e=>(void 0===y[e]&&(y[e]={name:e,type:d.type,docRef:d.docRef},n.l.info("Added new requirement: ",e)),d={},y[e]),getElements:()=>y,setNewElementType:e=>{void 0!==d&&(d.type=e)},setNewElementDocRef:e=>{void 0!==d&&(d.docRef=e)},addRelationship:(e,t,i)=>{o.push({type:e,src:t,dst:i})},getRelationships:()=>o,clear:()=>{o=[],h={},u={},d={},y={},(0,n.v)()}},_={CONTAINS:"contains",ARROW:"arrow"},g=_;let E={},R=0;const f=(e,t)=>e.insert("rect","#"+t).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",E.rect_min_width+"px").attr("height",E.rect_min_height+"px"),m=(e,t,i)=>{let n=E.rect_min_width/2,r=e.append("text").attr("class","req reqLabel reqTitle").attr("id",t).attr("x",n).attr("y",E.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((e=>{0==s?r.append("tspan").attr("text-anchor","middle").attr("x",E.rect_min_width/2).attr("dy",0).text(e):r.append("tspan").attr("text-anchor","middle").attr("x",E.rect_min_width/2).attr("dy",.75*E.line_height).text(e),s++}));let a=1.5*E.rect_padding+s*E.line_height*.75;return e.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",E.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:r,y:a}},I=(e,t,i,n)=>{let r=e.append("text").attr("class","req reqLabel").attr("id",t).attr("x",E.rect_padding).attr("y",n).attr("dominant-baseline","hanging"),s=0,a=[];return i.forEach((e=>{let t=e.length;for(;t>30&&s<3;){let i=e.substring(0,30);t=(e=e.substring(30,e.length)).length,a[a.length]=i,s++}if(3==s){let e=a[a.length-1];a[a.length-1]=e.substring(0,e.length-4)+"..."}else a[a.length]=e;s=0})),a.forEach((e=>{r.append("tspan").attr("x",E.rect_padding).attr("dy",E.line_height).text(e)})),r},b=e=>e.replace(/\s/g,"").replace(/\./g,"_"),k={parser:l,db:p,renderer:{draw:(e,t,i,c)=>{E=(0,n.c)().requirement;const l=E.securityLevel;let o;"sandbox"===l&&(o=(0,r.Ys)("#i"+t));const h=("sandbox"===l?(0,r.Ys)(o.nodes()[0].contentDocument.body):(0,r.Ys)("body")).select(`[id='${t}']`);((e,t)=>{let i=e.append("defs").append("marker").attr("id",_.CONTAINS+"_line_ending").attr("refX",0).attr("refY",t.line_height/2).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",t.line_height/2).attr("cy",t.line_height/2).attr("r",t.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",t.line_height).attr("y1",t.line_height/2).attr("y2",t.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",t.line_height).attr("x1",t.line_height/2).attr("x2",t.line_height/2).attr("stroke-width",1),e.append("defs").append("marker").attr("id",_.ARROW+"_line_ending").attr("refX",t.line_height).attr("refY",.5*t.line_height).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${t.line_height},${t.line_height/2}\n M${t.line_height},${t.line_height/2}\n L0,${t.line_height}`).attr("stroke-width",1)})(h,E);const u=new a.k({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:E.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let d=c.db.getRequirements(),y=c.db.getElements(),p=c.db.getRelationships();var k,S,T;k=d,S=u,T=h,Object.keys(k).forEach((e=>{let t=k[e];e=b(e),n.l.info("Added new requirement: ",e);const i=T.append("g").attr("id",e),r=f(i,"req-"+e);let s=m(i,e+"_title",[`<<${t.type}>>`,`${t.name}`]);I(i,e+"_body",[`Id: ${t.id}`,`Text: ${t.text}`,`Risk: ${t.risk}`,`Verification: ${t.verifyMethod}`],s.y);const a=r.node().getBBox();S.setNode(e,{width:a.width,height:a.height,shape:"rect",id:e})})),((e,t,i)=>{Object.keys(e).forEach((n=>{let r=e[n];const s=b(n),a=i.append("g").attr("id",s),c="element-"+s,l=f(a,c);let o=m(a,c+"_title",["<>",`${n}`]);I(a,c+"_body",[`Type: ${r.type||"Not Specified"}`,`Doc Ref: ${r.docRef||"None"}`],o.y);const h=l.node().getBBox();t.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(y,u,h),((e,t)=>{e.forEach((function(e){let i=b(e.src),n=b(e.dst);t.setEdge(i,n,{relationship:e})}))})(p,u),(0,s.bK)(u),function(e,t){t.nodes().forEach((function(i){void 0!==i&&void 0!==t.node(i)&&(e.select("#"+i),e.select("#"+i).attr("transform","translate("+(t.node(i).x-t.node(i).width/2)+","+(t.node(i).y-t.node(i).height/2)+" )"))}))}(h,u),p.forEach((function(e){!function(e,t,i,s,a){const c=i.edge(b(t.src),b(t.dst)),l=(0,r.jvg)().x((function(e){return e.x})).y((function(e){return e.y})),o=e.insert("path","#"+s).attr("class","er relationshipLine").attr("d",l(c.points)).attr("fill","none");t.type==a.db.Relationships.CONTAINS?o.attr("marker-start","url("+n.e.getUrl(E.arrowMarkerAbsolute)+"#"+t.type+"_line_ending)"):(o.attr("stroke-dasharray","10,7"),o.attr("marker-end","url("+n.e.getUrl(E.arrowMarkerAbsolute)+"#"+g.ARROW+"_line_ending)")),((e,t,i,n)=>{const r=t.node().getTotalLength(),s=t.node().getPointAtLength(.5*r),a="rel"+R;R++;const c=e.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(n).node().getBBox();e.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-c.width/2).attr("y",s.y-c.height/2).attr("width",c.width).attr("height",c.height).attr("fill","white").attr("fill-opacity","85%")})(e,o,0,`<<${t.type}>>`)}(h,e,u,t,c)}));const N=E.rect_padding,v=h.node().getBBox(),x=v.width+2*N,A=v.height+2*N;(0,n.i)(h,A,x,E.useMaxWidth),h.attr("viewBox",`${v.x-N} ${v.y-N} ${x} ${A}`)}},styles:e=>`\n\n marker {\n fill: ${e.relationColor};\n stroke: ${e.relationColor};\n }\n\n marker.cross {\n stroke: ${e.lineColor};\n }\n\n svg {\n font-family: ${e.fontFamily};\n font-size: ${e.fontSize};\n }\n\n .reqBox {\n fill: ${e.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${e.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${e.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${e.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${e.relationLabelColor};\n }\n\n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/361-f7cd601a.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/361-f7cd601a.chunk.min.js new file mode 100644 index 000000000..66b7d4746 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/361-f7cd601a.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[361],{5510:function(t,e,a){a.d(e,{diagram:function(){return mt}});var i=a(9339),r=a(7274),s=a(8252),n=a(7967),o=(a(7484),a(7856),function(){var t=function(t,e,a,i){for(a=a||{},i=t.length;i--;a[t[i]]=e);return a},e=[1,2],a=[1,3],i=[1,5],r=[1,7],s=[2,5],n=[1,15],o=[1,17],c=[1,19],l=[1,20],h=[1,22],d=[1,23],p=[1,24],g=[1,30],u=[1,31],x=[1,32],y=[1,33],m=[1,34],f=[1,35],b=[1,36],T=[1,37],E=[1,38],w=[1,39],_=[1,40],v=[1,41],P=[1,42],k=[1,44],L=[1,45],I=[1,46],M=[1,48],N=[1,49],A=[1,50],S=[1,51],O=[1,52],D=[1,53],R=[1,56],Y=[1,4,5,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,53,54,55,56,58,59,60,65,66,67,68,76,86],$=[4,5,22,56,58,59],C=[4,5,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,56,58,59,60,65,66,67,68,76,86],V=[4,5,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,55,56,58,59,60,65,66,67,68,76,86],B=[4,5,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,54,56,58,59,60,65,66,67,68,76,86],F=[4,5,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,53,56,58,59,60,65,66,67,68,76,86],W=[74,75,76],q=[1,133],z=[1,4,5,7,19,20,22,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,53,54,55,56,58,59,60,65,66,67,68,76,86],H={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,directive:6,SD:7,document:8,line:9,statement:10,box_section:11,box_line:12,participant_statement:13,openDirective:14,typeDirective:15,closeDirective:16,":":17,argDirective:18,create:19,box:20,restOfLine:21,end:22,signal:23,autonumber:24,NUM:25,off:26,activate:27,actor:28,deactivate:29,note_statement:30,links_statement:31,link_statement:32,properties_statement:33,details_statement:34,title:35,legacy_title:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,loop:42,rect:43,opt:44,alt:45,else_sections:46,par:47,par_sections:48,par_over:49,critical:50,option_sections:51,break:52,option:53,and:54,else:55,participant:56,AS:57,participant_actor:58,destroy:59,note:60,placement:61,text2:62,over:63,actor_pair:64,links:65,link:66,properties:67,details:68,spaceList:69,",":70,left_of:71,right_of:72,signaltype:73,"+":74,"-":75,ACTOR:76,SOLID_OPEN_ARROW:77,DOTTED_OPEN_ARROW:78,SOLID_ARROW:79,DOTTED_ARROW:80,SOLID_CROSS:81,DOTTED_CROSS:82,SOLID_POINT:83,DOTTED_POINT:84,TXT:85,open_directive:86,type_directive:87,arg_directive:88,close_directive:89,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",7:"SD",17:":",19:"create",20:"box",21:"restOfLine",22:"end",24:"autonumber",25:"NUM",26:"off",27:"activate",29:"deactivate",35:"title",36:"legacy_title",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"loop",43:"rect",44:"opt",45:"alt",47:"par",49:"par_over",50:"critical",52:"break",53:"option",54:"and",55:"else",56:"participant",57:"AS",58:"participant_actor",59:"destroy",60:"note",63:"over",65:"links",66:"link",67:"properties",68:"details",70:",",71:"left_of",72:"right_of",74:"+",75:"-",76:"ACTOR",77:"SOLID_OPEN_ARROW",78:"DOTTED_OPEN_ARROW",79:"SOLID_ARROW",80:"DOTTED_ARROW",81:"SOLID_CROSS",82:"DOTTED_CROSS",83:"SOLID_POINT",84:"DOTTED_POINT",85:"TXT",86:"open_directive",87:"type_directive",88:"arg_directive",89:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[11,0],[11,2],[12,2],[12,1],[12,1],[6,4],[6,6],[10,1],[10,2],[10,4],[10,2],[10,4],[10,3],[10,3],[10,2],[10,3],[10,3],[10,2],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,2],[10,2],[10,1],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,1],[51,1],[51,4],[48,1],[48,4],[46,1],[46,4],[13,5],[13,3],[13,5],[13,3],[13,3],[30,4],[30,4],[31,3],[32,3],[33,3],[34,3],[69,2],[69,1],[64,3],[64,1],[61,1],[61,1],[23,5],[23,5],[23,4],[28,1],[73,1],[73,1],[73,1],[73,1],[73,1],[73,1],[73,1],[73,1],[62,1],[14,1],[15,1],[18,1],[16,1]],performAction:function(t,e,a,i,r,s,n){var o=s.length-1;switch(r){case 4:return i.apply(s[o]),s[o];case 5:case 10:case 9:case 14:this.$=[];break;case 6:case 11:s[o-1].push(s[o]),this.$=s[o-1];break;case 7:case 8:case 12:case 13:case 66:this.$=s[o];break;case 18:s[o].type="createParticipant",this.$=s[o];break;case 19:s[o-1].unshift({type:"boxStart",boxData:i.parseBoxData(s[o-2])}),s[o-1].push({type:"boxEnd",boxText:s[o-2]}),this.$=s[o-1];break;case 21:this.$={type:"sequenceIndex",sequenceIndex:Number(s[o-2]),sequenceIndexStep:Number(s[o-1]),sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"sequenceIndex",sequenceIndex:Number(s[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 23:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:i.LINETYPE.AUTONUMBER};break;case 24:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 25:this.$={type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:s[o-1]};break;case 26:this.$={type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:s[o-1]};break;case 32:i.setDiagramTitle(s[o].substring(6)),this.$=s[o].substring(6);break;case 33:i.setDiagramTitle(s[o].substring(7)),this.$=s[o].substring(7);break;case 34:this.$=s[o].trim(),i.setAccTitle(this.$);break;case 35:case 36:this.$=s[o].trim(),i.setAccDescription(this.$);break;case 37:s[o-1].unshift({type:"loopStart",loopText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.LOOP_START}),s[o-1].push({type:"loopEnd",loopText:s[o-2],signalType:i.LINETYPE.LOOP_END}),this.$=s[o-1];break;case 38:s[o-1].unshift({type:"rectStart",color:i.parseMessage(s[o-2]),signalType:i.LINETYPE.RECT_START}),s[o-1].push({type:"rectEnd",color:i.parseMessage(s[o-2]),signalType:i.LINETYPE.RECT_END}),this.$=s[o-1];break;case 39:s[o-1].unshift({type:"optStart",optText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.OPT_START}),s[o-1].push({type:"optEnd",optText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.OPT_END}),this.$=s[o-1];break;case 40:s[o-1].unshift({type:"altStart",altText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.ALT_START}),s[o-1].push({type:"altEnd",signalType:i.LINETYPE.ALT_END}),this.$=s[o-1];break;case 41:s[o-1].unshift({type:"parStart",parText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.PAR_START}),s[o-1].push({type:"parEnd",signalType:i.LINETYPE.PAR_END}),this.$=s[o-1];break;case 42:s[o-1].unshift({type:"parStart",parText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.PAR_OVER_START}),s[o-1].push({type:"parEnd",signalType:i.LINETYPE.PAR_END}),this.$=s[o-1];break;case 43:s[o-1].unshift({type:"criticalStart",criticalText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.CRITICAL_START}),s[o-1].push({type:"criticalEnd",signalType:i.LINETYPE.CRITICAL_END}),this.$=s[o-1];break;case 44:s[o-1].unshift({type:"breakStart",breakText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.BREAK_START}),s[o-1].push({type:"breakEnd",optText:i.parseMessage(s[o-2]),signalType:i.LINETYPE.BREAK_END}),this.$=s[o-1];break;case 47:this.$=s[o-3].concat([{type:"option",optionText:i.parseMessage(s[o-1]),signalType:i.LINETYPE.CRITICAL_OPTION},s[o]]);break;case 49:this.$=s[o-3].concat([{type:"and",parText:i.parseMessage(s[o-1]),signalType:i.LINETYPE.PAR_AND},s[o]]);break;case 51:this.$=s[o-3].concat([{type:"else",altText:i.parseMessage(s[o-1]),signalType:i.LINETYPE.ALT_ELSE},s[o]]);break;case 52:s[o-3].draw="participant",s[o-3].type="addParticipant",s[o-3].description=i.parseMessage(s[o-1]),this.$=s[o-3];break;case 53:s[o-1].draw="participant",s[o-1].type="addParticipant",this.$=s[o-1];break;case 54:s[o-3].draw="actor",s[o-3].type="addParticipant",s[o-3].description=i.parseMessage(s[o-1]),this.$=s[o-3];break;case 55:s[o-1].draw="actor",s[o-1].type="addParticipant",this.$=s[o-1];break;case 56:s[o-1].type="destroyParticipant",this.$=s[o-1];break;case 57:this.$=[s[o-1],{type:"addNote",placement:s[o-2],actor:s[o-1].actor,text:s[o]}];break;case 58:s[o-2]=[].concat(s[o-1],s[o-1]).slice(0,2),s[o-2][0]=s[o-2][0].actor,s[o-2][1]=s[o-2][1].actor,this.$=[s[o-1],{type:"addNote",placement:i.PLACEMENT.OVER,actor:s[o-2].slice(0,2),text:s[o]}];break;case 59:this.$=[s[o-1],{type:"addLinks",actor:s[o-1].actor,text:s[o]}];break;case 60:this.$=[s[o-1],{type:"addALink",actor:s[o-1].actor,text:s[o]}];break;case 61:this.$=[s[o-1],{type:"addProperties",actor:s[o-1].actor,text:s[o]}];break;case 62:this.$=[s[o-1],{type:"addDetails",actor:s[o-1].actor,text:s[o]}];break;case 65:this.$=[s[o-2],s[o]];break;case 67:this.$=i.PLACEMENT.LEFTOF;break;case 68:this.$=i.PLACEMENT.RIGHTOF;break;case 69:this.$=[s[o-4],s[o-1],{type:"addMessage",from:s[o-4].actor,to:s[o-1].actor,signalType:s[o-3],msg:s[o]},{type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:s[o-1]}];break;case 70:this.$=[s[o-4],s[o-1],{type:"addMessage",from:s[o-4].actor,to:s[o-1].actor,signalType:s[o-3],msg:s[o]},{type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:s[o-4]}];break;case 71:this.$=[s[o-3],s[o-1],{type:"addMessage",from:s[o-3].actor,to:s[o-1].actor,signalType:s[o-2],msg:s[o]}];break;case 72:this.$={type:"addParticipant",actor:s[o]};break;case 73:this.$=i.LINETYPE.SOLID_OPEN;break;case 74:this.$=i.LINETYPE.DOTTED_OPEN;break;case 75:this.$=i.LINETYPE.SOLID;break;case 76:this.$=i.LINETYPE.DOTTED;break;case 77:this.$=i.LINETYPE.SOLID_CROSS;break;case 78:this.$=i.LINETYPE.DOTTED_CROSS;break;case 79:this.$=i.LINETYPE.SOLID_POINT;break;case 80:this.$=i.LINETYPE.DOTTED_POINT;break;case 81:this.$=i.parseMessage(s[o].trim().substring(1));break;case 82:i.parseDirective("%%{","open_directive");break;case 83:i.parseDirective(s[o],"type_directive");break;case 84:s[o]=s[o].trim().replace(/'/g,'"'),i.parseDirective(s[o],"arg_directive");break;case 85:i.parseDirective("}%%","close_directive","sequence")}},table:[{3:1,4:e,5:a,6:4,7:i,14:6,86:r},{1:[3]},{3:8,4:e,5:a,6:4,7:i,14:6,86:r},{3:9,4:e,5:a,6:4,7:i,14:6,86:r},{3:10,4:e,5:a,6:4,7:i,14:6,86:r},t([1,4,5,19,20,24,27,29,35,36,37,39,41,42,43,44,45,47,49,50,52,56,58,59,60,65,66,67,68,76,86],s,{8:11}),{15:12,87:[1,13]},{87:[2,82]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{16:54,17:[1,55],89:R},t([17,89],[2,83]),t(Y,[2,6]),{6:43,10:57,13:18,14:6,19:c,20:l,23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},t(Y,[2,8]),t(Y,[2,9]),t(Y,[2,17]),{13:58,56:k,58:L,59:I},{21:[1,59]},{5:[1,60]},{5:[1,63],25:[1,61],26:[1,62]},{28:64,76:D},{28:65,76:D},{5:[1,66]},{5:[1,67]},{5:[1,68]},{5:[1,69]},{5:[1,70]},t(Y,[2,32]),t(Y,[2,33]),{38:[1,71]},{40:[1,72]},t(Y,[2,36]),{21:[1,73]},{21:[1,74]},{21:[1,75]},{21:[1,76]},{21:[1,77]},{21:[1,78]},{21:[1,79]},{21:[1,80]},t(Y,[2,45]),{28:81,76:D},{28:82,76:D},{28:83,76:D},{73:84,77:[1,85],78:[1,86],79:[1,87],80:[1,88],81:[1,89],82:[1,90],83:[1,91],84:[1,92]},{61:93,63:[1,94],71:[1,95],72:[1,96]},{28:97,76:D},{28:98,76:D},{28:99,76:D},{28:100,76:D},t([5,57,70,77,78,79,80,81,82,83,84,85],[2,72]),{5:[1,101]},{18:102,88:[1,103]},{5:[2,85]},t(Y,[2,7]),t(Y,[2,18]),t($,[2,10],{11:104}),t(Y,[2,20]),{5:[1,106],25:[1,105]},{5:[1,107]},t(Y,[2,24]),{5:[1,108]},{5:[1,109]},t(Y,[2,27]),t(Y,[2,28]),t(Y,[2,29]),t(Y,[2,30]),t(Y,[2,31]),t(Y,[2,34]),t(Y,[2,35]),t(C,s,{8:110}),t(C,s,{8:111}),t(C,s,{8:112}),t(V,s,{46:113,8:114}),t(B,s,{48:115,8:116}),t(B,s,{8:116,48:117}),t(F,s,{51:118,8:119}),t(C,s,{8:120}),{5:[1,122],57:[1,121]},{5:[1,124],57:[1,123]},{5:[1,125]},{28:128,74:[1,126],75:[1,127],76:D},t(W,[2,73]),t(W,[2,74]),t(W,[2,75]),t(W,[2,76]),t(W,[2,77]),t(W,[2,78]),t(W,[2,79]),t(W,[2,80]),{28:129,76:D},{28:131,64:130,76:D},{76:[2,67]},{76:[2,68]},{62:132,85:q},{62:134,85:q},{62:135,85:q},{62:136,85:q},t(z,[2,15]),{16:137,89:R},{89:[2,84]},{4:[1,140],5:[1,142],12:139,13:141,22:[1,138],56:k,58:L,59:I},{5:[1,143]},t(Y,[2,22]),t(Y,[2,23]),t(Y,[2,25]),t(Y,[2,26]),{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[1,144],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[1,145],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[1,146],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{22:[1,147]},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[2,50],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,55:[1,148],56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{22:[1,149]},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[2,48],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,54:[1,150],56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{22:[1,151]},{22:[1,152]},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[2,46],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,53:[1,153],56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{4:n,5:o,6:43,9:14,10:16,13:18,14:6,19:c,20:l,22:[1,154],23:21,24:h,27:d,28:47,29:p,30:25,31:26,32:27,33:28,34:29,35:g,36:u,37:x,39:y,41:m,42:f,43:b,44:T,45:E,47:w,49:_,50:v,52:P,56:k,58:L,59:I,60:M,65:N,66:A,67:S,68:O,76:D,86:r},{21:[1,155]},t(Y,[2,53]),{21:[1,156]},t(Y,[2,55]),t(Y,[2,56]),{28:157,76:D},{28:158,76:D},{62:159,85:q},{62:160,85:q},{62:161,85:q},{70:[1,162],85:[2,66]},{5:[2,59]},{5:[2,81]},{5:[2,60]},{5:[2,61]},{5:[2,62]},{5:[1,163]},t(Y,[2,19]),t($,[2,11]),{13:164,56:k,58:L,59:I},t($,[2,13]),t($,[2,14]),t(Y,[2,21]),t(Y,[2,37]),t(Y,[2,38]),t(Y,[2,39]),t(Y,[2,40]),{21:[1,165]},t(Y,[2,41]),{21:[1,166]},t(Y,[2,42]),t(Y,[2,43]),{21:[1,167]},t(Y,[2,44]),{5:[1,168]},{5:[1,169]},{62:170,85:q},{62:171,85:q},{5:[2,71]},{5:[2,57]},{5:[2,58]},{28:172,76:D},t(z,[2,16]),t($,[2,12]),t(V,s,{8:114,46:173}),t(B,s,{8:116,48:174}),t(F,s,{8:119,51:175}),t(Y,[2,52]),t(Y,[2,54]),{5:[2,69]},{5:[2,70]},{85:[2,65]},{22:[2,51]},{22:[2,49]},{22:[2,47]}],defaultActions:{7:[2,82],8:[2,1],9:[2,2],10:[2,3],56:[2,85],95:[2,67],96:[2,68],103:[2,84],132:[2,59],133:[2,81],134:[2,60],135:[2,61],136:[2,62],159:[2,71],160:[2,57],161:[2,58],170:[2,69],171:[2,70],172:[2,65],173:[2,51],174:[2,49],175:[2,47]},parseError:function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},parse:function(t){var e=[0],a=[],i=[null],r=[],s=this.table,n="",o=0,c=0,l=r.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);h.setInput(t,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var g=h.yylloc;r.push(g);var u=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,y,m,f,b,T,E,w,_,v={};;){if(y=e[e.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==x&&(_=void 0,"number"!=typeof(_=a.pop()||h.lex()||1)&&(_ instanceof Array&&(_=(a=_).pop()),_=this.symbols_[_]||_),x=_),m=s[y]&&s[y][x]),void 0===m||!m.length||!m[0]){var P;for(b in w=[],s[y])this.terminals_[b]&&b>2&&w.push("'"+this.terminals_[b]+"'");P=h.showPosition?"Parse error on line "+(o+1)+":\n"+h.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==x?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(P,{text:h.match,token:this.terminals_[x]||x,line:h.yylineno,loc:g,expected:w})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+x);switch(m[0]){case 1:e.push(x),i.push(h.yytext),r.push(h.yylloc),e.push(m[1]),x=null,c=h.yyleng,n=h.yytext,o=h.yylineno,g=h.yylloc;break;case 2:if(T=this.productions_[m[1]][1],v.$=i[i.length-T],v._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},u&&(v._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(f=this.performAction.apply(v,[n,c,o,d.yy,m[1],i,r].concat(l))))return f;T&&(e=e.slice(0,-1*T*2),i=i.slice(0,-1*T),r=r.slice(0,-1*T)),e.push(this.productions_[m[1]][0]),i.push(v.$),r.push(v._$),E=s[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},U={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===i.length?this.yylloc.first_column:0)+i[i.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var a,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;se[0].length)){if(e=a,i=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,i){switch(a){case 0:return this.begin("open_directive"),86;case 1:return this.begin("type_directive"),87;case 2:return this.popState(),this.begin("arg_directive"),17;case 3:return this.popState(),this.popState(),89;case 4:return 88;case 5:case 56:case 69:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return 25;case 12:return this.begin("LINE"),20;case 13:return this.begin("ID"),56;case 14:return this.begin("ID"),58;case 15:return 19;case 16:return this.begin("ID"),59;case 17:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),76;case 18:return this.popState(),this.popState(),this.begin("LINE"),57;case 19:return this.popState(),this.popState(),5;case 20:return this.begin("LINE"),42;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),44;case 23:return this.begin("LINE"),45;case 24:return this.begin("LINE"),55;case 25:return this.begin("LINE"),47;case 26:return this.begin("LINE"),49;case 27:return this.begin("LINE"),54;case 28:return this.begin("LINE"),50;case 29:return this.begin("LINE"),53;case 30:return this.begin("LINE"),52;case 31:return this.popState(),21;case 32:return 22;case 33:return 71;case 34:return 72;case 35:return 65;case 36:return 66;case 37:return 67;case 38:return 68;case 39:return 63;case 40:return 60;case 41:return this.begin("ID"),27;case 42:return this.begin("ID"),29;case 43:return 35;case 44:return 36;case 45:return this.begin("acc_title"),37;case 46:return this.popState(),"acc_title_value";case 47:return this.begin("acc_descr"),39;case 48:return this.popState(),"acc_descr_value";case 49:this.begin("acc_descr_multiline");break;case 50:this.popState();break;case 51:return"acc_descr_multiline_value";case 52:return 7;case 53:return 24;case 54:return 26;case 55:return 70;case 57:return e.yytext=e.yytext.trim(),76;case 58:return 79;case 59:return 80;case 60:return 77;case 61:return 78;case 62:return 81;case 63:return 82;case 64:return 83;case 65:return 84;case 66:return 85;case 67:return 74;case 68:return 75;case 70:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[50,51],inclusive:!1},acc_descr:{rules:[48],inclusive:!1},acc_title:{rules:[46],inclusive:!1},open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,17],inclusive:!1},ALIAS:{rules:[7,8,18,19],inclusive:!1},LINE:{rules:[7,8,31],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,12,13,14,15,16,20,21,22,23,24,25,26,27,28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,47,49,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70],inclusive:!0}}};function j(){this.yy={}}return H.lexer=U,j.prototype=H,H.Parser=j,new j}());o.parser=o;const c=o;let l,h,d,p,g,u={},x={},y={},m=[],f=[],b=!1;const T=function(t,e,a,i){let r=d;const s=u[t];if(s){if(d&&s.box&&d!==s.box)throw new Error("A same participant should only be defined in one Box: "+s.name+" can't be in '"+s.box.name+"' and in '"+d.name+"' at the same time.");if(r=s.box?s.box:d,s.box=r,s&&e===s.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:i}),null!=i&&null!=a.text||(a={text:e,wrap:null,type:i}),u[t]={box:r,name:e,description:a.text,wrap:void 0===a.wrap&&_()||!!a.wrap,prevActor:l,links:{},properties:{},actorCnt:null,rectData:null,type:i||"participant"},l&&u[l]&&(u[l].nextActor=t),d&&d.actorKeys.push(t),l=t},E=function(t,e,a={text:void 0,wrap:void 0},i){if(i===v.ACTIVE_END&&(t=>{let e,a=0;for(e=0;e>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}return f.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&_()||!!a.wrap,type:i}),!0},w=function(t){return u[t]},_=()=>void 0!==h?h:(0,i.c)().sequence.wrap,v={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},P=function(t,e,a){a.text,void 0===a.wrap&&_()||a.wrap;const i=[].concat(t,t);f.push({from:i[0],to:i[1],message:a.text,wrap:void 0===a.wrap&&_()||!!a.wrap,type:v.NOTE,placement:e})},k=function(t,e){const a=w(t);try{let t=(0,i.d)(e.text,(0,i.c)());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"="),L(a,JSON.parse(t))}catch(t){i.l.error("error while parsing actor link text",t)}};function L(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const I=function(t,e){const a=w(t);try{let t=(0,i.d)(e.text,(0,i.c)());M(a,JSON.parse(t))}catch(t){i.l.error("error while parsing actor properties text",t)}};function M(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const N=function(t,e){const a=w(t),r=document.getElementById(e.text);try{const t=r.innerHTML,e=JSON.parse(t);e.properties&&M(a,e.properties),e.links&&L(a,e.links)}catch(t){i.l.error("error while parsing actor details text",t)}},A=function(t){if(Array.isArray(t))t.forEach((function(t){A(t)}));else switch(t.type){case"sequenceIndex":f.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":T(t.actor,t.actor,t.description,t.draw);break;case"createParticipant":if(u[t.actor])throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");p=t.actor,T(t.actor,t.actor,t.description,t.draw),x[t.actor]=f.length;break;case"destroyParticipant":g=t.actor,y[t.actor]=f.length;break;case"activeStart":case"activeEnd":E(t.actor,void 0,void 0,t.signalType);break;case"addNote":P(t.actor,t.placement,t.text);break;case"addLinks":k(t.actor,t.text);break;case"addALink":!function(t,e){const a=w(t);try{const t={};let o=(0,i.d)(e.text,(0,i.c)());var r=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var s=o.slice(0,r-1).trim(),n=o.slice(r+1).trim();t[s]=n,L(a,t)}catch(t){i.l.error("error while parsing actor link text",t)}}(t.actor,t.text);break;case"addProperties":I(t.actor,t.text);break;case"addDetails":N(t.actor,t.text);break;case"addMessage":if(p){if(t.to!==p)throw new Error("The created participant "+p+" does not have an associated creating message after its declaration. Please check the sequence diagram.");p=void 0}else if(g){if(t.to!==g&&t.from!==g)throw new Error("The destroyed participant "+g+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");g=void 0}E(t.from,t.to,t.msg,t.signalType);break;case"boxStart":e=t.boxData,m.push({name:e.text,wrap:void 0===e.wrap&&_()||!!e.wrap,fill:e.color,actorKeys:[]}),d=m.slice(-1)[0];break;case"boxEnd":d=void 0;break;case"loopStart":E(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":E(void 0,void 0,void 0,t.signalType);break;case"rectStart":E(void 0,void 0,t.color,t.signalType);break;case"optStart":E(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":E(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,i.s)(t.text);break;case"parStart":case"and":E(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":E(void 0,void 0,t.criticalText,t.signalType);break;case"option":E(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":E(void 0,void 0,t.breakText,t.signalType)}var e},S={addActor:T,addMessage:function(t,e,a,i){f.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&_()||!!a.wrap,answer:i})},addSignal:E,addLinks:k,addDetails:N,addProperties:I,autoWrap:_,setWrap:function(t){h=t},enableSequenceNumbers:function(){b=!0},disableSequenceNumbers:function(){b=!1},showSequenceNumbers:()=>b,getMessages:function(){return f},getActors:function(){return u},getCreatedActors:function(){return x},getDestroyedActors:function(){return y},getActor:w,getActorKeys:function(){return Object.keys(u)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:i.g,getBoxes:function(){return m},getDiagramTitle:i.t,setDiagramTitle:i.r,parseDirective:function(t,e,a){i.m.parseDirective(this,t,e,a)},getConfig:()=>(0,i.c)().sequence,clear:function(){u={},x={},y={},m=[],f=[],b=!1,(0,i.v)()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return i.l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",r=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",r=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",r=t.trim())}return{color:a,text:void 0!==r?(0,i.d)(r.replace(/^:?(?:no)?wrap:/,""),(0,i.c)()):void 0,wrap:void 0!==r?null!==r.match(/^:?wrap:/)||null===r.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:v,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:P,setAccTitle:i.s,apply:A,setAccDescription:i.b,getAccDescription:i.a,hasAtLeastOneBox:function(){return m.length>0},hasAtLeastOneBoxWithTitle:function(){return m.some((t=>t.name))}},O=function(t,e){return(0,s.d)(t,e)},D=(t,e)=>{(0,i.H)((()=>{const a=document.querySelectorAll(t);0!==a.length&&(a[0].addEventListener("mouseover",(function(){R("actor"+e+"_popup")})),a[0].addEventListener("mouseout",(function(){Y("actor"+e+"_popup")})))}))},R=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="block")},Y=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="none")},$=function(t,e){let a=0,r=0;const s=e.text.split(i.e.lineBreakRegex),[n,o]=(0,i.F)(e.fontSize);let c=[],l=0,h=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":h=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":h=()=>Math.round(e.y+(a+r+e.textMargin)/2);break;case"bottom":case"end":h=()=>Math.round(e.y+(a+r+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[d,p]of s.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(l=d*n);const s=t.append("text");s.attr("x",e.x),s.attr("y",h()),void 0!==e.anchor&&s.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&s.style("font-family",e.fontFamily),void 0!==o&&s.style("font-size",o),void 0!==e.fontWeight&&s.style("font-weight",e.fontWeight),void 0!==e.fill&&s.attr("fill",e.fill),void 0!==e.class&&s.attr("class",e.class),void 0!==e.dy?s.attr("dy",e.dy):0!==l&&s.attr("dy",l);const g=p||i.Z;if(e.tspan){const t=s.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else s.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(r+=(s._groups||s)[0][0].getBBox().height,a=r),c.push(s)}return c},C=function(t,e){const a=t.append("polygon");var i,r,s,n;return a.attr("points",(i=e.x)+","+(r=e.y)+" "+(i+(s=e.width))+","+r+" "+(i+s)+","+(r+(n=e.height)-7)+" "+(i+s-8.4)+","+(r+n)+" "+i+","+(r+n)),a.attr("class","labelBox"),e.y=e.y+e.height/2,$(t,e),a};let V=-1;const B=(t,e,a,i)=>{t.select&&a.forEach((a=>{const r=e[a],s=t.select("#actor"+r.actorCnt);!i.mirrorActors&&r.stopy?s.attr("y2",r.stopy+r.height/2):i.mirrorActors&&s.attr("y2",r.stopy)}))},F=function(t,e){(0,s.a)(t,e)},W=function(){function t(t,e,a,i,s,n,o){r(e.append("text").attr("x",a+s/2).attr("y",i+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,s,n,o,c,l){const{actorFontSize:h,actorFontFamily:d,actorFontWeight:p}=l,[g,u]=(0,i.F)(h),x=t.split(i.e.lineBreakRegex);for(let t=0;ta?c.width:a;const g=h.append("rect");if(g.attr("class","actorPopupMenuPanel"+d),g.attr("x",c.x),g.attr("y",c.height),g.attr("fill",c.fill),g.attr("stroke",c.stroke),g.attr("width",p),g.attr("height",c.height),g.attr("rx",c.rx),g.attr("ry",c.ry),null!=s){var u=20;for(let t in s){var x=h.append("a"),y=(0,n.Nm)(s[t]);x.attr("xlink:href",y),x.attr("target","_blank"),q(i)(t,x,c.x+10,c.height+u,p,20,{class:"actor"},i),u+=30}}return g.attr("height",u),{height:c.height+u,width:p}},K=function(t){return t.append("g")},X=function(t,e,a,i,r){const n=(0,s.g)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+r%3,n.width=e.stopx-e.startx,n.height=a-e.starty,O(o,n)},G=function(t,e,a,i){const{boxMargin:r,boxTextMargin:n,labelBoxHeight:o,labelBoxWidth:c,messageFontFamily:l,messageFontSize:h,messageFontWeight:d}=i,p=t.append("g"),g=function(t,e,a,i){return p.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",i).attr("class","loopLine")};g(e.startx,e.starty,e.stopx,e.starty),g(e.stopx,e.starty,e.stopx,e.stopy),g(e.startx,e.stopy,e.stopx,e.stopy),g(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){g(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let u=(0,s.e)();u.text=a,u.x=e.startx,u.y=e.starty,u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.anchor="middle",u.valign="middle",u.tspan=!1,u.width=c||50,u.height=o||20,u.textMargin=n,u.class="labelText",C(p,u),u={x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0},u.text=e.title,u.x=e.startx+c/2+(e.stopx-e.startx)/2,u.y=e.starty+r+n,u.anchor="middle",u.valign="middle",u.textMargin=n,u.class="loopText",u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.wrap=!0;let x=$(p,u);return void 0!==e.sectionTitles&&e.sectionTitles.forEach((function(t,a){if(t.message){u.text=t.message,u.x=e.startx+(e.stopx-e.startx)/2,u.y=e.sections[a].y+r+n,u.class="loopText",u.anchor="middle",u.valign="middle",u.tspan=!1,u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.wrap=e.wrap,x=$(p,u);let i=Math.round(x.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[a].height+=i-(r+n)}})),e.height=Math.round(e.stopy-e.starty),p},J=F,Z=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},Q=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},tt=function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},et=function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},at=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},it=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},rt=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};n.Nm;let st={};const nt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,pt((0,i.c)())},updateVal:function(t,e,a,i){void 0===t[e]?t[e]=a:t[e]=i(a,t[e])},updateBounds:function(t,e,a,i){const r=this;let s=0;function n(n){return function(o){s++;const c=r.sequenceItems.length-s+1;r.updateVal(o,"starty",e-c*st.boxMargin,Math.min),r.updateVal(o,"stopy",i+c*st.boxMargin,Math.max),r.updateVal(nt.data,"startx",t-c*st.boxMargin,Math.min),r.updateVal(nt.data,"stopx",a+c*st.boxMargin,Math.max),"activation"!==n&&(r.updateVal(o,"startx",t-c*st.boxMargin,Math.min),r.updateVal(o,"stopx",a+c*st.boxMargin,Math.max),r.updateVal(nt.data,"starty",e-c*st.boxMargin,Math.min),r.updateVal(nt.data,"stopy",i+c*st.boxMargin,Math.max))}}this.sequenceItems.forEach(n()),this.activations.forEach(n("activation"))},insert:function(t,e,a,r){const s=i.e.getMin(t,a),n=i.e.getMax(t,a),o=i.e.getMin(e,r),c=i.e.getMax(e,r);this.updateVal(nt.data,"startx",s,Math.min),this.updateVal(nt.data,"starty",o,Math.min),this.updateVal(nt.data,"stopx",n,Math.max),this.updateVal(nt.data,"stopy",c,Math.max),this.updateBounds(s,o,n,c)},newActivation:function(t,e,a){const i=a[t.from.actor],r=gt(t.from.actor).length||0,s=i.x+i.width/2+(r-1)*st.activationWidth/2;this.activations.push({startx:s,starty:this.verticalPos+2,stopx:s+st.activationWidth,stopy:void 0,actor:t.from.actor,anchored:K(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:nt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=i.e.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},ot=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),ct=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),lt=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight}),ht=function(t,e,a,r){if(r){let r=0;nt.bumpVerticalPos(2*st.boxMargin);for(const s of a){const a=e[s];a.stopy||(a.stopy=nt.getVerticalPos());const n=H(t,a,st,!0);r=i.e.getMax(r,n)}nt.bumpVerticalPos(r+st.boxMargin)}else for(const i of a){const a=e[i];H(t,a,st,!1)}},dt=function(t,e,a,i){let r=0,s=0;for(const n of a){const a=e[n],o=yt(a),c=j(t,a,o,st,st.forceMenus,i);c.height>r&&(r=c.height),c.width+a.x>s&&(s=c.width+a.x)}return{maxHeight:r,maxWidth:s}},pt=function(t){(0,i.f)(st,t),t.fontFamily&&(st.actorFontFamily=st.noteFontFamily=st.messageFontFamily=t.fontFamily),t.fontSize&&(st.actorFontSize=st.noteFontSize=st.messageFontSize=t.fontSize),t.fontWeight&&(st.actorFontWeight=st.noteFontWeight=st.messageFontWeight=t.fontWeight)},gt=function(t){return nt.activations.filter((function(e){return e.actor===t}))},ut=function(t,e){const a=e[t],r=gt(t);return[r.reduce((function(t,e){return i.e.getMin(t,e.startx)}),a.x+a.width/2),r.reduce((function(t,e){return i.e.getMax(t,e.stopx)}),a.x+a.width/2)]};function xt(t,e,a,r,s){nt.bumpVerticalPos(a);let n=r;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,s=ot(st);e.message=i.u.wrapLabel(`[${e.message}]`,a-2*st.wrapPadding,s),e.width=a,e.wrap=!0;const o=i.u.calculateTextDimensions(e.message,s),c=i.e.getMax(o.height,st.labelBoxHeight);n=r+c,i.l.debug(`${c} - ${e.message}`)}s(e),nt.bumpVerticalPos(n)}const yt=function(t){let e=0;const a=lt(st);for(const r in t.links){const t=i.u.calculateTextDimensions(r,a).width+2*st.wrapPadding+2*st.boxMargin;e{const a=t[e];a.wrap&&(a.description=i.u.wrapLabel(a.description,st.width-2*st.wrapPadding,lt(st)));const s=i.u.calculateTextDimensions(a.description,lt(st));a.width=a.wrap?st.width:i.e.getMax(st.width,s.width+2*st.wrapPadding),a.height=a.wrap?i.e.getMax(s.height,st.height):st.height,r=i.e.getMax(r,a.height)}));for(const a in e){const r=t[a];if(!r)continue;const s=t[r.nextActor];if(!s){const t=e[a]+st.actorMargin-r.width/2;r.margin=i.e.getMax(t,st.actorMargin);continue}const n=e[a]+st.actorMargin-r.width/2-s.width/2;r.margin=i.e.getMax(n,st.actorMargin)}let s=0;return a.forEach((e=>{const a=ot(st);let r=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);r-=2*st.boxTextMargin,e.wrap&&(e.name=i.u.wrapLabel(e.name,r-2*st.wrapPadding,a));const n=i.u.calculateTextDimensions(e.name,a);s=i.e.getMax(n.height,s);const o=i.e.getMax(r,n.width+2*st.wrapPadding);if(e.margin=st.boxTextMargin,rt.textMaxHeight=s)),i.e.getMax(r,st.height)}(g,w,y),it(p),at(p),rt(p),T&&(nt.bumpVerticalPos(st.boxMargin),E&&nt.bumpVerticalPos(y[0].textMaxHeight)),!0===st.hideUnusedParticipants){const t=new Set;f.forEach((e=>{t.add(e.from),t.add(e.to)})),m=m.filter((e=>t.has(e)))}!function(t,e,a,r,s,n,o){let c,l=0,h=0,d=0;for(const t of r){const r=e[t],s=r.box;c&&c!=s&&(nt.models.addBox(c),h+=st.boxMargin+c.margin),s&&s!=c&&(s.x=l+h,s.y=0,h+=s.margin),r.width=r.width||st.width,r.height=i.e.getMax(r.height||st.height,st.height),r.margin=r.margin||st.actorMargin,d=i.e.getMax(d,r.height),a[r.name]&&(h+=r.width/2),r.x=l+h,r.starty=nt.getVerticalPos(),nt.insert(r.x,0,r.x+r.width,r.height),l+=r.width+h,r.box&&(r.box.width=l+s.margin-r.box.x),h=r.margin,c=r.box,nt.models.addActor(r)}c&&nt.models.addBox(c),nt.bumpVerticalPos(d)}(0,g,u,m);const _=function(t,e,a,r){const s={},n=[];let o,c,l;return t.forEach((function(t){switch(t.id=i.u.random({length:10}),t.type){case r.db.LINETYPE.LOOP_START:case r.db.LINETYPE.ALT_START:case r.db.LINETYPE.OPT_START:case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:case r.db.LINETYPE.CRITICAL_START:case r.db.LINETYPE.BREAK_START:n.push({id:t.id,msg:t.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case r.db.LINETYPE.ALT_ELSE:case r.db.LINETYPE.PAR_AND:case r.db.LINETYPE.CRITICAL_OPTION:t.message&&(o=n.pop(),s[o.id]=o,s[t.id]=o,n.push(o));break;case r.db.LINETYPE.LOOP_END:case r.db.LINETYPE.ALT_END:case r.db.LINETYPE.OPT_END:case r.db.LINETYPE.PAR_END:case r.db.LINETYPE.CRITICAL_END:case r.db.LINETYPE.BREAK_END:o=n.pop(),s[o.id]=o;break;case r.db.LINETYPE.ACTIVE_START:{const a=e[t.from?t.from.actor:t.to.actor],i=gt(t.from?t.from.actor:t.to.actor).length,r=a.x+a.width/2+(i-1)*st.activationWidth/2,s={startx:r,stopx:r+st.activationWidth,actor:t.from.actor,enabled:!0};nt.activations.push(s)}break;case r.db.LINETYPE.ACTIVE_END:{const e=nt.activations.map((t=>t.actor)).lastIndexOf(t.from.actor);delete nt.activations.splice(e,1)[0]}}void 0!==t.placement?(c=function(t,e,a){const r=e[t.from].x,s=e[t.to].x,n=t.wrap&&t.message;let o=i.u.calculateTextDimensions(n?i.u.wrapLabel(t.message,st.width,ct(st)):t.message,ct(st));const c={width:n?st.width:i.e.getMax(st.width,o.width+2*st.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(c.width=n?i.e.getMax(st.width,o.width):i.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*st.noteMargin),c.startx=r+(e[t.from].width+st.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(c.width=n?i.e.getMax(st.width,o.width+2*st.noteMargin):i.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*st.noteMargin),c.startx=r-c.width+(e[t.from].width-st.actorMargin)/2):t.to===t.from?(o=i.u.calculateTextDimensions(n?i.u.wrapLabel(t.message,i.e.getMax(st.width,e[t.from].width),ct(st)):t.message,ct(st)),c.width=n?i.e.getMax(st.width,e[t.from].width):i.e.getMax(e[t.from].width,st.width,o.width+2*st.noteMargin),c.startx=r+(e[t.from].width-c.width)/2):(c.width=Math.abs(r+e[t.from].width/2-(s+e[t.to].width/2))+st.actorMargin,c.startx=r{o=t,o.from=i.e.getMin(o.from,c.startx),o.to=i.e.getMax(o.to,c.startx+c.width),o.width=i.e.getMax(o.width,Math.abs(o.from-o.to))-st.labelBoxWidth}))):(l=function(t,e,a){let r=!1;if([a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(r=!0),!r)return{};const s=ut(t.from,e),n=ut(t.to,e),o=s[0]<=n[0]?1:0,c=s[0]0&&n.forEach((a=>{if(o=a,l.startx===l.stopx){const a=e[t.from],r=e[t.to];o.from=i.e.getMin(a.x-l.width/2,a.x-a.width/2,o.from),o.to=i.e.getMax(r.x+l.width/2,r.x+a.width/2,o.to),o.width=i.e.getMax(o.width,Math.abs(o.to-o.from))-st.labelBoxWidth}else o.from=i.e.getMin(l.startx,o.from),o.to=i.e.getMax(l.stopx,o.to),o.width=i.e.getMax(o.width,l.width)-st.labelBoxWidth})))})),nt.activations=[],i.l.debug("Loop type widths:",s),s}(f,g,0,n);Z(p),et(p),Q(p),tt(p);let v=1,P=1;const k=[],L=[];f.forEach((function(t,e){let a,r,o;switch(t.type){case n.db.LINETYPE.NOTE:nt.resetVerticalPos(),r=t.noteModel,function(t,e){nt.bumpVerticalPos(st.boxMargin),e.height=st.boxMargin,e.starty=nt.getVerticalPos();const a=(0,s.g)();a.x=e.startx,a.y=e.starty,a.width=e.width||st.width,a.class="note";const i=t.append("g"),r=z(i,a),n=(0,s.e)();n.x=e.startx,n.y=e.starty,n.width=a.width,n.dy="1em",n.text=e.message,n.class="noteText",n.fontFamily=st.noteFontFamily,n.fontSize=st.noteFontSize,n.fontWeight=st.noteFontWeight,n.anchor=st.noteAlign,n.textMargin=st.noteMargin,n.valign="center";const o=$(i,n),c=Math.round(o.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));r.attr("height",c+2*st.noteMargin),e.height+=c+2*st.noteMargin,nt.bumpVerticalPos(c+2*st.noteMargin),e.stopy=e.starty+c+2*st.noteMargin,e.stopx=e.startx+a.width,nt.insert(e.startx,e.starty,e.stopx,e.stopy),nt.models.addNote(e)}(p,r);break;case n.db.LINETYPE.ACTIVE_START:nt.newActivation(t,p,g);break;case n.db.LINETYPE.ACTIVE_END:!function(t,e){const a=nt.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),X(p,a,e,st,gt(t.from.actor).length),nt.insert(a.startx,e-10,a.stopx,e)}(t,nt.getVerticalPos());break;case n.db.LINETYPE.LOOP_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t)));break;case n.db.LINETYPE.LOOP_END:a=nt.endLoop(),G(p,a,"loop",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;case n.db.LINETYPE.RECT_START:xt(_,t,st.boxMargin,st.boxMargin,(t=>nt.newLoop(void 0,t.message)));break;case n.db.LINETYPE.RECT_END:a=nt.endLoop(),L.push(a),nt.models.addLoop(a),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos());break;case n.db.LINETYPE.OPT_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t)));break;case n.db.LINETYPE.OPT_END:a=nt.endLoop(),G(p,a,"opt",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;case n.db.LINETYPE.ALT_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t)));break;case n.db.LINETYPE.ALT_ELSE:xt(_,t,st.boxMargin+st.boxTextMargin,st.boxMargin,(t=>nt.addSectionToLoop(t)));break;case n.db.LINETYPE.ALT_END:a=nt.endLoop(),G(p,a,"alt",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t))),nt.saveVerticalPos();break;case n.db.LINETYPE.PAR_AND:xt(_,t,st.boxMargin+st.boxTextMargin,st.boxMargin,(t=>nt.addSectionToLoop(t)));break;case n.db.LINETYPE.PAR_END:a=nt.endLoop(),G(p,a,"par",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;case n.db.LINETYPE.AUTONUMBER:v=t.message.start||v,P=t.message.step||P,t.message.visible?n.db.enableSequenceNumbers():n.db.disableSequenceNumbers();break;case n.db.LINETYPE.CRITICAL_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t)));break;case n.db.LINETYPE.CRITICAL_OPTION:xt(_,t,st.boxMargin+st.boxTextMargin,st.boxMargin,(t=>nt.addSectionToLoop(t)));break;case n.db.LINETYPE.CRITICAL_END:a=nt.endLoop(),G(p,a,"critical",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;case n.db.LINETYPE.BREAK_START:xt(_,t,st.boxMargin,st.boxMargin+st.boxTextMargin,(t=>nt.newLoop(t)));break;case n.db.LINETYPE.BREAK_END:a=nt.endLoop(),G(p,a,"break",st),nt.bumpVerticalPos(a.stopy-nt.getVerticalPos()),nt.models.addLoop(a);break;default:try{o=t.msgModel,o.starty=nt.getVerticalPos(),o.sequenceIndex=v,o.sequenceVisible=n.db.showSequenceNumbers();const a=function(t,e){nt.bumpVerticalPos(10);const{startx:a,stopx:r,message:s}=e,n=i.e.splitBreaks(s).length,o=i.u.calculateTextDimensions(s,ot(st)),c=o.height/n;let l;e.height+=c,nt.bumpVerticalPos(c);let h=o.height-10;const d=o.width;if(a===r){l=nt.getVerticalPos()+h,st.rightAngles||(h+=st.boxMargin,l=nt.getVerticalPos()+h),h+=30;const t=i.e.getMax(d/2,st.width/2);nt.insert(a-t,nt.getVerticalPos()-10+h,r+t,nt.getVerticalPos()+30+h)}else h+=st.boxMargin,l=nt.getVerticalPos()+h,nt.insert(a,l-10,r,l);return nt.bumpVerticalPos(h),e.height+=h,e.stopy=e.starty+e.height,nt.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),l}(0,o);!function(t,e,a,i,r,s,n){function o(a,i){a.xfunction(t,e,a,r){const{startx:n,stopx:o,starty:c,message:l,type:h,sequenceIndex:d,sequenceVisible:p}=e,g=i.u.calculateTextDimensions(l,ot(st)),u=(0,s.e)();u.x=n,u.y=c+10,u.width=o-n,u.class="messageText",u.dy="1em",u.text=l,u.fontFamily=st.messageFontFamily,u.fontSize=st.messageFontSize,u.fontWeight=st.messageFontWeight,u.anchor=st.messageAlign,u.valign="center",u.textMargin=st.wrapPadding,u.tspan=!1,$(t,u);const x=g.width;let y;n===o?y=st.rightAngles?t.append("path").attr("d",`M ${n},${a} H ${n+i.e.getMax(st.width/2,x/2)} V ${a+25} H ${n}`):t.append("path").attr("d","M "+n+","+a+" C "+(n+60)+","+(a-10)+" "+(n+60)+","+(a+30)+" "+n+","+(a+20)):(y=t.append("line"),y.attr("x1",n),y.attr("y1",a),y.attr("x2",o),y.attr("y2",a)),h===r.db.LINETYPE.DOTTED||h===r.db.LINETYPE.DOTTED_CROSS||h===r.db.LINETYPE.DOTTED_POINT||h===r.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";st.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),h!==r.db.LINETYPE.SOLID&&h!==r.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),h!==r.db.LINETYPE.SOLID_POINT&&h!==r.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),h!==r.db.LINETYPE.SOLID_CROSS&&h!==r.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(p||st.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",n).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(d))}(p,t.messageModel,t.lineStartY,n))),st.mirrorActors&&ht(p,g,m,!0),L.forEach((t=>J(p,t))),B(p,g,m,st),nt.models.boxes.forEach((function(t){t.height=nt.getVerticalPos()-t.y,nt.insert(t.x,t.y,t.x+t.width,t.height),t.startx=t.x,t.starty=t.y,t.stopx=t.startx+t.width,t.stopy=t.starty+t.height,t.stroke="rgb(0,0,0, 0.5)",U(p,t,st)})),T&&nt.bumpVerticalPos(st.boxMargin);const I=dt(p,g,m,d),{bounds:M}=nt.getBounds();let N=M.stopy-M.starty;N`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`}},8252:function(t,e,a){a.d(e,{a:function(){return n},b:function(){return l},c:function(){return c},d:function(){return s},e:function(){return d},f:function(){return o},g:function(){return h}});var i=a(7967),r=a(9339);const s=(t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),void 0!==e.rx&&a.attr("rx",e.rx),void 0!==e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const t in e.attrs)a.attr(t,e.attrs[t]);return void 0!==e.class&&a.attr("class",e.class),a},n=(t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,a).lower()},o=(t,e)=>{const a=e.text.replace(r.J," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const s=i.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(a),i},c=(t,e,a,r)=>{const s=t.append("image");s.attr("x",e),s.attr("y",a);const n=(0,i.Nm)(r);s.attr("xlink:href",n)},l=(t,e,a,r)=>{const s=t.append("use");s.attr("x",e),s.attr("y",a);const n=(0,i.Nm)(r);s.attr("xlink:href",`#${n}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/423-897d7f17.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/423-897d7f17.chunk.min.js new file mode 100644 index 000000000..f430c4228 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/423-897d7f17.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[423],{1423:function(e,t,n){n.d(t,{d:function(){return b},p:function(){return r},s:function(){return D}});var s=n(7274),i=n(9339),u=function(){var e=function(e,t,n,s){for(n=n||{},s=e.length;s--;n[e[s]]=t);return n},t=[1,34],n=[1,35],s=[1,36],i=[1,37],u=[1,9],r=[1,8],a=[1,19],c=[1,20],o=[1,21],l=[1,40],h=[1,41],A=[1,27],p=[1,25],d=[1,26],y=[1,32],E=[1,33],C=[1,28],m=[1,29],k=[1,30],g=[1,31],F=[1,45],f=[1,42],b=[1,43],D=[1,44],_=[1,46],B=[1,24],T=[1,16,24],S=[1,60],N=[1,61],v=[1,62],L=[1,63],$=[1,64],I=[1,65],O=[1,66],x=[1,16,24,52],R=[1,77],P=[1,16,24,27,28,36,50,52,55,68,69,70,71,72,73,74,79,81],w=[1,16,24,27,28,34,36,50,52,55,59,68,69,70,71,72,73,74,79,81,94,96,97,98,99],G=[1,86],M=[28,94,96,97,98,99],U=[28,73,74,94,96,97,98,99],Y=[28,68,69,70,71,72,94,96,97,98,99],K=[1,99],z=[1,16,24,50,52,55],Q=[1,16,24,36],j=[8,9,10,11,19,23,44,46,48,53,57,58,60,61,63,65,75,76,78,82,94,96,97,98,99],X={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,statements:6,direction:7,direction_tb:8,direction_bt:9,direction_rl:10,direction_lr:11,graphConfig:12,openDirective:13,typeDirective:14,closeDirective:15,NEWLINE:16,":":17,argDirective:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,CLASS_DIAGRAM:23,EOF:24,statement:25,classLabel:26,SQS:27,STR:28,SQE:29,namespaceName:30,alphaNumToken:31,className:32,classLiteralName:33,GENERICTYPE:34,relationStatement:35,LABEL:36,namespaceStatement:37,classStatement:38,methodStatement:39,annotationStatement:40,clickStatement:41,cssClassStatement:42,noteStatement:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,namespaceIdentifier:49,STRUCT_START:50,classStatements:51,STRUCT_STOP:52,NAMESPACE:53,classIdentifier:54,STYLE_SEPARATOR:55,members:56,CLASS:57,ANNOTATION_START:58,ANNOTATION_END:59,MEMBER:60,SEPARATOR:61,relation:62,NOTE_FOR:63,noteText:64,NOTE:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,CSSCLASS:82,commentToken:83,textToken:84,graphCodeTokens:85,textNoTagsToken:86,TAGSTART:87,TAGEND:88,"==":89,"--":90,PCT:91,DEFAULT:92,SPACE:93,MINUS:94,keywords:95,UNICODE_TEXT:96,NUM:97,ALPHA:98,BQUOTE_STR:99,$accept:0,$end:1},terminals_:{2:"error",8:"direction_tb",9:"direction_bt",10:"direction_rl",11:"direction_lr",16:"NEWLINE",17:":",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",23:"CLASS_DIAGRAM",24:"EOF",27:"SQS",28:"STR",29:"SQE",34:"GENERICTYPE",36:"LABEL",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",50:"STRUCT_START",52:"STRUCT_STOP",53:"NAMESPACE",55:"STYLE_SEPARATOR",57:"CLASS",58:"ANNOTATION_START",59:"ANNOTATION_END",60:"MEMBER",61:"SEPARATOR",63:"NOTE_FOR",65:"NOTE",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"CSSCLASS",85:"graphCodeTokens",87:"TAGSTART",88:"TAGEND",89:"==",90:"--",91:"PCT",92:"DEFAULT",93:"SPACE",94:"MINUS",95:"keywords",96:"UNICODE_TEXT",97:"NUM",98:"ALPHA",99:"BQUOTE_STR"},productions_:[0,[3,1],[3,2],[3,1],[7,1],[7,1],[7,1],[7,1],[4,1],[5,4],[5,6],[13,1],[14,1],[18,1],[15,1],[12,4],[6,1],[6,2],[6,3],[26,3],[30,1],[30,2],[32,1],[32,1],[32,2],[32,2],[32,2],[25,1],[25,2],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,2],[25,2],[25,1],[37,4],[37,5],[49,2],[51,1],[51,2],[51,3],[38,1],[38,3],[38,4],[38,6],[54,2],[54,3],[40,4],[56,1],[56,2],[39,1],[39,2],[39,1],[39,1],[35,3],[35,4],[35,4],[35,5],[43,3],[43,2],[62,3],[62,2],[62,2],[62,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[41,3],[41,4],[41,3],[41,4],[41,4],[41,5],[41,3],[41,4],[41,4],[41,5],[41,4],[41,5],[41,5],[41,6],[42,3],[83,1],[83,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[86,1],[86,1],[86,1],[86,1],[31,1],[31,1],[31,1],[31,1],[33,1],[64,1]],performAction:function(e,t,n,s,i,u,r){var a=u.length-1;switch(i){case 4:s.setDirection("TB");break;case 5:s.setDirection("BT");break;case 6:s.setDirection("RL");break;case 7:s.setDirection("LR");break;case 11:s.parseDirective("%%{","open_directive");break;case 12:s.parseDirective(u[a],"type_directive");break;case 13:u[a]=u[a].trim().replace(/'/g,'"'),s.parseDirective(u[a],"arg_directive");break;case 14:s.parseDirective("}%%","close_directive","class");break;case 19:this.$=u[a-1];break;case 20:case 22:case 23:this.$=u[a];break;case 21:case 24:this.$=u[a-1]+u[a];break;case 25:case 26:this.$=u[a-1]+"~"+u[a]+"~";break;case 27:s.addRelation(u[a]);break;case 28:u[a-1].title=s.cleanupLabel(u[a]),s.addRelation(u[a-1]);break;case 37:this.$=u[a].trim(),s.setAccTitle(this.$);break;case 38:case 39:this.$=u[a].trim(),s.setAccDescription(this.$);break;case 40:s.addClassesToNamespace(u[a-3],u[a-1]);break;case 41:s.addClassesToNamespace(u[a-4],u[a-1]);break;case 42:this.$=u[a],s.addNamespace(u[a]);break;case 43:case 53:this.$=[u[a]];break;case 44:this.$=[u[a-1]];break;case 45:u[a].unshift(u[a-2]),this.$=u[a];break;case 47:s.setCssClass(u[a-2],u[a]);break;case 48:s.addMembers(u[a-3],u[a-1]);break;case 49:s.setCssClass(u[a-5],u[a-3]),s.addMembers(u[a-5],u[a-1]);break;case 50:this.$=u[a],s.addClass(u[a]);break;case 51:this.$=u[a-1],s.addClass(u[a-1]),s.setClassLabel(u[a-1],u[a]);break;case 52:s.addAnnotation(u[a],u[a-2]);break;case 54:u[a].push(u[a-1]),this.$=u[a];break;case 55:case 57:case 58:break;case 56:s.addMember(u[a-1],s.cleanupLabel(u[a]));break;case 59:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 60:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 61:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 62:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 63:s.addNote(u[a],u[a-1]);break;case 64:s.addNote(u[a]);break;case 65:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 66:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 67:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 68:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 69:this.$=s.relationType.AGGREGATION;break;case 70:this.$=s.relationType.EXTENSION;break;case 71:this.$=s.relationType.COMPOSITION;break;case 72:this.$=s.relationType.DEPENDENCY;break;case 73:this.$=s.relationType.LOLLIPOP;break;case 74:this.$=s.lineType.LINE;break;case 75:this.$=s.lineType.DOTTED_LINE;break;case 76:case 82:this.$=u[a-2],s.setClickEvent(u[a-1],u[a]);break;case 77:case 83:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 78:this.$=u[a-2],s.setLink(u[a-1],u[a]);break;case 79:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 80:this.$=u[a-3],s.setLink(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 81:this.$=u[a-4],s.setLink(u[a-3],u[a-2],u[a]),s.setTooltip(u[a-3],u[a-1]);break;case 84:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1],u[a]);break;case 85:this.$=u[a-4],s.setClickEvent(u[a-3],u[a-2],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 86:this.$=u[a-3],s.setLink(u[a-2],u[a]);break;case 87:this.$=u[a-4],s.setLink(u[a-3],u[a-1],u[a]);break;case 88:this.$=u[a-4],s.setLink(u[a-3],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 89:this.$=u[a-5],s.setLink(u[a-4],u[a-2],u[a]),s.setTooltip(u[a-4],u[a-1]);break;case 90:s.setCssClass(u[a-1],u[a])}},table:[{3:1,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:y,65:E,75:C,76:m,78:k,82:g,94:F,96:f,97:b,98:D,99:_},{1:[3]},{1:[2,1]},{3:47,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:y,65:E,75:C,76:m,78:k,82:g,94:F,96:f,97:b,98:D,99:_},{1:[2,3]},{1:[2,8]},{14:48,20:[1,49]},e(B,[2,16],{16:[1,50]}),{16:[1,51]},{20:[2,11]},e(T,[2,27],{36:[1,52]}),e(T,[2,29]),e(T,[2,30]),e(T,[2,31]),e(T,[2,32]),e(T,[2,33]),e(T,[2,34]),e(T,[2,35]),e(T,[2,36]),{45:[1,53]},{47:[1,54]},e(T,[2,39]),e(T,[2,55],{62:55,66:58,67:59,28:[1,56],36:[1,57],68:S,69:N,70:v,71:L,72:$,73:I,74:O}),{50:[1,67]},e(x,[2,46],{50:[1,69],55:[1,68]}),e(T,[2,57]),e(T,[2,58]),{31:70,94:F,96:f,97:b,98:D},{31:38,32:71,33:39,94:F,96:f,97:b,98:D,99:_},{31:38,32:72,33:39,94:F,96:f,97:b,98:D,99:_},{31:38,32:73,33:39,94:F,96:f,97:b,98:D,99:_},{28:[1,74]},{31:38,32:75,33:39,94:F,96:f,97:b,98:D,99:_},{28:R,64:76},e(T,[2,4]),e(T,[2,5]),e(T,[2,6]),e(T,[2,7]),e(P,[2,22],{31:38,33:39,32:78,34:[1,79],94:F,96:f,97:b,98:D,99:_}),e(P,[2,23],{34:[1,80]}),{30:81,31:82,94:F,96:f,97:b,98:D},{31:38,32:83,33:39,94:F,96:f,97:b,98:D,99:_},e(w,[2,104]),e(w,[2,105]),e(w,[2,106]),e(w,[2,107]),e([1,16,24,27,28,34,36,50,52,55,68,69,70,71,72,73,74,79,81],[2,108]),{1:[2,2]},{15:84,17:[1,85],22:G},e([17,22],[2,12]),e(B,[2,17],{25:7,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,7:18,32:22,49:23,54:24,31:38,33:39,6:87,8:t,9:n,10:s,11:i,44:a,46:c,48:o,53:l,57:h,58:A,60:p,61:d,63:y,65:E,75:C,76:m,78:k,82:g,94:F,96:f,97:b,98:D,99:_}),{6:88,7:18,8:t,9:n,10:s,11:i,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:y,65:E,75:C,76:m,78:k,82:g,94:F,96:f,97:b,98:D,99:_},e(T,[2,28]),e(T,[2,37]),e(T,[2,38]),{28:[1,90],31:38,32:89,33:39,94:F,96:f,97:b,98:D,99:_},{62:91,66:58,67:59,68:S,69:N,70:v,71:L,72:$,73:I,74:O},e(T,[2,56]),{67:92,73:I,74:O},e(M,[2,68],{66:93,68:S,69:N,70:v,71:L,72:$}),e(U,[2,69]),e(U,[2,70]),e(U,[2,71]),e(U,[2,72]),e(U,[2,73]),e(Y,[2,74]),e(Y,[2,75]),{16:[1,95],38:96,51:94,54:24,57:h},{31:97,94:F,96:f,97:b,98:D},{56:98,60:K},{59:[1,100]},{28:[1,101]},{28:[1,102]},{79:[1,103],81:[1,104]},{31:105,94:F,96:f,97:b,98:D},{28:R,64:106},e(T,[2,64]),e(T,[2,109]),e(P,[2,24]),e(P,[2,25]),e(P,[2,26]),{50:[2,42]},{30:107,31:82,50:[2,20],94:F,96:f,97:b,98:D},e(z,[2,50],{26:108,27:[1,109]}),{16:[1,110]},{18:111,21:[1,112]},{16:[2,14]},e(B,[2,18]),{24:[1,113]},e(Q,[2,59]),{31:38,32:114,33:39,94:F,96:f,97:b,98:D,99:_},{28:[1,116],31:38,32:115,33:39,94:F,96:f,97:b,98:D,99:_},e(M,[2,67],{66:117,68:S,69:N,70:v,71:L,72:$}),e(M,[2,66]),{52:[1,118]},{38:96,51:119,54:24,57:h},{16:[1,120],52:[2,43]},e(x,[2,47],{50:[1,121]}),{52:[1,122]},{52:[2,53],56:123,60:K},{31:38,32:124,33:39,94:F,96:f,97:b,98:D,99:_},e(T,[2,76],{28:[1,125]}),e(T,[2,78],{28:[1,127],77:[1,126]}),e(T,[2,82],{28:[1,128],80:[1,129]}),{28:[1,130]},e(T,[2,90]),e(T,[2,63]),{50:[2,21]},e(z,[2,51]),{28:[1,131]},e(j,[2,9]),{15:132,22:G},{22:[2,13]},{1:[2,15]},e(Q,[2,61]),e(Q,[2,60]),{31:38,32:133,33:39,94:F,96:f,97:b,98:D,99:_},e(M,[2,65]),e(T,[2,40]),{52:[1,134]},{38:96,51:135,52:[2,44],54:24,57:h},{56:136,60:K},e(x,[2,48]),{52:[2,54]},e(T,[2,52]),e(T,[2,77]),e(T,[2,79]),e(T,[2,80],{77:[1,137]}),e(T,[2,83]),e(T,[2,84],{28:[1,138]}),e(T,[2,86],{28:[1,140],77:[1,139]}),{29:[1,141]},{16:[1,142]},e(Q,[2,62]),e(T,[2,41]),{52:[2,45]},{52:[1,143]},e(T,[2,81]),e(T,[2,85]),e(T,[2,87]),e(T,[2,88],{77:[1,144]}),e(z,[2,19]),e(j,[2,10]),e(x,[2,49]),e(T,[2,89])],defaultActions:{2:[2,1],4:[2,3],5:[2,8],9:[2,11],47:[2,2],81:[2,42],86:[2,14],107:[2,21],112:[2,13],113:[2,15],123:[2,54],135:[2,45]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=[0],n=[],s=[null],i=[],u=this.table,r="",a=0,c=0,o=i.slice.call(arguments,1),l=Object.create(this.lexer),h={yy:{}};for(var A in this.yy)Object.prototype.hasOwnProperty.call(this.yy,A)&&(h.yy[A]=this.yy[A]);l.setInput(e,h.yy),h.yy.lexer=l,h.yy.parser=this,void 0===l.yylloc&&(l.yylloc={});var p=l.yylloc;i.push(p);var d=l.options&&l.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,E,C,m,k,g,F,f,b,D={};;){if(E=t[t.length-1],this.defaultActions[E]?C=this.defaultActions[E]:(null==y&&(b=void 0,"number"!=typeof(b=n.pop()||l.lex()||1)&&(b instanceof Array&&(b=(n=b).pop()),b=this.symbols_[b]||b),y=b),C=u[E]&&u[E][y]),void 0===C||!C.length||!C[0]){var _;for(k in f=[],u[E])this.terminals_[k]&&k>2&&f.push("'"+this.terminals_[k]+"'");_=l.showPosition?"Parse error on line "+(a+1)+":\n"+l.showPosition()+"\nExpecting "+f.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(_,{text:l.match,token:this.terminals_[y]||y,line:l.yylineno,loc:p,expected:f})}if(C[0]instanceof Array&&C.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+y);switch(C[0]){case 1:t.push(y),s.push(l.yytext),i.push(l.yylloc),t.push(C[1]),y=null,c=l.yyleng,r=l.yytext,a=l.yylineno,p=l.yylloc;break;case 2:if(g=this.productions_[C[1]][1],D.$=s[s.length-g],D._$={first_line:i[i.length-(g||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(g||1)].first_column,last_column:i[i.length-1].last_column},d&&(D._$.range=[i[i.length-(g||1)].range[0],i[i.length-1].range[1]]),void 0!==(m=this.performAction.apply(D,[r,c,a,h.yy,C[1],s,i].concat(o))))return m;g&&(t=t.slice(0,-1*g*2),s=s.slice(0,-1*g),i=i.slice(0,-1*g)),t.push(this.productions_[C[1]][0]),s.push(D.$),i.push(D._$),F=u[t[t.length-2]][t[t.length-1]],t.push(F);break;case 3:return!0}}return!0}},W={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,s,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(s=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ut[0].length)){if(t=n,s=u,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[u])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[s]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,n,s){switch(n){case 0:return this.begin("open_directive"),19;case 1:return 8;case 2:return 9;case 3:return 10;case 4:return 11;case 5:return this.begin("type_directive"),20;case 6:return this.popState(),this.begin("arg_directive"),17;case 7:return this.popState(),this.popState(),22;case 8:return 21;case 9:case 10:case 19:case 34:case 39:case 43:case 50:break;case 11:return this.begin("acc_title"),44;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),46;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 24:case 27:case 29:case 61:case 64:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:case 38:return 16;case 20:case 21:return 23;case 22:case 40:case 48:return"EDGE_STATE";case 23:this.begin("callback_name");break;case 25:this.popState(),this.begin("callback_args");break;case 26:return 79;case 28:return 80;case 30:return"STR";case 31:this.begin("string");break;case 32:return this.begin("namespace"),53;case 33:case 42:return this.popState(),16;case 35:return this.begin("namespace-body"),50;case 36:case 46:return this.popState(),52;case 37:case 47:return"EOF_IN_STRUCT";case 41:return this.begin("class"),57;case 44:return this.popState(),this.popState(),52;case 45:return this.begin("class-body"),50;case 49:return"OPEN_IN_STRUCT";case 51:return"MEMBER";case 52:return 82;case 53:return 75;case 54:return 76;case 55:return 78;case 56:return 63;case 57:return 65;case 58:return 58;case 59:return 59;case 60:return 81;case 62:return"GENERICTYPE";case 63:this.begin("generic");break;case 65:return"BQUOTE_STR";case 66:this.begin("bqstring");break;case 67:case 68:case 69:case 70:return 77;case 71:case 72:return 69;case 73:case 74:return 71;case 75:return 70;case 76:return 68;case 77:return 72;case 78:return 73;case 79:return 74;case 80:return 36;case 81:return 55;case 82:return 94;case 83:return"DOT";case 84:return"PLUS";case 85:return 91;case 86:case 87:return"EQUALS";case 88:return 98;case 89:return 27;case 90:return 29;case 91:return"PUNCTUATION";case 92:return 97;case 93:return 96;case 94:return 93;case 95:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[31,36,37,38,39,40,41,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},namespace:{rules:[31,32,33,34,35,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},"class-body":{rules:[31,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},class:{rules:[31,42,43,44,45,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},acc_descr_multiline:{rules:[16,17,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},acc_descr:{rules:[14,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},acc_title:{rules:[12,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},arg_directive:{rules:[7,8,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},type_directive:{rules:[6,7,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},open_directive:{rules:[5,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},callback_args:{rules:[27,28,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},callback_name:{rules:[24,25,26,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},href:{rules:[31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},struct:{rules:[31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},generic:{rules:[31,52,53,54,55,56,57,58,59,60,61,62,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},bqstring:{rules:[31,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},string:{rules:[29,30,31,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,31,32,41,52,53,54,55,56,57,58,59,60,63,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],inclusive:!0}}};function H(){this.yy={}}return X.lexer=W,H.prototype=X,X.Parser=H,new H}();u.parser=u;const r=u,a="classId-";let c=[],o={},l=[],h=0,A={},p=0,d=[];const y=e=>i.e.sanitizeText(e,(0,i.c)()),E=function(e){let t="",n=e;if(e.indexOf("~")>0){const s=e.split("~");n=y(s[0]),t=y(s[1])}return{className:n,type:t}},C=function(e){const t=E(e);void 0===o[t.className]&&(o[t.className]={id:t.className,type:t.type,label:t.className,cssClasses:[],methods:[],members:[],annotations:[],domId:a+t.className+"-"+h},h++)},m=function(e){if(e in o)return o[e].domId;throw new Error("Class not found: "+e)},k=function(e,t){const n=E(e).className,s=o[n];if("string"==typeof t){const e=t.trim();e.startsWith("<<")&&e.endsWith(">>")?s.annotations.push(y(e.substring(2,e.length-2))):e.indexOf(")")>0?s.methods.push(y(e)):e&&s.members.push(y(e))}},g=function(e,t){e.split(",").forEach((function(e){let n=e;e[0].match(/\d/)&&(n=a+n),void 0!==o[n]&&o[n].cssClasses.push(t)}))},F=function(e){let t=(0,s.Ys)(".mermaidTooltip");null===(t._groups||t)[0][0]&&(t=(0,s.Ys)("body").append("div").attr("class","mermaidTooltip").style("opacity",0)),(0,s.Ys)(e).select("svg").selectAll("g.node").on("mouseover",(function(){const e=(0,s.Ys)(this);if(null===e.attr("title"))return;const n=this.getBoundingClientRect();t.transition().duration(200).style("opacity",".9"),t.text(e.attr("title")).style("left",window.scrollX+n.left+(n.right-n.left)/2+"px").style("top",window.scrollY+n.top-14+document.body.scrollTop+"px"),t.html(t.html().replace(/<br\/>/g,"
        ")),e.classed("hover",!0)})).on("mouseout",(function(){t.transition().duration(500).style("opacity",0),(0,s.Ys)(this).classed("hover",!1)}))};d.push(F);let f="TB";const b={parseDirective:function(e,t,n){i.m.parseDirective(this,e,t,n)},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,getConfig:()=>(0,i.c)().class,addClass:C,bindFunctions:function(e){d.forEach((function(t){t(e)}))},clear:function(){c=[],o={},l=[],d=[],d.push(F),A={},p=0,(0,i.v)()},getClass:function(e){return o[e]},getClasses:function(){return o},getNotes:function(){return l},addAnnotation:function(e,t){const n=E(e).className;o[n].annotations.push(t)},addNote:function(e,t){const n={id:`note${l.length}`,class:t,text:e};l.push(n)},getRelations:function(){return c},addRelation:function(e){i.l.debug("Adding relation: "+JSON.stringify(e)),C(e.id1),C(e.id2),e.id1=E(e.id1).className,e.id2=E(e.id2).className,e.relationTitle1=i.e.sanitizeText(e.relationTitle1.trim(),(0,i.c)()),e.relationTitle2=i.e.sanitizeText(e.relationTitle2.trim(),(0,i.c)()),c.push(e)},getDirection:()=>f,setDirection:e=>{f=e},addMember:k,addMembers:function(e,t){Array.isArray(t)&&(t.reverse(),t.forEach((t=>k(e,t))))},cleanupLabel:function(e){return e.startsWith(":")&&(e=e.substring(1)),y(e.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(e,t,n){e.split(",").forEach((function(e){(function(e,t,n){if("loose"!==(0,i.c)().securityLevel)return;if(void 0===t)return;const s=e;if(void 0!==o[s]){const e=m(s);let u=[];if("string"==typeof n){u=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let e=0;e{o[t].parent=e,A[e].classes[t]=o[t]}))},getNamespace:function(e){return A[e]},getNamespaces:function(){return A}},D=e=>`g.classGroup text {\n fill: ${e.nodeBorder};\n fill: ${e.classText};\n stroke: none;\n font-family: ${e.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${e.classText};\n}\n.edgeLabel .label rect {\n fill: ${e.mainBkg};\n}\n.label text {\n fill: ${e.classText};\n}\n.edgeLabel .label span {\n background: ${e.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${e.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${e.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${e.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/430-cc171d93.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/430-cc171d93.chunk.min.js new file mode 100644 index 000000000..86b7da145 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/430-cc171d93.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[430],{4430:function(t,e,r){r.d(e,{diagram:function(){return v}});var i=r(9339),a=r(5625),n=r(7274),s=r(3771);const o=[];for(let t=0;t<256;++t)o.push((t+256).toString(16).slice(1));var c=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i,l=function(t){if(!function(t){return"string"==typeof t&&c.test(t)}(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r};function h(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:case 3:return e^r^i;case 2:return e&r^e&i^r&i}}function d(t,e){return t<>>32-e}var u=function(t,e,r){function i(t,e,r,i){var a;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>0;l=c,c=o,o=d(s,30)>>>0,s=a,a=n}r[0]=r[0]+a>>>0,r[1]=r[1]+s>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}(n),n[6]=15&n[6]|80,n[8]=63&n[8]|128,r){i=i||0;for(let t=0;t<16;++t)r[i+t]=n[t];return r}return function(t,e=0){return(o[t[e+0]]+o[t[e+1]]+o[t[e+2]]+o[t[e+3]]+"-"+o[t[e+4]]+o[t[e+5]]+"-"+o[t[e+6]]+o[t[e+7]]+"-"+o[t[e+8]]+o[t[e+9]]+"-"+o[t[e+10]]+o[t[e+11]]+o[t[e+12]]+o[t[e+13]]+o[t[e+14]]+o[t[e+15]]).toLowerCase()}(n)}try{i.name="v5"}catch(t){}return i.DNS="6ba7b810-9dad-11d1-80b4-00c04fd430c8",i.URL="6ba7b811-9dad-11d1-80b4-00c04fd430c8",i}(),y=(r(7484),r(7967),r(7856),function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,2],r=[1,5],i=[6,9,11,23,25,27,29,30,31,52],a=[1,17],n=[1,18],s=[1,19],o=[1,20],c=[1,21],l=[1,22],h=[1,25],d=[1,30],u=[1,31],y=[1,32],p=[1,33],_=[1,34],f=[6,9,11,15,20,23,25,27,29,30,31,44,45,46,47,48,52],g=[1,46],m=[30,31,49,50],E=[4,6,9,11,23,25,27,29,30,31,52],O=[44,45,46,47,48],b=[22,37],k=[1,66],R=[1,65],N=[22,37,39,41],T={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,BLOCK_START:20,attributes:21,BLOCK_STOP:22,title:23,title_value:24,acc_title:25,acc_title_value:26,acc_descr:27,acc_descr_value:28,acc_descr_multiline_value:29,ALPHANUM:30,ENTITY_NAME:31,attribute:32,attributeType:33,attributeName:34,attributeKeyTypeList:35,attributeComment:36,ATTRIBUTE_WORD:37,attributeKeyType:38,COMMA:39,ATTRIBUTE_KEY:40,COMMENT:41,cardinality:42,relType:43,ZERO_OR_ONE:44,ZERO_OR_MORE:45,ONE_OR_MORE:46,ONLY_ONE:47,MD_PARENT:48,NON_IDENTIFYING:49,IDENTIFYING:50,WORD:51,open_directive:52,type_directive:53,arg_directive:54,close_directive:55,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"BLOCK_START",22:"BLOCK_STOP",23:"title",24:"title_value",25:"acc_title",26:"acc_title_value",27:"acc_descr",28:"acc_descr_value",29:"acc_descr_multiline_value",30:"ALPHANUM",31:"ENTITY_NAME",37:"ATTRIBUTE_WORD",39:"COMMA",40:"ATTRIBUTE_KEY",41:"COMMENT",44:"ZERO_OR_ONE",45:"ZERO_OR_MORE",46:"ONE_OR_MORE",47:"ONLY_ONE",48:"MD_PARENT",49:"NON_IDENTIFYING",50:"IDENTIFYING",51:"WORD",52:"open_directive",53:"type_directive",54:"arg_directive",55:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,4],[10,3],[10,1],[10,2],[10,2],[10,2],[10,1],[17,1],[17,1],[21,1],[21,2],[32,2],[32,3],[32,3],[32,4],[33,1],[34,1],[35,1],[35,3],[38,1],[36,1],[18,3],[42,1],[42,1],[42,1],[42,1],[42,1],[43,1],[43,1],[19,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 3:case 7:case 8:this.$=[];break;case 4:n[o-1].push(n[o]),this.$=n[o-1];break;case 5:case 6:case 20:case 44:case 28:case 29:case 32:this.$=n[o];break;case 12:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 13:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 14:i.addEntity(n[o-2]);break;case 15:i.addEntity(n[o]);break;case 16:case 17:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 21:case 42:case 43:case 33:this.$=n[o].replace(/"/g,"");break;case 22:case 30:this.$=[n[o]];break;case 23:n[o].push(n[o-1]),this.$=n[o];break;case 24:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 26:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 27:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 31:n[o-2].push(n[o]),this.$=n[o-2];break;case 34:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 35:this.$=i.Cardinality.ZERO_OR_ONE;break;case 36:this.$=i.Cardinality.ZERO_OR_MORE;break;case 37:this.$=i.Cardinality.ONE_OR_MORE;break;case 38:this.$=i.Cardinality.ONLY_ONE;break;case 39:this.$=i.Cardinality.MD_PARENT;break;case 40:this.$=i.Identification.NON_IDENTIFYING;break;case 41:this.$=i.Identification.IDENTIFYING;break;case 45:i.parseDirective("%%{","open_directive");break;case 46:i.parseDirective(n[o],"type_directive");break;case 47:n[o]=n[o].trim().replace(/'/g,'"'),i.parseDirective(n[o],"arg_directive");break;case 48:i.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:e,7:3,12:4,52:r},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,52:r},{13:8,53:[1,9]},{53:[2,45]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},{1:[2,2]},{14:23,15:[1,24],55:h},t([15,55],[2,46]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:15,10:26,12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),t(i,[2,15],{18:27,42:29,20:[1,28],44:d,45:u,46:y,47:p,48:_}),{24:[1,35]},{26:[1,36]},{28:[1,37]},t(i,[2,19]),t(f,[2,20]),t(f,[2,21]),{11:[1,38]},{16:39,54:[1,40]},{11:[2,48]},t(i,[2,5]),{17:41,30:c,31:l},{21:42,22:[1,43],32:44,33:45,37:g},{43:47,49:[1,48],50:[1,49]},t(m,[2,35]),t(m,[2,36]),t(m,[2,37]),t(m,[2,38]),t(m,[2,39]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(E,[2,9]),{14:50,55:h},{55:[2,47]},{15:[1,51]},{22:[1,52]},t(i,[2,14]),{21:53,22:[2,22],32:44,33:45,37:g},{34:54,37:[1,55]},{37:[2,28]},{42:56,44:d,45:u,46:y,47:p,48:_},t(O,[2,40]),t(O,[2,41]),{11:[1,57]},{19:58,30:[1,61],31:[1,60],51:[1,59]},t(i,[2,13]),{22:[2,23]},t(b,[2,24],{35:62,36:63,38:64,40:k,41:R}),t([22,37,40,41],[2,29]),t([30,31],[2,34]),t(E,[2,10]),t(i,[2,12]),t(i,[2,42]),t(i,[2,43]),t(i,[2,44]),t(b,[2,25],{36:67,39:[1,68],41:R}),t(b,[2,26]),t(N,[2,30]),t(b,[2,33]),t(N,[2,32]),t(b,[2,27]),{38:69,40:k},t(N,[2,31])],defaultActions:{5:[2,45],7:[2,2],25:[2,48],40:[2,47],46:[2,28],53:[2,23]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=[0],r=[],i=[null],a=[],n=this.table,s="",o=0,c=0,l=a.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(d.yy[u]=this.yy[u]);h.setInput(t,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var y=h.yylloc;a.push(y);var p=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,f,g,m,E,O,b,k,R,N={};;){if(f=e[e.length-1],this.defaultActions[f]?g=this.defaultActions[f]:(null==_&&(R=void 0,"number"!=typeof(R=r.pop()||h.lex()||1)&&(R instanceof Array&&(R=(r=R).pop()),R=this.symbols_[R]||R),_=R),g=n[f]&&n[f][_]),void 0===g||!g.length||!g[0]){var T;for(E in k=[],n[f])this.terminals_[E]&&E>2&&k.push("'"+this.terminals_[E]+"'");T=h.showPosition?"Parse error on line "+(o+1)+":\n"+h.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(T,{text:h.match,token:this.terminals_[_]||_,line:h.yylineno,loc:y,expected:k})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+_);switch(g[0]){case 1:e.push(_),i.push(h.yytext),a.push(h.yylloc),e.push(g[1]),_=null,c=h.yyleng,s=h.yytext,o=h.yylineno,y=h.yylloc;break;case 2:if(O=this.productions_[g[1]][1],N.$=i[i.length-O],N._$={first_line:a[a.length-(O||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(O||1)].first_column,last_column:a[a.length-1].last_column},p&&(N._$.range=[a[a.length-(O||1)].range[0],a[a.length-1].range[1]]),void 0!==(m=this.performAction.apply(N,[s,c,o,d.yy,g[1],i,a].concat(l))))return m;O&&(e=e.slice(0,-1*O*2),i=i.slice(0,-1*O),a=a.slice(0,-1*O)),e.push(this.productions_[g[1]][0]),i.push(N.$),a.push(N._$),b=n[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;ne[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),25;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),27;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.begin("open_directive"),52;case 8:return this.begin("type_directive"),53;case 9:return this.popState(),this.begin("arg_directive"),15;case 10:return this.popState(),this.popState(),55;case 11:return 54;case 12:return 11;case 13:case 20:case 25:break;case 14:return 9;case 15:return 31;case 16:return 51;case 17:return 4;case 18:return this.begin("block"),20;case 19:return 39;case 21:return 40;case 22:case 23:return 37;case 24:return 41;case 26:return this.popState(),22;case 27:case 57:return e.yytext[0];case 28:case 32:case 33:case 46:return 44;case 29:case 30:case 31:case 39:case 41:case 48:return 46;case 34:case 35:case 36:case 37:case 38:case 40:case 47:return 45;case 42:case 43:case 44:case 45:return 47;case 49:return 48;case 50:case 53:case 54:case 55:return 49;case 51:case 52:return 50;case 56:return 30;case 58:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},open_directive:{rules:[8],inclusive:!1},type_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[10,11],inclusive:!1},block:{rules:[19,20,21,22,23,24,25,26,27],inclusive:!1},INITIAL:{rules:[0,2,4,7,12,13,14,15,16,17,18,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],inclusive:!0}}};function A(){this.yy={}}return T.lexer=x,A.prototype=T,T.Parser=A,new A}());y.parser=y;const p=y;let _={},f=[];const g=function(t){return void 0===_[t]&&(_[t]={attributes:[]},i.l.info("Added new entity :",t)),_[t]},m={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},parseDirective:function(t,e,r){i.m.parseDirective(this,t,e,r)},getConfig:()=>(0,i.c)().er,addEntity:g,addAttributes:function(t,e){let r,a=g(t);for(r=e.length-1;r>=0;r--)a.attributes.push(e[r]),i.l.debug("Added attribute ",e[r].attributeName)},getEntities:()=>_,addRelationship:function(t,e,r,a){let n={entityA:t,roleA:e,entityB:r,relSpec:a};f.push(n),i.l.debug("Added new relationship :",n)},getRelationships:()=>f,clear:function(){_={},f=[],(0,i.v)()},setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,setDiagramTitle:i.r,getDiagramTitle:i.t},E={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},O=E,b=/[^\dA-Za-z](\W)*/g;let k={},R=new Map;const N=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let T=0;const x="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function A(t=""){return t.length>0?`${t}-`:""}const v={parser:p,db:m,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)k[r]=t[r]},draw:function(t,e,r,o){k=(0,i.c)().er,i.l.info("Drawing ER diagram");const c=(0,i.c)().securityLevel;let l;"sandbox"===c&&(l=(0,n.Ys)("#i"+e));const h=("sandbox"===c?(0,n.Ys)(l.nodes()[0].contentDocument.body):(0,n.Ys)("body")).select(`[id='${e}']`);let d;(function(t,e){let r;t.append("defs").append("marker").attr("id",E.MD_PARENT_START).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",E.MD_PARENT_END).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",E.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",E.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",E.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",E.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",E.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",E.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",E.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",E.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")})(h,k),d=new a.k({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:k.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const y=function(t,e,r){let a;return Object.keys(e).forEach((function(n){const s=function(t="",e=""){const r=t.replace(b,"");return`${A(e)}${A(r)}${u(t,x)}`}(n,"entity");R.set(n,s);const o=t.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",k.fontSize+"px").text(n),{width:h,height:d}=((t,e,r)=>{const a=k.entityPadding/3,n=k.entityPadding/3,s=.85*k.fontSize,o=e.node().getBBox(),c=[];let l=!1,h=!1,d=0,u=0,y=0,p=0,_=o.height+2*a,f=1;r.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),r.forEach((r=>{const n=`${e.node().id}-attr-${f}`;let o=0;const g=(0,i.x)(r.attributeType),m=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(g),E=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeName),O={};O.tn=m,O.nn=E;const b=m.node().getBBox(),k=E.node().getBBox();if(d=Math.max(d,b.width),u=Math.max(u,k.width),o=Math.max(b.height,k.height),l){const e=void 0!==r.attributeKeyTypeList?r.attributeKeyTypeList.join(","):"",a=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(e);O.kn=a;const c=a.node().getBBox();y=Math.max(y,c.width),o=Math.max(o,c.height)}if(h){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeComment||"");O.cn=e;const a=e.node().getBBox();p=Math.max(p,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),_+=o+2*a,f+=1}));let g=4;l&&(g+=2),h&&(g+=2);const m=d+u+y+p,E={width:Math.max(k.minEntityWidth,Math.max(o.width+2*k.entityPadding,m+n*g)),height:r.length>0?_:Math.max(k.minEntityHeight,o.height+2*k.entityPadding)};if(r.length>0){const r=Math.max(0,(E.width-m-n*g)/(g/2));e.attr("transform","translate("+E.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((e=>{const o=i+a+e.height/2;e.tn.attr("transform","translate("+n+","+o+")");const c=t.insert("rect","#"+e.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+r).attr("height",e.height+2*a),_=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));e.nn.attr("transform","translate("+(_+n)+","+o+")");const f=t.insert("rect","#"+e.nn.node().id).classed(`er ${s}`,!0).attr("x",_).attr("y",i).attr("width",u+2*n+r).attr("height",e.height+2*a);let g=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){e.kn.attr("transform","translate("+(g+n)+","+o+")");const c=t.insert("rect","#"+e.kn.node().id).classed(`er ${s}`,!0).attr("x",g).attr("y",i).attr("width",y+2*n+r).attr("height",e.height+2*a);g=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(e.cn.attr("transform","translate("+(g+n)+","+o+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${s}`,"true").attr("x",g).attr("y",i).attr("width",p+2*n+r).attr("height",e.height+2*a)),i+=e.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else E.height=Math.max(k.minEntityHeight,_),e.attr("transform","translate("+E.width/2+","+E.height/2+")");return E})(o,l,e[n].attributes),y=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();r.setNode(s,{width:y.width,height:y.height,shape:"rect",id:s})})),a}(h,o.db.getEntities(),d),p=function(t,e){return t.forEach((function(t){e.setEdge(R.get(t.entityA),R.get(t.entityB),{relationship:t},N(t))})),t}(o.db.getRelationships(),d);var _,f;(0,s.bK)(d),_=h,(f=d).nodes().forEach((function(t){void 0!==t&&void 0!==f.node(t)&&_.select("#"+t).attr("transform","translate("+(f.node(t).x-f.node(t).width/2)+","+(f.node(t).y-f.node(t).height/2)+" )")})),p.forEach((function(t){!function(t,e,r,a,s){T++;const o=r.edge(R.get(e.entityA),R.get(e.entityB),N(e)),c=(0,n.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.$0Z),l=t.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",c(o.points)).style("stroke",k.stroke).style("fill","none");e.relSpec.relType===s.db.Identification.NON_IDENTIFYING&&l.attr("stroke-dasharray","8,8");let h="";switch(k.arrowMarkerAbsolute&&(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,h=h.replace(/\(/g,"\\("),h=h.replace(/\)/g,"\\)")),e.relSpec.cardA){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-end","url("+h+"#"+O.ZERO_OR_ONE_END+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-end","url("+h+"#"+O.ZERO_OR_MORE_END+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-end","url("+h+"#"+O.ONE_OR_MORE_END+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-end","url("+h+"#"+O.ONLY_ONE_END+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-end","url("+h+"#"+O.MD_PARENT_END+")")}switch(e.relSpec.cardB){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-start","url("+h+"#"+O.ZERO_OR_ONE_START+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-start","url("+h+"#"+O.ZERO_OR_MORE_START+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-start","url("+h+"#"+O.ONE_OR_MORE_START+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-start","url("+h+"#"+O.ONLY_ONE_START+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-start","url("+h+"#"+O.MD_PARENT_START+")")}const d=l.node().getTotalLength(),u=l.node().getPointAtLength(.5*d),y="rel"+T,p=t.append("text").classed("er relationshipLabel",!0).attr("id",y).attr("x",u.x).attr("y",u.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",k.fontSize+"px").text(e.roleA).node().getBBox();t.insert("rect","#"+y).classed("er relationshipLabelBox",!0).attr("x",u.x-p.width/2).attr("y",u.y-p.height/2).attr("width",p.width).attr("height",p.height)}(h,t,d,y,o)}));const g=k.diagramPadding;i.u.insertTitle(h,"entityTitleText",k.titleTopMargin,o.db.getDiagramTitle());const m=h.node().getBBox(),v=m.width+2*g,M=m.height+2*g;(0,i.i)(h,M,v,k.useMaxWidth),h.attr("viewBox",`${m.x-g} ${m.y-g} ${v} ${M}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/433-f2655a46.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/433-f2655a46.chunk.min.js new file mode 100644 index 000000000..7327eaec2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/433-f2655a46.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[433],{6433:function(t,i,n){n.d(i,{diagram:function(){return h}});var e=n(9339),s=(n(7484),n(7967),n(7274),n(7856),function(){var t=function(t,i,n,e){for(n=n||{},e=t.length;e--;n[t[e]]=i);return n},i=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,i,n,e,s,r,h){switch(r.length,s){case 1:return e;case 4:break;case 6:e.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=[0],n=[],e=[null],s=[],r=this.table,h="",o=0,l=0,c=s.slice.call(arguments,1),a=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);a.setInput(t,y.yy),y.yy.lexer=a,y.yy.parser=this,void 0===a.yylloc&&(a.yylloc={});var p=a.yylloc;s.push(p);var f=a.options&&a.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,_,m,d,k,x,b,v,w,I={};;){if(_=i[i.length-1],this.defaultActions[_]?m=this.defaultActions[_]:(null==g&&(w=void 0,"number"!=typeof(w=n.pop()||a.lex()||1)&&(w instanceof Array&&(w=(n=w).pop()),w=this.symbols_[w]||w),g=w),m=r[_]&&r[_][g]),void 0===m||!m.length||!m[0]){var S;for(k in v=[],r[_])this.terminals_[k]&&k>2&&v.push("'"+this.terminals_[k]+"'");S=a.showPosition?"Parse error on line "+(o+1)+":\n"+a.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(S,{text:a.match,token:this.terminals_[g]||g,line:a.yylineno,loc:p,expected:v})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(m[0]){case 1:i.push(g),e.push(a.yytext),s.push(a.yylloc),i.push(m[1]),g=null,l=a.yyleng,h=a.yytext,o=a.yylineno,p=a.yylloc;break;case 2:if(x=this.productions_[m[1]][1],I.$=e[e.length-x],I._$={first_line:s[s.length-(x||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(x||1)].first_column,last_column:s[s.length-1].last_column},f&&(I._$.range=[s[s.length-(x||1)].range[0],s[s.length-1].range[1]]),void 0!==(d=this.performAction.apply(I,[h,l,o,y.yy,m[1],e,s].concat(c))))return d;x&&(i=i.slice(0,-1*x*2),e=e.slice(0,-1*x),s=s.slice(0,-1*x)),i.push(this.productions_[m[1]][0]),e.push(I.$),s.push(I._$),b=r[i[i.length-2]][i[i.length-1]],i.push(b);break;case 3:return!0}}return!0}},e={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var e=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===e.length?this.yylloc.first_column:0)+e[e.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var n,e,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(e=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,e;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;ri[0].length)){if(i=n,e=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,s[e]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,e){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function s(){this.yy={}}return n.lexer=e,s.prototype=n,n.Parser=s,new s}());s.parser=s;let r=false;const h={parser:s,db:{clear:()=>{r=false},setInfo:t=>{r=t},getInfo:()=>r},renderer:{draw:(t,i,n)=>{e.l.debug("rendering info diagram\n"+t);const s=(0,e.B)(i);(0,e.i)(s,100,400,!0),s.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${n}`)}}}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/438-760c9ed3.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/438-760c9ed3.chunk.min.js new file mode 100644 index 000000000..6827acc45 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/438-760c9ed3.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[438],{2438:function(t,e,n){n.d(e,{diagram:function(){return A}});var i=n(9339),r=n(7274),s=n(8252),a=(n(7484),n(7967),n(7856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,2],n=[1,5],i=[6,9,11,17,18,20,22,23,24,26],r=[1,15],s=[1,16],a=[1,17],o=[1,18],c=[1,19],l=[1,20],h=[1,24],u=[4,6,9,11,17,18,20,22,23,24,26],y={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,taskName:24,taskData:25,open_directive:26,type_directive:27,arg_directive:28,close_directive:29,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",24:"taskName",25:"taskData",26:"open_directive",27:"type_directive",28:"arg_directive",29:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,r,s,a){var o=s.length-1;switch(r){case 1:return s[o-1];case 3:case 7:case 8:this.$=[];break;case 4:s[o-1].push(s[o]),this.$=s[o-1];break;case 5:case 6:this.$=s[o];break;case 11:i.setDiagramTitle(s[o].substr(6)),this.$=s[o].substr(6);break;case 12:this.$=s[o].trim(),i.setAccTitle(this.$);break;case 13:case 14:this.$=s[o].trim(),i.setAccDescription(this.$);break;case 15:i.addSection(s[o].substr(8)),this.$=s[o].substr(8);break;case 16:i.addTask(s[o-1],s[o]),this.$="task";break;case 18:i.parseDirective("%%{","open_directive");break;case 19:i.parseDirective(s[o],"type_directive");break;case 20:s[o]=s[o].trim().replace(/'/g,'"'),i.parseDirective(s[o],"arg_directive");break;case 21:i.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:e,7:3,12:4,26:n},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,26:n},{13:8,27:[1,9]},{27:[2,18]},{6:[1,10],7:21,8:11,9:[1,12],10:13,11:[1,14],12:4,17:r,18:s,20:a,22:o,23:c,24:l,26:n},{1:[2,2]},{14:22,15:[1,23],29:h},t([15,29],[2,19]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:21,10:25,12:4,17:r,18:s,20:a,22:o,23:c,24:l,26:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),{19:[1,26]},{21:[1,27]},t(i,[2,14]),t(i,[2,15]),{25:[1,28]},t(i,[2,17]),{11:[1,29]},{16:30,28:[1,31]},{11:[2,21]},t(i,[2,5]),t(i,[2,12]),t(i,[2,13]),t(i,[2,16]),t(u,[2,9]),{14:32,29:h},{29:[2,20]},{11:[1,33]},t(u,[2,10])],defaultActions:{5:[2,18],7:[2,2],24:[2,21],31:[2,20]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=[0],n=[],i=[null],r=[],s=this.table,a="",o=0,c=0,l=r.slice.call(arguments,1),h=Object.create(this.lexer),u={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(u.yy[y]=this.yy[y]);h.setInput(t,u.yy),u.yy.lexer=h,u.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;r.push(p);var d=h.options&&h.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,g,x,m,k,_,b,v,$,w={};;){if(g=e[e.length-1],this.defaultActions[g]?x=this.defaultActions[g]:(null==f&&($=void 0,"number"!=typeof($=n.pop()||h.lex()||1)&&($ instanceof Array&&($=(n=$).pop()),$=this.symbols_[$]||$),f=$),x=s[g]&&s[g][f]),void 0===x||!x.length||!x[0]){var M;for(k in v=[],s[g])this.terminals_[k]&&k>2&&v.push("'"+this.terminals_[k]+"'");M=h.showPosition?"Parse error on line "+(o+1)+":\n"+h.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(M,{text:h.match,token:this.terminals_[f]||f,line:h.yylineno,loc:p,expected:v})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+f);switch(x[0]){case 1:e.push(f),i.push(h.yytext),r.push(h.yylloc),e.push(x[1]),f=null,c=h.yyleng,a=h.yytext,o=h.yylineno,p=h.yylloc;break;case 2:if(_=this.productions_[x[1]][1],w.$=i[i.length-_],w._$={first_line:r[r.length-(_||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(_||1)].first_column,last_column:r[r.length-1].last_column},d&&(w._$.range=[r[r.length-(_||1)].range[0],r[r.length-1].range[1]]),void 0!==(m=this.performAction.apply(w,[a,c,o,u.yy,x[1],i,r].concat(l))))return m;_&&(e=e.slice(0,-1*_*2),i=i.slice(0,-1*_),r=r.slice(0,-1*_)),e.push(this.productions_[x[1]][0]),i.push(w.$),r.push(w._$),b=s[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},p={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;se[0].length)){if(e=n,i=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),26;case 1:return this.begin("type_directive"),27;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),29;case 4:return 28;case 5:case 6:case 8:case 9:break;case 7:return 11;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 24;case 21:return 25;case 22:return 15;case 23:return 6;case 24:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23,24],inclusive:!0}}};function d(){this.yy={}}return y.lexer=p,d.prototype=y,y.Parser=d,new d}());a.parser=a;const o=a;let c="";const l=[],h=[],u=[],y=function(){let t=!0;for(const[e,n]of u.entries())u[e].processed,t=t&&n.processed;return t},p={parseDirective:function(t,e,n){i.m.parseDirective(this,t,e,n)},getConfig:()=>(0,i.c)().journey,clear:function(){l.length=0,h.length=0,c="",u.length=0,(0,i.v)()},setDiagramTitle:i.r,getDiagramTitle:i.t,setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,addSection:function(t){c=t,l.push(t)},getSections:function(){return l},getTasks:function(){let t=y(),e=0;for(;!t&&e<100;)t=y(),e++;return h.push(...u),h},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,r=[];1===n.length?(i=Number(n[0]),r=[]):(i=Number(n[0]),r=n[1].split(","));const s=r.map((t=>t.trim())),a={section:c,type:c,people:s,task:t,score:i};u.push(a)},addTaskOrg:function(t){const e={section:c,type:c,description:t,task:t,classes:[]};h.push(e)},getActors:function(){return function(){const t=[];return h.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},d=function(t,e){return(0,s.d)(t,e)},f=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n};let g=-1;const x=function(){function t(t,e,n,r,s,a,o,c){i(e.append("text").attr("x",n+s/2).attr("y",r+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,r,s,a,o,c,l){const{taskFontSize:h,taskFontFamily:u}=c,y=t.split(//gi);for(let t=0;t3?function(t){const n=(0,r.Nb1)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(15/2.2);t.append("path").attr("class","mouth").attr("d",n).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(n):e.score<3?function(t){const n=(0,r.Nb1)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(15/2.2);t.append("path").attr("class","mouth").attr("d",n).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(n):n.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(a,{cx:i,cy:300+30*(5-e.score),score:e.score});const o=(0,s.g)();o.x=e.x,o.y=e.y,o.fill=e.fill,o.width=n.width,o.height=n.height,o.class="task task-type-"+e.num,o.rx=3,o.ry=3,d(a,o);let c=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:c,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};f(a,i),c+=10})),x(n)(e.task,a,o.x,o.y,o.width,o.height,{class:"task"},n,e.colour)},v={},$=(0,i.c)().journey,w=$.leftMargin,M={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,r){const s=(0,i.c)().journey,a=this;let o=0;this.sequenceItems.forEach((function(i){o++;const c=a.sequenceItems.length-o+1;a.updateVal(i,"starty",e-c*s.boxMargin,Math.min),a.updateVal(i,"stopy",r+c*s.boxMargin,Math.max),a.updateVal(M.data,"startx",t-c*s.boxMargin,Math.min),a.updateVal(M.data,"stopx",n+c*s.boxMargin,Math.max),a.updateVal(i,"startx",t-c*s.boxMargin,Math.min),a.updateVal(i,"stopx",n+c*s.boxMargin,Math.max),a.updateVal(M.data,"starty",e-c*s.boxMargin,Math.min),a.updateVal(M.data,"stopy",r+c*s.boxMargin,Math.max)}))},insert:function(t,e,n,i){const r=Math.min(t,n),s=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(M.data,"startx",r,Math.min),this.updateVal(M.data,"starty",a,Math.min),this.updateVal(M.data,"stopx",s,Math.max),this.updateVal(M.data,"stopy",o,Math.max),this.updateBounds(r,a,s,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},E=$.sectionFills,S=$.sectionColours,T={setConf:function(t){Object.keys(t).forEach((function(e){$[e]=t[e]}))},draw:function(t,e,n,s){const a=(0,i.c)().journey,o=(0,i.c)().securityLevel;let c;"sandbox"===o&&(c=(0,r.Ys)("#i"+e));const l="sandbox"===o?(0,r.Ys)(c.nodes()[0].contentDocument.body):(0,r.Ys)("body");M.init();const h=l.select("#"+e);h.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z");const u=s.db.getTasks(),y=s.db.getDiagramTitle(),p=s.db.getActors();for(const t in v)delete v[t];let d=0;p.forEach((t=>{v[t]={color:a.actorColours[d%a.actorColours.length],position:d},d++})),function(t){const e=(0,i.c)().journey;let n=60;Object.keys(v).forEach((i=>{const r=v[i].color,s={cx:20,cy:n,r:7,fill:r,stroke:"#000",pos:v[i].position};m(t,s);const a={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};_(t,a),n+=20}))}(h),M.insert(0,0,w,50*Object.keys(v).length),function(t,e,n){const r=(0,i.c)().journey;let s="";const a=n+(2*r.height+r.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[n,i]of e.entries()){if(s!==i.section){c=E[o%E.length],h=o%E.length,l=S[o%S.length];let a=0;const u=i.section;for(let t=n;t(v[e]&&(t[e]=v[e]),t)),{});i.x=n*r.taskMargin+n*r.width+w,i.y=a,i.width=r.diagramMarginX,i.height=r.diagramMarginY,i.colour=l,i.fill=c,i.num=h,i.actors=u,b(t,i,r),M.insert(i.x,i.y,i.x+i.width+r.taskMargin,450)}}(h,u,0);const f=M.getBounds();y&&h.append("text").text(y).attr("x",w).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const g=f.stopy-f.starty+2*a.diagramMarginY,x=w+f.stopx+2*a.diagramMarginX;(0,i.i)(h,g,x,a.useMaxWidth),h.append("line").attr("x1",w).attr("y1",4*a.height).attr("x2",x-w-4).attr("y2",4*a.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const $=y?70:0;h.attr("viewBox",`${f.startx} -25 ${x} ${g+$}`),h.attr("preserveAspectRatio","xMinYMin meet"),h.attr("height",g+$+25)}},A={parser:o,db:p,renderer:T,styles:t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,init:t=>{T.setConf(t.journey),p.clear()}}},8252:function(t,e,n){n.d(e,{a:function(){return a},b:function(){return l},c:function(){return c},d:function(){return s},e:function(){return u},f:function(){return o},g:function(){return h}});var i=n(7967),r=n(9339);const s=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const t in e.attrs)n.attr(t,e.attrs[t]);return void 0!==e.class&&n.attr("class",e.class),n},a=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,n).lower()},o=(t,e)=>{const n=e.text.replace(r.J," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const s=i.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),i},c=(t,e,n,r)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const a=(0,i.Nm)(r);s.attr("xlink:href",a)},l=(t,e,n,r)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const a=(0,i.Nm)(r);s.attr("xlink:href",`#${a}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),u=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/476-86e5cf96.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/476-86e5cf96.chunk.min.js new file mode 100644 index 000000000..460ee2ebc --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/476-86e5cf96.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[476],{9368:function(e,t,n){n.d(t,{c:function(){return o}});var r=n(9360),i=n(9103),a=function(e){return(0,i.Z)(e,4)},d=n(3836);function o(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:l(e),edges:s(e)};return r.Z(e.graph())||(t.value=a(e.graph())),t}function l(e){return d.Z(e.nodes(),(function(t){var n=e.node(t),i=e.parent(t),a={v:t};return r.Z(n)||(a.value=n),r.Z(i)||(a.parent=i),a}))}function s(e){return d.Z(e.edges(),(function(t){var n=e.edge(t),i={v:t.v,w:t.w};return r.Z(t.name)||(i.name=t.name),r.Z(n)||(i.value=n),i}))}n(5351)},6476:function(e,t,n){n.d(t,{r:function(){return X}});var r=n(3771),i=n(9368),a=n(6076),d=n(9339),o=n(5625),l=n(3506),s=n(7274);let c={},h={},g={};const f=(e,t)=>(d.l.trace("In isDecendant",t," ",e," = ",h[t].includes(e)),!!h[t].includes(e)),u=(e,t,n,r)=>{d.l.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),d.l.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)u(i,t,n,r);else{const a=t.node(i);d.l.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(d.l.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(d.l.debug("Setting parent",i,e),n.setParent(i,e)):(d.l.info("In copy ",e,"root",r,"data",t.node(e),r),d.l.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const o=t.edges(i);d.l.debug("Copying Edges",o),o.forEach((i=>{d.l.info("Edge",i);const a=t.edge(i.v,i.w,i.name);d.l.info("Edge data",a,r);try{((e,t)=>(d.l.info("Decendants of ",t," is ",h[t]),d.l.info("Edge is ",e),e.v!==t&&e.w!==t&&(h[t]?h[t].includes(e.v)||f(e.v,t)||f(e.w,t)||h[t].includes(e.w):(d.l.debug("Tilt, ",t,",not in decendants"),!1))))(i,r)?(d.l.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),d.l.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):d.l.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(e){d.l.error(e)}}))}d.l.debug("Removing node",i),t.removeNode(i)}))},w=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)g[i]=e,r=[...r,...w(i,t)];return r},p=(e,t)=>{d.l.trace("Searching",e);const n=t.children(e);if(d.l.trace("Searching children of id ",e,n),n.length<1)return d.l.trace("This is a valid node",e),e;for(const r of n){const n=p(r,t);if(n)return d.l.trace("Found replacement for",e," => ",n),n}},v=e=>c[e]&&c[e].externalConnections&&c[e]?c[e].id:e,y=(e,t)=>{if(d.l.warn("extractor - ",t,i.c(e),e.children("D")),t>10)return void d.l.error("Bailing out");let n=e.nodes(),r=!1;for(const t of n){const n=e.children(t);r=r||n.length>0}if(r){d.l.debug("Nodes = ",n,t);for(const r of n)if(d.l.debug("Extracting node",r,c,c[r]&&!c[r].externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",t),c[r])if(!c[r].externalConnections&&e.children(r)&&e.children(r).length>0){d.l.warn("Cluster without external connections, without a parent and with children",r,t);let n="TB"===e.graph().rankdir?"LR":"TB";c[r]&&c[r].clusterData&&c[r].clusterData.dir&&(n=c[r].clusterData.dir,d.l.warn("Fixing dir",c[r].clusterData.dir,n));const a=new o.k({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));d.l.warn("Old graph before copy",i.c(e)),u(r,e,a,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:c[r].clusterData,labelText:c[r].labelText,graph:a}),d.l.warn("New graph after copy node: (",r,")",i.c(a)),d.l.debug("Old graph after copy",i.c(e))}else d.l.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!c[r].externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),t),d.l.debug(c);else d.l.debug("Not a cluster",r,t);n=e.nodes(),d.l.warn("New list of nodes",n);for(const r of n){const n=e.node(r);d.l.warn(" Now next level",r,n),n.clusterNode&&y(n.graph,t+1)}}else d.l.debug("Done, no node has children",e.nodes())},x=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=x(e,r);n=[...n,...i]})),n},m={rect:(e,t)=>{d.l.info("Creating subgraph rect for ",t.id,t);const n=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),r=n.insert("rect",":first-child"),i=(0,d.n)((0,d.c)().flowchart.htmlLabels),o=n.insert("g").attr("class","cluster-label"),c="markdown"===t.labelType?(0,l.c)(o,t.labelText,{style:t.labelStyle,useHtmlLabels:i}):o.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let h=c.getBBox();if((0,d.n)((0,d.c)().flowchart.htmlLabels)){const e=c.children[0],t=(0,s.Ys)(c);h=e.getBoundingClientRect(),t.attr("width",h.width),t.attr("height",h.height)}const g=0*t.padding,f=g/2,u=t.width<=h.width+g?h.width+g:t.width;t.width<=h.width+g?t.diff=(h.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,d.l.trace("Data ",t,JSON.stringify(t)),r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-u/2).attr("y",t.y-t.height/2-f).attr("width",u).attr("height",t.height+g),i?o.attr("transform","translate("+(t.x-h.width/2)+", "+(t.y-t.height/2)+")"):o.attr("transform","translate("+t.x+", "+(t.y-t.height/2)+")");const w=r.node().getBBox();return t.width=w.width,t.height=w.height,t.intersect=function(e){return(0,a.i)(t,e)},n},roundedWithTitle:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),o=n.append("rect"),l=i.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let c=l.getBBox();if((0,d.n)((0,d.c)().flowchart.htmlLabels)){const e=l.children[0],t=(0,s.Ys)(l);c=e.getBoundingClientRect(),t.attr("width",c.width),t.attr("height",c.height)}c=l.getBBox();const h=0*t.padding,g=h/2,f=t.width<=c.width+t.padding?c.width+t.padding:t.width;t.width<=c.width+t.padding?t.diff=(c.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,r.attr("class","outer").attr("x",t.x-f/2-g).attr("y",t.y-t.height/2-g).attr("width",f+h).attr("height",t.height+h),o.attr("class","inner").attr("x",t.x-f/2-g).attr("y",t.y-t.height/2-g+c.height-1).attr("width",f+h).attr("height",t.height+h-c.height-3),i.attr("transform","translate("+(t.x-c.width/2)+", "+(t.y-t.height/2-t.padding/3+((0,d.n)((0,d.c)().flowchart.htmlLabels)?5:3))+")");const u=r.node().getBBox();return t.height=u.height,t.intersect=function(e){return(0,a.i)(t,e)},n},noteGroup:(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2-d).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.intersect=function(e){return(0,a.i)(t,e)},n},divider:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const o=r.node().getBBox();return t.width=o.width,t.height=o.height,t.diff=-t.padding/2,t.intersect=function(e){return(0,a.i)(t,e)},n}};let b={};const N=async(e,t,n,o)=>{d.l.info("Graph in recursive render: XXX",i.c(t),o);const l=t.graph().rankdir;d.l.trace("Dir in recursive render - dir:",l);const s=e.insert("g").attr("class","root");t.nodes()?d.l.info("Recursive render XXX",t.nodes()):d.l.info("No nodes found for",t),t.edges().length>0&&d.l.trace("Recursive edges",t.edge(t.edges()[0]));const h=s.insert("g").attr("class","clusters"),g=s.insert("g").attr("class","edgePaths"),f=s.insert("g").attr("class","edgeLabels"),u=s.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const r=t.node(e);if(void 0!==o){const n=JSON.parse(JSON.stringify(o.clusterData));d.l.info("Setting data for cluster XXX (",e,") ",n,o),t.setNode(o.id,n),t.parent(e)||(d.l.trace("Setting parent",e,o.id),t.setParent(e,o.id,n))}if(d.l.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),r&&r.clusterNode){d.l.info("Cluster identified",e,r.width,t.node(e));const i=await N(u,r.graph,n,t.node(e)),o=i.elem;(0,a.u)(r,o),r.diff=i.diff||0,d.l.info("Node bounds (abc123)",e,r,r.width,r.x,r.y),(0,a.s)(o,r),d.l.warn("Recursive render complete ",o,r)}else t.children(e).length>0?(d.l.info("Cluster - the non recursive path XXX",e,r.id,r,t),d.l.info(p(r.id,t)),c[r.id]={id:p(r.id,t),node:r}):(d.l.info("Node - the non recursive path",e,r.id,r),await(0,a.e)(u,t.node(e),l))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),d.l.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),d.l.info("Fix",c,"ids:",e.v,e.w,"Translateing: ",c[e.v],c[e.w]),(0,a.f)(f,n)})),t.edges().forEach((function(e){d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),d.l.info("#############################################"),d.l.info("### Layout ###"),d.l.info("#############################################"),d.l.info(t),(0,r.bK)(t),d.l.info("Graph after layout:",i.c(t));let w=0;return(e=>x(e,e.children()))(t).forEach((function(e){const n=t.node(e);d.l.info("Position "+e+": "+JSON.stringify(t.node(e))),d.l.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?(0,a.p)(n):t.children(e).length>0?(((e,t)=>{d.l.trace("Inserting cluster");const n=t.shape||"rect";b[t.id]=m[n](e,t)})(h,n),c[n.id].node=n):(0,a.p)(n)})),t.edges().forEach((function(e){const r=t.edge(e);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r);const i=(0,a.g)(g,e,r,c,n,t);(0,a.h)(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);d.l.info(e,n.type,n.diff),"group"===n.type&&(w=n.diff)})),{elem:s,diff:w}},X=async(e,t,n,r,o)=>{(0,a.a)(e,n,r,o),(0,a.b)(),(0,a.d)(),b={},h={},g={},c={},d.l.warn("Graph at first:",i.c(t)),((e,t)=>{e?(d.l.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(d.l.warn("Cluster identified",t," Replacement id in edges: ",p(t,e)),h[t]=w(t,e),c[t]={id:p(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(d.l.debug("Cluster identified",t,h),r.forEach((e=>{e.v!==t&&e.w!==t&&f(e.v,t)^f(e.w,t)&&(d.l.warn("Edge: ",e," leaves cluster ",t),d.l.warn("Decendants of XXX ",t,": ",h[t]),c[t].externalConnections=!0)}))):d.l.debug("Not a cluster ",t,h)})),e.edges().forEach((function(t){const n=e.edge(t);d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(d.l.warn("Fix XXX",c,"ids:",t.v,t.w,"Translating: ",c[t.v]," --- ",c[t.w]),c[t.v]&&c[t.w]&&c[t.v]===c[t.w]){d.l.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const o=JSON.parse(JSON.stringify(n)),l=JSON.parse(JSON.stringify(n));o.label="",o.arrowTypeEnd="none",l.label="",o.fromCluster=t.v,l.toCluster=t.v,e.setEdge(r,a,o,t.name+"-cyclic-special"),e.setEdge(a,i,l,t.name+"-cyclic-special")}else(c[t.v]||c[t.w])&&(d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v&&(n.fromCluster=t.v),i!==t.w&&(n.toCluster=t.w),d.l.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name))})),d.l.warn("Adjusted Graph",i.c(e)),y(e,0),d.l.trace(c)):d.l.debug("Opting out, no graph ")})(t),d.l.warn("Graph after:",i.c(t)),await N(e,t,r)}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/506-6950d52c.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/506-6950d52c.chunk.min.js new file mode 100644 index 000000000..6f9f0e345 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/506-6950d52c.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[506],{3506:function(e,n,t){t.d(n,{c:function(){return on}});var r={};t.r(r),t.d(r,{attentionMarkers:function(){return Le},contentInitial:function(){return Ce},disable:function(){return Me},document:function(){return we},flow:function(){return ze},flowInitial:function(){return Te},insideSpan:function(){return _e},string:function(){return De},text:function(){return Be}});var i=t(9339);const u={};function o(e,n,t){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||t?e.value:"";if(n&&"alt"in e&&e.alt)return e.alt;if("children"in e)return c(e.children,n,t)}return Array.isArray(e)?c(e,n,t):""}function c(e,n,t){const r=[];let i=-1;for(;++ii?0:i+n:n>i?i:n,t=t>0?t:0,r.length<1e4)u=Array.from(r),u.unshift(n,t),e.splice(...u);else for(t&&e.splice(n,t);o0?(s(e,e.length,0,n),e):n}const a={}.hasOwnProperty;function f(e,n){let t;for(t in n){const r=(a.call(e,t)?e[t]:void 0)||(e[t]={}),i=n[t];let u;if(i)for(u in i){a.call(r,u)||(r[u]=[]);const e=i[u];d(r[u],Array.isArray(e)?e:e?[e]:[])}}}function d(e,n){let t=-1;const r=[];for(;++tu))return;const t=n.events.length;let i,c,l=t;for(;l--;)if("exit"===n.events[l][0]&&"chunkFlow"===n.events[l][1].type){if(i){c=n.events[l][1].end;break}i=!0}for(k(o),e=t;er;){const r=t[i];n.containerState=r[1],r[0].exit.call(n,e)}t.length=r}function y(){r.write([null]),i=void 0,r=void 0,n.containerState._closeFlow=void 0}}},T={tokenize:function(e,n,t){return I(e,e.attempt(this.parser.constructs.document,n,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}},z={tokenize:function(e,n,t){return function(n){return v(n)?I(e,r,"linePrefix")(n):r(n)};function r(e){return null===e||F(e)?n(e):t(e)}},partial:!0};function D(e){const n={};let t,r,i,u,o,c,l,a=-1;for(;++a=4?n(i):e.interrupt(r.parser.constructs.flow,t,n)(i)}},partial:!0},M={tokenize:function(e){const n=this,t=e.attempt(z,(function(r){if(null!==r)return e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),n.currentConstruct=void 0,t;e.consume(r)}),e.attempt(this.parser.constructs.flowInitial,r,I(e,e.attempt(this.parser.constructs.flow,r,e.attempt(_,r)),"linePrefix")));return t;function r(r){if(null!==r)return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),n.currentConstruct=void 0,t;e.consume(r)}}},P={resolveAll:R()},O=H("string"),j=H("text");function H(e){return{tokenize:function(n){const t=this,r=this.parser.constructs[e],i=n.attempt(r,u,o);return u;function u(e){return s(e)?i(e):o(e)}function o(e){if(null!==e)return n.enter("data"),n.consume(e),c;n.consume(e)}function c(e){return s(e)?(n.exit("data"),i(e)):(n.consume(e),c)}function s(e){if(null===e)return!0;const n=r[e];let i=-1;if(n)for(;++i-1){const e=o[0];"string"==typeof e?o[0]=e.slice(r):o.shift()}u>0&&o.push(e[i].slice(0,u))}return o}(o,e)}function g(){const{line:e,column:n,offset:t,_index:i,_bufferIndex:u}=r;return{line:e,column:n,offset:t,_index:i,_bufferIndex:u}}function x(e){a=void 0,h=e,p=p(e)}function k(e,n){n.restore()}function y(e,n){return function(t,i,u){let o,s,l,h;return Array.isArray(t)?m(t):"tokenize"in t?m([t]):(p=t,function(e){const n=null!==e&&p[e],t=null!==e&&p.null;return m([...Array.isArray(n)?n:n?[n]:[],...Array.isArray(t)?t:t?[t]:[]])(e)});var p;function m(e){return o=e,s=0,0===e.length?u:x(e[s])}function x(e){return function(t){return h=function(){const e=g(),n=d.previous,t=d.currentConstruct,i=d.events.length,u=Array.from(c);return{restore:function(){r=e,d.previous=n,d.currentConstruct=t,d.events.length=i,c=u,v()},from:i}}(),l=e,e.partial||(d.currentConstruct=e),e.name&&d.parser.constructs.disable.null.includes(e.name)?y():e.tokenize.call(n?Object.assign(Object.create(d),n):d,f,k,y)(t)}}function k(n){return a=!0,e(l,h),i}function y(e){return a=!0,h.restore(),++s=3&&(null===u||F(u))?(e.exit("thematicBreak"),n(u)):t(u)}function o(n){return n===r?(e.consume(n),i++,o):(e.exit("thematicBreakSequence"),v(n)?I(e,u,"whitespace")(n):u(n))}}},U={name:"list",tokenize:function(e,n,t){const r=this,i=r.events[r.events.length-1];let u=i&&"linePrefix"===i[1].type?i[2].sliceSerialize(i[1],!0).length:0,o=0;return function(n){const i=r.containerState.type||(42===n||43===n||45===n?"listUnordered":"listOrdered");if("listUnordered"===i?!r.containerState.marker||n===r.containerState.marker:x(n)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),"listUnordered"===i)return e.enter("listItemPrefix"),42===n||45===n?e.check(N,t,s)(n):s(n);if(!r.interrupt||49===n)return e.enter("listItemPrefix"),e.enter("listItemValue"),c(n)}return t(n)};function c(n){return x(n)&&++o<10?(e.consume(n),c):(!r.interrupt||o<2)&&(r.containerState.marker?n===r.containerState.marker:41===n||46===n)?(e.exit("listItemValue"),s(n)):t(n)}function s(n){return e.enter("listItemMarker"),e.consume(n),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||n,e.check(z,r.interrupt?t:l,e.attempt($,f,a))}function l(e){return r.containerState.initialBlankLine=!0,u++,f(e)}function a(n){return v(n)?(e.enter("listItemPrefixWhitespace"),e.consume(n),e.exit("listItemPrefixWhitespace"),f):t(n)}function f(t){return r.containerState.size=u+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,n(t)}},continuation:{tokenize:function(e,n,t){const r=this;return r.containerState._closeFlow=void 0,e.check(z,(function(t){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,I(e,n,"listItemIndent",r.containerState.size+1)(t)}),(function(t){return r.containerState.furtherBlankLines||!v(t)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,i(t)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(W,n,i)(t))}));function i(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,I(e,e.attempt(U,n,t),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(i)}}},exit:function(e){e.exit(this.containerState.type)}},$={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return!v(e)&&i&&"listItemPrefixWhitespace"===i[1].type?n(e):t(e)}),"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5)},partial:!0},W={tokenize:function(e,n,t){const r=this;return I(e,(function(e){const i=r.events[r.events.length-1];return i&&"listItemIndent"===i[1].type&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?n(e):t(e)}),"listItemIndent",r.containerState.size+1)},partial:!0},Z={name:"blockQuote",tokenize:function(e,n,t){const r=this;return function(n){if(62===n){const t=r.containerState;return t.open||(e.enter("blockQuote",{_container:!0}),t.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(n),e.exit("blockQuoteMarker"),i}return t(n)};function i(t){return v(t)?(e.enter("blockQuotePrefixWhitespace"),e.consume(t),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),n):(e.exit("blockQuotePrefix"),n(t))}},continuation:{tokenize:function(e,n,t){const r=this;return function(n){return v(n)?I(e,i,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):i(n)};function i(r){return e.attempt(Z,n,t)(r)}}},exit:function(e){e.exit("blockQuote")}};function Y(e,n,t,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(n){return 60===n?(e.enter(r),e.enter(i),e.enter(u),e.consume(n),e.exit(u),f):null===n||32===n||41===n||g(n)?t(n):(e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(n))};function f(t){return 62===t?(e.enter(u),e.consume(t),e.exit(u),e.exit(i),e.exit(r),n):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(t))}function d(n){return 62===n?(e.exit("chunkString"),e.exit(c),f(n)):null===n||60===n||F(n)?t(n):(e.consume(n),92===n?h:d)}function h(n){return 60===n||62===n||92===n?(e.consume(n),d):d(n)}function p(i){return a||null!==i&&41!==i&&!b(i)?a999||null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs?t(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),n):F(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(n){return null===n||91===n||93===n||F(n)||s++>999?(e.exit("chunkString"),l(n)):(e.consume(n),c||(c=!v(n)),92===n?f:a)}function f(n){return 91===n||92===n||93===n?(e.consume(n),s++,a):a(n)}}function J(e,n,t,r,i,u){let o;return function(n){return 34===n||39===n||40===n?(e.enter(r),e.enter(i),e.consume(n),e.exit(i),o=40===n?41:n,c):t(n)};function c(t){return t===o?(e.enter(i),e.consume(t),e.exit(i),e.exit(r),n):(e.enter(u),s(t))}function s(n){return n===o?(e.exit(u),c(o)):null===n?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),I(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(n))}function l(n){return n===o||null===n||F(n)?(e.exit("chunkString"),s(n)):(e.consume(n),92===n?a:l)}function a(n){return n===o||92===n?(e.consume(n),l):l(n)}}function K(e,n){let t;return function r(i){return F(i)?(e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),t=!0,r):v(i)?I(e,r,t?"linePrefix":"lineSuffix")(i):n(i)}}function X(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ee={name:"definition",tokenize:function(e,n,t){const r=this;let i;return function(n){return e.enter("definition"),function(n){return G.call(r,e,u,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(n)}(n)};function u(n){return i=X(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===n?(e.enter("definitionMarker"),e.consume(n),e.exit("definitionMarker"),o):t(n)}function o(n){return b(n)?K(e,c)(n):c(n)}function c(n){return Y(e,s,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(n)}function s(n){return e.attempt(ne,l,l)(n)}function l(n){return v(n)?I(e,a,"whitespace")(n):a(n)}function a(u){return null===u||F(u)?(e.exit("definition"),r.parser.defined.push(i),n(u)):t(u)}}},ne={tokenize:function(e,n,t){return function(n){return b(n)?K(e,r)(n):t(n)};function r(n){return J(e,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(n)}function i(n){return v(n)?I(e,u,"whitespace")(n):u(n)}function u(e){return null===e||F(e)?n(e):t(e)}},partial:!0},te={name:"codeIndented",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("codeIndented"),I(e,i,"linePrefix",5)(n)};function i(e){const n=r.events[r.events.length-1];return n&&"linePrefix"===n[1].type&&n[2].sliceSerialize(n[1],!0).length>=4?u(e):t(e)}function u(n){return null===n?c(n):F(n)?e.attempt(re,u,c)(n):(e.enter("codeFlowValue"),o(n))}function o(n){return null===n||F(n)?(e.exit("codeFlowValue"),u(n)):(e.consume(n),o)}function c(t){return e.exit("codeIndented"),n(t)}}},re={tokenize:function(e,n,t){const r=this;return i;function i(n){return r.parser.lazy[r.now().line]?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i):I(e,u,"linePrefix",5)(n)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(e):F(e)?i(e):t(e)}},partial:!0},ie={name:"headingAtx",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("atxHeading"),function(n){return e.enter("atxHeadingSequence"),i(n)}(n)};function i(n){return 35===n&&r++<6?(e.consume(n),i):null===n||b(n)?(e.exit("atxHeadingSequence"),u(n)):t(n)}function u(t){return 35===t?(e.enter("atxHeadingSequence"),o(t)):null===t||F(t)?(e.exit("atxHeading"),n(t)):v(t)?I(e,u,"whitespace")(t):(e.enter("atxHeadingText"),c(t))}function o(n){return 35===n?(e.consume(n),o):(e.exit("atxHeadingSequence"),u(n))}function c(n){return null===n||35===n||b(n)?(e.exit("atxHeadingText"),u(n)):(e.consume(n),c)}},resolve:function(e,n){let t,r,i=e.length-2,u=3;return"whitespace"===e[u][1].type&&(u+=2),i-2>u&&"whitespace"===e[i][1].type&&(i-=2),"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4),i>u&&(t={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},s(e,u,i-u+1,[["enter",t,n],["enter",r,n],["exit",r,n],["exit",t,n]])),e}},ue={name:"setextUnderline",tokenize:function(e,n,t){const r=this;let i;return function(n){let o,c=r.events.length;for(;c--;)if("lineEnding"!==r.events[c][1].type&&"linePrefix"!==r.events[c][1].type&&"content"!==r.events[c][1].type){o="paragraph"===r.events[c][1].type;break}return r.parser.lazy[r.now().line]||!r.interrupt&&!o?t(n):(e.enter("setextHeadingLine"),i=n,function(n){return e.enter("setextHeadingLineSequence"),u(n)}(n))};function u(n){return n===i?(e.consume(n),u):(e.exit("setextHeadingLineSequence"),v(n)?I(e,o,"lineSuffix")(n):o(n))}function o(r){return null===r||F(r)?(e.exit("setextHeadingLine"),n(r)):t(r)}},resolveTo:function(e,n){let t,r,i,u=e.length;for(;u--;)if("enter"===e[u][0]){if("content"===e[u][1].type){t=u;break}"paragraph"===e[u][1].type&&(r=u)}else"content"===e[u][1].type&&e.splice(u,1),i||"definition"!==e[u][1].type||(i=u);const o={type:"setextHeading",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)};return e[r][1].type="setextHeadingText",i?(e.splice(r,0,["enter",o,n]),e.splice(i+1,0,["exit",e[t][1],n]),e[t][1].end=Object.assign({},e[i][1].end)):e[t][1]=o,e.push(["exit",o,n]),e}},oe=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],ce=["pre","script","style","textarea"],se={name:"htmlFlow",tokenize:function(e,n,t){const r=this;let i,u,o,c,s;return function(n){return function(n){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(n),l}(n)};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),u=!0,m):63===c?(e.consume(c),i=3,r.interrupt?n:H):h(c)?(e.consume(c),o=String.fromCharCode(c),g):t(c)}function a(u){return 45===u?(e.consume(u),i=2,f):91===u?(e.consume(u),i=5,c=0,d):h(u)?(e.consume(u),i=4,r.interrupt?n:H):t(u)}function f(i){return 45===i?(e.consume(i),r.interrupt?n:H):t(i)}function d(i){return i==="CDATA[".charCodeAt(c++)?(e.consume(i),6===c?r.interrupt?n:D:d):t(i)}function m(n){return h(n)?(e.consume(n),o=String.fromCharCode(n),g):t(n)}function g(c){if(null===c||47===c||62===c||b(c)){const s=47===c,l=o.toLowerCase();return s||u||!ce.includes(l)?oe.includes(o.toLowerCase())?(i=6,s?(e.consume(c),x):r.interrupt?n(c):D(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?t(c):u?k(c):y(c)):(i=1,r.interrupt?n(c):D(c))}return 45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):t(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?n:D):t(i)}function k(n){return v(n)?(e.consume(n),k):T(n)}function y(n){return 47===n?(e.consume(n),T):58===n||95===n||h(n)?(e.consume(n),S):v(n)?(e.consume(n),y):T(n)}function S(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),S):E(n)}function E(n){return 61===n?(e.consume(n),A):v(n)?(e.consume(n),E):y(n)}function A(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),s=n,I):v(n)?(e.consume(n),A):w(n)}function I(n){return n===s?(e.consume(n),s=null,C):null===n||F(n)?t(n):(e.consume(n),I)}function w(n){return null===n||34===n||39===n||47===n||60===n||61===n||62===n||96===n||b(n)?E(n):(e.consume(n),w)}function C(e){return 47===e||62===e||v(e)?y(e):t(e)}function T(n){return 62===n?(e.consume(n),z):t(n)}function z(n){return null===n||F(n)?D(n):v(n)?(e.consume(n),z):t(n)}function D(n){return 45===n&&2===i?(e.consume(n),M):60===n&&1===i?(e.consume(n),P):62===n&&4===i?(e.consume(n),R):63===n&&3===i?(e.consume(n),H):93===n&&5===i?(e.consume(n),j):!F(n)||6!==i&&7!==i?null===n||F(n)?(e.exit("htmlFlowData"),B(n)):(e.consume(n),D):(e.exit("htmlFlowData"),e.check(le,q,B)(n))}function B(n){return e.check(ae,_,q)(n)}function _(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),L}function L(n){return null===n||F(n)?B(n):(e.enter("htmlFlowData"),D(n))}function M(n){return 45===n?(e.consume(n),H):D(n)}function P(n){return 47===n?(e.consume(n),o="",O):D(n)}function O(n){if(62===n){const t=o.toLowerCase();return ce.includes(t)?(e.consume(n),R):D(n)}return h(n)&&o.length<8?(e.consume(n),o+=String.fromCharCode(n),O):D(n)}function j(n){return 93===n?(e.consume(n),H):D(n)}function H(n){return 62===n?(e.consume(n),R):45===n&&2===i?(e.consume(n),H):D(n)}function R(n){return null===n||F(n)?(e.exit("htmlFlowData"),q(n)):(e.consume(n),R)}function q(t){return e.exit("htmlFlow"),n(t)}},resolveTo:function(e){let n=e.length;for(;n--&&("enter"!==e[n][0]||"htmlFlow"!==e[n][1].type););return n>1&&"linePrefix"===e[n-2][1].type&&(e[n][1].start=e[n-2][1].start,e[n+1][1].start=e[n-2][1].start,e.splice(n-2,2)),e},concrete:!0},le={tokenize:function(e,n,t){return function(r){return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),e.attempt(z,n,t)}},partial:!0},ae={tokenize:function(e,n,t){const r=this;return function(n){return F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i):t(n)};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0},fe={tokenize:function(e,n,t){const r=this;return function(n){return null===n?t(n):(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i)};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0},de={name:"codeFenced",tokenize:function(e,n,t){const r=this,i={tokenize:function(e,n,t){let i=0;return function(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),o};function o(n){return e.enter("codeFencedFence"),v(n)?I(e,s,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):s(n)}function s(n){return n===u?(e.enter("codeFencedFenceSequence"),l(n)):t(n)}function l(n){return n===u?(i++,e.consume(n),l):i>=c?(e.exit("codeFencedFenceSequence"),v(n)?I(e,a,"whitespace")(n):a(n)):t(n)}function a(r){return null===r||F(r)?(e.exit("codeFencedFence"),n(r)):t(r)}},partial:!0};let u,o=0,c=0;return function(n){return function(n){const t=r.events[r.events.length-1];return o=t&&"linePrefix"===t[1].type?t[2].sliceSerialize(t[1],!0).length:0,u=n,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),s(n)}(n)};function s(n){return n===u?(c++,e.consume(n),s):c<3?t(n):(e.exit("codeFencedFenceSequence"),v(n)?I(e,l,"whitespace")(n):l(n))}function l(t){return null===t||F(t)?(e.exit("codeFencedFence"),r.interrupt?n(t):e.check(fe,h,k)(t)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),a(t))}function a(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),l(n)):v(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),I(e,f,"whitespace")(n)):96===n&&n===u?t(n):(e.consume(n),a)}function f(n){return null===n||F(n)?l(n):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),d(n))}function d(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),l(n)):96===n&&n===u?t(n):(e.consume(n),d)}function h(n){return e.attempt(i,k,p)(n)}function p(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),m}function m(n){return o>0&&v(n)?I(e,g,"linePrefix",o+1)(n):g(n)}function g(n){return null===n||F(n)?e.check(fe,h,k)(n):(e.enter("codeFlowValue"),x(n))}function x(n){return null===n||F(n)?(e.exit("codeFlowValue"),g(n)):(e.consume(n),x)}function k(t){return e.exit("codeFenced"),n(t)}},concrete:!0},he=document.createElement("i");function pe(e){const n="&"+e+";";he.innerHTML=n;const t=he.textContent;return(59!==t.charCodeAt(t.length-1)||"semi"===e)&&t!==n&&t}const me={name:"characterReference",tokenize:function(e,n,t){const r=this;let i,u,o=0;return function(n){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(n),e.exit("characterReferenceMarker"),c};function c(n){return 35===n?(e.enter("characterReferenceMarkerNumeric"),e.consume(n),e.exit("characterReferenceMarkerNumeric"),s):(e.enter("characterReferenceValue"),i=31,u=p,l(n))}function s(n){return 88===n||120===n?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(n),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),i=6,u=k,l):(e.enter("characterReferenceValue"),i=7,u=x,l(n))}function l(c){if(59===c&&o){const i=e.exit("characterReferenceValue");return u!==p||pe(r.sliceSerialize(i))?(e.enter("characterReferenceMarker"),e.consume(c),e.exit("characterReferenceMarker"),e.exit("characterReference"),n):t(c)}return u(c)&&o++1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[t][1].end),p=Object.assign({},e[d][1].start);Ee(h,-c),Ee(p,c),u={type:c>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[t][1].end)},o={type:c>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:c>1?"strongText":"emphasisText",start:Object.assign({},e[t][1].end),end:Object.assign({},e[d][1].start)},r={type:c>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},o.end)},e[t][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},o.end),a=[],e[t][1].end.offset-e[t][1].start.offset&&(a=l(a,[["enter",e[t][1],n],["exit",e[t][1],n]])),a=l(a,[["enter",r,n],["enter",u,n],["exit",u,n],["enter",i,n]]),a=l(a,V(n.parser.constructs.insideSpan.null,e.slice(t+1,d),n)),a=l(a,[["exit",i,n],["enter",o,n],["exit",o,n],["exit",r,n]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=l(a,[["enter",e[d][1],n],["exit",e[d][1],n]])):f=0,s(e,t-1,d-t+3,a),d=t+a.length-f-2;break}for(d=-1;++d13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||65535==(65535&t)||65534==(65535&t)||t>1114111?"�":String.fromCharCode(t)}const je=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function He(e,n,t){if(n)return n;if(35===t.charCodeAt(0)){const e=t.charCodeAt(1),n=120===e||88===e;return Oe(t.slice(n?2:1),n?16:10)}return pe(t)||e}function Re(e){return e&&"object"==typeof e?"position"in e||"type"in e?Ve(e.position):"start"in e||"end"in e?Ve(e):"line"in e||"column"in e?qe(e):"":""}function qe(e){return Qe(e&&e.line)+":"+Qe(e&&e.column)}function Ve(e){return qe(e&&e.start)+"-"+qe(e&&e.end)}function Qe(e){return e&&"number"==typeof e?e:1}const Ne={}.hasOwnProperty,Ue=function(e,n,t){return"string"!=typeof n&&(t=n,n=void 0),function(e){const n={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:s(v),autolinkProtocol:p,autolinkEmail:p,atxHeading:s(y),blockQuote:s((function(){return{type:"blockquote",children:[]}})),characterEscape:p,characterReference:p,codeFenced:s(k),codeFencedFenceInfo:l,codeFencedFenceMeta:l,codeIndented:s(k,l),codeText:s((function(){return{type:"inlineCode",value:""}}),l),codeTextData:p,data:p,codeFlowValue:p,definition:s((function(){return{type:"definition",identifier:"",label:null,title:null,url:""}})),definitionDestinationString:l,definitionLabelString:l,definitionTitleString:l,emphasis:s((function(){return{type:"emphasis",children:[]}})),hardBreakEscape:s(F),hardBreakTrailing:s(F),htmlFlow:s(b,l),htmlFlowData:p,htmlText:s(b,l),htmlTextData:p,image:s((function(){return{type:"image",title:null,url:"",alt:null}})),label:l,link:s(v),listItem:s((function(e){return{type:"listItem",spread:e._spread,checked:null,children:[]}})),listItemValue:function(e){c("expectingFirstListItemValue")&&(this.stack[this.stack.length-2].start=Number.parseInt(this.sliceSerialize(e),10),i("expectingFirstListItemValue"))},listOrdered:s(S,(function(){i("expectingFirstListItemValue",!0)})),listUnordered:s(S),paragraph:s((function(){return{type:"paragraph",children:[]}})),reference:function(){i("referenceType","collapsed")},referenceString:l,resourceDestinationString:l,resourceTitleString:l,setextHeading:s(y),strong:s((function(){return{type:"strong",children:[]}})),thematicBreak:s((function(){return{type:"thematicBreak"}}))},exit:{atxHeading:f(),atxHeadingSequence:function(e){const n=this.stack[this.stack.length-1];if(!n.depth){const t=this.sliceSerialize(e).length;n.depth=t}},autolink:f(),autolinkEmail:function(e){m.call(this,e),this.stack[this.stack.length-1].url="mailto:"+this.sliceSerialize(e)},autolinkProtocol:function(e){m.call(this,e),this.stack[this.stack.length-1].url=this.sliceSerialize(e)},blockQuote:f(),characterEscapeValue:m,characterReferenceMarkerHexadecimal:x,characterReferenceMarkerNumeric:x,characterReferenceValue:function(e){const n=this.sliceSerialize(e),t=c("characterReferenceType");let r;t?(r=Oe(n,"characterReferenceMarkerNumeric"===t?10:16),i("characterReferenceType")):r=pe(n);const u=this.stack.pop();u.value+=r,u.position.end=$e(e.end)},codeFenced:f((function(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),i("flowCodeInside")})),codeFencedFence:function(){c("flowCodeInside")||(this.buffer(),i("flowCodeInside",!0))},codeFencedFenceInfo:function(){const e=this.resume();this.stack[this.stack.length-1].lang=e},codeFencedFenceMeta:function(){const e=this.resume();this.stack[this.stack.length-1].meta=e},codeFlowValue:m,codeIndented:f((function(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/(\r?\n|\r)$/g,"")})),codeText:f((function(){const e=this.resume();this.stack[this.stack.length-1].value=e})),codeTextData:m,data:m,definition:f(),definitionDestinationString:function(){const e=this.resume();this.stack[this.stack.length-1].url=e},definitionLabelString:function(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase()},definitionTitleString:function(){const e=this.resume();this.stack[this.stack.length-1].title=e},emphasis:f(),hardBreakEscape:f(g),hardBreakTrailing:f(g),htmlFlow:f((function(){const e=this.resume();this.stack[this.stack.length-1].value=e})),htmlFlowData:m,htmlText:f((function(){const e=this.resume();this.stack[this.stack.length-1].value=e})),htmlTextData:m,image:f((function(){const e=this.stack[this.stack.length-1];if(c("inReference")){const n=c("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;i("referenceType")})),label:function(){const e=this.stack[this.stack.length-1],n=this.resume(),t=this.stack[this.stack.length-1];if(i("inReference",!0),"link"===t.type){const n=e.children;t.children=n}else t.alt=n},labelText:function(e){const n=this.sliceSerialize(e),t=this.stack[this.stack.length-2];t.label=function(e){return e.replace(je,He)}(n),t.identifier=X(n).toLowerCase()},lineEnding:function(e){const t=this.stack[this.stack.length-1];if(c("atHardBreak"))return t.children[t.children.length-1].position.end=$e(e.end),void i("atHardBreak");!c("setextHeadingSlurpLineEnding")&&n.canContainEols.includes(t.type)&&(p.call(this,e),m.call(this,e))},link:f((function(){const e=this.stack[this.stack.length-1];if(c("inReference")){const n=c("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;i("referenceType")})),listItem:f(),listOrdered:f(),listUnordered:f(),paragraph:f(),referenceString:function(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=X(this.sliceSerialize(e)).toLowerCase(),i("referenceType","full")},resourceDestinationString:function(){const e=this.resume();this.stack[this.stack.length-1].url=e},resourceTitleString:function(){const e=this.resume();this.stack[this.stack.length-1].title=e},resource:function(){i("inReference")},setextHeading:f((function(){i("setextHeadingSlurpLineEnding")})),setextHeadingLineSequence:function(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2},setextHeadingText:function(){i("setextHeadingSlurpLineEnding",!0)},strong:f(),thematicBreak:f()}};We(n,(e||{}).mdastExtensions||[]);const t={};return function(e){let t={type:"root",children:[]};const u={stack:[t],tokenStack:[],config:n,enter:a,exit:d,buffer:l,resume:h,setData:i,getData:c},o=[];let s=-1;for(;++s0){const e=u.tokenStack[u.tokenStack.length-1];(e[1]||Ye).call(u,void 0,e[0])}for(t.position={start:$e(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:$e(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},s=-1;++s{0!==t&&(i++,r.push([])),e.split(" ").forEach((e=>{e&&r[i].push({content:e,type:n})}))})):"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((n=>{u(n,e.type)}))}return t.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{u(e)}))})),r}function Ke(e,n){var t;return Xe(e,[],(t=n.content,Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map((e=>e.segment)):[...t]),n.type)}function Xe(e,n,t,r){if(0===t.length)return[{content:n.join(""),type:r},{content:"",type:r}];const[i,...u]=t,o=[...n,i];return e([{content:o.join(""),type:r}])?Xe(e,o,u,r):(0===n.length&&i&&(n.push(i),t.shift()),[{content:n.join(""),type:r},{content:t.join(""),type:r}])}function en(e,n){if(e.some((({content:e})=>e.includes("\n"))))throw new Error("splitLineToFitWidth does not support newlines in the line");return nn(e,n)}function nn(e,n,t=[],r=[]){if(0===e.length)return r.length>0&&t.push(r),t.length>0?t:[];let i="";" "===e[0].content&&(i=" ",e.shift());const u=e.shift()??{content:" ",type:"normal"},o=[...r];if(""!==i&&o.push({content:i,type:"normal"}),o.push(u),n(o))return nn(e,n,t,o);if(r.length>0)t.push(r),e.unshift(u);else if(u.content){const[r,i]=Ke(n,u);t.push([r]),i.content&&e.unshift(i)}return nn(e,n,t)}function tn(e,n,t){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",n*t-.1+"em").attr("dy",t+"em")}function rn(e,n,t){const r=e.append("text"),i=tn(r,1,n);un(i,t);const u=i.node().getComputedTextLength();return r.remove(),u}function un(e,n){e.text(""),n.forEach(((n,t)=>{const r=e.append("tspan").attr("font-style","emphasis"===n.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===n.type?"bold":"normal");0===t?r.text(n.content):r.text(" "+n.content)}))}const on=(e,n="",{style:t="",isTitle:r=!1,classes:u="",useHtmlLabels:o=!0,isNode:c=!0,width:s=200,addSvgBackground:l=!1}={})=>{if(i.l.info("createText",n,t,r,u,o,c,l),o){const r=function(e){const{children:n}=Ue(e);return n.map((function e(n){return"text"===n.type?n.value.replace(/\n/g,"
        "):"strong"===n.type?`${n.children.map(e).join("")}`:"emphasis"===n.type?`${n.children.map(e).join("")}`:"paragraph"===n.type?`

        ${n.children.map(e).join("")}

        `:`Unsupported markdown: ${n.type}`})).join("")}(n),o=function(e,n,t,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=n.label,s=n.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n "+c+""),l=o,(a=n.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",t+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===t&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",t+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(e,{isNode:c,label:(0,i.L)(r).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``)),labelStyle:t.replace("fill:","color:")},s,u,l);return o}{const t=function(e,n,t,r=!1){const i=n.append("g"),u=i.insert("rect").attr("class","background"),o=i.append("text").attr("y","-10.1");let c=0;for(const n of t){const t=n=>rn(i,1.1,n)<=e,r=t(n)?[n]:en(n,t);for(const e of r)un(tn(o,c,1.1),e),c++}if(r){const e=o.node().getBBox(),n=2;return u.attr("x",-n).attr("y",-n).attr("width",e.width+2*n).attr("height",e.height+2*n),i.node()}return o.node()}(s,e,Je(n),l);return t}}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/519-8d0cec7f.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/519-8d0cec7f.chunk.min.js new file mode 100644 index 000000000..5762f1020 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/519-8d0cec7f.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[519],{9519:function(t,e,a){a.d(e,{diagram:function(){return g}});var r=a(1423),n=a(7274),i=a(3771),d=a(5625),o=a(9339),s=a(7863);a(7484),a(7967),a(7856);let l={};const p=function(t){const e=Object.entries(l).find((e=>e[1].label===t));if(e)return e[0]},c={draw:function(t,e,a,r){const c=(0,o.c)().class;l={},o.l.info("Rendering diagram "+t);const g=(0,o.c)().securityLevel;let h;"sandbox"===g&&(h=(0,n.Ys)("#i"+e));const f="sandbox"===g?(0,n.Ys)(h.nodes()[0].contentDocument.body):(0,n.Ys)("body"),u=f.select(`[id='${e}']`);var x;(x=u).append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),x.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),x.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),x.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),x.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),x.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),x.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),x.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z");const y=new d.k({multigraph:!0});y.setGraph({isMultiGraph:!0}),y.setDefaultEdgeLabel((function(){return{}}));const b=r.db.getClasses(),m=Object.keys(b);for(const t of m){const e=b[t],a=s.s.drawClass(u,e,c,r);l[a.id]=a,y.setNode(a.id,a),o.l.info("Org height: "+a.height)}r.db.getRelations().forEach((function(t){o.l.info("tjoho"+p(t.id1)+p(t.id2)+JSON.stringify(t)),y.setEdge(p(t.id1),p(t.id2),{relation:t},t.title||"DEFAULT")})),r.db.getNotes().forEach((function(t){o.l.debug(`Adding note: ${JSON.stringify(t)}`);const e=s.s.drawNote(u,t,c,r);l[e.id]=e,y.setNode(e.id,e),t.class&&t.class in b&&y.setEdge(t.id,p(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),(0,i.bK)(y),y.nodes().forEach((function(t){void 0!==t&&void 0!==y.node(t)&&(o.l.debug("Node "+t+": "+JSON.stringify(y.node(t))),f.select("#"+(r.db.lookUpDomId(t)||t)).attr("transform","translate("+(y.node(t).x-y.node(t).width/2)+","+(y.node(t).y-y.node(t).height/2)+" )"))})),y.edges().forEach((function(t){void 0!==t&&void 0!==y.edge(t)&&(o.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(y.edge(t))),s.s.drawEdge(u,y.edge(t),y.edge(t).relation,c,r))}));const w=u.node().getBBox(),k=w.width+40,E=w.height+40;(0,o.i)(u,E,k,c.useMaxWidth);const L=`${w.x-20} ${w.y-20} ${k} ${E}`;o.l.debug(`viewBox ${L}`),u.attr("viewBox",L)}},g={parser:r.p,db:r.d,renderer:c,styles:r.s,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,r.d.clear()}}},7863:function(t,e,a){a.d(e,{p:function(){return o},s:function(){return p}});var r=a(7274),n=a(9339);let i=0;const d=function(t){let e=t.id;return t.type&&(e+="<"+t.type+">"),e},o=function(t){let e="",a="",r="",i="",d=t.substring(0,1),o=t.substring(t.length-1,t.length);d.match(/[#+~-]/)&&(i=d);let s=/[\s\w)~]/;o.match(s)||(a=l(o));const p=""===i?0:1;let c=""===a?t.length:t.length-1;const g=(t=t.substring(p,c)).indexOf("("),h=t.indexOf(")");if(g>1&&h>g&&h<=t.length){let d=t.substring(0,g).trim();const o=t.substring(g+1,h);if(e=i+d+"("+(0,n.x)(o.trim())+")",h0&&(k+=e.cssClasses.join(" "));const E=l.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",w.width+2*a.padding).attr("height",w.height+a.padding+.5*a.dividerMargin).attr("class",k).node().getBBox().width;return p.node().childNodes.forEach((function(t){t.setAttribute("x",(E-t.getBBox().width)/2)})),e.tooltip&&p.insert("title").text(e.tooltip),u.attr("x2",E),b.attr("x2",E),o.width=E,o.height=w.height+a.padding+.5*a.dividerMargin,o},drawEdge:function(t,e,a,d,o){const s=function(t){switch(t){case o.db.relationType.AGGREGATION:return"aggregation";case o.db.relationType.EXTENSION:return"extension";case o.db.relationType.COMPOSITION:return"composition";case o.db.relationType.DEPENDENCY:return"dependency";case o.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const l=e.points,p=(0,r.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(r.$0Z),c=t.append("path").attr("d",p(l)).attr("id","edge"+i).attr("class","relation");let g,h,f="";d.arrowMarkerAbsolute&&(f=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,f=f.replace(/\(/g,"\\("),f=f.replace(/\)/g,"\\)")),1==a.relation.lineType&&c.attr("class","relation dashed-line"),10==a.relation.lineType&&c.attr("class","relation dotted-line"),"none"!==a.relation.type1&&c.attr("marker-start","url("+f+"#"+s(a.relation.type1)+"Start)"),"none"!==a.relation.type2&&c.attr("marker-end","url("+f+"#"+s(a.relation.type2)+"End)");const u=e.points.length;let x,y,b,m,w=n.u.calcLabelPosition(e.points);if(g=w.x,h=w.y,u%2!=0&&u>1){let t=n.u.calcCardinalityPosition("none"!==a.relation.type1,e.points,e.points[0]),r=n.u.calcCardinalityPosition("none"!==a.relation.type2,e.points,e.points[u-1]);n.l.debug("cardinality_1_point "+JSON.stringify(t)),n.l.debug("cardinality_2_point "+JSON.stringify(r)),x=t.x,y=t.y,b=r.x,m=r.y}if(void 0!==a.title){const e=t.append("g").attr("class","classLabel"),r=e.append("text").attr("class","label").attr("x",g).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(a.title);window.label=r;const n=r.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",n.x-d.padding/2).attr("y",n.y-d.padding/2).attr("width",n.width+d.padding).attr("height",n.height+d.padding)}n.l.info("Rendering relation "+JSON.stringify(a)),void 0!==a.relationTitle1&&"none"!==a.relationTitle1&&t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",x).attr("y",y).attr("fill","black").attr("font-size","6").text(a.relationTitle1),void 0!==a.relationTitle2&&"none"!==a.relationTitle2&&t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",b).attr("y",m).attr("fill","black").attr("font-size","6").text(a.relationTitle2),i++},drawNote:function(t,e,a,r){n.l.debug("Rendering note ",e,a);const i=e.id,d={id:i,text:e.text,width:0,height:0},o=t.append("g").attr("id",i).attr("class","classGroup");let s=o.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${e.text}"`).split("\n");l.forEach((function(t){n.l.debug(`Adding line: ${t}`),s.append("tspan").text(t).attr("class","title").attr("dy",a.textHeight)}));const p=o.node().getBBox(),c=o.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",p.width+2*a.padding).attr("height",p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(c-t.getBBox().width)/2)})),d.width=c,d.height=p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,d},parseMember:o}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/535-dcead599.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/535-dcead599.chunk.min.js new file mode 100644 index 000000000..ecc1a28a2 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/535-dcead599.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[535],{1535:function(t,e,i){i.d(e,{D:function(){return l},S:function(){return c},a:function(){return h},b:function(){return a},c:function(){return o},d:function(){return B},p:function(){return r},s:function(){return P}});var s=i(9339),n=function(){var t=function(t,e,i,s){for(i=i||{},s=t.length;s--;i[t[s]]=e);return i},e=[1,2],i=[1,3],s=[1,5],n=[1,7],r=[2,5],o=[1,15],a=[1,17],c=[1,21],l=[1,22],h=[1,23],u=[1,24],d=[1,37],p=[1,25],y=[1,26],f=[1,27],g=[1,28],m=[1,29],_=[1,32],S=[1,33],k=[1,34],T=[1,35],b=[1,36],E=[1,39],v=[1,40],x=[1,41],D=[1,42],C=[1,38],$=[1,45],A=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],L=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],I=[1,4,5,7,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],O=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],N={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,classDefStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,classDef:38,CLASSDEF_ID:39,CLASSDEF_STYLEOPTS:40,DEFAULT:41,class:42,CLASSENTITY_IDS:43,STYLECLASS:44,openDirective:45,typeDirective:46,closeDirective:47,":":48,argDirective:49,direction_tb:50,direction_bt:51,direction_rl:52,direction_lr:53,eol:54,";":55,EDGE_STATE:56,STYLE_SEPARATOR:57,left_of:58,right_of:59,open_directive:60,type_directive:61,arg_directive:62,close_directive:63,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"class",43:"CLASSENTITY_IDS",44:"STYLECLASS",48:":",50:"direction_tb",51:"direction_bt",52:"direction_rl",53:"direction_lr",55:";",56:"EDGE_STATE",57:"STYLE_SEPARATOR",58:"left_of",59:"right_of",60:"open_directive",61:"type_directive",62:"arg_directive",63:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[10,1],[10,2],[10,2],[10,1],[11,3],[11,3],[12,3],[6,3],[6,5],[32,1],[32,1],[32,1],[32,1],[54,1],[54,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1],[45,1],[46,1],[49,1],[47,1]],performAction:function(t,e,i,s,n,r,o){var a=r.length-1;switch(n){case 4:return s.setRootDoc(r[a]),r[a];case 5:this.$=[];break;case 6:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 7:case 8:case 12:this.$=r[a];break;case 9:this.$="nl";break;case 13:const t=r[a-1];t.description=s.trimColon(r[a]),this.$=t;break;case 14:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 15:const e=s.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 19:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 20:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 22:this.$={stmt:"state",id:r[a],type:"fork"};break;case 23:this.$={stmt:"state",id:r[a],type:"join"};break;case 24:this.$={stmt:"state",id:r[a],type:"choice"};break;case 25:this.$={stmt:"state",id:s.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 30:this.$=r[a].trim(),s.setAccTitle(this.$);break;case 31:case 32:this.$=r[a].trim(),s.setAccDescription(this.$);break;case 33:case 34:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 35:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 38:s.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:s.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:s.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:s.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 46:case 47:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""};break;case 50:s.parseDirective("%%{","open_directive");break;case 51:s.parseDirective(r[a],"type_directive");break;case 52:r[a]=r[a].trim().replace(/'/g,'"'),s.parseDirective(r[a],"arg_directive");break;case 53:s.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:e,5:i,6:4,7:s,45:6,60:n},{1:[3]},{3:8,4:e,5:i,6:4,7:s,45:6,60:n},{3:9,4:e,5:i,6:4,7:s,45:6,60:n},{3:10,4:e,5:i,6:4,7:s,45:6,60:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],r,{8:11}),{46:12,61:[1,13]},{61:[2,50]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:a,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:g,29:m,32:31,33:_,35:S,37:k,38:T,42:b,45:6,50:E,51:v,52:x,53:D,56:C,60:n},{47:43,48:[1,44],63:$},t([48,63],[2,51]),t(A,[2,6]),{6:30,10:46,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:g,29:m,32:31,33:_,35:S,37:k,38:T,42:b,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(A,[2,11]),t(A,[2,12],{14:[1,47],15:[1,48]}),t(A,[2,16]),{18:[1,49]},t(A,[2,18],{20:[1,50]}),{23:[1,51]},t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),{30:52,31:[1,53],58:[1,54],59:[1,55]},t(A,[2,28]),t(A,[2,29]),{34:[1,56]},{36:[1,57]},t(A,[2,32]),{39:[1,58],41:[1,59]},{43:[1,60]},t(L,[2,44],{57:[1,61]}),t(L,[2,45],{57:[1,62]}),t(A,[2,38]),t(A,[2,39]),t(A,[2,40]),t(A,[2,41]),t(I,[2,36]),{49:63,62:[1,64]},t(I,[2,53]),t(A,[2,7]),t(A,[2,13]),{13:65,24:d,56:C},t(A,[2,17]),t(O,r,{8:66}),{24:[1,67]},{24:[1,68]},{23:[1,69]},{24:[2,48]},{24:[2,49]},t(A,[2,30]),t(A,[2,31]),{40:[1,70]},{40:[1,71]},{44:[1,72]},{24:[1,73]},{24:[1,74]},{47:75,63:$},{63:[2,52]},t(A,[2,14],{14:[1,76]}),{4:o,5:a,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,77],22:u,24:d,25:p,26:y,27:f,28:g,29:m,32:31,33:_,35:S,37:k,38:T,42:b,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,20],{20:[1,78]}),{31:[1,79]},{24:[1,80]},t(A,[2,33]),t(A,[2,34]),t(A,[2,35]),t(L,[2,46]),t(L,[2,47]),t(I,[2,37]),t(A,[2,15]),t(A,[2,19]),t(O,r,{8:81}),t(A,[2,26]),t(A,[2,27]),{4:o,5:a,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,82],22:u,24:d,25:p,26:y,27:f,28:g,29:m,32:31,33:_,35:S,37:k,38:T,42:b,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,21])],defaultActions:{7:[2,50],8:[2,1],9:[2,2],10:[2,3],54:[2,48],55:[2,49],64:[2,52]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=[0],i=[],s=[null],n=[],r=this.table,o="",a=0,c=0,l=n.slice.call(arguments,1),h=Object.create(this.lexer),u={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(u.yy[d]=this.yy[d]);h.setInput(t,u.yy),u.yy.lexer=h,u.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;n.push(p);var y=h.options&&h.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,g,m,_,S,k,T,b,E,v={};;){if(g=e[e.length-1],this.defaultActions[g]?m=this.defaultActions[g]:(null==f&&(E=void 0,"number"!=typeof(E=i.pop()||h.lex()||1)&&(E instanceof Array&&(E=(i=E).pop()),E=this.symbols_[E]||E),f=E),m=r[g]&&r[g][f]),void 0===m||!m.length||!m[0]){var x;for(S in b=[],r[g])this.terminals_[S]&&S>2&&b.push("'"+this.terminals_[S]+"'");x=h.showPosition?"Parse error on line "+(a+1)+":\n"+h.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(x,{text:h.match,token:this.terminals_[f]||f,line:h.yylineno,loc:p,expected:b})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+f);switch(m[0]){case 1:e.push(f),s.push(h.yytext),n.push(h.yylloc),e.push(m[1]),f=null,c=h.yyleng,o=h.yytext,a=h.yylineno,p=h.yylloc;break;case 2:if(k=this.productions_[m[1]][1],v.$=s[s.length-k],v._$={first_line:n[n.length-(k||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(k||1)].first_column,last_column:n[n.length-1].last_column},y&&(v._$.range=[n[n.length-(k||1)].range[0],n[n.length-1].range[1]]),void 0!==(_=this.performAction.apply(v,[o,c,a,u.yy,m[1],s,n].concat(l))))return _;k&&(e=e.slice(0,-1*k*2),s=s.slice(0,-1*k),n=n.slice(0,-1*k)),e.push(this.productions_[m[1]][0]),s.push(v.$),n.push(v._$),T=r[e[e.length-2]][e[e.length-1]],e.push(T);break;case 3:return!0}}return!0}},R={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===s.length?this.yylloc.first_column:0)+s[s.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;re[0].length)){if(e=i,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,s){switch(i){case 0:return 41;case 1:case 44:return 50;case 2:case 45:return 51;case 3:case 46:return 52;case 4:case 47:return 53;case 5:return this.begin("open_directive"),60;case 6:return this.begin("type_directive"),61;case 7:return this.popState(),this.begin("arg_directive"),48;case 8:return this.popState(),this.popState(),63;case 9:return 62;case 10:case 11:case 13:case 14:case 15:case 16:case 56:case 58:case 64:break;case 12:case 79:return 5;case 17:case 34:return this.pushState("SCALE"),17;case 18:case 35:return 18;case 19:case 25:case 36:case 51:case 54:this.popState();break;case 20:return this.begin("acc_title"),33;case 21:return this.popState(),"acc_title_value";case 22:return this.begin("acc_descr"),35;case 23:return this.popState(),"acc_descr_value";case 24:this.begin("acc_descr_multiline");break;case 26:return"acc_descr_multiline_value";case 27:return this.pushState("CLASSDEF"),38;case 28:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 29:return this.popState(),this.pushState("CLASSDEFID"),39;case 30:return this.popState(),40;case 31:return this.pushState("CLASS"),42;case 32:return this.popState(),this.pushState("CLASS_STYLE"),43;case 33:return this.popState(),44;case 37:this.pushState("STATE");break;case 38:case 41:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 39:case 42:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 40:case 43:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 48:this.pushState("STATE_STRING");break;case 49:return this.pushState("STATE_ID"),"AS";case 50:case 66:return this.popState(),"ID";case 52:return"STATE_DESCR";case 53:return 19;case 55:return this.popState(),this.pushState("struct"),20;case 57:return this.popState(),21;case 59:return this.begin("NOTE"),29;case 60:return this.popState(),this.pushState("NOTE_ID"),58;case 61:return this.popState(),this.pushState("NOTE_ID"),59;case 62:this.popState(),this.pushState("FLOATING_NOTE");break;case 63:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 65:return"NOTE_TEXT";case 67:return this.popState(),this.pushState("NOTE_TEXT"),24;case 68:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 69:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 70:case 71:return 7;case 72:return 16;case 73:return 56;case 74:return 24;case 75:return e.yytext=e.yytext.trim(),14;case 76:return 15;case 77:return 28;case 78:return 57;case 80:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[14,15],inclusive:!1},close_directive:{rules:[14,15],inclusive:!1},arg_directive:{rules:[8,9,14,15],inclusive:!1},type_directive:{rules:[7,8,14,15],inclusive:!1},open_directive:{rules:[6,14,15],inclusive:!1},struct:{rules:[14,15,27,31,37,44,45,46,47,56,57,58,59,73,74,75,76,77],inclusive:!1},FLOATING_NOTE_ID:{rules:[66],inclusive:!1},FLOATING_NOTE:{rules:[63,64,65],inclusive:!1},NOTE_TEXT:{rules:[68,69],inclusive:!1},NOTE_ID:{rules:[67],inclusive:!1},NOTE:{rules:[60,61,62],inclusive:!1},CLASS_STYLE:{rules:[33],inclusive:!1},CLASS:{rules:[32],inclusive:!1},CLASSDEFID:{rules:[30],inclusive:!1},CLASSDEF:{rules:[28,29],inclusive:!1},acc_descr_multiline:{rules:[25,26],inclusive:!1},acc_descr:{rules:[23],inclusive:!1},acc_title:{rules:[21],inclusive:!1},SCALE:{rules:[18,19,35,36],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[50],inclusive:!1},STATE_STRING:{rules:[51,52],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[14,15,38,39,40,41,42,43,48,49,53,54,55],inclusive:!1},ID:{rules:[14,15],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,10,11,12,13,15,16,17,20,22,24,27,31,34,37,55,59,70,71,72,73,74,75,76,78,79,80],inclusive:!0}}};function w(){this.yy={}}return N.lexer=R,w.prototype=N,N.Parser=w,new w}();n.parser=n;const r=n,o="TB",a="state",c="relation",l="default",h="divider",u="[*]",d="start",p=u,y="color",f="fill";let g="LR",m=[],_={},S={root:{relations:[],states:{},documents:{}}},k=S.root,T=0,b=0;const E=t=>JSON.parse(JSON.stringify(t)),v=(t,e,i)=>{if(e.stmt===c)v(t,e.state1,!0),v(t,e.state2,!1);else if(e.stmt===a&&("[*]"===e.id?(e.id=i?t.id+"_start":t.id+"_end",e.start=i):e.id=e.id.trim()),e.doc){const t=[];let i,n=[];for(i=0;i0&&n.length>0){const i={stmt:a,id:(0,s.I)(),type:"divider",doc:E(n)};t.push(E(i)),e.doc=t}e.doc.forEach((t=>v(e,t,!0)))}},x=function(t,e=l,i=null,n=null,r=null,o=null,a=null,c=null){const h=null==t?void 0:t.trim();void 0===k.states[h]?(s.l.info("Adding state ",h,n),k.states[h]={id:h,descriptions:[],type:e,doc:i,note:r,classes:[],styles:[],textStyles:[]}):(k.states[h].doc||(k.states[h].doc=i),k.states[h].type||(k.states[h].type=e)),n&&(s.l.info("Setting state description",h,n),"string"==typeof n&&I(h,n.trim()),"object"==typeof n&&n.forEach((t=>I(h,t.trim())))),r&&(k.states[h].note=r,k.states[h].note.text=s.e.sanitizeText(k.states[h].note.text,(0,s.c)())),o&&(s.l.info("Setting state classes",h,o),("string"==typeof o?[o]:o).forEach((t=>N(h,t.trim())))),a&&(s.l.info("Setting state styles",h,a),("string"==typeof a?[a]:a).forEach((t=>R(h,t.trim())))),c&&(s.l.info("Setting state styles",h,a),("string"==typeof c?[c]:c).forEach((t=>w(h,t.trim()))))},D=function(t){S={root:{relations:[],states:{},documents:{}}},k=S.root,T=0,_={},t||(0,s.v)()},C=function(t){return k.states[t]};function $(t=""){let e=t;return t===u&&(T++,e=`${d}${T}`),e}function A(t="",e=l){return t===u?d:e}const L=function(t,e,i){if("object"==typeof t)!function(t,e,i){let n=$(t.id.trim()),r=A(t.id.trim(),t.type),o=$(e.id.trim()),a=A(e.id.trim(),e.type);x(n,r,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),x(o,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),k.relations.push({id1:n,id2:o,relationTitle:s.e.sanitizeText(i,(0,s.c)())})}(t,e,i);else{const n=$(t.trim()),r=A(t),o=function(t=""){let e=t;return t===p&&(T++,e=`end${T}`),e}(e.trim()),a=function(t="",e=l){return t===p?"end":e}(e);x(n,r),x(o,a),k.relations.push({id1:n,id2:o,title:s.e.sanitizeText(i,(0,s.c)())})}},I=function(t,e){const i=k.states[t],n=e.startsWith(":")?e.replace(":","").trim():e;i.descriptions.push(s.e.sanitizeText(n,(0,s.c)()))},O=function(t,e=""){void 0===_[t]&&(_[t]={id:t,styles:[],textStyles:[]});const i=_[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match(y)){const t=e.replace(f,"bgFill").replace(y,f);i.textStyles.push(t)}i.styles.push(e)}))},N=function(t,e){t.split(",").forEach((function(t){let i=C(t);if(void 0===i){const e=t.trim();x(e),i=C(e)}i.classes.push(e)}))},R=function(t,e){const i=C(t);void 0!==i&&i.textStyles.push(e)},w=function(t,e){const i=C(t);void 0!==i&&i.textStyles.push(e)},B={parseDirective:function(t,e,i){s.m.parseDirective(this,t,e,i)},getConfig:()=>(0,s.c)().state,addState:x,clear:D,getState:C,getStates:function(){return k.states},getRelations:function(){return k.relations},getClasses:function(){return _},getDirection:()=>g,addRelation:L,getDividerId:()=>(b++,"divider-id-"+b),setDirection:t=>{g=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){s.l.info("Documents = ",S)},getRootDoc:()=>m,setRootDoc:t=>{s.l.info("Setting root doc",t),m=t},getRootDocV2:()=>(v({id:"root"},{id:"root",doc:m},!0),{id:"root",doc:m}),extract:t=>{let e;e=t.doc?t.doc:t,s.l.info(e),D(!0),s.l.info("Extract",e),e.forEach((t=>{switch(t.stmt){case a:x(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case c:L(t.state1,t.state2,t.description);break;case"classDef":O(t.id.trim(),t.classes);break;case"applyClass":N(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:s.g,setAccTitle:s.s,getAccDescription:s.a,setAccDescription:s.b,addStyleClass:O,setCssClass:N,addDescription:I,setDiagramTitle:s.r,getDiagramTitle:s.t},P=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/545-8e970b03.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/545-8e970b03.chunk.min.js new file mode 100644 index 000000000..349f8418d --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/545-8e970b03.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[545],{4545:function(t,e,n){n.d(e,{diagram:function(){return Q}});var i=n(9339),a=n(7274),s=n(8252),r=n(7967),l=(n(7484),n(7856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,6],n=[1,7],i=[1,8],a=[1,9],s=[1,16],r=[1,11],l=[1,12],o=[1,13],h=[1,14],d=[1,15],u=[1,27],p=[1,33],y=[1,34],f=[1,35],b=[1,36],g=[1,37],_=[1,72],x=[1,73],m=[1,74],E=[1,75],A=[1,76],S=[1,77],v=[1,78],C=[1,38],k=[1,39],O=[1,40],T=[1,41],w=[1,42],D=[1,43],R=[1,44],N=[1,45],P=[1,46],M=[1,47],j=[1,48],B=[1,49],Y=[1,50],L=[1,51],I=[1,52],U=[1,53],F=[1,54],X=[1,55],z=[1,56],Q=[1,57],W=[1,59],$=[1,60],q=[1,61],V=[1,62],G=[1,63],H=[1,64],K=[1,65],J=[1,66],Z=[1,67],tt=[1,68],et=[1,69],nt=[24,52],it=[24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],at=[15,24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],st=[1,94],rt=[1,95],lt=[1,96],ot=[1,97],ct=[15,24,52],ht=[7,8,9,10,18,22,25,26,27,28],dt=[15,24,43,52],ut=[15,24,43,52,86,87,89,90],pt=[15,43],yt=[44,46,47,48,49,50,51,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],ft={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,directive:6,direction_tb:7,direction_bt:8,direction_rl:9,direction_lr:10,graphConfig:11,openDirective:12,typeDirective:13,closeDirective:14,NEWLINE:15,":":16,argDirective:17,open_directive:18,type_directive:19,arg_directive:20,close_directive:21,C4_CONTEXT:22,statements:23,EOF:24,C4_CONTAINER:25,C4_COMPONENT:26,C4_DYNAMIC:27,C4_DEPLOYMENT:28,otherStatements:29,diagramStatements:30,otherStatement:31,title:32,accDescription:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,boundaryStatement:39,boundaryStartStatement:40,boundaryStopStatement:41,boundaryStart:42,LBRACE:43,ENTERPRISE_BOUNDARY:44,attributes:45,SYSTEM_BOUNDARY:46,BOUNDARY:47,CONTAINER_BOUNDARY:48,NODE:49,NODE_L:50,NODE_R:51,RBRACE:52,diagramStatement:53,PERSON:54,PERSON_EXT:55,SYSTEM:56,SYSTEM_DB:57,SYSTEM_QUEUE:58,SYSTEM_EXT:59,SYSTEM_EXT_DB:60,SYSTEM_EXT_QUEUE:61,CONTAINER:62,CONTAINER_DB:63,CONTAINER_QUEUE:64,CONTAINER_EXT:65,CONTAINER_EXT_DB:66,CONTAINER_EXT_QUEUE:67,COMPONENT:68,COMPONENT_DB:69,COMPONENT_QUEUE:70,COMPONENT_EXT:71,COMPONENT_EXT_DB:72,COMPONENT_EXT_QUEUE:73,REL:74,BIREL:75,REL_U:76,REL_D:77,REL_L:78,REL_R:79,REL_B:80,REL_INDEX:81,UPDATE_EL_STYLE:82,UPDATE_REL_STYLE:83,UPDATE_LAYOUT_CONFIG:84,attribute:85,STR:86,STR_KEY:87,STR_VALUE:88,ATTRIBUTE:89,ATTRIBUTE_EMPTY:90,$accept:0,$end:1},terminals_:{2:"error",7:"direction_tb",8:"direction_bt",9:"direction_rl",10:"direction_lr",15:"NEWLINE",16:":",18:"open_directive",19:"type_directive",20:"arg_directive",21:"close_directive",22:"C4_CONTEXT",24:"EOF",25:"C4_CONTAINER",26:"C4_COMPONENT",27:"C4_DYNAMIC",28:"C4_DEPLOYMENT",32:"title",33:"accDescription",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",43:"LBRACE",44:"ENTERPRISE_BOUNDARY",46:"SYSTEM_BOUNDARY",47:"BOUNDARY",48:"CONTAINER_BOUNDARY",49:"NODE",50:"NODE_L",51:"NODE_R",52:"RBRACE",54:"PERSON",55:"PERSON_EXT",56:"SYSTEM",57:"SYSTEM_DB",58:"SYSTEM_QUEUE",59:"SYSTEM_EXT",60:"SYSTEM_EXT_DB",61:"SYSTEM_EXT_QUEUE",62:"CONTAINER",63:"CONTAINER_DB",64:"CONTAINER_QUEUE",65:"CONTAINER_EXT",66:"CONTAINER_EXT_DB",67:"CONTAINER_EXT_QUEUE",68:"COMPONENT",69:"COMPONENT_DB",70:"COMPONENT_QUEUE",71:"COMPONENT_EXT",72:"COMPONENT_EXT_DB",73:"COMPONENT_EXT_QUEUE",74:"REL",75:"BIREL",76:"REL_U",77:"REL_D",78:"REL_L",79:"REL_R",80:"REL_B",81:"REL_INDEX",82:"UPDATE_EL_STYLE",83:"UPDATE_REL_STYLE",84:"UPDATE_LAYOUT_CONFIG",86:"STR",87:"STR_KEY",88:"STR_VALUE",89:"ATTRIBUTE",90:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[3,2],[5,1],[5,1],[5,1],[5,1],[4,1],[6,4],[6,6],[12,1],[13,1],[17,1],[14,1],[11,4],[11,4],[11,4],[11,4],[11,4],[23,1],[23,1],[23,2],[29,1],[29,2],[29,3],[31,1],[31,1],[31,2],[31,2],[31,1],[39,3],[40,3],[40,3],[40,4],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[41,1],[30,1],[30,2],[30,3],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,1],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[45,1],[45,2],[85,1],[85,2],[85,1],[85,1]],performAction:function(t,e,n,i,a,s,r){var l=s.length-1;switch(a){case 4:i.setDirection("TB");break;case 5:i.setDirection("BT");break;case 6:i.setDirection("RL");break;case 7:i.setDirection("LR");break;case 11:i.parseDirective("%%{","open_directive");break;case 12:break;case 13:s[l]=s[l].trim().replace(/'/g,'"'),i.parseDirective(s[l],"arg_directive");break;case 14:i.parseDirective("}%%","close_directive","c4Context");break;case 15:case 16:case 17:case 18:case 19:i.setC4Type(s[l-3]);break;case 26:i.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 27:i.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 28:this.$=s[l].trim(),i.setTitle(this.$);break;case 29:case 30:this.$=s[l].trim(),i.setAccDescription(this.$);break;case 35:case 36:s[l].splice(2,0,"ENTERPRISE"),i.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 37:i.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 38:s[l].splice(2,0,"CONTAINER"),i.addContainerBoundary(...s[l]),this.$=s[l];break;case 39:i.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 40:i.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 41:i.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 42:i.popBoundaryParseStack();break;case 46:i.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 47:i.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 48:i.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 49:i.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 50:i.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 51:i.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 52:i.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 53:i.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 54:i.addContainer("container",...s[l]),this.$=s[l];break;case 55:i.addContainer("container_db",...s[l]),this.$=s[l];break;case 56:i.addContainer("container_queue",...s[l]),this.$=s[l];break;case 57:i.addContainer("external_container",...s[l]),this.$=s[l];break;case 58:i.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 59:i.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 60:i.addComponent("component",...s[l]),this.$=s[l];break;case 61:i.addComponent("component_db",...s[l]),this.$=s[l];break;case 62:i.addComponent("component_queue",...s[l]),this.$=s[l];break;case 63:i.addComponent("external_component",...s[l]),this.$=s[l];break;case 64:i.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 65:i.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 67:i.addRel("rel",...s[l]),this.$=s[l];break;case 68:i.addRel("birel",...s[l]),this.$=s[l];break;case 69:i.addRel("rel_u",...s[l]),this.$=s[l];break;case 70:i.addRel("rel_d",...s[l]),this.$=s[l];break;case 71:i.addRel("rel_l",...s[l]),this.$=s[l];break;case 72:i.addRel("rel_r",...s[l]),this.$=s[l];break;case 73:i.addRel("rel_b",...s[l]),this.$=s[l];break;case 74:s[l].splice(0,1),i.addRel("rel",...s[l]),this.$=s[l];break;case 75:i.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 76:i.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 77:i.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 78:this.$=[s[l]];break;case 79:s[l].unshift(s[l-1]),this.$=s[l];break;case 80:case 82:this.$=s[l].trim();break;case 81:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 83:this.$=""}},table:[{3:1,4:2,5:3,6:4,7:e,8:n,9:i,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[3]},{1:[2,1]},{1:[2,2]},{3:17,4:2,5:3,6:4,7:e,8:n,9:i,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[2,8]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{1:[2,7]},{13:18,19:[1,19]},{15:[1,20]},{15:[1,21]},{15:[1,22]},{15:[1,23]},{15:[1,24]},{19:[2,11]},{1:[2,3]},{14:25,16:[1,26],21:u},t([16,21],[2,12]),{23:28,29:29,30:30,31:31,32:p,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:79,29:29,30:30,31:31,32:p,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:80,29:29,30:30,31:31,32:p,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:81,29:29,30:30,31:31,32:p,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:82,29:29,30:30,31:31,32:p,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,83]},{17:84,20:[1,85]},{15:[2,14]},{24:[1,86]},t(nt,[2,20],{53:32,39:58,40:70,42:71,30:87,44:_,46:x,47:m,48:E,49:A,50:S,51:v,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(nt,[2,21]),t(it,[2,23],{15:[1,88]}),t(nt,[2,43],{15:[1,89]}),t(at,[2,26]),t(at,[2,27]),{35:[1,90]},{37:[1,91]},t(at,[2,30]),{45:92,85:93,86:st,87:rt,89:lt,90:ot},{45:98,85:93,86:st,87:rt,89:lt,90:ot},{45:99,85:93,86:st,87:rt,89:lt,90:ot},{45:100,85:93,86:st,87:rt,89:lt,90:ot},{45:101,85:93,86:st,87:rt,89:lt,90:ot},{45:102,85:93,86:st,87:rt,89:lt,90:ot},{45:103,85:93,86:st,87:rt,89:lt,90:ot},{45:104,85:93,86:st,87:rt,89:lt,90:ot},{45:105,85:93,86:st,87:rt,89:lt,90:ot},{45:106,85:93,86:st,87:rt,89:lt,90:ot},{45:107,85:93,86:st,87:rt,89:lt,90:ot},{45:108,85:93,86:st,87:rt,89:lt,90:ot},{45:109,85:93,86:st,87:rt,89:lt,90:ot},{45:110,85:93,86:st,87:rt,89:lt,90:ot},{45:111,85:93,86:st,87:rt,89:lt,90:ot},{45:112,85:93,86:st,87:rt,89:lt,90:ot},{45:113,85:93,86:st,87:rt,89:lt,90:ot},{45:114,85:93,86:st,87:rt,89:lt,90:ot},{45:115,85:93,86:st,87:rt,89:lt,90:ot},{45:116,85:93,86:st,87:rt,89:lt,90:ot},t(ct,[2,66]),{45:117,85:93,86:st,87:rt,89:lt,90:ot},{45:118,85:93,86:st,87:rt,89:lt,90:ot},{45:119,85:93,86:st,87:rt,89:lt,90:ot},{45:120,85:93,86:st,87:rt,89:lt,90:ot},{45:121,85:93,86:st,87:rt,89:lt,90:ot},{45:122,85:93,86:st,87:rt,89:lt,90:ot},{45:123,85:93,86:st,87:rt,89:lt,90:ot},{45:124,85:93,86:st,87:rt,89:lt,90:ot},{45:125,85:93,86:st,87:rt,89:lt,90:ot},{45:126,85:93,86:st,87:rt,89:lt,90:ot},{45:127,85:93,86:st,87:rt,89:lt,90:ot},{30:128,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:A,50:S,51:v,53:32,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,130],43:[1,129]},{45:131,85:93,86:st,87:rt,89:lt,90:ot},{45:132,85:93,86:st,87:rt,89:lt,90:ot},{45:133,85:93,86:st,87:rt,89:lt,90:ot},{45:134,85:93,86:st,87:rt,89:lt,90:ot},{45:135,85:93,86:st,87:rt,89:lt,90:ot},{45:136,85:93,86:st,87:rt,89:lt,90:ot},{45:137,85:93,86:st,87:rt,89:lt,90:ot},{24:[1,138]},{24:[1,139]},{24:[1,140]},{24:[1,141]},t(ht,[2,9]),{14:142,21:u},{21:[2,13]},{1:[2,15]},t(nt,[2,22]),t(it,[2,24],{31:31,29:143,32:p,33:y,34:f,36:b,38:g}),t(nt,[2,44],{29:29,30:30,31:31,53:32,39:58,40:70,42:71,23:144,32:p,33:y,34:f,36:b,38:g,44:_,46:x,47:m,48:E,49:A,50:S,51:v,54:C,55:k,56:O,57:T,58:w,59:D,60:R,61:N,62:P,63:M,64:j,65:B,66:Y,67:L,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(at,[2,28]),t(at,[2,29]),t(ct,[2,46]),t(dt,[2,78],{85:93,45:145,86:st,87:rt,89:lt,90:ot}),t(ut,[2,80]),{88:[1,146]},t(ut,[2,82]),t(ut,[2,83]),t(ct,[2,47]),t(ct,[2,48]),t(ct,[2,49]),t(ct,[2,50]),t(ct,[2,51]),t(ct,[2,52]),t(ct,[2,53]),t(ct,[2,54]),t(ct,[2,55]),t(ct,[2,56]),t(ct,[2,57]),t(ct,[2,58]),t(ct,[2,59]),t(ct,[2,60]),t(ct,[2,61]),t(ct,[2,62]),t(ct,[2,63]),t(ct,[2,64]),t(ct,[2,65]),t(ct,[2,67]),t(ct,[2,68]),t(ct,[2,69]),t(ct,[2,70]),t(ct,[2,71]),t(ct,[2,72]),t(ct,[2,73]),t(ct,[2,74]),t(ct,[2,75]),t(ct,[2,76]),t(ct,[2,77]),{41:147,52:[1,148]},{15:[1,149]},{43:[1,150]},t(pt,[2,35]),t(pt,[2,36]),t(pt,[2,37]),t(pt,[2,38]),t(pt,[2,39]),t(pt,[2,40]),t(pt,[2,41]),{1:[2,16]},{1:[2,17]},{1:[2,18]},{1:[2,19]},{15:[1,151]},t(it,[2,25]),t(nt,[2,45]),t(dt,[2,79]),t(ut,[2,81]),t(ct,[2,31]),t(ct,[2,42]),t(yt,[2,32]),t(yt,[2,33],{15:[1,152]}),t(ht,[2,10]),t(yt,[2,34])],defaultActions:{2:[2,1],3:[2,2],5:[2,8],6:[2,4],7:[2,5],8:[2,6],9:[2,7],16:[2,11],17:[2,3],27:[2,14],85:[2,13],86:[2,15],138:[2,16],139:[2,17],140:[2,18],141:[2,19]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=[0],n=[],i=[null],a=[],s=this.table,r="",l=0,o=0,c=a.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(d.yy[u]=this.yy[u]);h.setInput(t,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;a.push(p);var y=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,b,g,_,x,m,E,A,S,v={};;){if(b=e[e.length-1],this.defaultActions[b]?g=this.defaultActions[b]:(null==f&&(S=void 0,"number"!=typeof(S=n.pop()||h.lex()||1)&&(S instanceof Array&&(S=(n=S).pop()),S=this.symbols_[S]||S),f=S),g=s[b]&&s[b][f]),void 0===g||!g.length||!g[0]){var C;for(x in A=[],s[b])this.terminals_[x]&&x>2&&A.push("'"+this.terminals_[x]+"'");C=h.showPosition?"Parse error on line "+(l+1)+":\n"+h.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(C,{text:h.match,token:this.terminals_[f]||f,line:h.yylineno,loc:p,expected:A})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+f);switch(g[0]){case 1:e.push(f),i.push(h.yytext),a.push(h.yylloc),e.push(g[1]),f=null,o=h.yyleng,r=h.yytext,l=h.yylineno,p=h.yylloc;break;case 2:if(m=this.productions_[g[1]][1],v.$=i[i.length-m],v._$={first_line:a[a.length-(m||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(m||1)].first_column,last_column:a[a.length-1].last_column},y&&(v._$.range=[a[a.length-(m||1)].range[0],a[a.length-1].range[1]]),void 0!==(_=this.performAction.apply(v,[r,o,l,d.yy,g[1],i,a].concat(c))))return _;m&&(e=e.slice(0,-1*m*2),i=i.slice(0,-1*m),a=a.slice(0,-1*m)),e.push(this.productions_[g[1]][0]),i.push(v.$),a.push(v._$),E=s[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}},bt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var s in a)this[s]=a[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),s=0;se[0].length)){if(e=n,i=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,a[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),18;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 10;case 5:return this.begin("type_directive"),19;case 6:return this.popState(),this.begin("arg_directive"),16;case 7:return this.popState(),this.popState(),21;case 8:return 20;case 9:return 32;case 10:return 33;case 11:return this.begin("acc_title"),34;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),36;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 78:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:case 21:case 75:break;case 19:c;break;case 20:return 15;case 22:return 22;case 23:return 25;case 24:return 26;case 25:return 27;case 26:return 28;case 27:return this.begin("person_ext"),55;case 28:return this.begin("person"),54;case 29:return this.begin("system_ext_queue"),61;case 30:return this.begin("system_ext_db"),60;case 31:return this.begin("system_ext"),59;case 32:return this.begin("system_queue"),58;case 33:return this.begin("system_db"),57;case 34:return this.begin("system"),56;case 35:return this.begin("boundary"),47;case 36:return this.begin("enterprise_boundary"),44;case 37:return this.begin("system_boundary"),46;case 38:return this.begin("container_ext_queue"),67;case 39:return this.begin("container_ext_db"),66;case 40:return this.begin("container_ext"),65;case 41:return this.begin("container_queue"),64;case 42:return this.begin("container_db"),63;case 43:return this.begin("container"),62;case 44:return this.begin("container_boundary"),48;case 45:return this.begin("component_ext_queue"),73;case 46:return this.begin("component_ext_db"),72;case 47:return this.begin("component_ext"),71;case 48:return this.begin("component_queue"),70;case 49:return this.begin("component_db"),69;case 50:return this.begin("component"),68;case 51:case 52:return this.begin("node"),49;case 53:return this.begin("node_l"),50;case 54:return this.begin("node_r"),51;case 55:return this.begin("rel"),74;case 56:return this.begin("birel"),75;case 57:case 58:return this.begin("rel_u"),76;case 59:case 60:return this.begin("rel_d"),77;case 61:case 62:return this.begin("rel_l"),78;case 63:case 64:return this.begin("rel_r"),79;case 65:return this.begin("rel_b"),80;case 66:return this.begin("rel_index"),81;case 67:return this.begin("update_el_style"),82;case 68:return this.begin("update_rel_style"),83;case 69:return this.begin("update_layout_config"),84;case 70:return"EOF_IN_STRUCT";case 71:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 72:this.begin("attribute");break;case 73:case 84:this.popState(),this.popState();break;case 74:case 76:return 90;case 77:this.begin("string");break;case 79:case 85:return"STR";case 80:this.begin("string_kv");break;case 81:return this.begin("string_kv_key"),"STR_KEY";case 82:this.popState(),this.begin("string_kv_value");break;case 83:return"STR_VALUE";case 86:return"LBRACE";case 87:return"RBRACE";case 88:return"SPACE";case 89:return"EOL";case 90:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},string_kv_value:{rules:[83,84],inclusive:!1},string_kv_key:{rules:[82],inclusive:!1},string_kv:{rules:[81],inclusive:!1},string:{rules:[78,79],inclusive:!1},attribute:{rules:[73,74,75,76,77,80,85],inclusive:!1},update_layout_config:{rules:[70,71,72,73],inclusive:!1},update_rel_style:{rules:[70,71,72,73],inclusive:!1},update_el_style:{rules:[70,71,72,73],inclusive:!1},rel_b:{rules:[70,71,72,73],inclusive:!1},rel_r:{rules:[70,71,72,73],inclusive:!1},rel_l:{rules:[70,71,72,73],inclusive:!1},rel_d:{rules:[70,71,72,73],inclusive:!1},rel_u:{rules:[70,71,72,73],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[70,71,72,73],inclusive:!1},node_r:{rules:[70,71,72,73],inclusive:!1},node_l:{rules:[70,71,72,73],inclusive:!1},node:{rules:[70,71,72,73],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[70,71,72,73],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[70,71,72,73],inclusive:!1},component_ext:{rules:[70,71,72,73],inclusive:!1},component_queue:{rules:[70,71,72,73],inclusive:!1},component_db:{rules:[70,71,72,73],inclusive:!1},component:{rules:[70,71,72,73],inclusive:!1},container_boundary:{rules:[70,71,72,73],inclusive:!1},container_ext_queue:{rules:[70,71,72,73],inclusive:!1},container_ext_db:{rules:[70,71,72,73],inclusive:!1},container_ext:{rules:[70,71,72,73],inclusive:!1},container_queue:{rules:[70,71,72,73],inclusive:!1},container_db:{rules:[70,71,72,73],inclusive:!1},container:{rules:[70,71,72,73],inclusive:!1},birel:{rules:[70,71,72,73],inclusive:!1},system_boundary:{rules:[70,71,72,73],inclusive:!1},enterprise_boundary:{rules:[70,71,72,73],inclusive:!1},boundary:{rules:[70,71,72,73],inclusive:!1},system_ext_queue:{rules:[70,71,72,73],inclusive:!1},system_ext_db:{rules:[70,71,72,73],inclusive:!1},system_ext:{rules:[70,71,72,73],inclusive:!1},system_queue:{rules:[70,71,72,73],inclusive:!1},system_db:{rules:[70,71,72,73],inclusive:!1},system:{rules:[70,71,72,73],inclusive:!1},person_ext:{rules:[70,71,72,73],inclusive:!1},person:{rules:[70,71,72,73],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,86,87,88,89,90],inclusive:!0}}};function gt(){this.yy={}}return ft.lexer=bt,gt.prototype=ft,ft.Parser=gt,new gt}());l.parser=l;const o=l;let h=[],d=[""],u="global",p="",y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],f=[],b="",g=!1,_=4,x=2;var m;const E=function(t){return null==t?h:h.filter((e=>e.parentBoundary===t))},A=function(){return g},S={addPersonOrSystem:function(t,e,n,i,a,s,r){if(null===e||null===n)return;let l={};const o=h.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,h.push(l)),l.label=null==n?{text:""}:{text:n},null==i)l.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]={text:e}}else l.descr={text:i};if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.sprite=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=u,l.wrap=A()},addPersonOrSystemBoundary:function(t,e,n,i,a){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"system"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.tags=i;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=u,s.wrap=A(),p=u,u=t,d.push(p)},addContainer:function(t,e,n,i,a,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==i)o.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.techn={text:i};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=A(),o.typeC4Shape={text:t},o.parentBoundary=u},addContainerBoundary:function(t,e,n,i,a){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"container"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.tags=i;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=u,s.wrap=A(),p=u,u=t,d.push(p)},addComponent:function(t,e,n,i,a,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==i)o.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.techn={text:i};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=A(),o.typeC4Shape={text:t},o.parentBoundary=u},addDeploymentNode:function(t,e,n,i,a,s,r,l){if(null===e||null===n)return;let o={};const c=y.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,y.push(o)),o.label=null==n?{text:""}:{text:n},null==i)o.type={text:"node"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.type={text:i};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=u,o.wrap=A(),p=u,u=e,d.push(p)},popBoundaryParseStack:function(){u=p,d.pop(),p=d.pop(),d.push(p)},addRel:function(t,e,n,i,a,s,r,l,o){if(null==t||null==e||null==n||null==i)return;let c={};const h=f.find((t=>t.from===e&&t.to===n));if(h?c=h:f.push(c),c.type=t,c.from=e,c.to=n,c.label={text:i},null==a)c.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];c[t]={text:e}}else c.techn={text:a};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=A()},updateElStyle:function(t,e,n,i,a,s,r,l,o,c,d){let u=h.find((t=>t.alias===e));if(void 0!==u||(u=y.find((t=>t.alias===e)),void 0!==u)){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];u[t]=e}else u.bgColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];u[t]=e}else u.fontColor=i;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];u[t]=e}else u.borderColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];u[t]=e}else u.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];u[t]=e}else u.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];u[t]=e}else u.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];u[t]=e}else u.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];u[t]=e}else u.legendText=c;if(null!=d)if("object"==typeof d){let[t,e]=Object.entries(d)[0];u[t]=e}else u.legendSprite=d}},updateRelStyle:function(t,e,n,i,a,s,r){const l=f.find((t=>t.from===e&&t.to===n));if(void 0!==l){if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.textColor=i;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.lineColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,n){let i=_,a=x;if("object"==typeof e){const t=Object.values(e)[0];i=parseInt(t)}else i=parseInt(e);if("object"==typeof n){const t=Object.values(n)[0];a=parseInt(t)}else a=parseInt(n);i>=1&&(_=i),a>=1&&(x=a)},autoWrap:A,setWrap:function(t){g=t},getC4ShapeArray:E,getC4Shape:function(t){return h.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(E(t))},getBoundarys:function(t){return null==t?y:y.filter((e=>e.parentBoundary===t))},getCurrentBoundaryParse:function(){return u},getParentBoundaryParse:function(){return p},getRels:function(){return f},getTitle:function(){return b},getC4Type:function(){return m},getC4ShapeInRow:function(){return _},getC4BoundaryInRow:function(){return x},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,parseDirective:function(t,e,n){i.m.parseDirective(this,t,e,n)},getConfig:()=>(0,i.c)().c4,clear:function(){h=[],y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],p="",u="global",d=[""],f=[],d=[""],b="",g=!1,_=4,x=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=(0,i.d)(t,(0,i.c)());b=e},setC4Type:function(t){let e=(0,i.d)(t,(0,i.c)());m=e}},v=function(t,e){return(0,s.d)(t,e)},C=function(){function t(t,e,n,i,s,r,l){a(e.append("text").attr("x",n+s/2).attr("y",i+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,n,s,r,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(i.e.lineBreakRegex);for(let t=0;t>"),e.typeC4Shape.text){case"person":case"external_person":!function(t,e,n,i,a,s){const l=t.append("image");l.attr("width",e),l.attr("height",n),l.attr("x",i),l.attr("y",a);let o=s.startsWith("data:image/png;base64")?s:(0,r.Nm)(s);l.attr("xlink:href",o)}(h,48,48,e.x+e.width/2-24,e.y+e.image.Y,c)}let f=n[e.typeC4Shape.text+"Font"]();return f.fontWeight="bold",f.fontSize=f.fontSize+2,f.fontColor=o,C(n)(e.label.text,h,e.x,e.y+e.label.Y,e.width,e.height,{fill:o},f),f=n[e.typeC4Shape.text+"Font"](),f.fontColor=o,e.techn&&""!==(null==(i=e.techn)?void 0:i.text)?C(n)(e.techn.text,h,e.x,e.y+e.techn.Y,e.width,e.height,{fill:o,"font-style":"italic"},f):e.type&&""!==e.type.text&&C(n)(e.type.text,h,e.x,e.y+e.type.Y,e.width,e.height,{fill:o,"font-style":"italic"},f),e.descr&&""!==e.descr.text&&(f=n.personFont(),f.fontColor=o,C(n)(e.descr.text,h,e.x,e.y+e.descr.Y,e.width,e.height,{fill:o},f)),e.height};let O=0,T=0,w=4,D=2;l.yy=S;let R={};class N{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,P(t.db.getConfig())}setData(t,e,n,i){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=i}updateVal(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,n=e+t.width,i=this.nextData.starty+2*t.margin,a=i+t.height;(e>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>w)&&(e=this.nextData.startx+t.margin+R.nextLinePaddingX,i=this.nextData.stopy+2*t.margin,this.nextData.stopx=n=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=i+t.height,this.nextData.cnt=1),t.x=e,t.y=i,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",i,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",i,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},P(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const P=function(t){(0,i.f)(R,t),t.fontFamily&&(R.personFontFamily=R.systemFontFamily=R.messageFontFamily=t.fontFamily),t.fontSize&&(R.personFontSize=R.systemFontSize=R.messageFontSize=t.fontSize),t.fontWeight&&(R.personFontWeight=R.systemFontWeight=R.messageFontWeight=t.fontWeight)},M=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),j=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function B(t,e,n,a,s){if(!e[t].width)if(n)e[t].text=(0,i.w)(e[t].text,s,a),e[t].textLines=e[t].text.split(i.e.lineBreakRegex).length,e[t].width=s,e[t].height=(0,i.j)(e[t].text,a);else{let n=e[t].text.split(i.e.lineBreakRegex);e[t].textLines=n.length;let s=0;e[t].height=0,e[t].width=0;for(const r of n)e[t].width=Math.max((0,i.h)(r,a),e[t].width),s=(0,i.j)(r,a),e[t].height=e[t].height+s}}const Y=function(t,e,n){e.x=n.data.startx,e.y=n.data.starty,e.width=n.data.stopx-n.data.startx,e.height=n.data.stopy-n.data.starty,e.label.y=R.c4ShapeMargin-35;let a=e.wrap&&R.wrap,s=j(R);s.fontSize=s.fontSize+2,s.fontWeight="bold",B("label",e,a,s,(0,i.h)(e.label.text,s)),function(t,e,n){const i=t.append("g");let a=e.bgColor?e.bgColor:"none",s=e.borderColor?e.borderColor:"#444444",r=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:a,stroke:s,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};v(i,o);let c=n.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=r,C(n)(e.label.text,i,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=n.boundaryFont(),c.fontColor=r,C(n)(e.type.text,i,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=n.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=r,C(n)(e.descr.text,i,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))}(t,e,R)},L=function(t,e,n,a){let s=0;for(const r of a){s=0;const a=n[r];let l=M(R,a.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,a.typeC4Shape.width=(0,i.h)("«"+a.typeC4Shape.text+"»",l),a.typeC4Shape.height=l.fontSize+2,a.typeC4Shape.Y=R.c4ShapePadding,s=a.typeC4Shape.Y+a.typeC4Shape.height-4,a.image={width:0,height:0,Y:0},a.typeC4Shape.text){case"person":case"external_person":a.image.width=48,a.image.height=48,a.image.Y=s,s=a.image.Y+a.image.height}a.sprite&&(a.image.width=48,a.image.height=48,a.image.Y=s,s=a.image.Y+a.image.height);let o=a.wrap&&R.wrap,c=R.width-2*R.c4ShapePadding,h=M(R,a.typeC4Shape.text);h.fontSize=h.fontSize+2,h.fontWeight="bold",B("label",a,o,h,c),a.label.Y=s+8,s=a.label.Y+a.label.height,a.type&&""!==a.type.text?(a.type.text="["+a.type.text+"]",B("type",a,o,M(R,a.typeC4Shape.text),c),a.type.Y=s+5,s=a.type.Y+a.type.height):a.techn&&""!==a.techn.text&&(a.techn.text="["+a.techn.text+"]",B("techn",a,o,M(R,a.techn.text),c),a.techn.Y=s+5,s=a.techn.Y+a.techn.height);let d=s,u=a.label.width;a.descr&&""!==a.descr.text&&(B("descr",a,o,M(R,a.typeC4Shape.text),c),a.descr.Y=s+20,s=a.descr.Y+a.descr.height,u=Math.max(a.label.width,a.descr.width),d=s-5*a.descr.textLines),u+=R.c4ShapePadding,a.width=Math.max(a.width||R.width,u,R.width),a.height=Math.max(a.height||R.height,d,R.height),a.margin=a.margin||R.c4ShapeMargin,t.insert(a),k(e,a,R)}t.bumpLastMargin(R.c4ShapeMargin)};class I{constructor(t,e){this.x=t,this.y=e}}let U=function(t,e){let n=t.x,i=t.y,a=e.x,s=e.y,r=n+t.width/2,l=i+t.height/2,o=Math.abs(n-a),c=Math.abs(i-s),h=c/o,d=t.height/t.width,u=null;return i==s&&na?u=new I(n,l):n==a&&is&&(u=new I(r,i)),n>a&&i=h?new I(n,l+h*t.width/2):new I(r-o/c*t.height/2,i+t.height):n=h?new I(n+t.width,l+h*t.width/2):new I(r+o/c*t.height/2,i+t.height):ns?u=d>=h?new I(n+t.width,l-h*t.width/2):new I(r+t.height/2*o/c,i):n>a&&i>s&&(u=d>=h?new I(n,l-t.width/2*h):new I(r-t.height/2*o/c,i)),u},F=function(t,e){let n={x:0,y:0};n.x=e.x+e.width/2,n.y=e.y+e.height/2;let i=U(t,n);return n.x=t.x+t.width/2,n.y=t.y+t.height/2,{startPoint:i,endPoint:U(e,n)}};function X(t,e,n,i,a){let s=new N(a);s.data.widthLimit=n.data.widthLimit/Math.min(D,i.length);for(let[r,l]of i.entries()){let i=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=i,i=l.image.Y+l.image.height);let o=l.wrap&&R.wrap,c=j(R);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",B("label",l,o,c,s.data.widthLimit),l.label.Y=i+8,i=l.label.Y+l.label.height,l.type&&""!==l.type.text&&(l.type.text="["+l.type.text+"]",B("type",l,o,j(R),s.data.widthLimit),l.type.Y=i+5,i=l.type.Y+l.type.height),l.descr&&""!==l.descr.text){let t=j(R);t.fontSize=t.fontSize-2,B("descr",l,o,t,s.data.widthLimit),l.descr.Y=i+20,i=l.descr.Y+l.descr.height}if(0==r||r%D==0){let t=n.data.startx+R.diagramMarginX,e=n.data.stopy+R.diagramMarginY+i;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+R.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=a.db.getC4ShapeArray(l.alias),d=a.db.getC4ShapeKeys(l.alias);d.length>0&&L(s,t,h,d),e=l.alias;let u=a.db.getBoundarys(e);u.length>0&&X(t,e,s,u,a),"global"!==l.alias&&Y(t,l,s),n.data.stopy=Math.max(s.data.stopy+R.c4ShapeMargin,n.data.stopy),n.data.stopx=Math.max(s.data.stopx+R.c4ShapeMargin,n.data.stopx),O=Math.max(O,n.data.stopx),T=Math.max(T,n.data.stopy)}}const z={drawPersonOrSystemArray:L,drawBoundary:Y,setConf:P,draw:function(t,e,n,s){R=(0,i.c)().c4;const r=(0,i.c)().securityLevel;let l;"sandbox"===r&&(l=(0,a.Ys)("#i"+e));const o="sandbox"===r?(0,a.Ys)(l.nodes()[0].contentDocument.body):(0,a.Ys)("body");let c=s.db;s.db.setWrap(R.wrap),w=c.getC4ShapeInRow(),D=c.getC4BoundaryInRow(),i.l.debug(`C:${JSON.stringify(R,null,2)}`);const h="sandbox"===r?o.select(`[id="${e}"]`):(0,a.Ys)(`[id="${e}"]`);h.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z"),function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")}(h),function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")}(h);let d=new N(s);d.setData(R.diagramMarginX,R.diagramMarginX,R.diagramMarginY,R.diagramMarginY),d.data.widthLimit=screen.availWidth,O=R.diagramMarginX,T=R.diagramMarginY;const u=s.db.getTitle();X(h,"",d,s.db.getBoundarys(""),s),function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")}(h),function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")}(h),function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")}(h),function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")}(h),function(t,e,n,a){let s=0;for(let t of e){s+=1;let e=t.wrap&&R.wrap,l={fontFamily:(r=R).messageFontFamily,fontSize:r.messageFontSize,fontWeight:r.messageFontWeight};"C4Dynamic"===a.db.getC4Type()&&(t.label.text=s+": "+t.label.text);let o=(0,i.h)(t.label.text,l);B("label",t,e,l,o),t.techn&&""!==t.techn.text&&(o=(0,i.h)(t.techn.text,l),B("techn",t,e,l,o)),t.descr&&""!==t.descr.text&&(o=(0,i.h)(t.descr.text,l),B("descr",t,e,l,o));let c=n(t.from),h=n(t.to),d=F(c,h);t.startPoint=d.startPoint,t.endPoint=d.endPoint}var r;((t,e,n)=>{const i=t.append("g");let a=0;for(let t of e){let e=t.textColor?t.textColor:"#444444",s=t.lineColor?t.lineColor:"#444444",r=t.offsetX?parseInt(t.offsetX):0,l=t.offsetY?parseInt(t.offsetY):0,o="";if(0===a){let e=i.append("line");e.attr("x1",t.startPoint.x),e.attr("y1",t.startPoint.y),e.attr("x2",t.endPoint.x),e.attr("y2",t.endPoint.y),e.attr("stroke-width","1"),e.attr("stroke",s),e.style("fill","none"),"rel_b"!==t.type&&e.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==t.type&&"rel_b"!==t.type||e.attr("marker-start","url("+o+"#arrowend)"),a=-1}else{let e=i.append("path");e.attr("fill","none").attr("stroke-width","1").attr("stroke",s).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",t.startPoint.x).replaceAll("starty",t.startPoint.y).replaceAll("controlx",t.startPoint.x+(t.endPoint.x-t.startPoint.x)/2-(t.endPoint.x-t.startPoint.x)/4).replaceAll("controly",t.startPoint.y+(t.endPoint.y-t.startPoint.y)/2).replaceAll("stopx",t.endPoint.x).replaceAll("stopy",t.endPoint.y)),"rel_b"!==t.type&&e.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==t.type&&"rel_b"!==t.type||e.attr("marker-start","url("+o+"#arrowend)")}let c=n.messageFont();C(n)(t.label.text,i,Math.min(t.startPoint.x,t.endPoint.x)+Math.abs(t.endPoint.x-t.startPoint.x)/2+r,Math.min(t.startPoint.y,t.endPoint.y)+Math.abs(t.endPoint.y-t.startPoint.y)/2+l,t.label.width,t.label.height,{fill:e},c),t.techn&&""!==t.techn.text&&(c=n.messageFont(),C(n)("["+t.techn.text+"]",i,Math.min(t.startPoint.x,t.endPoint.x)+Math.abs(t.endPoint.x-t.startPoint.x)/2+r,Math.min(t.startPoint.y,t.endPoint.y)+Math.abs(t.endPoint.y-t.startPoint.y)/2+n.messageFontSize+5+l,Math.max(t.label.width,t.techn.width),t.techn.height,{fill:e,"font-style":"italic"},c))}})(t,e,R)}(h,s.db.getRels(),s.db.getC4Shape,s),d.data.stopx=O,d.data.stopy=T;const p=d.data;let y=p.stopy-p.starty+2*R.diagramMarginY;const f=p.stopx-p.startx+2*R.diagramMarginX;u&&h.append("text").text(u).attr("x",(p.stopx-p.startx)/2-4*R.diagramMarginX).attr("y",p.starty+R.diagramMarginY),(0,i.i)(h,y,f,R.useMaxWidth);const b=u?60:0;h.attr("viewBox",p.startx-R.diagramMarginX+" -"+(R.diagramMarginY+b)+" "+f+" "+(y+b)),i.l.debug("models:",p)}},Q={parser:o,db:S,renderer:z,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:t=>{z.setConf(t.c4)}}},8252:function(t,e,n){n.d(e,{a:function(){return r},b:function(){return c},c:function(){return o},d:function(){return s},e:function(){return d},f:function(){return l},g:function(){return h}});var i=n(7967),a=n(9339);const s=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const t in e.attrs)n.attr(t,e.attrs[t]);return void 0!==e.class&&n.attr("class",e.class),n},r=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,n).lower()},l=(t,e)=>{const n=e.text.replace(a.J," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const s=i.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),i},o=(t,e,n,a)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const r=(0,i.Nm)(a);s.attr("xlink:href",r)},c=(t,e,n,a)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const r=(0,i.Nm)(a);s.attr("xlink:href",`#${r}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/546-560b35c2.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/546-560b35c2.chunk.min.js new file mode 100644 index 000000000..f1c2fbe83 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/546-560b35c2.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[546],{3546:function(t,e,i){i.d(e,{diagram:function(){return y}});var n=i(9339),s=i(7274),r=(i(7484),i(7967),i(7856),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,4],i=[1,5],n=[1,6],s=[1,7],r=[1,9],c=[1,11,13,15,17,19,20,26,27,28,29],l=[2,5],a=[1,6,11,13,15,17,19,20,26,27,28,29],o=[26,27,28],h=[2,8],u=[1,18],y=[1,19],p=[1,20],d=[1,21],g=[1,22],_=[1,23],f=[1,28],m=[6,26,27,28,29],v={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,showData:8,line:9,statement:10,txt:11,value:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,openDirective:21,typeDirective:22,closeDirective:23,":":24,argDirective:25,NEWLINE:26,";":27,EOF:28,open_directive:29,type_directive:30,arg_directive:31,close_directive:32,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",8:"showData",11:"txt",12:"value",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",24:":",26:"NEWLINE",27:";",28:"EOF",29:"open_directive",30:"type_directive",31:"arg_directive",32:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,3],[7,0],[7,2],[9,2],[10,0],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[5,3],[5,5],[4,1],[4,1],[4,1],[21,1],[22,1],[25,1],[23,1]],performAction:function(t,e,i,n,s,r,c){var l=r.length-1;switch(s){case 4:n.setShowData(!0);break;case 7:this.$=r[l-1];break;case 9:n.addSection(r[l-1],n.cleanupValue(r[l]));break;case 10:this.$=r[l].trim(),n.setDiagramTitle(this.$);break;case 11:this.$=r[l].trim(),n.setAccTitle(this.$);break;case 12:case 13:this.$=r[l].trim(),n.setAccDescription(this.$);break;case 14:n.addSection(r[l].substr(8)),this.$=r[l].substr(8);break;case 21:n.parseDirective("%%{","open_directive");break;case 22:n.parseDirective(r[l],"type_directive");break;case 23:r[l]=r[l].trim().replace(/'/g,'"'),n.parseDirective(r[l],"arg_directive");break;case 24:n.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:e,21:8,26:i,27:n,28:s,29:r},{1:[3]},{3:10,4:2,5:3,6:e,21:8,26:i,27:n,28:s,29:r},{3:11,4:2,5:3,6:e,21:8,26:i,27:n,28:s,29:r},t(c,l,{7:12,8:[1,13]}),t(a,[2,18]),t(a,[2,19]),t(a,[2,20]),{22:14,30:[1,15]},{30:[2,21]},{1:[2,1]},{1:[2,2]},t(o,h,{21:8,9:16,10:17,5:24,1:[2,3],11:u,13:y,15:p,17:d,19:g,20:_,29:r}),t(c,l,{7:25}),{23:26,24:[1,27],32:f},t([24,32],[2,22]),t(c,[2,6]),{4:29,26:i,27:n,28:s},{12:[1,30]},{14:[1,31]},{16:[1,32]},{18:[1,33]},t(o,[2,13]),t(o,[2,14]),t(o,[2,15]),t(o,h,{21:8,9:16,10:17,5:24,1:[2,4],11:u,13:y,15:p,17:d,19:g,20:_,29:r}),t(m,[2,16]),{25:34,31:[1,35]},t(m,[2,24]),t(c,[2,7]),t(o,[2,9]),t(o,[2,10]),t(o,[2,11]),t(o,[2,12]),{23:36,32:f},{32:[2,23]},t(m,[2,17])],defaultActions:{9:[2,21],10:[2,1],11:[2,2],35:[2,23]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=[0],i=[],n=[null],s=[],r=this.table,c="",l=0,a=0,o=s.slice.call(arguments,1),h=Object.create(this.lexer),u={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(u.yy[y]=this.yy[y]);h.setInput(t,u.yy),u.yy.lexer=h,u.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;s.push(p);var d=h.options&&h.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,_,f,m,v,b,k,x,S,w={};;){if(_=e[e.length-1],this.defaultActions[_]?f=this.defaultActions[_]:(null==g&&(S=void 0,"number"!=typeof(S=i.pop()||h.lex()||1)&&(S instanceof Array&&(S=(i=S).pop()),S=this.symbols_[S]||S),g=S),f=r[_]&&r[_][g]),void 0===f||!f.length||!f[0]){var $;for(v in x=[],r[_])this.terminals_[v]&&v>2&&x.push("'"+this.terminals_[v]+"'");$=h.showPosition?"Parse error on line "+(l+1)+":\n"+h.showPosition()+"\nExpecting "+x.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError($,{text:h.match,token:this.terminals_[g]||g,line:h.yylineno,loc:p,expected:x})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(f[0]){case 1:e.push(g),n.push(h.yytext),s.push(h.yylloc),e.push(f[1]),g=null,a=h.yyleng,c=h.yytext,l=h.yylineno,p=h.yylloc;break;case 2:if(b=this.productions_[f[1]][1],w.$=n[n.length-b],w._$={first_line:s[s.length-(b||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(b||1)].first_column,last_column:s[s.length-1].last_column},d&&(w._$.range=[s[s.length-(b||1)].range[0],s[s.length-1].range[1]]),void 0!==(m=this.performAction.apply(w,[c,a,l,u.yy,f[1],n,s].concat(o))))return m;b&&(e=e.slice(0,-1*b*2),n=n.slice(0,-1*b),s=s.slice(0,-1*b)),e.push(this.productions_[f[1]][0]),n.push(w.$),s.push(w._$),k=r[e[e.length-2]][e[e.length-1]],e.push(k);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=i,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return this.begin("open_directive"),29;case 1:return this.begin("type_directive"),30;case 2:return this.popState(),this.begin("arg_directive"),24;case 3:return this.popState(),this.popState(),32;case 4:return 31;case 5:case 6:case 8:case 9:break;case 7:return 26;case 10:return this.begin("title"),13;case 11:return this.popState(),"title_value";case 12:return this.begin("acc_title"),15;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),17;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:case 20:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:this.begin("string");break;case 21:return"txt";case 22:return 6;case 23:return 8;case 24:return"value";case 25:return 28}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[20,21],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,14,16,19,22,23,24,25],inclusive:!0}}};function k(){this.yy={}}return v.lexer=b,k.prototype=v,v.Parser=k,new k}());r.parser=r;const c=r,l=n.C.pie,a={};let o=a,h=false;const u=structuredClone(l),y={parser:c,db:{getConfig:()=>structuredClone(u),parseDirective:(t,e,i)=>{(0,n.D)(void 0,t,e,i)},clear:()=>{o=structuredClone(a),h=false,(0,n.v)()},setDiagramTitle:n.r,getDiagramTitle:n.t,setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addSection:(t,e)=>{t=(0,n.d)(t,(0,n.c)()),void 0===o[t]&&(o[t]=e,n.l.debug(`added new section: ${t}, with value: ${e}`))},getSections:()=>o,cleanupValue:t=>(":"===t.substring(0,1)&&(t=t.substring(1).trim()),Number(t.trim())),setShowData:t=>{h=t},getShowData:()=>h},renderer:{draw:(t,e,i,r)=>{var c,l;n.l.debug("rendering pie chart\n"+t);const a=r.db,o=(0,n.c)(),h=(0,n.E)(a.getConfig(),o.pie),u=(null==(l=null==(c=document.getElementById(e))?void 0:c.parentElement)?void 0:l.offsetWidth)??h.useWidth,y=(0,n.B)(e);y.attr("viewBox",`0 0 ${u} 450`),(0,n.i)(y,450,u,h.useMaxWidth);const p=y.append("g");p.attr("transform","translate("+u/2+",225)");const{themeVariables:d}=o;let[g]=(0,n.F)(d.pieOuterStrokeWidth);g??(g=2);const _=h.textPosition,f=Math.min(u,450)/2-40,m=(0,s.Nb1)().innerRadius(0).outerRadius(f),v=(0,s.Nb1)().innerRadius(f*_).outerRadius(f*_);p.append("circle").attr("cx",0).attr("cy",0).attr("r",f+g/2).attr("class","pieOuterCircle");const b=a.getSections(),k=(t=>{const e=Object.entries(t).map((t=>({label:t[0],value:t[1]})));return(0,s.ve8)().value((t=>t.value))(e)})(b),x=[d.pie1,d.pie2,d.pie3,d.pie4,d.pie5,d.pie6,d.pie7,d.pie8,d.pie9,d.pie10,d.pie11,d.pie12],S=(0,s.PKp)(x);p.selectAll("mySlices").data(k).enter().append("path").attr("d",m).attr("fill",(t=>S(t.data.label))).attr("class","pieCircle");let w=0;Object.keys(b).forEach((t=>{w+=b[t]})),p.selectAll("mySlices").data(k).enter().append("text").text((t=>(t.data.value/w*100).toFixed(0)+"%")).attr("transform",(t=>"translate("+v.centroid(t)+")")).style("text-anchor","middle").attr("class","slice"),p.append("text").text(a.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const $=p.selectAll(".legend").data(S.domain()).enter().append("g").attr("class","legend").attr("transform",((t,e)=>"translate(216,"+(22*e-22*S.domain().length/2)+")"));$.append("rect").attr("width",18).attr("height",18).style("fill",S).style("stroke",S),$.data(k).append("text").attr("x",22).attr("y",14).text((t=>{const{label:e,value:i}=t.data;return a.getShowData()?`${e} [${i}]`:e}))}},styles:t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/579-9222afff.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/579-9222afff.chunk.min.js new file mode 100644 index 000000000..629004ff6 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/579-9222afff.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[579],{8579:function(t,n,e){e.d(n,{diagram:function(){return R}});var i=e(9339),s=e(7274);function r(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e>n||void 0===e&&n>=n)&&(e=n);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function o(t){return t.target.depth}function c(t,n){return t.sourceLinks.length?t.depth:n-1}function l(t,n){let e=0;if(void 0===n)for(let n of t)(n=+n)&&(e+=n);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function h(t,n){let e;if(void 0===n)for(const n of t)null!=n&&(e=n)&&(e=n);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e=s)&&(e=s)}return e}function a(t){return function(){return t}}function u(t,n){return y(t.source,n.source)||t.index-n.index}function f(t,n){return y(t.target,n.target)||t.index-n.index}function y(t,n){return t.y0-n.y0}function d(t){return t.value}function p(t){return t.index}function g(t){return t.nodes}function _(t){return t.links}function k(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function x({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const e of n.sourceLinks)e.y0=t+e.width/2,t+=e.width;for(const t of n.targetLinks)t.y1=e+t.width/2,e+=t.width}}var m=Math.PI,v=2*m,b=1e-6,w=v-b;function E(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function L(){return new E}E.prototype=L.prototype={constructor:E,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,c=e-t,l=i-n,h=r-t,a=o-n,u=h*h+a*a;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>b)if(Math.abs(a*c-l*h)>b&&s){var f=e-r,y=i-o,d=c*c+l*l,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),k=s*Math.tan((m-Math.acos((d+u-p)/(2*g*_)))/2),x=k/_,v=k/g;Math.abs(x-1)>b&&(this._+="L"+(t+x*h)+","+(n+x*a)),this._+="A"+s+","+s+",0,0,"+ +(a*f>h*y)+","+(this._x1=t+v*c)+","+(this._y1=n+v*l)}else this._+="L"+(this._x1=t)+","+(this._y1=n)},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),c=e*Math.sin(i),l=t+o,h=n+c,a=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+l+","+h:(Math.abs(this._x1-l)>b||Math.abs(this._y1-h)>b)&&(this._+="L"+l+","+h),e&&(u<0&&(u=u%v+v),u>w?this._+="A"+e+","+e+",0,1,"+a+","+(t-o)+","+(n-c)+"A"+e+","+e+",0,1,"+a+","+(this._x1=l)+","+(this._y1=h):u>b&&(this._+="A"+e+","+e+",0,"+ +(u>=m)+","+a+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};var A=L,S=Array.prototype.slice;function M(t){return function(){return t}}function I(t){return t[0]}function T(t){return t[1]}function O(t){return t.source}function P(t){return t.target}function C(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function D(t){return[t.source.x1,t.y0]}function N(t){return[t.target.x0,t.y1]}function $(){return function(t){var n=O,e=P,i=I,s=T,r=null;function o(){var o,c=S.call(arguments),l=n.apply(this,c),h=e.apply(this,c);if(r||(r=o=A()),t(r,+i.apply(this,(c[0]=l,c)),+s.apply(this,c),+i.apply(this,(c[0]=h,c)),+s.apply(this,c)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:M(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:M(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}(C).source(D).target(N)}e(7484),e(7967),e(7856);var j=function(){var t=function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e},n=[1,9],e=[1,10],i=[1,5,10,12],s={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(t,n,e,i,s,r,o){var c=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[c-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[c-2].trim().replaceAll('""','"')),e=parseFloat(r[c].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[c];break;case 10:this.$=r[c-1]}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(i,[2,8]),t(i,[2,9]),{19:[1,16]},t(i,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(i,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)},parse:function(t){var n=[0],e=[],i=[null],s=[],r=this.table,o="",c=0,l=0,h=s.slice.call(arguments,1),a=Object.create(this.lexer),u={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(u.yy[f]=this.yy[f]);a.setInput(t,u.yy),u.yy.lexer=a,u.yy.parser=this,void 0===a.yylloc&&(a.yylloc={});var y=a.yylloc;s.push(y);var d=a.options&&a.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var p,g,_,k,x,m,v,b,w,E={};;){if(g=n[n.length-1],this.defaultActions[g]?_=this.defaultActions[g]:(null==p&&(w=void 0,"number"!=typeof(w=e.pop()||a.lex()||1)&&(w instanceof Array&&(w=(e=w).pop()),w=this.symbols_[w]||w),p=w),_=r[g]&&r[g][p]),void 0===_||!_.length||!_[0]){var L;for(x in b=[],r[g])this.terminals_[x]&&x>2&&b.push("'"+this.terminals_[x]+"'");L=a.showPosition?"Parse error on line "+(c+1)+":\n"+a.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[p]||p)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==p?"end of input":"'"+(this.terminals_[p]||p)+"'"),this.parseError(L,{text:a.match,token:this.terminals_[p]||p,line:a.yylineno,loc:y,expected:b})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+p);switch(_[0]){case 1:n.push(p),i.push(a.yytext),s.push(a.yylloc),n.push(_[1]),p=null,l=a.yyleng,o=a.yytext,c=a.yylineno,y=a.yylloc;break;case 2:if(m=this.productions_[_[1]][1],E.$=i[i.length-m],E._$={first_line:s[s.length-(m||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(m||1)].first_column,last_column:s[s.length-1].last_column},d&&(E._$.range=[s[s.length-(m||1)].range[0],s[s.length-1].range[1]]),void 0!==(k=this.performAction.apply(E,[o,l,c,u.yy,_[1],i,s].concat(h))))return k;m&&(n=n.slice(0,-1*m*2),i=i.slice(0,-1*m),s=s.slice(0,-1*m)),n.push(this.productions_[_[1]][0]),i.push(E.$),s.push(E._$),v=r[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;rn[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{easy_keword_rules:!0},performAction:function(t,n,e,i){switch(e){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}},rules:[/^(?:sankey-beta\b)/,/^(?:$)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:(\u002C))/,/^(?:(\u0022))/,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/,/^(?:(\u0022)(?!(\u0022)))/,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};function o(){this.yy={}}return s.lexer=r,o.prototype=s,s.Parser=o,new o}();j.parser=j;const z=j;let Y=[],F=[],U={};class W{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}}class K{constructor(t){this.ID=t}}const G={nodesMap:U,getConfig:()=>(0,i.c)().sankey,getNodes:()=>F,getLinks:()=>Y,getGraph:()=>({nodes:F.map((t=>({id:t.ID}))),links:Y.map((t=>({source:t.source.ID,target:t.target.ID,value:t.value})))}),addLink:(t,n,e)=>{Y.push(new W(t,n,e))},findOrCreateNode:t=>(t=i.e.sanitizeText(t,(0,i.c)()),U[t]||(U[t]=new K(t),F.push(U[t])),U[t]),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,getDiagramTitle:i.t,setDiagramTitle:i.r,clear:()=>{Y=[],F=[],U={},(0,i.v)()}},V=class{static next(t){return new V(t+ ++V.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}};let X=V;X.count=0;const q={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?r(t.sourceLinks,o)-1:0},justify:c},Q={draw:function(t,n,e,o){const{securityLevel:m,sankey:v}=(0,i.c)(),b=i.K.sankey;let w;"sandbox"===m&&(w=(0,s.Ys)("#i"+n));const E="sandbox"===m?(0,s.Ys)(w.nodes()[0].contentDocument.body):(0,s.Ys)("body"),L="sandbox"===m?E.select(`[id="${n}"]`):(0,s.Ys)(`[id="${n}"]`),A=(null==v?void 0:v.width)??b.width,S=(null==v?void 0:v.height)??b.width,M=(null==v?void 0:v.useMaxWidth)??b.useMaxWidth,I=(null==v?void 0:v.nodeAlignment)??b.nodeAlignment,T=(null==v?void 0:v.prefix)??b.prefix,O=(null==v?void 0:v.suffix)??b.suffix,P=(null==v?void 0:v.showValues)??b.showValues;(0,i.i)(L,S,A,M);const C=o.db.getGraph(),D=q[I];(function(){let t,n,e,i=0,s=0,o=1,m=1,v=24,b=8,w=p,E=c,L=g,A=_,S=6;function M(){const c={nodes:L.apply(null,arguments),links:A.apply(null,arguments)};return function({nodes:t,links:n}){for(const[n,e]of t.entries())e.index=n,e.sourceLinks=[],e.targetLinks=[];const i=new Map(t.map(((n,e)=>[w(n,e,t),n])));for(const[t,e]of n.entries()){e.index=t;let{source:n,target:s}=e;"object"!=typeof n&&(n=e.source=k(i,n)),"object"!=typeof s&&(s=e.target=k(i,s)),n.sourceLinks.push(e),s.targetLinks.push(e)}if(null!=e)for(const{sourceLinks:n,targetLinks:i}of t)n.sort(e),i.sort(e)}(c),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(l(n.sourceLinks,d),l(n.targetLinks,d)):n.fixedValue}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function(e){const c=function({nodes:t}){const e=h(t,(t=>t.depth))+1,s=(o-i-v)/(e-1),r=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(E.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,r[t]?r[t].push(n):r[t]=[n]}if(n)for(const t of r)t.sort(n);return r}(e);t=Math.min(b,(m-s)/(h(c,(t=>t.length))-1)),function(n){const e=r(n,(n=>(m-s-(n.length-1)*t)/l(n,d)));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(m-n+t)/(i.length+1);for(let t=0;t0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,D(t)}void 0===n&&r.sort(y),O(r,i)}}function T(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:s}of t.sourceLinks){let r=s*(e.layer-t.layer);n+=j(t,e)*r,i+=r}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,D(t)}void 0===n&&r.sort(y),O(r,i)}}function O(n,e){const i=n.length>>1,r=n[i];C(n,r.y0-t,i-1,e),P(n,r.y1+t,i+1,e),C(n,m,n.length-1,e),P(n,s,0,e)}function P(n,e,i,s){for(;i1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function C(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function D({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(f);for(const{target:{targetLinks:n}}of t)n.sort(u)}}function N(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(f),e.sort(u)}function $(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function j(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return M.update=function(t){return x(t),t},M.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:a(t),M):w},M.nodeAlign=function(t){return arguments.length?(E="function"==typeof t?t:a(t),M):E},M.nodeSort=function(t){return arguments.length?(n=t,M):n},M.nodeWidth=function(t){return arguments.length?(v=+t,M):v},M.nodePadding=function(n){return arguments.length?(b=t=+n,M):b},M.nodes=function(t){return arguments.length?(L="function"==typeof t?t:a(t),M):L},M.links=function(t){return arguments.length?(A="function"==typeof t?t:a(t),M):A},M.linkSort=function(t){return arguments.length?(e=t,M):e},M.size=function(t){return arguments.length?(i=s=0,o=+t[0],m=+t[1],M):[o-i,m-s]},M.extent=function(t){return arguments.length?(i=+t[0][0],o=+t[1][0],s=+t[0][1],m=+t[1][1],M):[[i,s],[o,m]]},M.iterations=function(t){return arguments.length?(S=+t,M):S},M})().nodeId((t=>t.id)).nodeWidth(10).nodePadding(10+(P?15:0)).nodeAlign(D).extent([[0,0],[A,S]])(C);const N=(0,s.PKp)(s.K2I);L.append("g").attr("class","nodes").selectAll(".node").data(C.nodes).join("g").attr("class","node").attr("id",(t=>(t.uid=X.next("node-")).id)).attr("transform",(function(t){return"translate("+t.x0+","+t.y0+")"})).attr("x",(t=>t.x0)).attr("y",(t=>t.y0)).append("rect").attr("height",(t=>t.y1-t.y0)).attr("width",(t=>t.x1-t.x0)).attr("fill",(t=>N(t.id))),L.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(C.nodes).join("text").attr("x",(t=>t.x0(t.y1+t.y0)/2)).attr("dy",(P?"0":"0.35")+"em").attr("text-anchor",(t=>t.x0P?`${t}\n${T}${Math.round(100*n)/100}${O}`:t));const j=L.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(C.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),z=(null==v?void 0:v.linkColor)||"gradient";if("gradient"===z){const t=j.append("linearGradient").attr("id",(t=>(t.uid=X.next("linearGradient-")).id)).attr("gradientUnits","userSpaceOnUse").attr("x1",(t=>t.source.x1)).attr("x2",(t=>t.target.x0));t.append("stop").attr("offset","0%").attr("stop-color",(t=>N(t.source.id))),t.append("stop").attr("offset","100%").attr("stop-color",(t=>N(t.target.id)))}let Y;switch(z){case"gradient":Y=t=>t.uid;break;case"source":Y=t=>N(t.source.id);break;case"target":Y=t=>N(t.target.id);break;default:Y=z}j.append("path").attr("d",$()).attr("stroke",Y).attr("stroke-width",(t=>Math.max(1,t.width)))}},B=z.parse.bind(z);z.parse=t=>B((t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim())(t));const R={parser:z,db:G,renderer:Q}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/626-1706197a.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/626-1706197a.chunk.min.js new file mode 100644 index 000000000..1af186fd5 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/626-1706197a.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[626],{1626:function(e,t,s){s.d(t,{diagram:function(){return N}});var o=s(1535),i=s(5625),a=s(7274),r=s(9339),n=s(6476);s(7484),s(7967),s(7856),s(3771),s(9368);const d="rect",c="rectWithTitle",l="statediagram",p=`${l}-state`,g="transition",b=`${g} note-edge`,h=`${l}-note`,u=`${l}-cluster`,y=`${l}-cluster-alt`,f="parent",w="note",x="----",$=`${x}${w}`,m=`${x}${f}`,T="fill:none",k="fill: #333",S="text",D="normal";let A={},v=0;function B(e="",t=0,s="",o=x){return`state-${e}${null!==s&&s.length>0?`${o}${s}`:""}-${t}`}const C=(e,t,s,i,a,n)=>{const l=s.id,g=null==(x=i[l])?"":x.classes?x.classes.join(" "):"";var x;if("root"!==l){let t=d;!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==o.D&&(t=s.type),A[l]||(A[l]={id:l,shape:t,description:r.e.sanitizeText(l,(0,r.c)()),classes:`${g} ${p}`});const i=A[l];s.description&&(Array.isArray(i.description)?(i.shape=c,i.description.push(s.description)):i.description.length>0?(i.shape=c,i.description===l?i.description=[s.description]:i.description=[i.description,s.description]):(i.shape=d,i.description=s.description),i.description=r.e.sanitizeTextOrArray(i.description,(0,r.c)())),1===i.description.length&&i.shape===c&&(i.shape=d),!i.type&&s.doc&&(r.l.info("Setting cluster for ",l,R(s)),i.type="group",i.dir=R(s),i.shape=s.type===o.a?"divider":"roundedWithTitle",i.classes=i.classes+" "+u+" "+(n?y:""));const a={labelStyle:"",shape:i.shape,labelText:i.description,classes:i.classes,style:"",id:l,dir:i.dir,domId:B(l,v),type:i.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:h,style:"",id:l+$+"-"+v,domId:B(l,v,w),type:i.type,padding:15},o={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:i.classes,style:"",id:l+m,domId:B(l,v,f),type:"group",padding:0};v++;const r=l+m;e.setNode(r,o),e.setNode(t.id,t),e.setNode(l,a),e.setParent(l,r),e.setParent(t.id,r);let n=l,d=t.id;"left of"===s.note.position&&(n=t.id,d=l),e.setEdge(n,d,{arrowhead:"none",arrowType:"",style:T,labelStyle:"",classes:b,arrowheadStyle:k,labelpos:"c",labelType:S,thickness:D})}else e.setNode(l,a)}t&&"root"!==t.id&&(r.l.trace("Setting node ",l," to be child of its parent ",t.id),e.setParent(l,t.id)),s.doc&&(r.l.trace("Adding nodes children "),E(e,s,s.doc,i,a,!n))},E=(e,t,s,i,a,n)=>{r.l.trace("items",s),s.forEach((s=>{switch(s.stmt){case o.b:case o.D:C(e,t,s,i,a,n);break;case o.S:{C(e,t,s.state1,i,a,n),C(e,t,s.state2,i,a,n);const o={id:"edge"+v,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:T,labelStyle:"",label:r.e.sanitizeText(s.description,(0,r.c)()),arrowheadStyle:k,labelpos:"c",labelType:S,thickness:D,classes:g};e.setEdge(s.state1.id,s.state2.id,o,v),v++}}}))},R=(e,t=o.c)=>{let s=t;if(e.doc)for(let t=0;t{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,o.d.clear()}}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js new file mode 100644 index 000000000..99160eb49 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js @@ -0,0 +1,2 @@ +/*! For license information please see 637-86fbbecd.chunk.min.js.LICENSE.txt */ +(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[637],{7967:function(t,e){"use strict";e.Nm=e.Rq=void 0;var i=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,n=/&(newline|tab);/gi,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^.+(:|:)/gim,s=[".","/"];e.Rq="about:blank",e.Nm=function(t){if(!t)return e.Rq;var l,h=(l=t,l.replace(o,"").replace(r,(function(t,e){return String.fromCharCode(e)}))).replace(n,"").replace(o,"").trim();if(!h)return e.Rq;if(function(t){return s.indexOf(t[0])>-1}(h))return h;var c=h.match(a);if(!c)return h;var u=c[0];return i.test(u)?e.Rq:h}},7484:function(t){t.exports=function(){"use strict";var t=6e4,e=36e5,i="millisecond",r="second",n="minute",o="hour",a="day",s="week",l="month",h="quarter",c="year",u="date",f="Invalid Date",d=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,p=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,g={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],i=t%100;return"["+t+(e[(i-20)%10]||e[i]||e[0])+"]"}},m=function(t,e,i){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(i)+t},y={s:m,z:function(t){var e=-t.utcOffset(),i=Math.abs(e),r=Math.floor(i/60),n=i%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(n,2,"0")},m:function t(e,i){if(e.date()1)return t(a[0])}else{var s=e.name;b[s]=e,n=s}return!r&&n&&(_=n),n||!r&&_},v=function(t,e){if(C(t))return t.clone();var i="object"==typeof e?e:{};return i.date=t,i.args=arguments,new T(i)},k=y;k.l=x,k.i=C,k.w=function(t,e){return v(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var T=function(){function g(t){this.$L=x(t.locale,null,!0),this.parse(t)}var m=g.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,i=t.utc;if(null===e)return new Date(NaN);if(k.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(d);if(r){var n=r[2]-1||0,o=(r[7]||"0").substring(0,3);return i?new Date(Date.UTC(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return k},m.isValid=function(){return!(this.$d.toString()===f)},m.isSame=function(t,e){var i=v(t);return this.startOf(e)<=i&&i<=this.endOf(e)},m.isAfter=function(t,e){return v(t)1?i-1:0),n=1;n/gm),$=a(/\${[\w\W]*}/gm),z=a(/^data-[\-\w.\u00B7-\uFFFF]/),j=a(/^aria-[\-\w]+$/),P=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),R=a(/^(?:\w+script|data):/i),W=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),U=a(/^html$/i);var H=Object.freeze({__proto__:null,MUSTACHE_EXPR:N,ERB_EXPR:D,TMPLIT_EXPR:$,DATA_ATTR:z,ARIA_ATTR:j,IS_ALLOWED_URI:P,IS_SCRIPT_OR_DATA:R,ATTR_WHITESPACE:W,DOCTYPE_NAME:U});const Y=()=>"undefined"==typeof window?null:window;return function e(){let i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Y();const r=t=>e(t);if(r.version="3.0.5",r.removed=[],!i||!i.document||9!==i.document.nodeType)return r.isSupported=!1,r;const n=i.document,a=n.currentScript;let{document:s}=i;const{DocumentFragment:l,HTMLTemplateElement:h,Node:x,Element:v,NodeFilter:N,NamedNodeMap:D=i.NamedNodeMap||i.MozNamedAttrMap,HTMLFormElement:$,DOMParser:z,trustedTypes:j}=i,R=v.prototype,W=w(R,"cloneNode"),V=w(R,"nextSibling"),G=w(R,"childNodes"),X=w(R,"parentNode");if("function"==typeof h){const t=s.createElement("template");t.content&&t.content.ownerDocument&&(s=t.content.ownerDocument)}let J,Q="";const{implementation:K,createNodeIterator:tt,createDocumentFragment:et,getElementsByTagName:it}=s,{importNode:rt}=n;let nt={};r.isSupported="function"==typeof t&&"function"==typeof X&&K&&void 0!==K.createHTMLDocument;const{MUSTACHE_EXPR:ot,ERB_EXPR:at,TMPLIT_EXPR:st,DATA_ATTR:lt,ARIA_ATTR:ht,IS_SCRIPT_OR_DATA:ct,ATTR_WHITESPACE:ut}=H;let{IS_ALLOWED_URI:ft}=H,dt=null;const pt=k({},[...S,...B,...F,...M,...E]);let gt=null;const mt=k({},[...Z,...O,...q,...I]);let yt=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),_t=null,bt=null,Ct=!0,xt=!0,vt=!1,kt=!0,Tt=!1,wt=!1,St=!1,Bt=!1,Ft=!1,Lt=!1,Mt=!1,At=!0,Et=!1,Zt=!0,Ot=!1,qt={},It=null;const Nt=k({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Dt=null;const $t=k({},["audio","video","img","source","image","track"]);let zt=null;const jt=k({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Pt="http://www.w3.org/1998/Math/MathML",Rt="http://www.w3.org/2000/svg",Wt="http://www.w3.org/1999/xhtml";let Ut=Wt,Ht=!1,Yt=null;const Vt=k({},[Pt,Rt,Wt],p);let Gt;const Xt=["application/xhtml+xml","text/html"];let Jt,Qt=null;const Kt=s.createElement("form"),te=function(t){return t instanceof RegExp||t instanceof Function},ee=function(t){if(!Qt||Qt!==t){if(t&&"object"==typeof t||(t={}),t=T(t),Gt=Gt=-1===Xt.indexOf(t.PARSER_MEDIA_TYPE)?"text/html":t.PARSER_MEDIA_TYPE,Jt="application/xhtml+xml"===Gt?p:d,dt="ALLOWED_TAGS"in t?k({},t.ALLOWED_TAGS,Jt):pt,gt="ALLOWED_ATTR"in t?k({},t.ALLOWED_ATTR,Jt):mt,Yt="ALLOWED_NAMESPACES"in t?k({},t.ALLOWED_NAMESPACES,p):Vt,zt="ADD_URI_SAFE_ATTR"in t?k(T(jt),t.ADD_URI_SAFE_ATTR,Jt):jt,Dt="ADD_DATA_URI_TAGS"in t?k(T($t),t.ADD_DATA_URI_TAGS,Jt):$t,It="FORBID_CONTENTS"in t?k({},t.FORBID_CONTENTS,Jt):Nt,_t="FORBID_TAGS"in t?k({},t.FORBID_TAGS,Jt):{},bt="FORBID_ATTR"in t?k({},t.FORBID_ATTR,Jt):{},qt="USE_PROFILES"in t&&t.USE_PROFILES,Ct=!1!==t.ALLOW_ARIA_ATTR,xt=!1!==t.ALLOW_DATA_ATTR,vt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,kt=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Tt=t.SAFE_FOR_TEMPLATES||!1,wt=t.WHOLE_DOCUMENT||!1,Ft=t.RETURN_DOM||!1,Lt=t.RETURN_DOM_FRAGMENT||!1,Mt=t.RETURN_TRUSTED_TYPE||!1,Bt=t.FORCE_BODY||!1,At=!1!==t.SANITIZE_DOM,Et=t.SANITIZE_NAMED_PROPS||!1,Zt=!1!==t.KEEP_CONTENT,Ot=t.IN_PLACE||!1,ft=t.ALLOWED_URI_REGEXP||P,Ut=t.NAMESPACE||Wt,yt=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&te(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(yt.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&te(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(yt.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(yt.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Tt&&(xt=!1),Lt&&(Ft=!0),qt&&(dt=k({},[...E]),gt=[],!0===qt.html&&(k(dt,S),k(gt,Z)),!0===qt.svg&&(k(dt,B),k(gt,O),k(gt,I)),!0===qt.svgFilters&&(k(dt,F),k(gt,O),k(gt,I)),!0===qt.mathMl&&(k(dt,M),k(gt,q),k(gt,I))),t.ADD_TAGS&&(dt===pt&&(dt=T(dt)),k(dt,t.ADD_TAGS,Jt)),t.ADD_ATTR&&(gt===mt&&(gt=T(gt)),k(gt,t.ADD_ATTR,Jt)),t.ADD_URI_SAFE_ATTR&&k(zt,t.ADD_URI_SAFE_ATTR,Jt),t.FORBID_CONTENTS&&(It===Nt&&(It=T(It)),k(It,t.FORBID_CONTENTS,Jt)),Zt&&(dt["#text"]=!0),wt&&k(dt,["html","head","body"]),dt.table&&(k(dt,["tbody"]),delete _t.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw C('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw C('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');J=t.TRUSTED_TYPES_POLICY,Q=J.createHTML("")}else void 0===J&&(J=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(i=e.getAttribute(r));const n="dompurify"+(i?"#"+i:"");try{return t.createPolicy(n,{createHTML(t){return t},createScriptURL(t){return t}})}catch(t){return console.warn("TrustedTypes policy "+n+" could not be created."),null}}(j,a)),null!==J&&"string"==typeof Q&&(Q=J.createHTML(""));o&&o(t),Qt=t}},ie=k({},["mi","mo","mn","ms","mtext"]),re=k({},["foreignobject","desc","title","annotation-xml"]),ne=k({},["title","style","font","a","script"]),oe=k({},B);k(oe,F),k(oe,L);const ae=k({},M);k(ae,A);const se=function(t){f(r.removed,{element:t});try{t.parentNode.removeChild(t)}catch(e){t.remove()}},le=function(t,e){try{f(r.removed,{attribute:e.getAttributeNode(t),from:e})}catch(t){f(r.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!gt[t])if(Ft||Lt)try{se(e)}catch(t){}else try{e.setAttribute(t,"")}catch(t){}},he=function(t){let e,i;if(Bt)t=""+t;else{const e=g(t,/^[\r\n\t ]+/);i=e&&e[0]}"application/xhtml+xml"===Gt&&Ut===Wt&&(t=''+t+"");const r=J?J.createHTML(t):t;if(Ut===Wt)try{e=(new z).parseFromString(r,Gt)}catch(t){}if(!e||!e.documentElement){e=K.createDocument(Ut,"template",null);try{e.documentElement.innerHTML=Ht?Q:r}catch(t){}}const n=e.body||e.documentElement;return t&&i&&n.insertBefore(s.createTextNode(i),n.childNodes[0]||null),Ut===Wt?it.call(e,wt?"html":"body")[0]:wt?e.documentElement:n},ce=function(t){return tt.call(t.ownerDocument||t,t,N.SHOW_ELEMENT|N.SHOW_COMMENT|N.SHOW_TEXT,null,!1)},ue=function(t){return"object"==typeof x?t instanceof x:t&&"object"==typeof t&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},fe=function(t,e,i){nt[t]&&c(nt[t],(t=>{t.call(r,e,i,Qt)}))},de=function(t){let e;if(fe("beforeSanitizeElements",t,null),(i=t)instanceof $&&("string"!=typeof i.nodeName||"string"!=typeof i.textContent||"function"!=typeof i.removeChild||!(i.attributes instanceof D)||"function"!=typeof i.removeAttribute||"function"!=typeof i.setAttribute||"string"!=typeof i.namespaceURI||"function"!=typeof i.insertBefore||"function"!=typeof i.hasChildNodes))return se(t),!0;var i;const n=Jt(t.nodeName);if(fe("uponSanitizeElement",t,{tagName:n,allowedTags:dt}),t.hasChildNodes()&&!ue(t.firstElementChild)&&(!ue(t.content)||!ue(t.content.firstElementChild))&&b(/<[/\w]/g,t.innerHTML)&&b(/<[/\w]/g,t.textContent))return se(t),!0;if(!dt[n]||_t[n]){if(!_t[n]&&ge(n)){if(yt.tagNameCheck instanceof RegExp&&b(yt.tagNameCheck,n))return!1;if(yt.tagNameCheck instanceof Function&&yt.tagNameCheck(n))return!1}if(Zt&&!It[n]){const e=X(t)||t.parentNode,i=G(t)||t.childNodes;if(i&&e)for(let r=i.length-1;r>=0;--r)e.insertBefore(W(i[r],!0),V(t))}return se(t),!0}return t instanceof v&&!function(t){let e=X(t);e&&e.tagName||(e={namespaceURI:Ut,tagName:"template"});const i=d(t.tagName),r=d(e.tagName);return!!Yt[t.namespaceURI]&&(t.namespaceURI===Rt?e.namespaceURI===Wt?"svg"===i:e.namespaceURI===Pt?"svg"===i&&("annotation-xml"===r||ie[r]):Boolean(oe[i]):t.namespaceURI===Pt?e.namespaceURI===Wt?"math"===i:e.namespaceURI===Rt?"math"===i&&re[r]:Boolean(ae[i]):t.namespaceURI===Wt?!(e.namespaceURI===Rt&&!re[r])&&!(e.namespaceURI===Pt&&!ie[r])&&!ae[i]&&(ne[i]||!oe[i]):!("application/xhtml+xml"!==Gt||!Yt[t.namespaceURI]))}(t)?(se(t),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!b(/<\/no(script|embed|frames)/i,t.innerHTML)?(Tt&&3===t.nodeType&&(e=t.textContent,e=m(e,ot," "),e=m(e,at," "),e=m(e,st," "),t.textContent!==e&&(f(r.removed,{element:t.cloneNode()}),t.textContent=e)),fe("afterSanitizeElements",t,null),!1):(se(t),!0)},pe=function(t,e,i){if(At&&("id"===e||"name"===e)&&(i in s||i in Kt))return!1;if(xt&&!bt[e]&&b(lt,e));else if(Ct&&b(ht,e));else if(!gt[e]||bt[e]){if(!(ge(t)&&(yt.tagNameCheck instanceof RegExp&&b(yt.tagNameCheck,t)||yt.tagNameCheck instanceof Function&&yt.tagNameCheck(t))&&(yt.attributeNameCheck instanceof RegExp&&b(yt.attributeNameCheck,e)||yt.attributeNameCheck instanceof Function&&yt.attributeNameCheck(e))||"is"===e&&yt.allowCustomizedBuiltInElements&&(yt.tagNameCheck instanceof RegExp&&b(yt.tagNameCheck,i)||yt.tagNameCheck instanceof Function&&yt.tagNameCheck(i))))return!1}else if(zt[e]);else if(b(ft,m(i,ut,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==y(i,"data:")||!Dt[t])if(vt&&!b(ct,m(i,ut,"")));else if(i)return!1;return!0},ge=function(t){return t.indexOf("-")>0},me=function(t){let e,i,n,o;fe("beforeSanitizeAttributes",t,null);const{attributes:a}=t;if(!a)return;const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:gt};for(o=a.length;o--;){e=a[o];const{name:l,namespaceURI:h}=e;if(i="value"===l?e.value:_(e.value),n=Jt(l),s.attrName=n,s.attrValue=i,s.keepAttr=!0,s.forceKeepAttr=void 0,fe("uponSanitizeAttribute",t,s),i=s.attrValue,s.forceKeepAttr)continue;if(le(l,t),!s.keepAttr)continue;if(!kt&&b(/\/>/i,i)){le(l,t);continue}Tt&&(i=m(i,ot," "),i=m(i,at," "),i=m(i,st," "));const c=Jt(t.nodeName);if(pe(c,n,i)){if(!Et||"id"!==n&&"name"!==n||(le(l,t),i="user-content-"+i),J&&"object"==typeof j&&"function"==typeof j.getAttributeType)if(h);else switch(j.getAttributeType(c,n)){case"TrustedHTML":i=J.createHTML(i);break;case"TrustedScriptURL":i=J.createScriptURL(i)}try{h?t.setAttributeNS(h,l,i):t.setAttribute(l,i),u(r.removed)}catch(t){}}}fe("afterSanitizeAttributes",t,null)},ye=function t(e){let i;const r=ce(e);for(fe("beforeSanitizeShadowDOM",e,null);i=r.nextNode();)fe("uponSanitizeShadowNode",i,null),de(i)||(i.content instanceof l&&t(i.content),me(i));fe("afterSanitizeShadowDOM",e,null)};return r.sanitize=function(t){let e,i,o,a,s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(Ht=!t,Ht&&(t="\x3c!--\x3e"),"string"!=typeof t&&!ue(t)){if("function"!=typeof t.toString)throw C("toString is not a function");if("string"!=typeof(t=t.toString()))throw C("dirty is not a string, aborting")}if(!r.isSupported)return t;if(St||ee(s),r.removed=[],"string"==typeof t&&(Ot=!1),Ot){if(t.nodeName){const e=Jt(t.nodeName);if(!dt[e]||_t[e])throw C("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof x)e=he("\x3c!----\x3e"),i=e.ownerDocument.importNode(t,!0),1===i.nodeType&&"BODY"===i.nodeName||"HTML"===i.nodeName?e=i:e.appendChild(i);else{if(!Ft&&!Tt&&!wt&&-1===t.indexOf("<"))return J&&Mt?J.createHTML(t):t;if(e=he(t),!e)return Ft?null:Mt?Q:""}e&&Bt&&se(e.firstChild);const h=ce(Ot?t:e);for(;o=h.nextNode();)de(o)||(o.content instanceof l&&ye(o.content),me(o));if(Ot)return t;if(Ft){if(Lt)for(a=et.call(e.ownerDocument);e.firstChild;)a.appendChild(e.firstChild);else a=e;return(gt.shadowroot||gt.shadowrootmode)&&(a=rt.call(n,a,!0)),a}let c=wt?e.outerHTML:e.innerHTML;return wt&&dt["!doctype"]&&e.ownerDocument&&e.ownerDocument.doctype&&e.ownerDocument.doctype.name&&b(U,e.ownerDocument.doctype.name)&&(c="\n"+c),Tt&&(c=m(c,ot," "),c=m(c,at," "),c=m(c,st," ")),J&&Mt?J.createHTML(c):c},r.setConfig=function(t){ee(t),St=!0},r.clearConfig=function(){Qt=null,St=!1},r.isValidAttribute=function(t,e,i){Qt||ee({});const r=Jt(t),n=Jt(e);return pe(r,n,i)},r.addHook=function(t,e){"function"==typeof e&&(nt[t]=nt[t]||[],f(nt[t],e))},r.removeHook=function(t){if(nt[t])return u(nt[t])},r.removeHooks=function(t){nt[t]&&(nt[t]=[])},r.removeAllHooks=function(){nt={}},r}()}()},8464:function(t,e,i){"use strict";function r(t){for(var e=[],i=1;i=e)&&(i=e);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i=n)&&(i=n)}return i}function n(t,e){let i;if(void 0===e)for(const e of t)null!=e&&(i>e||void 0===i&&e>=e)&&(i=e);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i>n||void 0===i&&n>=n)&&(i=n)}return i}function o(t){return t}i.d(e,{Nb1:function(){return Ya},LLu:function(){return _},F5q:function(){return y},$0Z:function(){return as},Dts:function(){return ls},WQY:function(){return cs},qpX:function(){return fs},u93:function(){return ds},tFB:function(){return gs},YY7:function(){return _s},OvA:function(){return Cs},dCK:function(){return vs},zgE:function(){return ws},fGX:function(){return Bs},$m7:function(){return Ls},c_6:function(){return Xa},fxm:function(){return As},FdL:function(){return $s},ak_:function(){return zs},SxZ:function(){return Rs},eA_:function(){return Us},jsv:function(){return Ys},iJ:function(){return Hs},JHv:function(){return or},jvg:function(){return Ka},Fp7:function(){return r},VV$:function(){return n},ve8:function(){return is},BYU:function(){return Gr},PKp:function(){return tn},Xf:function(){return ya},K2I:function(){return _a},Ys:function(){return ba},td_:function(){return Ca},YPS:function(){return $i},rr1:function(){return yn},i$Z:function(){return Gn},y2j:function(){return Sn},WQD:function(){return gn},Z_i:function(){return dn},Ox9:function(){return vn},F0B:function(){return In},LqH:function(){return Bn},Zyz:function(){return xn},Igq:function(){return wn},YDX:function(){return kn},EFj:function(){return Tn}});var a=1,s=2,l=3,h=4,c=1e-6;function u(t){return"translate("+t+",0)"}function f(t){return"translate(0,"+t+")"}function d(t){return e=>+t(e)}function p(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),i=>+t(i)+e}function g(){return!this.__axis}function m(t,e){var i=[],r=null,n=null,m=6,y=6,_=3,b="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,C=t===a||t===h?-1:1,x=t===h||t===s?"x":"y",v=t===a||t===l?u:f;function k(u){var f=null==r?e.ticks?e.ticks.apply(e,i):e.domain():r,k=null==n?e.tickFormat?e.tickFormat.apply(e,i):o:n,T=Math.max(m,0)+_,w=e.range(),S=+w[0]+b,B=+w[w.length-1]+b,F=(e.bandwidth?p:d)(e.copy(),b),L=u.selection?u.selection():u,M=L.selectAll(".domain").data([null]),A=L.selectAll(".tick").data(f,e).order(),E=A.exit(),Z=A.enter().append("g").attr("class","tick"),O=A.select("line"),q=A.select("text");M=M.merge(M.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),A=A.merge(Z),O=O.merge(Z.append("line").attr("stroke","currentColor").attr(x+"2",C*m)),q=q.merge(Z.append("text").attr("fill","currentColor").attr(x,C*T).attr("dy",t===a?"0em":t===l?"0.71em":"0.32em")),u!==L&&(M=M.transition(u),A=A.transition(u),O=O.transition(u),q=q.transition(u),E=E.transition(u).attr("opacity",c).attr("transform",(function(t){return isFinite(t=F(t))?v(t+b):this.getAttribute("transform")})),Z.attr("opacity",c).attr("transform",(function(t){var e=this.parentNode.__axis;return v((e&&isFinite(e=e(t))?e:F(t))+b)}))),E.remove(),M.attr("d",t===h||t===s?y?"M"+C*y+","+S+"H"+b+"V"+B+"H"+C*y:"M"+b+","+S+"V"+B:y?"M"+S+","+C*y+"V"+b+"H"+B+"V"+C*y:"M"+S+","+b+"H"+B),A.attr("opacity",1).attr("transform",(function(t){return v(F(t)+b)})),O.attr(x+"2",C*m),q.attr(x,C*T).text(k),L.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===h?"end":"middle"),L.each((function(){this.__axis=F}))}return k.scale=function(t){return arguments.length?(e=t,k):e},k.ticks=function(){return i=Array.from(arguments),k},k.tickArguments=function(t){return arguments.length?(i=null==t?[]:Array.from(t),k):i.slice()},k.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),k):r&&r.slice()},k.tickFormat=function(t){return arguments.length?(n=t,k):n},k.tickSize=function(t){return arguments.length?(m=y=+t,k):m},k.tickSizeInner=function(t){return arguments.length?(m=+t,k):m},k.tickSizeOuter=function(t){return arguments.length?(y=+t,k):y},k.tickPadding=function(t){return arguments.length?(_=+t,k):_},k.offset=function(t){return arguments.length?(b=+t,k):b},k}function y(t){return m(a,t)}function _(t){return m(l,t)}function b(){}function C(t){return null==t?b:function(){return this.querySelector(t)}}function x(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function v(){return[]}function k(t){return null==t?v:function(){return this.querySelectorAll(t)}}function T(t){return function(){return this.matches(t)}}function w(t){return function(e){return e.matches(t)}}var S=Array.prototype.find;function B(){return this.firstElementChild}var F=Array.prototype.filter;function L(){return Array.from(this.children)}function M(t){return new Array(t.length)}function A(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function E(t,e,i,r,n,o){for(var a,s=0,l=e.length,h=o.length;se?1:t>=e?0:NaN}A.prototype={constructor:A,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var N="http://www.w3.org/1999/xhtml",D={svg:"http://www.w3.org/2000/svg",xhtml:N,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function $(t){var e=t+="",i=e.indexOf(":");return i>=0&&"xmlns"!==(e=t.slice(0,i))&&(t=t.slice(i+1)),D.hasOwnProperty(e)?{space:D[e],local:t}:t}function z(t){return function(){this.removeAttribute(t)}}function j(t){return function(){this.removeAttributeNS(t.space,t.local)}}function P(t,e){return function(){this.setAttribute(t,e)}}function R(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function W(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttribute(t):this.setAttribute(t,i)}}function U(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,i)}}function H(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function Y(t){return function(){this.style.removeProperty(t)}}function V(t,e,i){return function(){this.style.setProperty(t,e,i)}}function G(t,e,i){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,i)}}function X(t,e){return t.style.getPropertyValue(e)||H(t).getComputedStyle(t,null).getPropertyValue(e)}function J(t){return function(){delete this[t]}}function Q(t,e){return function(){this[t]=e}}function K(t,e){return function(){var i=e.apply(this,arguments);null==i?delete this[t]:this[t]=i}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new it(t)}function it(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function rt(t,e){for(var i=et(t),r=-1,n=e.length;++r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Ft=[null];function Lt(t,e){this._groups=t,this._parents=e}function Mt(){return new Lt([[document.documentElement]],Ft)}Lt.prototype=Mt.prototype={constructor:Lt,select:function(t){"function"!=typeof t&&(t=C(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n=x&&(x=C+1);!(b=y[x])&&++x=0;)(r=n[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function e(e,i){return e&&i?t(e.__data__,i.__data__):!e-!i}t||(t=I);for(var i=this._groups,r=i.length,n=new Array(r),o=0;o1?this.each((null==e?Y:"function"==typeof e?G:V)(t,e,null==i?"":i)):X(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?J:"function"==typeof e?K:Q)(t,e)):this.node()[t]},classed:function(t,e){var i=tt(t+"");if(arguments.length<2){for(var r=et(this.node()),n=-1,o=i.length;++n=0&&(e=t.slice(i+1),t=t.slice(0,i)),{type:t,name:e}}))}(t+""),a=o.length;if(!(arguments.length<2)){for(s=e?Tt:kt,r=0;r{}};function Zt(){for(var t,e=0,i=arguments.length,r={};e=0&&(e=t.slice(i+1),t=t.slice(0,i)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),a=-1,s=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a0)for(var i,r,n=new Array(i),o=0;o=0&&e._call.call(void 0,t),e=e._next;--zt}()}finally{zt=0,function(){for(var t,e,i=Nt,r=1/0;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(e=i._next,i._next=null,i=t?t._next=e:Nt=e);Dt=t,ee(r)}(),Ut=0}}function te(){var t=Yt.now(),e=t-Wt;e>Rt&&(Ht-=e,Wt=t)}function ee(t){zt||(jt&&(jt=clearTimeout(jt)),t-Ut>24?(t<1/0&&(jt=setTimeout(Kt,t-Yt.now()-Ht)),Pt&&(Pt=clearInterval(Pt))):(Pt||(Wt=Yt.now(),Pt=setInterval(te,Rt)),zt=1,Vt(Kt)))}function ie(t,e,i){var r=new Jt;return e=null==e?0:+e,r.restart((i=>{r.stop(),t(i+e)}),e,i),r}Jt.prototype=Qt.prototype={constructor:Jt,restart:function(t,e,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?Gt():+i)+(null==e?0:+e),this._next||Dt===this||(Dt?Dt._next=this:Nt=this,Dt=this),this._call=t,this._time=i,ee()},stop:function(){this._call&&(this._call=null,this._time=1/0,ee())}};var re=$t("start","end","cancel","interrupt"),ne=[],oe=0,ae=3;function se(t,e,i,r,n,o){var a=t.__transition;if(a){if(i in a)return}else t.__transition={};!function(t,e,i){var r,n=t.__transition;function o(l){var h,c,u,f;if(1!==i.state)return s();for(h in n)if((f=n[h]).name===i.name){if(f.state===ae)return ie(o);4===f.state?(f.state=6,f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group),delete n[h]):+hoe)throw new Error("too late; already scheduled");return i}function he(t,e){var i=ce(t,e);if(i.state>ae)throw new Error("too late; already running");return i}function ce(t,e){var i=t.__transition;if(!i||!(i=i[e]))throw new Error("transition not found");return i}function ue(t,e){return t=+t,e=+e,function(i){return t*(1-i)+e*i}}var fe,de=180/Math.PI,pe={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function ge(t,e,i,r,n,o){var a,s,l;return(a=Math.sqrt(t*t+e*e))&&(t/=a,e/=a),(l=t*i+e*r)&&(i-=t*l,r-=e*l),(s=Math.sqrt(i*i+r*r))&&(i/=s,r/=s,l/=s),t*r180?e+=360:e-t>180&&(t+=360),o.push({i:i.push(n(i)+"rotate(",null,r)-2,x:ue(t,e)})):e&&i.push(n(i)+"rotate("+e+r)}(o.rotate,a.rotate,s,l),function(t,e,i,o){t!==e?o.push({i:i.push(n(i)+"skewX(",null,r)-2,x:ue(t,e)}):e&&i.push(n(i)+"skewX("+e+r)}(o.skewX,a.skewX,s,l),function(t,e,i,r,o,a){if(t!==i||e!==r){var s=o.push(n(o)+"scale(",null,",",null,")");a.push({i:s-4,x:ue(t,i)},{i:s-2,x:ue(e,r)})}else 1===i&&1===r||o.push(n(o)+"scale("+i+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,s,l),o=a=null,function(t){for(var e,i=-1,r=l.length;++i>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===i?Pe(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===i?Pe(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Ae.exec(t))?new Ue(e[1],e[2],e[3],1):(e=Ee.exec(t))?new Ue(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Ze.exec(t))?Pe(e[1],e[2],e[3],e[4]):(e=Oe.exec(t))?Pe(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=qe.exec(t))?Je(e[1],e[2]/100,e[3]/100,1):(e=Ie.exec(t))?Je(e[1],e[2]/100,e[3]/100,e[4]):Ne.hasOwnProperty(t)?je(Ne[t]):"transparent"===t?new Ue(NaN,NaN,NaN,0):null}function je(t){return new Ue(t>>16&255,t>>8&255,255&t,1)}function Pe(t,e,i,r){return r<=0&&(t=e=i=NaN),new Ue(t,e,i,r)}function Re(t){return t instanceof Te||(t=ze(t)),t?new Ue((t=t.rgb()).r,t.g,t.b,t.opacity):new Ue}function We(t,e,i,r){return 1===arguments.length?Re(t):new Ue(t,e,i,null==r?1:r)}function Ue(t,e,i,r){this.r=+t,this.g=+e,this.b=+i,this.opacity=+r}function He(){return`#${Xe(this.r)}${Xe(this.g)}${Xe(this.b)}`}function Ye(){const t=Ve(this.opacity);return`${1===t?"rgb(":"rgba("}${Ge(this.r)}, ${Ge(this.g)}, ${Ge(this.b)}${1===t?")":`, ${t})`}`}function Ve(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Ge(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function Xe(t){return((t=Ge(t))<16?"0":"")+t.toString(16)}function Je(t,e,i,r){return r<=0?t=e=i=NaN:i<=0||i>=1?t=e=NaN:e<=0&&(t=NaN),new Ke(t,e,i,r)}function Qe(t){if(t instanceof Ke)return new Ke(t.h,t.s,t.l,t.opacity);if(t instanceof Te||(t=ze(t)),!t)return new Ke;if(t instanceof Ke)return t;var e=(t=t.rgb()).r/255,i=t.g/255,r=t.b/255,n=Math.min(e,i,r),o=Math.max(e,i,r),a=NaN,s=o-n,l=(o+n)/2;return s?(a=e===o?(i-r)/s+6*(i0&&l<1?0:a,new Ke(a,s,l,t.opacity)}function Ke(t,e,i,r){this.h=+t,this.s=+e,this.l=+i,this.opacity=+r}function ti(t){return(t=(t||0)%360)<0?t+360:t}function ei(t){return Math.max(0,Math.min(1,t||0))}function ii(t,e,i){return 255*(t<60?e+(i-e)*t/60:t<180?i:t<240?e+(i-e)*(240-t)/60:e)}function ri(t,e,i,r,n){var o=t*t,a=o*t;return((1-3*t+3*o-a)*e+(4-6*o+3*a)*i+(1+3*t+3*o-3*a)*r+a*n)/6}ve(Te,ze,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:De,formatHex:De,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return Qe(this).formatHsl()},formatRgb:$e,toString:$e}),ve(Ue,We,ke(Te,{brighter(t){return t=null==t?Se:Math.pow(Se,t),new Ue(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?we:Math.pow(we,t),new Ue(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ue(Ge(this.r),Ge(this.g),Ge(this.b),Ve(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:He,formatHex:He,formatHex8:function(){return`#${Xe(this.r)}${Xe(this.g)}${Xe(this.b)}${Xe(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Ye,toString:Ye})),ve(Ke,(function(t,e,i,r){return 1===arguments.length?Qe(t):new Ke(t,e,i,null==r?1:r)}),ke(Te,{brighter(t){return t=null==t?Se:Math.pow(Se,t),new Ke(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?we:Math.pow(we,t),new Ke(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,i=this.l,r=i+(i<.5?i:1-i)*e,n=2*i-r;return new Ue(ii(t>=240?t-240:t+120,n,r),ii(t,n,r),ii(t<120?t+240:t-120,n,r),this.opacity)},clamp(){return new Ke(ti(this.h),ei(this.s),ei(this.l),Ve(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Ve(this.opacity);return`${1===t?"hsl(":"hsla("}${ti(this.h)}, ${100*ei(this.s)}%, ${100*ei(this.l)}%${1===t?")":`, ${t})`}`}}));var ni=t=>()=>t;function oi(t,e){return function(i){return t+i*e}}function ai(t,e){var i=e-t;return i?oi(t,i):ni(isNaN(t)?e:t)}var si=function t(e){var i=function(t){return 1==(t=+t)?ai:function(e,i){return i-e?function(t,e,i){return t=Math.pow(t,i),e=Math.pow(e,i)-t,i=1/i,function(r){return Math.pow(t+r*e,i)}}(e,i,t):ni(isNaN(e)?i:e)}}(e);function r(t,e){var r=i((t=We(t)).r,(e=We(e)).r),n=i(t.g,e.g),o=i(t.b,e.b),a=ai(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=n(e),t.b=o(e),t.opacity=a(e),t+""}}return r.gamma=t,r}(1);function li(t){return function(e){var i,r,n=e.length,o=new Array(n),a=new Array(n),s=new Array(n);for(i=0;i=1?(i=1,e-1):Math.floor(i*e),n=t[r],o=t[r+1],a=r>0?t[r-1]:2*n-o,s=ro&&(n=e.slice(o,n),s[a]?s[a]+=n:s[++a]=n),(i=i[0])===(r=r[0])?s[a]?s[a]+=r:s[++a]=r:(s[++a]=null,l.push({i:a,x:ue(i,r)})),o=ci.lastIndex;return o=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?le:he;return function(){var a=o(this,t),s=a.on;s!==r&&(n=(r=s).copy()).on(e,i),a.on=n}}(i,t,e))},attr:function(t,e){var i=$(t),r="transform"===i?_e:fi;return this.attrTween(t,"function"==typeof e?(i.local?_i:yi)(i,r,xe(this,"attr."+t,e)):null==e?(i.local?pi:di)(i):(i.local?mi:gi)(i,r,e))},attrTween:function(t,e){var i="attr."+t;if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;var r=$(t);return this.tween(i,(r.local?bi:Ci)(r,e))},style:function(t,e,i){var r="transform"==(t+="")?ye:fi;return null==e?this.styleTween(t,function(t,e){var i,r,n;return function(){var o=X(this,t),a=(this.style.removeProperty(t),X(this,t));return o===a?null:o===i&&a===r?n:n=e(i=o,r=a)}}(t,r)).on("end.style."+t,Si(t)):"function"==typeof e?this.styleTween(t,function(t,e,i){var r,n,o;return function(){var a=X(this,t),s=i(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=X(this,t)),a===l?null:a===r&&l===n?o:(n=l,o=e(r=a,s))}}(t,r,xe(this,"style."+t,e))).each(function(t,e){var i,r,n,o,a="style."+e,s="end."+a;return function(){var l=he(this,t),h=l.on,c=null==l.value[a]?o||(o=Si(e)):void 0;h===i&&n===c||(r=(i=h).copy()).on(s,n=c),l.on=r}}(this._id,t)):this.styleTween(t,function(t,e,i){var r,n,o=i+"";return function(){var a=X(this,t);return a===o?null:a===r?n:n=e(r=a,i)}}(t,r,e),i).on("end.style."+t,null)},styleTween:function(t,e,i){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;return this.tween(r,function(t,e,i){var r,n;function o(){var o=e.apply(this,arguments);return o!==n&&(r=(n=o)&&function(t,e,i){return function(r){this.style.setProperty(t,e.call(this,r),i)}}(t,o,i)),r}return o._value=e,o}(t,e,null==i?"":i))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(xe(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,i;function r(){var r=t.apply(this,arguments);return r!==i&&(e=(i=r)&&function(t){return function(e){this.textContent=t.call(this,e)}}(r)),e}return r._value=t,r}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var i in this.__transition)if(+i!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var i=this._id;if(t+="",arguments.length<2){for(var r,n=ce(this.node(),i).tween,o=0,a=n.length;o2&&i.state<5,i.state=6,i.timer.stop(),i.on.call(r?"interrupt":"cancel",t,t.__data__,i.index,i.group),delete o[n]):a=!1;a&&delete t.__transition}}(this,t)}))},At.prototype.transition=function(t){var e,i;t instanceof Fi?(e=t._id,t=t._name):(e=Li(),(i=Ai).time=Gt(),t=null==t?null:t+"");for(var r=this._groups,n=r.length,o=0;ofunction(t,e){return fetch(t,e).then(Ni)}(e,i).then((e=>(new DOMParser).parseFromString(e,t)))}["w","e"].map(Ii),["n","s"].map(Ii),["n","w","e","s","nw","ne","sw","se"].map(Ii),Di("application/xml"),Di("text/html");var $i=Di("image/svg+xml");const zi=Math.PI/180,ji=180/Math.PI,Pi=.96422,Ri=1,Wi=.82521,Ui=4/29,Hi=6/29,Yi=3*Hi*Hi,Vi=Hi*Hi*Hi;function Gi(t){if(t instanceof Xi)return new Xi(t.l,t.a,t.b,t.opacity);if(t instanceof ir)return rr(t);t instanceof Ue||(t=Re(t));var e,i,r=tr(t.r),n=tr(t.g),o=tr(t.b),a=Ji((.2225045*r+.7168786*n+.0606169*o)/Ri);return r===n&&n===o?e=i=a:(e=Ji((.4360747*r+.3850649*n+.1430804*o)/Pi),i=Ji((.0139322*r+.0971045*n+.7141733*o)/Wi)),new Xi(116*a-16,500*(e-a),200*(a-i),t.opacity)}function Xi(t,e,i,r){this.l=+t,this.a=+e,this.b=+i,this.opacity=+r}function Ji(t){return t>Vi?Math.pow(t,1/3):t/Yi+Ui}function Qi(t){return t>Hi?t*t*t:Yi*(t-Ui)}function Ki(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function tr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function er(t,e,i,r){return 1===arguments.length?function(t){if(t instanceof ir)return new ir(t.h,t.c,t.l,t.opacity);if(t instanceof Xi||(t=Gi(t)),0===t.a&&0===t.b)return new ir(NaN,0180||i<-180?i-360*Math.round(i/360):i):ni(isNaN(t)?e:t)}));nr(ai);const ar=Math.sqrt(50),sr=Math.sqrt(10),lr=Math.sqrt(2);function hr(t,e,i){const r=(e-t)/Math.max(0,i),n=Math.floor(Math.log10(r)),o=r/Math.pow(10,n),a=o>=ar?10:o>=sr?5:o>=lr?2:1;let s,l,h;return n<0?(h=Math.pow(10,-n)/a,s=Math.round(t*h),l=Math.round(e*h),s/he&&--l,h=-h):(h=Math.pow(10,n)*a,s=Math.round(t/h),l=Math.round(e/h),s*he&&--l),le?1:t>=e?0:NaN}function dr(t,e){return null==t||null==e?NaN:et?1:e>=t?0:NaN}function pr(t){let e,i,r;function n(t,r,n=0,o=t.length){if(n>>1;i(t[e],r)<0?n=e+1:o=e}while(nfr(t(e),i),r=(e,i)=>t(e)-i):(e=t===fr||t===dr?t:gr,i=t,r=t),{left:n,center:function(t,e,i=0,o=t.length){const a=n(t,e,i,o-1);return a>i&&r(t[a-1],e)>-r(t[a],e)?a-1:a},right:function(t,r,n=0,o=t.length){if(n>>1;i(t[e],r)<=0?n=e+1:o=e}while(ne&&(i=t,t=e,e=i),h=function(i){return Math.max(t,Math.min(e,i))}),r=l>2?Mr:Lr,n=o=null,u}function u(e){return null==e||isNaN(e=+e)?i:(n||(n=r(a.map(t),s,l)))(t(h(e)))}return u.invert=function(i){return h(e((o||(o=r(s,a.map(t),ue)))(i)))},u.domain=function(t){return arguments.length?(a=Array.from(t,wr),c()):a.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),c()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=Tr,c()},u.clamp=function(t){return arguments.length?(h=!!t||Br,c()):h!==Br},u.interpolate=function(t){return arguments.length?(l=t,c()):l},u.unknown=function(t){return arguments.length?(i=t,u):i},function(i,r){return t=i,e=r,c()}}()(Br,Br)}function Zr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}var Or,qr=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Ir(t){if(!(e=qr.exec(t)))throw new Error("invalid format: "+t);var e;return new Nr({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function Nr(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function Dr(t,e){if((i=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var i,r=t.slice(0,i);return[r.length>1?r[0]+r.slice(2):r,+t.slice(i+1)]}function $r(t){return(t=Dr(Math.abs(t)))?t[1]:NaN}function zr(t,e){var i=Dr(t,e);if(!i)return t+"";var r=i[0],n=i[1];return n<0?"0."+new Array(-n).join("0")+r:r.length>n+1?r.slice(0,n+1)+"."+r.slice(n+1):r+new Array(n-r.length+2).join("0")}Ir.prototype=Nr.prototype,Nr.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var jr={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>zr(100*t,e),r:zr,s:function(t,e){var i=Dr(t,e);if(!i)return t+"";var r=i[0],n=i[1],o=n-(Or=3*Math.max(-8,Math.min(8,Math.floor(n/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+Dr(t,Math.max(0,e+o-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function Pr(t){return t}var Rr,Wr,Ur,Hr=Array.prototype.map,Yr=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Vr(t){var e=t.domain;return t.ticks=function(t){var i=e();return function(t,e,i){if(!((i=+i)>0))return[];if((t=+t)==(e=+e))return[t];const r=e=n))return[];const s=o-n+1,l=new Array(s);if(r)if(a<0)for(let t=0;t0;){if((n=cr(l,h,i))===r)return o[a]=l,o[s]=h,e(o);if(n>0)l=Math.floor(l/n)*n,h=Math.ceil(h/n)*n;else{if(!(n<0))break;l=Math.ceil(l*n)/n,h=Math.floor(h*n)/n}r=n}return t},t}function Gr(){var t=Er();return t.copy=function(){return Ar(t,Gr())},Zr.apply(t,arguments),Vr(t)}Rr=function(t){var e,i,r=void 0===t.grouping||void 0===t.thousands?Pr:(e=Hr.call(t.grouping,Number),i=t.thousands+"",function(t,r){for(var n=t.length,o=[],a=0,s=e[0],l=0;n>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),o.push(t.substring(n-=s,n+s)),!((l+=s+1)>r));)s=e[a=(a+1)%e.length];return o.reverse().join(i)}),n=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?Pr:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(Hr.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",h=void 0===t.minus?"−":t.minus+"",c=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=Ir(t)).fill,i=t.align,u=t.sign,f=t.symbol,d=t.zero,p=t.width,g=t.comma,m=t.precision,y=t.trim,_=t.type;"n"===_?(g=!0,_="g"):jr[_]||(void 0===m&&(m=12),y=!0,_="g"),(d||"0"===e&&"="===i)&&(d=!0,e="0",i="=");var b="$"===f?n:"#"===f&&/[boxX]/.test(_)?"0"+_.toLowerCase():"",C="$"===f?o:/[%p]/.test(_)?l:"",x=jr[_],v=/[defgprs%]/.test(_);function k(t){var n,o,l,f=b,k=C;if("c"===_)k=x(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?c:x(Math.abs(t),m),y&&(t=function(t){t:for(var e,i=t.length,r=1,n=-1;r0&&(n=0)}return n>0?t.slice(0,n)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==u&&(T=!1),f=(T?"("===u?u:h:"-"===u||"("===u?"":u)+f,k=("s"===_?Yr[8+Or/3]:"")+k+(T&&"("===u?")":""),v)for(n=-1,o=t.length;++n(l=t.charCodeAt(n))||l>57){k=(46===l?a+t.slice(n+1):t.slice(n))+k,t=t.slice(0,n);break}}g&&!d&&(t=r(t,1/0));var w=f.length+t.length+k.length,S=w>1)+f+t+k+S.slice(w);break;default:t=S+f+t+k}return s(t)}return m=void 0===m?6:/[gprs]/.test(_)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),k.toString=function(){return t+""},k}return{format:u,formatPrefix:function(t,e){var i=u(((t=Ir(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor($r(e)/3))),n=Math.pow(10,-r),o=Yr[8+r/3];return function(t){return i(n*t)+o}}}}({thousands:",",grouping:[3],currency:["$",""]}),Wr=Rr.format,Ur=Rr.formatPrefix;class Xr extends Map{constructor(t,e=Qr){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[e,i]of t)this.set(e,i)}get(t){return super.get(Jr(this,t))}has(t){return super.has(Jr(this,t))}set(t,e){return super.set(function({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):(t.set(r,i),i)}(this,t),e)}delete(t){return super.delete(function({_intern:t,_key:e},i){const r=e(i);return t.has(r)&&(i=t.get(r),t.delete(r)),i}(this,t))}}function Jr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):i}function Qr(t){return null!==t&&"object"==typeof t?t.valueOf():t}const Kr=Symbol("implicit");function tn(){var t=new Xr,e=[],i=[],r=Kr;function n(n){let o=t.get(n);if(void 0===o){if(r!==Kr)return r;t.set(n,o=e.push(n)-1)}return i[o%i.length]}return n.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new Xr;for(const r of i)t.has(r)||t.set(r,e.push(r)-1);return n},n.range=function(t){return arguments.length?(i=Array.from(t),n):i.slice()},n.unknown=function(t){return arguments.length?(r=t,n):r},n.copy=function(){return tn(e,i).unknown(r)},Zr.apply(n,arguments),n}const en=1e3,rn=6e4,nn=36e5,on=864e5,an=6048e5,sn=31536e6,ln=new Date,hn=new Date;function cn(t,e,i,r){function n(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return n.floor=e=>(t(e=new Date(+e)),e),n.ceil=i=>(t(i=new Date(i-1)),e(i,1),t(i),i),n.round=t=>{const e=n(t),i=n.ceil(t);return t-e(e(t=new Date(+t),null==i?1:Math.floor(i)),t),n.range=(i,r,o)=>{const a=[];if(i=n.ceil(i),o=null==o?1:Math.floor(o),!(i0))return a;let s;do{a.push(s=new Date(+i)),e(i,o),t(i)}while(scn((e=>{if(e>=e)for(;t(e),!i(e);)e.setTime(e-1)}),((t,r)=>{if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!i(t););else for(;--r>=0;)for(;e(t,1),!i(t););})),i&&(n.count=(e,r)=>(ln.setTime(+e),hn.setTime(+r),t(ln),t(hn),Math.floor(i(ln,hn))),n.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?n.filter(r?e=>r(e)%t==0:e=>n.count(0,e)%t==0):n:null)),n}const un=cn((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));un.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?cn((e=>{e.setTime(Math.floor(e/t)*t)}),((e,i)=>{e.setTime(+e+i*t)}),((e,i)=>(i-e)/t)):un:null),un.range;const fn=cn((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*en)}),((t,e)=>(e-t)/en),(t=>t.getUTCSeconds())),dn=(fn.range,cn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*en)}),((t,e)=>{t.setTime(+t+e*rn)}),((t,e)=>(e-t)/rn),(t=>t.getMinutes()))),pn=(dn.range,cn((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*rn)}),((t,e)=>(e-t)/rn),(t=>t.getUTCMinutes()))),gn=(pn.range,cn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*en-t.getMinutes()*rn)}),((t,e)=>{t.setTime(+t+e*nn)}),((t,e)=>(e-t)/nn),(t=>t.getHours()))),mn=(gn.range,cn((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*nn)}),((t,e)=>(e-t)/nn),(t=>t.getUTCHours()))),yn=(mn.range,cn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*rn)/on),(t=>t.getDate()-1))),_n=(yn.range,cn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/on),(t=>t.getUTCDate()-1))),bn=(_n.range,cn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/on),(t=>Math.floor(t/on))));function Cn(t){return cn((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*rn)/an))}bn.range;const xn=Cn(0),vn=Cn(1),kn=Cn(2),Tn=Cn(3),wn=Cn(4),Sn=Cn(5),Bn=Cn(6);function Fn(t){return cn((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/an))}xn.range,vn.range,kn.range,Tn.range,wn.range,Sn.range,Bn.range;const Ln=Fn(0),Mn=Fn(1),An=Fn(2),En=Fn(3),Zn=Fn(4),On=Fn(5),qn=Fn(6),In=(Ln.range,Mn.range,An.range,En.range,Zn.range,On.range,qn.range,cn((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),Nn=(In.range,cn((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),Dn=(Nn.range,cn((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));Dn.every=t=>isFinite(t=Math.floor(t))&&t>0?cn((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,i)=>{e.setFullYear(e.getFullYear()+i*t)})):null,Dn.range;const $n=cn((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));function zn(t,e,i,r,n,o){const a=[[fn,1,en],[fn,5,5e3],[fn,15,15e3],[fn,30,3e4],[o,1,rn],[o,5,3e5],[o,15,9e5],[o,30,18e5],[n,1,nn],[n,3,108e5],[n,6,216e5],[n,12,432e5],[r,1,on],[r,2,1728e5],[i,1,an],[e,1,2592e6],[e,3,7776e6],[t,1,sn]];function s(e,i,r){const n=Math.abs(i-e)/r,o=pr((([,,t])=>t)).right(a,n);if(o===a.length)return t.every(ur(e/sn,i/sn,r));if(0===o)return un.every(Math.max(ur(e,i,r),1));const[s,l]=a[n/a[o-1][2]isFinite(t=Math.floor(t))&&t>0?cn((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,i)=>{e.setUTCFullYear(e.getUTCFullYear()+i*t)})):null,$n.range;const[jn,Pn]=zn($n,Nn,Ln,bn,mn,pn),[Rn,Wn]=zn(Dn,In,xn,yn,gn,dn);function Un(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function Hn(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Yn(t,e,i){return{y:t,m:e,d:i,H:0,M:0,S:0,L:0}}var Vn,Gn,Xn={"-":"",_:" ",0:"0"},Jn=/^\s*\d+/,Qn=/^%/,Kn=/[\\^$*+?|[\]().{}]/g;function to(t,e,i){var r=t<0?"-":"",n=(r?-t:t)+"",o=n.length;return r+(o[t.toLowerCase(),e])))}function no(t,e,i){var r=Jn.exec(e.slice(i,i+1));return r?(t.w=+r[0],i+r[0].length):-1}function oo(t,e,i){var r=Jn.exec(e.slice(i,i+1));return r?(t.u=+r[0],i+r[0].length):-1}function ao(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.U=+r[0],i+r[0].length):-1}function so(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.V=+r[0],i+r[0].length):-1}function lo(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.W=+r[0],i+r[0].length):-1}function ho(t,e,i){var r=Jn.exec(e.slice(i,i+4));return r?(t.y=+r[0],i+r[0].length):-1}function co(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),i+r[0].length):-1}function uo(t,e,i){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(i,i+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),i+r[0].length):-1}function fo(t,e,i){var r=Jn.exec(e.slice(i,i+1));return r?(t.q=3*r[0]-3,i+r[0].length):-1}function po(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.m=r[0]-1,i+r[0].length):-1}function go(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.d=+r[0],i+r[0].length):-1}function mo(t,e,i){var r=Jn.exec(e.slice(i,i+3));return r?(t.m=0,t.d=+r[0],i+r[0].length):-1}function yo(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.H=+r[0],i+r[0].length):-1}function _o(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.M=+r[0],i+r[0].length):-1}function bo(t,e,i){var r=Jn.exec(e.slice(i,i+2));return r?(t.S=+r[0],i+r[0].length):-1}function Co(t,e,i){var r=Jn.exec(e.slice(i,i+3));return r?(t.L=+r[0],i+r[0].length):-1}function xo(t,e,i){var r=Jn.exec(e.slice(i,i+6));return r?(t.L=Math.floor(r[0]/1e3),i+r[0].length):-1}function vo(t,e,i){var r=Qn.exec(e.slice(i,i+1));return r?i+r[0].length:-1}function ko(t,e,i){var r=Jn.exec(e.slice(i));return r?(t.Q=+r[0],i+r[0].length):-1}function To(t,e,i){var r=Jn.exec(e.slice(i));return r?(t.s=+r[0],i+r[0].length):-1}function wo(t,e){return to(t.getDate(),e,2)}function So(t,e){return to(t.getHours(),e,2)}function Bo(t,e){return to(t.getHours()%12||12,e,2)}function Fo(t,e){return to(1+yn.count(Dn(t),t),e,3)}function Lo(t,e){return to(t.getMilliseconds(),e,3)}function Mo(t,e){return Lo(t,e)+"000"}function Ao(t,e){return to(t.getMonth()+1,e,2)}function Eo(t,e){return to(t.getMinutes(),e,2)}function Zo(t,e){return to(t.getSeconds(),e,2)}function Oo(t){var e=t.getDay();return 0===e?7:e}function qo(t,e){return to(xn.count(Dn(t)-1,t),e,2)}function Io(t){var e=t.getDay();return e>=4||0===e?wn(t):wn.ceil(t)}function No(t,e){return t=Io(t),to(wn.count(Dn(t),t)+(4===Dn(t).getDay()),e,2)}function Do(t){return t.getDay()}function $o(t,e){return to(vn.count(Dn(t)-1,t),e,2)}function zo(t,e){return to(t.getFullYear()%100,e,2)}function jo(t,e){return to((t=Io(t)).getFullYear()%100,e,2)}function Po(t,e){return to(t.getFullYear()%1e4,e,4)}function Ro(t,e){var i=t.getDay();return to((t=i>=4||0===i?wn(t):wn.ceil(t)).getFullYear()%1e4,e,4)}function Wo(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+to(e/60|0,"0",2)+to(e%60,"0",2)}function Uo(t,e){return to(t.getUTCDate(),e,2)}function Ho(t,e){return to(t.getUTCHours(),e,2)}function Yo(t,e){return to(t.getUTCHours()%12||12,e,2)}function Vo(t,e){return to(1+_n.count($n(t),t),e,3)}function Go(t,e){return to(t.getUTCMilliseconds(),e,3)}function Xo(t,e){return Go(t,e)+"000"}function Jo(t,e){return to(t.getUTCMonth()+1,e,2)}function Qo(t,e){return to(t.getUTCMinutes(),e,2)}function Ko(t,e){return to(t.getUTCSeconds(),e,2)}function ta(t){var e=t.getUTCDay();return 0===e?7:e}function ea(t,e){return to(Ln.count($n(t)-1,t),e,2)}function ia(t){var e=t.getUTCDay();return e>=4||0===e?Zn(t):Zn.ceil(t)}function ra(t,e){return t=ia(t),to(Zn.count($n(t),t)+(4===$n(t).getUTCDay()),e,2)}function na(t){return t.getUTCDay()}function oa(t,e){return to(Mn.count($n(t)-1,t),e,2)}function aa(t,e){return to(t.getUTCFullYear()%100,e,2)}function sa(t,e){return to((t=ia(t)).getUTCFullYear()%100,e,2)}function la(t,e){return to(t.getUTCFullYear()%1e4,e,4)}function ha(t,e){var i=t.getUTCDay();return to((t=i>=4||0===i?Zn(t):Zn.ceil(t)).getUTCFullYear()%1e4,e,4)}function ca(){return"+0000"}function ua(){return"%"}function fa(t){return+t}function da(t){return Math.floor(+t/1e3)}function pa(t){return new Date(t)}function ga(t){return t instanceof Date?+t:+new Date(+t)}function ma(t,e,i,r,n,o,a,s,l,h){var c=Er(),u=c.invert,f=c.domain,d=h(".%L"),p=h(":%S"),g=h("%I:%M"),m=h("%I %p"),y=h("%a %d"),_=h("%b %d"),b=h("%B"),C=h("%Y");function x(t){return(l(t)=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:fa,s:da,S:Zo,u:Oo,U:qo,V:No,w:Do,W:$o,x:null,X:null,y:zo,Y:Po,Z:Wo,"%":ua},C={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:Uo,e:Uo,f:Xo,g:sa,G:ha,H:Ho,I:Yo,j:Vo,L:Go,m:Jo,M:Qo,p:function(t){return n[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:fa,s:da,S:Ko,u:ta,U:ea,V:ra,w:na,W:oa,x:null,X:null,y:aa,Y:la,Z:ca,"%":ua},x={a:function(t,e,i){var r=d.exec(e.slice(i));return r?(t.w=p.get(r[0].toLowerCase()),i+r[0].length):-1},A:function(t,e,i){var r=u.exec(e.slice(i));return r?(t.w=f.get(r[0].toLowerCase()),i+r[0].length):-1},b:function(t,e,i){var r=y.exec(e.slice(i));return r?(t.m=_.get(r[0].toLowerCase()),i+r[0].length):-1},B:function(t,e,i){var r=g.exec(e.slice(i));return r?(t.m=m.get(r[0].toLowerCase()),i+r[0].length):-1},c:function(t,i,r){return T(t,e,i,r)},d:go,e:go,f:xo,g:co,G:ho,H:yo,I:yo,j:mo,L:Co,m:po,M:_o,p:function(t,e,i){var r=h.exec(e.slice(i));return r?(t.p=c.get(r[0].toLowerCase()),i+r[0].length):-1},q:fo,Q:ko,s:To,S:bo,u:oo,U:ao,V:so,w:no,W:lo,x:function(t,e,r){return T(t,i,e,r)},X:function(t,e,i){return T(t,r,e,i)},y:co,Y:ho,Z:uo,"%":vo};function v(t,e){return function(i){var r,n,o,a=[],s=-1,l=0,h=t.length;for(i instanceof Date||(i=new Date(+i));++s53)return null;"w"in o||(o.w=1),"Z"in o?(n=(r=Hn(Yn(o.y,0,1))).getUTCDay(),r=n>4||0===n?Mn.ceil(r):Mn(r),r=_n.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(n=(r=Un(Yn(o.y,0,1))).getDay(),r=n>4||0===n?vn.ceil(r):vn(r),r=yn.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),n="Z"in o?Hn(Yn(o.y,0,1)).getUTCDay():Un(Yn(o.y,0,1)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(n+5)%7:o.w+7*o.U-(n+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,Hn(o)):Un(o)}}function T(t,e,i,r){for(var n,o,a=0,s=e.length,l=i.length;a=l)return-1;if(37===(n=e.charCodeAt(a++))){if(n=e.charAt(a++),!(o=x[n in Xn?e.charAt(a++):n])||(r=o(t,i,r))<0)return-1}else if(n!=i.charCodeAt(r++))return-1}return r}return b.x=v(i,b),b.X=v(r,b),b.c=v(e,b),C.x=v(i,C),C.X=v(r,C),C.c=v(e,C),{format:function(t){var e=v(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=v(t+="",C);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}),Gn=Vn.format,Vn.parse,Vn.utcFormat,Vn.utcParse;var _a=function(t){for(var e=new Array(10),i=0;i<10;)e[i]="#"+t.slice(6*i,6*++i);return e}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function ba(t){return"string"==typeof t?new Lt([[document.querySelector(t)]],[document.documentElement]):new Lt([[t]],Ft)}function Ca(t){return"string"==typeof t?new Lt([document.querySelectorAll(t)],[document.documentElement]):new Lt([x(t)],Ft)}function xa(t){return function(){return t}}const va=Math.abs,ka=Math.atan2,Ta=Math.cos,wa=Math.max,Sa=Math.min,Ba=Math.sin,Fa=Math.sqrt,La=1e-12,Ma=Math.PI,Aa=Ma/2,Ea=2*Ma;function Za(t){return t>=1?Aa:t<=-1?-Aa:Math.asin(t)}const Oa=Math.PI,qa=2*Oa,Ia=1e-6,Na=qa-Ia;function Da(t){this._+=t[0];for(let e=1,i=t.length;e=0))throw new Error(`invalid digits: ${t}`);if(e>15)return Da;const i=10**e;return function(t){this._+=t[0];for(let e=1,r=t.length;eIa)if(Math.abs(c*s-l*h)>Ia&&n){let f=i-o,d=r-a,p=s*s+l*l,g=f*f+d*d,m=Math.sqrt(p),y=Math.sqrt(u),_=n*Math.tan((Oa-Math.acos((p+u-g)/(2*m*y)))/2),b=_/y,C=_/m;Math.abs(b-1)>Ia&&this._append`L${t+b*h},${e+b*c}`,this._append`A${n},${n},0,0,${+(c*f>h*d)},${this._x1=t+C*s},${this._y1=e+C*l}`}else this._append`L${this._x1=t},${this._y1=e}`}arc(t,e,i,r,n,o){if(t=+t,e=+e,o=!!o,(i=+i)<0)throw new Error(`negative radius: ${i}`);let a=i*Math.cos(r),s=i*Math.sin(r),l=t+a,h=e+s,c=1^o,u=o?r-n:n-r;null===this._x1?this._append`M${l},${h}`:(Math.abs(this._x1-l)>Ia||Math.abs(this._y1-h)>Ia)&&this._append`L${l},${h}`,i&&(u<0&&(u=u%qa+qa),u>Na?this._append`A${i},${i},0,1,${c},${t-a},${e-s}A${i},${i},0,1,${c},${this._x1=l},${this._y1=h}`:u>Ia&&this._append`A${i},${i},0,${+(u>=Oa)},${c},${this._x1=t+i*Math.cos(n)},${this._y1=e+i*Math.sin(n)}`)}rect(t,e,i,r){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${i=+i}v${+r}h${-i}Z`}toString(){return this._}}function za(t){let e=3;return t.digits=function(i){if(!arguments.length)return e;if(null==i)e=null;else{const t=Math.floor(i);if(!(t>=0))throw new RangeError(`invalid digits: ${i}`);e=t}return t},()=>new $a(e)}function ja(t){return t.innerRadius}function Pa(t){return t.outerRadius}function Ra(t){return t.startAngle}function Wa(t){return t.endAngle}function Ua(t){return t&&t.padAngle}function Ha(t,e,i,r,n,o,a){var s=t-i,l=e-r,h=(a?o:-o)/Fa(s*s+l*l),c=h*l,u=-h*s,f=t+c,d=e+u,p=i+c,g=r+u,m=(f+p)/2,y=(d+g)/2,_=p-f,b=g-d,C=_*_+b*b,x=n-o,v=f*g-p*d,k=(b<0?-1:1)*Fa(wa(0,x*x*C-v*v)),T=(v*b-_*k)/C,w=(-v*_-b*k)/C,S=(v*b+_*k)/C,B=(-v*_+b*k)/C,F=T-m,L=w-y,M=S-m,A=B-y;return F*F+L*L>M*M+A*A&&(T=S,w=B),{cx:T,cy:w,x01:-c,y01:-u,x11:T*(n/x-1),y11:w*(n/x-1)}}function Ya(){var t=ja,e=Pa,i=xa(0),r=null,n=Ra,o=Wa,a=Ua,s=null,l=za(h);function h(){var h,c,u,f=+t.apply(this,arguments),d=+e.apply(this,arguments),p=n.apply(this,arguments)-Aa,g=o.apply(this,arguments)-Aa,m=va(g-p),y=g>p;if(s||(s=h=l()),dLa)if(m>Ea-La)s.moveTo(d*Ta(p),d*Ba(p)),s.arc(0,0,d,p,g,!y),f>La&&(s.moveTo(f*Ta(g),f*Ba(g)),s.arc(0,0,f,g,p,y));else{var _,b,C=p,x=g,v=p,k=g,T=m,w=m,S=a.apply(this,arguments)/2,B=S>La&&(r?+r.apply(this,arguments):Fa(f*f+d*d)),F=Sa(va(d-f)/2,+i.apply(this,arguments)),L=F,M=F;if(B>La){var A=Za(B/f*Ba(S)),E=Za(B/d*Ba(S));(T-=2*A)>La?(v+=A*=y?1:-1,k-=A):(T=0,v=k=(p+g)/2),(w-=2*E)>La?(C+=E*=y?1:-1,x-=E):(w=0,C=x=(p+g)/2)}var Z=d*Ta(C),O=d*Ba(C),q=f*Ta(k),I=f*Ba(k);if(F>La){var N,D=d*Ta(x),$=d*Ba(x),z=f*Ta(v),j=f*Ba(v);if(m1?0:u<-1?Ma:Math.acos(u))/2),Y=Fa(N[0]*N[0]+N[1]*N[1]);L=Sa(F,(f-Y)/(H-1)),M=Sa(F,(d-Y)/(H+1))}else L=M=0}w>La?M>La?(_=Ha(z,j,Z,O,d,M,y),b=Ha(D,$,q,I,d,M,y),s.moveTo(_.cx+_.x01,_.cy+_.y01),MLa&&T>La?L>La?(_=Ha(q,I,D,$,f,-L,y),b=Ha(Z,O,z,j,f,-L,y),s.lineTo(_.cx+_.x01,_.cy+_.y01),Lt?1:e>=t?0:NaN}function es(t){return t}function is(){var t=es,e=ts,i=null,r=xa(0),n=xa(Ea),o=xa(0);function a(a){var s,l,h,c,u,f=(a=Va(a)).length,d=0,p=new Array(f),g=new Array(f),m=+r.apply(this,arguments),y=Math.min(Ea,Math.max(-Ea,n.apply(this,arguments)-m)),_=Math.min(Math.abs(y)/f,o.apply(this,arguments)),b=_*(y<0?-1:1);for(s=0;s0&&(d+=u);for(null!=e?p.sort((function(t,i){return e(g[t],g[i])})):null!=i&&p.sort((function(t,e){return i(a[t],a[e])})),s=0,h=d?(y-f*b)/d:0;s0?u*h:0)+b,g[l]={data:a[l],index:s,value:u,startAngle:m,endAngle:c,padAngle:_};return g}return a.value=function(e){return arguments.length?(t="function"==typeof e?e:xa(+e),a):t},a.sortValues=function(t){return arguments.length?(e=t,i=null,a):e},a.sort=function(t){return arguments.length?(i=t,e=null,a):i},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:xa(+t),a):r},a.endAngle=function(t){return arguments.length?(n="function"==typeof t?t:xa(+t),a):n},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:xa(+t),a):o},a}function rs(){}function ns(t,e,i){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+i)/6)}function os(t){this._context=t}function as(t){return new os(t)}function ss(t){this._context=t}function ls(t){return new ss(t)}function hs(t){this._context=t}function cs(t){return new hs(t)}$a.prototype,Array.prototype.slice,Ga.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},os.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:ns(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:ns(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},ss.prototype={areaStart:rs,areaEnd:rs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:ns(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},hs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var i=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(i,r):this._context.moveTo(i,r);break;case 3:this._point=4;default:ns(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class us{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function fs(t){return new us(t,!0)}function ds(t){return new us(t,!1)}function ps(t,e){this._basis=new os(t),this._beta=e}ps.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,i=t.length-1;if(i>0)for(var r,n=t[0],o=e[0],a=t[i]-n,s=e[i]-o,l=-1;++l<=i;)r=l/i,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+r*a),this._beta*e[l]+(1-this._beta)*(o+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};var gs=function t(e){function i(t){return 1===e?new os(t):new ps(t,e)}return i.beta=function(e){return t(+e)},i}(.85);function ms(t,e,i){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-i),t._x2,t._y2)}function ys(t,e){this._context=t,this._k=(1-e)/6}ys.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:ms(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var _s=function t(e){function i(t){return new ys(t,e)}return i.tension=function(e){return t(+e)},i}(0);function bs(t,e){this._context=t,this._k=(1-e)/6}bs.prototype={areaStart:rs,areaEnd:rs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Cs=function t(e){function i(t){return new bs(t,e)}return i.tension=function(e){return t(+e)},i}(0);function xs(t,e){this._context=t,this._k=(1-e)/6}xs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var vs=function t(e){function i(t){return new xs(t,e)}return i.tension=function(e){return t(+e)},i}(0);function ks(t,e,i){var r=t._x1,n=t._y1,o=t._x2,a=t._y2;if(t._l01_a>La){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,n=(n*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>La){var h=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,c=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*h+t._x1*t._l23_2a-e*t._l12_2a)/c,a=(a*h+t._y1*t._l23_2a-i*t._l12_2a)/c}t._context.bezierCurveTo(r,n,o,a,t._x2,t._y2)}function Ts(t,e){this._context=t,this._alpha=e}Ts.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:ks(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var ws=function t(e){function i(t){return e?new Ts(t,e):new ys(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ss(t,e){this._context=t,this._alpha=e}Ss.prototype={areaStart:rs,areaEnd:rs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:ks(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Bs=function t(e){function i(t){return e?new Ss(t,e):new bs(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Fs(t,e){this._context=t,this._alpha=e}Fs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:ks(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Ls=function t(e){function i(t){return e?new Fs(t,e):new xs(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ms(t){this._context=t}function As(t){return new Ms(t)}function Es(t){return t<0?-1:1}function Zs(t,e,i){var r=t._x1-t._x0,n=e-t._x1,o=(t._y1-t._y0)/(r||n<0&&-0),a=(i-t._y1)/(n||r<0&&-0),s=(o*n+a*r)/(r+n);return(Es(o)+Es(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(s))||0}function Os(t,e){var i=t._x1-t._x0;return i?(3*(t._y1-t._y0)/i-e)/2:e}function qs(t,e,i){var r=t._x0,n=t._y0,o=t._x1,a=t._y1,s=(o-r)/3;t._context.bezierCurveTo(r+s,n+s*e,o-s,a-s*i,o,a)}function Is(t){this._context=t}function Ns(t){this._context=new Ds(t)}function Ds(t){this._context=t}function $s(t){return new Is(t)}function zs(t){return new Ns(t)}function js(t){this._context=t}function Ps(t){var e,i,r=t.length-1,n=new Array(r),o=new Array(r),a=new Array(r);for(n[0]=0,o[0]=2,a[0]=t[0]+2*t[1],e=1;e=0;--e)n[e]=(a[e]-n[e+1])/o[e];for(o[r-1]=(t[r]+n[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var i=this._x*(1-this._t)+t*this._t;this._context.lineTo(i,this._y),this._context.lineTo(i,e)}}this._x=t,this._y=e}},Vs.prototype={constructor:Vs,scale:function(t){return 1===t?this:new Vs(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new Vs(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}},new Vs(1,0,0),Vs.prototype},4549:function(t,e,i){"use strict";i.d(e,{Z:function(){return o}});var r=i(5971),n=i(2142),o=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new class{constructor(){this.type=n.w.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=n.w.ALL}is(t){return this.type===t}}}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=n.w.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:i,l:n}=t;void 0===e&&(t.h=r.Z.channel.rgb2hsl(t,"h")),void 0===i&&(t.s=r.Z.channel.rgb2hsl(t,"s")),void 0===n&&(t.l=r.Z.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:i,b:n}=t;void 0===e&&(t.r=r.Z.channel.hsl2rgb(t,"r")),void 0===i&&(t.g=r.Z.channel.hsl2rgb(t,"g")),void 0===n&&(t.b=r.Z.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(n.w.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(n.w.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(n.w.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(n.w.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(n.w.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(n.w.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},1767:function(t,e,i){"use strict";i.d(e,{Z:function(){return g}});var r=i(4549),n=i(2142);const o={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(o.re);if(!e)return;const i=e[1],n=parseInt(i,16),a=i.length,s=a%4==0,l=a>4,h=l?1:17,c=l?8:4,u=s?0:-1,f=l?255:15;return r.Z.set({r:(n>>c*(u+3)&f)*h,g:(n>>c*(u+2)&f)*h,b:(n>>c*(u+1)&f)*h,a:s?(n&f)*h/255:1},t)},stringify:t=>{const{r:e,g:i,b:r,a:o}=t;return o<1?`#${n.Q[Math.round(e)]}${n.Q[Math.round(i)]}${n.Q[Math.round(r)]}${n.Q[Math.round(255*o)]}`:`#${n.Q[Math.round(e)]}${n.Q[Math.round(i)]}${n.Q[Math.round(r)]}`}};var a=o,s=i(5971);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,i]=e;switch(i){case"grad":return s.Z.channel.clamp.h(.9*parseFloat(t));case"rad":return s.Z.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.Z.channel.clamp.h(360*parseFloat(t))}}return s.Z.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const i=t.match(l.re);if(!i)return;const[,n,o,a,h,c]=i;return r.Z.set({h:l._hue2deg(n),s:s.Z.channel.clamp.s(parseFloat(o)),l:s.Z.channel.clamp.l(parseFloat(a)),a:h?s.Z.channel.clamp.a(c?parseFloat(h)/100:parseFloat(h)):1},t)},stringify:t=>{const{h:e,s:i,l:r,a:n}=t;return n<1?`hsla(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}%, ${s.Z.lang.round(r)}%, ${n})`:`hsl(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}%, ${s.Z.lang.round(r)}%)`}};var h=l;const c={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=c.colors[t];if(e)return a.parse(e)},stringify:t=>{const e=a.stringify(t);for(const t in c.colors)if(c.colors[t]===e)return t}};var u=c;const f={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const i=t.match(f.re);if(!i)return;const[,n,o,a,l,h,c,u,d]=i;return r.Z.set({r:s.Z.channel.clamp.r(o?2.55*parseFloat(n):parseFloat(n)),g:s.Z.channel.clamp.g(l?2.55*parseFloat(a):parseFloat(a)),b:s.Z.channel.clamp.b(c?2.55*parseFloat(h):parseFloat(h)),a:u?s.Z.channel.clamp.a(d?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`rgba(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}, ${s.Z.lang.round(r)}, ${s.Z.lang.round(n)})`:`rgb(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}, ${s.Z.lang.round(r)})`}};var d=f;const p={format:{keyword:c,hex:a,rgb:f,rgba:f,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=a.parse(t)||d.parse(t)||h.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(n.w.HSL)||void 0===t.data.r?h.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?d.stringify(t):a.stringify(t)};var g=p},2142:function(t,e,i){"use strict";i.d(e,{Q:function(){return n},w:function(){return o}});var r=i(5971);const n={};for(let t=0;t<=255;t++)n[t]=r.Z.unit.dec2hex(t);const o={ALL:0,RGB:1,HSL:2}},6174:function(t,e,i){"use strict";var r=i(5971),n=i(1767);e.Z=(t,e,i)=>{const o=n.Z.parse(t),a=o[e],s=r.Z.channel.clamp[e](a+i);return a!==s&&(o[e]=s),n.Z.stringify(o)}},3438:function(t,e,i){"use strict";var r=i(5971),n=i(1767);e.Z=(t,e)=>{const i=n.Z.parse(t);for(const t in e)i[t]=r.Z.channel.clamp[t](e[t]);return n.Z.stringify(i)}},7201:function(t,e,i){"use strict";var r=i(6174);e.Z=(t,e)=>(0,r.Z)(t,"l",-e)},6500:function(t,e,i){"use strict";i.d(e,{Z:function(){return a}});var r=i(5971),n=i(1767),o=t=>(t=>{const{r:e,g:i,b:o}=n.Z.parse(t),a=.2126*r.Z.channel.toLinear(e)+.7152*r.Z.channel.toLinear(i)+.0722*r.Z.channel.toLinear(o);return r.Z.lang.round(a)})(t)>=.5,a=t=>!o(t)},2281:function(t,e,i){"use strict";var r=i(6174);e.Z=(t,e)=>(0,r.Z)(t,"l",e)},1117:function(t,e,i){"use strict";var r=i(5971),n=i(4549),o=i(1767),a=i(3438);e.Z=(t,e,i=0,s=1)=>{if("number"!=typeof t)return(0,a.Z)(t,{a:e});const l=n.Z.set({r:r.Z.channel.clamp.r(t),g:r.Z.channel.clamp.g(e),b:r.Z.channel.clamp.b(i),a:r.Z.channel.clamp.a(s)});return o.Z.stringify(l)}},5971:function(t,e,i){"use strict";i.d(e,{Z:function(){return n}});const r={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t),hsl2rgb:({h:t,s:e,l:i},n)=>{if(!e)return 2.55*i;t/=360,e/=100;const o=(i/=100)<.5?i*(1+e):i+e-i*e,a=2*i-o;switch(n){case"r":return 255*r.hue2rgb(a,o,t+1/3);case"g":return 255*r.hue2rgb(a,o,t);case"b":return 255*r.hue2rgb(a,o,t-1/3)}},rgb2hsl:({r:t,g:e,b:i},r)=>{t/=255,e/=255,i/=255;const n=Math.max(t,e,i),o=Math.min(t,e,i),a=(n+o)/2;if("l"===r)return 100*a;if(n===o)return 0;const s=n-o;if("s"===r)return 100*(a>.5?s/(2-n-o):s/(n+o));switch(n){case t:return 60*((e-i)/s+(ee>i?Math.min(e,Math.max(i,t)):Math.min(i,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},2536:function(t,e,i){"use strict";i.d(e,{Z:function(){return s}});var r=i(9651),n=function(t,e){for(var i=t.length;i--;)if((0,r.Z)(t[i][0],e))return i;return-1},o=Array.prototype.splice;function a(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e-1},a.prototype.set=function(t,e){var i=this.__data__,r=n(i,t);return r<0?(++this.size,i.push([t,e])):i[r][1]=e,this};var s=a},6183:function(t,e,i){"use strict";var r=i(2119),n=i(6092),o=(0,r.Z)(n.Z,"Map");e.Z=o},520:function(t,e,i){"use strict";i.d(e,{Z:function(){return f}});var r=(0,i(2119).Z)(Object,"create"),n=Object.prototype.hasOwnProperty,o=Object.prototype.hasOwnProperty;function a(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t0){if(++n>=800)return arguments[0]}else n=0;return r.apply(void 0,arguments)})},19:function(t,e){"use strict";var i=Function.prototype.toString;e.Z=function(t){if(null!=t){try{return i.call(t)}catch(t){}try{return t+""}catch(t){}}return""}},2002:function(t,e){"use strict";e.Z=function(t){return function(){return t}}},9651:function(t,e){"use strict";e.Z=function(t,e){return t===e||t!=t&&e!=e}},9203:function(t,e){"use strict";e.Z=function(t){return t}},4732:function(t,e,i){"use strict";i.d(e,{Z:function(){return c}});var r=i(1922),n=i(8533),o=function(t){return(0,n.Z)(t)&&"[object Arguments]"==(0,r.Z)(t)},a=Object.prototype,s=a.hasOwnProperty,l=a.propertyIsEnumerable,h=o(function(){return arguments}())?o:function(t){return(0,n.Z)(t)&&s.call(t,"callee")&&!l.call(t,"callee")},c=h},7771:function(t,e){"use strict";var i=Array.isArray;e.Z=i},585:function(t,e,i){"use strict";var r=i(3234),n=i(1656);e.Z=function(t){return null!=t&&(0,n.Z)(t.length)&&!(0,r.Z)(t)}},836:function(t,e,i){"use strict";var r=i(585),n=i(8533);e.Z=function(t){return(0,n.Z)(t)&&(0,r.Z)(t)}},6706:function(t,e,i){"use strict";i.d(e,{Z:function(){return s}});var r=i(6092),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n?r.Z.Buffer:void 0,s=(a?a.isBuffer:void 0)||function(){return!1}},9697:function(t,e,i){"use strict";var r=i(8448),n=i(6155),o=i(4732),a=i(7771),s=i(585),l=i(6706),h=i(2764),c=i(7212),u=Object.prototype.hasOwnProperty;e.Z=function(t){if(null==t)return!0;if((0,s.Z)(t)&&((0,a.Z)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.Z)(t)||(0,c.Z)(t)||(0,o.Z)(t)))return!t.length;var e=(0,n.Z)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,h.Z)(t))return!(0,r.Z)(t).length;for(var i in t)if(u.call(t,i))return!1;return!0}},3234:function(t,e,i){"use strict";var r=i(1922),n=i(7226);e.Z=function(t){if(!(0,n.Z)(t))return!1;var e=(0,r.Z)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},1656:function(t,e){"use strict";e.Z=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},7226:function(t,e){"use strict";e.Z=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},8533:function(t,e){"use strict";e.Z=function(t){return null!=t&&"object"==typeof t}},7514:function(t,e,i){"use strict";var r=i(1922),n=i(2513),o=i(8533),a=Function.prototype,s=Object.prototype,l=a.toString,h=s.hasOwnProperty,c=l.call(Object);e.Z=function(t){if(!(0,o.Z)(t)||"[object Object]"!=(0,r.Z)(t))return!1;var e=(0,n.Z)(t);if(null===e)return!0;var i=h.call(e,"constructor")&&e.constructor;return"function"==typeof i&&i instanceof i&&l.call(i)==c}},7212:function(t,e,i){"use strict";i.d(e,{Z:function(){return c}});var r=i(1922),n=i(1656),o=i(8533),a={};a["[object Float32Array]"]=a["[object Float64Array]"]=a["[object Int8Array]"]=a["[object Int16Array]"]=a["[object Int32Array]"]=a["[object Uint8Array]"]=a["[object Uint8ClampedArray]"]=a["[object Uint16Array]"]=a["[object Uint32Array]"]=!0,a["[object Arguments]"]=a["[object Array]"]=a["[object ArrayBuffer]"]=a["[object Boolean]"]=a["[object DataView]"]=a["[object Date]"]=a["[object Error]"]=a["[object Function]"]=a["[object Map]"]=a["[object Number]"]=a["[object Object]"]=a["[object RegExp]"]=a["[object Set]"]=a["[object String]"]=a["[object WeakMap]"]=!1;var s=i(1162),l=i(4254),h=l.Z&&l.Z.isTypedArray,c=h?(0,s.Z)(h):function(t){return(0,o.Z)(t)&&(0,n.Z)(t.length)&&!!a[(0,r.Z)(t)]}},7590:function(t,e,i){"use strict";i.d(e,{Z:function(){return h}});var r=i(9001),n=i(7226),o=i(2764),a=Object.prototype.hasOwnProperty,s=function(t){if(!(0,n.Z)(t))return function(t){var e=[];if(null!=t)for(var i in Object(t))e.push(i);return e}(t);var e=(0,o.Z)(t),i=[];for(var r in t)("constructor"!=r||!e&&a.call(t,r))&&i.push(r);return i},l=i(585),h=function(t){return(0,l.Z)(t)?(0,r.Z)(t,!0):s(t)}},2454:function(t,e,i){"use strict";var r=i(520);function n(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var i=function(){var r=arguments,n=e?e.apply(this,r):r[0],o=i.cache;if(o.has(n))return o.get(n);var a=t.apply(this,r);return i.cache=o.set(n,a)||o,a};return i.cache=new(n.Cache||r.Z),i}n.Cache=r.Z,e.Z=n},6841:function(t,e,i){"use strict";i.d(e,{Z:function(){return F}});var r,n=i(5365),o=i(4752),a=i(9651),s=function(t,e,i){(void 0!==i&&!(0,a.Z)(t[e],i)||void 0===i&&!(e in t))&&(0,o.Z)(t,e,i)},l=i(5381),h=i(1050),c=i(2701),u=i(7215),f=i(5418),d=i(4732),p=i(7771),g=i(836),m=i(6706),y=i(3234),_=i(7226),b=i(7514),C=i(7212),x=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]},v=i(1899),k=i(7590),T=function(t,e,i,r,n,o,a){var l,T=x(t,i),w=x(e,i),S=a.get(w);if(S)s(t,i,S);else{var B=o?o(T,w,i+"",t,e,a):void 0,F=void 0===B;if(F){var L=(0,p.Z)(w),M=!L&&(0,m.Z)(w),A=!L&&!M&&(0,C.Z)(w);B=w,L||M||A?(0,p.Z)(T)?B=T:(0,g.Z)(T)?B=(0,u.Z)(T):M?(F=!1,B=(0,h.Z)(w,!0)):A?(F=!1,B=(0,c.Z)(w,!0)):B=[]:(0,b.Z)(w)||(0,d.Z)(w)?(B=T,(0,d.Z)(T)?(l=T,B=(0,v.Z)(l,(0,k.Z)(l))):(0,_.Z)(T)&&!(0,y.Z)(T)||(B=(0,f.Z)(w))):F=!1}F&&(a.set(w,B),n(B,w,r,o,a),a.delete(w)),s(t,i,B)}},w=function t(e,i,r,o,a){e!==i&&(0,l.Z)(i,(function(l,h){if(a||(a=new n.Z),(0,_.Z)(l))T(e,i,h,r,t,o,a);else{var c=o?o(x(e,h),l,h+"",e,i,a):void 0;void 0===c&&(c=l),s(e,h,c)}}),k.Z)},S=i(9581),B=i(439),F=(r=function(t,e,i){w(t,e,i)},(0,S.Z)((function(t,e){var i=-1,n=e.length,o=n>1?e[n-1]:void 0,a=n>2?e[2]:void 0;for(o=r.length>3&&"function"==typeof o?(n--,o):void 0,a&&(0,B.Z)(e[0],e[1],a)&&(o=n<3?void 0:o,n=1),t=Object(t);++i{const i=l.Z.parse(t),r={};for(const t in e)e[t]&&(r[t]=i[t]+e[t]);return(0,h.Z)(t,r)},u=i(1117),f=(t,e=100)=>{const i=l.Z.parse(t);return i.r=255-i.r,i.g=255-i.g,i.b=255-i.b,((t,e,i=50)=>{const{r:r,g:n,b:o,a:a}=l.Z.parse(t),{r:s,g:h,b:c,a:f}=l.Z.parse(e),d=i/100,p=2*d-1,g=a-f,m=((p*g==-1?p:(p+g)/(1+p*g))+1)/2,y=1-m,_=r*m+s*y,b=n*m+h*y,C=o*m+c*y,x=a*d+f*(1-d);return(0,u.Z)(_,b,C,x)})(i,t,e)},d=i(7201),p=i(2281),g=i(6500),m=i(2454),y=i(6841),_="comm",b="rule",C="decl",x=Math.abs,v=String.fromCharCode;function k(t){return t.trim()}function T(t,e,i){return t.replace(e,i)}function w(t,e){return t.indexOf(e)}function S(t,e){return 0|t.charCodeAt(e)}function B(t,e,i){return t.slice(e,i)}function F(t){return t.length}function L(t,e){return e.push(t),t}function M(t,e){for(var i="",r=0;r0?S(N,--q):0,Z--,10===I&&(Z=1,E--),I}function z(){return I=q2||W(I)>3?"":" "}function Y(t,e){for(;--e&&z()&&!(I<48||I>102||I>57&&I<65||I>70&&I<97););return R(t,P()+(e<6&&32==j()&&32==z()))}function V(t){for(;z();)switch(I){case t:return q;case 34:case 39:34!==t&&39!==t&&V(I);break;case 40:41===t&&V(t);break;case 92:z()}return q}function G(t,e){for(;z()&&t+I!==57&&(t+I!==84||47!==j()););return"/*"+R(e,q-1)+"*"+v(47===t?t:z())}function X(t){for(;!W(j());)z();return R(t,q)}function J(t){return function(t){return N="",t}(Q("",null,null,null,[""],t=function(t){return E=Z=1,O=F(N=t),q=0,[]}(t),0,[0],t))}function Q(t,e,i,r,n,o,a,s,l){for(var h=0,c=0,u=a,f=0,d=0,p=0,g=1,m=1,y=1,_=0,b="",C=n,x=o,k=r,B=b;m;)switch(p=_,_=z()){case 40:if(108!=p&&58==S(B,u-1)){-1!=w(B+=T(U(_),"&","&\f"),"&\f")&&(y=-1);break}case 34:case 39:case 91:B+=U(_);break;case 9:case 10:case 13:case 32:B+=H(p);break;case 92:B+=Y(P()-1,7);continue;case 47:switch(j()){case 42:case 47:L(tt(G(z(),P()),e,i,l),l);break;default:B+="/"}break;case 123*g:s[h++]=F(B)*y;case 125*g:case 59:case 0:switch(_){case 0:case 125:m=0;case 59+c:-1==y&&(B=T(B,/\f/g,"")),d>0&&F(B)-u&&L(d>32?et(B+";",r,i,u-1,l):et(T(B," ","")+";",r,i,u-2,l),l);break;case 59:B+=";";default:if(L(k=K(B,e,i,h,c,n,s,b,C=[],x=[],u,o),o),123===_)if(0===c)Q(B,e,k,k,C,o,u,s,x);else switch(99===f&&110===S(B,3)?100:f){case 100:case 108:case 109:case 115:Q(t,k,k,r&&L(K(t,k,k,0,0,n,s,b,n,C=[],u,x),x),n,x,u,s,r?C:x);break;default:Q(B,k,k,k,[""],x,0,s,x)}}h=c=d=0,g=y=1,b=B="",u=a;break;case 58:u=1+F(B),d=p;default:if(g<1)if(123==_)--g;else if(125==_&&0==g++&&125==$())continue;switch(B+=v(_),_*g){case 38:y=c>0?1:(B+="\f",-1);break;case 44:s[h++]=(F(B)-1)*y,y=1;break;case 64:45===j()&&(B+=U(z())),f=j(),c=u=F(b=B+=X(P())),_++;break;case 45:45===p&&2==F(B)&&(g=0)}}return o}function K(t,e,i,r,n,o,a,s,l,h,c,u){for(var f=n-1,d=0===n?o:[""],p=function(t){return t.length}(d),g=0,m=0,y=0;g0?d[_]+" "+C:T(C,/&\f/g,d[_])))&&(l[y++]=v);return D(t,e,i,0===n?b:s,l,h,c,u)}function tt(t,e,i,r){return D(t,e,i,_,v(I),B(t,2,-2),0,r)}function et(t,e,i,r,n){return D(t,e,i,C,B(t,0,r),B(t,r+1,-1),r,n)}var it=i(9697);const rt={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},nt={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},ot=function(t="fatal"){let e=rt.fatal;"string"==typeof t?(t=t.toLowerCase())in rt&&(e=rt[t]):"number"==typeof t&&(e=t),nt.trace=()=>{},nt.debug=()=>{},nt.info=()=>{},nt.warn=()=>{},nt.error=()=>{},nt.fatal=()=>{},e<=rt.fatal&&(nt.fatal=console.error?console.error.bind(console,at("FATAL"),"color: orange"):console.log.bind(console,"",at("FATAL"))),e<=rt.error&&(nt.error=console.error?console.error.bind(console,at("ERROR"),"color: orange"):console.log.bind(console,"",at("ERROR"))),e<=rt.warn&&(nt.warn=console.warn?console.warn.bind(console,at("WARN"),"color: orange"):console.log.bind(console,"",at("WARN"))),e<=rt.info&&(nt.info=console.info?console.info.bind(console,at("INFO"),"color: lightblue"):console.log.bind(console,"",at("INFO"))),e<=rt.debug&&(nt.debug=console.debug?console.debug.bind(console,at("DEBUG"),"color: lightgreen"):console.log.bind(console,"",at("DEBUG"))),e<=rt.trace&&(nt.trace=console.debug?console.debug.bind(console,at("TRACE"),"color: lightgreen"):console.log.bind(console,"",at("TRACE")))},at=t=>`%c${n().format("ss.SSS")} : ${t} : `,st=//gi,lt=t=>s.sanitize(t),ht=(t,e)=>{var i;if(!1!==(null==(i=e.flowchart)?void 0:i.htmlLabels)){const i=e.securityLevel;"antiscript"===i||"strict"===i?t=lt(t):"loose"!==i&&(t=(t=(t=ft(t)).replace(//g,">")).replace(/=/g,"="),t=ut(t))}return t},ct=(t,e)=>t?t=e.dompurifyConfig?s.sanitize(ht(t,e),e.dompurifyConfig).toString():s.sanitize(ht(t,e),{FORBID_TAGS:["style"]}).toString():t,ut=t=>t.replace(/#br#/g,"
        "),ft=t=>t.replace(st,"#br#"),dt=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),pt=function(t){let e=t;if(t.split("~").length-1>=2){let t=e;do{e=t,t=e.replace(/~([^\s,:;]+)~/,"<$1>")}while(t!=e);return pt(t)}return e},gt={getRows:t=>t?ft(t).replace(/\\n/g,"#br#").split("#br#"):[""],sanitizeText:ct,sanitizeTextOrArray:(t,e)=>"string"==typeof t?ct(t,e):t.flat().map((t=>ct(t,e))),hasBreaks:t=>st.test(t),splitBreaks:t=>t.split(st),lineBreakRegex:st,removeScript:lt,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:dt,getMax:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)},getMin:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}},mt=(t,e)=>c(t,e?{s:-40,l:10}:{s:-40,l:-10}),yt="#ffffff",_t="#f2f2f2",bt=t=>{const e=new class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=c(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=c(this.primaryColor,{h:-160}),this.primaryBorderColor=mt(this.primaryColor,this.darkMode),this.secondaryBorderColor=mt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=mt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=(0,u.Z)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||c(this.primaryColor,{h:30}),this.cScale4=this.cScale4||c(this.primaryColor,{h:60}),this.cScale5=this.cScale5||c(this.primaryColor,{h:90}),this.cScale6=this.cScale6||c(this.primaryColor,{h:120}),this.cScale7=this.cScale7||c(this.primaryColor,{h:150}),this.cScale8=this.cScale8||c(this.primaryColor,{h:210}),this.cScale9=this.cScale9||c(this.primaryColor,{h:270}),this.cScale10=this.cScale10||c(this.primaryColor,{h:300}),this.cScale11=this.cScale11||c(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,d.Z)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,d.Z)(this.tertiaryColor,40);for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e};class Ct{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,p.Z)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=c(this.primaryColor,{h:-160}),this.primaryBorderColor=mt(this.primaryColor,this.darkMode),this.secondaryBorderColor=mt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=mt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=(0,p.Z)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,p.Z)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const xt={base:{getThemeVariables:t=>{const e=new class{constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||c(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||c(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||mt(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||mt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||mt(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||mt(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||f(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||f(this.tertiaryColor),this.lineColor=this.lineColor||f(this.background),this.arrowheadColor=this.arrowheadColor||f(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,d.Z)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,d.Z)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||f(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,p.Z)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||c(this.primaryColor,{h:30}),this.cScale4=this.cScale4||c(this.primaryColor,{h:60}),this.cScale5=this.cScale5||c(this.primaryColor,{h:90}),this.cScale6=this.cScale6||c(this.primaryColor,{h:120}),this.cScale7=this.cScale7||c(this.primaryColor,{h:150}),this.cScale8=this.cScale8||c(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||c(this.primaryColor,{h:270}),this.cScale10=this.cScale10||c(this.primaryColor,{h:300}),this.cScale11=this.cScale11||c(this.primaryColor,{h:330}),this.darkMode)for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,p.Z)(this.primaryColor,16),this.tertiaryColor=c(this.primaryColor,{h:-160}),this.primaryBorderColor=f(this.background),this.secondaryBorderColor=mt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=mt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,p.Z)(f("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=(0,u.Z)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,d.Z)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,d.Z)(this.sectionBkgColor,10),this.taskBorderColor=(0,u.Z)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,u.Z)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=(0,p.Z)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,p.Z)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,p.Z)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=c(this.primaryColor,{h:64}),this.fillType3=c(this.secondaryColor,{h:64}),this.fillType4=c(this.primaryColor,{h:-64}),this.fillType5=c(this.secondaryColor,{h:-64}),this.fillType6=c(this.primaryColor,{h:128}),this.fillType7=c(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||c(this.primaryColor,{h:30}),this.cScale4=this.cScale4||c(this.primaryColor,{h:60}),this.cScale5=this.cScale5||c(this.primaryColor,{h:90}),this.cScale6=this.cScale6||c(this.primaryColor,{h:120}),this.cScale7=this.cScale7||c(this.primaryColor,{h:150}),this.cScale8=this.cScale8||c(this.primaryColor,{h:210}),this.cScale9=this.cScale9||c(this.primaryColor,{h:270}),this.cScale10=this.cScale10||c(this.primaryColor,{h:300}),this.cScale11=this.cScale11||c(this.primaryColor,{h:330});for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},default:{getThemeVariables:bt},forest:{getThemeVariables:t=>{const e=new class{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,p.Z)("#cde498",10),this.primaryBorderColor=mt(this.primaryColor,this.darkMode),this.secondaryBorderColor=mt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=mt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.primaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=(0,d.Z)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||c(this.primaryColor,{h:30}),this.cScale4=this.cScale4||c(this.primaryColor,{h:60}),this.cScale5=this.cScale5||c(this.primaryColor,{h:90}),this.cScale6=this.cScale6||c(this.primaryColor,{h:120}),this.cScale7=this.cScale7||c(this.primaryColor,{h:150}),this.cScale8=this.cScale8||c(this.primaryColor,{h:210}),this.cScale9=this.cScale9||c(this.primaryColor,{h:270}),this.cScale10=this.cScale10||c(this.primaryColor,{h:300}),this.cScale11=this.cScale11||c(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,d.Z)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,d.Z)(this.tertiaryColor,40);for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new Ct;return e.calculate(t),e}}},vt={flowchart:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},theme:"default",maxTextSize:5e4,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize"],deterministicIds:!1,fontSize:16},kt={...vt,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:xt.default.getThemeVariables(),sequence:{...vt.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...vt.gantt,tickInterval:void 0,useWidth:void 0},c4:{...vt.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...vt.pie,useWidth:984},requirement:{...vt.requirement,useWidth:void 0},gitGraph:{...vt.gitGraph,useMaxWidth:!1},sankey:{...vt.sankey,useMaxWidth:!1}},Tt=(t,e="")=>Object.keys(t).reduce(((i,r)=>Array.isArray(t[r])?i:"object"==typeof t[r]&&null!==t[r]?[...i,e+r,...Tt(t[r],"")]:[...i,e+r]),[]),wt=new Set(Tt(kt,"")),St=kt,Bt=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,Ft=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Lt=/\s*%%.*\n/gm;class Mt extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const At={},Et=function(t,e){t=t.replace(Bt,"").replace(Ft,"").replace(Lt,"\n");for(const[i,{detector:r}]of Object.entries(At))if(r(t,e))return i;throw new Mt(`No diagram type detected matching given configuration for text: ${t}`)},Zt=(...t)=>{for(const{id:e,detector:i,loader:r}of t)Ot(e,i,r)},Ot=(t,e,i)=>{At[t]?nt.error(`Detector with key ${t} already exists`):At[t]={detector:e,loader:i},nt.debug(`Detector with key ${t} added${i?" with loader":""}`)},qt=(t,e,{depth:i=2,clobber:r=!1}={})=>{const n={depth:i,clobber:r};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>qt(t,e,n))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||i<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(r||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=qt(t[n],e[n],{depth:i-1,clobber:r}))})),t)},It=qt,Nt="​",Dt={curveBasis:a.$0Z,curveBasisClosed:a.Dts,curveBasisOpen:a.WQY,curveBumpX:a.qpX,curveBumpY:a.u93,curveBundle:a.tFB,curveCardinalClosed:a.OvA,curveCardinalOpen:a.dCK,curveCardinal:a.YY7,curveCatmullRomClosed:a.fGX,curveCatmullRomOpen:a.$m7,curveCatmullRom:a.zgE,curveLinear:a.c_6,curveLinearClosed:a.fxm,curveMonotoneX:a.FdL,curveMonotoneY:a.ak_,curveNatural:a.SxZ,curveStep:a.eA_,curveStepAfter:a.jsv,curveStepBefore:a.iJ},$t=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,zt=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${$t.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),nt.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=Ft.exec(t));)if(r.index===Ft.lastIndex&&Ft.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length&&n.push({type:t,args:null}),1===n.length?n[0]:n}catch(i){return nt.error(`ERROR: ${i.message} - Unable to parse directive\n ${null!==e?" type:"+e:""} based on the text:${t}`),{type:null,args:null}}};function jt(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return Dt[i]||e}function Pt(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function Rt(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let Wt=0;const Ut=()=>(Wt++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Wt),Ht=t=>function(t){let e="";for(let i=0;i{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
        "},i),gt.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=Jt(`${t} `,i),l=Jt(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=Gt(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),Gt=(0,m.Z)(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(Jt(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function Xt(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:15},e),Qt(t,e).height}function Jt(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),Qt(t,e).width}const Qt=(0,m.Z)(((t,e)=>{e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e);const{fontSize:i,fontFamily:r,fontWeight:n}=e;if(!t)return{width:0,height:0};const[,o]=re(i),s=["sans-serif",r],l=t.split(gt.lineBreakRegex),h=[],c=(0,a.Ys)("body");if(!c.remove)return{width:0,height:0,lineHeight:0};const u=c.append("svg");for(const t of s){let e=0;const i={width:0,height:0,lineHeight:0};for(const r of l){const a={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0};a.text=r||Nt;const s=Yt(u,a).style("font-size",o).style("font-weight",n).style("font-family",t),l=(s._groups||s)[0][0].getBBox();if(0===l.width&&0===l.height)throw new Error("svg element not in render tree");i.width=Math.round(Math.max(i.width,l.width)),e=Math.round(l.height),i.height+=e,i.lineHeight=Math.round(Math.max(i.lineHeight,e))}h.push(i)}return u.remove(),h[isNaN(h[1].height)||isNaN(h[1].width)||isNaN(h[1].lineHeight)||h[0].height>h[1].height&&h[0].width>h[1].width&&h[0].lineHeight>h[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let Kt;const te=t=>{if(nt.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach((t=>te(t)));else{for(const e of Object.keys(t)){if(nt.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!wt.has(e)||null==t[e]){nt.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){nt.debug("sanitizing object",e),te(t[e]);continue}const i=["themeCSS","fontFamily","altFontFamily"];for(const r of i)e.includes(r)&&(nt.debug("sanitizing css option",e),t[e]=ee(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const i=t.themeVariables[e];(null==i?void 0:i.match)&&!i.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}nt.debug("After sanitization",t)}},ee=t=>{let e=0,i=0;for(const r of t){if(e{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t,10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function ne(t,e){return(0,y.Z)({},t,e)}const oe={assignWithDepth:It,wrapLabel:Vt,calculateTextHeight:Xt,calculateTextWidth:Jt,calculateTextDimensions:Qt,cleanAndMerge:ne,detectInit:function(t,e){const i=zt(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));te(t),r=It(r,[...t])}else r=i.args;if(!r)return;let n=Et(t,e);return["config"].forEach((t=>{void 0!==r[t]&&("flowchart-v2"===n&&(n="flowchart"),r[n]=r[t],delete r[t])})),r},detectDirective:zt,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:jt,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;t.forEach((t=>{i+=Pt(t,e),e=t}));let r,n=i/2;return e=void 0,t.forEach((t=>{if(e&&!r){const i=Pt(t,e);if(i=1&&(r={x:t.x,y:t.y}),o>0&&o<1&&(r={x:(1-o)*e.x+o*t.x,y:(1-o)*e.y+o*t.y})}}e=t})),r}(t)},calcCardinalityPosition:(t,e,i)=>{let r;nt.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());let n,o=25;r=void 0,e.forEach((t=>{if(r&&!n){const e=Pt(t,r);if(e=1&&(n={x:t.x,y:t.y}),i>0&&i<1&&(n={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const a=t?10:5,s=Math.atan2(e[0].y-n.y,e[0].x-n.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+n.x)/2,l.y=-Math.cos(s)*a+(e[0].y+n.y)/2,l},calcTerminalLabelPosition:function(t,e,i){let r,n=JSON.parse(JSON.stringify(i));nt.info("our points",n),"start_left"!==e&&"start_right"!==e&&(n=n.reverse()),n.forEach((t=>{r=t}));let o,a=25+t;r=void 0,n.forEach((t=>{if(r&&!o){const e=Pt(t,r);if(e=1&&(o={x:t.x,y:t.y}),i>0&&i<1&&(o={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const s=10+.5*t,l=Math.atan2(n[0].y-o.y,n[0].x-o.x),h={x:0,y:0};return h.x=Math.sin(l)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2,"start_left"===e&&(h.x=Math.sin(l+Math.PI)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l+Math.PI)*s+(n[0].y+o.y)/2),"end_right"===e&&(h.x=Math.sin(l-Math.PI)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l-Math.PI)*s+(n[0].y+o.y)/2-5),"end_left"===e&&(h.x=Math.sin(l)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2-5),h},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?(0,o.Nm)(i):i},getStylesFromArray:Rt,generateId:Ut,random:Ht,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let t=0;t{if(!r)return;const n=t.node().getBBox();t.append("text").text(r).attr("x",n.x+n.width/2).attr("y",-i).attr("class",e)},parseFontSize:re},ae="10.4.0",se=Object.freeze(St);let le,he=It({},se),ce=[],ue=It({},se);const fe=(t,e)=>{let i=It({},t),r={};for(const t of e)me(t),r=It(r,t);if(i=It(i,r),r.theme&&r.theme in xt){const t=It({},le),e=It(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in xt&&(i.themeVariables=xt[i.theme].getThemeVariables(e))}return ue=i,xe(ue),ue},de=()=>It({},he),pe=t=>(xe(t),It(ue,t),ge()),ge=()=>It({},ue),me=t=>{t&&(["secure",...he.secure??[]].forEach((e=>{Object.hasOwn(t,e)&&(nt.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{e.startsWith("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&me(t[e])})))},ye=t=>{te(t),!t.fontFamily||t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily}),ce.push(t),fe(he,ce)},_e=(t=he)=>{ce=[],fe(t,ce)},be={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},Ce={},xe=t=>{var e;t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&(Ce[e="LAZY_LOAD_DEPRECATED"]||(nt.warn(be[e]),Ce[e]=!0))},ve={id:"c4",detector:t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),loader:async()=>{const{diagram:t}=await i.e(545).then(i.bind(i,4545));return{id:"c4",diagram:t}}},ke="flowchart",Te={id:ke,detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&/^\s*graph/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(506),i.e(76),i.e(476),i.e(813),i.e(728)]).then(i.bind(i,8728));return{id:ke,diagram:t}}},we="flowchart-v2",Se={id:we,detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(!(!/^\s*graph/.test(t)||"dagre-wrapper"!==(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer))||/^\s*flowchart/.test(t))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(506),i.e(76),i.e(476),i.e(813),i.e(81)]).then(i.bind(i,3081));return{id:we,diagram:t}}},Be={id:"er",detector:t=>/^\s*erDiagram/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(430)]).then(i.bind(i,4430));return{id:"er",diagram:t}}},Fe="gitGraph",Le={id:Fe,detector:t=>/^\s*gitGraph/.test(t),loader:async()=>{const{diagram:t}=await i.e(729).then(i.bind(i,7729));return{id:Fe,diagram:t}}},Me="gantt",Ae={id:Me,detector:t=>/^\s*gantt/.test(t),loader:async()=>{const{diagram:t}=await i.e(773).then(i.bind(i,9773));return{id:Me,diagram:t}}},Ee="info",Ze={id:Ee,detector:t=>/^\s*info/.test(t),loader:async()=>{const{diagram:t}=await i.e(433).then(i.bind(i,6433));return{id:Ee,diagram:t}}},Oe={id:"pie",detector:t=>/^\s*pie/.test(t),loader:async()=>{const{diagram:t}=await i.e(546).then(i.bind(i,3546));return{id:"pie",diagram:t}}},qe="quadrantChart",Ie={id:qe,detector:t=>/^\s*quadrantChart/.test(t),loader:async()=>{const{diagram:t}=await i.e(118).then(i.bind(i,7118));return{id:qe,diagram:t}}},Ne="requirement",De={id:Ne,detector:t=>/^\s*requirement(Diagram)?/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(19)]).then(i.bind(i,4019));return{id:Ne,diagram:t}}},$e="sequence",ze={id:$e,detector:t=>/^\s*sequenceDiagram/.test(t),loader:async()=>{const{diagram:t}=await i.e(361).then(i.bind(i,5510));return{id:$e,diagram:t}}},je="class",Pe={id:je,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&/^\s*classDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(423),i.e(519)]).then(i.bind(i,9519));return{id:je,diagram:t}}},Re="classDiagram",We={id:Re,detector:(t,e)=>{var i;return!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer))||/^\s*classDiagram-v2/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(506),i.e(76),i.e(476),i.e(423),i.e(747)]).then(i.bind(i,6747));return{id:Re,diagram:t}}},Ue="state",He={id:Ue,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&/^\s*stateDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(535),i.e(642)]).then(i.bind(i,7642));return{id:Ue,diagram:t}}},Ye="stateDiagram",Ve={id:Ye,detector:(t,e)=>{var i;return!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(771),i.e(506),i.e(76),i.e(476),i.e(535),i.e(626)]).then(i.bind(i,1626));return{id:Ye,diagram:t}}},Ge="journey",Xe={id:Ge,detector:t=>/^\s*journey/.test(t),loader:async()=>{const{diagram:t}=await i.e(438).then(i.bind(i,2438));return{id:Ge,diagram:t}}},Je=t=>{var e;const{securityLevel:i}=ge();let r=(0,a.Ys)("body");if("sandbox"===i){const i=(null==(e=(0,a.Ys)(`#i${t}`).node())?void 0:e.contentDocument)??document;r=(0,a.Ys)(i.body)}return r.select(`#${t}`)},Qe=function(t,e,i,r){const n=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r}(e,i,r);!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,n)},Ke=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;nt.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;nt.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,nt.info(`Calculated bounds: ${s}x${l}`),Qe(e,l,s,r);const h=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",h)},ti={draw:(t,e,i)=>{nt.debug("renering svg for syntax error\n");const r=Je(e);r.attr("viewBox","0 0 2412 512"),Qe(r,100,512,!0);const n=r.append("g");n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)}},ei=ti,ii={db:{},renderer:ti,parser:{parser:{yy:{}},parse:()=>{}}},ri="flowchart-elk",ni={id:ri,detector:(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(506),i.e(76),i.e(813),i.e(639)]).then(i.bind(i,1639));return{id:ri,diagram:t}}},oi="timeline",ai={id:oi,detector:t=>/^\s*timeline/.test(t),loader:async()=>{const{diagram:t}=await i.e(940).then(i.bind(i,5940));return{id:oi,diagram:t}}},si="mindmap",li={id:si,detector:t=>/^\s*mindmap/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(506),i.e(662)]).then(i.bind(i,4662));return{id:si,diagram:t}}},hi="sankey",ci={id:hi,detector:t=>/^\s*sankey-beta/.test(t),loader:async()=>{const{diagram:t}=await i.e(579).then(i.bind(i,8579));return{id:hi,diagram:t}}},ui={};let fi="",di="",pi="";const gi=t=>ct(t,ge()),mi=function(){fi="",pi="",di=""},yi=function(t){fi=gi(t).replace(/^\s+/g,"")},_i=function(){return fi||di},bi=function(t){pi=gi(t).replace(/\n\s+/g,"\n")},Ci=function(){return pi},xi=function(t){di=gi(t)},vi=function(){return di},ki={getAccTitle:_i,setAccTitle:yi,getDiagramTitle:vi,setDiagramTitle:xi,getAccDescription:Ci,setAccDescription:bi,clear:mi},Ti=Object.freeze(Object.defineProperty({__proto__:null,clear:mi,default:ki,getAccDescription:Ci,getAccTitle:_i,getDiagramTitle:vi,setAccDescription:bi,setAccTitle:yi,setDiagramTitle:xi},Symbol.toStringTag,{value:"Module"}));let wi={};const Si=function(t,e,i,r){nt.debug("parseDirective is being called",e,i,r);try{if(void 0!==e)switch(e=e.trim(),i){case"open_directive":wi={};break;case"type_directive":if(!wi)throw new Error("currentDirective is undefined");wi.type=e.toLowerCase();break;case"arg_directive":if(!wi)throw new Error("currentDirective is undefined");wi.args=JSON.parse(e);break;case"close_directive":Bi(t,wi,r),wi=void 0}}catch(t){nt.error(`Error while rendering sequenceDiagram directive: ${e} jison context: ${i}`),nt.error(t.message)}},Bi=function(t,e,i){switch(nt.info(`Directive type=${e.type} with args:`,e.args),e.type){case"init":case"initialize":["config"].forEach((t=>{void 0!==e.args[t]&&("flowchart-v2"===i&&(i="flowchart"),e.args[i]=e.args[t],delete e.args[t])})),ye(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;case"themeCss":nt.warn("themeCss encountered");break;default:nt.warn(`Unhandled directive: source: '%%{${e.type}: ${JSON.stringify(e.args?e.args:{})}}%%`,e)}},Fi=nt,Li=ot,Mi=ge,Ai=t=>ct(t,Mi()),Ei=Ke,Zi=(t,e,i,r)=>Si(t,e,i,r),Oi={},qi=(t,e,i)=>{if(Oi[t])throw new Error(`Diagram ${t} already registered.`);var r,n;Oi[t]=e,i&&Ot(t,i),r=t,void 0!==(n=e.styles)&&(ui[r]=n),e.injectUtils&&e.injectUtils(Fi,Li,Mi,Ai,Ei,Ti,Zi)},Ii=t=>{if(t in Oi)return Oi[t];throw new Ni(t)};class Ni extends Error{constructor(t){super(`Diagram ${t} not found.`)}}let Di=!1;const $i=()=>{Di||(Di=!0,qi("error",ii,(t=>"error"===t.toLowerCase().trim())),qi("---",{db:{clear:()=>{}},styles:{},renderer:{},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},(t=>t.toLowerCase().trimStart().startsWith("---"))),Zt(ve,We,Pe,Be,Ae,Ze,Oe,De,ze,ni,Se,Te,li,ai,Le,Ve,He,Xe,Ie,ci))};function zi(t){return null==t}var ji={isNothing:zi,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:zi(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;is&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"→")+a,pos:r-e+o.length}}function Hi(t,e){return ji.repeat(" ",e-t.length)+t}var Yi=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,h="",c=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+c+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=Ui(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),h=ji.repeat(" ",e.indent)+Hi((t.line-s+1).toString(),c)+" | "+l.str+"\n"+h;for(l=Ui(t.buffer,n[a],o[a],t.position,u),h+=ji.repeat(" ",e.indent)+Hi((t.line+1).toString(),c)+" | "+l.str+"\n",h+=ji.repeat("-",e.indent+c+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=Ui(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),h+=ji.repeat(" ",e.indent)+Hi((t.line+s+1).toString(),c)+" | "+l.str+"\n";return h.replace(/\n$/,"")},Vi=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],Gi=["scalar","sequence","mapping"],Xi=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===Vi.indexOf(e))throw new Wi('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===Gi.indexOf(this.kind))throw new Wi('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function Ji(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function Qi(t){return this.extend(t)}Qi.prototype.extend=function(t){var e=[],i=[];if(t instanceof Xi)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new Wi("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof Xi))throw new Wi("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new Wi("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new Wi("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof Xi))throw new Wi("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(Qi.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=Ji(r,"implicit"),r.compiledExplicit=Ji(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),or=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),ar=/^[-+]?[0-9]+e/,sr=new Xi("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!or.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||ji.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(ji.isNegativeZero(t))return"-0.0";return i=t.toString(10),ar.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),lr=Ki.extend({implicit:[tr,er,nr,sr]}),hr=lr,cr=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),ur=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"),fr=new Xi("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==cr.exec(t)||null!==ur.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,h=0,c=null;if(null===(e=cr.exec(t))&&(e=ur.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(h=e[7].slice(0,3);h.length<3;)h+="0";h=+h}return e[9]&&(c=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(c=-c)),l=new Date(Date.UTC(i,r,n,o,a,s,h)),c&&l.setTime(l.getTime()-c),l},instanceOf:Date,represent:function(t){return t.toISOString()}}),dr=new Xi("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),pr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r",gr=new Xi("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=pr;for(i=0;i64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=pr,a=0,s=[];for(e=0;e>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0==(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=pr;for(e=0;e>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0==(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),mr=Object.prototype.hasOwnProperty,yr=Object.prototype.toString,_r=new Xi("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e>10),56320+(t-65536&1023))}for(var Ur=new Array(256),Hr=new Array(256),Yr=0;Yr<256;Yr++)Ur[Yr]=Rr(Yr)?1:0,Hr[Yr]=Rr(Yr);function Vr(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||kr,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Gr(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=Yi(i),new Wi(e,i)}function Xr(t,e){throw Gr(t,e)}function Jr(t,e){t.onWarning&&t.onWarning.call(null,Gr(t,e))}var Qr={YAML:function(t,e,i){var r,n,o;null!==t.version&&Xr(t,"duplication of %YAML directive"),1!==i.length&&Xr(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&Xr(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&Xr(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&Jr(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&Xr(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],qr.test(r)||Xr(t,"ill-formed tag handle (first argument) of the TAG directive"),Tr.call(t.tagMap,r)&&Xr(t,'there is a previously declared suffix for "'+r+'" tag handle'),Ir.test(n)||Xr(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(e){Xr(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function Kr(t,e,i,r){var n,o,a,s;if(e1&&(t.result+=ji.repeat("\n",e-1))}function sn(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,Xr(t,"tab characters must not be used in indentation")),45===r)&&zr(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,nn(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,cn(t,e,Br,!1,!0),a.push(t.result),nn(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)Xr(t,"bad indentation of a sequence entry");else if(t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente)&&(y&&(a=t.line,s=t.lineStart,l=t.position),cn(t,e,Fr,!0,n)&&(y?g=t.result:m=t.result),y||(en(t,f,d,p,g,m,a,s,l),p=g=m=null),nn(t,!0,-1),h=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==h)Xr(t,"bad indentation of a mapping entry");else if(t.lineIndent=0))break;0===n?Xr(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):h?Xr(t,"repeat of an indentation width identifier"):(c=e+n-1,h=!0)}if($r(o)){do{o=t.input.charCodeAt(++t.position)}while($r(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!Dr(o)&&0!==o)}for(;0!==o;){for(rn(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!h||t.lineIndentc&&(c=t.lineIndent),Dr(o))u++;else{if(t.lineIndent0){for(n=a,o=0;n>0;n--)(a=Pr(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:Xr(t,"expected hexadecimal character");t.result+=Wr(o),t.position++}else Xr(t,"unknown escape sequence");i=r=t.position}else Dr(s)?(Kr(t,i,r,!0),an(t,nn(t,!1,e)),i=r=t.position):t.position===t.lineStart&&on(t)?Xr(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}Xr(t,"unexpected end of the stream within a double quoted scalar")}(t,f)?m=!0:function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!zr(r)&&!jr(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Xr(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Tr.call(t.anchorMap,i)||Xr(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],nn(t,!0,-1),!0}(t)?(m=!0,null===t.tag&&null===t.anchor||Xr(t,"alias node should not have any properties")):function(t,e,i){var r,n,o,a,s,l,h,c,u=t.kind,f=t.result;if(zr(c=t.input.charCodeAt(t.position))||jr(c)||35===c||38===c||42===c||33===c||124===c||62===c||39===c||34===c||37===c||64===c||96===c)return!1;if((63===c||45===c)&&(zr(r=t.input.charCodeAt(t.position+1))||i&&jr(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==c;){if(58===c){if(zr(r=t.input.charCodeAt(t.position+1))||i&&jr(r))break}else if(35===c){if(zr(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&on(t)||i&&jr(c))break;if(Dr(c)){if(s=t.line,l=t.lineStart,h=t.lineIndent,nn(t,!1,-1),t.lineIndent>=e){a=!0,c=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=h;break}}a&&(Kr(t,n,o,!1),an(t,t.line-s),n=o=t.position,a=!1),$r(c)||(o=t.position+1),c=t.input.charCodeAt(++t.position)}return Kr(t,n,o,!1),!!t.result||(t.kind=u,t.result=f,!1)}(t,f,wr===i)&&(m=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&sn(t,d))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&Xr(t,'unacceptable node kind for ! tag; it should be "scalar", not "'+t.kind+'"'),l=0,h=t.implicitTypes.length;l"),null!==t.result&&u.kind!==t.kind&&Xr(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):Xr(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function un(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(nn(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!zr(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&Xr(t,"directive name must not be less than one character in length");0!==n;){for(;$r(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!Dr(n));break}if(Dr(n))break;for(e=t.position;0!==n&&!zr(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&rn(t),Tr.call(Qr,i)?Qr[i](t,i,r):Jr(t,'unknown document directive "'+i+'"')}nn(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,nn(t,!0,-1)):a&&Xr(t,"directives end mark is expected"),cn(t,t.lineIndent-1,Fr,!1,!0),nn(t,!0,-1),t.checkLineBreaks&&Zr.test(t.input.slice(o,t.position))&&Jr(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&on(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,nn(t,!0,-1)):t.positionr((t=>t.trimStart().replace(/^\s*%%(?!{)[^\n]+\n?/gm,""))(gn(t,this.db,ye))),this.parser.parser.yy=this.db,this.init=i.init,this.parse()}parse(){var t,e,i;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t),null==(i=this.init)||i.call(this,ge()),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const yn=async t=>{const e=Et(t,ge());try{Ii(e)}catch(t){const i=At[e].loader;if(!i)throw new Mt(`Diagram ${e} not found.`);const{id:r,diagram:n}=await i();qi(r,n)}return new mn(t)};let _n=[];const bn=t=>{_n.push(t)},Cn=["graph","flowchart","flowchart-v2","flowchart-elk","stateDiagram","stateDiagram-v2"],xn=["foreignobject"],vn=["dominant-baseline"],kn=function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},Tn=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,wn=(t,e,i,r)=>{const n=((t,e,i={})=>{var r;let n="";if(void 0!==t.themeCSS&&(n+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(n+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(n+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!(0,it.Z)(i)&&Cn.includes(e)){const e=t.htmlLabels||(null==(r=t.flowchart)?void 0:r.htmlLabels)?["> *","span"]:["rect","polygon","ellipse","circle","path"];for(const t in i){const r=i[t];(0,it.Z)(r.styles)||e.forEach((t=>{n+=Tn(r.id,t,r.styles)})),(0,it.Z)(r.textStyles)||(n+=Tn(r.id,"tspan",r.textStyles))}}return n})(t,e,i);return M(J(`${r}{${((t,e,i)=>{let r="";return t in ui&&ui[t]?r=ui[t](i):nt.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`})(e,n,t.themeVariables)}}`),A)},Sn=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function Bn(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const Fn=Object.freeze({render:async function(t,e,i){var r,n,o,l;$i(),_e(),gn(e,{},ye);const h=oe.detectInit(e);h&&ye(h);const c=ge();nt.debug(c),e.length>((null==c?void 0:c.maxTextSize)??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa"),e=(e=e.replace(/\r\n?/g,"\n")).replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">"));const u="#"+t,f="i"+t,d="#"+f,p="d"+t,g="#"+p;let m=(0,a.Ys)("body");const y="sandbox"===c.securityLevel,_="loose"===c.securityLevel,b=c.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),y){const t=Bn((0,a.Ys)(i),f);m=(0,a.Ys)(t.nodes()[0].contentDocument.body),m.node().style.margin=0}else m=(0,a.Ys)(i);Sn(m,t,p,`font-family: ${b}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,p,f),y){const t=Bn((0,a.Ys)("body"),f);m=(0,a.Ys)(t.nodes()[0].contentDocument.body),m.node().style.margin=0}else m=(0,a.Ys)("body");Sn(m,t,p)}let C,x;e=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"fl°°"+e+"¶ß":"fl°"+e+"¶ß"})),e}(e);try{C=await yn(e)}catch(t){C=new mn("error"),x=t}const v=m.select(g).node(),k=C.type,T=v.firstChild,w=T.firstChild,S=Cn.includes(k)?C.renderer.getClasses(e,C):{},B=wn(c,k,S,u),F=document.createElement("style");F.innerHTML=B,T.insertBefore(F,w);try{await C.renderer.draw(e,t,ae,C)}catch(i){throw ei.draw(e,t,ae),i}!function(t,e,i,r){(function(t,e){t.attr("role","graphics-document document"),""!==e&&t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert){if(i){const e=`chart-desc-${r}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i=`chart-title-${r}`;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(k,m.select(`${g} svg`),null==(n=(r=C.db).getAccTitle)?void 0:n.call(r),null==(l=(o=C.db).getAccDescription)?void 0:l.call(o)),m.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let L=m.select(g).node().innerHTML;if(nt.debug("config.arrowMarkerAbsolute",c.arrowMarkerAbsolute),L=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),r=kn(r),r=r.replace(/
        /g,"
        "),r})(L,y,dt(c.arrowMarkerAbsolute)),y?L=((t="",e)=>{var i,r;return``})(L,m.select(g+" svg").node()):_||(L=s.sanitize(L,{ADD_TAGS:xn,ADD_ATTR:vn})),_n.forEach((t=>{t()})),_n=[],x)throw x;const M=y?d:g,A=(0,a.Ys)(M).node();return A&&"remove"in A&&A.remove(),{svg:L,bindFunctions:C.db.bindFunctions}},parse:async function(t,e){$i();try{await yn(t)}catch(t){if(null==e?void 0:e.suppressErrors)return!1;throw t}return!0},parseDirective:Si,getDiagramFromText:yn,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),le=It({},t),(null==t?void 0:t.theme)&&t.theme in xt?t.themeVariables=xt[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=xt.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(r=t,he=It({},se),he=It(he,r),r.theme&&xt[r.theme]&&(he.themeVariables=xt[r.theme].getThemeVariables(r.themeVariables)),fe(he,ce),he):de();var r;ot(i.logLevel),$i()},getConfig:ge,setConfig:pe,getSiteConfig:de,updateSiteConfig:t=>(he=It(he,t),fe(he,ce),he),reset:()=>{_e()},globalReset:()=>{_e(se)},defaultConfig:se});ot(ge().logLevel),_e(ge());const Ln=(t,e,i)=>{nt.warn(t),ie(t)?(i&&i(t.str,t.hash),e.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},Mn=async function(t={querySelector:".mermaid"}){try{await An(t)}catch(e){if(ie(e)&&nt.error(e.str),Dn.parseError&&Dn.parseError(e),!t.suppressErrors)throw nt.error("Use the suppressErrors option to suppress these errors"),e}},An=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const n=Fn.getConfig();let o;if(nt.debug((t?"":"No ")+"Callback function found"),i)o=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");o=document.querySelectorAll(e)}nt.debug(`Found ${o.length} diagrams`),void 0!==(null==n?void 0:n.startOnLoad)&&(nt.debug("Start On Load: "+(null==n?void 0:n.startOnLoad)),Fn.updateSiteConfig({startOnLoad:null==n?void 0:n.startOnLoad}));const a=new oe.initIdGenerator(n.deterministicIds,n.deterministicIDSeed);let s;const l=[];for(const e of Array.from(o)){if(nt.info("Rendering diagram: "+e.id),e.getAttribute("data-processed"))continue;e.setAttribute("data-processed","true");const i=`mermaid-${a.next()}`;s=e.innerHTML,s=(0,r.Z)(oe.entityDecode(s)).trim().replace(//gi,"
        ");const n=oe.detectInit(s);n&&nt.debug("Detected early reinit: ",n);try{const{svg:r,bindFunctions:n}=await Nn(i,s,e);e.innerHTML=r,t&&await t(i),n&&n(e)}catch(t){Ln(t,l,Dn.parseError)}}if(l.length>0)throw l[0]},En=function(t){Fn.initialize(t)},Zn=function(){if(Dn.startOnLoad){const{startOnLoad:t}=Fn.getConfig();t&&Dn.run().catch((t=>nt.error("Mermaid failed to initialize",t)))}};"undefined"!=typeof document&&window.addEventListener("load",Zn,!1);const On=[];let qn=!1;const In=async()=>{if(!qn){for(qn=!0;On.length>0;){const t=On.shift();if(t)try{await t()}catch(t){nt.error("Error executing queue",t)}}qn=!1}},Nn=(t,e,i)=>new Promise(((r,n)=>{On.push((()=>new Promise(((o,a)=>{Fn.render(t,e,i).then((t=>{o(t),r(t)}),(t=>{var e;nt.error("Error parsing",t),null==(e=Dn.parseError)||e.call(Dn,t),a(t),n(t)}))})))),In().catch(n)})),Dn={startOnLoad:!0,mermaidAPI:Fn,parse:async(t,e)=>new Promise(((i,r)=>{On.push((()=>new Promise(((n,o)=>{Fn.parse(t,e).then((t=>{n(t),i(t)}),(t=>{var e;nt.error("Error parsing",t),null==(e=Dn.parseError)||e.call(Dn,t),o(t),r(t)}))})))),In().catch(r)})),render:Nn,init:async function(t,e,i){nt.warn("mermaid.init is deprecated. Please use run instead."),t&&En(t);const r={postRenderCallback:i,querySelector:".mermaid"};"string"==typeof e?r.querySelector=e:e&&(e instanceof HTMLElement?r.nodes=[e]:r.nodes=e),await Mn(r)},run:Mn,registerExternalDiagrams:async(t,{lazyLoad:e=!0}={})=>{Zt(...t),!1===e&&await(async()=>{nt.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(At).map((async([t,{detector:e,loader:i}])=>{if(i)try{Ii(t)}catch(r){try{const{diagram:t,id:r}=await i();qi(r,t,e)}catch(e){throw nt.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete At[t],e}}})))).filter((t=>"rejected"===t.status));if(t.length>0){nt.error(`Failed to load ${t.length} external diagrams`);for(const e of t)nt.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}})()},initialize:En,parseError:void 0,contentLoaded:Zn,setParseErrorHandler:function(t){Dn.parseError=t},detectType:Et}},6637:function(t,e,i){"use strict";i.r(e),i.d(e,{default:function(){return r.N}});var r=i(9339);i(7484),i(7967),i(7274),i(7856)}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js.LICENSE.txt b/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js.LICENSE.txt new file mode 100644 index 000000000..8e6284a61 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/637-86fbbecd.chunk.min.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! + * Wait for document loaded before starting the execution + */ + +/*! @license DOMPurify 3.0.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.5/LICENSE */ + +/*! Check if previously processed */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/docs/themes/hugo-geekdoc/static/js/639-88c6538a.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/639-88c6538a.chunk.min.js new file mode 100644 index 000000000..eda79db14 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/639-88c6538a.chunk.min.js @@ -0,0 +1 @@ +(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[639],{7295:function(n,t,e){n.exports=function n(t,e,i){function r(a,u){if(!e[a]){if(!t[a]){if(c)return c(a,!0);var o=new Error("Cannot find module '"+a+"'");throw o.code="MODULE_NOT_FOUND",o}var s=e[a]={exports:{}};t[a][0].call(s.exports,(function(n){return r(t[a][1][n]||n)}),s,s.exports,n,t,e,i)}return e[a].exports}for(var c=void 0,a=0;a0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,u=e.algorithms,o=void 0===u?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:u,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:o}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,u=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:u}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,i){(function(n){(function(){"use strict";var e;function r(){}function c(){}function a(){}function u(){}function o(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function v(){}function m(){}function y(){}function k(){}function j(){}function E(){}function T(){}function M(){}function S(){}function P(){}function I(){}function C(){}function O(){}function A(){}function $(){}function L(){}function N(){}function x(){}function D(){}function R(){}function K(){}function _(){}function F(){}function B(){}function H(){}function q(){}function G(){}function z(){}function U(){}function X(){}function W(){}function V(){}function Q(){}function Y(){}function J(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function un(){}function on(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function vn(){}function mn(){}function yn(){}function kn(){}function jn(){}function En(){}function Tn(){}function Mn(){}function Sn(){}function Pn(){}function In(){}function Cn(){}function On(){}function An(){}function $n(){}function Ln(){}function Nn(){}function xn(){}function Dn(){}function Rn(){}function Kn(){}function _n(){}function Fn(){}function Bn(){}function Hn(){}function qn(){}function Gn(){}function zn(){}function Un(){}function Xn(){}function Wn(){}function Vn(){}function Qn(){}function Yn(){}function Jn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ut(){}function ot(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function vt(){}function mt(){}function yt(){}function kt(){}function jt(){}function Et(){}function Tt(){}function Mt(){}function St(){}function Pt(){}function It(){}function Ct(){}function Ot(){}function At(){}function $t(){}function Lt(){}function Nt(){}function xt(){}function Dt(){}function Rt(){}function Kt(){}function _t(){}function Ft(){}function Bt(){}function Ht(){}function qt(){}function Gt(){}function zt(){}function Ut(){}function Xt(){}function Wt(){}function Vt(){}function Qt(){}function Yt(){}function Jt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function ue(){}function oe(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function ve(){}function me(){}function ye(){}function ke(){}function je(){}function Ee(){}function Te(){}function Me(){}function Se(){}function Pe(){}function Ie(){}function Ce(){}function Oe(){}function Ae(){}function $e(){}function Le(){}function Ne(){}function xe(){}function De(){}function Re(){}function Ke(){}function _e(){}function Fe(){}function Be(){}function He(){}function qe(){}function Ge(){}function ze(){}function Ue(){}function Xe(){}function We(){}function Ve(){}function Qe(){}function Ye(){}function Je(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function ui(){}function oi(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function vi(){}function mi(){}function yi(){}function ki(){}function ji(){}function Ei(){}function Ti(){}function Mi(){}function Si(){}function Pi(){}function Ii(){}function Ci(){}function Oi(){}function Ai(){}function $i(){}function Li(){}function Ni(){}function xi(){}function Di(){}function Ri(){}function Ki(){}function _i(){}function Fi(){}function Bi(){}function Hi(){}function qi(){}function Gi(){}function zi(){}function Ui(){}function Xi(){}function Wi(){}function Vi(){}function Qi(){}function Yi(){}function Ji(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function ur(){}function or(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function vr(){}function mr(){}function yr(){}function kr(){}function jr(){}function Er(){}function Tr(){}function Mr(){}function Sr(){}function Pr(){}function Ir(){}function Cr(){}function Or(){}function Ar(){}function $r(){}function Lr(){}function Nr(){}function xr(){}function Dr(){}function Rr(){}function Kr(){}function _r(){}function Fr(){}function Br(){}function Hr(){}function qr(){}function Gr(){}function zr(){}function Ur(){}function Xr(){}function Wr(){}function Vr(){}function Qr(){}function Yr(){}function Jr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function uc(){}function oc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function vc(){}function mc(){}function yc(){}function kc(){}function jc(){}function Ec(){}function Tc(){}function Mc(){}function Sc(){}function Pc(){}function Ic(){}function Cc(){}function Oc(){}function Ac(){}function $c(){}function Lc(){}function Nc(){}function xc(){}function Dc(){}function Rc(){}function Kc(){}function _c(){}function Fc(){}function Bc(){}function Hc(){}function qc(){}function Gc(){}function zc(){}function Uc(){}function Xc(){}function Wc(){}function Vc(){}function Qc(){}function Yc(){}function Jc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function ua(){}function oa(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function va(){}function ma(){}function ya(){}function ka(){}function ja(){}function Ea(){}function Ta(){}function Ma(){}function Sa(){}function Pa(){}function Ia(){}function Ca(){}function Oa(){}function Aa(){}function $a(){}function La(){}function Na(){}function xa(){}function Da(){}function Ra(){}function Ka(){}function _a(){}function Fa(){}function Ba(){}function Ha(){}function qa(){}function Ga(){}function za(){}function Ua(){}function Xa(){}function Wa(){}function Va(){}function Qa(){}function Ya(){}function Ja(){}function Za(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function uu(){}function ou(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function vu(){}function mu(){}function yu(){}function ku(){}function ju(){}function Eu(){}function Tu(){}function Mu(){}function Su(){}function Pu(){}function Iu(){}function Cu(){}function Ou(){}function Au(){}function $u(){}function Lu(){}function Nu(){}function xu(){}function Du(){}function Ru(){}function Ku(){}function _u(){}function Fu(){}function Bu(){}function Hu(){}function qu(){}function Gu(){}function zu(){}function Uu(){}function Xu(){}function Wu(){}function Vu(){}function Qu(){}function Yu(){}function Ju(){}function Zu(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function uo(){}function oo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function vo(){}function mo(){}function yo(){}function ko(){}function jo(){}function Eo(){}function To(){}function Mo(){}function So(){}function Po(){}function Io(){}function Co(){}function Oo(){}function Ao(){}function $o(){}function Lo(){}function No(){}function xo(){}function Do(){}function Ro(){}function Ko(){}function _o(){}function Fo(){}function Bo(){}function Ho(){}function qo(){}function Go(){}function zo(){}function Uo(){}function Xo(){}function Wo(){}function Vo(){}function Qo(){}function Yo(){}function Jo(){}function Zo(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function us(){}function os(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function vs(){}function ms(){}function ys(){}function ks(){}function js(){}function Es(){}function Ts(){}function Ms(){}function Ss(){}function Ps(){}function Is(){}function Cs(){}function Os(){}function As(){}function $s(){}function Ls(){}function Ns(){}function xs(){}function Ds(){}function Rs(){}function Ks(){}function _s(){}function Fs(){}function Bs(){}function Hs(){}function qs(){}function Gs(){}function zs(){}function Us(){}function Xs(){}function Ws(){}function Vs(){}function Qs(){}function Ys(){}function Js(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function uh(){}function oh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function vh(){}function mh(){}function yh(){}function kh(){}function jh(){}function Eh(){}function Th(){}function Mh(){}function Sh(){}function Ph(){}function Ih(){}function Ch(){}function Oh(){}function Ah(){}function $h(){}function Lh(){}function Nh(){}function xh(){}function Dh(){}function Rh(){}function Kh(){}function _h(){gm()}function Fh(){O6()}function Bh(){len()}function Hh(){pcn()}function qh(){Eon()}function Gh(){Bdn()}function zh(){Lrn()}function Uh(){Wrn()}function Xh(){QE()}function Wh(){UE()}function Vh(){Ax()}function Qh(){YE()}function Yh(){m2()}function Jh(){ZE()}function Zh(){eQ()}function nf(){P0()}function tf(){uY()}function ef(){oz()}function rf(){A6()}function cf(){Qun()}function af(){I0()}function uf(){gX()}function of(){Ajn()}function sf(){Rrn()}function hf(){sz()}function ff(){gjn()}function lf(){az()}function bf(){C0()}function wf(){e5()}function df(){bz()}function gf(){MY()}function pf(){nT()}function vf(){lln()}function mf(){_rn()}function yf(){b3()}function kf(){Dun()}function jf(){Hdn()}function Ef(){lin()}function Tf(){cln()}function Mf(){i4()}function Sf(){fz()}function Pf(){epn()}function If(){uln()}function Cf(){Jln()}function Of(){IY()}function Af(){Run()}function $f(){Cjn()}function Lf(){L6()}function Nf(){Onn()}function xf(){Jvn()}function Df(){dx()}function Rf(){W2()}function Kf(){Fpn()}function _f(n){vB(n)}function Ff(n){this.a=n}function Bf(n){this.a=n}function Hf(n){this.a=n}function qf(n){this.a=n}function Gf(n){this.a=n}function zf(n){this.a=n}function Uf(n){this.a=n}function Xf(n){this.a=n}function Wf(n){this.a=n}function Vf(n){this.a=n}function Qf(n){this.a=n}function Yf(n){this.a=n}function Jf(n){this.a=n}function Zf(n){this.a=n}function nl(n){this.a=n}function tl(n){this.a=n}function el(n){this.a=n}function il(n){this.a=n}function rl(n){this.a=n}function cl(n){this.a=n}function al(n){this.a=n}function ul(n){this.b=n}function ol(n){this.c=n}function sl(n){this.a=n}function hl(n){this.a=n}function fl(n){this.a=n}function ll(n){this.a=n}function bl(n){this.a=n}function wl(n){this.a=n}function dl(n){this.a=n}function gl(n){this.a=n}function pl(n){this.a=n}function vl(n){this.a=n}function ml(n){this.a=n}function yl(n){this.a=n}function kl(n){this.a=n}function jl(n){this.a=n}function El(n){this.a=n}function Tl(n){this.a=n}function Ml(n){this.a=n}function Sl(){this.a=[]}function Pl(n,t){n.a=t}function Il(n,t){n.j=t}function Cl(n,t){n.c=t}function Ol(n,t){n.d=t}function Al(n,t){n.k=t}function $l(n,t){n.c=t}function Ll(n,t){n.a=t}function Nl(n,t){n.a=t}function xl(n,t){n.f=t}function Dl(n,t){n.a=t}function Rl(n,t){n.b=t}function Kl(n,t){n.d=t}function _l(n,t){n.i=t}function Fl(n,t){n.o=t}function Bl(n,t){n.e=t}function Hl(n,t){n.g=t}function ql(n,t){n.e=t}function Gl(n,t){n.f=t}function zl(n,t){n.f=t}function Ul(n,t){n.n=t}function Xl(n){n.b=n.a}function Wl(n){n.c=n.d.d}function Vl(n){this.d=n}function Ql(n){this.a=n}function Yl(n){this.a=n}function Jl(n){this.a=n}function Zl(n){this.a=n}function nb(n){this.a=n}function tb(n){this.a=n}function eb(n){this.a=n}function ib(n){this.a=n}function rb(n){this.a=n}function cb(n){this.a=n}function ab(n){this.a=n}function ub(n){this.a=n}function ob(n){this.a=n}function sb(n){this.a=n}function hb(n){this.b=n}function fb(n){this.b=n}function lb(n){this.b=n}function bb(n){this.a=n}function wb(n){this.a=n}function db(n){this.a=n}function gb(n){this.c=n}function pb(n){this.c=n}function vb(n){this.c=n}function mb(n){this.a=n}function yb(n){this.a=n}function kb(n){this.a=n}function jb(n){this.a=n}function Eb(n){this.a=n}function Tb(n){this.a=n}function Mb(n){this.a=n}function Sb(n){this.a=n}function Pb(n){this.a=n}function Ib(n){this.a=n}function Cb(n){this.a=n}function Ob(n){this.a=n}function Ab(n){this.a=n}function $b(n){this.a=n}function Lb(n){this.a=n}function Nb(n){this.a=n}function xb(n){this.a=n}function Db(n){this.a=n}function Rb(n){this.a=n}function Kb(n){this.a=n}function _b(n){this.a=n}function Fb(n){this.a=n}function Bb(n){this.a=n}function Hb(n){this.a=n}function qb(n){this.a=n}function Gb(n){this.a=n}function zb(n){this.a=n}function Ub(n){this.a=n}function Xb(n){this.a=n}function Wb(n){this.a=n}function Vb(n){this.a=n}function Qb(n){this.a=n}function Yb(n){this.a=n}function Jb(n){this.a=n}function Zb(n){this.a=n}function nw(n){this.a=n}function tw(n){this.a=n}function ew(n){this.a=n}function iw(n){this.a=n}function rw(n){this.a=n}function cw(n){this.a=n}function aw(n){this.a=n}function uw(n){this.a=n}function ow(n){this.a=n}function sw(n){this.a=n}function hw(n){this.e=n}function fw(n){this.a=n}function lw(n){this.a=n}function bw(n){this.a=n}function ww(n){this.a=n}function dw(n){this.a=n}function gw(n){this.a=n}function pw(n){this.a=n}function vw(n){this.a=n}function mw(n){this.a=n}function yw(n){this.a=n}function kw(n){this.a=n}function jw(n){this.a=n}function Ew(n){this.a=n}function Tw(n){this.a=n}function Mw(n){this.a=n}function Sw(n){this.a=n}function Pw(n){this.a=n}function Iw(n){this.a=n}function Cw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function $w(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function xw(n){this.a=n}function Dw(n){this.a=n}function Rw(n){this.a=n}function Kw(n){this.a=n}function _w(n){this.a=n}function Fw(n){this.a=n}function Bw(n){this.a=n}function Hw(n){this.a=n}function qw(n){this.a=n}function Gw(n){this.a=n}function zw(n){this.a=n}function Uw(n){this.a=n}function Xw(n){this.a=n}function Ww(n){this.a=n}function Vw(n){this.a=n}function Qw(n){this.a=n}function Yw(n){this.a=n}function Jw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function ud(n){this.a=n}function od(n){this.a=n}function sd(n){this.a=n}function hd(n){this.c=n}function fd(n){this.b=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function vd(n){this.a=n}function md(n){this.a=n}function yd(n){this.a=n}function kd(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Td(n){this.a=n}function Md(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Id(n){this.a=n}function Cd(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function $d(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function xd(n){this.a=n}function Dd(n){this.a=n}function Rd(n){this.a=n}function Kd(n){this.a=n}function _d(n){this.a=n}function Fd(n){this.a=n}function Bd(n){this.a=n}function Hd(n){this.a=n}function qd(n){this.a=n}function Gd(n){this.a=n}function zd(n){this.a=n}function Ud(n){this.a=n}function Xd(n){this.a=n}function Wd(n){this.a=n}function Vd(n){this.a=n}function Qd(n){this.a=n}function Yd(n){this.a=n}function Jd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function ug(n){this.a=n}function og(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function vg(n){this.a=n}function mg(n){this.a=n}function yg(n){this.a=n}function kg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Tg(n){this.a=n}function Mg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Ig(n){this.a=n}function Cg(n){this.a=n}function Og(n){this.b=n}function Ag(n){this.f=n}function $g(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function xg(n){this.a=n}function Dg(n){this.a=n}function Rg(n){this.a=n}function Kg(n){this.a=n}function _g(n){this.a=n}function Fg(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function qg(n){this.b=n}function Gg(n){this.c=n}function zg(n){this.e=n}function Ug(n){this.a=n}function Xg(n){this.a=n}function Wg(n){this.a=n}function Vg(n){this.a=n}function Qg(n){this.a=n}function Yg(n){this.d=n}function Jg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.e=n}function tp(){this.a=0}function ep(){$C(this)}function ip(){AC(this)}function rp(){U_(this)}function cp(){QB(this)}function ap(){}function up(){this.c=Wat}function op(n,t){n.b+=t}function sp(n){n.b=new gy}function hp(n){return n.e}function fp(n){return n.a}function lp(n){return n.a}function bp(n){return n.a}function wp(n){return n.a}function dp(n){return n.a}function gp(){return null}function pp(){return null}function vp(n,t){n.b=t-n.b}function mp(n,t){n.a=t-n.a}function yp(n,t){t.ad(n.a)}function kp(n,t){n.e=t,t.b=n}function jp(n){px(),this.a=n}function Ep(n){px(),this.a=n}function Tp(n){px(),this.a=n}function Mp(n){VF(),this.a=n}function Sp(n){$q(),p_n.be(n)}function Pp(){OA.call(this)}function Ip(){OA.call(this)}function Cp(){Pp.call(this)}function Op(){Pp.call(this)}function Ap(){Pp.call(this)}function $p(){Pp.call(this)}function Lp(){Pp.call(this)}function Np(){Pp.call(this)}function xp(){Pp.call(this)}function Dp(){Pp.call(this)}function Rp(){Pp.call(this)}function Kp(){Pp.call(this)}function _p(){Pp.call(this)}function Fp(){this.a=this}function Bp(){this.Bb|=256}function Hp(){this.b=new xI}function qp(){qp=O,new rp}function Gp(){Cp.call(this)}function zp(n,t){n.length=t}function Up(n,t){eD(n.a,t)}function Xp(n,t){K3(n.e,t)}function Wp(n){kfn(n.c,n.b)}function Vp(n){this.a=function(n){var t;return(t=gon(n))>34028234663852886e22?JTn:t<-34028234663852886e22?ZTn:t}(n)}function Qp(){this.a=new rp}function Yp(){this.a=new rp}function Jp(){this.a=new ip}function Zp(){this.a=new ip}function nv(){this.a=new ip}function tv(){this.a=new kn}function ev(){this.a=new WV}function iv(){this.a=new bt}function rv(){this.a=new jE}function cv(){this.a=new gU}function av(){this.a=new NG}function uv(){this.a=new aN}function ov(){this.a=new ip}function sv(){this.a=new ip}function hv(){this.a=new ip}function fv(){this.a=new ip}function lv(){this.d=new ip}function bv(){this.a=new Qp}function wv(){this.a=new rp}function dv(){this.b=new rp}function gv(){this.b=new ip}function pv(){this.e=new ip}function vv(){this.d=new ip}function mv(){this.a=new cf}function yv(){ip.call(this)}function kv(){Jp.call(this)}function jv(){sN.call(this)}function Ev(){sv.call(this)}function Tv(){Mv.call(this)}function Mv(){ap.call(this)}function Sv(){ap.call(this)}function Pv(){Sv.call(this)}function Iv(){Eq.call(this)}function Cv(){Eq.call(this)}function Ov(){um.call(this)}function Av(){um.call(this)}function $v(){um.call(this)}function Lv(){om.call(this)}function Nv(){ME.call(this)}function xv(){eo.call(this)}function Dv(){eo.call(this)}function Rv(){bm.call(this)}function Kv(){bm.call(this)}function _v(){rp.call(this)}function Fv(){rp.call(this)}function Bv(){rp.call(this)}function Hv(){Qp.call(this)}function qv(){T0.call(this)}function Gv(){Bp.call(this)}function zv(){zO.call(this)}function Uv(){zO.call(this)}function Xv(){rp.call(this)}function Wv(){rp.call(this)}function Vv(){rp.call(this)}function Qv(){yo.call(this)}function Yv(){yo.call(this)}function Jv(){Qv.call(this)}function Zv(){Dh.call(this)}function nm(n){_Z.call(this,n)}function tm(n){_Z.call(this,n)}function em(n){Wf.call(this,n)}function im(n){tE.call(this,n)}function rm(n){im.call(this,n)}function cm(n){tE.call(this,n)}function am(){this.a=new ME}function um(){this.a=new Qp}function om(){this.a=new rp}function sm(){this.a=new ip}function hm(){this.j=new ip}function fm(){this.a=new Xa}function lm(){this.a=new bj}function bm(){this.a=new mo}function wm(){wm=O,n_n=new Ky}function dm(){dm=O,ZKn=new Ry}function gm(){gm=O,zKn=new c}function pm(){pm=O,a_n=new mA}function vm(n){im.call(this,n)}function mm(n){im.call(this,n)}function ym(n){hW.call(this,n)}function km(n){hW.call(this,n)}function jm(n){ix.call(this,n)}function Em(n){kon.call(this,n)}function Tm(n){rE.call(this,n)}function Mm(n){aE.call(this,n)}function Sm(n){aE.call(this,n)}function Pm(n){aE.call(this,n)}function Im(n){xK.call(this,n)}function Cm(n){Im.call(this,n)}function Om(){Ml.call(this,{})}function Am(n){qO(),this.a=n}function $m(n){n.b=null,n.c=0}function Lm(n,t){n.a=t,function(n){var t,i,r;for(function(n){var t,i,r;for(i=new pb(n.a.a.b);i.a0&&((!lC(n.a.c)||!t.n.d)&&(!bC(n.a.c)||!t.n.b)&&(t.g.d-=e.Math.max(0,r/2-.5)),(!lC(n.a.c)||!t.n.a)&&(!bC(n.a.c)||!t.n.c)&&(t.g.a+=e.Math.max(0,r-1)))}(n),r=new ip,i=new pb(n.a.a.b);i.a0&&((!lC(n.a.c)||!t.n.d)&&(!bC(n.a.c)||!t.n.b)&&(t.g.d+=e.Math.max(0,r/2-.5)),(!lC(n.a.c)||!t.n.a)&&(!bC(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}(n)}(n)}function Nm(n,t,e){n.a[t.g]=e}function xm(n,t,e){!function(n,t,e){var i,r;for(TC(n,n.j+t,n.k+e),r=new UO((!n.a&&(n.a=new XO(Qrt,n,5)),n.a));r.e!=r.i.gc();)yC(i=Yx(hen(r),469),i.a+t,i.b+e);EC(n,n.b+t,n.c+e)}(e,n,t)}function Dm(n,t){!function(n,t){lC(n.f)?function(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new pb(n.d);i.a=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},function(){if(!Object.create||!Object.getOwnPropertyNames)return!1;var n="__proto__",t=Object.create(null);return void 0===t[n]&&0==Object.getOwnPropertyNames(t).length&&(t[n]=42,42===t[n]&&0!=Object.getOwnPropertyNames(t).length)}()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[vMn]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}()}()}function By(n){return n.a?n.b:0}function Hy(n){return n.a?n.b:0}function qy(n,t){return aJ(n,t)}function Gy(n,t){return qG(n,t)}function zy(n,t){return n.f=t,n}function Uy(n,t){return n.c=t,n}function Xy(n,t){return n.a=t,n}function Wy(n,t){return n.f=t,n}function Vy(n,t){return n.k=t,n}function Qy(n,t){return n.a=t,n}function Yy(n,t){return n.e=t,n}function Jy(n,t){n.b=!0,n.d=t}function Zy(n,t){return n?0:t-1}function nk(n,t){return n.b=t,n}function tk(n,t){return n.a=t,n}function ek(n,t){return n.c=t,n}function ik(n,t){return n.d=t,n}function rk(n,t){return n.e=t,n}function ck(n,t){return n.f=t,n}function ak(n,t){return n.a=t,n}function uk(n,t){return n.b=t,n}function ok(n,t){return n.c=t,n}function sk(n,t){return n.c=t,n}function hk(n,t){return n.b=t,n}function fk(n,t){return n.d=t,n}function lk(n,t){return n.e=t,n}function bk(n,t){return n.g=t,n}function wk(n,t){return n.a=t,n}function dk(n,t){return n.i=t,n}function gk(n,t){return n.j=t,n}function pk(n,t){return n.k=t,n}function vk(n,t,e){!function(n,t,e){__(n,new ZT(t.a,e.a))}(n.a,t,e)}function mk(n){wH.call(this,n)}function yk(n){wH.call(this,n)}function kk(n){ox.call(this,n)}function jk(n){O7.call(this,n)}function Ek(n){FZ.call(this,n)}function Tk(n){KH.call(this,n)}function Mk(n){KH.call(this,n)}function Sk(){sO.call(this,"")}function Pk(){this.a=0,this.b=0}function Ik(){this.b=0,this.a=0}function Ck(n,t){n.b=0,F1(n,t)}function Ok(n,t){return n.c._b(t)}function Ak(n){return n.e&&n.e()}function $k(n){return n?n.d:null}function Lk(n,t){return R8(n.b,t)}function Nk(n){return sL(n),n.o}function xk(){xk=O,Ort=function(){var n,t;Jvn();try{if(t=Yx(Jcn((mT(),aat),xNn),2014))return t}catch(t){if(!CO(t=j4(t),102))throw hp(t);n=t,AK((GC(),n))}return new ao}()}function Dk(){var n;Dk=O,Art=sct?Yx(Hln((mT(),aat),xNn),2016):(n=Yx(CO(aG((mT(),aat),xNn),555)?aG(aat,xNn):new Gfn,555),sct=!0,function(n){n.q||(n.q=!0,n.p=q3(n,0),n.a=q3(n,1),P2(n.a,0),n.f=q3(n,2),P2(n.f,1),S2(n.f,2),n.n=q3(n,3),S2(n.n,3),S2(n.n,4),S2(n.n,5),S2(n.n,6),n.g=q3(n,4),P2(n.g,7),S2(n.g,8),n.c=q3(n,5),P2(n.c,7),P2(n.c,8),n.i=q3(n,6),P2(n.i,9),P2(n.i,10),P2(n.i,11),P2(n.i,12),S2(n.i,13),n.j=q3(n,7),P2(n.j,9),n.d=q3(n,8),P2(n.d,3),P2(n.d,4),P2(n.d,5),P2(n.d,6),S2(n.d,7),S2(n.d,8),S2(n.d,9),S2(n.d,10),n.b=q3(n,9),S2(n.b,0),S2(n.b,1),n.e=q3(n,10),S2(n.e,1),S2(n.e,2),S2(n.e,3),S2(n.e,4),P2(n.e,5),P2(n.e,6),P2(n.e,7),P2(n.e,8),P2(n.e,9),P2(n.e,10),S2(n.e,11),n.k=q3(n,11),S2(n.k,0),S2(n.k,1),n.o=G3(n,12),n.s=G3(n,13))}(n),function(n){var t,e,i,r,c,a,u;n.r||(n.r=!0,E2(n,"graph"),T2(n,"graph"),M2(n,xNn),g4(n.o,"T"),fY(Iq(n.a),n.p),fY(Iq(n.f),n.a),fY(Iq(n.n),n.f),fY(Iq(n.g),n.n),fY(Iq(n.c),n.n),fY(Iq(n.i),n.c),fY(Iq(n.j),n.c),fY(Iq(n.d),n.f),fY(Iq(n.e),n.a),TU(n.p,uqn,zSn,!0,!0,!1),u=$4(a=o6(n.p,n.p,"setProperty")),t=SH(n.o),e=new up,fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),van(e,i=PH(u)),Ycn(a,t,RNn),Ycn(a,t=PH(u),KNn),u=$4(a=o6(n.p,null,"getProperty")),t=SH(n.o),e=PH(u),fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),Ycn(a,t,RNn),(c=fun(a,t=PH(u),null))&&c.Fi(),a=o6(n.p,n.wb.e,"hasProperty"),t=SH(n.o),e=new up,fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),Ycn(a,t,RNn),Crn(a=o6(n.p,n.p,"copyProperties"),n.p,_Nn),a=o6(n.p,null,"getAllProperties"),t=SH(n.wb.P),e=SH(n.o),fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),i=new up,fY((!e.d&&(e.d=new XO(hat,e,1)),e.d),i),e=SH(n.wb.M),fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),(r=fun(a,t,null))&&r.Fi(),TU(n.a,Vrt,aNn,!0,!1,!0),Prn(Yx(c1(aq(n.a),0),18),n.k,null,FNn,0,-1,Vrt,!1,!1,!0,!0,!1,!1,!1),TU(n.f,Yrt,oNn,!0,!1,!0),Prn(Yx(c1(aq(n.f),0),18),n.g,Yx(c1(aq(n.g),0),18),"labels",0,-1,Yrt,!1,!1,!0,!0,!1,!1,!1),z2(Yx(c1(aq(n.f),1),34),n.wb._,BNn,null,0,1,Yrt,!1,!1,!0,!1,!0,!1),TU(n.n,Jrt,"ElkShape",!0,!1,!0),z2(Yx(c1(aq(n.n),0),34),n.wb.t,HNn,sMn,1,1,Jrt,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.n),1),34),n.wb.t,qNn,sMn,1,1,Jrt,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.n),2),34),n.wb.t,"x",sMn,1,1,Jrt,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.n),3),34),n.wb.t,"y",sMn,1,1,Jrt,!1,!1,!0,!1,!0,!1),Crn(a=o6(n.n,null,"setDimensions"),n.wb.t,qNn),Crn(a,n.wb.t,HNn),Crn(a=o6(n.n,null,"setLocation"),n.wb.t,"x"),Crn(a,n.wb.t,"y"),TU(n.g,act,wNn,!1,!1,!0),Prn(Yx(c1(aq(n.g),0),18),n.f,Yx(c1(aq(n.f),0),18),GNn,0,1,act,!1,!1,!0,!1,!1,!1,!1),z2(Yx(c1(aq(n.g),1),34),n.wb._,zNn,"",0,1,act,!1,!1,!0,!1,!0,!1),TU(n.c,Zrt,sNn,!0,!1,!0),Prn(Yx(c1(aq(n.c),0),18),n.d,Yx(c1(aq(n.d),1),18),"outgoingEdges",0,-1,Zrt,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.c),1),18),n.d,Yx(c1(aq(n.d),2),18),"incomingEdges",0,-1,Zrt,!1,!1,!0,!1,!0,!1,!1),TU(n.i,uct,dNn,!1,!1,!0),Prn(Yx(c1(aq(n.i),0),18),n.j,Yx(c1(aq(n.j),0),18),"ports",0,-1,uct,!1,!1,!0,!0,!1,!1,!1),Prn(Yx(c1(aq(n.i),1),18),n.i,Yx(c1(aq(n.i),2),18),UNn,0,-1,uct,!1,!1,!0,!0,!1,!1,!1),Prn(Yx(c1(aq(n.i),2),18),n.i,Yx(c1(aq(n.i),1),18),GNn,0,1,uct,!1,!1,!0,!1,!1,!1,!1),Prn(Yx(c1(aq(n.i),3),18),n.d,Yx(c1(aq(n.d),0),18),"containedEdges",0,-1,uct,!1,!1,!0,!0,!1,!1,!1),z2(Yx(c1(aq(n.i),4),34),n.wb.e,XNn,null,0,1,uct,!0,!0,!1,!1,!0,!0),TU(n.j,oct,gNn,!1,!1,!0),Prn(Yx(c1(aq(n.j),0),18),n.i,Yx(c1(aq(n.i),0),18),GNn,0,1,oct,!1,!1,!0,!1,!1,!1,!1),TU(n.d,nct,hNn,!1,!1,!0),Prn(Yx(c1(aq(n.d),0),18),n.i,Yx(c1(aq(n.i),3),18),"containingNode",0,1,nct,!1,!1,!0,!1,!1,!1,!1),Prn(Yx(c1(aq(n.d),1),18),n.c,Yx(c1(aq(n.c),0),18),WNn,0,-1,nct,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.d),2),18),n.c,Yx(c1(aq(n.c),1),18),VNn,0,-1,nct,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.d),3),18),n.e,Yx(c1(aq(n.e),5),18),QNn,0,-1,nct,!1,!1,!0,!0,!1,!1,!1),z2(Yx(c1(aq(n.d),4),34),n.wb.e,"hyperedge",null,0,1,nct,!0,!0,!1,!1,!0,!0),z2(Yx(c1(aq(n.d),5),34),n.wb.e,XNn,null,0,1,nct,!0,!0,!1,!1,!0,!0),z2(Yx(c1(aq(n.d),6),34),n.wb.e,"selfloop",null,0,1,nct,!0,!0,!1,!1,!0,!0),z2(Yx(c1(aq(n.d),7),34),n.wb.e,"connected",null,0,1,nct,!0,!0,!1,!1,!0,!0),TU(n.b,Qrt,uNn,!1,!1,!0),z2(Yx(c1(aq(n.b),0),34),n.wb.t,"x",sMn,1,1,Qrt,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.b),1),34),n.wb.t,"y",sMn,1,1,Qrt,!1,!1,!0,!1,!0,!1),Crn(a=o6(n.b,null,"set"),n.wb.t,"x"),Crn(a,n.wb.t,"y"),TU(n.e,tct,fNn,!1,!1,!0),z2(Yx(c1(aq(n.e),0),34),n.wb.t,"startX",null,0,1,tct,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.e),1),34),n.wb.t,"startY",null,0,1,tct,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.e),2),34),n.wb.t,"endX",null,0,1,tct,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.e),3),34),n.wb.t,"endY",null,0,1,tct,!1,!1,!0,!1,!0,!1),Prn(Yx(c1(aq(n.e),4),18),n.b,null,YNn,0,-1,tct,!1,!1,!0,!0,!1,!1,!1),Prn(Yx(c1(aq(n.e),5),18),n.d,Yx(c1(aq(n.d),3),18),GNn,0,1,tct,!1,!1,!0,!1,!1,!1,!1),Prn(Yx(c1(aq(n.e),6),18),n.c,null,JNn,0,1,tct,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.e),7),18),n.c,null,ZNn,0,1,tct,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.e),8),18),n.e,Yx(c1(aq(n.e),9),18),nxn,0,-1,tct,!1,!1,!0,!1,!0,!1,!1),Prn(Yx(c1(aq(n.e),9),18),n.e,Yx(c1(aq(n.e),8),18),txn,0,-1,tct,!1,!1,!0,!1,!0,!1,!1),z2(Yx(c1(aq(n.e),10),34),n.wb._,BNn,null,0,1,tct,!1,!1,!0,!1,!0,!1),Crn(a=o6(n.e,null,"setStartLocation"),n.wb.t,"x"),Crn(a,n.wb.t,"y"),Crn(a=o6(n.e,null,"setEndLocation"),n.wb.t,"x"),Crn(a,n.wb.t,"y"),TU(n.k,i_n,"ElkPropertyToValueMapEntry",!1,!1,!1),t=SH(n.o),e=new up,fY((!t.d&&(t.d=new XO(hat,t,1)),t.d),e),Pfn(Yx(c1(aq(n.k),0),34),t,"key",i_n,!1,!1,!0,!1),z2(Yx(c1(aq(n.k),1),34),n.s,KNn,null,0,1,i_n,!1,!1,!0,!1,!0,!1),YB(n.o,S7n,"IProperty",!0),YB(n.s,UKn,"PropertyValue",!0),s8(n,xNn))}(n),Srn(n),GG(aat,xNn,n),n)}function Rk(){Rk=O,dat=function(){var n,t;Jvn();try{if(t=Yx(Jcn((mT(),aat),hRn),1941))return t}catch(t){if(!CO(t=j4(t),102))throw hp(t);n=t,AK((GC(),n))}return new qo}()}function Kk(){Kk=O,Out=function(){var n,t;rJ();try{if(t=Yx(Jcn((mT(),aat),BRn),2024))return t}catch(t){if(!CO(t=j4(t),102))throw hp(t);n=t,AK((GC(),n))}return new Ds}()}function _k(){var n;_k=O,Aut=wot?Yx(Hln((mT(),aat),BRn),1945):(zI(Cut,new Vs),zI(aot,new ah),zI(uot,new ph),zI(oot,new Ih),zI(fFn,new $h),zI(Gy(Yot,1),new Lh),zI(D_n,new Nh),zI(__n,new xh),zI(fFn,new _s),zI(fFn,new Fs),zI(fFn,new Bs),zI(H_n,new Hs),zI(fFn,new qs),zI(JKn,new Gs),zI(JKn,new zs),zI(fFn,new Us),zI(q_n,new Xs),zI(fFn,new Ws),zI(fFn,new Qs),zI(fFn,new Ys),zI(fFn,new Js),zI(fFn,new Zs),zI(Gy(Yot,1),new nh),zI(fFn,new th),zI(fFn,new eh),zI(JKn,new ih),zI(JKn,new rh),zI(fFn,new ch),zI(U_n,new uh),zI(fFn,new oh),zI(J_n,new sh),zI(fFn,new hh),zI(fFn,new fh),zI(fFn,new lh),zI(fFn,new bh),zI(JKn,new wh),zI(JKn,new dh),zI(fFn,new gh),zI(fFn,new vh),zI(fFn,new mh),zI(fFn,new yh),zI(fFn,new kh),zI(fFn,new jh),zI(nFn,new Eh),zI(fFn,new Th),zI(fFn,new Mh),zI(fFn,new Sh),zI(nFn,new Ph),zI(J_n,new Ch),zI(fFn,new Oh),zI(U_n,new Ah),n=Yx(CO(aG((mT(),aat),BRn),586)?aG(aat,BRn):new AB,586),wot=!0,function(n){n.N||(n.N=!0,n.b=q3(n,0),S2(n.b,0),S2(n.b,1),S2(n.b,2),n.bb=q3(n,1),S2(n.bb,0),S2(n.bb,1),n.fb=q3(n,2),S2(n.fb,3),S2(n.fb,4),P2(n.fb,5),n.qb=q3(n,3),S2(n.qb,0),P2(n.qb,1),P2(n.qb,2),S2(n.qb,3),S2(n.qb,4),P2(n.qb,5),S2(n.qb,6),n.a=G3(n,4),n.c=G3(n,5),n.d=G3(n,6),n.e=G3(n,7),n.f=G3(n,8),n.g=G3(n,9),n.i=G3(n,10),n.j=G3(n,11),n.k=G3(n,12),n.n=G3(n,13),n.o=G3(n,14),n.p=G3(n,15),n.q=G3(n,16),n.s=G3(n,17),n.r=G3(n,18),n.t=G3(n,19),n.u=G3(n,20),n.v=G3(n,21),n.w=G3(n,22),n.B=G3(n,23),n.A=G3(n,24),n.C=G3(n,25),n.D=G3(n,26),n.F=G3(n,27),n.G=G3(n,28),n.H=G3(n,29),n.J=G3(n,30),n.I=G3(n,31),n.K=G3(n,32),n.M=G3(n,33),n.L=G3(n,34),n.P=G3(n,35),n.Q=G3(n,36),n.R=G3(n,37),n.S=G3(n,38),n.T=G3(n,39),n.U=G3(n,40),n.V=G3(n,41),n.X=G3(n,42),n.W=G3(n,43),n.Y=G3(n,44),n.Z=G3(n,45),n.$=G3(n,46),n._=G3(n,47),n.ab=G3(n,48),n.cb=G3(n,49),n.db=G3(n,50),n.eb=G3(n,51),n.gb=G3(n,52),n.hb=G3(n,53),n.ib=G3(n,54),n.jb=G3(n,55),n.kb=G3(n,56),n.lb=G3(n,57),n.mb=G3(n,58),n.nb=G3(n,59),n.ob=G3(n,60),n.pb=G3(n,61))}(n),function(n){var t;n.O||(n.O=!0,E2(n,"type"),T2(n,"ecore.xml.type"),M2(n,BRn),t=Yx(Hln((mT(),aat),BRn),1945),fY(Iq(n.fb),n.b),TU(n.b,Cut,"AnyType",!1,!1,!0),z2(Yx(c1(aq(n.b),0),34),n.wb.D,ZDn,null,0,-1,Cut,!1,!1,!0,!1,!1,!1),z2(Yx(c1(aq(n.b),1),34),n.wb.D,"any",null,0,-1,Cut,!0,!0,!0,!1,!1,!0),z2(Yx(c1(aq(n.b),2),34),n.wb.D,"anyAttribute",null,0,-1,Cut,!1,!1,!0,!1,!1,!1),TU(n.bb,aot,URn,!1,!1,!0),z2(Yx(c1(aq(n.bb),0),34),n.gb,"data",null,0,1,aot,!1,!1,!0,!1,!0,!1),z2(Yx(c1(aq(n.bb),1),34),n.gb,lxn,null,1,1,aot,!1,!1,!0,!1,!0,!1),TU(n.fb,uot,XRn,!1,!1,!0),z2(Yx(c1(aq(n.fb),0),34),t.gb,"rawValue",null,0,1,uot,!0,!0,!0,!1,!0,!0),z2(Yx(c1(aq(n.fb),1),34),t.a,KNn,null,0,1,uot,!0,!0,!0,!1,!0,!0),Prn(Yx(c1(aq(n.fb),2),18),n.wb.q,null,"instanceType",1,1,uot,!1,!1,!0,!1,!1,!1,!1),TU(n.qb,oot,WRn,!1,!1,!0),z2(Yx(c1(aq(n.qb),0),34),n.wb.D,ZDn,null,0,-1,null,!1,!1,!0,!1,!1,!1),Prn(Yx(c1(aq(n.qb),1),18),n.wb.ab,null,"xMLNSPrefixMap",0,-1,null,!0,!1,!0,!0,!1,!1,!1),Prn(Yx(c1(aq(n.qb),2),18),n.wb.ab,null,"xSISchemaLocation",0,-1,null,!0,!1,!0,!0,!1,!1,!1),z2(Yx(c1(aq(n.qb),3),34),n.gb,"cDATA",null,0,-2,null,!0,!0,!0,!1,!1,!0),z2(Yx(c1(aq(n.qb),4),34),n.gb,"comment",null,0,-2,null,!0,!0,!0,!1,!1,!0),Prn(Yx(c1(aq(n.qb),5),18),n.bb,null,yKn,0,-2,null,!0,!0,!0,!0,!1,!1,!0),z2(Yx(c1(aq(n.qb),6),34),n.gb,zNn,null,0,-2,null,!0,!0,!0,!1,!1,!0),YB(n.a,UKn,"AnySimpleType",!0),YB(n.c,fFn,"AnyURI",!0),YB(n.d,Gy(Yot,1),"Base64Binary",!0),YB(n.e,Vot,"Boolean",!0),YB(n.f,D_n,"BooleanObject",!0),YB(n.g,Yot,"Byte",!0),YB(n.i,__n,"ByteObject",!0),YB(n.j,fFn,"Date",!0),YB(n.k,fFn,"DateTime",!0),YB(n.n,vFn,"Decimal",!0),YB(n.o,Jot,"Double",!0),YB(n.p,H_n,"DoubleObject",!0),YB(n.q,fFn,"Duration",!0),YB(n.s,JKn,"ENTITIES",!0),YB(n.r,JKn,"ENTITIESBase",!0),YB(n.t,fFn,nKn,!0),YB(n.u,Zot,"Float",!0),YB(n.v,q_n,"FloatObject",!0),YB(n.w,fFn,"GDay",!0),YB(n.B,fFn,"GMonth",!0),YB(n.A,fFn,"GMonthDay",!0),YB(n.C,fFn,"GYear",!0),YB(n.D,fFn,"GYearMonth",!0),YB(n.F,Gy(Yot,1),"HexBinary",!0),YB(n.G,fFn,"ID",!0),YB(n.H,fFn,"IDREF",!0),YB(n.J,JKn,"IDREFS",!0),YB(n.I,JKn,"IDREFSBase",!0),YB(n.K,Wot,"Int",!0),YB(n.M,EFn,"Integer",!0),YB(n.L,U_n,"IntObject",!0),YB(n.P,fFn,"Language",!0),YB(n.Q,Qot,"Long",!0),YB(n.R,J_n,"LongObject",!0),YB(n.S,fFn,"Name",!0),YB(n.T,fFn,tKn,!0),YB(n.U,EFn,"NegativeInteger",!0),YB(n.V,fFn,fKn,!0),YB(n.X,JKn,"NMTOKENS",!0),YB(n.W,JKn,"NMTOKENSBase",!0),YB(n.Y,EFn,"NonNegativeInteger",!0),YB(n.Z,EFn,"NonPositiveInteger",!0),YB(n.$,fFn,"NormalizedString",!0),YB(n._,fFn,"NOTATION",!0),YB(n.ab,fFn,"PositiveInteger",!0),YB(n.cb,fFn,"QName",!0),YB(n.db,nst,"Short",!0),YB(n.eb,nFn,"ShortObject",!0),YB(n.gb,fFn,rTn,!0),YB(n.hb,fFn,"Time",!0),YB(n.ib,fFn,"Token",!0),YB(n.jb,nst,"UnsignedByte",!0),YB(n.kb,nFn,"UnsignedByteObject",!0),YB(n.lb,Qot,"UnsignedInt",!0),YB(n.mb,J_n,"UnsignedIntObject",!0),YB(n.nb,EFn,"UnsignedLong",!0),YB(n.ob,Wot,"UnsignedShort",!0),YB(n.pb,U_n,"UnsignedShortObject",!0),s8(n,BRn),function(n){Zln(n.a,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"anySimpleType"])),Zln(n.b,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"anyType",tRn,ZDn])),Zln(Yx(c1(aq(n.b),0),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,NRn,gxn,":mixed"])),Zln(Yx(c1(aq(n.b),1),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,NRn,FRn,HRn,gxn,":1",YRn,"lax"])),Zln(Yx(c1(aq(n.b),2),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,$Rn,FRn,HRn,gxn,":2",YRn,"lax"])),Zln(n.c,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"anyURI",_Rn,xRn])),Zln(n.d,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"base64Binary",_Rn,xRn])),Zln(n.e,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,Xjn,_Rn,xRn])),Zln(n.f,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"boolean:Object",bRn,Xjn])),Zln(n.g,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,BDn])),Zln(n.i,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"byte:Object",bRn,BDn])),Zln(n.j,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"date",_Rn,xRn])),Zln(n.k,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"dateTime",_Rn,xRn])),Zln(n.n,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"decimal",_Rn,xRn])),Zln(n.o,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,qDn,_Rn,xRn])),Zln(n.p,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"double:Object",bRn,qDn])),Zln(n.q,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"duration",_Rn,xRn])),Zln(n.s,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"ENTITIES",bRn,JRn,ZRn,"1"])),Zln(n.r,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,JRn,DRn,nKn])),Zln(n.t,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,nKn,bRn,tKn])),Zln(n.u,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,GDn,_Rn,xRn])),Zln(n.v,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"float:Object",bRn,GDn])),Zln(n.w,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"gDay",_Rn,xRn])),Zln(n.B,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"gMonth",_Rn,xRn])),Zln(n.A,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"gMonthDay",_Rn,xRn])),Zln(n.C,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"gYear",_Rn,xRn])),Zln(n.D,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"gYearMonth",_Rn,xRn])),Zln(n.F,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"hexBinary",_Rn,xRn])),Zln(n.G,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"ID",bRn,tKn])),Zln(n.H,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"IDREF",bRn,tKn])),Zln(n.J,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"IDREFS",bRn,eKn,ZRn,"1"])),Zln(n.I,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,eKn,DRn,"IDREF"])),Zln(n.K,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,zDn])),Zln(n.M,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,iKn])),Zln(n.L,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"int:Object",bRn,zDn])),Zln(n.P,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"language",bRn,rKn,cKn,aKn])),Zln(n.Q,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,UDn])),Zln(n.R,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"long:Object",bRn,UDn])),Zln(n.S,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"Name",bRn,rKn,cKn,uKn])),Zln(n.T,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,tKn,bRn,"Name",cKn,oKn])),Zln(n.U,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"negativeInteger",bRn,sKn,hKn,"-1"])),Zln(n.V,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,fKn,bRn,rKn,cKn,"\\c+"])),Zln(n.X,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"NMTOKENS",bRn,lKn,ZRn,"1"])),Zln(n.W,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,lKn,DRn,fKn])),Zln(n.Y,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,bKn,bRn,iKn,wKn,"0"])),Zln(n.Z,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,sKn,bRn,iKn,hKn,"0"])),Zln(n.$,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,dKn,bRn,Vjn,_Rn,"replace"])),Zln(n._,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"NOTATION",_Rn,xRn])),Zln(n.ab,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"positiveInteger",bRn,bKn,wKn,"1"])),Zln(n.bb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"processingInstruction_._type",tRn,"empty"])),Zln(Yx(c1(aq(n.bb),0),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,ARn,gxn,"data"])),Zln(Yx(c1(aq(n.bb),1),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,ARn,gxn,lxn])),Zln(n.cb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"QName",_Rn,xRn])),Zln(n.db,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,XDn])),Zln(n.eb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"short:Object",bRn,XDn])),Zln(n.fb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"simpleAnyType",tRn,ORn])),Zln(Yx(c1(aq(n.fb),0),34),nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,":3",tRn,ORn])),Zln(Yx(c1(aq(n.fb),1),34),nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,":4",tRn,ORn])),Zln(Yx(c1(aq(n.fb),2),18),nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,":5",tRn,ORn])),Zln(n.gb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,Vjn,_Rn,"preserve"])),Zln(n.hb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"time",_Rn,xRn])),Zln(n.ib,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,rKn,bRn,dKn,_Rn,xRn])),Zln(n.jb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,gKn,hKn,"255",wKn,"0"])),Zln(n.kb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"unsignedByte:Object",bRn,gKn])),Zln(n.lb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,pKn,hKn,"4294967295",wKn,"0"])),Zln(n.mb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"unsignedInt:Object",bRn,pKn])),Zln(n.nb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"unsignedLong",bRn,bKn,hKn,vKn,wKn,"0"])),Zln(n.ob,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,mKn,hKn,"65535",wKn,"0"])),Zln(n.pb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"unsignedShort:Object",bRn,mKn])),Zln(n.qb,nRn,x4(Gy(fFn,1),TEn,2,6,[gxn,"",tRn,ZDn])),Zln(Yx(c1(aq(n.qb),0),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,NRn,gxn,":mixed"])),Zln(Yx(c1(aq(n.qb),1),18),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,ARn,gxn,"xmlns:prefix"])),Zln(Yx(c1(aq(n.qb),2),18),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,ARn,gxn,"xsi:schemaLocation"])),Zln(Yx(c1(aq(n.qb),3),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,LRn,gxn,"cDATA",RRn,KRn])),Zln(Yx(c1(aq(n.qb),4),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,LRn,gxn,"comment",RRn,KRn])),Zln(Yx(c1(aq(n.qb),5),18),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,LRn,gxn,yKn,RRn,KRn])),Zln(Yx(c1(aq(n.qb),6),34),nRn,x4(Gy(fFn,1),TEn,2,6,[tRn,LRn,gxn,zNn,RRn,KRn]))}(n))}(n),xB((yT(),wat),n,new Ks),Srn(n),GG(aat,BRn,n),n)}function Fk(){Fk=O,Pct=s0()}function Bk(){throw hp(new xp)}function Hk(){throw hp(new xp)}function qk(){throw hp(new xp)}function Gk(){throw hp(new xp)}function zk(){throw hp(new xp)}function Uk(){throw hp(new xp)}function Xk(n){this.a=new kE(n)}function Wk(n){Ekn(),function(n,t){var e,i,r,c,a,u,o,s;if(e=0,a=0,c=t.length,u=null,s=new $y,a1?zz(GK(t.a[1],32),Gz(t.a[0],uMn)):Gz(t.a[0],uMn),VU(e7(t.e,e))))}(n,new IC(o));for(n.d=s.a.length,r=0;r0}(Yx(n,33))?KA(i,(Qtn(),E7n))||KA(i,T7n):KA(i,(Qtn(),E7n));if(CO(n,352))return KA(i,(Qtn(),k7n));if(CO(n,186))return KA(i,(Qtn(),M7n));if(CO(n,354))return KA(i,(Qtn(),j7n))}return!0}(n,t)}function uj(n,t,e){n.splice(t,e)}function oj(n){n.c?pdn(n):vdn(n)}function sj(n){this.a=0,this.b=n}function hj(){this.a=new Ubn(p6n)}function fj(){this.b=new Ubn(i5n)}function lj(){this.b=new Ubn(o9n)}function bj(){this.b=new Ubn(o9n)}function wj(){throw hp(new xp)}function dj(){throw hp(new xp)}function gj(){throw hp(new xp)}function pj(){throw hp(new xp)}function vj(){throw hp(new xp)}function mj(){throw hp(new xp)}function yj(){throw hp(new xp)}function kj(){throw hp(new xp)}function jj(){throw hp(new xp)}function Ej(){throw hp(new xp)}function Tj(n){this.a=new Mj(n)}function Mj(n){!function(n,t,e){var i;n.b=t,n.a=e,i=512==(512&n.a)?new Zv:new Dh,n.c=function(n,t,e){var i,r,c;if(n.e=e,n.d=0,n.b=0,n.f=1,n.i=t,16==(16&n.e)&&(n.i=function(n){var t,e,i,r,c;for(i=n.length,t=new Oy,c=0;ct&&t0)){if(c=-1,32==XB(f.c,0)){if(l=h[0],JJ(t,h),h[0]>l)continue}else if(Rq(t,f.c,h[0])){h[0]+=f.c.length;continue}return 0}if(c<0&&f.a&&(c=s,a=h[0],r=0),c>=0){if(o=f.b,s==c&&0==(o-=r++))return 0;if(!Lkn(t,h,f,o,u)){s=c-1,h[0]=a;continue}}else if(c=-1,!Lkn(t,h,f,0,u))return 0}return function(n,t){var i,r,c,a,u,o;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>nTn&&JX(t,n.p-TTn),u=t.q.getDate(),mG(t,1),n.k>=0&&function(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),Ivn(n,e)}(t,n.k),n.c>=0?mG(t,n.c):n.k>=0?(r=35-new y5(t.q.getFullYear()-TTn,t.q.getMonth(),35).q.getDate(),mG(t,e.Math.min(r,u))):mG(t,u),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),function(n,t){n.q.setHours(t),Ivn(n,t)}(t,24==n.f&&n.g?0:n.f),n.j>=0&&function(n,t){var e;e=n.q.getHours()+(t/60|0),n.q.setMinutes(t),Ivn(n,e)}(t,n.j),n.n>=0&&function(n,t){var e;e=n.q.getHours()+(t/3600|0),n.q.setSeconds(t),Ivn(n,e)}(t,n.n),n.i>=0&&TI(t,t7(e7(Bcn(D3(t.q.getTime()),hTn),hTn),n.i)),n.a&&(JX(c=new uE,c.q.getFullYear()-TTn-80),LT(D3(t.q.getTime()),D3(c.q.getTime()))&&JX(t,c.q.getFullYear()-TTn+100)),n.d>=0)if(-1==n.c)(i=(7+n.d-t.q.getDay())%7)>3&&(i-=7),o=t.q.getMonth(),mG(t,t.q.getDate()+i),t.q.getMonth()!=o&&mG(t,t.q.getDate()+(i>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>nTn&&(a=t.q.getTimezoneOffset(),TI(t,t7(D3(t.q.getTime()),60*(n.o-a)*hTn))),!0}(u,i)?h[0]:0}(n,t,c=new y5((r=new uE).q.getFullYear()-TTn,r.q.getMonth(),r.q.getDate())))||i0}function LT(n,t){return k8(n,t)<0}function NT(n,t){return n.a.get(t)}function xT(n,t){return P_(n.e,t)}function DT(n){return vB(n),!1}function RT(n){Nz.call(this,n,21)}function KT(n,t){vG.call(this,n,t)}function _T(n,t){Uj.call(this,n,t)}function FT(n,t){Uj.call(this,n,t)}function BT(n){QF(),ix.call(this,n)}function HT(n,t){nK(n,n.length,t)}function qT(n,t){cF(n,n.length,t)}function GT(n,t,e){n.splice(t,0,e)}function zT(n,t){this.d=n,this.e=t}function UT(n,t){this.b=n,this.a=t}function XT(n,t){this.b=n,this.a=t}function WT(n,t){this.b=n,this.a=t}function VT(n,t){this.a=n,this.b=t}function QT(n,t){this.a=n,this.b=t}function YT(n,t){this.a=n,this.b=t}function JT(n,t){this.a=n,this.b=t}function ZT(n,t){this.a=n,this.b=t}function nM(n,t){this.b=n,this.a=t}function tM(n,t){this.b=n,this.a=t}function eM(n,t){Uj.call(this,n,t)}function iM(n,t){Uj.call(this,n,t)}function rM(n,t){Uj.call(this,n,t)}function cM(n,t){Uj.call(this,n,t)}function aM(n,t){Uj.call(this,n,t)}function uM(n,t){Uj.call(this,n,t)}function oM(n,t){Uj.call(this,n,t)}function sM(n,t){Uj.call(this,n,t)}function hM(n,t){Uj.call(this,n,t)}function fM(n,t){Uj.call(this,n,t)}function lM(n,t){Uj.call(this,n,t)}function bM(n,t){Uj.call(this,n,t)}function wM(n,t){Uj.call(this,n,t)}function dM(n,t){Uj.call(this,n,t)}function gM(n,t){Uj.call(this,n,t)}function pM(n,t){Uj.call(this,n,t)}function vM(n,t){Uj.call(this,n,t)}function mM(n,t){Uj.call(this,n,t)}function yM(n,t){this.a=n,this.b=t}function kM(n,t){this.a=n,this.b=t}function jM(n,t){this.a=n,this.b=t}function EM(n,t){this.a=n,this.b=t}function TM(n,t){this.a=n,this.b=t}function MM(n,t){this.a=n,this.b=t}function SM(n,t){this.a=n,this.b=t}function PM(n,t){this.a=n,this.b=t}function IM(n,t){this.a=n,this.b=t}function CM(n,t){this.b=n,this.a=t}function OM(n,t){this.b=n,this.a=t}function AM(n,t){this.b=n,this.a=t}function $M(n,t){this.b=n,this.a=t}function LM(n,t){this.c=n,this.d=t}function NM(n,t){this.e=n,this.d=t}function xM(n,t){this.a=n,this.b=t}function DM(n,t){this.b=t,this.c=n}function RM(n,t){Uj.call(this,n,t)}function KM(n,t){Uj.call(this,n,t)}function _M(n,t){Uj.call(this,n,t)}function FM(n,t){Uj.call(this,n,t)}function BM(n,t){Uj.call(this,n,t)}function HM(n,t){Uj.call(this,n,t)}function qM(n,t){Uj.call(this,n,t)}function GM(n,t){Uj.call(this,n,t)}function zM(n,t){Uj.call(this,n,t)}function UM(n,t){Uj.call(this,n,t)}function XM(n,t){Uj.call(this,n,t)}function WM(n,t){Uj.call(this,n,t)}function VM(n,t){Uj.call(this,n,t)}function QM(n,t){Uj.call(this,n,t)}function YM(n,t){Uj.call(this,n,t)}function JM(n,t){Uj.call(this,n,t)}function ZM(n,t){Uj.call(this,n,t)}function nS(n,t){Uj.call(this,n,t)}function tS(n,t){Uj.call(this,n,t)}function eS(n,t){Uj.call(this,n,t)}function iS(n,t){Uj.call(this,n,t)}function rS(n,t){Uj.call(this,n,t)}function cS(n,t){Uj.call(this,n,t)}function aS(n,t){Uj.call(this,n,t)}function uS(n,t){Uj.call(this,n,t)}function oS(n,t){Uj.call(this,n,t)}function sS(n,t){Uj.call(this,n,t)}function hS(n,t){Uj.call(this,n,t)}function fS(n,t){Uj.call(this,n,t)}function lS(n,t){Uj.call(this,n,t)}function bS(n,t){Uj.call(this,n,t)}function wS(n,t){Uj.call(this,n,t)}function dS(n,t){Uj.call(this,n,t)}function gS(n,t){Uj.call(this,n,t)}function pS(n,t){this.b=n,this.a=t}function vS(n,t){this.a=n,this.b=t}function mS(n,t){this.a=n,this.b=t}function yS(n,t){this.a=n,this.b=t}function kS(n,t){this.a=n,this.b=t}function jS(n,t){Uj.call(this,n,t)}function ES(n,t){Uj.call(this,n,t)}function TS(n,t){this.b=n,this.d=t}function MS(n,t){Uj.call(this,n,t)}function SS(n,t){Uj.call(this,n,t)}function PS(n,t){this.a=n,this.b=t}function IS(n,t){this.a=n,this.b=t}function CS(n,t){Uj.call(this,n,t)}function OS(n,t){Uj.call(this,n,t)}function AS(n,t){Uj.call(this,n,t)}function $S(n,t){Uj.call(this,n,t)}function LS(n,t){Uj.call(this,n,t)}function NS(n,t){Uj.call(this,n,t)}function xS(n,t){Uj.call(this,n,t)}function DS(n,t){Uj.call(this,n,t)}function RS(n,t){Uj.call(this,n,t)}function KS(n,t){Uj.call(this,n,t)}function _S(n,t){Uj.call(this,n,t)}function FS(n,t){Uj.call(this,n,t)}function BS(n,t){Uj.call(this,n,t)}function HS(n,t){Uj.call(this,n,t)}function qS(n,t){Uj.call(this,n,t)}function GS(n,t){Uj.call(this,n,t)}function zS(n,t){return KA(n.g,t)}function US(n,t){Uj.call(this,n,t)}function XS(n,t){Uj.call(this,n,t)}function WS(n,t){this.a=n,this.b=t}function VS(n,t){this.a=n,this.b=t}function QS(n,t){this.a=n,this.b=t}function YS(n,t){Uj.call(this,n,t)}function JS(n,t){Uj.call(this,n,t)}function ZS(n,t){Uj.call(this,n,t)}function nP(n,t){Uj.call(this,n,t)}function tP(n,t){Uj.call(this,n,t)}function eP(n,t){Uj.call(this,n,t)}function iP(n,t){Uj.call(this,n,t)}function rP(n,t){Uj.call(this,n,t)}function cP(n,t){Uj.call(this,n,t)}function aP(n,t){Uj.call(this,n,t)}function uP(n,t){Uj.call(this,n,t)}function oP(n,t){Uj.call(this,n,t)}function sP(n,t){Uj.call(this,n,t)}function hP(n,t){Uj.call(this,n,t)}function fP(n,t){Uj.call(this,n,t)}function lP(n,t){Uj.call(this,n,t)}function bP(n,t){this.a=n,this.b=t}function wP(n,t){this.a=n,this.b=t}function dP(n,t){this.a=n,this.b=t}function gP(n,t){this.a=n,this.b=t}function pP(n,t){this.a=n,this.b=t}function vP(n,t){this.a=n,this.b=t}function mP(n,t){this.a=n,this.b=t}function yP(n,t){Uj.call(this,n,t)}function kP(n,t){this.a=n,this.b=t}function jP(n,t){this.a=n,this.b=t}function EP(n,t){this.a=n,this.b=t}function TP(n,t){this.a=n,this.b=t}function MP(n,t){this.a=n,this.b=t}function SP(n,t){this.a=n,this.b=t}function PP(n,t){this.b=n,this.a=t}function IP(n,t){this.b=n,this.a=t}function CP(n,t){this.b=n,this.a=t}function OP(n,t){this.b=n,this.a=t}function AP(n,t){this.a=n,this.b=t}function $P(n,t){this.a=n,this.b=t}function LP(n,t){!function(n,t){if(CO(t,239))return function(n,t){var e;if(null==(e=g1(n.i,t)))throw hp(new hy("Node did not exist in input."));return f3(t,e),null}(n,Yx(t,33));if(CO(t,186))return function(n,t){var e;if(null==(e=BF(n.k,t)))throw hp(new hy("Port did not exist in input."));return f3(t,e),null}(n,Yx(t,118));if(CO(t,354))return function(n,t){return f3(t,BF(n.f,t)),null}(n,Yx(t,137));if(CO(t,352))return function(n,t){var e,i,r,c,a,u;if(!(a=Yx(BF(n.c,t),183)))throw hp(new hy("Edge did not exist in input."));return i=itn(a),!Sj((!t.a&&(t.a=new m_(tct,t,6,6)),t.a))&&(e=new Rx(n,i,u=new Sl),function(n,t){!function(n,t){var e;for(e=0;n.e!=n.i.gc();)sR(t,hen(n),d9(e)),e!=Yjn&&++e}(new UO(n),t)}((!t.a&&(t.a=new m_(tct,t,6,6)),t.a),e),OZ(a,QNn,u)),zQ(t,(Cjn(),Gnt))&&!(!(r=Yx(jln(t,Gnt),74))||wB(r))&&(XW(r,new mg(c=new Sl)),OZ(a,"junctionPoints",c)),ND(a,"container",EG(t).k),null}(n,Yx(t,79));if(t)return null;throw hp(new Qm(axn+Gun(new ay(x4(Gy(UKn,1),iEn,1,5,[t])))))}(n.a,Yx(t,56))}function NP(n,t){!function(n,t){dD(),eD(n,new mP(t,d9(t.e.c.length+t.g.c.length)))}(n.a,Yx(t,11))}function xP(){return Fy(),new xFn}function DP(){lz(),this.b=new Qp}function RP(){ywn(),this.a=new Qp}function KP(){uz(),wK.call(this)}function _P(n,t){Uj.call(this,n,t)}function FP(n,t){this.a=n,this.b=t}function BP(n,t){this.a=n,this.b=t}function HP(n,t){this.a=n,this.b=t}function qP(n,t){this.a=n,this.b=t}function GP(n,t){this.a=n,this.b=t}function zP(n,t){this.a=n,this.b=t}function UP(n,t){this.d=n,this.b=t}function XP(n,t){this.d=n,this.e=t}function WP(n,t){this.f=n,this.c=t}function VP(n,t){this.b=n,this.c=t}function QP(n,t){this.i=n,this.g=t}function YP(n,t){this.e=n,this.a=t}function JP(n,t){this.a=n,this.b=t}function ZP(n,t){n.i=null,J0(n,t)}function nI(n,t){return mnn(n.a,t)}function tI(n){return knn(n.c,n.b)}function eI(n){return n?n.dd():null}function iI(n){return null==n?null:n}function rI(n){return typeof n===Xjn}function cI(n){return typeof n===Wjn}function aI(n){return typeof n===Vjn}function uI(n,t){return n.Hd().Xb(t)}function oI(n,t){return function(n,t){for(MF(t);n.Ob();)if(!f4(Yx(n.Pb(),10)))return!1;return!0}(n.Kc(),t)}function sI(n,t){return 0==k8(n,t)}function hI(n,t){return 0!=k8(n,t)}function fI(n){return""+(vB(n),n)}function lI(n,t){return n.substr(t)}function bI(n){return A7(n),n.d.gc()}function wI(n){return function(n,t){var e,i,r;for(e=new pb(n.a.a);e.at?1:0}function iO(n,t){return k8(n,t)>0?n:t}function rO(n,t,e){return{l:n,m:t,h:e}}function cO(n,t){null!=n.a&&NP(t,n.a)}function aO(n){n.a=new $,n.c=new $}function uO(n){this.b=n,this.a=new ip}function oO(n){this.b=new et,this.a=n}function sO(n){oN.call(this),this.a=n}function hO(){_T.call(this,"Range",2)}function fO(){Mcn(),this.a=new Ubn(azn)}function lO(n,t,e){return Fnn(t,e,n.c)}function bO(n){return new QS(n.c,n.d)}function wO(n){return new QS(n.c,n.d)}function dO(n){return new QS(n.a,n.b)}function gO(n,t){return function(n,t,e){var i,r,c,a,u,o,s,h,f;for(!e&&(e=function(n){var t;return(t=new p).a=n,t.b=function(n){var t;return 0==n?"Etc/GMT":(n<0?(n=-n,t="Etc/GMT-"):t="Etc/GMT+",t+XJ(n))}(n),t.c=VQ(fFn,TEn,2,2,6,1),t.c[0]=A2(n),t.c[1]=A2(n),t}(t.q.getTimezoneOffset())),r=6e4*(t.q.getTimezoneOffset()-e.a),o=u=new bL(t7(D3(t.q.getTime()),r)),u.q.getTimezoneOffset()!=t.q.getTimezoneOffset()&&(r>0?r-=864e5:r+=864e5,o=new bL(t7(D3(t.q.getTime()),r))),h=new $y,s=n.a.length,c=0;c=97&&i<=122||i>=65&&i<=90){for(a=c+1;a=s)throw hp(new Qm("Missing trailing '"));a+11)throw hp(new Qm(GRn));for(h=dwn(n.e.Tg(),t),i=Yx(n.g,119),a=0;a0),c=Yx(s.a.Xb(s.c=--s.b),17);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,S$(s.b>0),c=Yx(s.a.Xb(s.c=--s.b),17);s.b>0&&hB(s)}}(n,t,e),e}function $O(n,t,e){n.a=1502^t,n.b=e^kMn}function LO(n,t,e){return n.a[t.g][e.g]}function NO(n,t){return n.a[t.c.p][t.p]}function xO(n,t){return n.e[t.c.p][t.p]}function DO(n,t){return n.c[t.c.p][t.p]}function RO(n,t){return n.j[t.p]=function(n){var t,e,i,r;for(t=0,e=0,r=new pb(n.j);r.a1||e>1)return 2;return t+e==1?2:0}(t)}function KO(n,t){return n.a*=t,n.b*=t,n}function _O(n,t,e){return DF(n.g,t,e),e}function FO(n){n.a=Yx(H3(n.b.a,4),126)}function BO(n){n.a=Yx(H3(n.b.a,4),126)}function HO(n){xq(n,vxn),Sbn(n,function(n){var t,e,i,r,c;switch(xq(n,vxn),(!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b).i+(!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c).i){case 0:throw hp(new Qm("The edge must have at least one source or target."));case 1:return 0==(!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b).i?IG(iun(Yx(c1((!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c),0),82))):IG(iun(Yx(c1((!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),0),82)))}if(1==(!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b).i&&1==(!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c).i){if(r=iun(Yx(c1((!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),0),82)),c=iun(Yx(c1((!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c),0),82)),IG(r)==IG(c))return IG(r);if(r==IG(c))return r;if(c==IG(r))return c}for(t=iun(Yx(kV(i=W_(n0(x4(Gy(QKn,1),iEn,20,0,[(!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),(!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c)])))),82));Vfn(i);)if((e=iun(Yx(kV(i),82)))!=t&&!XZ(e,t))if(IG(e)==IG(t))t=IG(e);else if(!(t=Uln(t,e)))return null;return t}(n))}function qO(){qO=O,FFn=new Am(null)}function GO(){(GO=O)(),UFn=new z}function zO(){this.Bb|=256,this.Bb|=512}function UO(n){this.i=n,this.f=this.i.j}function XO(n,t,e){TD.call(this,n,t,e)}function WO(n,t,e){XO.call(this,n,t,e)}function VO(n,t,e){XO.call(this,n,t,e)}function QO(n,t,e){WO.call(this,n,t,e)}function YO(n,t,e){TD.call(this,n,t,e)}function JO(n,t,e){TD.call(this,n,t,e)}function ZO(n,t,e){CD.call(this,n,t,e)}function nA(n,t,e){CD.call(this,n,t,e)}function tA(n,t,e){ZO.call(this,n,t,e)}function eA(n,t,e){YO.call(this,n,t,e)}function iA(n,t){this.a=n,eE.call(this,t)}function rA(n,t){this.a=n,dy.call(this,t)}function cA(n,t){this.a=n,dy.call(this,t)}function aA(n,t){this.a=n,dy.call(this,t)}function uA(n){this.a=n,ol.call(this,n.d)}function oA(n){this.c=n,this.a=this.c.a}function sA(n,t){this.a=t,dy.call(this,n)}function hA(n,t){this.a=t,hW.call(this,n)}function fA(n,t){this.a=n,hW.call(this,t)}function lA(n,t){return function(n,t,e){try{!function(n,t,e){if(MF(t),e.Ob())for(kI(t,$F(e.Pb()));e.Ob();)kI(t,n.a),kI(t,$F(e.Pb()))}(n,t,e)}catch(n){throw CO(n=j4(n),597)?hp(new eV(n)):hp(n)}return t}(n,new Ay,t).a}function bA(n,t){return MF(t),new wA(n,t)}function wA(n,t){this.a=t,aE.call(this,n)}function dA(n){this.b=n,this.a=this.b.a.e}function gA(n){n.b.Qb(),--n.d.f.d,oK(n.d)}function pA(n){Zf.call(this,Yx(MF(n),35))}function vA(n){Zf.call(this,Yx(MF(n),35))}function mA(){Uj.call(this,"INSTANCE",0)}function yA(n){if(!n)throw hp(new $p)}function kA(n){if(!n)throw hp(new Lp)}function jA(n){if(!n)throw hp(new Kp)}function EA(){EA=O,ET(),yut=new Kf}function TA(){TA=O,$_n=!1,L_n=!0}function MA(n){nb.call(this,(vB(n),n))}function SA(n){nb.call(this,(vB(n),n))}function PA(n){fb.call(this,n),this.a=n}function IA(n){lb.call(this,n),this.a=n}function CA(n){Ny.call(this,n),this.a=n}function OA(){jO(this),qH(this),this._d()}function AA(n,t){this.a=t,aE.call(this,n)}function $A(n,t){return new jsn(n.a,n.b,t)}function LA(n,t){return n.lastIndexOf(t)}function NA(n,t,e){return n.indexOf(t,e)}function xA(n){return null==n?aEn:I7(n)}function DA(n){return null!=n.a?n.a:null}function RA(n,t){return null!=fG(n.a,t)}function KA(n,t){return!!t&&n.b[t.g]==t}function _A(n){return n.$H||(n.$H=++mBn)}function FA(n,t){return eD(t.a,n.a),n.a}function BA(n,t){return eD(t.b,n.a),n.a}function HA(n,t){return eD(t.a,n.a),n.a}function qA(n){return S$(null!=n.a),n.a}function GA(n){Mb.call(this,new tY(n))}function zA(n,t){Etn.call(this,n,t,null)}function UA(n){this.a=n,hb.call(this,n)}function XA(){XA=O,XHn=new _L(OSn,0)}function WA(n,t){return++n.b,eD(n.a,t)}function VA(n,t){return++n.b,uJ(n.a,t)}function QA(n,t){return Yx(_V(n.b,t),15)}function YA(n){return ZC(n.a)||ZC(n.b)}function JA(n,t,e){return $X(n,t,e,n.c)}function ZA(n,t,e){Yx(jJ(n,t),21).Fc(e)}function n$(n,t){kT(),this.a=n,this.b=t}function t$(n,t){jT(),this.b=n,this.c=t}function e$(n,t){gK(),this.f=t,this.d=n}function i$(n,t){qV(t,n),this.d=n,this.c=t}function r$(n){var t;t=n.a,n.a=n.b,n.b=t}function c$(n,t){return new NN(n,n.gc(),t)}function a$(n){this.d=n,UO.call(this,n)}function u$(n){this.c=n,UO.call(this,n)}function o$(n){this.c=n,a$.call(this,n)}function s$(){JE(),this.b=new qw(this)}function h$(n){return g0(n,UEn),new pQ(n)}function f$(n){return $q(),parseInt(n)||-1}function l$(n,t,e){return n.substr(t,e-t)}function b$(n,t,e){return NA(n,gun(t),e)}function w$(n){return rF(n.c,n.c.length)}function d$(n){return null!=n.f?n.f:""+n.g}function g$(n){return S$(0!=n.b),n.a.a.c}function p$(n){return S$(0!=n.b),n.c.b.c}function v$(n){CO(n,150)&&Yx(n,150).Gh()}function m$(n){return n.b=Yx(FH(n.a),42)}function y$(n){RE(),this.b=n,this.a=!0}function k$(n){KE(),this.b=n,this.a=!0}function j$(n){n.d=new P$(n),n.e=new rp}function E$(n){if(!n)throw hp(new Dp)}function T$(n){if(!n)throw hp(new $p)}function M$(n){if(!n)throw hp(new Lp)}function S$(n){if(!n)throw hp(new Kp)}function P$(n){oD.call(this,n,null,null)}function I$(){Uj.call(this,"POLYOMINO",0)}function C$(n,t,e,i){LK.call(this,n,t,e,i)}function O$(n,t){return!!n.q&&P_(n.q,t)}function A$(n,t,e){n.Zc(t).Rb(e)}function $$(n,t,e){return n.a+=t,n.b+=e,n}function L$(n,t,e){return n.a*=t,n.b*=e,n}function N$(n,t,e){return n.a-=t,n.b-=e,n}function x$(n,t){return n.a=t.a,n.b=t.b,n}function D$(n){return n.a=-n.a,n.b=-n.b,n}function R$(n){this.c=n,this.a=1,this.b=1}function K$(n){this.c=n,L1(n,0),N1(n,0)}function _$(n){ME.call(this),r0(this,n)}function F$(n){ljn(),sp(this),this.mf(n)}function B$(n,t){kT(),n$.call(this,n,t)}function H$(n,t){jT(),t$.call(this,n,t)}function q$(n,t){jT(),t$.call(this,n,t)}function G$(n,t){jT(),H$.call(this,n,t)}function z$(n,t,e){yY.call(this,n,t,e,2)}function U$(n,t){WC(),KR.call(this,n,t)}function X$(n,t){WC(),U$.call(this,n,t)}function W$(n,t){WC(),U$.call(this,n,t)}function V$(n,t){WC(),W$.call(this,n,t)}function Q$(n,t){WC(),KR.call(this,n,t)}function Y$(n,t){WC(),Q$.call(this,n,t)}function J$(n,t){WC(),KR.call(this,n,t)}function Z$(n,t,e){return Imn(SJ(n,t),e)}function nL(n,t){return P8(n.e,Yx(t,49))}function tL(n,t){t.$modCount=n.$modCount}function eL(){eL=O,s6n=new Og("root")}function iL(){iL=O,$ct=new Rv,new Kv}function rL(){this.a=new Zq,this.b=new Zq}function cL(){T0.call(this),this.Bb|=eMn}function aL(){Uj.call(this,"GROW_TREE",0)}function uL(n){return null==n?null:function(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(Jpn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=VQ(Xot,sTn,25,4*(0!=(u=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,o=0;o>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,d=0==(-128&(i=n[r++]))?i>>6<<24>>24:(i>>6^252)<<24>>24,c[a++]=hot[b],c[a++]=hot[w|s<<4],c[a++]=hot[h<<2|d],c[a++]=hot[63&i];return 8==u?(s=(3&(t=n[r]))<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,c[a++]=hot[b],c[a++]=hot[s<<4],c[a++]=61,c[a++]=61):16==u&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,c[a++]=hot[b],c[a++]=hot[w|s<<4],c[a++]=hot[h<<2],c[a++]=61),Vnn(c,0,c.length)}(n)}function oL(n){return null==n?null:function(n){var t,e,i,r;if(kdn(),null==n)return null;for(i=n.length,t=VQ(Xot,sTn,25,2*i,15,1),e=0;e>4],t[2*e+1]=lot[15&r];return Vnn(t,0,t.length)}(n)}function sL(n){null==n.o&&function(n){if(n.pe()){var t=n.c;return t.qe()?n.o="["+t.n:t.pe()?n.o="["+t.ne():n.o="[L"+t.ne()+";",n.b=t.me()+"[]",void(n.k=t.oe()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=Wnn(".",[e,Wnn("$",i)]),n.b=Wnn(".",[e,Wnn(".",i)]),n.k=i[i.length-1]}(n)}function hL(n){return QD(null==n||rI(n)),n}function fL(n){return QD(null==n||cI(n)),n}function lL(n){return QD(null==n||aI(n)),n}function bL(n){this.q=new e.Date(VU(n))}function wL(n,t){this.c=n,Xj.call(this,n,t)}function dL(n,t){this.a=n,wL.call(this,n,t)}function gL(n,t){this.d=n,Wl(this),this.b=t}function pL(n,t){ZQ.call(this,n),this.a=t}function vL(n,t){ZQ.call(this,n),this.a=t}function mL(n){hnn.call(this,0,0),this.f=n}function yL(n,t,e){dQ.call(this,n,t,e,null)}function kL(n,t,e){dQ.call(this,n,t,e,null)}function jL(n,t){return Yx(UJ(n.b,t),149)}function EL(n,t){return Yx(UJ(n.c,t),229)}function TL(n){return Yx(TR(n.a,n.b),287)}function ML(n){return new QS(n.c,n.d+n.a)}function SL(n){return hz(),wC(Yx(n,197))}function PL(){PL=O,UHn=J9((Ann(),nrt))}function IL(n,t){t.a?function(n,t){var e,i,r;if(!uF(n.a,t.b))throw hp(new Ym("Invalid hitboxes for scanline overlap calculation."));for(r=!1,i=new sb(new gN(new UA(new ob(n.a.a).a).b));OT(i.a.a);)if(e=Yx(m$(i.a).cd(),65),u5(t.b,e))vk(n.b.a,t.b,e),r=!0;else if(r)break}(n,t):RA(n.a,t.b)}function CL(n,t){hBn||eD(n.a,t)}function OL(n,t){return xq(t,jSn),n.f=t,n}function AL(n,t,e){return opn(n,t,3,e)}function $L(n,t,e){return opn(n,t,6,e)}function LL(n,t,e){return opn(n,t,9,e)}function NL(n,t,e){++n.j,n.Ki(),XQ(n,t,e)}function xL(n,t,e){++n.j,n.Hi(t,n.oi(t,e))}function DL(n,t,e){n.Zc(t).Rb(e)}function RL(n,t,e){return rmn(n.c,n.b,t,e)}function KL(n,t){return(t&Yjn)%n.d.length}function _L(n,t){Og.call(this,n),this.a=t}function FL(n,t){Gg.call(this,n),this.a=t}function BL(n,t){Gg.call(this,n),this.a=t}function HL(n,t){this.c=n,FZ.call(this,t)}function qL(n,t){this.a=n,qg.call(this,t)}function GL(n,t){this.a=n,qg.call(this,t)}function zL(n){this.a=(g0(n,UEn),new pQ(n))}function UL(n){this.a=(g0(n,UEn),new pQ(n))}function XL(n){return!n.a&&(n.a=new w),n.a}function WL(n){return n>8?0:n+1}function VL(n,t,e){return YR(n,Yx(t,22),e)}function QL(n,t,e){return n.a+=Vnn(t,0,e),n}function YL(n,t){var e;return e=n.e,n.e=t,e}function JL(n,t){n[vMn].call(n,t)}function ZL(n,t){n.a.Vc(n.b,t),++n.b,n.c=-1}function nN(n){U_(n.e),n.d.b=n.d,n.d.a=n.d}function tN(n){n.b?tN(n.b):n.f.c.zc(n.e,n.d)}function eN(n,t){return qy(new Array(t),n)}function iN(n){return String.fromCharCode(n)}function rN(){this.a=new ip,this.b=new ip}function cN(){this.a=new bt,this.b=new Hp}function aN(){this.b=new Pk,this.c=new ip}function uN(){this.d=new Pk,this.e=new Pk}function oN(){this.n=new Pk,this.o=new Pk}function sN(){this.n=new Sv,this.i=new hC}function hN(){this.a=new Jh,this.b=new uc}function fN(){this.a=new ip,this.d=new ip}function lN(){this.b=new Qp,this.a=new Qp}function bN(){this.b=new rp,this.a=new rp}function wN(){this.b=new fj,this.a=new da}function dN(){sN.call(this),this.a=new Pk}function gN(n){Q3.call(this,n,(HY(),WFn))}function pN(n,t,e,i){FR.call(this,n,t,e,i)}function vN(n,t,e){return opn(n,t,11,e)}function mN(n,t){return n.a+=t.a,n.b+=t.b,n}function yN(n,t){return n.a-=t.a,n.b-=t.b,n}function kN(n,t){return null==xB(n.a,t,"")}function jN(n,t){Hm.call(this,pDn+n+Exn+t)}function EN(n,t,e,i){m_.call(this,n,t,e,i)}function TN(n,t,e,i){m_.call(this,n,t,e,i)}function MN(n,t,e,i){TN.call(this,n,t,e,i)}function SN(n,t,e,i){y_.call(this,n,t,e,i)}function PN(n,t,e,i){y_.call(this,n,t,e,i)}function IN(n,t,e,i){y_.call(this,n,t,e,i)}function CN(n,t,e,i){PN.call(this,n,t,e,i)}function ON(n,t,e,i){PN.call(this,n,t,e,i)}function AN(n,t,e,i){IN.call(this,n,t,e,i)}function $N(n,t,e,i){ON.call(this,n,t,e,i)}function LN(n,t,e,i){g_.call(this,n,t,e,i)}function NN(n,t,e){this.a=n,i$.call(this,t,e)}function xN(n,t,e){this.c=t,this.b=e,this.a=n}function DN(n,t){return n.Aj().Nh().Kh(n,t)}function RN(n,t){return n.Aj().Nh().Ih(n,t)}function KN(n,t){return vB(n),iI(n)===iI(t)}function _N(n,t){return vB(n),iI(n)===iI(t)}function FN(n,t){return $k(Dnn(n.a,t,!1))}function BN(n,t){return $k(Rnn(n.a,t,!1))}function HN(n,t){return n.b.sd(new JT(n,t))}function qN(n,t,e){return n.lastIndexOf(t,e)}function GN(n){return n.c?hJ(n.c.a,n,0):-1}function zN(n){return n==uit||n==sit||n==oit}function UN(n,t){return CO(t,15)&&Pdn(n.c,t)}function XN(n,t){return!!c6(n,t)}function WN(n,t){this.c=n,Z_.call(this,n,t)}function VN(n){this.c=n,PI.call(this,IEn,0)}function QN(n,t){aD.call(this,n,n.length,t)}function YN(n,t,e){return Yx(n.c,69).mk(t,e)}function JN(n,t,e){return function(n,t,e){return t.Rk(n.e,n.c,e)}(n,Yx(t,332),e)}function ZN(n,t,e){return function(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?Kq(n,4,i,c,null,$vn(n,i,c,CO(i,99)&&0!=(Yx(i,18).Bb&eMn)),!0):Kq(n,i.Kj()?2:1,i,c,i.zj(),-1,!0),e?e.Ei(r):e=r,e}(n,Yx(t,332),e)}function nx(n,t){return null==t?null:x8(n.b,t)}function tx(n){return cI(n)?(vB(n),n):n.ke()}function ex(n){return!isNaN(n)&&!isFinite(n)}function ix(n){px(),this.a=(XH(),new Ny(n))}function rx(n){dD(),this.d=n,this.a=new ep}function cx(n,t,e){this.a=n,this.b=t,this.c=e}function ax(n,t,e){this.a=n,this.b=t,this.c=e}function ux(n,t,e){this.d=n,this.b=e,this.a=t}function ox(n){aO(this),BH(this),C2(this,n)}function sx(n){AC(this),sD(this.c,0,n.Pc())}function hx(n){hB(n.a),iY(n.c,n.b),n.b=null}function fx(n){this.a=n,oE(),D3(Date.now())}function lx(){lx=O,pBn=new r,vBn=new r}function bx(){bx=O,KFn=new L,_Fn=new N}function wx(){wx=O,Cct=VQ(UKn,iEn,1,0,5,1)}function dx(){dx=O,Fat=VQ(UKn,iEn,1,0,5,1)}function gx(){gx=O,Bat=VQ(UKn,iEn,1,0,5,1)}function px(){px=O,new jp((XH(),XH(),TFn))}function vx(n,t){if(!n)throw hp(new Qm(t))}function mx(n){FR.call(this,n.d,n.c,n.a,n.b)}function yx(n){FR.call(this,n.d,n.c,n.a,n.b)}function kx(n,t,e){this.b=n,this.c=t,this.a=e}function jx(n,t,e){this.b=n,this.a=t,this.c=e}function Ex(n,t,e){this.a=n,this.b=t,this.c=e}function Tx(n,t,e){this.a=n,this.b=t,this.c=e}function Mx(n,t,e){this.a=n,this.b=t,this.c=e}function Sx(n,t,e){this.a=n,this.b=t,this.c=e}function Px(n,t,e){this.b=n,this.a=t,this.c=e}function Ix(n,t,e){this.e=t,this.b=n,this.d=e}function Cx(n){var t;return(t=new jn).e=n,t}function Ox(n){var t;return(t=new lv).b=n,t}function Ax(){Ax=O,aUn=new Ne,uUn=new xe}function $x(){$x=O,CXn=new vr,OXn=new mr}function Lx(n,t){this.c=n,this.a=t,this.b=t-n}function Nx(n,t,e){this.a=n,this.b=t,this.c=e}function xx(n,t,e){this.a=n,this.b=t,this.c=e}function Dx(n,t,e){this.a=n,this.b=t,this.c=e}function Rx(n,t,e){this.a=n,this.b=t,this.c=e}function Kx(n,t,e){this.a=n,this.b=t,this.c=e}function _x(n,t,e){this.e=n,this.a=t,this.c=e}function Fx(n,t,e){WC(),tG.call(this,n,t,e)}function Bx(n,t,e){WC(),iB.call(this,n,t,e)}function Hx(n,t,e){WC(),iB.call(this,n,t,e)}function qx(n,t,e){WC(),iB.call(this,n,t,e)}function Gx(n,t,e){WC(),Bx.call(this,n,t,e)}function zx(n,t,e){WC(),Bx.call(this,n,t,e)}function Ux(n,t,e){WC(),zx.call(this,n,t,e)}function Xx(n,t,e){WC(),Hx.call(this,n,t,e)}function Wx(n,t,e){WC(),qx.call(this,n,t,e)}function Vx(n,t){return MF(n),MF(t),new Fj(n,t)}function Qx(n,t){return MF(n),MF(t),new BD(n,t)}function Yx(n,t){return QD(null==n||Oen(n,t)),n}function Jx(n){var t;return zJ(t=new ip,n),t}function Zx(n){var t;return $2(t=new rv,n),t}function nD(n){var t;return $2(t=new ME,n),t}function tD(n){return!n.e&&(n.e=new ip),n.e}function eD(n,t){return n.c[n.c.length]=t,!0}function iD(n,t){this.c=n,this.b=t,this.a=!1}function rD(n){this.d=n,Wl(this),this.b=function(n){return CO(n,15)?Yx(n,15).Yc():n.Kc()}(n.d)}function cD(){this.a=";,;",this.b="",this.c=""}function aD(n,t,e){s_.call(this,t,e),this.a=n}function uD(n,t,e){this.b=n,MI.call(this,t,e)}function oD(n,t,e){this.c=n,zT.call(this,t,e)}function sD(n,t,e){hhn(e,0,n,t,e.length,!1)}function hD(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function fD(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function lD(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function bD(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function wD(n){return $3(function(n){return rO(~n.l&BTn,~n.m&BTn,~n.h&HTn)}(tC(n)?W3(n):n))}function dD(){dD=O,Ikn(),Y3n=qit,J3n=Eit}function gD(){this.b=ty(fL(oen((Bdn(),yGn))))}function pD(n){return HE(),VQ(UKn,iEn,1,n,5,1)}function vD(n){return new QS(n.c+n.b,n.d+n.a)}function mD(n){return S$(0!=n.b),VZ(n,n.a.a)}function yD(n){return S$(0!=n.b),VZ(n,n.c.b)}function kD(n,t){if(!n)throw hp(new qm(t))}function jD(n,t){if(!n)throw hp(new Qm(t))}function ED(n,t,e){LM.call(this,n,t),this.b=e}function TD(n,t,e){XP.call(this,n,t),this.c=e}function MD(n,t,e){RZ.call(this,t,e),this.d=n}function SD(n){gx(),yo.call(this),this.th(n)}function PD(n,t,e){this.a=n,HI.call(this,t,e)}function ID(n,t,e){this.a=n,HI.call(this,t,e)}function CD(n,t,e){XP.call(this,n,t),this.c=e}function OD(){wV(),uB.call(this,(mT(),aat))}function AD(n){return null!=n&&!$7(n,Wct,Vct)}function $D(n,t){return(u9(n)<<4|u9(t))&fTn}function LD(n,t){var e;n.n&&(e=t,eD(n.f,e))}function ND(n,t,e){OZ(n,t,new zF(e))}function xD(n,t){return n.g=t<0?-1:t,n}function DD(n,t){return function(n){var t;(t=e.Math.sqrt(n.a*n.a+n.b*n.b))>0&&(n.a/=t,n.b/=t)}(n),n.a*=t,n.b*=t,n}function RD(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function KD(n,t){return VW(n,t,n.c.b,n.c),!0}function _D(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function FD(n){this.b=n,this.a=DK(this.b.a).Ed()}function BD(n,t){this.b=n,this.a=t,_h.call(this)}function HD(n,t){this.a=n,this.b=t,_h.call(this)}function qD(n,t){s_.call(this,t,1040),this.a=n}function GD(n){return 0==n||isNaN(n)?n:n<0?-1:1}function zD(n,t){return ean(n,new LM(t.a,t.b))}function UD(n){var t;return t=n.n,n.a.b+t.d+t.a}function XD(n){var t;return t=n.n,n.e.b+t.d+t.a}function WD(n){var t;return t=n.n,n.e.a+t.b+t.c}function VD(n){return Ljn(),new BR(0,n)}function QD(n){if(!n)throw hp(new Vm(null))}function YD(){YD=O,XH(),jut=new bb(HRn)}function JD(){JD=O,new _en((wm(),n_n),(dm(),ZKn))}function ZD(){ZD=O,G_n=VQ(U_n,TEn,19,256,0,1)}function nR(n,t,e,i){F7.call(this,n,t,e,i,0,0)}function tR(n){return n.e.c.length+n.g.c.length}function eR(n){return n.e.c.length-n.g.c.length}function iR(n){return n.b.c.length-n.e.c.length}function rR(n){gx(),SD.call(this,n),this.a=-1}function cR(n,t){VP.call(this,n,t),this.a=this}function aR(n,t){var e;return(e=TF(n,t)).i=2,e}function uR(n,t){return++n.j,n.Ti(t)}function oR(n,t,e){return n.a=-1,ZA(n,t.g,e),n}function sR(n,t,e){!function(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g;null==(w=BF(n.e,i))&&(s=Yx(w=new Om,183),o=new zF(t+"_s"+r),OZ(s,rxn,o)),nB(e,b=Yx(w,183)),nq(g=new Om,"x",i.j),nq(g,"y",i.k),OZ(b,uxn,g),nq(f=new Om,"x",i.b),nq(f,"y",i.c),OZ(b,"endPoint",f),!Sj((!i.a&&(i.a=new XO(Qrt,i,5)),i.a))&&(c=new pg(h=new Sl),XW((!i.a&&(i.a=new XO(Qrt,i,5)),i.a),c),OZ(b,YNn,h)),!!Jen(i)&&jun(n.a,b,ZNn,ksn(n,Jen(i))),!!Zen(i)&&jun(n.a,b,JNn,ksn(n,Zen(i))),!(0==(!i.e&&(i.e=new AN(tct,i,10,9)),i.e).i)&&(a=new FP(n,l=new Sl),XW((!i.e&&(i.e=new AN(tct,i,10,9)),i.e),a),OZ(b,txn,l)),0!=(!i.g&&(i.g=new AN(tct,i,9,10)),i.g).i&&(u=new BP(n,d=new Sl),XW((!i.g&&(i.g=new AN(tct,i,9,10)),i.g),u),OZ(b,nxn,d))}(n.a,n.b,n.c,Yx(t,202),e)}function hR(n,t,e){return new xN(function(n){return 0>=n?new EE:function(n){return 0>n?new EE:new vL(null,new cV(n+1,n))}(n-1)}(n).Ie(),e,t)}function fR(n,t,e,i,r,c){return nan(n,t,e,i,r,0,c)}function lR(){lR=O,R_n=VQ(__n,TEn,217,256,0,1)}function bR(){bR=O,X_n=VQ(J_n,TEn,162,256,0,1)}function wR(){wR=O,Z_n=VQ(nFn,TEn,184,256,0,1)}function dR(){dR=O,F_n=VQ(B_n,TEn,172,128,0,1)}function gR(){hD(this,!1,!1,!1,!1)}function pR(n){VF(),this.a=(XH(),new bb(MF(n)))}function vR(n){for(MF(n);n.Ob();)n.Pb(),n.Qb()}function mR(n){this.c=n,this.b=this.c.d.vc().Kc()}function yR(n){this.c=n,this.a=new TE(this.c.a)}function kR(n){this.a=new kE(n.gc()),C2(this,n)}function jR(n){Mb.call(this,new bW),C2(this,n)}function ER(n,t){return n.a+=Vnn(t,0,t.length),n}function TR(n,t){return $z(t,n.c.length),n.c[t]}function MR(n,t){return $z(t,n.a.length),n.a[t]}function SR(n,t){HE(),ZQ.call(this,n),this.a=t}function PR(n,t){return function(n,t){return ytn(t7(ytn(n.a).a,t.a))}(Yx(n,162),Yx(t,162))}function IR(n){return n.c-Yx(TR(n.a,n.b),287).b}function CR(n){return n.q?n.q:(XH(),XH(),MFn)}function OR(n){return n.e.Hd().gc()*n.c.Hd().gc()}function AR(n,t,i){return e.Math.min(i/n,1/t)}function $R(n,t){return n?0:e.Math.max(0,t-1)}function LR(n){var t;return(t=han(n))?LR(t):n}function NR(n,t){return null==n.a&&qdn(n),n.a[t]}function xR(n){return n.c?n.c.f:n.e.b}function DR(n){return n.c?n.c.g:n.e.a}function RR(n){FZ.call(this,n.gc()),jF(this,n)}function KR(n,t){WC(),zg.call(this,t),this.a=n}function _R(n,t,e){this.a=n,XO.call(this,t,e,2)}function FR(n,t,e,i){fD(this,n,t,e,i)}function BR(n,t){Ljn(),np.call(this,n),this.a=t}function HR(n){this.b=new ME,this.a=n,this.c=-1}function qR(){this.d=new QS(0,0),this.e=new Qp}function GR(n){i$.call(this,0,0),this.a=n,this.b=0}function zR(n){this.a=n,this.c=new rp,function(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),rO(i&BTn,r&BTn,c&HTn)}(tC(n)?W3(n):n,t))}function XK(n,t){return function(n,t){return TA(),n==t?0:n?1:-1}((vB(n),n),(vB(t),t))}function WK(n,t){return $9((vB(n),n),(vB(t),t))}function VK(n,t){return MF(t),n.a.Ad(t)&&!n.b.Ad(t)}function QK(n,t){return W8(n,(vB(t),new Pb(t)))}function YK(n,t){return W8(n,(vB(t),new Ib(t)))}function JK(n){return Q2(),0!=Yx(n,11).e.c.length}function ZK(n){return Q2(),0!=Yx(n,11).g.c.length}function n_(n,t,e){return function(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(0!=t.e.c.length&&0!=e.e.c.length){if((i=Yx(TR(t.e,0),17).c.i)==(a=Yx(TR(e.e,0),17).c.i))return eO(Yx(Aun(Yx(TR(t.e,0),17),(Ojn(),IQn)),19).a,Yx(Aun(Yx(TR(e.e,0),17),IQn),19).a);for(f=0,l=(h=n.a).length;fu?1:0:(n.b&&(n.b._b(c)&&(r=Yx(n.b.xc(c),19).a),n.b._b(o)&&(u=Yx(n.b.xc(o),19).a)),ru?1:0)):0!=t.e.c.length&&0!=e.g.c.length?1:-1}(n,Yx(t,11),Yx(e,11))}function t_(n){return n.e?oQ(n.e):null}function e_(n){n.d||(n.d=n.b.Kc(),n.c=n.b.gc())}function i_(n,t){if(n<0||n>=t)throw hp(new Gp)}function r_(n,t,e){return udn(),s3(n,t)&&s3(n,e)}function c_(n){return Chn(),!n.Hc(pit)&&!n.Hc(mit)}function a_(n){return new QS(n.c+n.b/2,n.d+n.a/2)}function u_(n,t){return t.kh()?P8(n.b,Yx(t,49)):t}function o_(n,t){this.e=n,this.d=0!=(64&t)?t|MEn:t}function s_(n,t){this.c=0,this.d=n,this.b=64|t|MEn}function h_(n){this.b=new pQ(11),this.a=(WH(),n)}function f_(n){this.b=null,this.a=(WH(),n||IFn)}function l_(n){this.a=xen(n.a),this.b=new sx(n.b)}function b_(n){this.b=n,a$.call(this,n),FO(this)}function w_(n){this.b=n,o$.call(this,n),BO(this)}function d_(n,t,e){this.a=n,EN.call(this,t,e,5,6)}function g_(n,t,e,i){this.b=n,XO.call(this,t,e,i)}function p_(n,t,e,i,r){kY.call(this,n,t,e,i,r,-1)}function v_(n,t,e,i,r){jY.call(this,n,t,e,i,r,-1)}function m_(n,t,e,i){XO.call(this,n,t,e),this.b=i}function y_(n,t,e,i){TD.call(this,n,t,e),this.b=i}function k_(n){WP.call(this,n,!1),this.a=!1}function j_(n,t){this.b=n,ol.call(this,n.b),this.a=t}function E_(n,t){VF(),Jj.call(this,n,$8(new ay(t)))}function T_(n,t){return Ljn(),new rB(n,t,0)}function M_(n,t){return Ljn(),new rB(6,n,t)}function S_(n,t){return _N(n.substr(0,t.length),t)}function P_(n,t){return aI(t)?hq(n,t):!!Dq(n.f,t)}function I_(n,t){for(vB(t);n.Ob();)t.td(n.Pb())}function C_(n,t,e){bdn(),this.e=n,this.d=t,this.a=e}function O_(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function A_(n){var t;for(t=n;t.f;)t=t.f;return t}function $_(n){var t;return S$(null!=(t=T5(n))),t}function L_(n){var t;return S$(null!=(t=function(n){var t;return null==(t=n.a[n.c-1&n.a.length-1])?null:(n.c=n.c-1&n.a.length-1,DF(n.a,n.c,null),t)}(n))),t}function N_(n,t){var e;return qV(t,e=n.a.gc()),e-t}function x_(n,t){var e;for(e=0;en||n>t)throw hp(new Py("fromIndex: 0, toIndex: "+n+MMn+t))}(t,n.length),new qD(n,t)}(n,n.length))}function W_(n){return new $K(new sA(n.a.length,n.a))}function V_(n){return typeof n===Ujn||typeof n===Qjn}function Q_(n,t){return k8(n,t)<0?-1:k8(n,t)>0?1:0}function Y_(n,t,e){return jmn(n,Yx(t,46),Yx(e,167))}function J_(n,t){return Yx(KK(DK(n.a)).Xb(t),42).cd()}function Z_(n,t){this.d=n,UO.call(this,n),this.e=t}function nF(n){this.d=(vB(n),n),this.a=0,this.c=IEn}function tF(n,t){np.call(this,1),this.a=n,this.b=t}function eF(n,t){return n.c?eF(n.c,t):eD(n.b,t),n}function iF(n,t,e){var i;return i=VJ(n,t),ZX(n,t,e),i}function rF(n,t){return aJ(n.slice(0,t),n)}function cF(n,t,e){var i;for(i=0;i=14&&e<=16);case 11:return null!=t&&typeof t===Qjn;case 12:return null!=t&&(typeof t===Ujn||typeof t==Qjn);case 0:return Oen(t,n.__elementTypeId$);case 2:return V_(t)&&!(t.im===C);case 1:return V_(t)&&!(t.im===C)||Oen(t,n.__elementTypeId$);default:return!0}}(n,e)),n[t]=e}function RF(n,t){var e;return HU(t,e=n.a.gc()),e-1-t}function KF(n,t){return n.a+=String.fromCharCode(t),n}function _F(n,t){return n.a+=String.fromCharCode(t),n}function FF(n,t){for(vB(t);n.c0?(den(n,e,0),e.a+=String.fromCharCode(i),den(n,e,r=htn(t,c)),c+=r-1):39==i?c+1=n.g}function ZF(n,t,e){return tgn(n,h2(n,t,e))}function nB(n,t){var e;VJ(n,e=n.a.length),ZX(n,e,t)}function tB(n,t){console[n].call(console,t)}function eB(n,t){var e;++n.j,e=n.Vi(),n.Ii(n.oi(e,t))}function iB(n,t,e){zg.call(this,t),this.a=n,this.b=e}function rB(n,t,e){np.call(this,n),this.a=t,this.b=e}function cB(n,t,e){this.a=n,Gg.call(this,t),this.b=e}function aB(n,t,e){this.a=n,lX.call(this,8,t,null,e)}function uB(n){this.a=(vB(nRn),nRn),this.b=n,new Xv}function oB(n){this.c=n,this.b=this.c.a,this.a=this.c.e}function sB(n){this.c=n,this.b=n.a.d.a,tL(n.a.e,this)}function hB(n){M$(-1!=n.c),n.d.$c(n.c),n.b=n.c,n.c=-1}function fB(n){return e.Math.sqrt(n.a*n.a+n.b*n.b)}function lB(n,t){return i_(t,n.a.c.length),TR(n.a,t)}function bB(n,t){return iI(n)===iI(t)||null!=n&&Q8(n,t)}function wB(n){return n?n.dc():!n.Kc().Ob()}function dB(n){return!n.a&&n.c?n.c.b:n.a}function gB(n){return!n.a&&(n.a=new XO(Wrt,n,4)),n.a}function pB(n){return!n.d&&(n.d=new XO(hat,n,1)),n.d}function vB(n){if(null==n)throw hp(new Np);return n}function mB(n){n.c?n.c.He():(n.d=!0,function(n){var t,e,i,r,c;if(c=new ip,WZ(n.b,new Gb(c)),n.b.c=VQ(UKn,iEn,1,0,5,1),0!=c.c.length){for($z(0,c.c.length),t=Yx(c.c[0],78),e=1,i=c.c.length;e0;)n=n<<1|(n<0?1:0);return n}function qB(n,t){return iI(n)===iI(t)||null!=n&&Q8(n,t)}function GB(n,t){return rK(n.a,t)?n.b[Yx(t,22).g]:null}function zB(n,t,e,i){n.a=l$(n.a,0,t)+""+i+lI(n.a,e)}function UB(n,t){n.u.Hc((Chn(),pit))&&function(n,t){var i,r,c,a;for(i=(a=Yx(GB(n.b,t),124)).a,c=Yx(Yx(_V(n.r,t),21),84).Kc();c.Ob();)(r=Yx(c.Pb(),111)).c&&(i.a=e.Math.max(i.a,WD(r.c)));if(i.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}(n,t),function(n,t){var e;n.C&&((e=Yx(GB(n.b,t),124).n).d=n.C.d,e.a=n.C.a)}(n,t)}function XB(n,t){return Lz(t,n.length),n.charCodeAt(t)}function WB(){Im.call(this,"There is no more element.")}function VB(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function QB(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function YB(n,t,e,i){return h3(n,t,e,!1),f9(n,i),n}function JB(n){return!n.n&&(n.n=new m_(act,n,1,7)),n.n}function ZB(n){return!n.c&&(n.c=new m_(oct,n,9,9)),n.c}function nH(n){return n.e==qRn&&function(n,t){n.e=t}(n,function(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=lL(ynn((!e.b&&(e.b=new z$((xjn(),Dat),out,e)),e.b),gxn)))?i:t.ne()}(n.g,n.b)),n.e}function tH(n){return n.f==qRn&&function(n,t){n.f=t}(n,function(n,t){var e,i;return(e=t.Hh(n.a))?(i=lL(ynn((!e.b&&(e.b=new z$((xjn(),Dat),out,e)),e.b),RRn)),_N(KRn,i)?OK(n,i1(t.Hj())):i):null}(n.g,n.b)),n.f}function eH(n){var t;return!(t=n.b)&&(n.b=t=new Qf(n)),t}function iH(n){var t;for(t=n.Kc();t.Ob();)t.Pb(),t.Qb()}function rH(n){if(A7(n.d),n.d.d!=n.c)throw hp(new Dp)}function cH(n,t){this.b=n,this.c=t,this.a=new TE(this.b)}function aH(n,t,e){this.a=oTn,this.d=n,this.b=t,this.c=e}function uH(n,t){this.d=(vB(n),n),this.a=16449,this.c=t}function oH(n,t){Q9(n,ty(q1(t,"x")),ty(q1(t,"y")))}function sH(n,t){Q9(n,ty(q1(t,"x")),ty(q1(t,"y")))}function hH(n,t){return W9(n),new SR(n,new _Y(t,n.a))}function fH(n,t){return W9(n),new SR(n,new JV(t,n.a))}function lH(n,t){return W9(n),new pL(n,new QV(t,n.a))}function bH(n,t){return W9(n),new vL(n,new YV(t,n.a))}function wH(n){this.a=new ip,this.e=VQ(Wot,TEn,48,n,0,2)}function dH(n,t,e,i){this.a=n,this.e=t,this.d=e,this.c=i}function gH(n,t,e,i){this.a=n,this.c=t,this.b=e,this.d=i}function pH(n,t,e,i){this.c=n,this.b=t,this.a=e,this.d=i}function vH(n,t,e,i){this.c=n,this.b=t,this.d=e,this.a=i}function mH(n,t,e,i){this.c=n,this.d=t,this.b=e,this.a=i}function yH(n,t,e,i){this.a=n,this.d=t,this.c=e,this.b=i}function kH(n,t,e,i){Uj.call(this,n,t),this.a=e,this.b=i}function jH(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function EH(n,t,i){(function(n,t){var e,i,r,c;for(function(n){var t;for(t=0;t(i=oG(e))&&++i,i}function SH(n){var t;return b1(t=new up,n),t}function PH(n){var t;return Xun(t=new up,n),t}function IH(n){return function(n){var t;return CO(t=Aun(n,(Ojn(),CQn)),160)?W7(Yx(t,160)):null}(n)||null}function CH(n){return!n.b&&(n.b=new m_(nct,n,12,3)),n.b}function OH(n,t,e){e.a?N1(n,t.b-n.f/2):L1(n,t.a-n.g/2)}function AH(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function $H(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function LH(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function NH(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function xH(n,t,e,i){WC(),AV.call(this,t,e,i),this.a=n}function DH(n,t,e,i){WC(),AV.call(this,t,e,i),this.a=n}function RH(n,t){this.a=n,gL.call(this,n,Yx(n.d,15).Zc(t))}function KH(n){this.f=n,this.c=this.f.e,n.f>0&&Icn(this)}function _H(n,t,e,i){this.b=n,this.c=i,PI.call(this,t,e)}function FH(n){return S$(n.b0?(e.Error.stackTraceLimit=Error.stackTraceLimit=64,1):"stack"in new Error),n=new d,p_n=t?new E:n}function Lq(n,t){var e;return e=Nk(n.gm),null==t?e:e+": "+t}function Nq(n,t){var e;return pW(e=n.b.Qc(t),n.b.gc()),e}function xq(n,t){if(null==n)throw hp(new Zm(t));return n}function Dq(n,t){return q6(n,t,function(n,t){var e;return null==(e=n.a.get(t))?new Array:e}(n,null==t?0:n.b.se(t)))}function Rq(n,t,e){return e>=0&&_N(n.substr(e,t.length),t)}function Kq(n,t,e,i,r,c,a){return new oW(n.e,t,e,i,r,c,a)}function _q(n,t,e,i,r,c){this.a=n,E0.call(this,t,e,i,r,c)}function Fq(n,t,e,i,r,c){this.a=n,E0.call(this,t,e,i,r,c)}function Bq(n,t){this.g=n,this.d=x4(Gy(Gzn,1),kIn,10,0,[t])}function Hq(n,t){this.e=n,this.a=UKn,this.b=Zdn(t),this.c=t}function qq(n,t){sN.call(this),YZ(this),this.a=n,this.c=t}function Gq(n,t,e,i){DF(n.c[t.g],e.g,i),DF(n.c[e.g],t.g,i)}function zq(n,t,e,i){DF(n.c[t.g],t.g,e),DF(n.b[t.g],t.g,i)}function Uq(n,t,e,i){return e>=0?n.jh(t,e,i):n.Sg(null,e,i)}function Xq(n){return 0==n.b.b?n.a.$e():mD(n.b)}function Wq(n){return iI(n.a)===iI((W2(),Gat))&&function(n){var t,e,i,r,c,a,u,o,s,h;for(t=new To,e=new To,s=_N(ZDn,(r=dpn(n.b,nRn))?lL(ynn((!r.b&&(r.b=new z$((xjn(),Dat),out,r)),r.b),tRn)):null),o=0;o=0?n.sh(i,e):pbn(n,t,e)}function wG(n,t,e){_G(),n&&xB(Sct,n,t),n&&xB(Mct,n,e)}function dG(n,t,e){this.i=new ip,this.b=n,this.g=t,this.a=e}function gG(n,t,e){this.c=new ip,this.e=n,this.f=t,this.b=e}function pG(n,t,e){this.a=new ip,this.e=n,this.f=t,this.c=e}function vG(n,t){jO(this),this.f=t,this.g=n,qH(this),this._d()}function mG(n,t){var e;e=n.q.getHours(),n.q.setDate(t),Ivn(n,e)}function yG(n,t){var e;for(MF(t),e=n.a;e;e=e.c)t.Od(e.g,e.i)}function kG(n){var t;return L5(t=new Xk(IZ(n.length)),n),t}function jG(n,t){if(null==t)throw hp(new Np);return function(n,t){var e,i=n.a;t=String(t),i.hasOwnProperty(t)&&(e=i[t]);var r=(r5(),S_n)[typeof e];return r?r(e):Z6(typeof e)}(n,t)}function EG(n){return n.Db>>16!=3?null:Yx(n.Cb,33)}function TG(n){return n.Db>>16!=9?null:Yx(n.Cb,33)}function MG(n){return n.Db>>16!=6?null:Yx(n.Cb,79)}function SG(n){return n.Db>>16!=7?null:Yx(n.Cb,235)}function PG(n){return n.Db>>16!=7?null:Yx(n.Cb,160)}function IG(n){return n.Db>>16!=11?null:Yx(n.Cb,33)}function CG(n,t){var e;return(e=n.Yg(t))>=0?n.lh(e):zhn(n,t)}function OG(n,t){var e;return Eun(e=new jR(t),n),new sx(e)}function AG(n){var t;return t=n.d,t=n.si(n.f),fY(n,t),t.Ob()}function $G(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function LG(n,t){return e.Math.abs(n)>16!=3?null:Yx(n.Cb,147)}function BG(n){return n.Db>>16!=6?null:Yx(n.Cb,235)}function HG(n){return n.Db>>16!=17?null:Yx(n.Cb,26)}function qG(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.le(t))}function GG(n,t,e){return null==t?Ysn(n.f,null,e):r7(n.g,t,e)}function zG(n,t,e,i,r,c){return new yJ(n.e,t,n.aj(),e,i,r,c)}function UG(n,t,e){return n.a=l$(n.a,0,t)+""+e+lI(n.a,t),n}function XG(n,t,e){return eD(n.a,(KB(),gin(t,e),new Wj(t,e))),n}function WG(n){return jA(n.c),n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function VG(n){return jA(n.e),n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function QG(n,t){n.d&&uJ(n.d.e,n),n.d=t,n.d&&eD(n.d.e,n)}function YG(n,t){n.c&&uJ(n.c.g,n),n.c=t,n.c&&eD(n.c.g,n)}function JG(n,t){n.c&&uJ(n.c.a,n),n.c=t,n.c&&eD(n.c.a,n)}function ZG(n,t){n.i&&uJ(n.i.j,n),n.i=t,n.i&&eD(n.i.j,n)}function nz(n,t,e){this.a=t,this.c=n,this.b=(MF(e),new sx(e))}function tz(n,t,e){this.a=t,this.c=n,this.b=(MF(e),new sx(e))}function ez(n,t){this.a=n,this.c=dO(this.a),this.b=new Tq(t)}function iz(n,t){if(n<0||n>t)throw hp(new Hm(RMn+n+KMn+t))}function rz(n,t){return cK(n.a,t)?K_(n,Yx(t,22).g,null):null}function cz(){cz=O,o_n=z6((pm(),x4(Gy(s_n,1),XEn,538,0,[a_n])))}function az(){az=O,A3n=yK(new fX,($un(),tzn),($jn(),iXn))}function uz(){uz=O,$3n=yK(new fX,($un(),tzn),($jn(),iXn))}function oz(){oz=O,N3n=yK(new fX,($un(),tzn),($jn(),iXn))}function sz(){sz=O,c4n=oR(new fX,($un(),tzn),($jn(),CUn))}function hz(){hz=O,h4n=oR(new fX,($un(),tzn),($jn(),CUn))}function fz(){fz=O,b4n=oR(new fX,($un(),tzn),($jn(),CUn))}function lz(){lz=O,j4n=oR(new fX,($un(),tzn),($jn(),CUn))}function bz(){bz=O,c6n=yK(new fX,(Krn(),n5n),(ysn(),c5n))}function wz(n,t,e,i){this.c=n,this.d=i,pz(this,t),vz(this,e)}function dz(n){this.c=new ME,this.b=n.b,this.d=n.c,this.a=n.a}function gz(n){this.a=e.Math.cos(n),this.b=e.Math.sin(n)}function pz(n,t){n.a&&uJ(n.a.k,n),n.a=t,n.a&&eD(n.a.k,n)}function vz(n,t){n.b&&uJ(n.b.f,n),n.b=t,n.b&&eD(n.b.f,n)}function mz(n,t){(function(n,t,e){Yx(t.b,65),WZ(t.a,new xx(n,e,t))})(n,n.b,n.c),Yx(n.b.b,65),t&&Yx(t.b,65).b}function yz(n,t){CO(n.Cb,88)&&rhn(bV(Yx(n.Cb,88)),4),E2(n,t)}function kz(n,t){CO(n.Cb,179)&&(Yx(n.Cb,179).tb=null),E2(n,t)}function jz(n,t){return TT(),GJ(t)?new cR(t,n):new VP(t,n)}function Ez(n){var t;return Rk(),b1(t=new up,n),t}function Tz(n){var t;return Rk(),b1(t=new up,n),t}function Mz(n,t){var e;return e=new qF(n),t.c[t.c.length]=e,e}function Sz(n,t){var e;return(e=Yx(x8(QH(n.a),t),14))?e.gc():0}function Pz(n){return W9(n),WH(),WH(),HZ(n,CFn)}function Iz(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function Cz(n,t){cm.call(this,new kE(IZ(n))),g0(t,EEn),this.a=t}function Oz(n,t,e){i9(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function Az(n,t,e){var i;i9(t,e,n.c.length),i=e-t,uj(n.c,t,i)}function $z(n,t){if(n<0||n>=t)throw hp(new Hm(RMn+n+KMn+t))}function Lz(n,t){if(n<0||n>=t)throw hp(new Ly(RMn+n+KMn+t))}function Nz(n,t){this.b=(vB(n),n),this.a=0==(t&nMn)?64|t|MEn:t}function xz(n){$C(this),zp(this.a,j5(e.Math.max(8,n))<<1)}function Dz(n){return $5(x4(Gy(B7n,1),TEn,8,0,[n.i.n,n.n,n.a]))}function Rz(n,t){return function(n,t,e){var i,r,c,a,u,o;if(a=new go,u=dwn(n.e.Tg(),t),i=Yx(n.g,119),TT(),Yx(t,66).Oj())for(c=0;c0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function PU(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function IU(n){return hR(n.e.Hd().gc()*n.c.Hd().gc(),16,new qf(n))}function CU(n){return Yx(Htn(n,VQ(Nzn,yIn,17,n.c.length,0,1)),474)}function OU(n){return Yx(Htn(n,VQ(Gzn,kIn,10,n.c.length,0,1)),193)}function AU(n,t,e){MF(n),function(n){var t,e,i;for(XH(),JC(n.c,n.a),i=new pb(n.c);i.a=0&&d=t)throw hp(new Hm(function(n,t){if(n<0)return ngn(eEn,x4(Gy(UKn,1),iEn,1,5,["index",d9(n)]));if(t<0)throw hp(new Qm(rEn+t));return ngn("%s (%s) must be less than size (%s)",x4(Gy(UKn,1),iEn,1,5,["index",d9(n),d9(t)]))}(n,t)));return n}function qU(n,t,e){if(n<0||te)throw hp(new Hm(function(n,t,e){return n<0||n>e?Usn(n,e,"start index"):t<0||t>e?Usn(t,e,"end index"):ngn("end index (%s) must not be less than start index (%s)",x4(Gy(UKn,1),iEn,1,5,[d9(t),d9(n)]))}(n,t,e)))}function GU(n,t){if(__(n.a,t),t.d)throw hp(new Im(GMn));t.d=n}function zU(n,t){if(t.$modCount!=n.$modCount)throw hp(new Dp)}function UU(n,t){return!!CO(t,42)&&Fin(n.a,Yx(t,42))}function XU(n,t){return!!CO(t,42)&&Fin(n.a,Yx(t,42))}function WU(n,t){return!!CO(t,42)&&Fin(n.a,Yx(t,42))}function VU(n){var t;return tC(n)?-0==(t=n)?0:t:function(n){return gcn(n,(LJ(),A_n))<0?-function(n){return n.l+n.m*GTn+n.h*zTn}(h5(n)):n.l+n.m*GTn+n.h*zTn}(n)}function QU(n){var t;return yB(n),t=new F,Qk(n.a,new _b(t)),t}function YU(n){var t;return yB(n),t=new _,Qk(n.a,new Kb(t)),t}function JU(n,t){this.a=n,Vl.call(this,n),iz(t,n.gc()),this.b=t}function ZU(n){this.e=n,this.b=this.e.a.entries(),this.a=new Array}function nX(n){return new pQ((g0(n,VEn),PZ(t7(t7(5,n),n/10|0))))}function tX(n){return Yx(Htn(n,VQ(rUn,jIn,11,n.c.length,0,1)),1943)}function eX(n,t,e){n.d&&uJ(n.d.e,n),n.d=t,n.d&&ZR(n.d.e,e,n)}function iX(n,t){(function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(m=0,0==t.f.b)for(p=new pb(n);p.a2e3&&(k_n=n,j_n=e.setTimeout(Ij,10)),0==y_n++&&(function(n){var t,e;if(n.a){e=null;do{t=n.a,n.a=null,e=Zon(t,e)}while(n.a);n.a=e}}((py(),g_n)),!0)}();try{return function(n,t,e){return n.apply(t,e)}(n,t,i)}finally{!function(n){n&&function(n){var t,e;if(n.b){e=null;do{t=n.b,n.b=null,e=Zon(t,e)}while(n.b);n.b=e}}((py(),g_n)),--y_n,n&&-1!=j_n&&(function(n){e.clearTimeout(n)}(j_n),j_n=-1)}(r)}}function hX(n){var t;t=n.Wg(),this.a=CO(t,69)?Yx(t,69).Zh():t.Kc()}function fX(){hm.call(this),this.j.c=VQ(UKn,iEn,1,0,5,1),this.a=-1}function lX(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function bX(n,t,e,i){this.e=i,this.d=null,this.c=n,this.a=t,this.b=e}function wX(n,t,e){this.d=new sd(this),this.e=n,this.i=t,this.f=e}function dX(){dX=O,zVn=new nS(pSn,0),UVn=new nS("TOP_LEFT",1)}function gX(){gX=O,K3n=RB(d9(1),d9(4)),R3n=RB(d9(1),d9(2))}function pX(){pX=O,l9n=z6((eT(),x4(Gy(d9n,1),XEn,551,0,[h9n])))}function vX(){vX=O,s9n=z6((tT(),x4(Gy(f9n,1),XEn,482,0,[u9n])))}function mX(){mX=O,a7n=z6((iT(),x4(Gy(s7n,1),XEn,530,0,[r7n])))}function yX(){yX=O,yqn=z6((BE(),x4(Gy(Bqn,1),XEn,481,0,[vqn])))}function kX(n,t,e,i){return CO(e,54)?new C$(n,t,e,i):new LK(n,t,e,i)}function jX(n,t){return Yx(qA(QK(Yx(_V(n.k,t),15).Oc(),hWn)),113)}function EX(n,t){return Yx(qA(YK(Yx(_V(n.k,t),15).Oc(),hWn)),113)}function TX(n){return new Nz(function(n,t){var e,i;for(XH(),i=new ip,e=0;e0}function IX(n){return S$(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function CX(n,t){vB(t),DF(n.a,n.c,t),n.c=n.c+1&n.a.length-1,vrn(n)}function OX(n,t){vB(t),n.b=n.b-1&n.a.length-1,DF(n.a,n.b,t),vrn(n)}function AX(n,t){var e;for(e=n.j.c.length;e0&&smn(n.g,0,t,0,n.i),t}function _X(n,t){var e;return MT(),!(e=Yx(BF(Nct,n),55))||e.wj(t)}function FX(n){var t;for(t=0;n.Ob();)n.Pb(),t=t7(t,1);return PZ(t)}function BX(n,t){var e;return e=new $y,n.xd(e),e.a+="..",t.yd(e),e.a}function HX(n,t,e){return fvn(n,t,e,CO(t,99)&&0!=(Yx(t,18).Bb&eMn))}function qX(n,t,e){return function(n,t,e,i){var r,c,a,u,o,s;if(u=new go,o=dwn(n.e.Tg(),t),r=Yx(n.g,119),TT(),Yx(t,66).Oj())for(a=0;an.c));a++)r.a>=n.s&&(c<0&&(c=a),u=a);return o=(n.s+n.c)/2,c>=0&&(o=function(n){return(n.c+n.a)/2}(($z(i=function(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w;if(c=e,e=e&&(i=t,c=(o=(u.c+u.a)/2)-e,u.c<=o-e&&ZR(n,i++,new Lx(u.c,c)),(a=o+e)<=u.a&&(r=new Lx(a,u.a),iz(i,n.c.length),GT(n.c,i,r)))}(t,i,e)),o}(r,e,i))),function(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new wz((iQ(),K4n),t,c,1),new wz(K4n,c,a,1),r=new pb(e);r.a0;)i+=n.a[e],e-=e&-e;return i}function UW(n,t){var e;for(e=t;e;)$$(n,-e.i,-e.j),e=IG(e);return n}function XW(n,t){var e,i;for(vB(t),i=n.Kc();i.Ob();)e=i.Pb(),t.td(e)}function WW(n,t){var e;return new Wj(e=t.cd(),n.e.pc(e,Yx(t.dd(),14)))}function VW(n,t,e,i){var r;(r=new $).c=t,r.b=e,r.a=i,i.b=e.a=r,++n.b}function QW(n,t,e){var i;return $z(t,n.c.length),i=n.c[t],n.c[t]=e,i}function YW(n){return n.c&&n.d?Yz(n.c)+"->"+Yz(n.d):"e_"+_A(n)}function JW(n,t){return(W9(n),ej(new SR(n,new _Y(t,n.a)))).sd(dBn)}function ZW(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function nV(n){if(!n.c.Sb())throw hp(new Kp);return n.a=!0,n.c.Ub()}function tV(n){n.i=0,qT(n.b,null),qT(n.c,null),n.a=null,n.e=null,++n.g}function eV(n){KT.call(this,null==n?aEn:I7(n),CO(n,78)?Yx(n,78):null)}function iV(n){Tjn(),sp(this),this.a=new ME,a6(this,n),KD(this.a,n)}function rV(){AC(this),this.b=new QS(JTn,JTn),this.a=new QS(ZTn,ZTn)}function cV(n,t){this.c=0,this.b=t,SI.call(this,n,17493),this.a=this.c}function aV(n){uV(),hBn||(this.c=n,this.e=!0,this.a=new ip)}function uV(){uV=O,hBn=!0,oBn=!1,sBn=!1,lBn=!1,fBn=!1}function oV(n,t){return!!CO(t,149)&&_N(n.c,Yx(t,149).c)}function sV(n,t){var e;return e=0,n&&(e+=n.f.a/2),t&&(e+=t.f.a/2),e}function hV(n,t){return Yx(UJ(n.d,t),23)||Yx(UJ(n.e,t),23)}function fV(n){this.b=n,UO.call(this,n),this.a=Yx(H3(this.b.a,4),126)}function lV(n){this.b=n,u$.call(this,n),this.a=Yx(H3(this.b.a,4),126)}function bV(n){return n.t||(n.t=new Kg(n),y9(new Um(n),0,n.t)),n.t}function wV(){var n,t;wV=O,Rk(),t=new Bp,gut=t,n=new qv,put=n}function dV(n){var t;return n.c||CO(t=n.r,88)&&(n.c=Yx(t,26)),n.c}function gV(n){return rO(n&BTn,n>>22&BTn,n<0?HTn:0)}function pV(n,t){var e,i;(e=Yx(function(n,t){MF(n);try{return n.Bc(t)}catch(n){if(CO(n=j4(n),205)||CO(n,173))return null;throw hp(n)}}(n.c,t),14))&&(i=e.gc(),e.$b(),n.d-=i)}function vV(n,t){var e;return!!(e=c6(n,t.cd()))&&qB(e.e,t.dd())}function mV(n,t){return 0==t||0==n.e?n:t>0?Nnn(n,t):Own(n,-t)}function yV(n,t){return 0==t||0==n.e?n:t>0?Own(n,t):Nnn(n,-t)}function kV(n){if(Vfn(n))return n.c=n.a,n.a.Pb();throw hp(new Kp)}function jV(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(bon(),_zn)&&e.k==_zn}function EV(n){var t;return o4(t=new jq,n),b5(t,(gjn(),$1n),null),t}function TV(n,t,e){var i;return(i=n.Yg(t))>=0?n._g(i,e,!0):tfn(n,t,e)}function MV(n,t,e,i){var r;for(r=0;rt)throw hp(new Hm(Usn(n,t,"index")));return n}function GV(n,t,e,i){var r;return function(n,t,e,i,r){var c,a;for(c=0,a=0;an.d[r.p]&&(e+=zW(n.b,i)*Yx(a.b,19).a,OX(n.a,d9(i)));for(;!ry(n.a);)eZ(n.b,Yx($_(n.a),19).a)}return e}(n,e)}function uQ(n){var t;return n.a||CO(t=n.r,148)&&(n.a=Yx(t,148)),n.a}function oQ(n){return n.a?n.e?oQ(n.e):null:n}function sQ(n,t){return vB(t),n.c=0,"Initial capacity must not be negative")}function vQ(){vQ=O,oHn=z6((JZ(),x4(Gy(sHn,1),XEn,232,0,[rHn,cHn,aHn])))}function mQ(){mQ=O,dHn=z6((BY(),x4(Gy(gHn,1),XEn,461,0,[fHn,hHn,lHn])))}function yQ(){yQ=O,kHn=z6((OJ(),x4(Gy(GHn,1),XEn,462,0,[mHn,vHn,pHn])))}function kQ(){kQ=O,bBn=z6((C6(),x4(Gy(wBn,1),XEn,132,0,[cBn,aBn,uBn])))}function jQ(){jQ=O,XGn=z6((CJ(),x4(Gy(ezn,1),XEn,379,0,[GGn,qGn,zGn])))}function EQ(){EQ=O,Ozn=z6((e9(),x4(Gy(Lzn,1),XEn,423,0,[Izn,Pzn,Szn])))}function TQ(){TQ=O,PWn=z6((O0(),x4(Gy(AWn,1),XEn,314,0,[TWn,EWn,MWn])))}function MQ(){MQ=O,$Wn=z6((f0(),x4(Gy(KWn,1),XEn,337,0,[IWn,OWn,CWn])))}function SQ(){SQ=O,WWn=z6((i5(),x4(Gy(tVn,1),XEn,450,0,[zWn,GWn,UWn])))}function PQ(){PQ=O,ZXn=z6((v2(),x4(Gy(oWn,1),XEn,361,0,[YXn,QXn,VXn])))}function IQ(){IQ=O,GVn=z6((AJ(),x4(Gy(XVn,1),XEn,303,0,[BVn,HVn,FVn])))}function CQ(){CQ=O,_Vn=z6((r4(),x4(Gy(qVn,1),XEn,292,0,[DVn,RVn,xVn])))}function OQ(){OQ=O,E2n=z6((i8(),x4(Gy(I2n,1),XEn,378,0,[m2n,y2n,k2n])))}function AQ(){AQ=O,f3n=z6((d3(),x4(Gy(w3n,1),XEn,375,0,[u3n,o3n,s3n])))}function $Q(){$Q=O,Y2n=z6((k5(),x4(Gy(n3n,1),XEn,339,0,[W2n,X2n,V2n])))}function LQ(){LQ=O,a3n=z6((h0(),x4(Gy(h3n,1),XEn,452,0,[r3n,e3n,i3n])))}function NQ(){NQ=O,O3n=z6((F4(),x4(Gy(F3n,1),XEn,377,0,[P3n,I3n,S3n])))}function xQ(){xQ=O,y3n=z6(($6(),x4(Gy(T3n,1),XEn,336,0,[g3n,p3n,v3n])))}function DQ(){DQ=O,M3n=z6((V2(),x4(Gy(C3n,1),XEn,338,0,[E3n,k3n,j3n])))}function RQ(){RQ=O,W3n=z6((l0(),x4(Gy(V3n,1),XEn,454,0,[G3n,z3n,U3n])))}function KQ(){KQ=O,v6n=z6((m7(),x4(Gy(k6n,1),XEn,442,0,[g6n,w6n,d6n])))}function _Q(){_Q=O,P6n=z6((I6(),x4(Gy(r8n,1),XEn,380,0,[E6n,T6n,M6n])))}function FQ(){FQ=O,g8n=z6((p7(),x4(Gy(W8n,1),XEn,381,0,[b8n,w8n,l8n])))}function BQ(){BQ=O,h8n=z6((w3(),x4(Gy(f8n,1),XEn,293,0,[u8n,o8n,a8n])))}function HQ(){HQ=O,a9n=z6((v7(),x4(Gy(o9n,1),XEn,437,0,[e9n,i9n,r9n])))}function qQ(){qQ=O,Det=z6((O8(),x4(Gy(Bet,1),XEn,334,0,[Let,$et,Net])))}function GQ(){GQ=O,set=z6((ZZ(),x4(Gy(det,1),XEn,272,0,[cet,aet,uet])))}function zQ(n,t){return!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),mnn(n.o,t)}function UQ(n){return!n.g&&(n.g=new oo),!n.g.c&&(n.g.c=new Rg(n)),n.g.c}function XQ(n,t,e){var i,r;if(null!=e)for(i=0;i=r){for(a=1;ae||t=0?n._g(e,!0,!0):tfn(n,t,!0)}function MY(){MY=O,a6n=ltn(ltn(bT(new fX,(Krn(),J4n)),(ysn(),h5n)),a5n)}function SY(n){for(;!n.a;)if(!HN(n.c,new Fb(n)))return!1;return!0}function PY(n){return MF(n),CO(n,198)?Yx(n,198):new al(n)}function IY(){var n,t,e,i;IY=O,d7n=new bu,p7n=new wu,Cjn(),n=Ttt,t=d7n,e=itt,i=p7n,KB(),g7n=new Em(x4(Gy(i_n,1),DEn,42,0,[(gin(n,t),new Wj(n,t)),(gin(e,i),new Wj(e,i))]))}function CY(){CY=O,m6n=new xS("LEAF_NUMBER",0),y6n=new xS("NODE_SIZE",1)}function OY(n){n.a=VQ(Wot,MTn,25,n.b+1,15,1),n.c=VQ(Wot,MTn,25,n.b,15,1),n.d=0}function AY(n,t){if(null==n.g||t>=n.i)throw hp(new BI(t,n.i));return n.g[t]}function $Y(n,t,e){if(k6(n,e),null!=e&&!n.wj(e))throw hp(new Op);return e}function LY(n){var t;if(n.Ek())for(t=n.i-1;t>=0;--t)c1(n,t);return KX(n)}function NY(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function xY(n,t){var e;return nW(t),(e=aJ(n.slice(0,t),n)).length=t,e}function DY(n,t,e,i){WH(),i=i||IFn,Xsn(n.slice(t,e),n,t,e,-t,i)}function RY(n,t,e,i,r){return t<0?tfn(n,e,i):Yx(e,66).Nj().Pj(n,n.yh(),t,i,r)}function KY(n,t){if(t.a)throw hp(new Im(GMn));__(n.a,t),t.a=n,!n.j&&(n.j=t)}function _Y(n,t){PI.call(this,t.rd(),-16449&t.qd()),vB(n),this.a=n,this.c=t}function FY(n,t){var e,i;return i=t/n.c.Hd().gc()|0,e=t%n.c.Hd().gc(),bQ(n,i,e)}function BY(){BY=O,fHn=new oM(ySn,0),hHn=new oM(pSn,1),lHn=new oM(kSn,2)}function HY(){HY=O,WFn=new _T("All",0),VFn=new CC,QFn=new hO,YFn=new OC}function qY(){qY=O,ZFn=z6((HY(),x4(Gy(nBn,1),XEn,297,0,[WFn,VFn,QFn,YFn])))}function GY(){GY=O,vzn=z6((_4(),x4(Gy(Czn,1),XEn,405,0,[bzn,gzn,wzn,dzn])))}function zY(){zY=O,ZHn=z6((e4(),x4(Gy(rqn,1),XEn,406,0,[YHn,WHn,VHn,QHn])))}function UY(){UY=O,cqn=z6((Sen(),x4(Gy(aqn,1),XEn,323,0,[tqn,nqn,eqn,iqn])))}function XY(){XY=O,pqn=z6((Pen(),x4(Gy(mqn,1),XEn,394,0,[bqn,lqn,wqn,dqn])))}function WY(){WY=O,e5n=z6((Krn(),x4(Gy(i5n,1),XEn,393,0,[Y4n,J4n,Z4n,n5n])))}function VY(){VY=O,jXn=z6((R4(),x4(Gy(AXn,1),XEn,360,0,[yXn,vXn,mXn,pXn])))}function QY(){QY=O,c8n=z6((Hin(),x4(Gy(s8n,1),XEn,340,0,[i8n,t8n,e8n,n8n])))}function YY(){YY=O,RXn=z6((K4(),x4(Gy(qXn,1),XEn,411,0,[$Xn,LXn,NXn,xXn])))}function JY(){JY=O,C2n=z6((Hen(),x4(Gy(x2n,1),XEn,197,0,[S2n,P2n,M2n,T2n])))}function ZY(){ZY=O,Srt=z6((P6(),x4(Gy(Crt,1),XEn,396,0,[jrt,Ert,krt,Trt])))}function nJ(){nJ=O,Het=z6((Frn(),x4(Gy(Jet,1),XEn,285,0,[Fet,Ret,Ket,_et])))}function tJ(){tJ=O,get=z6((g7(),x4(Gy(Eet,1),XEn,218,0,[wet,fet,het,bet])))}function eJ(){eJ=O,mrt=z6((unn(),x4(Gy(yrt,1),XEn,311,0,[prt,wrt,grt,drt])))}function iJ(){iJ=O,ert=z6((Ann(),x4(Gy(lrt,1),XEn,374,0,[Zit,nrt,Jit,Yit])))}function rJ(){rJ=O,Jvn(),iot=JTn,eot=ZTn,cot=new ib(JTn),rot=new ib(ZTn)}function cJ(){cJ=O,rVn=new WM(fIn,0),iVn=new WM("IMPROVE_STRAIGHTNESS",1)}function aJ(n,t){return 10!=QJ(t)&&x4(V5(t),t.hm,t.__elementTypeId$,QJ(t),n),n}function uJ(n,t){var e;return-1!=(e=hJ(n,t,0))&&(KV(n,e),!0)}function oJ(n,t){var e;return(e=Yx(zV(n.e,t),387))?(_D(e),e.e):null}function sJ(n){var t;return tC(n)&&(t=0-n,!isNaN(t))?t:$3(h5(n))}function hJ(n,t,e){for(;e0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=e.Math.min(n.c,n.f[s.p]),n.b=e.Math.max(n.b,n.f[s.p])):u&&(n.f[s.p]=l)}}(n,t,i),0==n.a.c.length||function(n,t){var e,i,r,c,a,u,o,s,h,f;for(s=n.e[t.c.p][t.p]+1,o=t.c.a.c.length+1,u=new pb(n.a);u.a=0?$en(n,e,!0,!0):tfn(n,t,!0)}function _J(n,t){var e,i;return JE(),e=SX(n),i=SX(t),!!e&&!!i&&!Een(e.k,i.k)}function FJ(n){(this.q?this.q:(XH(),XH(),MFn)).Ac(n.q?n.q:(XH(),XH(),MFn))}function BJ(n,t){sqn=new it,gqn=t,Yx((oqn=n).b,65),QQ(oqn,sqn,null),Bmn(oqn)}function HJ(n,t,e){var i;return i=n.g[t],_O(n,t,n.oi(t,e)),n.gi(t,e,i),n.ci(),i}function qJ(n,t){var e;return(e=n.Xc(t))>=0&&(n.$c(e),!0)}function GJ(n){var t;return n.d!=n.r&&(t=fcn(n),n.e=!!t&&t.Cj()==KDn,n.d=t),n.e}function zJ(n,t){var e;for(MF(n),MF(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function UJ(n,t){var e;return(e=Yx(BF(n.e,t),387))?(OO(n,e),e.e):null}function XJ(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function WJ(n,t){return W9(n),new SR(n,new VN(new JV(t,n.a)))}function VJ(n,t){var e=n.a[t],i=(r5(),S_n)[typeof e];return i?i(e):Z6(typeof e)}function QJ(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function YJ(n){var t;return null!=(t=0==n.b.c.length?null:TR(n.b,0))&&e2(n,0),t}function JJ(n,t){for(;t[0]=0;)++t[0]}function ZJ(n,t){this.e=t,this.a=h4(n),this.a<54?this.f=VU(n):this.c=Utn(n)}function nZ(n,t,e,i){Ljn(),np.call(this,26),this.c=n,this.a=t,this.d=e,this.b=i}function tZ(n,t,e){var i,r;for(i=10,r=0;rn.a[i]&&(i=e);return i}function uZ(n,t){return 0==t.e||0==n.e?pFn:(jfn(),Vbn(n,t))}function oZ(){oZ=O,kzn=new St,jzn=new Tt,mzn=new At,yzn=new $t,Ezn=new Lt}function sZ(){sZ=O,$Bn=new cM("BY_SIZE",0),LBn=new cM("BY_SIZE_AND_SHAPE",1)}function hZ(){hZ=O,Qqn=new fM("EADES",0),Yqn=new fM("FRUCHTERMAN_REINGOLD",1)}function fZ(){fZ=O,FWn=new zM("READING_DIRECTION",0),BWn=new zM("ROTATION",1)}function lZ(){lZ=O,_Wn=z6((min(),x4(Gy(HWn,1),XEn,335,0,[NWn,LWn,DWn,RWn,xWn])))}function bZ(){bZ=O,D2n=z6((ain(),x4(Gy(z2n,1),XEn,315,0,[N2n,A2n,$2n,O2n,L2n])))}function wZ(){wZ=O,GXn=z6((Tan(),x4(Gy(JXn,1),XEn,363,0,[_Xn,BXn,HXn,FXn,KXn])))}function dZ(){dZ=O,cYn=z6((d7(),x4(Gy(p2n,1),XEn,163,0,[iYn,ZQn,nYn,tYn,eYn])))}function gZ(){gZ=O,E9n=z6((Aon(),x4(Gy(c7n,1),XEn,316,0,[p9n,v9n,k9n,m9n,y9n])))}function pZ(){pZ=O,P7n=z6((Qtn(),x4(Gy(D7n,1),XEn,175,0,[T7n,E7n,k7n,M7n,j7n])))}function vZ(){vZ=O,t9n=z6((xbn(),x4(Gy(c9n,1),XEn,355,0,[Q8n,V8n,J8n,Y8n,Z8n])))}function mZ(){mZ=O,izn=z6(($un(),x4(Gy(azn,1),XEn,356,0,[YGn,JGn,ZGn,nzn,tzn])))}function yZ(){yZ=O,ret=z6((t9(),x4(Gy(oet,1),XEn,103,0,[tet,net,Ztt,Jtt,eet])))}function kZ(){kZ=O,ait=z6((Ytn(),x4(Gy(bit,1),XEn,249,0,[eit,rit,nit,tit,iit])))}function jZ(){jZ=O,zit=z6((Ikn(),x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit])))}function EZ(n,t){var e;return(e=Yx(BF(n.a,t),134))||(e=new Zn,xB(n.a,t,e)),e}function TZ(n){var t;return!!(t=Yx(Aun(n,(Ojn(),YVn)),305))&&t.a==n}function MZ(n){var t;return!!(t=Yx(Aun(n,(Ojn(),YVn)),305))&&t.i==n}function SZ(n,t){return vB(t),e_(n),!!n.d.Ob()&&(t.td(n.d.Pb()),!0)}function PZ(n){return k8(n,Yjn)>0?Yjn:k8(n,nTn)<0?nTn:WR(n)}function IZ(n){return n<3?(g0(n,GEn),n+1):n=0&&t=-.01&&n.a<=SSn&&(n.a=0),n.b>=-.01&&n.b<=SSn&&(n.b=0),n}function $Z(n,t){return t==(bx(),bx(),_Fn)?n.toLocaleLowerCase():n.toLowerCase()}function LZ(n){return(0!=(2&n.i)?"interface ":0!=(1&n.i)?"":"class ")+(sL(n),n.o)}function NZ(n){var t;t=new zv,fY((!n.q&&(n.q=new m_(fat,n,11,10)),n.q),t)}function xZ(n){this.g=n,this.f=new ip,this.a=e.Math.min(this.g.c.c,this.g.d.c)}function DZ(n){this.b=new ip,this.a=new ip,this.c=new ip,this.d=new ip,this.e=n}function RZ(n,t){this.a=new rp,this.e=new rp,this.b=(i8(),k2n),this.c=n,this.b=t}function KZ(n,t,e){sN.call(this),YZ(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function _Z(n){this.d=n,this.c=n.c.vc().Kc(),this.b=null,this.a=null,this.e=(pm(),a_n)}function FZ(n){if(n<0)throw hp(new Qm("Illegal Capacity: "+n));this.g=this.ri(n)}function BZ(n){var t;M$(!!n.c),t=n.c.a,VZ(n.d,n.c),n.b==n.c?n.b=t:--n.a,n.c=null}function HZ(n,t){var e;return W9(n),e=new _H(n,n.a.rd(),4|n.a.qd(),t),new SR(n,e)}function qZ(n,t){var e;for(e=n.Kc();e.Ob();)b5(Yx(e.Pb(),70),(Ojn(),kQn),t)}function GZ(n){var t;return(t=ty(fL(Aun(n,(gjn(),y1n)))))<0&&b5(n,y1n,t=0),t}function zZ(n,t,e,i,r,c){var a;YG(a=EV(i),r),QG(a,c),Qhn(n.a,i,new jx(a,t,e.f))}function UZ(n,t){var e;if(!(e=Ybn(n.Tg(),t)))throw hp(new Qm(mNn+t+jNn));return e}function XZ(n,t){var e;for(e=n;IG(e);)if((e=IG(e))==t)return!0;return!1}function WZ(n,t){var e,i,r,c;for(vB(t),r=0,c=(i=n.c).length;r>16!=6?null:Yx(Bfn(n),235)}(n))&&!t.kh()&&(n.w=t),t)}function r1(n){var t;return null==n?null:function(n,t){var e,i,r,c,a;if(null==n)return null;for(a=VQ(Xot,sTn,25,2*t,15,1),i=0,r=0;i>4&15,c=15&n[i],a[r++]=zrt[e],a[r++]=zrt[c];return Vnn(a,0,a.length)}(t=Yx(n,190),t.length)}function c1(n,t){if(null==n.g||t>=n.i)throw hp(new BI(t,n.i));return n.li(t,n.g[t])}function a1(n){var t,e;for(t=n.a.d.j,e=n.c.d.j;t!=e;)n2(n.b,t),t=A9(t);n2(n.b,t)}function u1(n,t){var e,i,r,c;for(r=0,c=(i=n.d).length;r=14&&t<=16)),n}function f1(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function l1(n,t,e){var i,r;i=t;do{r=ty(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function b1(n,t){var e,i;i=n.a,e=function(n,t,e){var i,r;return r=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new p_(n,1,5,r,n.a),e?Pan(e,i):e=i),e}(n,t,null),i!=t&&!n.e&&(e=zyn(n,t,e)),e&&e.Fi()}function w1(n,t){return XC(),o0(ZEn),e.Math.abs(n-t)<=ZEn||n==t||isNaN(n)&&isNaN(t)}function d1(n,t){return XC(),o0(ZEn),e.Math.abs(n-t)<=ZEn||n==t||isNaN(n)&&isNaN(t)}function g1(n,t){return function(n){return n?n.i:null}(K2(n,t,WR(e7(BEn,HB(WR(e7(null==t?0:W5(t),HEn)),15)))))}function p1(){p1=O,zzn=z6((bon(),x4(Gy(Uzn,1),XEn,267,0,[Hzn,Bzn,_zn,qzn,Fzn,Kzn])))}function v1(){v1=O,dnt=z6((dan(),x4(Gy(iet,1),XEn,291,0,[bnt,lnt,fnt,snt,ont,hnt])))}function m1(){m1=O,V7n=z6((qen(),x4(Gy(wnt,1),XEn,248,0,[H7n,z7n,U7n,X7n,q7n,G7n])))}function y1(){y1=O,vWn=z6((psn(),x4(Gy(kWn,1),XEn,227,0,[bWn,dWn,lWn,wWn,gWn,fWn])))}function k1(){k1=O,jVn=z6((uon(),x4(Gy(LVn,1),XEn,275,0,[mVn,gVn,yVn,vVn,pVn,dVn])))}function j1(){j1=O,wVn=z6((Wcn(),x4(Gy(kVn,1),XEn,274,0,[hVn,sVn,lVn,oVn,fVn,uVn])))}function E1(){E1=O,v2n=z6((nun(),x4(Gy(j2n,1),XEn,313,0,[d2n,b2n,f2n,l2n,g2n,w2n])))}function T1(){T1=O,eVn=z6((pon(),x4(Gy(cVn,1),XEn,276,0,[QWn,VWn,JWn,YWn,nVn,ZWn])))}function M1(){M1=O,l5n=z6((ysn(),x4(Gy(Z5n,1),XEn,327,0,[h5n,a5n,o5n,u5n,s5n,c5n])))}function S1(){S1=O,jit=z6((Chn(),x4(Gy(Git,1),XEn,273,0,[mit,pit,vit,git,dit,yit])))}function P1(){P1=O,Tet=z6((vun(),x4(Gy(xet,1),XEn,312,0,[ket,met,jet,pet,yet,vet])))}function I1(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,0,e,n.a))}function C1(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,1,e,n.b))}function O1(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,3,e,n.b))}function A1(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,3,e,n.f))}function $1(n,t){var e;e=n.g,n.g=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,4,e,n.g))}function L1(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,5,e,n.i))}function N1(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,6,e,n.j))}function x1(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,1,e,n.j))}function D1(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,4,e,n.c))}function R1(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new aW(n,2,e,n.k))}function K1(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new uW(n,2,e,n.d))}function _1(n,t){var e;e=n.s,n.s=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new uW(n,4,e,n.s))}function F1(n,t){var e;e=n.t,n.t=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new uW(n,5,e,n.t))}function B1(n,t){var e;e=n.F,n.F=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,5,e,t))}function H1(n,t){var e;return(e=Yx(BF((MT(),Nct),n),55))?e.xj(t):VQ(UKn,iEn,1,t,5,1)}function q1(n,t){var e;return t in n.a&&(e=jG(n,t).he())?e.a:null}function G1(n,t){var e,i;return xk(),i=new uo,!!t&&Xbn(i,t),x0(e=i,n),e}function z1(n,t,e){if(k6(n,e),!n.Bk()&&null!=e&&!n.wj(e))throw hp(new Op);return e}function U1(n,t){return n.n=t,n.n?(n.f=new ip,n.e=new ip):(n.f=null,n.e=null),n}function X1(n,t,e,i,r,c){var a;return e0(e,a=TF(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function W1(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function V1(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Q1(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function Y1(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function J1(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function Z1(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r=0),function(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,E$(e<(n.c-n.b&i)),e>=r?(function(n,t){var e,i;for(e=n.a.length-1,n.c=n.c-1&e;t!=n.c;)i=t+1&e,DF(n.a,t,n.a[i]),t=i;DF(n.a,n.c,null)}(n,t),-1):(function(n,t){var e,i;for(e=n.a.length-1;t!=n.b;)i=t-1&e,DF(n.a,t,n.a[i]),t=i;DF(n.a,n.b,null),n.b=n.b+1&e}(n,t),1)}(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function u0(n){return n.a<54?n.f<0?-1:n.f>0?1:0:(!n.c&&(n.c=J6(n.f)),n.c).e}function o0(n){if(!(n>=0))throw hp(new Qm("tolerance ("+n+") must be >= 0"));return n}function s0(){return m7n||h6(m7n=new Jdn,x4(Gy(ZBn,1),iEn,130,0,[new $f])),m7n}function h0(){h0=O,r3n=new sS(MSn,0),e3n=new sS("INPUT",1),i3n=new sS("OUTPUT",2)}function f0(){f0=O,IWn=new qM("ARD",0),OWn=new qM("MSD",1),CWn=new qM("MANUAL",2)}function l0(){l0=O,G3n=new dS("BARYCENTER",0),z3n=new dS(KIn,1),U3n=new dS(_In,2)}function b0(n,t){var e;if(e=n.gc(),t<0||t>e)throw hp(new jN(t,e));return new WN(n,t)}function w0(n,t){var e;return CO(t,42)?n.c.Mc(t):(e=mnn(n,t),ttn(n,t),e)}function d0(n,t,e){return a8(n,t),E2(n,e),_1(n,0),F1(n,1),l9(n,!0),s9(n,!0),n}function g0(n,t){if(n<0)throw hp(new Qm(t+" cannot be negative but was: "+n));return n}function p0(n,t){var e,i;for(e=0,i=n.gc();e0?Yx(TR(e.a,i-1),10):null}function $0(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,2,e,n.k))}function L0(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,8,e,n.f))}function N0(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,7,e,n.i))}function x0(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,8,e,n.a))}function D0(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,0,e,n.b))}function R0(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,0,e,n.b))}function K0(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,1,e,n.c))}function _0(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,1,e,n.c))}function F0(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,4,e,n.c))}function B0(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,1,e,n.d))}function H0(n,t){var e;e=n.D,n.D=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,2,e,n.D))}function q0(n,t){n.r>0&&n.c0&&0!=n.g&&q0(n.i,t/n.r*n.i.d))}function G0(n,t){return Lwn(n.e,t)?(TT(),GJ(t)?new cR(t,n):new VP(t,n)):new JP(t,n)}function z0(n,t){return function(n){return n?n.g:null}(_2(n.a,t,WR(e7(BEn,HB(WR(e7(null==t?0:W5(t),HEn)),15)))))}function U0(n){var t;return(n=e.Math.max(n,2))>(t=j5(n))?(t<<=1)>0?t:zEn:t}function X0(n){switch(kA(3!=n.e),n.e){case 2:return!1;case 0:return!0}return function(n){return n.e=3,n.d=n.Yb(),2!=n.e&&(n.e=0,!0)}(n)}function W0(n,t){var e;return!!CO(t,8)&&(e=Yx(t,8),n.a==e.a&&n.b==e.b)}function V0(n,t,e){var i,r;return r=t>>5,i=31&t,Gz(UK(n.n[e][r],WR(GK(i,1))),3)}function Q0(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,21,e,n.b))}function Y0(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,11,e,n.d))}function J0(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,13,e,n.j))}function Z0(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i0?t-1:t,pk(function(n,t){return n.j=t,n}(U1(xD(new am,e),n.n),n.j),n.k)}(n,n.g),KD(n.a,e),e.i=n,n.d=t,e)}function Z2(n,t,e){run(e,"DFS Treeifying phase",1),function(n,t){var e,i,r;for(r=t.b.b,n.a=new ME,n.b=VQ(Wot,MTn,25,r,15,1),e=0,i=Ztn(t.b,0);i.b!=i.d.c;)Yx(IX(i),86).g=e++}(n,t),function(n,t){var e,i,r,c,a;for(a=Yx(Aun(t,(cln(),X5n)),425),c=Ztn(t.b,0);c.b!=c.d.c;)if(r=Yx(IX(c),86),0==n.b[r.g]){switch(a.g){case 0:yin(n,r);break;case 1:gln(n,r)}n.b[r.g]=2}for(i=Ztn(n.a,0);i.b!=i.d.c;)V7((e=Yx(IX(i),188)).b.d,e,!0),V7(e.c.b,e,!0);b5(t,(ryn(),S5n),n.a)}(n,t),n.a=null,n.b=null,Ron(e)}function n3(n,t,e){this.g=n,this.d=t,this.e=e,this.a=new ip,function(n){var t,e,i,r;for(r=V8(n.d,n.e).Kc();r.Ob();)for(i=Yx(r.Pb(),11),e=new pb(n.e==(Ikn(),qit)?i.e:i.g);e.a0&&(this.g=this.ri(this.i+(this.i/8|0)+1),n.Qc(this.g))}function e3(n,t){CD.call(this,sut,n,t),this.b=this,this.a=dwn(n.Tg(),CZ(this.e.Tg(),this.c))}function i3(n,t){var e,i;for(vB(t),i=t.vc().Kc();i.Ob();)e=Yx(i.Pb(),42),n.zc(e.cd(),e.dd())}function r3(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function c3(n){switch(n.g){case 2:return Ikn(),qit;case 4:return Ikn(),Eit;default:return n}}function a3(n){switch(n.g){case 1:return Ikn(),Bit;case 3:return Ikn(),Tit;default:return n}}function u3(n,t){return TA(),aI(n)?FV(n,lL(t)):cI(n)?WK(n,fL(t)):rI(n)?XK(n,hL(t)):n.wd(t)}function o3(n,t){t.q=n,n.d=e.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),eD(n.a,t)}function s3(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.ac&&t.b0||h.j==qit&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new pb(h.g);r.a=0x8000000000000000?(LJ(),I_n):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=zTn&&(n-=(e=oG(n/zTn))*zTn),t=0,n>=GTn&&(n-=(t=oG(n/GTn))*GTn),r=rO(oG(n),t,e),i&&A5(r),r)}(n))}function R3(n,t){var e,i,r;for(e=n.c.Ee(),r=t.Kc();r.Ob();)i=r.Pb(),n.a.Od(e,i);return n.b.Kb(e)}function K3(n,t){var e,i,r;if(null!=(e=n.Jg())&&n.Mg())for(i=0,r=e.length;i1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw hp(new Kp)}function W3(n){var t,e,i;return e=0,(i=n)<0&&(i+=zTn,e=HTn),t=oG(i/GTn),rO(oG(i-t*GTn),t,e)}function V3(n){var t,e,i;for(i=0,e=new TE(n.a);e.a>22),r=n.h-t.h+(i>>22),rO(e&BTn,i&BTn,r&HTn)}function k4(n){var t;return n<128?(!(t=(dR(),F_n)[n])&&(t=F_n[n]=new eb(n)),t):new eb(n)}function j4(n){var t;return CO(n,78)?n:((t=n&&n.__java$exception)||Sp(t=new n8(n)),t)}function E4(n){if(CO(n,186))return Yx(n,118);if(n)return null;throw hp(new Zm(pxn))}function T4(n,t){if(null==t)return!1;for(;n.a!=n.b;)if(Q8(t,w8(n)))return!0;return!1}function M4(n){return!!n.a.Ob()||n.a==n.d&&(n.a=new ZU(n.e.f),n.a.Ob())}function S4(n,t){var e;return 0!=(e=t.Pc()).length&&(sD(n.c,n.c.length,e),!0)}function P4(n,t){var e;for(e=new pb(n.b);e.a=0,"Negative initial capacity"),jD(t>=0,"Non-positive load factor"),U_(this)}function a5(n,t,e){return!(n>=128)&&hI(n<64?Gz(GK(1,n),e):Gz(GK(1,n-64),t),0)}function u5(n,t){return!(!n||!t||n==t)&&y7(n.b.c,t.b.c+t.b.b)<0&&y7(t.b.c,n.b.c+n.b.b)<0}function o5(n){var t,e,i;return e=n.n,i=n.o,t=n.d,new mH(e.a-t.b,e.b-t.d,i.a+(t.b+t.c),i.b+(t.d+t.a))}function s5(n){var t,i;for(null==n.j&&(n.j=($q(),function(n){var t,i,r;for(t="Sz",i="ez",r=e.Math.min(n.length,5)-1;r>=0;r--)if(_N(n[r].d,t)||_N(n[r].d,i)){n.length>=r+1&&n.splice(0,r+1);break}return n}(p_n.ce(n)))),t=0,i=n.j.length;t(i=n.gc()))throw hp(new jN(t,i));return n.hi()&&(e=OG(n,e)),n.Vh(t,e)}function l5(n,t,e){return null==e?(!n.q&&(n.q=new rp),zV(n.q,t)):(!n.q&&(n.q=new rp),xB(n.q,t,e)),n}function b5(n,t,e){return null==e?(!n.q&&(n.q=new rp),zV(n.q,t)):(!n.q&&(n.q=new rp),xB(n.q,t,e)),n}function w5(n){var t,i;return o4(i=new XV,n),b5(i,(d2(),EGn),n),function(n,t,i){var r,c,a,u,o;for(r=0,a=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));a.e!=a.i.gc();)u="",0==(!(c=Yx(hen(a),33)).n&&(c.n=new m_(act,c,1,7)),c.n).i||(u=Yx(c1((!c.n&&(c.n=new m_(act,c,1,7)),c.n),0),137).a),o4(o=new GF(u),c),b5(o,(d2(),EGn),c),o.b=r++,o.d.a=c.i+c.g/2,o.d.b=c.j+c.f/2,o.e.a=e.Math.max(c.g,1),o.e.b=e.Math.max(c.f,1),eD(t.e,o),Ysn(i.f,c,o),Yx(jln(c,(Bdn(),fGn)),98),Ran()}(n,i,t=new rp),function(n,t,i){var r,c,a,u,o,s,f,l;for(s=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));s.e!=s.i.gc();)for(c=new $K(bA(lbn(o=Yx(hen(s),33)).a.Kc(),new h));Vfn(c);){if(!(r=Yx(kV(c),79)).b&&(r.b=new AN(Zrt,r,4,7)),!(r.b.i<=1&&(!r.c&&(r.c=new AN(Zrt,r,5,8)),r.c.i<=1)))throw hp(new by("Graph must not contain hyperedges."));if(!Rfn(r)&&o!=iun(Yx(c1((!r.c&&(r.c=new AN(Zrt,r,5,8)),r.c),0),82)))for(o4(f=new rN,r),b5(f,(d2(),EGn),r),Cl(f,Yx(eI(Dq(i.f,o)),144)),Ol(f,Yx(BF(i,iun(Yx(c1((!r.c&&(r.c=new AN(Zrt,r,5,8)),r.c),0),82))),144)),eD(t.c,f),u=new UO((!r.n&&(r.n=new m_(act,r,1,7)),r.n));u.e!=u.i.gc();)o4(l=new wW(f,(a=Yx(hen(u),137)).a),a),b5(l,EGn,a),l.e.a=e.Math.max(a.g,1),l.e.b=e.Math.max(a.f,1),Wvn(l),eD(t.d,l)}}(n,i,t),i}function d5(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r>=1);return t}function E5(n){var t,e;return 32==(e=Yhn(n.h))?32==(t=Yhn(n.m))?Yhn(n.l)+32:t+20-10:e-12}function T5(n){var t;return null==(t=n.a[n.b])?null:(DF(n.a,n.b,null),n.b=n.b+1&n.a.length-1,t)}function M5(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function S5(n,t,e){var i,r;return i=new nY(t,e),r=new q,n.b=Hwn(n,n.b,i,r),r.b||++n.c,n.b.b=!1,r.d}function P5(n,t,e){var i,r,c;for(c=0,r=V8(t,e).Kc();r.Ob();)i=Yx(r.Pb(),11),xB(n.c,i,d9(c++))}function I5(n){var t,e;for(e=new pb(n.a.b);e.ae&&(e=n[t]);return e}function x5(n,t,e){var i;return Swn(n,t,i=new ip,(Ikn(),Eit),!0,!1),Swn(n,e,i,qit,!1,!1),i}function D5(n,t,e){var i,r;return r=cX(t,"labels"),function(n,t,e){var i,r,c,a;if(e)for(r=((i=new NK(e.a.length)).b-i.a)*i.c<0?(PT(),Fot):new oA(i);r.Ob();)(c=aX(e,Yx(r.Pb(),19).a))&&(a=G1(oX(c,zNn),t),xB(n.f,a,c),rxn in c.a&&$0(a,oX(c,rxn)),eun(c,a),ihn(c,a))}((i=new AP(n,e)).a,i.b,r),r}function R5(n,t){var e;for(e=0;e1||t>=0&&n.b<3)}function U5(n){var t,e;for(t=new Nv,e=Ztn(n,0);e.b!=e.d.c;)A$(t,0,new fC(Yx(IX(e),8)));return t}function X5(n){var t;for(t=new pb(n.a.b);t.a=n.b.c.length||(l6(n,2*t+1),(e=2*t+2)=0&&n[i]===t[i];i--);return i<0?0:LT(Gz(n[i],uMn),Gz(t[i],uMn))?-1:1}function d6(n,t){var e,i;return i=Yx(H3(n.a,4),126),e=VQ(Oct,vDn,415,t,0,1),null!=i&&smn(i,0,e,0,i.length),e}function g6(n,t){var e;return e=new xdn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function p6(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(Nin(n,c,a))return!0;return!1}function v6(n,t,e){var i,r,c,a;for(vB(e),a=!1,c=n.Zc(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function m6(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=Yx(r.Pb(),42),n.re(t,i.dd()))return!0;return!1}function y6(n,t,e){return n.d[t.p][e.p]||(function(n,t,e){if(n.e)switch(n.b){case 1:!function(n,t,e){n.i=0,n.e=0,t!=e&&H5(n,t,e)}(n.c,t,e);break;case 0:!function(n,t,e){n.i=0,n.e=0,t!=e&&q5(n,t,e)}(n.c,t,e)}else YX(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function k6(n,t){if(!n.ai()&&null==t)throw hp(new Qm("The 'no null' constraint is violated"));return t}function j6(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),H0(n,null==t?null:(vB(t),t)),n.C&&n.yk(null)}function E6(n,t){return!(!n||n==t||!O$(t,(Ojn(),vQn)))&&Yx(Aun(t,(Ojn(),vQn)),10)!=n}function T6(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.pl()}}function M6(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n.ql()}}function S6(n){vG.call(this,"The given string does not match the expected format for individual spacings.",n)}function P6(){P6=O,jrt=new yP("ELK",0),Ert=new yP("JSON",1),krt=new yP("DOT",2),Trt=new yP("SVG",3)}function I6(){I6=O,E6n=new DS(fIn,0),T6n=new DS("RADIAL_COMPACTION",1),M6n=new DS("WEDGE_COMPACTION",2)}function C6(){C6=O,cBn=new FT("CONCURRENT",0),aBn=new FT("IDENTITY_FINISH",1),uBn=new FT("UNORDERED",2)}function O6(){O6=O,BE(),jqn=new FI(ePn,Eqn=vqn),kqn=new Og(iPn),Tqn=new Og(rPn),Mqn=new Og(cPn)}function A6(){A6=O,SXn=new ji,PXn=new Ei,MXn=new Ti,TXn=new Mi,vB(new Si),EXn=new D}function $6(){$6=O,g3n=new lS("CONSERVATIVE",0),p3n=new lS("CONSERVATIVE_SOFT",1),v3n=new lS("SLOPPY",2)}function L6(){L6=O,Oet=new RC(15),Cet=new DC((Cjn(),utt),Oet),Aet=Ott,Met=ynt,Set=Jnt,Iet=ttt,Pet=ntt}function N6(n,t,e){var i,r;for(i=new ME,r=Ztn(e,0);r.b!=r.d.c;)KD(i,new fC(Yx(IX(r),8)));v6(n,t,i)}function x6(n){var t;return!n.a&&(n.a=new m_(sat,n,9,5)),0!=(t=n.a).i?function(n){return n.b?n.b:n.a}(Yx(c1(t,0),678)):null}function D6(n,t){var e;return e=t7(n,t),LT(Uz(n,t),0)|function(n,t){return k8(n,t)>=0}(Uz(n,e),0)?e:t7(IEn,Uz(UK(e,63),1))}function R6(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;e0)return i_(t-1,n.a.c.length),KV(n.a,t-1);throw hp(new Rp)}function _6(n,t,e){if(n>t)throw hp(new Qm(NMn+n+xMn+t));if(n<0||t>e)throw hp(new Py(NMn+n+DMn+t+MMn+e))}function F6(n){if(!n.a||0==(8&n.a.i))throw hp(new Ym("Enumeration class expected for layout option "+n.f))}function B6(n){var t;++n.j,0==n.i?n.g=null:n.in$n?n-i>n$n:i-n>n$n)}function Q6(n,t){return n?t&&!n.j||CO(n,124)&&0==Yx(n,124).a.b?0:n.Re():0}function Y6(n,t){return n?t&&!n.k||CO(n,124)&&0==Yx(n,124).a.a?0:n.Se():0}function J6(n){return bdn(),n<0?-1!=n?new jen(-1,-n):lFn:n<=10?wFn[oG(n)]:new jen(1,n)}function Z6(n){throw r5(),hp(new Cm("Unexpected typeof result '"+n+"'; please report this bug to the GWT team"))}function n8(n){vy(),jO(this),qH(this),this.e=n,Cwn(this,n),this.g=null==n?aEn:I7(n),this.a="",this.b=n,this.a=""}function t8(){this.a=new nu,this.f=new Kd(this),this.b=new _d(this),this.i=new Fd(this),this.e=new Bd(this)}function e8(){vm.call(this,new tY(IZ(16))),g0(2,EEn),this.b=2,this.a=new IB(null,null,0,null),kp(this.a,this.a)}function i8(){i8=O,m2n=new eS("DUMMY_NODE_OVER",0),y2n=new eS("DUMMY_NODE_UNDER",1),k2n=new eS("EQUAL",2)}function r8(){r8=O,uzn=kG(x4(Gy(oet,1),XEn,103,0,[(t9(),Ztt),net])),ozn=kG(x4(Gy(oet,1),XEn,103,0,[eet,Jtt]))}function c8(n){return(Ikn(),xit).Hc(n.j)?ty(fL(Aun(n,(Ojn(),XQn)))):$5(x4(Gy(B7n,1),TEn,8,0,[n.i.n,n.n,n.a])).b}function a8(n,t){var e,i;e=n.nk(t,null),i=null,t&&(Rk(),b1(i=new up,n.r)),(e=fun(n,i,e))&&e.Fi()}function u8(n,t){var e,i,r;return i=!1,e=t.q.d,t.dr&&(san(t.q,r),i=e!=t.q.d)),i}function o8(n,t){var i,r,c,a,u;return a=t.i,u=t.j,r=a-(i=n.f).i,c=u-i.j,e.Math.sqrt(r*r+c*c)}function s8(n,t){var e;return(e=rtn(n))||(!Xrt&&(Xrt=new Oo),Cmn(),fY((e=new Yg(xsn(t))).Vk(),n)),e}function h8(n,t){var e,i;return(e=Yx(n.c.Bc(t),14))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function f8(n,t){var e;for(e=0;e=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function C8(n){var t,e,i,r;if(null!=n)for(e=0;e0&&a6(Yx(TR(n.a,n.a.c.length-1),570),t)||eD(n.a,new iV(t))}function _8(n){var t;return(t=new Ay).a+="VerticalSegment ",mI(t,n.e),t.a+=" ",yI(t,lA(new Ty,new pb(n.k))),t.a}function F8(n){var t;return(t=Yx(UJ(n.c.c,""),229))||(t=new dz(ok(uk(new pu,""),"Other")),Gtn(n.c.c,"",t)),t}function B8(n){var t;return 0!=(64&n.Db)?Kln(n):((t=new MA(Kln(n))).a+=" (name: ",pI(t,n.zb),t.a+=")",t.a)}function H8(n,t,e){var i,r;return r=n.sb,n.sb=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new p_(n,1,4,r,t),e?e.Ei(i):e=i),e}function q8(n,t){var e,i;for(e=0,i=i7(n,t).Kc();i.Ob();)e+=null!=Aun(Yx(i.Pb(),11),(Ojn(),RQn))?1:0;return e}function G8(n,t,e){var i,r,c;for(i=0,c=Ztn(n,0);c.b!=c.d.c&&!((r=ty(fL(IX(c))))>e);)r>=t&&++i;return i}function z8(n,t,e){var i,r;return r=n.r,n.r=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new p_(n,1,8,r,n.r),e?e.Ei(i):e=i),e}function U8(n,t){var e,i;return!(i=(e=Yx(t,676)).vk())&&e.wk(i=CO(t,88)?new UP(n,Yx(t,26)):new mU(n,Yx(t,148))),i}function X8(n,t,e){var i;n.qi(n.i+1),i=n.oi(t,e),t!=n.i&&smn(n.g,t,n.g,t+1,n.i-t),DF(n.g,t,i),++n.i,n.bi(t,e),n.ci()}function W8(n,t){var e;return e=new sn,n.a.sd(e)?(qO(),new Am(vB(fJ(n,e.a,t)))):(yB(n),qO(),qO(),FFn)}function V8(n,t){switch(t.g){case 2:case 1:return i7(n,t);case 3:case 4:return I3(i7(n,t))}return XH(),XH(),TFn}function Q8(n,t){return aI(n)?_N(n,t):cI(n)?KN(n,t):rI(n)?(vB(n),iI(n)===iI(t)):IK(n)?n.Fb(t):uK(n)?WI(n,t):Jz(n,t)}function Y8(n,t,e,i,r){0!=t&&0!=i&&(1==t?r[i]=Gen(r,e,i,n[0]):1==i?r[t]=Gen(r,n,t,e[0]):function(n,t,e,i,r){var c,a,u,o;if(iI(n)!==iI(t)||i!=r)for(u=0;ue)throw hp(new Hm(NMn+n+DMn+t+", size: "+e));if(n>t)throw hp(new Qm(NMn+n+xMn+t))}function r9(n,t,e){if(t<0)Ehn(n,e);else{if(!e.Ij())throw hp(new Qm(mNn+e.ne()+yNn));Yx(e,66).Nj().Vj(n,n.yh(),t)}}function c9(n,t,e,i,r,c){this.e=new ip,this.f=(h0(),r3n),eD(this.e,n),this.d=t,this.a=e,this.b=i,this.f=r,this.c=c}function a9(n,t){var e,i;for(i=new UO(n);i.e!=i.i.gc();)if(e=Yx(hen(i),26),iI(t)===iI(e))return!0;return!1}function u9(n){return n>=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function o9(n){var t;return 0!=(64&n.Db)?Kln(n):((t=new MA(Kln(n))).a+=" (source: ",pI(t,n.d),t.a+=")",t.a)}function s9(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,2,e,t))}function h9(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,8,e,t))}function f9(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,8,e,t))}function l9(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,3,e,t))}function b9(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,9,e,t))}function w9(n,t){var e;return-1==n.b&&n.a&&(e=n.a.Gj(),n.b=e?n.c.Xg(n.a.aj(),e):tnn(n.c.Tg(),n.a)),n.c.Og(n.b,t)}function d9(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(ZD(),G_n)[t])&&(e=G_n[t]=new rb(n)),e):new rb(n)}function g9(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(wR(),Z_n)[t])&&(e=Z_n[t]=new ab(n)),e):new ab(n)}function p9(n){var t;return n.k==(bon(),_zn)&&((t=Yx(Aun(n,(Ojn(),hQn)),61))==(Ikn(),Tit)||t==Bit)}function v9(n,t,e){var i,r;return(r=Hln(n.b,t))&&(i=Yx(Imn(SJ(n,r),""),26))?Lln(n,i,t,e):null}function m9(n,t){var e,i;for(i=new UO(n);i.e!=i.i.gc();)if(e=Yx(hen(i),138),iI(t)===iI(e))return!0;return!1}function y9(n,t,e){var i;if(t>(i=n.gc()))throw hp(new jN(t,i));if(n.hi()&&n.Hc(e))throw hp(new Qm(kxn));n.Xh(t,e)}function k9(n,t){var e;if(CO(e=Ybn(n,t),322))return Yx(e,34);throw hp(new Qm(mNn+t+"' is not a valid attribute"))}function j9(n){var t,e,i;for(t=new ip,i=new pb(n.b);i.at?1:n==t?0==n?$9(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function L9(n,t,e){var i,r;return n.ej()?(r=n.fj(),i=Vhn(n,t,e),n.$i(n.Zi(7,d9(e),i,t,r)),i):Vhn(n,t,e)}function N9(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.cd(),function(n,t,e){++n.e,--n.f,Yx(n.d[t].$c(e),133).dd()}(n,i=((e=t.Sh())&Yjn)%n.d.length,Bln(n,i,e,r)))}function x9(n,t){var e;e=0!=(n.Bb&DNn),t?n.Bb|=DNn:n.Bb&=-1025,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,10,e,t))}function D9(n,t){var e;e=0!=(n.Bb&nMn),t?n.Bb|=nMn:n.Bb&=-4097,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,12,e,t))}function R9(n,t){var e;e=0!=(n.Bb&_Dn),t?n.Bb|=_Dn:n.Bb&=-8193,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,15,e,t))}function K9(n,t){var e;e=0!=(n.Bb&FDn),t?n.Bb|=FDn:n.Bb&=-2049,0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new OV(n,1,11,e,t))}function _9(n){var t,e;for(e=Vln(i1(n)).Kc();e.Ob();)if(dpn(n,t=lL(e.Pb())))return dW((pT(),Jct),t);return null}function F9(n,t,e){var i;if(n.c)Pun(n.c,t,e);else for(i=new pb(n.b);i.a>10)+iMn&fTn,t[1]=56320+(1023&n)&fTn,Vnn(t,0,t.length)}function X9(n){var t;return(t=Yx(Aun(n,(gjn(),a1n)),103))==(t9(),tet)?ty(fL(Aun(n,RZn)))>=1?net:Jtt:t}function W9(n){if(n.c)W9(n.c);else if(n.d)throw hp(new Ym("Stream already terminated, can't be modified or used"))}function V9(n){var t;return 0!=(64&n.Db)?Kln(n):((t=new MA(Kln(n))).a+=" (identifier: ",pI(t,n.k),t.a+=")",t.a)}function Q9(n,t,e){var i;return xk(),I1(i=new ro,t),C1(i,e),n&&fY((!n.a&&(n.a=new XO(Qrt,n,5)),n.a),i),i}function Y9(n,t,e,i){var r,c;return vB(i),vB(e),null==(c=null==(r=n.xc(t))?e:PE(Yx(r,15),Yx(e,14)))?n.Bc(t):n.zc(t,c),c}function J9(n){var t,e,i,r;return n2(e=new cx(t=Yx(Ak((r=(i=n.gm).f)==u_n?i:r),9),Yx(eN(t,t.length),9),0),n),e}function Z9(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=Yx(r.Pb(),10),m4(e,Yx(TR(t,i.p),14)))return i;return null}function n7(n,t){var e;return tC(n)&&tC(t)&&XTn<(e=n-t)&&e>22),r=n.h+t.h+(i>>22),rO(e&BTn,i&BTn,r&HTn)}(tC(n)?W3(n):n,tC(t)?W3(t):t))}function e7(n,t){var e;return tC(n)&&tC(t)&&XTn<(e=n*t)&&e>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(u=8191&t.l),p=r*u,v=c*u,m=a*u,0!=(o=t.l>>13|(15&t.m)<<9)&&(g+=e*o,p+=i*o,v+=r*o,m+=c*o),0!=(s=t.m>>4&8191)&&(p+=e*s,v+=i*s,m+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(v+=e*h,m+=i*h),0!=(f=(1048320&t.h)>>8)&&(m+=e*f),b=((d=e*u)>>22)+(g>>9)+((262143&p)<<4)+((31&v)<<17),w=(p>>18)+(v>>5)+((4095&m)<<8),w+=(b+=(l=(d&BTn)+((511&g)<<13))>>22)>>22,rO(l&=BTn,b&=BTn,w&=HTn)}(tC(n)?W3(n):n,tC(t)?W3(t):t))}function i7(n,t){var e;return n.i||yhn(n),(e=Yx(GB(n.g,t),46))?new Oz(n.j,Yx(e.a,19).a,Yx(e.b,19).a):(XH(),XH(),TFn)}function r7(n,t,e){var i;return i=n.a.get(t),n.a.set(t,void 0===e?null:e),void 0===i?(++n.c,gq(n.b)):++n.d,i}function c7(){var n,t,i;Qan(),i=XFn+++Date.now(),n=oG(e.Math.floor(i*jMn))&TMn,t=oG(i-n*EMn),this.a=1502^n,this.b=t^kMn}function a7(n){var t,e;for(t=new ip,e=new pb(n.j);e.a>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,63&(n+=n>>8)+(n>>16)}function f7(n){var t,e,i;for(t=new UL(n.Hd().gc()),i=0,e=PY(n.Hd().Kc());e.Ob();)XG(t,e.Pb(),d9(i++));return function(n){var t;switch(KB(),n.c.length){case 0:return e_n;case 1:return function(n,t){return KB(),gin(n,t),new OB(n,t)}((t=Yx(vhn(new pb(n)),42)).cd(),t.dd());default:return new Em(Yx(Htn(n,VQ(i_n,DEn,42,n.c.length,0,1)),165))}}(t.a)}function l7(n,t){0==n.n.c.length&&eD(n.n,new gG(n.s,n.t,n.i)),eD(n.b,t),Cin(Yx(TR(n.n,n.n.c.length-1),211),t),uvn(n,t)}function b7(n){return n.c==n.b.b&&n.i==n.g.b||(n.a.c=VQ(UKn,iEn,1,0,5,1),S4(n.a,n.b),S4(n.a,n.g),n.c=n.b.b,n.i=n.g.b),n.a}function w7(n,t){var e,i;for(i=0,e=Yx(t.Kb(n),20).Kc();e.Ob();)ny(hL(Aun(Yx(e.Pb(),17),(Ojn(),HQn))))||++i;return i}function d7(){d7=O,iYn=new cS(fIn,0),ZQn=new cS("FIRST",1),nYn=new cS(qIn,2),tYn=new cS("LAST",3),eYn=new cS(GIn,4)}function g7(){g7=O,wet=new tP(MSn,0),fet=new tP("POLYLINE",1),het=new tP("ORTHOGONAL",2),bet=new tP("SPLINES",3)}function p7(){p7=O,b8n=new _S("ASPECT_RATIO_DRIVEN",0),w8n=new _S("MAX_SCALE_DRIVEN",1),l8n=new _S("AREA_DRIVEN",2)}function v7(){v7=O,e9n=new BS("P1_STRUCTURE",0),i9n=new BS("P2_PROCESSING_ORDER",1),r9n=new BS("P3_EXECUTION",2)}function m7(){m7=O,g6n=new NS("OVERLAP_REMOVAL",0),w6n=new NS("COMPACTION",1),d6n=new NS("GRAPH_SIZE_CALCULATION",2)}function y7(n,t){return XC(),o0(ZEn),e.Math.abs(n-t)<=ZEn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:QI(isNaN(n),isNaN(t))}function k7(n,t){var e,i;for(e=Ztn(n,0);e.b!=e.d.c;){if((i=ey(fL(IX(e))))==t)return;if(i>t){MU(e);break}}oF(e,t)}function j7(n,t){var e,i,r,c,a;if(e=t.f,Gtn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;c>>0).toString(16):n.toString()}function C7(n){var t;this.a=new cx(t=Yx(n.e&&n.e(),9),Yx(eN(t,t.length),9),0),this.b=VQ(UKn,iEn,1,this.a.a.length,5,1)}function O7(n){var t,e,i;for(this.a=new oC,i=new pb(n);i.a=c)return t.c+i;return t.c+t.b.gc()}function x7(n,t){var e,i,r,c,a,u;for(i=0,e=0,a=0,u=(c=t).length;a0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function D7(n){var t,e,i;for((i=new Cy).a+="[",t=0,e=n.gc();tPPn,S=e.Math.abs(b.b-d.b)>PPn,(!i&&M&&S||i&&(M||S))&&KD(p.a,k)),C2(p.a,r),0==r.b?b=k:(S$(0!=r.b),b=Yx(r.c.b.c,8)),l4(w,l,g),G2(c)==T&&(dB(T.i)!=c.a&&dsn(g=new Pk,dB(T.i),m),b5(p,YQn,g)),Mon(w,p,m),f.a.zc(w,f);YG(p,j),QG(p,T)}for(h=f.a.ec().Kc();h.Ob();)YG(s=Yx(h.Pb(),17),null),QG(s,null);Ron(t)}(t,J2(r,1)),Ron(r)}function F7(n,t,e,i,r,c){this.a=n,this.c=t,this.b=e,this.f=i,this.d=r,this.e=c,this.c>0&&this.b>0&&AR(this.c,this.b,this.a)}function B7(n){cnn(),this.c=DV(x4(Gy(v7n,1),iEn,831,0,[o2n])),this.b=new rp,this.a=n,xB(this.b,s2n,1),WZ(h2n,new Qd(this))}function H7(n,t){var e;return n.d?P_(n.b,t)?Yx(BF(n.b,t),51):(e=t.Kf(),xB(n.b,t,e),e):t.Kf()}function q7(n,t){var e;return iI(n)===iI(t)||!!CO(t,91)&&(e=Yx(t,91),n.e==e.e&&n.d==e.d&&function(n,t){var e;for(e=n.d-1;e>=0&&n.a[e]===t[e];e--);return e<0}(n,e.a))}function G7(n){switch(Ikn(),n.g){case 4:return Tit;case 1:return Eit;case 3:return Bit;case 2:return qit;default:return Hit}}function z7(n,t){switch(t){case 3:return 0!=n.f;case 4:return 0!=n.g;case 5:return 0!=n.i;case 6:return 0!=n.j}return z3(n,t)}function U7(n){switch(n.g){case 0:return new qa;case 1:return new Ua;default:throw hp(new Qm(FIn+(null!=n.f?n.f:""+n.g)))}}function X7(n){switch(n.g){case 0:return new om;case 1:return new Lv;default:throw hp(new Qm(V$n+(null!=n.f?n.f:""+n.g)))}}function W7(n){var t,e,i;return(e=n.zg())?CO(t=n.Ug(),160)&&null!=(i=W7(Yx(t,160)))?i+"."+e:e:null}function V7(n,t,e){var i,r;for(r=n.Kc();r.Ob();)if(i=r.Pb(),iI(t)===iI(i)||null!=t&&Q8(t,i))return e&&r.Qb(),!0;return!1}function Q7(n,t,e){var i,r;if(++n.j,e.dc())return!1;for(r=e.Kc();r.Ob();)i=r.Pb(),n.Hi(t,n.oi(t,i)),++t;return!0}function Y7(n,t){var e;if(t){for(e=0;eo.d&&(f=o.d+o.a+h));i.c.d=f,t.a.zc(i,t),s=e.Math.max(s,i.c.d+i.c.a)}return s}(n),SE(new SR(null,new Nz(n.d,16)),new Jb(n)),t}function nnn(n){var t;return 0!=(64&n.Db)?B8(n):((t=new MA(B8(n))).a+=" (instanceClassName: ",pI(t,n.D),t.a+=")",t.a)}function tnn(n,t){var e,i,r;if(null==n.i&&svn(n),e=n.i,-1!=(i=t.aj()))for(r=e.length;i>1,this.k=t-1>>1}function fnn(n,t,e){var i,r;for(i=Gz(e,uMn),r=0;0!=k8(i,0)&&r0&&(t.lengthn.i&&DF(t,n.i,null),t}function wnn(n,t,e){var i,r,c;return n.ej()?(i=n.i,c=n.fj(),X8(n,i,t),r=n.Zi(3,null,t,i,c),e?e.Ei(r):e=r):X8(n,n.i,t),e}function dnn(n){var t;return PL(),t=new fC(Yx(n.e.We((Cjn(),ttt)),8)),n.B.Hc((Vgn(),crt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function gnn(n){return Hen(),(n.q?n.q:(XH(),XH(),MFn))._b((gjn(),Y1n))?Yx(Aun(n,Y1n),197):Yx(Aun(dB(n),J1n),197)}function pnn(n,t){var e,i;return i=null,O$(n,(gjn(),_0n))&&(e=Yx(Aun(n,_0n),94)).Xe(t)&&(i=e.We(t)),null==i&&(i=Aun(dB(n),t)),i}function vnn(n,t){var e,i,r;return!!CO(t,42)&&(i=(e=Yx(t,42)).cd(),bB(r=x8(n.Rc(),i),e.dd())&&(null!=r||n.Rc()._b(i)))}function mnn(n,t){var e;return n.f>0&&(n.qj(),-1!=Bln(n,((e=null==t?0:W5(t))&Yjn)%n.d.length,e,t))}function ynn(n,t){var e,i;return n.f>0&&(n.qj(),e=efn(n,((i=null==t?0:W5(t))&Yjn)%n.d.length,i,t))?e.dd():null}function knn(n,t){var e,i,r,c;for(c=dwn(n.e.Tg(),t),e=Yx(n.g,119),r=0;r>5,t&=31,r=n.d+e+(0==t?0:1),function(n,t,e,i){var r,c,a;if(0==i)smn(t,0,n,e,n.length-e);else for(a=32-i,n[n.length-1]=0,c=n.length-1;c>e;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function Rnn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function Knn(n,t,e,i){var r,c,a;return r=!1,function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;return l=n.c[t],b=n.c[e],!((w=Yx(Aun(l,(Ojn(),mQn)),15))&&0!=w.gc()&&w.Hc(b)||(d=l.k!=(bon(),Bzn)&&b.k!=Bzn,v=(g=Yx(Aun(l,vQn),10))!=(p=Yx(Aun(b,vQn),10)),m=!!g&&g!=l||!!p&&p!=b,y=Iin(l,(Ikn(),Tit)),k=Iin(b,Bit),m|=Iin(l,Bit)||Iin(b,Tit),d&&(m&&v||y||k))||l.k==(bon(),qzn)&&b.k==Hzn||b.k==(bon(),qzn)&&l.k==Hzn)&&(h=n.c[t],c=n.c[e],r=Acn(n.e,h,c,(Ikn(),qit)),o=Acn(n.i,h,c,Eit),function(n,t,e){n.d=0,n.b=0,t.k==(bon(),qzn)&&e.k==qzn&&Yx(Aun(t,(Ojn(),CQn)),10)==Yx(Aun(e,CQn),10)&&(lJ(t).j==(Ikn(),Tit)?Wln(n,t,e):Wln(n,e,t)),t.k==qzn&&e.k==Bzn?lJ(t).j==(Ikn(),Tit)?n.d=1:n.b=1:e.k==qzn&&t.k==Bzn&&(lJ(e).j==(Ikn(),Tit)?n.b=1:n.d=1),function(n,t,e){t.k==(bon(),Hzn)&&e.k==Bzn&&(n.d=q8(t,(Ikn(),Bit)),n.b=q8(t,Tit)),e.k==Hzn&&t.k==Bzn&&(n.d=q8(e,(Ikn(),Tit)),n.b=q8(e,Bit))}(n,t,e)}(n.f,h,c),s=y6(n.b,h,c)+Yx(r.a,19).a+Yx(o.a,19).a+n.f.d,u=y6(n.b,c,h)+Yx(r.b,19).a+Yx(o.b,19).a+n.f.b,n.a&&(f=Yx(Aun(h,CQn),11),a=Yx(Aun(c,CQn),11),s+=Yx((i=Drn(n.g,f,a)).a,19).a,u+=Yx(i.b,19).a),s>u)}(n.f,e,i)&&(function(n,t,e){var i,r;Sun(n.e,t,e,(Ikn(),qit)),Sun(n.i,t,e,Eit),n.a&&(r=Yx(Aun(t,(Ojn(),CQn)),11),i=Yx(Aun(e,CQn),11),tU(n.g,r,i))}(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function _nn(n,t,e,i,r){var c,a,u;for(a=r;t.b!=t.c;)c=Yx($_(t),10),u=Yx(i7(c,i).Xb(0),11),n.d[u.p]=a++,e.c[e.c.length]=u;return a}function Fnn(n,t,i){var r,c,a,u,o;return u=n.k,o=t.k,c=fL(pnn(n,r=i[u.g][o.g])),a=fL(pnn(t,r)),e.Math.max((vB(c),c),(vB(a),a))}function Bnn(n,t,e){var i,r,c;for(r=Yx(BF(n.b,e),177),i=0,c=new pb(t.j);c.at?1:QI(isNaN(n),isNaN(t)))>0}function Unn(n,t){return XC(),XC(),o0(ZEn),(e.Math.abs(n-t)<=ZEn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:QI(isNaN(n),isNaN(t)))<0}function Xnn(n,t){return XC(),XC(),o0(ZEn),(e.Math.abs(n-t)<=ZEn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:QI(isNaN(n),isNaN(t)))<=0}function Wnn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];ecMn)return e.fh();if((i=e.Zg())||e==n)break}return i}function ctn(n){return _G(),CO(n,156)?Yx(BF(Mct,NFn),288).vg(n):P_(Mct,V5(n))?Yx(BF(Mct,V5(n)),288).vg(n):null}function atn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw hp(new Qm("Input edge is not connected to the input port."))}function utn(n,t){return n.e>t.e?1:n.et.d?n.e:n.d=48&&n<48+e.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function stn(n,t){var e;return iI(t)===iI(n)||!!CO(t,21)&&(e=Yx(t,21)).gc()==n.gc()&&n.Ic(e)}function htn(n,t){var e,i;for(Lz(t,n.length),e=n.charCodeAt(t),i=t+1;i=2*t&&eD(e,new Lx(a[i-1]+t,a[i]-t));return e}(e,i),SE(HZ(new SR(null,new Nz(function(n){var t,e,i,r,c,a,u;for(c=new oC,e=new pb(n);e.a2&&u.e.b+u.j.b<=2&&(r=u,i=a),c.a.zc(r,c),r.q=i);return c}(t),1)),new ja),new yH(n,e,r,i)))}function wtn(n,t,e){var i;0!=(n.Db&t)?null==e?function(n,t){var e,i,r,c,a,u,o;if(1==(i=h7(254&n.Db)))n.Eb=null;else if(c=h1(n.Eb),2==i)r=Vin(n,t),n.Eb=c[0==r?1:0];else{for(a=VQ(UKn,iEn,1,i-1,5,1),e=2,u=0,o=0;e<=128;e<<=1)e==t?++u:0!=(n.Db&e)&&(a[o++]=c[u++]);n.Eb=a}n.Db&=~t}(n,t):-1==(i=Vin(n,t))?n.Eb=e:DF(h1(n.Eb),i,e):null!=e&&function(n,t,e){var i,r,c,a,u,o;if(0==(r=h7(254&n.Db)))n.Eb=e;else{if(1==r)a=VQ(UKn,iEn,1,2,5,1),0==Vin(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=VQ(UKn,iEn,1,r+1,5,1),c=h1(n.Eb),i=2,u=0,o=0;i<=128;i<<=1)i==t?a[o++]=e:0!=(n.Db&i)&&(a[o++]=c[u++]);n.Eb=a}n.Db|=t}(n,t,e)}function dtn(n){var t;return 0==(32&n.Db)&&0!=(t=vF(Yx(H3(n,16),26)||n.zh())-vF(n.zh()))&&wtn(n,32,VQ(UKn,iEn,1,t,5,1)),n}function gtn(n){var t,e;for(t=new pb(n.g);t.a0&&k8(n,128)<0?(t=WR(n)+128,!(e=(bR(),X_n)[t])&&(e=X_n[t]=new cb(n)),e):new cb(n)}function ktn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=lL(ynn((!e.b&&(e.b=new z$((xjn(),Dat),out,e)),e.b),gxn)))?i:t.ne()}function jtn(n,t){var e,i;for(lz(),i=new $K(bA(a7(n).a.Kc(),new h));Vfn(i);)if((e=Yx(kV(i),17)).d.i==t||e.c.i==t)return e;return null}function Etn(n,t,e){this.c=n,this.f=new ip,this.e=new Pk,this.j=new gR,this.n=new gR,this.b=t,this.g=new mH(t.c,t.d,t.b,t.a),this.a=e}function Ttn(n){var t,e,i,r;for(this.a=new oC,this.d=new Qp,this.e=0,i=0,r=(e=n).length;iE&&(d.c=E-d.b),eD(u.d,new fK(d,P9(u,d))),m=t==Tit?e.Math.max(m,g.b+h.b.rf().b):e.Math.min(m,g.b));for(m+=t==Tit?n.t:-n.t,(y=Z7((u.e=m,u)))>0&&(Yx(GB(n.b,t),124).a.b=y),f=b.Kc();f.Ob();)!(h=Yx(f.Pb(),111)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else kkn(n,t)}(n,t):kkn(n,t):n.u.Hc(mit)&&(i?function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if((f=Yx(Yx(_V(n.r,t),21),84)).gc()<=2||t==(Ikn(),Eit)||t==(Ikn(),qit))qkn(n,t);else{for(g=n.u.Hc((Chn(),yit)),i=t==(Ikn(),Tit)?(e4(),YHn):(e4(),WHn),v=t==Tit?(OJ(),pHn):(OJ(),mHn),r=Qy(Ox(i),n.s),p=t==Tit?JTn:ZTn,h=f.Kc();h.Ob();)!(o=Yx(h.Pb(),111)).c||o.c.d.c.length<=0||(d=o.b.rf(),w=o.e,(b=(l=o.c).i).b=(a=l.n,l.e.a+a.b+a.c),b.a=(u=l.n,l.e.b+u.d+u.a),g?(b.c=w.a-(c=l.n,l.e.a+c.b+c.c)-n.s,g=!1):b.c=w.a+d.a+n.s,xq(v,jSn),l.f=v,lY(l,(BY(),lHn)),eD(r.d,new fK(b,P9(r,b))),p=t==Tit?e.Math.min(p,w.b):e.Math.max(p,w.b+o.b.rf().b));for(p+=t==Tit?-n.t:n.t,Z7((r.e=p,r)),s=f.Kc();s.Ob();)!(o=Yx(s.Pb(),111)).c||o.c.d.c.length<=0||((b=o.c.i).c-=o.e.a,b.d-=o.e.b)}}(n,t):qkn(n,t))}function xtn(n,t){var e,i;++n.j,null!=t&&function(n,t){var e,i,r;if(iI(n)===iI(t))return!0;if(null==n||null==t)return!1;if(n.length!=t.length)return!1;for(e=0;e=(r=n.length))return r;for(t=t>0?t:0;ti&&DF(t,i,null),t}function qtn(n,t){var e,i;for(i=n.a.length,t.lengthi&&DF(t,i,null),t}function Gtn(n,t,e){var i,r,c;return(r=Yx(BF(n.e,t),387))?(c=YL(r,e),OO(n,r),c):(i=new oD(n,t,e),xB(n.e,t,i),iG(i),null)}function ztn(n){var t;if(null==n)return null;if(null==(t=function(n){var t,e,i,r,c,a,u;if(kdn(),null==n)return null;if((r=n.length)%2!=0)return null;for(t=xJ(n),e=VQ(Yot,LNn,25,c=r/2|0,15,1),i=0;i>24}return e}(Vvn(n,!0))))throw hp(new fy("Invalid hexBinary value: '"+n+"'"));return t}function Utn(n){return bdn(),k8(n,0)<0?0!=k8(n,-1)?new pan(-1,sJ(n)):lFn:k8(n,10)<=0?wFn[WR(n)]:new pan(1,n)}function Xtn(){return Njn(),x4(Gy(JHn,1),XEn,159,0,[BHn,FHn,HHn,$Hn,AHn,LHn,DHn,xHn,NHn,_Hn,KHn,RHn,CHn,IHn,OHn,SHn,MHn,PHn,EHn,jHn,THn,qHn])}function Wtn(n){var t;this.d=new ip,this.j=new Pk,this.g=new Pk,t=n.g.b,this.f=Yx(Aun(dB(t),(gjn(),a1n)),103),this.e=ty(fL(cen(t,F0n)))}function Vtn(n){this.b=new ip,this.e=new ip,this.d=n,this.a=!ej(hH(new SR(null,new nF(new UV(n.b))),new Cb(new Gr))).sd((HE(),dBn))}function Qtn(){Qtn=O,T7n=new US("PARENTS",0),E7n=new US("NODES",1),k7n=new US("EDGES",2),M7n=new US("PORTS",3),j7n=new US("LABELS",4)}function Ytn(){Ytn=O,eit=new aP("DISTRIBUTED",0),rit=new aP("JUSTIFIED",1),nit=new aP("BEGIN",2),tit=new aP(pSn,3),iit=new aP("END",4)}function Jtn(n){switch(n.g){case 1:return t9(),eet;case 4:return t9(),Ztt;case 2:return t9(),net;case 3:return t9(),Jtt}return t9(),tet}function Ztn(n,t){var e,i;if(iz(t,n.b),t>=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e=64&&t<128&&(r=zz(r,GK(1,t-64)));return r}function cen(n,t){var e,i;return i=null,O$(n,(Cjn(),Htt))&&(e=Yx(Aun(n,Htt),94)).Xe(t)&&(i=e.We(t)),null==i&&dB(n)&&(i=Aun(dB(n),t)),i}function aen(n,t){var e,i,r;(i=(r=t.d.i).k)!=(bon(),Hzn)&&i!=Kzn&&Vfn(e=new $K(bA(o7(r).a.Kc(),new h)))&&xB(n.k,t,Yx(kV(e),17))}function uen(n,t){var e,i,r;return i=CZ(n.Tg(),t),(e=t-n.Ah())<0?(r=n.Yg(i))>=0?n.lh(r):zhn(n,i):e<0?zhn(n,i):Yx(i,66).Nj().Sj(n,n.yh(),e)}function oen(n){var t;if(CO(n.a,4)){if(null==(t=ctn(n.a)))throw hp(new Ym(ELn+n.b+"'. "+mLn+(sL(Ict),Ict.k)+yLn));return t}return n.a}function sen(n){var t;if(null==n)return null;if(null==(t=function(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(Jpn(),null==n)return null;if((w=function(n){var t,e,i;for(i=0,e=n.length,t=0;t>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return Pj(a=c[h++])&&Pj(u=c[h++])?(t=sot[a],e=sot[u],o=c[h++],s=c[h++],-1==sot[o]||-1==sot[s]?61==o&&61==s?0!=(15&e)?null:(smn(f,0,g=VQ(Yot,LNn,25,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=o&&61==s?0!=(3&(i=sot[o]))?null:(smn(f,0,g=VQ(Yot,LNn,25,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=sot[o],r=sot[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}(Vvn(n,!0))))throw hp(new fy("Invalid base64Binary value: '"+n+"'"));return t}function hen(n){var t;try{return t=n.i.Xb(n.e),n.mj(),n.g=n.e++,t}catch(t){throw CO(t=j4(t),73)?(n.mj(),hp(new Kp)):hp(t)}}function fen(n){var t;try{return t=n.c.ki(n.e),n.mj(),n.g=n.e++,t}catch(t){throw CO(t=j4(t),73)?(n.mj(),hp(new Kp)):hp(t)}}function len(){len=O,Cjn(),Rqn=Ktt,Aqn=Nnt,Sqn=mnt,$qn=utt,pcn(),xqn=_Bn,Nqn=RBn,Dqn=BBn,Lqn=DBn,O6(),Iqn=jqn,Pqn=kqn,Cqn=Tqn,Oqn=Mqn}function ben(n){switch(VE(),this.c=new ip,this.d=n,n.g){case 0:case 2:this.a=DB(Tzn),this.b=JTn;break;case 3:case 1:this.a=Tzn,this.b=ZTn}}function wen(n,t,e){var i;if(n.c)L1(n.c,n.c.i+t),N1(n.c,n.c.j+e);else for(i=new pb(n.b);i.a0&&(eD(n.b,new iD(t.a,e)),0<(i=t.a.length)?t.a=t.a.substr(0,0):0>i&&(t.a+=IO(VQ(Xot,sTn,25,-i,15,1))))}function gen(n,t){var e,i,r;for(e=n.o,r=Yx(Yx(_V(n.r,t),21),84).Kc();r.Ob();)(i=Yx(r.Pb(),111)).e.a=mrn(i,e.a),i.e.b=e.b*ty(fL(i.b.We(XHn)))}function pen(n,t){var e;return e=Yx(Aun(n,(gjn(),$1n)),74),MO(t,$zn)?e?BH(e):(e=new Nv,b5(n,$1n,e)):e&&b5(n,$1n,null),e}function ven(n){var t;return(t=new Ay).a+="n",n.k!=(bon(),Hzn)&&yI(yI((t.a+="(",t),d$(n.k).toLowerCase()),")"),yI((t.a+="_",t),yrn(n)),t.a}function men(n,t,e,i){var r;return e>=0?n.hh(t,e,i):(n.eh()&&(i=(r=n.Vg())>=0?n.Qg(i):n.eh().ih(n,-1-r,null,i)),n.Sg(t,e,i))}function yen(n,t){switch(t){case 7:return!n.e&&(n.e=new AN(nct,n,7,4)),void Hmn(n.e);case 8:return!n.d&&(n.d=new AN(nct,n,8,5)),void Hmn(n.d)}rnn(n,t)}function ken(n,t){var e;e=n.Zc(t);try{return e.Pb()}catch(n){throw CO(n=j4(n),109)?hp(new Hm("Can't get element "+t)):hp(n)}}function jen(n,t){this.e=n,t=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function Sen(){Sen=O,tqn=new iM(NSn,0),nqn=new iM(xSn,1),eqn=new iM(DSn,2),iqn=new iM(RSn,3),tqn.a=!1,nqn.a=!0,eqn.a=!1,iqn.a=!0}function Pen(){Pen=O,bqn=new eM(NSn,0),lqn=new eM(xSn,1),wqn=new eM(DSn,2),dqn=new eM(RSn,3),bqn.a=!1,lqn.a=!0,wqn.a=!1,dqn.a=!0}function Ien(n){var t,e,i;if(e=0,0==(i=idn(n)).c.length)return 1;for(t=new pb(i);t.ae.b)return!0}return!1}function Oen(n,t){return aI(n)?!!zjn[t]:n.hm?!!n.hm[t]:cI(n)?!!Gjn[t]:!!rI(n)&&!!qjn[t]}function Aen(n,t,e){return null==e?(!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),ttn(n.o,t)):(!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),xcn(n.o,t,e)),n}function $en(n,t,e,i){var r,c,a;return c=CZ(n.Tg(),t),(r=t-n.Ah())<0?(a=n.Yg(c))>=0?n._g(a,e,!0):tfn(n,c,e):Yx(c,66).Nj().Pj(n,n.yh(),r,e,i)}function Len(n,t,e,i){var r,c;e.mh(t)&&(TT(),GJ(t)?function(n,t){var e,i,r,c;for(i=0,r=t.gc();i=0)return i;if(n.Fk())for(e=0;e=(r=n.gc()))throw hp(new jN(t,r));if(n.hi()&&(i=n.Xc(e))>=0&&i!=t)throw hp(new Qm(kxn));return n.mi(t,e)}function _en(n,t){if(this.a=Yx(MF(n),245),this.b=Yx(MF(t),245),n.vd(t)>0||n==(dm(),ZKn)||t==(wm(),n_n))throw hp(new Qm("Invalid range: "+BX(n,t)))}function Fen(n){var t,e;for(this.b=new ip,this.c=n,this.a=!1,e=new pb(n.a);e.a0),(t&-t)==t)return oG(t*Xln(n,31)*4.656612873077393e-10);do{i=(e=Xln(n,31))%t}while(e-i+(t-1)<0);return oG(i)}function Xen(n){var t,e,i;return lx(),null!=(i=vBn[e=":"+n])?oG((vB(i),i)):(t=null==(i=pBn[e])?function(n){var t,e,i,r;for(t=0,r=(i=n.length)-4,e=0;e0)for(i=new sx(Yx(_V(n.a,c),21)),XH(),JC(i,new ow(t)),r=new JU(c.b,0);r.b1&&(r=function(n,t){var e,i,r;for(e=HA(new ev,n),r=new pb(t);r.a(o=null==n.d?0:n.d.length)){for(h=n.d,n.d=VQ(Ect,yDn,63,2*o+4,0,1),c=0;cYAn;){for(a=t,u=0;e.Math.abs(t-a)0),c.a.Xb(c.c=--c.b),rvn(n,n.b-u,a,r,c),S$(c.b0),r.a.Xb(r.c=--r.b)}if(!n.d)for(i=0;i102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function gin(n,t){if(null==n)throw hp(new Zm("null key in entry: null="+t));if(null==t)throw hp(new Zm("null value in entry: "+n+"=null"))}function pin(n,t){var i;return i=x4(Gy(Jot,1),rMn,25,15,[Q6(n.a[0],t),Q6(n.a[1],t),Q6(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function vin(n,t){var i;return i=x4(Gy(Jot,1),rMn,25,15,[Y6(n.a[0],t),Y6(n.a[1],t),Y6(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function min(){min=O,NWn=new GM("GREEDY",0),LWn=new GM(iCn,1),DWn=new GM(eCn,2),RWn=new GM("MODEL_ORDER",3),xWn=new GM("GREEDY_MODEL_ORDER",4)}function yin(n,t){var e,i,r;for(n.b[t.g]=1,i=Ztn(t.d,0);i.b!=i.d.c;)r=(e=Yx(IX(i),188)).c,1==n.b[r.g]?KD(n.a,e):2==n.b[r.g]?n.b[r.g]=1:yin(n,r)}function kin(n,t,e){var i,r,c,a;for(a=n.r+t,n.r+=t,n.d+=e,i=e/n.n.c.length,r=0,c=new pb(n.n);c.a0||!a&&0==u))}(n,e,i.d,r,c,a,u)&&t.Fc(i),(s=i.a[1])&&Lin(n,t,e,s,r,c,a,u))}function Nin(n,t,e){try{return sI(V0(n,t,e),1)}catch(i){throw CO(i=j4(i),320)?hp(new Hm(FSn+n.o+"*"+n.p+BSn+t+tEn+e+HSn)):hp(i)}}function xin(n,t,e){try{return sI(V0(n,t,e),0)}catch(i){throw CO(i=j4(i),320)?hp(new Hm(FSn+n.o+"*"+n.p+BSn+t+tEn+e+HSn)):hp(i)}}function Din(n,t,e){try{return sI(V0(n,t,e),2)}catch(i){throw CO(i=j4(i),320)?hp(new Hm(FSn+n.o+"*"+n.p+BSn+t+tEn+e+HSn)):hp(i)}}function Rin(n,t){if(-1==n.g)throw hp(new Lp);n.mj();try{n.d._c(n.g,t),n.f=n.d.j}catch(n){throw CO(n=j4(n),73)?hp(new Dp):hp(n)}}function Kin(n,t,i){run(i,"Linear segments node placement",1),n.b=Yx(Aun(t,(Ojn(),zQn)),304),function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$;for(O=new ip,w=new pb(t.b);w.a=0){for(o=null,u=new JU(h.a,s+1);u.b0&&s[r]&&(d=lO(n.b,s[r],c)),g=e.Math.max(g,c.c.c.b+d);for(a=new pb(f.e);a.ak)?(s=2,u=Yjn):0==s?(s=1,u=E):(s=0,u=E):(b=E>=u||u-E0?(f=Yx(TR(l.c.a,a-1),10),T=lO(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+T)):g=l.n.b-l.d.d,s=e.Math.min(g,s),ac&&DF(t,c,null),t}function Fin(n,t){var e,i,r;return e=t.cd(),r=t.dd(),i=n.xc(e),!(!(iI(r)===iI(i)||null!=r&&Q8(r,i))||null==i&&!n._b(e))}function Bin(n,t,e,i){var r,c;this.a=t,this.c=i,function(n,t){n.b=t}(this,new QS(-(r=n.a).c,-r.d)),mN(this.b,e),c=i/2,t.a?N$(this.b,0,c):N$(this.b,c,0),eD(n.c,this)}function Hin(){Hin=O,i8n=new RS(fIn,0),t8n=new RS(rCn,1),e8n=new RS("EDGE_LENGTH_BY_POSITION",2),n8n=new RS("CROSSING_MINIMIZATION_BY_POSITION",3)}function qin(n,t){var e,i;if(e=Yx(g1(n.g,t),33))return e;if(i=Yx(g1(n.j,t),118))return i;throw hp(new hy("Referenced shape does not exist: "+t))}function Gin(n,t){if(n.c==t)return n.d;if(n.d==t)return n.c;throw hp(new Qm("Node 'one' must be either source or target of edge 'edge'."))}function zin(n,t){if(n.c.i==t)return n.d.i;if(n.d.i==t)return n.c.i;throw hp(new Qm("Node "+t+" is neither source nor target of edge "+n))}function Uin(n,t){var e;switch(t.g){case 2:case 4:e=n.a,n.c.d.n.b0&&(o+=r),s[h]=a,a+=u*(o+i)}function Win(n){var t,e,i;for(i=n.f,n.n=VQ(Jot,rMn,25,i,15,1),n.d=VQ(Jot,rMn,25,i,15,1),t=0;t0?n.c:0),++c;n.b=r,n.d=a}function irn(n,t){var i;return i=x4(Gy(Jot,1),rMn,25,15,[zen(n,(JZ(),rHn),t),zen(n,cHn,t),zen(n,aHn,t)]),n.f&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function rrn(n,t,e){try{cgn(n,t+n.j,e+n.k,!1,!0)}catch(n){throw CO(n=j4(n),73)?hp(new Hm(n.g+qSn+t+tEn+e+").")):hp(n)}}function crn(n,t,e){try{cgn(n,t+n.j,e+n.k,!0,!1)}catch(n){throw CO(n=j4(n),73)?hp(new Hm(n.g+qSn+t+tEn+e+").")):hp(n)}}function arn(n){var t;O$(n,(gjn(),U1n))&&((t=Yx(Aun(n,U1n),21)).Hc((Eln(),Get))?(t.Mc(Get),t.Fc(Uet)):t.Hc(Uet)&&(t.Mc(Uet),t.Fc(Get)))}function urn(n){var t;O$(n,(gjn(),U1n))&&((t=Yx(Aun(n,U1n),21)).Hc((Eln(),Yet))?(t.Mc(Yet),t.Fc(Vet)):t.Hc(Vet)&&(t.Mc(Vet),t.Fc(Yet)))}function orn(n,t,e,i){var r,c;for(r=t;r0&&(c.b+=t),c}function brn(n,t){var i,r,c;for(c=new Pk,r=n.Kc();r.Ob();)bgn(i=Yx(r.Pb(),37),0,c.b),c.b+=i.f.b+t,c.a=e.Math.max(c.a,i.f.a);return c.a>0&&(c.a+=t),c}function wrn(n){var t,i,r;for(r=Yjn,i=new pb(n.a);i.a>16==6?n.Cb.ih(n,5,cct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function vrn(n){var t,i,r;n.b==n.c&&(r=n.a.length,i=j5(e.Math.max(8,r))<<1,0!=n.b?(Z0(n,t=eN(n.a,i),r),n.a=t,n.b=0):zp(n.a,i),n.c=r)}function mrn(n,t){var e;return(e=n.b).Xe((Cjn(),ytt))?e.Hf()==(Ikn(),qit)?-e.rf().a-ty(fL(e.We(ytt))):t+ty(fL(e.We(ytt))):e.Hf()==(Ikn(),qit)?-e.rf().a:t}function yrn(n){var t;return 0!=n.b.c.length&&Yx(TR(n.b,0),70).a?Yx(TR(n.b,0),70).a:null!=(t=IH(n))?t:""+(n.c?hJ(n.c.a,n,0):-1)}function krn(n){var t;return 0!=n.f.c.length&&Yx(TR(n.f,0),70).a?Yx(TR(n.f,0),70).a:null!=(t=IH(n))?t:""+(n.i?hJ(n.i.j,n,0):-1)}function jrn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e0?n.c:0),c=e.Math.max(c,t.d),++r;n.e=a,n.b=c}function Mrn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),n.o):(!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),UQ(n.o)):$en(n,t,e,i)}function Srn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t>22))>>22)<0||(n.l=e&BTn,n.m=i&BTn,n.h=r&HTn,0)))}function Crn(n,t,e){var i,r;return a8(r=new Uv,t),E2(r,e),fY((!n.c&&(n.c=new m_(lat,n,12,10)),n.c),r),_1(i=r,0),F1(i,1),l9(i,!0),s9(i,!0),i}function Orn(n,t){var e,i;if(t>=n.i)throw hp(new BI(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&smn(n.g,t+1,n.g,t,i),DF(n.g,--n.i,null),n.fi(t,e),n.ci(),e}function Arn(n,t){var e;return n.Db>>16==17?n.Cb.ih(n,21,rat,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function $rn(n){var t,e,i,r,c;for(r=Yjn,c=null,i=new pb(n.d);i.ae.a.c.length))throw hp(new Qm("index must be >= 0 and <= layer node count"));n.c&&uJ(n.c.a,n),n.c=e,e&&ZR(e.a,t,n)}function qrn(n,t){var e,i,r;for(i=new $K(bA(a7(n).a.Kc(),new h));Vfn(i);)return e=Yx(kV(i),17),new Bf(MF((r=Yx(t.Kb(e),10)).n.b+r.o.b/2));return gm(),gm(),zKn}function Grn(n,t){this.c=new rp,this.a=n,this.b=t,this.d=Yx(Aun(n,(Ojn(),zQn)),304),iI(Aun(n,(gjn(),X1n)))===iI((cJ(),iVn))?this.e=new Cv:this.e=new Iv}function zrn(n,t){var e,i;return i=null,n.Xe((Cjn(),Htt))&&(e=Yx(n.We(Htt),94)).Xe(t)&&(i=e.We(t)),null==i&&n.yf()&&(i=n.yf().We(t)),null==i&&(i=oen(t)),i}function Urn(n,t){var e,i;e=n.Zc(t);try{return i=e.Pb(),e.Qb(),i}catch(n){throw CO(n=j4(n),109)?hp(new Hm("Can't remove element "+t)):hp(n)}}function Xrn(n,t){var e,i,r;for(vB(t),T$(t!=n),r=n.b.c.length,i=t.Kc();i.Ob();)e=i.Pb(),eD(n.b,vB(e));return r!=n.b.c.length&&(l6(n,0),!0)}function Wrn(){Wrn=O,Cjn(),xGn=Hnt,new DC(Cnt,(TA(),!0)),KGn=Jnt,_Gn=ttt,FGn=itt,RGn=Qnt,BGn=att,HGn=Mtt,Lrn(),NGn=CGn,$Gn=SGn,LGn=IGn,DGn=OGn,AGn=MGn}function Vrn(n,t,e,i){var r,c,a;for(JG(t,Yx(i.Xb(0),29)),a=i.bd(1,i.gc()),c=Yx(e.Kb(t),20).Kc();c.Ob();)Vrn(n,(r=Yx(c.Pb(),17)).c.i==t?r.d.i:r.c.i,e,a)}function Qrn(n){var t;return t=new rp,O$(n,(Ojn(),QQn))?Yx(Aun(n,QQn),83):(SE(hH(new SR(null,new Nz(n.j,16)),new tr),new _w(t)),b5(n,QQn,t),t)}function Yrn(n,t){var e;return n.Db>>16==6?n.Cb.ih(n,6,nct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(ajn(),xrt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Jrn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,1,Yrt,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(ajn(),Rrt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Zrn(n,t){var e;return n.Db>>16==9?n.Cb.ih(n,9,uct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(ajn(),_rt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function ncn(n,t){var e;return n.Db>>16==5?n.Cb.ih(n,9,oat,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(xjn(),Tat),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function tcn(n,t){var e;return n.Db>>16==3?n.Cb.ih(n,0,ect,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(xjn(),pat),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function ecn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,6,cct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(xjn(),Lat),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function icn(){this.a=new lo,this.g=new iin,this.j=new iin,this.b=new rp,this.d=new iin,this.i=new iin,this.k=new rp,this.c=new rp,this.e=new rp,this.f=new rp}function rcn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;rcMn)return ccn(n,i);if(i==n)return!0}}return!1}function acn(n,t){var i,r,c;for(uJ(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=d$n,r=new pb(n.a);r.a>16==3?n.Cb.ih(n,12,uct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(ajn(),Nrt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function ocn(n,t){var e;return n.Db>>16==11?n.Cb.ih(n,10,uct,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(ajn(),Krt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function scn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,11,rat,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(xjn(),Aat),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hcn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,12,fat,t):(e=nin(Yx(CZ(Yx(H3(n,16),26)||(xjn(),Nat),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function fcn(n){var t;return 0==(1&n.Bb)&&n.r&&n.r.kh()&&(t=Yx(n.r,49),n.r=Yx(P8(n,t),138),n.r!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,9,8,t,n.r))),n.r}function lcn(n,t,i){var r;return r=x4(Gy(Jot,1),rMn,25,15,[yun(n,(JZ(),rHn),t,i),yun(n,cHn,t,i),yun(n,aHn,t,i)]),n.f&&(r[0]=e.Math.max(r[0],r[2]),r[2]=r[0]),r}function bcn(n,t){var e,i,r;if(0!=(r=function(n,t){var e,i,r;for(r=new pQ(t.gc()),i=t.Kc();i.Ob();)(e=Yx(i.Pb(),286)).c==e.f?nsn(n,e,e.c):Von(n,e)||(r.c[r.c.length]=e);return r}(n,t)).c.length)for(JC(r,new ti),e=r.c.length,i=0;i>19)!=(u=t.h>>19)?u-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function pcn(){pcn=O,$dn(),BBn=new FI(uSn,HBn=VBn),sZ(),_Bn=new FI(oSn,FBn=LBn),nen(),RBn=new FI(sSn,KBn=CBn),DBn=new FI(hSn,(TA(),!0))}function vcn(n,t,e){var i,r;i=t*e,CO(n.g,145)?(r=SX(n)).f.d?r.f.a||(n.d.a+=i+SSn):(n.d.d-=i+SSn,n.d.a+=i+SSn):CO(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function mcn(n,t,i){var r,c,a,u,o;for(c=n[i.g],o=new pb(t.d);o.a0?n.g:0),++i;t.b=r,t.e=c}function kcn(n){var t,e,i;if(i=n.b,mE(n.i,i.length)){for(e=2*i.length,n.b=VQ(c_n,qEn,317,e,0,1),n.c=VQ(c_n,qEn,317,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)phn(n,t,t);++n.g}}function jcn(n,t,e){var i;(i=t.c.i).k==(bon(),Bzn)?(b5(n,(Ojn(),TQn),Yx(Aun(i,TQn),11)),b5(n,MQn,Yx(Aun(i,MQn),11))):(b5(n,(Ojn(),TQn),t.c),b5(n,MQn,e.d))}function Ecn(n,t,i){var r,c,a,u,o,s;return udn(),u=t/2,a=i/2,o=1,s=1,(r=e.Math.abs(n.a))>u&&(o=u/r),(c=e.Math.abs(n.b))>a&&(s=a/c),KO(n,e.Math.min(o,s)),n}function Tcn(){uE.call(this),this.e=-1,this.a=!1,this.p=nTn,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=nTn}function Mcn(){Mcn=O,WGn=yK(oR(oR(oR(new fX,($un(),nzn),($jn(),NUn)),nzn,KUn),tzn,zUn),tzn,jUn),QGn=oR(oR(new fX,nzn,lUn),nzn,EUn),VGn=yK(new fX,tzn,MUn)}function Scn(n,t){var e,i,r,c;for(c=new rp,t.e=null,t.f=null,i=new pb(t.i);i.a0)try{i=ipn(t,nTn,Yjn)}catch(n){throw CO(n=j4(n),127)?hp(new mJ(n)):hp(n)}return!n.a&&(n.a=new Vg(n)),i<(e=n.a).i&&i>=0?Yx(c1(e,i),56):null}(n,0==(r=t.c.length)?"":($z(0,t.c.length),lL(t.c[0]))),i=1;i0&&(r=efn(n,(c&Yjn)%n.d.length,c,t))?r.ed(e):(i=n.tj(c,t,e),n.c.Fc(i),null)}function Dcn(n,t){var e,i,r,c;switch(U8(n,t)._k()){case 3:case 2:for(r=0,c=(e=emn(t)).i;r=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}(n,n)/I8(2.718281828459045,n))}function Fcn(n,t){var e;if(n.ni()&&null!=t){for(e=0;e0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=e.Math.min(r,c))}function Ucn(n,t){var e;if(e=!1,aI(t)&&(e=!0,nB(n,new zF(lL(t)))),e||CO(t,236)&&(e=!0,nB(n,new Tl(tx(Yx(t,236))))),!e)throw hp(new Gm(ixn))}function Xcn(n){var t,e;switch(Yx(Aun(dB(n),(gjn(),A1n)),420).g){case 0:return t=n.n,e=n.o,new QS(t.a+e.a/2,t.b+e.b/2);case 1:return new fC(n.n);default:return null}}function Wcn(){Wcn=O,hVn=new VM(fIn,0),sVn=new VM("LEFTUP",1),lVn=new VM("RIGHTUP",2),oVn=new VM("LEFTDOWN",3),fVn=new VM("RIGHTDOWN",4),uVn=new VM("BALANCED",5)}function Vcn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new m_(act,n,1,7)),Hmn(n.n),!n.n&&(n.n=new m_(act,n,1,7)),void jF(n.n,Yx(e,14));case 2:return void $0(n,lL(e))}J5(n,t,e)}function Qcn(n,t,e){switch(t){case 3:return void A1(n,ty(fL(e)));case 4:return void $1(n,ty(fL(e)));case 5:return void L1(n,ty(fL(e)));case 6:return void N1(n,ty(fL(e)))}Vcn(n,t,e)}function Ycn(n,t,e){var i,r;(i=fun(r=new Uv,t,null))&&i.Fi(),E2(r,e),fY((!n.c&&(n.c=new m_(lat,n,12,10)),n.c),r),_1(r,0),F1(r,1),l9(r,!0),s9(r,!0)}function Jcn(n,t){var e,i;return CO(e=NT(n.g,t),235)?((i=Yx(e,235)).Qh(),i.Nh()):CO(e,498)?i=Yx(e,1938).b:null}function Zcn(n,t,e,i){var r,c;return MF(t),MF(e),EJ(!!(c=Yx(nx(n.d,t),19)),"Row %s not in %s",t,n.e),EJ(!!(r=Yx(nx(n.b,e),19)),"Column %s not in %s",e,n.c),N4(n,c.a,r.a,i)}function nan(n,t,e,i,r,c,a){var u,o,s,h,f;if(f=Zin(u=(s=c==a-1)?i:0,h=r[c]),10!=i&&x4(Gy(n,a-c),t[c],e[c],u,f),!s)for(++c,o=0;o0?n.i:0)),++t;for(function(n,t){var e,i;for(vB(t),e=!1,i=new pb(n);i.a1||-1==u?(c=Yx(o,15),r.Wb(function(n,t){var e,i,r;for(i=new pQ(t.gc()),e=t.Kc();e.Ob();)(r=Qgn(n,Yx(e.Pb(),56)))&&(i.c[i.c.length]=r);return i}(n,c))):r.Wb(Qgn(n,Yx(o,56))))}function ban(n){switch(Yx(Aun(n.b,(gjn(),g1n)),375).g){case 1:SE(fH(WJ(new SR(null,new Nz(n.d,16)),new _r),new Fr),new Br);break;case 2:!function(n){var t,e,i,r,c,a,u;for(i=0,u=0,a=new pb(n.d);a.a0&&Nrn(this,this.c-1,(Ikn(),Eit)),this.c0&&n[0].length>0&&(this.c=ny(hL(Aun(dB(n[0][0]),(Ojn(),yQn))))),this.a=VQ(B3n,TEn,2018,n.length,0,2),this.b=VQ(X3n,TEn,2019,n.length,0,2),this.d=new e8}function Nan(n){return 0!=n.c.length&&(($z(0,n.c.length),Yx(n.c[0],17)).c.i.k==(bon(),Bzn)||JW(fH(new SR(null,new Nz(n,16)),new Kc),new _c))}function xan(n,t,e){return run(e,"Tree layout",1),_U(n.b),q_(n.b,(Krn(),Y4n),Y4n),q_(n.b,J4n,J4n),q_(n.b,Z4n,Z4n),q_(n.b,n5n,n5n),n.a=Zmn(n.b,t),function(n,t,e){var i,r,c;if(!(r=e)&&(r=new am),run(r,"Layout",n.a.c.length),ny(hL(Aun(t,(cln(),R5n)))))for(oE(),i=0;i=0?(e=Bcn(n,UTn),i=Snn(n,UTn)):(e=Bcn(t=UK(n,1),5e8),i=t7(GK(i=Snn(t,5e8),1),Gz(n,1))),zz(GK(i,32),Gz(e,uMn))}function Xan(n,t,e){var i;switch(S$(0!=t.b),i=Yx(VZ(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return oF(Ztn(t,0),i),t}function Wan(n,t,e,i){var r,c,a,u,o;switch(o=n.b,u=Ktn(a=(c=t.d).j,o.d[a.g],e),r=mN(dO(c.n),c.a),c.j.g){case 1:case 3:u.a+=r.a;break;case 2:case 4:u.b+=r.b}VW(i,u,i.c.b,i.c)}function Van(n,t,e){var i,r,c,a;for(a=hJ(n.e,t,0),(c=new pv).b=e,i=new JU(n.e,a);i.b=0;t--)zFn[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)GFn[n]=e,e*=.5}function Yan(n){var t,e;if(ny(hL(jln(n,(gjn(),I1n)))))for(e=new $K(bA(lbn(n).a.Kc(),new h));Vfn(e);)if(Whn(t=Yx(kV(e),79))&&ny(hL(jln(t,C1n))))return!0;return!1}function Jan(n,t){var e,i,r;__(n.f,t)&&(t.b=n,i=t.c,-1!=hJ(n.j,i,0)||eD(n.j,i),r=t.d,-1!=hJ(n.j,r,0)||eD(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new Wtn(n)),function(n,t){var e,i;for(i=new pb(t);i.a=n.f)break;c.c[c.c.length]=e}return c}function oun(n){var t,e,i,r;for(t=null,r=new pb(n.wf());r.a0&&smn(n.g,t,n.g,t+i,u),a=e.Kc(),n.i+=i,r=0;rc&&S_(s,$Z(e[u],KFn))&&(r=u,c=o);return r>=0&&(i[0]=t+c),r}function dun(n,t,e){run(e,"Grow Tree",1),n.b=t.f,ny(hL(Aun(t,(y3(),hqn))))?(n.c=new it,mz(n,null)):n.c=new it,n.a=!1,iwn(n,t.f),b5(t,fqn,(TA(),!!n.a)),Ron(e)}function gun(n){var t,e;return n>=eMn?(t=iMn+(n-eMn>>10&1023)&fTn,e=56320+(n-eMn&1023)&fTn,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&fTn)}function pun(n,t,e,i,r){var c,a,u;for(c=Vwn(n,t,e,i,r),u=!1;!c;)Nln(n,r,!0),u=!0,c=Vwn(n,t,e,i,r);u&&Nln(n,r,!1),0!=(a=G4(r)).c.length&&(n.d&&n.d.lg(a),pun(n,r,e,i,a))}function vun(){vun=O,ket=new eP(fIn,0),met=new eP("DIRECTED",1),jet=new eP("UNDIRECTED",2),pet=new eP("ASSOCIATION",3),yet=new eP("GENERALIZATION",4),vet=new eP("DEPENDENCY",5)}function mun(n,t){var e,i;for(vB(t),i=n.b.c.length,eD(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.ue(TR(n.b,i),t)<=0)return QW(n.b,e,t),!0;QW(n.b,e,TR(n.b,i))}return QW(n.b,i,t),!0}function yun(n,t,i,r){var c,a;if(c=0,i)c=Y6(n.a[i.g][t.g],r);else for(a=0;a=a)}function jun(n,t,e,i){var r;if(r=!1,aI(i)&&(r=!0,ND(t,e,lL(i))),r||rI(i)&&(r=!0,jun(n,t,e,i)),r||CO(i,236)&&(r=!0,nq(t,e,Yx(i,236))),!r)throw hp(new Gm(ixn))}function Eun(n,t){var e,i,r,c;if(vB(t),(c=n.a.gc())=hTn?"error":"warn",n.a),n.b&&Jbn(t,e,n.b,"Exception: ",!0))}function Aun(n,t){var e,i;return!n.q&&(n.q=new rp),null!=(i=BF(n.q,t))?i:(CO(e=t.wg(),4)&&(null==e?(!n.q&&(n.q=new rp),zV(n.q,t)):(!n.q&&(n.q=new rp),xB(n.q,t,e))),e)}function $un(){$un=O,YGn=new bM("P1_CYCLE_BREAKING",0),JGn=new bM("P2_LAYERING",1),ZGn=new bM("P3_NODE_ORDERING",2),nzn=new bM("P4_NODE_PLACEMENT",3),tzn=new bM("P5_EDGE_ROUTING",4)}function Lun(n,t){var e,i,r,c;for(i=(1==t?ozn:uzn).a.ec().Kc();i.Ob();)for(e=Yx(i.Pb(),103),c=Yx(_V(n.f.c,e),21).Kc();c.Ob();)r=Yx(c.Pb(),46),uJ(n.b.b,r.b),uJ(n.b.a,Yx(r.b,81).d)}function Nun(n,t){var e;if(oZ(),n.c==t.c){if(n.b==t.b||function(n,t){return _4(),n==bzn&&t==gzn||n==gzn&&t==bzn||n==dzn&&t==wzn||n==wzn&&t==dzn}(n.b,t.b)){if(e=function(n){return n==bzn||n==gzn}(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return eO(n.b.g,t.b.g)}return $9(n.c,t.c)}function xun(n,t){var e,i;if(zun(n,t))return!0;for(i=new pb(t);i.a=(r=n.Vi())||t<0)throw hp(new Hm(jxn+t+Exn+r));if(e>=r||e<0)throw hp(new Hm(Txn+e+Exn+r));return t!=e?(c=n.Ti(e),n.Hi(t,c),i=c):i=n.Oi(e),i}function qun(n){var t,e,i;if(i=n,n)for(t=0,e=n.Ug();e;e=e.Ug()){if(++t>cMn)return qun(e);if(i=e,e==n)throw hp(new Ym("There is a cycle in the containment hierarchy of "+n))}return i}function Gun(n){var t,e,i;for(i=new J3(tEn,"[","]"),e=n.Kc();e.Ob();)HV(i,iI(t=e.Pb())===iI(n)?"(this Collection)":null==t?aEn:I7(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function zun(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;ei&&(Lz(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||t1&&(n.j.b+=n.e)):(n.j.a+=i.a,n.j.b=e.Math.max(n.j.b,i.b),n.d.c.length>1&&(n.j.a+=n.e))}function Qun(){Qun=O,UXn=x4(Gy(trt,1),lIn,61,0,[(Ikn(),Tit),Eit,Bit]),zXn=x4(Gy(trt,1),lIn,61,0,[Eit,Bit,qit]),XXn=x4(Gy(trt,1),lIn,61,0,[Bit,qit,Tit]),WXn=x4(Gy(trt,1),lIn,61,0,[qit,Tit,Eit])}function Yun(n,t,e,i){var r,c,a,u,o;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(o=n.b,r=c.j,u=null;r!=a.j;)u=0==t?A9(r):C9(r),KD(i,mN(Ktn(r,o.d[r.g],e),Ktn(u,o.d[u.g],e))),r=u}function Jun(n,t,e,i){var r,c,a,u,o;return u=Yx((a=Drn(n.a,t,e)).a,19).a,c=Yx(a.b,19).a,i&&(o=Yx(Aun(t,(Ojn(),RQn)),10),r=Yx(Aun(e,RQn),10),o&&r&&(YX(n.b,o,r),u+=n.b.i,c+=n.b.e)),u>c}function Zun(n){var t,e,i,r,c,a,u,o;for(this.a=xen(n),this.b=new ip,i=0,r=(e=n).length;i0&&(n.a[q.p]=J++)}for(rn=0,N=0,R=(A=i).length;N0;){for(S$(X.b>0),U=0,o=new pb((q=Yx(X.a.Xb(X.c=--X.b),11)).e);o.a0&&(q.j==(Ikn(),Tit)?(n.a[q.p]=rn,++rn):(n.a[q.p]=rn+K+F,++F))}rn+=F}for(z=new rp,d=new oC,$=0,x=(C=t).length;$h.b&&(h.b=W)):q.i.c==Y&&(Wh.c&&(h.c=W));for(DY(g,0,g.length,null),en=VQ(Wot,MTn,25,g.length,15,1),r=VQ(Wot,MTn,25,rn+1,15,1),v=0;v0;)T%2>0&&(c+=un[T+1]),++un[T=(T-1)/2|0];for(S=VQ(i4n,iEn,362,2*g.length,0,1),k=0;kTL(n.d).c?(n.i+=n.g.c,Cnn(n.d)):TL(n.d).c>TL(n.g).c?(n.e+=n.d.c,Cnn(n.g)):(n.i+=IR(n.g),n.e+=IR(n.d),Cnn(n.g),Cnn(n.d))}function ion(n,t,i,r){n.a.d=e.Math.min(t,i),n.a.a=e.Math.max(t,r)-n.a.d,to&&(s=o/r),(c=e.Math.abs(t.b-n.b))>a&&(h=a/c),u=e.Math.min(s,h),n.a+=u*(t.a-n.a),n.b+=u*(t.b-n.b)}function son(n,t,e,i,r){var c,a;for(a=!1,c=Yx(TR(e.b,0),33);Svn(n,t,c,i,r)&&(a=!0,oan(e,c),0!=e.b.c.length);)c=Yx(TR(e.b,0),33);return 0==e.b.c.length&&acn(e.j,e),a&&ern(t.q),a}function hon(n,t){var e,i,r,c;if(udn(),t.b<2)return!1;for(i=e=Yx(IX(c=Ztn(t,0)),8);c.b!=c.d.c;){if(Rbn(n,i,r=Yx(IX(c),8)))return!0;i=r}return!!Rbn(n,i,e)}function fon(n,t,e,i){return 0==e?(!n.o&&(n.o=new yY((ajn(),Frt),mct,n,0)),YN(n.o,t,i)):Yx(CZ(Yx(H3(n,16),26)||n.zh(),e),66).Nj().Rj(n,dtn(n),e-vF(n.zh()),t,i)}function lon(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=Yx(n.sb,49).ih(n,1,ict,e)),t&&(e=Yx(t,49).gh(n,1,ict,e)),(e=H8(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,4,t,t))}function bon(){bon=O,Hzn=new gM("NORMAL",0),Bzn=new gM("LONG_EDGE",1),_zn=new gM("EXTERNAL_PORT",2),qzn=new gM("NORTH_SOUTH_PORT",3),Fzn=new gM("LABEL",4),Kzn=new gM("BREAKING_POINT",5)}function won(n,t,e){var i;run(e,"Self-Loop routing",1),i=function(n){switch(Yx(Aun(n,(gjn(),b1n)),218).g){case 1:return new ic;case 3:return new oc;default:return new ec}}(t),dI(Aun(t,(tQ(),K7n))),SE(fH(hH(hH(WJ(new SR(null,new Nz(t.b,16)),new zi),new Ui),new Xi),new Wi),new yM(n,i)),Ron(e)}function don(n,t){var e,i,r;return(t&=63)<22?(e=n.l<>22-t,r=n.h<>22-t):t<44?(e=0,i=n.l<>44-t):(e=0,i=0,r=n.l<n)throw hp(new Qm("k must be smaller than n"));return 0==t||t==n?1:0==n?0:_cn(n)/(_cn(t)*_cn(n-t))}function mon(n,t){var e,i,r,c;for(e=new SC(n);null!=e.g||e.c?null==e.g||0!=e.i&&Yx(e.g[e.i-1],47).Ob():AG(e);)if(CO(c=Yx(abn(e),56),160))for(i=Yx(c,160),r=0;r0&&ygn(n,e,t),r):function(n,t,e){var i,r,c;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?((c=WK(i.a,r.a))<0?ygn(n,t,e):c>0&&ygn(n,e,t),c):null!=i.a?(ygn(n,t,e),-1):null!=r.a?(ygn(n,e,t),1):0}(n,t,e)}function xon(n,t,e){var i,r,c,a;if(0!=t.b){for(i=new ME,a=Ztn(t,0);a.b!=a.d.c;)C2(i,q4(c=Yx(IX(a),86))),(r=c.e).a=Yx(Aun(c,(ryn(),O5n)),19).a,r.b=Yx(Aun(c,A5n),19).a;xon(n,i,J2(e,i.b/n.a|0))}}function Don(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(function(n,t,e){var i;return(i=omn(n,t,!1)).b<=t&&i.a<=e}(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+11&&(n.e.b+=n.a)):(n.e.a+=i.a,n.e.b=e.Math.max(n.e.b,i.b),n.d.c.length>1&&(n.e.a+=n.a))}function Bon(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function Hon(n,t,e,i,r){if(ii&&(n.a=i),n.br&&(n.b=r),n}function qon(n){if(CO(n,149))return function(n){var t,e,i,r,c;return c=cun(n),null!=n.a&&ND(c,"category",n.a),!Sj(new Yl(n.d))&&(OZ(c,"knownOptions",i=new Sl),t=new Mg(i),XW(new Yl(n.d),t)),!Sj(n.g)&&(OZ(c,"supportedFeatures",r=new Sl),e=new Sg(r),XW(n.g,e)),c}(Yx(n,149));if(CO(n,229))return function(n){var t,e,i;return i=cun(n),!Sj(n.c)&&(OZ(i,"knownLayouters",e=new Sl),t=new Pg(e),XW(n.c,t)),i}(Yx(n,229));if(CO(n,23))return function(n){var t,e,i;return i=cun(n),null!=n.e&&ND(i,dxn,n.e),!!n.k&&ND(i,"type",d$(n.k)),!Sj(n.j)&&(e=new Sl,OZ(i,VNn,e),t=new Ig(e),XW(n.j,t)),i}(Yx(n,23));throw hp(new Qm(axn+Gun(new ay(x4(Gy(UKn,1),iEn,1,5,[n])))))}function Gon(n,t,e,i){var r,c;if(t.k==(bon(),Bzn))for(c=new $K(bA(u7(t).a.Kc(),new h));Vfn(c);)if((r=Yx(kV(c),17)).c.i.k==Bzn&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function zon(n,t,e,i){var r;this.b=i,this.e=n==(l0(),z3n),r=t[e],this.d=fR(Vot,[TEn,wSn],[177,25],16,[r.length,r.length],2),this.a=fR(Wot,[TEn,MTn],[48,25],15,[r.length,r.length],2),this.c=new $an(t,e)}function Uon(n){var t,e,i;for(n.k=new Cz((Ikn(),x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit])).length,n.j.c.length),i=new pb(n.j);i.a=e)return nsn(n,t,i.p),!0;return!1}function Qon(n){var t;return 0!=(64&n.Db)?yon(n):(t=new SA(wNn),!n.a||yI(yI((t.a+=' "',t),n.a),'"'),yI(tj(yI(tj(yI(tj(yI(tj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function Yon(n,t,e){var i,r,c,a,u;for(u=dwn(n.e.Tg(),t),r=Yx(n.g,119),i=0,a=0;a0&&esn(n,c,e));t.p=0}function isn(n){var t;this.c=new ME,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new cx(t=Yx(Ak(D7n),9),Yx(eN(t,t.length),9),0),this.g=n.f}function rsn(n,t,e){var i,r,c;if(!(e<=t+2))for(r=(e-t)/2|0,i=0;i=0?n.Bh(r):Ehn(n,i)}else r9(n,e,i)}function osn(n){var t,e;if(e=null,t=!1,CO(n,204)&&(t=!0,e=Yx(n,204).a),t||CO(n,258)&&(t=!0,e=""+Yx(n,258).a),t||CO(n,483)&&(t=!0,e=""+Yx(n,483).a),!t)throw hp(new Gm(ixn));return e}function ssn(n,t){var e,i;if(n.f){for(;t.Ob();)if(CO(i=(e=Yx(t.Pb(),72)).ak(),99)&&0!=(Yx(i,18).Bb&MNn)&&(!n.e||i.Gj()!=Vrt||0!=i.aj())&&null!=e.dd())return t.Ub(),!0;return!1}return t.Ob()}function hsn(n,t){var e,i;if(n.f){for(;t.Sb();)if(CO(i=(e=Yx(t.Ub(),72)).ak(),99)&&0!=(Yx(i,18).Bb&MNn)&&(!n.e||i.Gj()!=Vrt||0!=i.aj())&&null!=e.dd())return t.Pb(),!0;return!1}return t.Sb()}function fsn(n,t,e){var i,r,c,a,u,o;for(o=dwn(n.e.Tg(),t),i=0,u=n.i,r=Yx(n.g,119),a=0;a=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++0;)WG(this);this.b=t,this.a=null}function Esn(n,t){var e,i;t.a?function(n,t){var e;if(!uF(n.b,t.b))throw hp(new Ym("Invalid hitboxes for scanline constraint calculation."));(C4(t.b,Yx(function(n,t){return $k(Rnn(n.a,t,!0))}(n.b,t.b),57))||C4(t.b,Yx(function(n,t){return $k(Dnn(n.a,t,!0))}(n.b,t.b),57)))&&(oE(),t.b),n.a[t.b.f]=Yx(BN(n.b,t.b),57),(e=Yx(FN(n.b,t.b),57))&&(n.a[e.f]=t.b)}(n,t):(!!(e=Yx(BN(n.b,t.b),57))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=Yx(FN(n.b,t.b),57))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),RA(n.b,t.b))}function Tsn(n,t){var e,i;if(e=Yx(GB(n.b,t),124),Yx(Yx(_V(n.r,t),21),84).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((Ann(),nrt))&&Xdn(n,t),i=function(n,t){var e,i,r;for(r=0,i=Yx(Yx(_V(n.r,t),21),84).Kc();i.Ob();)r+=(e=Yx(i.Pb(),111)).d.b+e.b.rf().a+e.d.c,i.Ob()&&(r+=n.w);return r}(n,t),hdn(n,t)==(Ytn(),eit)&&(i+=2*n.w),e.a.a=i}function Msn(n,t){var e,i;if(e=Yx(GB(n.b,t),124),Yx(Yx(_V(n.r,t),21),84).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((Ann(),nrt))&&Wdn(n,t),i=function(n,t){var e,i,r;for(r=0,i=Yx(Yx(_V(n.r,t),21),84).Kc();i.Ob();)r+=(e=Yx(i.Pb(),111)).d.d+e.b.rf().b+e.d.a,i.Ob()&&(r+=n.w);return r}(n,t),hdn(n,t)==(Ytn(),eit)&&(i+=2*n.w),e.a.b=i}function Ssn(n,t){var e,i,r,c;for(c=new ip,i=new pb(t);i.a=0&&_N(n.substr(u,2),"//")?(o=Btn(n,u+=2,Wct,Vct),i=n.substr(u,o-u),u=o):null==f||u!=n.length&&(Lz(u,n.length),47==n.charCodeAt(u))||(a=!1,-1==(o=NA(n,gun(35),u))&&(o=n.length),i=n.substr(u,o-u),u=o);if(!e&&u0&&58==XB(h,h.length-1)&&(r=h,u=o)),u0&&(Lz(0,e.length),47!=e.charCodeAt(0))))throw hp(new Qm("invalid opaquePart: "+e));if(n&&(null==t||!fE(Rct,t.toLowerCase()))&&null!=e&&$7(e,Wct,Vct))throw hp(new Qm(EDn+e));if(n&&null!=t&&fE(Rct,t.toLowerCase())&&!function(n){if(null!=n&&n.length>0&&33==XB(n,n.length-1))try{return null==xsn(l$(n,0,n.length-1)).e}catch(n){if(!CO(n=j4(n),32))throw hp(n)}return!1}(e))throw hp(new Qm(EDn+e));if(!function(n){var t;return null==n||(t=n.length)>0&&(Lz(t-1,n.length),58==n.charCodeAt(t-1))&&!$7(n,Wct,Vct)}(i))throw hp(new Qm("invalid device: "+i));if(!function(n){var t,e;if(null==n)return!1;for(t=0,e=n.length;te.a&&(i.Hc((dan(),ont))?r=(t.a-e.a)/2:i.Hc(hnt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((dan(),lnt))?c=(t.b-e.b)/2:i.Hc(fnt)&&(c=t.b-e.b)),Pun(n,r,c)}function Gsn(n,t,e,i,r,c,a,u,o,s,h,f,l){CO(n.Cb,88)&&rhn(bV(Yx(n.Cb,88)),4),E2(n,e),n.f=a,D9(n,u),K9(n,o),x9(n,s),R9(n,h),l9(n,f),H9(n,l),s9(n,!0),_1(n,r),n.ok(c),a8(n,t),null!=i&&(n.i=null,J0(n,i))}function zsn(n){var t,e;if(n.f){for(;n.n>0;){if(CO(e=(t=Yx(n.k.Xb(n.n-1),72)).ak(),99)&&0!=(Yx(e,18).Bb&MNn)&&(!n.e||e.Gj()!=Vrt||0!=e.aj())&&null!=t.dd())return!0;--n.n}return!1}return n.n>0}function Usn(n,t,e){if(n<0)return ngn(eEn,x4(Gy(UKn,1),iEn,1,5,[e,d9(n)]));if(t<0)throw hp(new Qm(rEn+t));return ngn("%s (%s) must not be greater than size (%s)",x4(Gy(UKn,1),iEn,1,5,[e,d9(n),d9(t)]))}function Xsn(n,t,e,i,r,c){var a,u,o;if(i-e<7)!function(n,t,e,i){var r,c,a;for(r=t+1;rt&&i.ue(n[c-1],n[c])>0;--c)a=n[c],DF(n,c,n[c-1]),DF(n,c-1,a)}(t,e,i,c);else if(Xsn(t,n,u=e+r,o=u+((a=i+r)-u>>1),-r,c),Xsn(t,n,o,a,-r,c),c.ue(n[o-1],n[o])<=0)for(;e=i||t=0?n.sh(c,e):pbn(n,r,e)}else E7(n,i,r,e)}function Qsn(n){var t,e,i,r,c;if(e=Yx(n,49).qh())try{if(i=null,(t=Hln((mT(),aat),spn(null==(c=e).e?c:(!c.c&&(c.c=new xdn(0!=(256&c.f),c.i,c.a,c.d,0!=(16&c.f),c.j,c.g,null)),c.c))))&&(r=t.rh())&&(i=r.Wk(function(n){return vB(n),n}(e.e))),i&&i!=n)return Qsn(i)}catch(c){if(!CO(c=j4(c),60))throw hp(c)}return n}function Ysn(n,t,e){var i,r,c,a;if(a=null==t?0:n.b.se(t),0==(r=null==(i=n.a.get(a))?new Array:i).length)n.a.set(a,r);else if(c=q6(n,t,r))return c.ed(e);return DF(r,r.length,new zT(t,e)),++n.c,gq(n.b),null}function Jsn(n,t){var e;return _U(n.a),q_(n.a,(p2(),h6n),h6n),q_(n.a,f6n,f6n),oR(e=new fX,f6n,(m7(),g6n)),iI(jln(t,(_rn(),F6n)))!==iI((I6(),E6n))&&oR(e,f6n,w6n),oR(e,f6n,d6n),aC(n.a,e),Zmn(n.a,t)}function Zsn(n){if(!n)return yy(),M_n;var t=n.valueOf?n.valueOf():n;if(t!==n){var i=S_n[typeof t];return i?i(t):Z6(typeof t)}return n instanceof Array||n instanceof e.Array?new jl(n):new Ml(n)}function nhn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=Yx(GB(n.p,i),244)).i).b=Rhn(r),c.a=Dhn(r),c.b=e.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,i.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}cvn(r),hvn(r)}function thn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=Yx(GB(n.p,i),244)).i).b=Rhn(r),c.a=Dhn(r),c.a=e.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,i.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}cvn(r),hvn(r)}function ehn(n,t){var e,i,r,c;if(udn(),t.b<2)return!1;for(i=e=Yx(IX(c=Ztn(t,0)),8);c.b!=c.d.c;){if(r=Yx(IX(c),8),!s3(n,i)||!s3(n,r))return!1;i=r}return!(!s3(n,i)||!s3(n,e))}function ihn(n,t){var e,i,r,c,a;return e=q1(a=n,"x"),function(n,t){L1(n,null==t||ex((vB(t),t))||isNaN((vB(t),t))?0:(vB(t),t))}(new lg(t).a,e),i=q1(a,"y"),function(n,t){N1(n,null==t||ex((vB(t),t))||isNaN((vB(t),t))?0:(vB(t),t))}(new bg(t).a,i),r=q1(a,qNn),function(n,t){$1(n,null==t||ex((vB(t),t))||isNaN((vB(t),t))?0:(vB(t),t))}(new wg(t).a,r),c=q1(a,HNn),function(n,t){A1(n,null==t||ex((vB(t),t))||isNaN((vB(t),t))?0:(vB(t),t))}(new dg(t).a,c),c}function rhn(n,t){Gdn(n,t),0!=(1&n.b)&&(n.a.a=null),0!=(2&n.b)&&(n.a.f=null),0!=(4&n.b)&&(n.a.g=null,n.a.i=null),0!=(16&n.b)&&(n.a.d=null,n.a.e=null),0!=(8&n.b)&&(n.a.b=null),0!=(32&n.b)&&(n.a.j=null,n.a.c=null)}function chn(n){var t,e,i,r,c;if(null==n)return aEn;for(c=new J3(tEn,"[","]"),i=0,r=(e=n).length;i0)for(a=n.c.d,r=KO(yN(new QS((u=n.d.d).a,u.b),a),1/(i+1)),c=new QS(a.a,a.b),e=new pb(n.a);e.a($z(c+1,t.c.length),Yx(t.c[c+1],19)).a-i&&++u,eD(r,($z(c+u,t.c.length),Yx(t.c[c+u],19))),a+=($z(c+u,t.c.length),Yx(t.c[c+u],19)).a-i,++e;e=0?n._g(e,!0,!0):tfn(n,r,!0),153),Yx(i,215).ol(t)}function Thn(n){var t,i;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),i=oG(e.Math.floor(e.Math.log(n)/.6931471805599453)),(!t||n!=e.Math.pow(2,i))&&++i,i):h4(D3(n))}function Mhn(n,t){var e,i,r;return o4(i=new rin(n),t),b5(i,(Ojn(),sQn),t),b5(i,(gjn(),g0n),(Ran(),oit)),b5(i,xZn,(qen(),G7n)),Al(i,(bon(),_zn)),ZG(e=new Ion,i),whn(e,(Ikn(),qit)),ZG(r=new Ion,i),whn(r,Eit),i}function Shn(n){switch(n.g){case 0:return new zm((l0(),G3n));case 1:return new bf;case 2:return new yf;default:throw hp(new Qm("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function Phn(n,t){var e,i,r,c;for(n.c[t.p]=!0,eD(n.a,t),c=new pb(t.j);c.a=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=By(F2(lH(hH(X_(n.a),new Mn),new Sn)));return a>0?a+n.n.d+n.n.a:0}function Rhn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=By(F2(lH(hH(X_(n.a),new En),new Tn)));else{for(t=0,r=0,c=(i=vin(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function Khn(n){var t,e;return(e=new Ay).a+="e_",null!=(t=function(n){return 0!=n.b.c.length&&Yx(TR(n.b,0),70).a?Yx(TR(n.b,0),70).a:IH(n)}(n))&&(e.a+=""+t),n.c&&n.d&&(yI((e.a+=" ",e),krn(n.c)),yI(mI((e.a+="[",e),n.c.i),"]"),yI((e.a+=pIn,e),krn(n.d)),yI(mI((e.a+="[",e),n.d.i),"]")),e.a}function _hn(n){switch(n.g){case 0:return new df;case 1:return new gf;case 2:return new wf;case 3:return new pf;default:throw hp(new Qm("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function Fhn(n,t,i,r,c){var a;switch(a=0,c.g){case 1:a=e.Math.max(0,t.b+n.b-(i.b+r));break;case 3:a=e.Math.max(0,-n.b-r);break;case 2:a=e.Math.max(0,-n.a-r);break;case 4:a=e.Math.max(0,t.a+n.a-(i.a+r))}return a}function Bhn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=fcn(n))&&(TT(),t.Cj()==KDn)?(n.b=-1,!0):(n.b=1,!1);default:return!1}}function Hhn(n,t){var e,i,r,c;if(kjn(n),0!=n.c||123!=n.a)throw hp(new wy(Kjn((GC(),Hxn))));if(c=112==t,i=n.d,(e=b$(n.i,125,i))<0)throw hp(new wy(Kjn((GC(),qxn))));return r=l$(n.i,i,e),n.d=e+1,bY(r,c,512==(512&n.e))}function qhn(n,t,e,i,r){var c,a,u,o;return iI(o=nL(n,Yx(r,56)))!==iI(r)?(u=Yx(n.g[e],72),_O(n,e,zan(n,0,c=VX(t,o))),gC(n.e)&&(Pan(a=Kq(n,9,c.ak(),r,o,i,!1),new yJ(n.e,9,n.c,u,c,i,!1)),vJ(a)),o):r}function Ghn(n,t){var e,i;try{return function(n,t){var e;return T$(!!(e=(vB(n),n).g)),vB(t),e(t)}(n.a,t)}catch(r){if(CO(r=j4(r),32)){try{if(i=ipn(t,nTn,Yjn),e=Ak(n.a),i>=0&&i=0?n._g(e,!0,!0):tfn(n,r,!0),153),Yx(i,215).ll(t);throw hp(new Qm(mNn+t.ne()+jNn))}function Uhn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(Lz(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)Lz(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function Xhn(n,t,e){var i,r,c,a;c=n.c,a=n.d,r=($5(x4(Gy(B7n,1),TEn,8,0,[c.i.n,c.n,c.a])).b+$5(x4(Gy(B7n,1),TEn,8,0,[a.i.n,a.n,a.a])).b)/2,i=c.j==(Ikn(),Eit)?new QS(t+c.i.c.c.a+e,r):new QS(t-e,r),A$(n.a,0,i)}function Whn(n){var t,e,i;for(t=null,e=W_(n0(x4(Gy(QKn,1),iEn,20,0,[(!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),(!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c)])));Vfn(e);)if(i=iun(Yx(kV(e),82)),t){if(t!=i)return!1}else t=i;return!0}function Vhn(n,t,e){var i;if(++n.j,t>=n.i)throw hp(new Hm(jxn+t+Exn+n.i));if(e>=n.i)throw hp(new Hm(Txn+e+Exn+n.i));return i=n.g[e],t!=e&&(t>16)>>16&16),e+=t=(n>>=t)-256>>16&8,e+=t=(n<<=t)-nMn>>16&4,(e+=t=(n<<=t)-MEn>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function Jhn(n){var t,e,i,r;for(UH(),Fqn=new ip,_qn=new rp,Kqn=new ip,!n.a&&(n.a=new m_(uct,n,10,11)),function(n){var t,e,i,r,c,a,u,o,s,f;for(t=new rp,a=new UO(n);a.e!=a.i.gc();){for(c=Yx(hen(a),33),e=new Qp,xB(_qn,c,e),f=new ut,i=Yx(kW(new SR(null,new nF(new $K(bA(fbn(c).a.Kc(),new h)))),iK(f,mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[(C6(),aBn)])))),83),i0(e,Yx(i.xc((TA(),!0)),14),new ot),r=Yx(kW(hH(Yx(i.xc(!1),15).Lc(),new st),mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[aBn]))),15).Kc();r.Ob();)(s=_un(Yx(r.Pb(),79)))&&((u=Yx(eI(Dq(t.f,s)),21))||(u=Awn(s),Ysn(t.f,s,u)),C2(e,u));for(i=Yx(kW(new SR(null,new nF(new $K(bA(lbn(c).a.Kc(),new h)))),iK(f,mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[aBn])))),83),i0(e,Yx(i.xc(!0),14),new ht),o=Yx(kW(hH(Yx(i.xc(!1),15).Lc(),new ft),mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[aBn]))),15).Kc();o.Ob();)(s=Fun(Yx(o.Pb(),79)))&&((u=Yx(eI(Dq(t.f,s)),21))||(u=Awn(s),Ysn(t.f,s,u)),C2(e,u))}}(t=n.a),r=new UO(t);r.e!=r.i.gc();)i=Yx(hen(r),33),-1==hJ(Fqn,i,0)&&(e=new ip,eD(Kqn,e),$tn(i,e));return Kqn}function Zhn(n,t){var i,r,c,a,u,o,s,h;for(h=ty(fL(Aun(t,(gjn(),W0n)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,o=1;o0?1:QI(isNaN(r),isNaN(0)))>=0^(o0(UAn),(e.Math.abs(o)<=UAn||0==o||isNaN(o)&&isNaN(0)?0:o<0?-1:o>0?1:QI(isNaN(o),isNaN(0)))>=0)?e.Math.max(o,r):(o0(UAn),(e.Math.abs(r)<=UAn||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:QI(isNaN(r),isNaN(0)))>0?e.Math.sqrt(o*o+r*r):-e.Math.sqrt(o*o+r*r))}(a=r.b,u=c.b))>=0?i:(o=fB(yN(new QS(u.c+u.b/2,u.d+u.a/2),new QS(a.c+a.b/2,a.d+a.a/2))),-(Ppn(a,u)-1)*o)}function tfn(n,t,e){var i,r,c;if(c=iyn((wsn(),wut),n.Tg(),t))return TT(),Yx(c,66).Oj()||(c=Bz(PJ(wut,c))),r=Yx((i=n.Yg(c))>=0?n._g(i,!0,!0):tfn(n,c,!0),153),Yx(r,215).hl(t,e);throw hp(new Qm(mNn+t.ne()+jNn))}function efn(n,t,e,i){var r,c,a,u,o;if(r=n.d[t])if(c=r.g,o=r.i,null!=i){for(u=0;u>5),15,1))[e]=1<1;t>>=1)0!=(1&t)&&(i=uZ(i,e)),e=1==e.d?uZ(e,e):new Mtn(fpn(e.a,e.d,VQ(Wot,MTn,25,e.d<<1,15,1)));return uZ(i,e)}(n,t)}function rfn(n){var t,e,i;for(WE(),this.b=szn,this.c=(t9(),tet),this.f=(XE(),czn),this.a=n,Yy(this,new It),qbn(this),i=new pb(n.b);i.a=null.jm()?(abn(n),ufn(n)):t.Ob()}function ofn(n,t,i){var r,c,a,u;if(!(u=i)&&(u=xD(new am,0)),run(u,rIn,1),$yn(n.c,t),1==(a=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;if(n.c=n.d,l=null==(b=hL(Aun(t,(gjn(),C0n))))||(vB(b),b),c=Yx(Aun(t,(Ojn(),bQn)),21).Hc((edn(),SVn)),e=!((r=Yx(Aun(t,g0n),98))==(Ran(),uit)||r==sit||r==oit),!l||!e&&c)f=new ay(x4(Gy(Dzn,1),bIn,37,0,[t]));else{for(h=new pb(t.a);h.at.a&&(i.Hc((dan(),ont))?n.c.a+=(e.a-t.a)/2:i.Hc(hnt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((dan(),lnt))?n.c.b+=(e.b-t.b)/2:i.Hc(fnt)&&(n.c.b+=e.b-t.b)),Yx(Aun(n,(Ojn(),bQn)),21).Hc((edn(),SVn))&&(e.a>t.a||e.b>t.b))for(u=new pb(n.a);u.a0?G7(e):O9(G7(e)),Aen(t,k0n,r)}function mfn(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&JC(a,new Ur),r=a.c.length/2|0,i=0;i=0;)i=e[c],a.rl(i.ak())&&fY(r,i);!Xkn(n,r)&&gC(n.e)&&Xp(n,t.$j()?Kq(n,6,t,(XH(),TFn),null,-1,!1):Kq(n,t.Kj()?2:1,t,null,null,-1,!1))}function jfn(){var n,t;for(jfn=O,kFn=VQ(EFn,TEn,91,32,0,1),jFn=VQ(EFn,TEn,91,32,0,1),n=1,t=0;t<=18;t++)kFn[t]=Utn(n),jFn[t]=Utn(GK(n,t)),n=e7(n,5);for(;tc)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function Tfn(n){var t,e,i,r,c,a;for(lz(),e=new bW,i=new pb(n.e.b);i.a1?n.e*=ty(n.a):n.f/=ty(n.a),function(n){var t,e;for(t=n.b.a.a.ec().Kc();t.Ob();)e=new nbn(Yx(t.Pb(),561),n.e,n.f),eD(n.g,e)}(n),gtn(n),function(n){var t,i,r,c,a,u,o,s,h,f;for(i=function(n){var t,i,r,c,a,u,o,s,h,f;for(i=n.o,t=n.p,u=Yjn,c=nTn,o=Yjn,a=nTn,h=0;h=0?n.Qg(null):n.eh().ih(n,-1-t,null,null),n.Rg(Yx(r,49),e),i&&i.Fi(),n.Lg()&&n.Mg()&&e>-1&&K3(n,new p_(n,9,e,c,r)),r):c}function Hfn(n){var t,e,i,r,c,a,u;for(c=0,r=n.f.e,e=0;e>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=r3(n)))return!1;e=i==r?-e:~e}return 0!=(e&t)}function Xfn(n,t){var e,i,r,c,a,u,o;if(c=t.e)for(e=Bfn(c),i=Yx(n.g,674),a=0;a>16)),15).Xc(c))>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?HTn:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?HTn:0,c=i?BTn:0,r=e>>t-44),rO(r&BTn,c&BTn,a&HTn)}function eln(n){var t,i,r,c,a,u;for(this.c=new ip,this.d=n,r=JTn,c=JTn,t=ZTn,i=ZTn,u=Ztn(n,0);u.b!=u.d.c;)a=Yx(IX(u),8),r=e.Math.min(r,a.a),c=e.Math.min(c,a.b),t=e.Math.max(t,a.a),i=e.Math.max(i,a.b);this.a=new mH(r,c,t-r,i-c)}function iln(n,t){var e,i,r,c;for(i=new pb(n.b);i.a0&&CO(t,42)&&(n.a.qj(),c=null==(o=(s=Yx(t,42)).cd())?0:W5(o),a=KL(n.a,c),e=n.a.d[a]))for(i=Yx(e.g,367),h=e.i,u=0;u=2)for(t=fL((i=c.Kc()).Pb());i.Ob();)a=t,t=fL(i.Pb()),r=e.Math.min(r,(vB(t),t-(vB(a),a)));return r}function gln(n,t){var e,i,r,c,a;VW(i=new ME,t,i.c.b,i.c);do{for(S$(0!=i.b),e=Yx(VZ(i,i.a.a),86),n.b[e.g]=1,c=Ztn(e.d,0);c.b!=c.d.c;)a=(r=Yx(IX(c),188)).c,1==n.b[a.g]?KD(n.a,r):2==n.b[a.g]?n.b[a.g]=1:VW(i,a,i.c.b,i.c)}while(0!=i.b)}function pln(n,t){var e,i,r;if(iI(t)===iI(MF(n)))return!0;if(!CO(t,15))return!1;if(i=Yx(t,15),(r=n.gc())!=i.gc())return!1;if(CO(i,54)){for(e=0;e0&&(r=e),a=new pb(n.f.e);a.a0&&c0):c<0&&-c0)}function Oln(n,t,e,i){var r,c,a,u,o,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new pb(n.c);s.a=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function Dln(n,t){var e,i,r,c,a,u;for(c=(1==t?ozn:uzn).a.ec().Kc();c.Ob();)for(r=Yx(c.Pb(),103),u=Yx(_V(n.f.c,r),21).Kc();u.Ob();)switch(a=Yx(u.Pb(),46),i=Yx(a.b,81),e=Yx(a.a,189).c,r.g){case 2:case 1:i.g.d+=e;break;case 4:case 3:i.g.c+=e}}function Rln(n,t){var e,i,r,c,a,u,o,s,h;for(s=-1,h=0,u=0,o=(a=n).length;u0&&++h;++s}return h}function Kln(n){var t;return(t=new SA(Nk(n.gm))).a+="@",yI(t,(W5(n)>>>0).toString(16)),n.kh()?(t.a+=" (eProxyURI: ",mI(t,n.qh()),n.$g()&&(t.a+=" eClass: ",mI(t,n.$g())),t.a+=")"):n.$g()&&(t.a+=" (eClass: ",mI(t,n.$g()),t.a+=")"),t.a}function _ln(n){var t,e,i;if(n.e)throw hp(new Ym((sL(OBn),UMn+OBn.k+XMn)));for(n.d==(t9(),tet)&&ekn(n,Ztt),e=new pb(n.a.a);e.a=0)return r;for(c=1,a=new pb(t.j);a.a0&&t.ue(($z(r-1,n.c.length),Yx(n.c[r-1],10)),c)>0;)QW(n,r,($z(r-1,n.c.length),Yx(n.c[r-1],10))),--r;$z(r,n.c.length),n.c[r]=c}e.a=new rp,e.b=new rp}function zln(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(Ikn(),Tit)||t==Eit?(qZ(Yx(T5(n),15),(Frn(),Ret)),qZ(Yx(T5(n),15),Ket)):(qZ(Yx(T5(n),15),(Frn(),Ket)),qZ(Yx(T5(n),15),Ret));else for(i=new VB(n);i.a!=i.b;)qZ(Yx(w8(i),15),e)}function Uln(n,t){var e,i,r,c,a,u;for(a=new JU(i=Jx(new $g(n)),i.c.length),u=new JU(r=Jx(new $g(t)),r.c.length),c=null;a.b>0&&u.b>0&&(S$(a.b>0),e=Yx(a.a.Xb(a.c=--a.b),33),S$(u.b>0),e==Yx(u.a.Xb(u.c=--u.b),33));)c=e;return c}function Xln(n,t){var i,r,c,a;return c=n.a*kMn+1502*n.b,a=n.b*kMn+11,c+=i=e.Math.floor(a*jMn),a-=i*EMn,c%=EMn,n.a=c,n.b=a,t<=24?e.Math.floor(n.a*GFn[t]):((r=n.a*(1<=2147483648&&(r-=oMn),r)}function Wln(n,t,e){var i,r,c,a;Wz(n,t)>Wz(n,e)?(i=i7(e,(Ikn(),Eit)),n.d=i.dc()?0:tR(Yx(i.Xb(0),11)),a=i7(t,qit),n.b=a.dc()?0:tR(Yx(a.Xb(0),11))):(r=i7(e,(Ikn(),qit)),n.d=r.dc()?0:tR(Yx(r.Xb(0),11)),c=i7(t,Eit),n.b=c.dc()?0:tR(Yx(c.Xb(0),11)))}function Vln(n){var t,e,i,r,c,a,u;if(n&&(t=n.Hh(hRn))&&null!=(a=lL(ynn((!t.b&&(t.b=new z$((xjn(),Dat),out,t)),t.b),"conversionDelegates")))){for(u=new ip,r=0,c=(i=Ogn(a,"\\w+")).length;r>1,n.k=i-1>>1}(this,this.d,this.c),function(n){var t,e,i,r,c,a,u;for(e=_C(n.e),c=KO(N$(dO(KC(n.e)),n.d*n.a,n.c*n.b),-.5),t=e.a-c.a,r=e.b-c.b,u=0;u0&&tyn(this,c)}function tbn(n,t,e,i,r,c){var a,u,o;if(!r[t.b]){for(r[t.b]=!0,!(a=i)&&(a=new XV),eD(a.e,t),o=c[t.b].Kc();o.Ob();)(u=Yx(o.Pb(),282)).d!=e&&u.c!=e&&(u.c!=t&&tbn(n,u.c,t,a,r,c),u.d!=t&&tbn(n,u.d,t,a,r,c),eD(a.c,u),S4(a.d,u.b));return a}return null}function ebn(n){var t,e,i;for(t=0,e=new pb(n.e);e.a=2}function ibn(n){var t,e;try{return null==n?aEn:I7(n)}catch(i){if(CO(i=j4(i),102))return t=i,e=Nk(V5(n))+"@"+(oE(),(Nen(n)>>>0).toString(16)),Ltn(O4(),(_E(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+Nk(t.gm)+">";throw hp(i)}}function rbn(n){switch(n.g){case 0:return new af;case 1:return new nf;case 2:return new cT;case 3:return new Cc;case 4:return new lN;case 5:return new uf;default:throw hp(new Qm("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function cbn(n,t,e){var i,r,c;for(c=new pb(n.t);c.a0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&KD(t,i.b));for(r=new pb(n.i);r.a0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&KD(e,i.a))}function abn(n){var t,e,i;if(null==n.g&&(n.d=n.si(n.f),fY(n,n.d),n.c))return n.f;if(i=(t=Yx(n.g[n.i-1],47)).Pb(),n.e=t,(e=n.si(i)).Ob())n.d=e,fY(n,e);else for(n.d=null;!t.Ob()&&(DF(n.g,--n.i,null),0!=n.i);)t=Yx(n.g[n.i-1],47);return i}function ubn(n,t,i,r){var c,a,u;for(Al(c=new rin(n),(bon(),Fzn)),b5(c,(Ojn(),CQn),t),b5(c,BQn,r),b5(c,(gjn(),g0n),(Ran(),oit)),b5(c,TQn,t.c),b5(c,MQn,t.d),Bwn(t,c),u=e.Math.floor(i/2),a=new pb(c.j);a.a=0?n._g(i,!0,!0):tfn(n,c,!0),153),Yx(r,215).ml(t,e)}function vbn(n,t,e){run(e,"Eades radial",1),e.n&&t&&nU(e,RU(t),(P6(),jrt)),n.d=Yx(jln(t,(eL(),s6n)),33),n.c=ty(fL(jln(t,(_rn(),Q6n)))),n.e=Ven(Yx(jln(t,Y6n),293)),n.a=function(n){switch(n.g){case 0:return new Ga;case 1:return new za;default:throw hp(new Qm(y$n+(null!=n.f?n.f:""+n.g)))}}(Yx(jln(t,Z6n),426)),n.b=function(n){switch(n.g){case 1:return new _a;case 2:return new Fa;case 3:return new Ka;case 0:return null;default:throw hp(new Qm(y$n+(null!=n.f?n.f:""+n.g)))}}(Yx(jln(t,U6n),340)),function(n){var t,e,i,r,c;if(i=0,r=wPn,n.b)for(t=0;t<360;t++)e=.017453292519943295*t,qgn(n,n.d,0,0,w$n,e),(c=n.b.ig(n.d))0),c.a.Xb(c.c=--c.b),ZL(c,r),S$(c.b0);e++);if(e>0&&e0);t++);return t>0&&e>16!=6&&t){if(ccn(n,t))throw hp(new Qm(CNn+Mfn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Yrn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=men(t,n,6,i)),(i=$L(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,6,t,t))}function Mbn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(ccn(n,t))throw hp(new Qm(CNn+ogn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Zrn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=men(t,n,9,i)),(i=LL(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,9,t,t))}function Sbn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(ccn(n,t))throw hp(new Qm(CNn+bmn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?ucn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=men(t,n,12,i)),(i=AL(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,3,t,t))}function Pbn(n){var t,e,i,r,c;if(i=fcn(n),null==(c=n.j)&&i)return n.$j()?null:i.zj();if(CO(i,148)){if((e=i.Aj())&&(r=e.Nh())!=n.i){if((t=Yx(i,148)).Ej())try{n.g=r.Kh(t,c)}catch(t){if(!CO(t=j4(t),78))throw hp(t);n.g=null}n.i=r}return n.g}return null}function Ibn(n){var t;return eD(t=new ip,new ZT(new QS(n.c,n.d),new QS(n.c+n.b,n.d))),eD(t,new ZT(new QS(n.c,n.d),new QS(n.c,n.d+n.a))),eD(t,new ZT(new QS(n.c+n.b,n.d+n.a),new QS(n.c+n.b,n.d))),eD(t,new ZT(new QS(n.c+n.b,n.d+n.a),new QS(n.c,n.d+n.a))),t}function Cbn(n,t,e,i){var r,c,a;if(a=Hcn(t,e),i.c[i.c.length]=t,-1==n.j[a.p]||2==n.j[a.p]||n.a[t.p])return i;for(n.j[a.p]=-1,c=new $K(bA(a7(a).a.Kc(),new h));Vfn(c);)if(!ZW(r=Yx(kV(c),17))&&(ZW(r)||r.c.i.c!=r.d.i.c)&&r!=t)return Cbn(n,r,a,i);return i}function Obn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=Yx(r.Pb(),79),!Yx(BF(n.b,i),266)&&(IG(Kun(i))==IG(Bun(i))?Wwn(n,i,e):Kun(i)==IG(Bun(i))?null==BF(n.c,i)&&null!=BF(n.b,Bun(i))&&Gyn(n,i,e,!1):null==BF(n.d,i)&&null!=BF(n.b,Kun(i))&&Gyn(n,i,e,!0))}function Abn(n,t){var e,i,r,c,a,u,o;for(r=n.Kc();r.Ob();)for(i=Yx(r.Pb(),10),ZG(u=new Ion,i),whn(u,(Ikn(),Eit)),b5(u,(Ojn(),DQn),(TA(),!0)),a=t.Kc();a.Ob();)c=Yx(a.Pb(),10),ZG(o=new Ion,c),whn(o,qit),b5(o,DQn,!0),b5(e=new jq,DQn,!0),YG(e,u),QG(e,o)}function $bn(n,t,e,i){var r,c,a,u;r=Bnn(n,t,e),c=Bnn(n,e,t),a=Yx(BF(n.c,t),112),u=Yx(BF(n.c,e),112),r0&&w.a<=0){o.c=VQ(UKn,iEn,1,0,5,1),o.c[o.c.length]=w;break}(b=w.i-w.d)>=u&&(b>u&&(o.c=VQ(UKn,iEn,1,0,5,1),u=b),o.c[o.c.length]=w)}0!=o.c.length&&(a=Yx(TR(o,Uen(r,o.c.length)),112),fG(m.a,a),a.g=h++,evn(a,t,e,i),o.c=VQ(UKn,iEn,1,0,5,1))}for(g=n.c.length+1,l=new pb(n);l.ai.b.g&&(c.c[c.c.length]=i);return c}function xbn(){xbn=O,Q8n=new FS("CANDIDATE_POSITION_LAST_PLACED_RIGHT",0),V8n=new FS("CANDIDATE_POSITION_LAST_PLACED_BELOW",1),J8n=new FS("CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT",2),Y8n=new FS("CANDIDATE_POSITION_WHOLE_DRAWING_BELOW",3),Z8n=new FS("WHOLE_DRAWING",4)}function Dbn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=11&&t){if(ccn(n,t))throw hp(new Qm(CNn+ugn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?ocn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=men(t,n,10,i)),(i=vN(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,11,t,t))}function Rbn(n,t,e){return udn(),(!s3(n,t)||!s3(n,e))&&(nkn(new QS(n.c,n.d),new QS(n.c+n.b,n.d),t,e)||nkn(new QS(n.c+n.b,n.d),new QS(n.c+n.b,n.d+n.a),t,e)||nkn(new QS(n.c+n.b,n.d+n.a),new QS(n.c,n.d+n.a),t,e)||nkn(new QS(n.c,n.d+n.a),new QS(n.c,n.d),t,e))}function Kbn(n,t){var e,i,r,c;if(!n.dc())for(e=0,i=n.gc();e>16!=7&&t){if(ccn(n,t))throw hp(new Qm(CNn+Qon(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Jrn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Yx(t,49).gh(n,1,Yrt,i)),(i=kK(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,7,t,t))}function Wbn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(ccn(n,t))throw hp(new Qm(CNn+o9(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?tcn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Yx(t,49).gh(n,0,ect,i)),(i=jK(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,3,t,t))}function Vbn(n,t){var e,i,r,c,a,u,o,s,h;return jfn(),t.d>n.d&&(u=n,n=t,t=u),t.d<63?function(n,t){var e,i,r,c,a,u,o,s,h;return c=(e=n.d)+(i=t.d),a=n.e!=t.e?-1:1,2==c?(h=WR(o=e7(Gz(n.a[0],uMn),Gz(t.a[0],uMn))),0==(s=WR(UK(o,32)))?new wQ(a,h):new C_(a,2,x4(Gy(Wot,1),MTn,25,15,[h,s]))):(Y8(n.a,e,t.a,i,r=VQ(Wot,MTn,25,c,15,1)),SU(u=new C_(a,c,r)),u)}(n,t):(s=yV(n,a=(-2&n.d)<<4),h=yV(t,a),i=Evn(n,mV(s,a)),r=Evn(t,mV(h,a)),o=Vbn(s,h),e=Vbn(i,r),c=mV(c=Smn(Smn(c=Vbn(Evn(s,i),Evn(r,h)),o),e),a),Smn(Smn(o=mV(o,a<<1),c),e))}function Qbn(n,t,e){var i,r,c,a,u;for(a=V8(n,e),u=VQ(Gzn,kIn,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)ny(hL(Aun(r=Yx(c.Pb(),11),(Ojn(),gQn))))&&(u[i++]=Yx(Aun(r,RQn),10));if(i=0;r+=e?1:-1)c|=t.c.Sf(u,r,e,i&&!ny(hL(Aun(t.j,(Ojn(),lQn))))&&!ny(hL(Aun(t.j,(Ojn(),qQn))))),c|=t.q._f(u,r,e),c|=zdn(n,u[r],e,i);return __(n.c,t),c}function nwn(n,t,e){var i,r,c,a,u,o,s,h;for(s=0,h=(o=tX(n.j)).length;s1&&(n.a=!0),hK(Yx(e.b,65),mN(dO(Yx(t.b,65).c),KO(yN(dO(Yx(e.b,65).a),Yx(t.b,65).a),r))),mz(n,t),iwn(n,e)}function rwn(n){var t,e,i,r,c,a;for(r=new pb(n.a.a);r.a0&&c>0?t++:i>0?e++:c>0?r++:e++}XH(),JC(n.j,new bi)}function awn(n,t){var e,i,r,c,a,u,o,s,h;for(u=t.j,a=t.g,o=Yx(TR(u,u.c.length-1),113),$z(0,u.c.length),s=srn(n,a,o,h=Yx(u.c[0],113)),c=1;cs&&(o=e,h=r,s=i);t.a=h,t.c=o}function uwn(n){if(!n.a.d||!n.a.e)throw hp(new Ym((sL(eHn),eHn.k+" must have a source and target "+(sL(iHn),iHn.k+" specified."))));if(n.a.d==n.a.e)throw hp(new Ym("Network simplex does not support self-loops: "+n.a+" "+n.a.d+" "+n.a.e));return WA(n.a.d.g,n.a),WA(n.a.e.b,n.a),n.a}function own(n,t,e){var i,r,c,a,u,o;if(i=0,0!=t.b&&0!=e.b){c=Ztn(t,0),a=Ztn(e,0),u=ty(fL(IX(c))),o=ty(fL(IX(a))),r=!0;do{if(u>o-n.b&&uo-n.a&&ut.a&&(i.Hc((dan(),ont))?n.c.a+=(e.a-t.a)/2:i.Hc(hnt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((dan(),lnt))?n.c.b+=(e.b-t.b)/2:i.Hc(fnt)&&(n.c.b+=e.b-t.b)),Yx(Aun(n,(Ojn(),bQn)),21).Hc((edn(),SVn))&&(e.a>t.a||e.b>t.b))for(a=new pb(n.a);a.a0&&++l;++f}return l}function dwn(n,t){var e,i,r,c;return TT(),t?t==(ayn(),Zut)||(t==xut||t==Lut||t==Nut)&&n!=$ut?new ykn(n,t):((e=(i=Yx(t,677)).pk())||(nH(PJ((wsn(),wut),t)),e=i.pk()),!e.i&&(e.i=new rp),!(r=Yx(eI(Dq((c=e.i).f,n)),1942))&&xB(c,n,r=new ykn(n,t)),r):kut}function gwn(n,t){var e,i,r,c,a,u,o,s;for(u=Yx(Aun(n,(Ojn(),CQn)),11),o=$5(x4(Gy(B7n,1),TEn,8,0,[u.i.n,u.n,u.a])).a,s=n.i.n.b,r=0,c=(i=CU(n.e)).length;r0&&(c+=(a=Yx(TR(this.b,0),167)).o,r+=a.p),c*=2,r*=2,t>1?c=oG(e.Math.ceil(c*t)):r=oG(e.Math.ceil(r/t)),this.a=new hnn(c,r)}function Mwn(n,t,i,r,c,a){var u,o,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=Yx(BF(n.f,t.A),57)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,i.q&&i.o?(s=(b=Yx(BF(n.f,i.C),57)).d.c,++f):s=i.a.c,w=d+(o=(s-d)/e.Math.max(2,f-h)),l=h;l=0;a+=r?1:-1){for(u=t[a],o=i==(Ikn(),Eit)?r?i7(u,i):I3(i7(u,i)):r?I3(i7(u,i)):i7(u,i),c&&(n.c[u.p]=o.gc()),f=o.Kc();f.Ob();)h=Yx(f.Pb(),11),n.d[h.p]=s++;S4(e,o)}}function Pwn(n,t,e){var i,r,c,a,u,o,s,h;for(c=ty(fL(n.b.Kc().Pb())),s=ty(fL(function(n){var t;if(n){if((t=n).dc())throw hp(new Kp);return t.Xb(t.gc()-1)}return Iz(n.Kc())}(t.b))),i=KO(dO(n.a),s-e),r=KO(dO(t.a),e-c),KO(h=mN(i,r),1/(s-c)),this.a=h,this.b=new ip,u=!0,(a=n.b.Kc()).Pb();a.Ob();)o=ty(fL(a.Pb())),u&&o-e>YAn&&(this.b.Fc(e),u=!1),this.b.Fc(o);u&&this.b.Fc(e)}function Iwn(n){var t,i,r,c;if(function(n,t){var i,r,c,a,u,o,s;for(c=VQ(Wot,MTn,25,n.e.a.c.length,15,1),u=new pb(n.e.a);u.a0){for(oy(n.c);Yfn(n,Yx(Hz(new pb(n.e.a)),121))>5,t&=31,i>=n.d)return n.e<0?(bdn(),lFn):(bdn(),pFn);if(c=n.d-i,function(n,t,e,i,r){var c,a,u;for(c=!0,a=0;a>>r|e[a+i+1]<>>r,++a}}(r=VQ(Wot,MTn,25,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e0&&n.a[e]<<32-t!=0){for(e=0;e=0)&&(!(e=iyn((wsn(),wut),r,t))||((i=e.Zj())>1||-1==i)&&3!=TB(PJ(wut,e))))}function Nwn(n,t,e,i){var r,c,a,u,o;return u=iun(Yx(c1((!t.b&&(t.b=new AN(Zrt,t,4,7)),t.b),0),82)),o=iun(Yx(c1((!t.c&&(t.c=new AN(Zrt,t,5,8)),t.c),0),82)),IG(u)==IG(o)||XZ(o,u)?null:(a=EG(t))==e?i:(c=Yx(BF(n.a,a),10))&&(r=c.e)?r:null}function xwn(n,t,e){var i,r,c,a,u;if((c=n[function(n,t){return n?t-1:0}(e,n.length)])[0].k==(bon(),_zn))for(r=Zy(e,c.length),u=t.j,i=0;i>24}(n));break;case 2:n.g=k4(function(n){if(2!=n.p)throw hp(new Lp);return WR(n.f)&fTn}(n));break;case 3:n.g=function(n){if(3!=n.p)throw hp(new Lp);return n.e}(n);break;case 4:n.g=new ib(function(n){if(4!=n.p)throw hp(new Lp);return n.e}(n));break;case 6:n.g=ytn(function(n){if(6!=n.p)throw hp(new Lp);return n.f}(n));break;case 5:n.g=d9(function(n){if(5!=n.p)throw hp(new Lp);return WR(n.f)}(n));break;case 7:n.g=g9(function(n){if(7!=n.p)throw hp(new Lp);return WR(n.f)<<16>>16}(n))}return n.g}function Kwn(n){if(null==n.n)switch(n.p){case 0:n.n=function(n){if(0!=n.p)throw hp(new Lp);return hI(n.k,0)}(n)?(TA(),L_n):(TA(),$_n);break;case 1:n.n=iZ(function(n){if(1!=n.p)throw hp(new Lp);return WR(n.k)<<24>>24}(n));break;case 2:n.n=k4(function(n){if(2!=n.p)throw hp(new Lp);return WR(n.k)&fTn}(n));break;case 3:n.n=function(n){if(3!=n.p)throw hp(new Lp);return n.j}(n);break;case 4:n.n=new ib(function(n){if(4!=n.p)throw hp(new Lp);return n.j}(n));break;case 6:n.n=ytn(function(n){if(6!=n.p)throw hp(new Lp);return n.k}(n));break;case 5:n.n=d9(function(n){if(5!=n.p)throw hp(new Lp);return WR(n.k)}(n));break;case 7:n.n=g9(function(n){if(7!=n.p)throw hp(new Lp);return WR(n.k)<<16>>16}(n))}return n.n}function _wn(n){var t,e,i,r,c,a;for(r=new pb(n.a.a);r.a0&&(i[0]+=n.d,u-=i[0]),i[2]>0&&(i[2]+=n.d,u-=i[2]),a=e.Math.max(0,u),i[1]=e.Math.max(i[1],u),SV(n,cHn,c.c+r.b+i[0]-(i[1]-u)/2,i),t==cHn&&(n.c.b=a,n.c.c=c.c+r.b+(a-u)/2)}function Gwn(){this.c=VQ(Jot,rMn,25,(Ikn(),x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit])).length,15,1),this.b=VQ(Jot,rMn,25,x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit]).length,15,1),this.a=VQ(Jot,rMn,25,x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit]).length,15,1),HT(this.c,JTn),HT(this.b,ZTn),HT(this.a,ZTn)}function zwn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=VQ(Wot,MTn,25,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=VQ(Wot,MTn,25,i+2,15,1),smn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||xln(n)}}function Uwn(n,t,e){var i,r,c,a,u,o;if(!MX(t)){for(run(o=J2(e,(CO(t,14)?Yx(t,14).gc():FX(t.Kc()))/n.a|0),a$n,1),u=new Ca,a=0,c=t.Kc();c.Ob();)i=Yx(c.Pb(),86),u=n0(x4(Gy(QKn,1),iEn,20,0,[u,new Dd(i)])),a1;)tdn(r,r.i-1);return i}function Jwn(n,t){var e,i,r,c,a,u;for(e=new ep,r=new pb(n.b);r.an.d[a.p]&&(e+=zW(n.b,c),OX(n.a,d9(c)));for(;!ry(n.a);)eZ(n.b,Yx($_(n.a),19).a)}return e}function ndn(n,t,e){var i,r,c,a;for(c=(!t.a&&(t.a=new m_(uct,t,10,11)),t.a).i,r=new UO((!t.a&&(t.a=new m_(uct,t,10,11)),t.a));r.e!=r.i.gc();)0==(!(i=Yx(hen(r),33)).a&&(i.a=new m_(uct,i,10,11)),i.a).i||(c+=ndn(n,i,!1));if(e)for(a=IG(t);a;)c+=(!a.a&&(a.a=new m_(uct,a,10,11)),a.a).i,a=IG(a);return c}function tdn(n,t){var e,i,r,c;return n.ej()?(i=null,r=n.fj(),n.ij()&&(i=n.kj(n.pi(t),null)),e=n.Zi(4,c=Orn(n,t),null,t,r),n.bj()&&null!=c?(i=n.dj(c,i))?(i.Ei(e),i.Fi()):n.$i(e):i?(i.Ei(e),i.Fi()):n.$i(e),c):(c=Orn(n,t),n.bj()&&null!=c&&(i=n.dj(c,null))&&i.Fi(),c)}function edn(){edn=O,TVn=new YM("COMMENTS",0),SVn=new YM("EXTERNAL_PORTS",1),PVn=new YM("HYPEREDGES",2),IVn=new YM("HYPERNODES",3),CVn=new YM("NON_FREE_PORTS",4),OVn=new YM("NORTH_SOUTH_PORTS",5),$Vn=new YM(cCn,6),EVn=new YM("CENTER_LABELS",7),MVn=new YM("END_LABELS",8),AVn=new YM("PARTITIONS",9)}function idn(n){var t,e,i,r,c;for(r=new ip,t=new kR((!n.a&&(n.a=new m_(uct,n,10,11)),n.a)),i=new $K(bA(lbn(n).a.Kc(),new h));Vfn(i);)CO(c1((!(e=Yx(kV(i),79)).b&&(e.b=new AN(Zrt,e,4,7)),e.b),0),186)||(c=iun(Yx(c1((!e.c&&(e.c=new AN(Zrt,e,5,8)),e.c),0),82)),t.a._b(c)||(r.c[r.c.length]=c));return r}function rdn(n){var t,e,i,r,c;for(r=new Qp,t=new kR((!n.a&&(n.a=new m_(uct,n,10,11)),n.a)),i=new $K(bA(lbn(n).a.Kc(),new h));Vfn(i);)CO(c1((!(e=Yx(kV(i),79)).b&&(e.b=new AN(Zrt,e,4,7)),e.b),0),186)||(c=iun(Yx(c1((!e.c&&(e.c=new AN(Zrt,e,5,8)),e.c),0),82)),t.a._b(c)||r.a.zc(c,r));return r}function cdn(n,t){var i,r,c;IG(n)&&(c=Yx(Aun(t,(gjn(),n0n)),174),iI(jln(n,g0n))===iI((Ran(),lit))&&Aen(n,g0n,fit),dT(),r=hkn(new Xm(IG(n)),new e$(IG(n)?new Xm(IG(n)):null,n),!1,!0),n2(c,(Ann(),Yit)),(i=Yx(Aun(t,e0n),8)).a=e.Math.max(r.a,i.a),i.b=e.Math.max(r.b,i.b))}function adn(){adn=O,tWn=new kH(NSn,0,(Ikn(),Tit),Tit),rWn=new kH(DSn,1,Bit,Bit),nWn=new kH(xSn,2,Eit,Eit),uWn=new kH(RSn,3,qit,qit),iWn=new kH("NORTH_WEST_CORNER",4,qit,Tit),eWn=new kH("NORTH_EAST_CORNER",5,Tit,Eit),aWn=new kH("SOUTH_WEST_CORNER",6,Bit,qit),cWn=new kH("SOUTH_EAST_CORNER",7,Eit,Bit)}function udn(){udn=O,_7n=x4(Gy(Qot,1),tMn,25,14,[1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368e3,{l:3506176,m:794077,h:1},{l:884736,m:916411,h:20},{l:3342336,m:3912489,h:363},{l:589824,m:3034138,h:6914},{l:3407872,m:1962506,h:138294}]),e.Math.pow(2,-65)}function odn(n,t){var e,i,r,c,a;if(0==n.c.length)return new mP(d9(0),d9(0));for(e=($z(0,n.c.length),Yx(n.c[0],11)).j,a=0,c=t.g,i=t.g+1;a=h&&(s=r);s&&(f=e.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function hdn(n,t){var e;switch(e=null,t.g){case 1:n.e.Xe((Cjn(),gtt))&&(e=Yx(n.e.We(gtt),249));break;case 3:n.e.Xe((Cjn(),ptt))&&(e=Yx(n.e.We(ptt),249));break;case 2:n.e.Xe((Cjn(),dtt))&&(e=Yx(n.e.We(dtt),249));break;case 4:n.e.Xe((Cjn(),vtt))&&(e=Yx(n.e.We(vtt),249))}return!e&&(e=Yx(n.e.We((Cjn(),btt)),249)),e}function fdn(n,t,e){var i,r,c,a,u,o;for(t.p=1,r=t.c,o=inn(t,(h0(),i3n)).Kc();o.Ob();)for(i=new pb(Yx(o.Pb(),11).g);i.a$$n?JC(s,n.b):r<=$$n&&r>L$n?JC(s,n.d):r<=L$n&&r>N$n?JC(s,n.c):r<=N$n&&JC(s,n.a),a=ldn(n,s,a);return c}function bdn(){var n;for(bdn=O,bFn=new wQ(1,1),dFn=new wQ(1,10),pFn=new wQ(0,0),lFn=new wQ(-1,1),wFn=x4(Gy(EFn,1),TEn,91,0,[pFn,bFn,new wQ(1,2),new wQ(1,3),new wQ(1,4),new wQ(1,5),new wQ(1,6),new wQ(1,7),new wQ(1,8),new wQ(1,9),dFn]),gFn=VQ(EFn,TEn,91,32,0,1),n=0;n1&&(i=new QS(r,e.b),KD(t.a,i)),r0(t.a,x4(Gy(B7n,1),TEn,8,0,[f,h]))}function ydn(n){uT(n,new tun(rk(nk(ik(ek(new du,nNn),"ELK Randomizer"),'Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of "real" layout algorithms.'),new Qu))),DU(n,nNn,fPn,Wit),DU(n,nNn,LPn,15),DU(n,nNn,xPn,d9(0)),DU(n,nNn,hPn,OPn)}function kdn(){var n,t,e,i,r,c;for(kdn=O,fot=VQ(Yot,LNn,25,255,15,1),lot=VQ(Xot,sTn,25,16,15,1),t=0;t<255;t++)fot[t]=-1;for(e=57;e>=48;e--)fot[e]=e-48<<24>>24;for(i=70;i>=65;i--)fot[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)fot[r]=r-97+10<<24>>24;for(c=0;c<10;c++)lot[c]=48+c&fTn;for(n=10;n<=15;n++)lot[n]=65+n-10&fTn}function jdn(n,t,e){var i,r,c,a,u,o,s,h;return u=t.i-n.g/2,o=e.i-n.g/2,s=t.j-n.g/2,h=e.j-n.g/2,c=t.g+n.g/2,a=e.g+n.g/2,i=t.f+n.g/2,r=e.f+n.g/2,u=0;--i)for(t=e[i],r=0;r>19!=0)return"-"+Mdn(h5(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Jmn(e,gV(UTn),!0),t=""+rj(P_n),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function Sdn(n,t,i,r){var c,a,u,o;if(FX((Ax(),new $K(bA(a7(t).a.Kc(),new h))))>=n.a)return-1;if(!Ban(t,i))return-1;if(MX(Yx(r.Kb(t),20)))return 1;for(c=0,u=Yx(r.Kb(t),20).Kc();u.Ob();){if(-1==(o=Sdn(n,(a=Yx(u.Pb(),17)).c.i==t?a.d.i:a.c.i,i,r)))return-1;if((c=e.Math.max(c,o))>n.c-1)return-1}return c+1}function Pdn(n,t){var e,i,r,c,a,u;if(iI(t)===iI(n))return!0;if(!CO(t,15))return!1;if(i=Yx(t,15),u=n.gc(),i.gc()!=u)return!1;if(a=i.Kc(),n.ni()){for(e=0;e0)if(n.qj(),null!=t){for(c=0;c0&&(n.a=u+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=Ayn(new gF(1,r),t,b,w,t.f.b+u-t.c.b))>0&&(t.f.b+=u+(l-1)*r)}(n,t,r),function(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(m=new ip,f=new pb(n.b);f.a>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw hp(new Iy("Invalid hexadecimal"))}}function Adn(n,t,e){var i,r,c,a;for(run(e,"Processor order nodes",2),n.a=ty(fL(Aun(t,(cln(),V5n)))),r=new ME,a=Ztn(t.b,0);a.b!=a.d.c;)ny(hL(Aun(c=Yx(IX(a),86),(ryn(),C5n))))&&VW(r,c,r.c.b,r.c);S$(0!=r.b),Omn(n,i=Yx(r.a.a.c,86)),!e.b&&q0(e,1),agn(n,i,0-ty(fL(Aun(i,(ryn(),k5n))))/2,0),!e.b&&q0(e,1),Ron(e)}function $dn(){$dn=O,YBn=new aM("SPIRAL",0),UBn=new aM("LINE_BY_LINE",1),XBn=new aM("MANHATTAN",2),zBn=new aM("JITTER",3),VBn=new aM("QUADRANTS_LINE_BY_LINE",4),QBn=new aM("QUADRANTS_MANHATTAN",5),WBn=new aM("QUADRANTS_JITTER",6),GBn=new aM("COMBINE_LINE_BY_LINE_MANHATTAN",7),qBn=new aM("COMBINE_JITTER_MANHATTAN",8)}function Ldn(n,t,e,i){var r,c,a,u,o,s;for(o=qcn(n,e),s=qcn(t,e),r=!1;o&&s&&(i||Ern(o,s,e));)a=qcn(o,e),u=qcn(s,e),pJ(t),pJ(n),c=o.c,lyn(o,!1),lyn(s,!1),e?(Hrn(t,s.p,c),t.p=s.p,Hrn(n,o.p+1,c),n.p=o.p):(Hrn(n,o.p,c),n.p=o.p,Hrn(t,s.p+1,c),t.p=s.p),JG(o,null),JG(s,null),o=a,s=u,r=!0;return r}function Ndn(n,t,e,i){var r,c,a,u,o;for(r=!1,c=!1,u=new pb(i.j);u.a=t.length)throw hp(new Hm("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new rx(i),h2(this.e,this.c,(Ikn(),qit)),this.i=new rx(i),h2(this.i,this.c,Eit),this.f=new zR(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(bon(),_zn),this.a&&function(n,t,e){var i,r,c,a,u,o,s;u=(c=n.d.p).e,o=c.r,n.g=new rx(o),i=(a=n.d.o.c.p)>0?u[a-1]:VQ(Gzn,kIn,10,0,0,1),r=u[a],s=ar.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=Yx(BF(n.f,a.d.i),57),t.bc.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(u=new $K(bA(u7(b).a.Kc(),new h));Vfn(u);)0!=(a=Yx(kV(u),17)).a.b&&(t=Yx(p$(a.a),8),a.d.j==(Ikn(),Tit)&&((g=new _vn(t,new QS(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,d.c[d.c.length]=g),a.d.j==Bit&&((g=new _vn(t,new QS(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,d.c[d.c.length]=g))}return d}(n);break;case 3:r=new ip,SE(hH(fH(WJ(WJ(new SR(null,new Nz(n.d.b,16)),new Or),new Ar),new $r),new pr),new Yw(r)),i=r;break;default:throw hp(new Ym("Compaction not supported for "+t+" edges."))}(function(n,t){var i,r,c,a,u,o,s;if(0!=t.c.length){for(XH(),JR(t.c,t.c.length,null),r=Yx(Hz(c=new pb(t)),145);c.a0&&t0?c.a?e>(u=c.b.rf().a)&&(r=(e-u)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:c_(n.u)&&((i=oun(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.rf().a&&(c.d.c=i.c+i.b-c.b.rf().a))}(n,t),c=null,s=null,o){for(s=c=Yx((a=u.Kc()).Pb(),111);a.Ob();)s=Yx(a.Pb(),111);c.d.b=0,s.d.c=0,f&&!c.a&&(c.d.c=0)}l&&(function(n){var t,i,r,c,a;for(t=0,i=0,a=n.Kc();a.Ob();)r=Yx(a.Pb(),111),t=e.Math.max(t,r.d.b),i=e.Math.max(i,r.d.c);for(c=n.Kc();c.Ob();)(r=Yx(c.Pb(),111)).d.b=t,r.d.c=i}(u),o&&(c.d.b=0,s.d.c=0))}function Wdn(n,t){var i,r,c,a,u,o,s,h,f,l;if(u=Yx(Yx(_V(n.r,t),21),84),o=n.u.Hc((Chn(),mit)),i=n.u.Hc(git),r=n.u.Hc(dit),s=n.u.Hc(yit),l=n.B.Hc((Vgn(),frt)),h=!i&&!r&&(s||2==u.gc()),function(n,t){var i,r,c,a,u,o,s;for(o=Yx(Yx(_V(n.r,t),21),84).Kc();o.Ob();)(r=(u=Yx(o.Pb(),111)).c?XD(u.c):0)>0?u.a?r>(s=u.b.rf().b)&&(n.v||1==u.c.d.c.length?(a=(r-s)/2,u.d.d=a,u.d.a=a):(i=(Yx(TR(u.c.d,0),181).rf().b-s)/2,u.d.d=e.Math.max(0,i),u.d.a=r-i-s)):u.d.a=n.t+r:c_(n.u)&&((c=oun(u.b)).d<0&&(u.d.d=-c.d),c.d+c.a>u.b.rf().b&&(u.d.a=c.d+c.a-u.b.rf().b))}(n,t),f=null,c=null,o){for(c=f=Yx((a=u.Kc()).Pb(),111);a.Ob();)c=Yx(a.Pb(),111);f.d.d=0,c.d.a=0,h&&!f.a&&(f.d.a=0)}l&&(function(n){var t,i,r,c,a;for(i=0,t=0,a=n.Kc();a.Ob();)r=Yx(a.Pb(),111),i=e.Math.max(i,r.d.d),t=e.Math.max(t,r.d.a);for(c=n.Kc();c.Ob();)(r=Yx(c.Pb(),111)).d.d=i,r.d.a=t}(u),o&&(f.d.d=0,c.d.a=0))}function Vdn(n,t,e){var i,r,c,a,u;if(i=t.k,t.p>=0)return!1;if(t.p=e.b,eD(e.e,t),i==(bon(),Bzn)||i==qzn)for(r=new pb(t.j);r.a1||-1==a)&&(c|=16),0!=(r.Bb&MNn)&&(c|=64)),0!=(e.Bb&eMn)&&(c|=FDn),c|=DNn):CO(t,457)?c|=512:(i=t.Bj())&&0!=(1&i.i)&&(c|=256),0!=(512&n.Bb)&&(c|=128),c}function ngn(n,t){var e,i,r,c,a;for(n=null==n?aEn:(vB(n),n),r=0;rn.d[u.p]&&(e+=zW(n.b,c),OX(n.a,d9(c))):++a;for(e+=n.b.d*a;!ry(n.a);)eZ(n.b,Yx($_(n.a),19).a)}return e}function egn(n){var t,e,i,r,c,a,u;for(u=new rp,i=new pb(n.a.b);i.a=n.o)throw hp(new Gp);a=t>>5,c=GK(1,WR(GK(31&t,1))),n.n[e][a]=r?zz(n.n[e][a],c):Gz(n.n[e][a],wD(c)),c=GK(c,1),n.n[e][a]=i?zz(n.n[e][a],c):Gz(n.n[e][a],wD(c))}catch(i){throw CO(i=j4(i),320)?hp(new Hm(FSn+n.o+"*"+n.p+BSn+t+tEn+e+HSn)):hp(i)}}function agn(n,t,i,r){var c,a;t&&(c=ty(fL(Aun(t,(ryn(),M5n))))+r,a=i+ty(fL(Aun(t,k5n)))/2,b5(t,O5n,d9(WR(D3(e.Math.round(c))))),b5(t,A5n,d9(WR(D3(e.Math.round(a))))),0==t.d.b||agn(n,Yx(PO(new Rd(Ztn(new Dd(t).a.d,0))),86),i+ty(fL(Aun(t,k5n)))+n.a,r+ty(fL(Aun(t,j5n)))),null!=Aun(t,I5n)&&agn(n,Yx(Aun(t,I5n),86),i,r))}function ugn(n){var t,e,i;return 0!=(64&n.Db)?yon(n):(t=new SA(dNn),(e=n.k)?yI(yI((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new m_(act,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new m_(act,n,1,7)),Yx(c1(n.n,0),137)).a)||yI(yI((t.a+=' "',t),i),'"'))),yI(tj(yI(tj(yI(tj(yI(tj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function ogn(n){var t,e,i;return 0!=(64&n.Db)?yon(n):(t=new SA(gNn),(e=n.k)?yI(yI((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new m_(act,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new m_(act,n,1,7)),Yx(c1(n.n,0),137)).a)||yI(yI((t.a+=' "',t),i),'"'))),yI(tj(yI(tj(yI(tj(yI(tj((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function sgn(n,t){var e,i,r,c,a,u;if(null==t||0==t.length)return null;if(!(r=Yx(aG(n.a,t),149))){for(i=new ub(new Zl(n.b).a.vc().Kc());i.a.Ob();)if(c=Yx(i.a.Pb(),42),a=(e=Yx(c.dd(),149)).c,u=t.length,_N(a.substr(a.length-u,u),t)&&(t.length==a.length||46==XB(a,a.length-t.length-1))){if(r)return null;r=e}r&&GG(n.a,t,r)}return r}function hgn(n){var t,e,i;O$(n,(gjn(),U1n))&&((i=Yx(Aun(n,U1n),21)).dc()||(e=new cx(t=Yx(Ak(cit),9),Yx(eN(t,t.length),9),0),i.Hc((Eln(),Xet))?n2(e,Xet):n2(e,Wet),i.Hc(zet)||n2(e,zet),i.Hc(Get)?n2(e,Yet):i.Hc(qet)?n2(e,Qet):i.Hc(Uet)&&n2(e,Vet),i.Hc(Yet)?n2(e,Get):i.Hc(Qet)?n2(e,qet):i.Hc(Vet)&&n2(e,Uet),b5(n,U1n,e)))}function fgn(n){var t,e,i,r,c,a,u;for(r=Yx(Aun(n,(Ojn(),vQn)),10),$z(0,(i=n.j).c.length),e=Yx(i.c[0],11),a=new pb(r.j);a.ar.p?(whn(c,Bit),c.d&&(u=c.o.b,t=c.a.b,c.a.b=u-t)):c.j==Bit&&r.p>n.p&&(whn(c,Tit),c.d&&(u=c.o.b,t=c.a.b,c.a.b=-(u-t)));break}return r}function lgn(n,t,e,i,r){var c,a,u,o,s,h,f;if(!(CO(t,239)||CO(t,354)||CO(t,186)))throw hp(new Qm("Method only works for ElkNode-, ElkLabel and ElkPort-objects."));return a=n.a/2,o=t.i+i-a,h=t.j+r-a,s=o+t.g+n.a,f=h+t.f+n.a,KD(c=new Nv,new QS(o,h)),KD(c,new QS(o,f)),KD(c,new QS(s,f)),KD(c,new QS(s,h)),o4(u=new eln(c),t),e&&xB(n.b,t,u),u}function bgn(n,t,e){var i,r,c,a,u,o,s,h;for(c=new QS(t,e),s=new pb(n.a);s.a1&&(i=new QS(r,e.b),KD(t.a,i)),r0(t.a,x4(Gy(B7n,1),TEn,8,0,[f,h]))}function Ign(n,t,e){var i,r,c,a,u,o;if(t){if(e<=-1){if(CO(i=CZ(t.Tg(),-1-e),99))return Yx(i,18);for(u=0,o=(a=Yx(t.ah(i),153)).gc();u0){for(r=o.length;r>0&&""==o[r-1];)--r;r=40)&&function(n){var t,e,i,r,c,a,u;for(n.o=new ep,i=new ME,a=new pb(n.e.a);a.a0,u=T7(t,c),VA(e?u.b:u.g,t),1==b7(u).c.length&&VW(i,u,i.c.b,i.c),r=new mP(c,t),OX(n.o,r),uJ(n.e.a,c))}(n),function(n){var t,e,i,r,c,a,u,o,s,h;for(s=n.e.a.c.length,c=new pb(n.e.a);c.a0&&KD(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&KD(n.e,c))))}function Xgn(n,t,e){var i,r,c,a,u,o,s,h,f;for(c=new pQ(t.c.length),s=new pb(t);s.a=0&&o0&&(Lz(0,n.length),45==n.charCodeAt(0)||(Lz(0,n.length),43==n.charCodeAt(0)))?1:0;ie)throw hp(new Iy(YTn+n+'"'));return a}function rpn(n){switch(n){case 100:return Rjn(TKn,!0);case 68:return Rjn(TKn,!1);case 119:return Rjn(MKn,!0);case 87:return Rjn(MKn,!1);case 115:return Rjn(SKn,!0);case 83:return Rjn(SKn,!1);case 99:return Rjn(PKn,!0);case 67:return Rjn(PKn,!1);case 105:return Rjn(IKn,!0);case 73:return Rjn(IKn,!1);default:throw hp(new Im(EKn+n.toString(16)))}}function cpn(n,t,e,i,r){e&&(!i||(n.c-n.b&n.a.length-1)>1)&&1==t&&Yx(n.a[n.b],10).k==(bon(),Fzn)?_pn(Yx(n.a[n.b],10),(Frn(),Ret)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&Yx(n.a[n.c-1&n.a.length-1],10).k==(bon(),Fzn)?_pn(Yx(n.a[n.c-1&n.a.length-1],10),(Frn(),Ket)):2==(n.c-n.b&n.a.length-1)?(_pn(Yx(T5(n),10),(Frn(),Ret)),_pn(Yx(T5(n),10),Ket)):function(n,t){var e,i,r,c,a,u,o,s,h;for(o=h$(n.c-n.b&n.a.length-1),s=null,h=null,c=new VB(n);c.a!=c.b;)r=Yx(w8(c),10),e=(u=Yx(Aun(r,(Ojn(),TQn)),11))?u.i:null,i=(a=Yx(Aun(r,MQn),11))?a.i:null,s==e&&h==i||(vln(o,t),s=e,h=i),o.c[o.c.length]=r;vln(o,t)}(n,r),iW(n)}function apn(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(XB(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=Uhn(n,t))&&t[0]==c)return!1;if(t[0]=0&&u!=e&&(c=new p_(n,1,u,a,null),i?i.Ei(c):i=c),e>=0&&(c=new p_(n,1,e,u==e?a:null,t),i?i.Ei(c):i=c)),i}function spn(n){var t,e,i;if(null==n.b){if(i=new Cy,null!=n.i&&(pI(i,n.i),i.a+=":"),0!=(256&n.f)){for(0!=(256&n.f)&&null!=n.a&&(function(n){return null!=n&&fE(Rct,n.toLowerCase())}(n.i)||(i.a+="//"),pI(i,n.a)),null!=n.d&&(i.a+="/",pI(i,n.d)),0!=(16&n.f)&&(i.a+="/"),t=0,e=n.j.length;t0&&(t.td(e),e.i&&T9(e))}(r=vwn(n,t),(a=Yx(ken(r,0),214)).c.Rf()?a.c.Lf()?new dd(n):new gd(n):new wd(n)),function(n){var t,e,i;for(i=new pb(n.b);i.a>>31;0!=i&&(n[e]=i)}(e,e,t<<1),i=0,r=0,a=0;rs)&&(o+u+omn(i,s,!1).a<=t.b&&(pY(e,c-e.s),e.c=!0,pY(i,c-e.s),Qen(i,e.s,e.t+e.d+u),i.k=!0,o3(e.q,i),h=!0,r&&(c0(t,i),i.j=t,n.c.length>a&&(acn(($z(a,n.c.length),Yx(n.c[a],200)),i),0==($z(a,n.c.length),Yx(n.c[a],200)).a.c.length&&KV(n,a)))),h)}function wpn(n,t,e){var i,r,c,a,u;if(0==t.p){for(t.p=1,(r=e)||(r=new mP(new ip,new cx(i=Yx(Ak(trt),9),Yx(eN(i,i.length),9),0))),Yx(r.a,15).Fc(t),t.k==(bon(),_zn)&&Yx(r.b,21).Fc(Yx(Aun(t,(Ojn(),hQn)),61)),a=new pb(t.j);a.a0)if(r=Yx(n.Ab.g,1934),null==t){for(c=0;c1)for(i=new pb(r);i.ai.s&&o=0&&s>=0&&oa)return Ikn(),Eit;break;case 4:case 3:if(h<0)return Ikn(),Tit;if(h+e>c)return Ikn(),Bit}return(o=(s+u/2)/a)+(i=(h+e/2)/c)<=1&&o-i<=0?(Ikn(),qit):o+i>=1&&o-i>=0?(Ikn(),Eit):i<.5?(Ikn(),Tit):(Ikn(),Bit)}function Mpn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(e=!1,o=ty(fL(Aun(t,(gjn(),G0n)))),l=ZEn*o,r=new pb(t.b);r.aa.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function Spn(n,t,e,i,r,c,a){var u,o,s,h,f;for(f=new hC,o=t.Kc();o.Ob();)for(h=new pb(Yx(o.Pb(),839).wf());h.an.b/2+t.b/2||(c=e.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==i&&0==c?0:0==i?a/c+1:0==c?r/i+1:e.Math.min(r/i,a/c)+1}function Ipn(n,t){var i,r,c,a,u,o;return(c=u0(n))==(o=u0(t))?n.e==t.e&&n.a<54&&t.a<54?n.ft.f?1:0:(r=n.e-t.e,(i=(n.d>0?n.d:e.Math.floor((n.a-1)*aMn)+1)-(t.d>0?t.d:e.Math.floor((t.a-1)*aMn)+1))>r+1?c:i0&&(u=uZ(u,xvn(r))),utn(a,u))):c0&&n.d!=(CJ(),zGn)&&(u+=a*(i.d.a+n.a[t.b][i.b]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(CJ(),qGn)&&(o+=a*(i.d.b+n.a[t.b][i.b]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new QS(u/c,t.d.b);case 2:return new QS(t.d.a,o/c);default:return new QS(u/c,o/c)}}function Opn(n,t){var e,i,r,c;if(A6(),c=Yx(Aun(n.i,(gjn(),g0n)),98),0!=n.j.g-t.j.g||c!=(Ran(),uit)&&c!=sit&&c!=oit)return 0;if(c==(Ran(),uit)&&(e=Yx(Aun(n,p0n),19),i=Yx(Aun(t,p0n),19),e&&i&&0!=(r=e.a-i.a)))return r;switch(n.j.g){case 1:return $9(n.n.a,t.n.a);case 2:return $9(n.n.b,t.n.b);case 3:return $9(t.n.a,n.n.a);case 4:return $9(t.n.b,n.n.b);default:throw hp(new Ym(mIn))}}function Apn(n){var t,e,i,r,c;for(eD(c=new pQ((!n.a&&(n.a=new XO(Qrt,n,5)),n.a).i+2),new QS(n.j,n.k)),SE(new SR(null,(!n.a&&(n.a=new XO(Qrt,n,5)),new Nz(n.a,16))),new Jd(c)),eD(c,new QS(n.b,n.c)),t=1;t0&&(Y4(o,!1,(t9(),Ztt)),Y4(o,!0,net)),WZ(t.g,new PM(n,e)),xB(n.g,t,e)}function Lpn(){var n;for(Lpn=O,W_n=x4(Gy(Wot,1),MTn,25,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),V_n=VQ(Wot,MTn,25,37,15,1),Q_n=x4(Gy(Wot,1),MTn,25,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),Y_n=VQ(Qot,tMn,25,37,14,1),n=2;n<=36;n++)V_n[n]=oG(e.Math.pow(n,W_n[n])),Y_n[n]=Bcn(IEn,V_n[n])}function Npn(n){var t;if(1!=(!n.a&&(n.a=new m_(tct,n,6,6)),n.a).i)throw hp(new Qm(eNn+(!n.a&&(n.a=new m_(tct,n,6,6)),n.a).i));return t=new Nv,E4(Yx(c1((!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),0),82))&&C2(t,mjn(n,E4(Yx(c1((!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),0),82)),!1)),E4(Yx(c1((!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c),0),82))&&C2(t,mjn(n,E4(Yx(c1((!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c),0),82)),!0)),t}function xpn(n,t){var e,i,r;for(r=!1,i=new $K(bA((t.d?n.a.c==(Jq(),d4n)?u7(t.b):o7(t.b):n.a.c==(Jq(),w4n)?u7(t.b):o7(t.b)).a.Kc(),new h));Vfn(i);)if(e=Yx(kV(i),17),(ny(n.a.f[n.a.g[t.b.p].p])||ZW(e)||e.c.i.c!=e.d.i.c)&&!ny(n.a.n[n.a.g[t.b.p].p])&&!ny(n.a.n[n.a.g[t.b.p].p])&&(r=!0,gE(n.b,n.a.g[zin(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function Dpn(n,t,e){var i,r,c,a,u,o,s;if(0==(i=e.gc()))return!1;if(n.ej())if(o=n.fj(),Q7(n,t,e),a=1==i?n.Zi(3,null,e.Kc().Pb(),t,o):n.Zi(5,null,e,t,o),n.bj()){for(u=i<100?null:new Ek(i),c=t+i,r=t;r0){for(u=0;u>16==-15&&n.Cb.nh()&&vJ(new kY(n.Cb,9,13,e,n.c,Ren(IJ(Yx(n.Cb,59)),n))):CO(n.Cb,88)&&n.Db>>16==-23&&n.Cb.nh()&&(CO(t=n.c,88)||(xjn(),t=Oat),CO(e,88)||(xjn(),e=Oat),vJ(new kY(n.Cb,9,10,e,t,Ren(tW(Yx(n.Cb,26)),n)))))),n.c}function Hpn(n,t,e){var i,r,c,a,u,o,s,h;for(run(e,"Hyperedge merging",1),function(n,t){var e,i,r,c;for((c=Yx(kW(WJ(WJ(new SR(null,new Nz(t.b,16)),new Re),new Ke),mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[(C6(),aBn)]))),15)).Jc(new _e),e=0,r=c.Kc();r.Ob();)-1==(i=Yx(r.Pb(),11)).p&&wln(n,i,e++)}(n,t),u=new JU(t.b,0);u.be);return r}function Gpn(n,t){var e,i,r;i=0!=Xln(n.d,1),!ny(hL(Aun(t.j,(Ojn(),lQn))))&&!ny(hL(Aun(t.j,qQn)))||iI(Aun(t.j,(gjn(),XZn)))===iI((k5(),W2n))?t.c.Tf(t.e,i):i=ny(hL(Aun(t.j,lQn))),Zbn(n,t,i,!0),ny(hL(Aun(t.j,qQn)))&&b5(t.j,qQn,(TA(),!1)),ny(hL(Aun(t.j,lQn)))&&(b5(t.j,lQn,(TA(),!1)),b5(t.j,qQn,!0)),e=Rsn(n,t);do{if(k2(n),0==e)return 0;r=e,Zbn(n,t,i=!i,!1),e=Rsn(n,t)}while(r>e);return r}function zpn(n,t,e){var i,r,c,a,u,o,s;if(t==e)return!0;if(t=Xfn(n,t),e=Xfn(n,e),i=win(t)){if((o=win(e))!=i)return!!o&&(a=i.Dj())==o.Dj()&&null!=a;if(!t.d&&(t.d=new XO(hat,t,1)),r=(c=t.d).i,!e.d&&(e.d=new XO(hat,e,1)),r==(s=e.d).i)for(u=0;u0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}((IG(n)&&(dT(),new Xm(IG(n))),dT(),new e$(IG(n)?new Xm(IG(n)):null,n)),net),a=Yx(Aun(r,c0n),116),$G(i=r.d,a),$G(i,c),r}function Vpn(n,t){var i,r,c,a;return r=e.Math.abs(a_(n.b).a-a_(t.b).a),a=e.Math.abs(a_(n.b).b-a_(t.b).b),i=1,c=1,r>n.b.b/2+t.b.b/2&&(i=1-e.Math.min(e.Math.abs(n.b.c-(t.b.c+t.b.b)),e.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-e.Math.min(e.Math.abs(n.b.d-(t.b.d+t.b.a)),e.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-e.Math.min(i,c))*e.Math.sqrt(r*r+a*a)}function Qpn(n){var t,i,r;for(gkn(n,n.e,n.f,(Yq(),X4n),!0,n.c,n.i),gkn(n,n.e,n.f,X4n,!1,n.c,n.i),gkn(n,n.e,n.f,W4n,!0,n.c,n.i),gkn(n,n.e,n.f,W4n,!1,n.c,n.i),function(n,t,e,i,r){var c,a,u,o,s,h,f;for(a=new pb(t);a.a=w&&(v>w&&(b.c=VQ(UKn,iEn,1,0,5,1),w=v),b.c[b.c.length]=a);0!=b.c.length&&(l=Yx(TR(b,Uen(t,b.c.length)),128),P.a.Bc(l),l.s=d++,cbn(l,M,j),b.c=VQ(UKn,iEn,1,0,5,1))}for(y=n.c.length+1,u=new pb(n);u.aS.s&&(hB(e),uJ(S.i,i),i.c>0&&(i.a=S,eD(S.t,i),i.b=E,eD(E.i,i)))})(n.i,Yx(Aun(n.d,(Ojn(),FQn)),230)),function(n){var t,i,r,c,a,u,o,s,h;for(s=new ME,u=new ME,c=new pb(n);c.a-1){for(r=Ztn(u,0);r.b!=r.d.c;)(i=Yx(IX(r),128)).v=a;for(;0!=u.b;)for(t=new pb((i=Yx(Urn(u,0),128)).i);t.a=65;e--)sot[e]=e-65<<24>>24;for(i=122;i>=97;i--)sot[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)sot[r]=r-48+52<<24>>24;for(sot[43]=62,sot[47]=63,c=0;c<=25;c++)hot[c]=65+c&fTn;for(a=26,o=0;a<=51;++a,o++)hot[a]=97+o&fTn;for(n=52,u=0;n<=61;++n,u++)hot[n]=48+u&fTn;hot[62]=43,hot[63]=47}function Zpn(n,t){var e,i,r,c,a,u,o;if(!TG(n))throw hp(new Ym(tNn));if(c=(i=TG(n)).g,r=i.f,c<=0&&r<=0)return Ikn(),Hit;switch(u=n.i,o=n.j,t.g){case 2:case 1:if(u<0)return Ikn(),qit;if(u+n.g>c)return Ikn(),Eit;break;case 4:case 3:if(o<0)return Ikn(),Tit;if(o+n.f>r)return Ikn(),Bit}return(a=(u+n.g/2)/c)+(e=(o+n.f/2)/r)<=1&&a-e<=0?(Ikn(),qit):a+e>=1&&a-e>=0?(Ikn(),Eit):e<.5?(Ikn(),Tit):(Ikn(),Bit)}function nvn(n){var t,e,i,r,c,a;if(Ljn(),4!=n.e&&5!=n.e)throw hp(new Qm("Token#complementRanges(): must be RANGE: "+n.e));for(xln(c=n),Lmn(c),i=c.b.length+2,0==c.b[0]&&(i-=2),(e=c.b[c.b.length-1])==jKn&&(i-=2),(r=new cU(4)).b=VQ(Wot,MTn,25,i,15,1),a=0,c.b[0]>0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t0&&(Kl(o,o.d-r.d),r.c==(iQ(),K4n)&&Dl(o,o.a-r.d),o.d<=0&&o.i>0&&VW(t,o,t.c.b,t.c));for(c=new pb(n.f);c.a0&&(_l(u,u.i-r.d),r.c==(iQ(),K4n)&&Rl(u,u.b-r.d),u.i<=0&&u.d>0&&VW(e,u,e.c.b,e.c))}function ivn(n,t,e){var i,r,c,a,u,o,s,h;for(run(e,"Processor compute fanout",1),U_(n.b),U_(n.a),u=null,c=Ztn(t.b,0);!u&&c.b!=c.d.c;)ny(hL(Aun(s=Yx(IX(c),86),(ryn(),C5n))))&&(u=s);for(VW(o=new ME,u,o.c.b,o.c),Ckn(n,o),h=Ztn(t.b,0);h.b!=h.d.c;)a=lL(Aun(s=Yx(IX(h),86),(ryn(),v5n))),r=null!=aG(n.b,a)?Yx(aG(n.b,a),19).a:0,b5(s,p5n,d9(r)),i=1+(null!=aG(n.a,a)?Yx(aG(n.a,a),19).a:0),b5(s,d5n,d9(i));Ron(e)}function rvn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(f=function(n,t){var e,i,r;for(r=new JU(n.e,0),e=0;r.bYAn)return e;i>-1e-6&&++e}return e}(n,e),u=0;u0),i.a.Xb(i.c=--i.b),h>f+u&&hB(i);for(c=new pb(l);c.a0),i.a.Xb(i.c=--i.b)}}function cvn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w;if(i=n.i,t=n.n,0==n.b)for(w=i.c+t.b,b=i.b-t.b-t.c,s=0,f=(u=n.a).length;s0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=e.Math.max(r[1],l),vK(n.a[1],i.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(o=0,h=(a=n.a).length;oa&&(a=r,s.c=VQ(UKn,iEn,1,0,5,1)),r==a&&eD(s,new mP(e.c.i,e)));XH(),JC(s,n.c),ZR(n.b,u.p,s)}}(l,n),l.f=h$(l.d),function(n,t){var e,i,r,c,a,u,o,s;for(c=new pb(t.b);c.aa&&(a=r,s.c=VQ(UKn,iEn,1,0,5,1)),r==a&&eD(s,new mP(e.d.i,e)));XH(),JC(s,n.c),ZR(n.f,u.p,s)}}(l,n),l}function uvn(n,t){var i,r,c;for(c=Yx(TR(n.n,n.n.c.length-1),211).d,n.p=e.Math.min(n.p,t.g),n.r=e.Math.max(n.r,c),n.g=e.Math.max(n.g,t.g+(1==n.b.c.length?0:n.i)),n.o=e.Math.min(n.o,t.f),n.e+=t.f+(1==n.b.c.length?0:n.i),n.f=e.Math.max(n.f,t.f),r=n.n.c.length>0?(n.n.c.length-1)*n.i:0,i=new pb(n.n);i.a1)for(i=Ztn(r,0);i.b!=i.d.c;)for(c=0,u=new pb((e=Yx(IX(i),231)).e);u.a0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=e.Math.max(t[1],l),mK(n.a[1],r.d+i.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+i.d,b=r.a-i.d-i.a,s=0,f=(u=n.a).length;s=0&&c!=e)throw hp(new Qm(kxn));for(r=0,o=0;o0||0==y7(c.b.d,n.b.d+n.b.a)&&r.b<0||0==y7(c.b.d+c.b.a,n.b.d)&&r.b>0){o=0;break}}else o=e.Math.min(o,bhn(n,c,r));o=e.Math.min(o,bvn(n,a,o,r))}return o}function wvn(n,t){var e,i,r,c,a,u;if(n.b<2)throw hp(new Qm("The vector chain must contain at least a source and a target point."));for(S$(0!=n.b),TC(t,(i=Yx(n.a.a.c,8)).a,i.b),u=new a$((!t.a&&(t.a=new XO(Qrt,t,5)),t.a)),c=Ztn(n,1);c.aty(NO(a.g,a.d[0]).a)?(S$(o.b>0),o.a.Xb(o.c=--o.b),ZL(o,a),r=!0):u.e&&u.e.gc()>0&&(c=(!u.e&&(u.e=new ip),u.e).Mc(t),s=(!u.e&&(u.e=new ip),u.e).Mc(e),(c||s)&&((!u.e&&(u.e=new ip),u.e).Fc(a),++a.c));r||(i.c[i.c.length]=a)}function kvn(n){var t,e,i;if(dC(Yx(Aun(n,(gjn(),g0n)),98)))for(e=new pb(n.j);e.a>>0).toString(16),t.length-2,t.length):n>=eMn?"\\v"+l$(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&fTn)}return e}function Evn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=n.e,0==(o=t.e))return n;if(0==a)return 0==t.e?t:new C_(-t.e,t.d,t.a);if((c=n.d)+(u=t.d)==2)return e=Gz(n.a[0],uMn),i=Gz(t.a[0],uMn),a<0&&(e=sJ(e)),o<0&&(i=sJ(i)),Utn(n7(e,i));if(-1==(r=c!=u?c>u?1:-1:w6(n.a,t.a,c)))f=-o,h=a==o?GV(t.a,u,n.a,c):WQ(t.a,u,n.a,c);else if(f=a,a==o){if(0==r)return bdn(),pFn;h=GV(n.a,c,t.a,u)}else h=WQ(n.a,c,t.a,u);return SU(s=new C_(f,h.length,h)),s}function Tvn(n){var t,e,i,r,c,a;for(this.e=new ip,this.a=new ip,e=n.b-1;e<3;e++)A$(n,0,Yx(ken(n,0),8));if(n.b<4)throw hp(new Qm("At (least dimension + 1) control points are necessary!"));for(this.b=3,this.d=!0,this.c=!1,function(n,t){var e,i,r,c,a;if(t<2*n.b)throw hp(new Qm("The knot vector must have at least two time the dimension elements."));for(n.f=1,r=0;r=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=Yx(TR(t.n,t.n.c.length-1),211)).e+c.d+e.g+r<=i&&(Yx(TR(t.n,t.n.c.length-1),211).f-n.f+e.f<=n.b||1==n.a.c.length))return l7(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return eD(t.b,e),a=Yx(TR(t.n,t.n.c.length-1),211),eD(t.n,new gG(t.s,a.f+a.a+t.i,t.i)),Cin(Yx(TR(t.n,t.n.c.length-1),211),e),uvn(t,e),!0}return!1}function Pvn(n,t,e){var i,r,c,a;return n.ej()?(r=null,c=n.fj(),i=n.Zi(1,a=HJ(n,t,e),e,t,c),n.bj()&&!(n.ni()&&null!=a?Q8(a,e):iI(a)===iI(e))?(null!=a&&(r=n.dj(a,r)),r=n.cj(e,r),n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):(n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)),a):(a=HJ(n,t,e),n.bj()&&!(n.ni()&&null!=a?Q8(a,e):iI(a)===iI(e))&&(r=null,null!=a&&(r=n.dj(a,null)),(r=n.cj(e,r))&&r.Fi()),a)}function Ivn(n,t){var i,r,c,a,u,o,s;t%=24,n.q.getHours()!=t&&((i=new e.Date(n.q.getTime())).setDate(i.getDate()+1),(u=n.q.getTimezoneOffset()-i.getTimezoneOffset())>0&&(o=u/60|0,s=u%60,r=n.q.getDate(),n.q.getHours()+o>=24&&++r,c=new e.Date(n.q.getFullYear(),n.q.getMonth(),r,t+o,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function Cvn(n,t){var e,i,r,c;if(run(t,"Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new rln(n)).i&&(r.i=D2(r,new kc)),e=ty(r.i)*r.f/(null==r.i&&(r.i=D2(r,new kc)),ty(r.i)),r.b>e)Ron(t);else{switch(Yx(Aun(n,(gjn(),t2n)),337).g){case 2:c=new Tc;break;case 0:c=new wc;break;default:c=new Mc}if(i=c.Vf(n,r),!c.Wf())switch(Yx(Aun(n,u2n),338).g){case 2:i=dhn(r,i);break;case 1:i=uun(r,i)}(function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(!e.dc()){for(a=0,h=0,l=Yx((i=e.Kc()).Pb(),19).a;a1||-1==w)if(f=Yx(d,69),l=Yx(h,69),f.dc())l.$b();else for(a=!!nin(t),c=0,u=n.a?f.Kc():f.Zh();u.Ob();)s=Yx(u.Pb(),56),(r=Yx(UJ(n,s),56))?(a?-1==(o=l.Xc(r))?l.Xh(c,r):c!=o&&l.ji(c,r):l.Xh(c,r),++c):n.b&&!a&&(l.Xh(c,s),++c);else null==d?h.Wb(null):null==(r=UJ(n,d))?n.b&&!nin(t)&&h.Wb(d):h.Wb(r)}function Nvn(n,t){var i,r,c,a,u,o,s,f;for(i=new Le,c=new $K(bA(u7(t).a.Kc(),new h));Vfn(c);)if(!ZW(r=Yx(kV(c),17))&&Ban(o=r.c.i,uUn)){if(-1==(f=Sdn(n,o,uUn,aUn)))continue;i.b=e.Math.max(i.b,f),!i.a&&(i.a=new ip),eD(i.a,o)}for(u=new $K(bA(o7(t).a.Kc(),new h));Vfn(u);)if(!ZW(a=Yx(kV(u),17))&&Ban(s=a.d.i,aUn)){if(-1==(f=Sdn(n,s,aUn,uUn)))continue;i.d=e.Math.max(i.d,f),!i.c&&(i.c=new ip),eD(i.c,s)}return i}function xvn(n){var t,e,i,r;if(jfn(),t=oG(n),n1e6)throw hp(new Bm("power of ten too big"));if(n<=Yjn)return mV(ifn(kFn[1],t),t);for(r=i=ifn(kFn[1],Yjn),e=D3(n-Yjn),t=oG(n%Yjn);k8(e,Yjn)>0;)r=uZ(r,i),e=n7(e,Yjn);for(r=mV(r=uZ(r,ifn(kFn[1],t)),Yjn),e=D3(n-Yjn);k8(e,Yjn)>0;)r=mV(r,Yjn),e=n7(e,Yjn);return mV(r,t)}function Dvn(n,t){var e,i,r,c,a;run(t,"Layer constraint postprocessing",1),0!=(a=n.b).c.length&&($z(0,a.c.length),function(n,t,e,i,r){var c,a,u,o,s,h;for(c=new pb(n.b);c.a1)););(u>0||l.Hc((Chn(),pit))&&(!c.n&&(c.n=new m_(act,c,1,7)),c.n).i>0)&&(o=!0),u>1&&(s=!0)}o&&t.Fc((edn(),SVn)),s&&t.Fc((edn(),PVn))}(t,i=Yx(Aun(r,(Ojn(),bQn)),21)),i.Hc((edn(),SVn)))for(e=new UO((!t.c&&(t.c=new m_(oct,t,9,9)),t.c));e.e!=e.i.gc();)bkn(n,t,r,Yx(hen(e),118));return 0!=Yx(jln(t,(gjn(),n0n)),174).gc()&&cdn(t,r),ny(hL(Aun(r,u0n)))&&i.Fc(AVn),O$(r,O0n)&&Rm(new B7(ty(fL(Aun(r,O0n)))),r),iI(jln(t,E1n))===iI((O8(),$et))?function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(a=new ME,v=Yx(Aun(e,(gjn(),a1n)),103),w=0,C2(a,(!t.a&&(t.a=new m_(uct,t,10,11)),t.a));0!=a.b;)s=Yx(0==a.b?null:(S$(0!=a.b),VZ(a,a.a.a)),33),(iI(jln(t,XZn))!==iI((k5(),W2n))||iI(jln(t,r1n))===iI((min(),RWn))||iI(jln(t,r1n))===iI((min(),xWn))||ny(hL(jln(t,VZn)))||iI(jln(t,HZn))!==iI((e9(),Izn)))&&!ny(hL(jln(s,UZn)))&&Aen(s,(Ojn(),IQn),d9(w++)),!ny(hL(jln(s,r0n)))&&(f=0!=(!s.a&&(s.a=new m_(uct,s,10,11)),s.a).i,b=Yan(s),l=iI(jln(s,E1n))===iI((O8(),$et)),g=null,(T=!zQ(s,(Cjn(),gnt))||_N(lL(jln(s,gnt)),CIn))&&l&&(f||b)&&(b5(g=Wpn(s),a1n,v),O$(g,O0n)&&Rm(new B7(ty(fL(Aun(g,O0n)))),g),0!=Yx(jln(s,n0n),174).gc()&&(h=g,SE(new SR(null,(!s.c&&(s.c=new m_(oct,s,9,9)),new Nz(s.c,16))),new gw(h)),cdn(s,g))),m=e,(y=Yx(BF(n.a,IG(s)),10))&&(m=y.e),d=Qyn(n,s,m),g&&(d.e=g,g.e=d,C2(a,(!s.a&&(s.a=new m_(uct,s,10,11)),s.a))));for(w=0,VW(a,t,a.c.b,a.c);0!=a.b;){for(o=new UO((!(c=Yx(0==a.b?null:(S$(0!=a.b),VZ(a,a.a.a)),33)).b&&(c.b=new m_(nct,c,12,3)),c.b));o.e!=o.i.gc();)dgn(u=Yx(hen(o),79)),(iI(jln(t,XZn))!==iI((k5(),W2n))||iI(jln(t,r1n))===iI((min(),RWn))||iI(jln(t,r1n))===iI((min(),xWn))||ny(hL(jln(t,VZn)))||iI(jln(t,HZn))!==iI((e9(),Izn)))&&Aen(u,(Ojn(),IQn),d9(w++)),j=iun(Yx(c1((!u.b&&(u.b=new AN(Zrt,u,4,7)),u.b),0),82)),E=iun(Yx(c1((!u.c&&(u.c=new AN(Zrt,u,5,8)),u.c),0),82)),ny(hL(jln(u,r0n)))||ny(hL(jln(j,r0n)))||ny(hL(jln(E,r0n)))||(p=c,Whn(u)&&ny(hL(jln(j,I1n)))&&ny(hL(jln(u,C1n)))||XZ(E,j)?p=j:XZ(j,E)&&(p=E),m=e,(y=Yx(BF(n.a,p),10))&&(m=y.e),b5(Ijn(n,u,p,m),(Ojn(),nQn),Nwn(n,u,t,e)));if(l=iI(jln(c,E1n))===iI((O8(),$et)))for(r=new UO((!c.a&&(c.a=new m_(uct,c,10,11)),c.a));r.e!=r.i.gc();)T=!zQ(i=Yx(hen(r),33),(Cjn(),gnt))||_N(lL(jln(i,gnt)),CIn),k=iI(jln(i,E1n))===iI($et),T&&k&&VW(a,i,a.c.b,a.c)}}(n,t,r):function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d;for(f=0,r=new UO((!t.a&&(t.a=new m_(uct,t,10,11)),t.a));r.e!=r.i.gc();)ny(hL(jln(i=Yx(hen(r),33),(gjn(),r0n))))||(iI(jln(t,XZn))===iI((k5(),W2n))&&iI(jln(t,r1n))!==iI((min(),RWn))&&iI(jln(t,r1n))!==iI((min(),xWn))&&!ny(hL(jln(t,VZn)))&&iI(jln(t,HZn))===iI((e9(),Izn))||ny(hL(jln(i,UZn)))||(Aen(i,(Ojn(),IQn),d9(f)),++f),Qyn(n,i,e));for(f=0,s=new UO((!t.b&&(t.b=new m_(nct,t,12,3)),t.b));s.e!=s.i.gc();)u=Yx(hen(s),79),(iI(jln(t,(gjn(),XZn)))!==iI((k5(),W2n))||iI(jln(t,r1n))===iI((min(),RWn))||iI(jln(t,r1n))===iI((min(),xWn))||ny(hL(jln(t,VZn)))||iI(jln(t,HZn))!==iI((e9(),Izn)))&&(Aen(u,(Ojn(),IQn),d9(f)),++f),w=Kun(u),d=Bun(u),h=ny(hL(jln(w,I1n))),b=!ny(hL(jln(u,r0n))),l=h&&Whn(u)&&ny(hL(jln(u,C1n))),c=IG(w)==t&&IG(w)==IG(d),a=(IG(w)==t&&d==t)^(IG(d)==t&&w==t),b&&!l&&(a||c)&&Ijn(n,u,t,e);if(IG(t))for(o=new UO(CH(IG(t)));o.e!=o.i.gc();)(w=Kun(u=Yx(hen(o),79)))==t&&Whn(u)&&(l=ny(hL(jln(w,(gjn(),I1n))))&&ny(hL(jln(u,C1n))))&&Ijn(n,u,t,e)}(n,t,r),r}function _vn(n,t,i,r){var c,a,u;if(this.j=new ip,this.k=new ip,this.b=new ip,this.c=new ip,this.e=new hC,this.i=new Nv,this.f=new cp,this.d=new ip,this.g=new ip,eD(this.b,n),eD(this.b,t),this.e.c=e.Math.min(n.a,t.a),this.e.d=e.Math.min(n.b,t.b),this.e.b=e.Math.abs(n.a-t.a),this.e.a=e.Math.abs(n.b-t.b),c=Yx(Aun(r,(gjn(),$1n)),74))for(u=Ztn(c,0);u.b!=u.d.c;)w1((a=Yx(IX(u),8)).a,n.a)&&KD(this.i,a);i&&eD(this.j,i),eD(this.k,r)}function Fvn(n,t,e){var i,r,c,a,u,o,s,h,f,l;for(h=new h_(new rw(e)),x_(u=VQ(Vot,wSn,25,n.f.e.c.length,16,1),u.length),e[t.b]=0,s=new pb(n.f.e);s.as&&i>s)){r=!1,e.n&&LD(e,"bk node placement breaks on "+u+" which should have been after "+h);break}h=u,s=ty(t.p[u.p])+ty(t.d[u.p])+u.o.b+u.d.a}if(!r)break}return e.n&&LD(e,t+" is feasible: "+r),r}function Hvn(n,t,e,i){var r,c,a,u,o,s,h;if(e.d.i!=t.i){for(Al(r=new rin(n),(bon(),Bzn)),b5(r,(Ojn(),CQn),e),b5(r,(gjn(),g0n),(Ran(),oit)),i.c[i.c.length]=r,ZG(a=new Ion,r),whn(a,(Ikn(),qit)),ZG(u=new Ion,r),whn(u,Eit),h=e.d,QG(e,a),o4(c=new jq,e),b5(c,$1n,null),YG(c,u),QG(c,h),s=new JU(e.b,0);s.b=g&&n.e[s.p]>w*n.b||m>=i*g)&&(l.c[l.c.length]=o,o=new ip,C2(u,a),a.a.$b(),h-=f,b=e.Math.max(b,h*n.b+d),h+=m,v=m,m=0,f=0,d=0);return new mP(b,l)}function zvn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(e=new ub(new Zl(n.c.b).a.vc().Kc());e.a.Ob();)u=Yx(e.a.Pb(),42),null==(r=(t=Yx(u.dd(),149)).a)&&(r=""),!(i=EL(n.c,r))&&0==r.length&&(i=F8(n)),i&&!V7(i.c,t,!1)&&KD(i.c,t);for(a=Ztn(n.a,0);a.b!=a.d.c;)c=Yx(IX(a),478),s=hV(n.c,c.a),l=hV(n.c,c.b),s&&l&&KD(s.c,new mP(l,c.c));for(BH(n.a),f=Ztn(n.b,0);f.b!=f.d.c;)h=Yx(IX(f),478),t=jL(n.c,h.a),o=hV(n.c,h.b),t&&o&&sT(t,o,h.c);BH(n.b)}function Uvn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Mo,c=new Mo,null==(t=Hat).a.zc(n,t)){for(r=new UO(Iq(n));r.e!=r.i.gc();)jF(a,Uvn(Yx(hen(r),26)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new m_(tat,n,21,17)),i=new UO(n.s);i.e!=i.i.gc();)CO(e=Yx(hen(i),170),99)&&fY(c,Yx(e,18));B6(c),n.r=new ID(n,(Yx(c1(aq((YF(),gat).o),6),18),c.i),c.g),jF(a,n.r),B6(a),n.f=new HI((Yx(c1(aq(gat.o),5),18),a.i),a.g),bV(n).b&=-3}return n.f}function Xvn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(a=n.o,i=VQ(Wot,MTn,25,a,15,1),r=VQ(Wot,MTn,25,a,15,1),e=n.p,t=VQ(Wot,MTn,25,e,15,1),c=VQ(Wot,MTn,25,e,15,1),s=0;s=0&&!Nin(n,h,f);)--f;r[h]=f}for(b=0;b=0&&!Nin(n,u,w);)--u;c[w]=u}for(o=0;ot[l]&&li[o]&&cgn(n,o,l,!1,!0)}function Wvn(n){var t,e,i,r,c,a,u,o;e=ny(hL(Aun(n,(Bdn(),tGn)))),c=n.a.c.d,u=n.a.d.d,e?(a=KO(yN(new QS(u.a,u.b),c),.5),o=KO(dO(n.e),.5),t=yN(mN(new QS(c.a,c.b),a),o),x$(n.d,t)):(r=ty(fL(Aun(n.a,vGn))),i=n.d,c.a>=u.a?c.b>=u.b?(i.a=u.a+(c.a-u.a)/2+r,i.b=u.b+(c.b-u.b)/2-r-n.e.b):(i.a=u.a+(c.a-u.a)/2+r,i.b=c.b+(u.b-c.b)/2+r):c.b>=u.b?(i.a=c.a+(u.a-c.a)/2+r,i.b=u.b+(c.b-u.b)/2+r):(i.a=c.a+(u.a-c.a)/2+r,i.b=c.b+(u.b-c.b)/2-r-n.e.b))}function Vvn(n,t){var e,i,r,c,a,u,o;if(null==n)return null;if(0==(c=n.length))return"";for(o=VQ(Xot,sTn,25,c,15,1),YQ(0,c,n.length),YQ(0,c,o.length),aF(n,0,c,o,0),e=null,u=t,r=0,a=0;r0?l$(e.a,0,c-1):"":n.substr(0,c-1):e?e.a:n}function Qvn(n){uT(n,new tun(rk(nk(ik(ek(new du,uPn),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new at))),DU(n,uPn,oPn,oen(Rqn)),DU(n,uPn,sPn,oen(Aqn)),DU(n,uPn,hPn,oen(Sqn)),DU(n,uPn,fPn,oen($qn)),DU(n,uPn,oSn,oen(xqn)),DU(n,uPn,sSn,oen(Nqn)),DU(n,uPn,uSn,oen(Dqn)),DU(n,uPn,hSn,oen(Lqn)),DU(n,uPn,ePn,oen(Iqn)),DU(n,uPn,iPn,oen(Pqn)),DU(n,uPn,rPn,oen(Cqn)),DU(n,uPn,cPn,oen(Oqn))}function Yvn(n,t,e,i){var r,c,a,u,o,s,h;if(Al(c=new rin(n),(bon(),qzn)),b5(c,(gjn(),g0n),(Ran(),oit)),r=0,t){for(b5(a=new Ion,(Ojn(),CQn),t),b5(c,CQn,t.i),whn(a,(Ikn(),qit)),ZG(a,c),s=0,h=(o=CU(t.e)).length;s=0&&l<=1&&b>=0&&b<=1?mN(new QS(n.a,n.b),KO(new QS(t.a,t.b),l)):null}function nmn(n){var t,i,r,c,a,u,o,s,h,f;for(s=new Jl(new Yl(Tfn(n)).a.vc().Kc());s.a.Ob();){for(r=Yx(s.a.Pb(),42),h=0,f=0,h=(o=Yx(r.cd(),10)).d.d,f=o.o.b+o.d.a,n.d[o.p]=0,t=o;(c=n.a[t.p])!=o;)i=jtn(t,c),0,u=n.c==(Jq(),w4n)?i.d.n.b+i.d.a.b-i.c.n.b-i.c.a.b:i.c.n.b+i.c.a.b-i.d.n.b-i.d.a.b,a=ty(n.d[t.p])+u,n.d[c.p]=a,h=e.Math.max(h,c.d.d-a),f=e.Math.max(f,a+c.o.b+c.d.a),t=c;t=o;do{n.d[t.p]=ty(n.d[t.p])+h,t=n.a[t.p]}while(t!=o);n.b[o.p]=h+f}}function tmn(n){var t,i,r,c,a,u,o,s,h,f,l;for(n.b=!1,f=JTn,o=ZTn,l=JTn,s=ZTn,i=n.e.a.ec().Kc();i.Ob();)for(r=(t=Yx(i.Pb(),266)).a,f=e.Math.min(f,r.c),o=e.Math.max(o,r.c+r.b),l=e.Math.min(l,r.d),s=e.Math.max(s,r.d+r.a),a=new pb(t.c);a.a=($z(c,n.c.length),Yx(n.c[c],200)).e,!((s=omn(i,f,!1).a)>t.b&&!o)&&((o||s<=t.b)&&(o&&s>t.b?(e.d=s,pY(e,Don(e,s))):(san(e.q,u),e.c=!0),pY(i,r-(e.s+e.r)),Qen(i,e.q.e+e.q.d,t.f),c0(t,i),n.c.length>c&&(acn(($z(c,n.c.length),Yx(n.c[c],200)),i),0==($z(c,n.c.length),Yx(n.c[c],200)).a.c.length&&KV(n,c)),h=!0),h))}function rmn(n,t,e,i){var r,c,a,u,o,s,h;if(h=dwn(n.e.Tg(),t),r=0,c=Yx(n.g,119),o=null,TT(),Yx(t,66).Oj()){for(u=0;u0?n.i:0)>t&&s>0&&(a=0,u+=s+n.i,c=e.Math.max(c,b),r+=s+n.i,s=0,b=0,i&&(++l,eD(n.n,new gG(n.s,u,n.i))),o=0),b+=h.g+(o>0?n.i:0),s=e.Math.max(s,h.f),i&&Cin(Yx(TR(n.n,l),211),h),a+=h.g+(o>0?n.i:0),++o;return c=e.Math.max(c,b),r+=s,i&&(n.r=c,n.d=r,Trn(n.j)),new mH(n.s,n.t,c,r)}function smn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;if(oE(),B_(n,"src"),B_(e,"dest"),l=V5(n),o=V5(e),kD(0!=(4&l.i),"srcType is not an array"),kD(0!=(4&o.i),"destType is not an array"),f=l.c,a=o.c,kD(0!=(1&f.i)?f==a:0==(1&a.i),"Array types don't match"),b=n.length,s=e.length,t<0||i<0||r<0||t+r>b||i+r>s)throw hp(new Cp);if(0==(1&f.i)&&l!=o)if(h=h1(n),c=h1(e),iI(n)===iI(e)&&ti;)DF(c,u,h[--t]);else for(u=i+r;i0&&hhn(n,t,e,i,r,!0)}function hmn(){hmn=O,mFn=x4(Gy(Wot,1),MTn,25,15,[nTn,1162261467,zEn,1220703125,362797056,1977326743,zEn,387420489,UTn,214358881,429981696,815730721,1475789056,170859375,268435456,410338673,612220032,893871739,128e7,1801088541,113379904,148035889,191102976,244140625,308915776,387420489,481890304,594823321,729e6,887503681,zEn,1291467969,1544804416,1838265625,60466176]),yFn=x4(Gy(Wot,1),MTn,25,15,[-1,-1,31,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5])}function fmn(n,t){var e,i,r,c,a;if(a=Yx(t,136),xln(n),xln(a),null!=a.b){if(n.c=!0,null==n.b)return n.b=VQ(Wot,MTn,25,a.b.length,15,1),void smn(a.b,0,n.b,0,a.b.length);for(c=VQ(Wot,MTn,25,n.b.length+a.b.length,15,1),e=0,i=0,r=0;e=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]0&&(!(r=(!n.n&&(n.n=new m_(act,n,1,7)),Yx(c1(n.n,0),137)).a)||yI(yI((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new AN(Zrt,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",yI(t,lA(new Ty,new UO(n.b))),e&&(t.a+="]"),t.a+=pIn,e&&(t.a+="["),yI(t,lA(new Ty,new UO(n.c))),e&&(t.a+="]"),t.a)}function wmn(n,t){var e,i,r,c,a,u,o;if(n.a){if(o=null,null!=(u=n.a.ne())?t.a+=""+u:null!=(a=n.a.Dj())&&(-1!=(c=VI(a,gun(91)))?(o=a.substr(c),t.a+=""+l$(null==a?aEn:(vB(a),a),0,c)):t.a+=""+a),n.d&&0!=n.d.i){for(r=!0,t.a+="<",i=new UO(n.d);i.e!=i.i.gc();)e=Yx(hen(i),87),r?r=!1:t.a+=tEn,wmn(e,t);t.a+=">"}null!=o&&(t.a+=""+o)}else n.e?null!=(u=n.e.zb)&&(t.a+=""+u):(t.a+="?",n.b?(t.a+=" super ",wmn(n.b,t)):n.f&&(t.a+=" extends ",wmn(n.f,t)))}function dmn(n,t,e,i){var r,c,a,u,o,s;if(c=X9(i),!ny(hL(Aun(i,(gjn(),q1n))))&&!ny(hL(Aun(n,P1n)))||dC(Yx(Aun(n,g0n),98)))switch(ZG(u=new Ion,n),t?((s=u.n).a=t.a-n.n.a,s.b=t.b-n.n.b,Hon(s,0,0,n.o.a,n.o.b),whn(u,Tpn(u,c))):(r=G7(c),whn(u,e==(h0(),i3n)?r:O9(r))),a=Yx(Aun(i,(Ojn(),bQn)),21),o=u.j,c.g){case 2:case 1:(o==(Ikn(),Tit)||o==Bit)&&a.Fc((edn(),OVn));break;case 4:case 3:(o==(Ikn(),Eit)||o==qit)&&a.Fc((edn(),OVn))}else r=G7(c),u=vpn(n,e,e==(h0(),i3n)?r:O9(r));return u}function gmn(n,t,i){var r,c,a,u,o,s,h;return e.Math.abs(t.s-t.c)h?new wz((iQ(),_4n),i,t,s-h):s>0&&h>0&&(new wz((iQ(),_4n),t,i,0),new wz(_4n,i,t,0))),a)}function pmn(n,t){var i,r,c,a,u;for(u=new t6(new Ql(n.f.b).a);u.b;){if(c=Yx((a=s1(u)).cd(),594),1==t){if(c.gf()!=(t9(),eet)&&c.gf()!=Jtt)continue}else if(c.gf()!=(t9(),Ztt)&&c.gf()!=net)continue;switch(r=Yx(Yx(a.dd(),46).b,81),i=Yx(Yx(a.dd(),46).a,189).c,c.gf().g){case 2:r.g.c=n.e.a,r.g.b=e.Math.max(1,r.g.b+i);break;case 1:r.g.c=r.g.c+i,r.g.b=e.Math.max(1,r.g.b-i);break;case 4:r.g.d=n.e.b,r.g.a=e.Math.max(1,r.g.a+i);break;case 3:r.g.d=r.g.d+i,r.g.a=e.Math.max(1,r.g.a-i)}}}function vmn(n,t){var e,i,r,c,a,u,o,s,f,l,b;for(i=new $K(bA(lbn(t).a.Kc(),new h));Vfn(i);)CO(c1((!(e=Yx(kV(i),79)).b&&(e.b=new AN(Zrt,e,4,7)),e.b),0),186)||(o=iun(Yx(c1((!e.c&&(e.c=new AN(Zrt,e,5,8)),e.c),0),82)),Rfn(e)||(a=t.i+t.g/2,u=t.j+t.f/2,f=o.i+o.g/2,l=o.j+o.f/2,(b=new Pk).a=f-a,b.b=l-u,Ecn(c=new QS(b.a,b.b),t.g,t.f),b.a-=c.a,b.b-=c.b,a=f-b.a,u=l-b.b,Ecn(s=new QS(b.a,b.b),o.g,o.f),b.a-=s.a,b.b-=s.b,f=a+b.a,l=u+b.b,x1(r=Ywn(e,!0,!0),a),R1(r,u),O1(r,f),D1(r,l),vmn(n,o)))}function mmn(n){uT(n,new tun(rk(nk(ik(ek(new du,J$n),"ELK SPOrE Compaction"),"ShrinkTree is a compaction algorithm that maintains the topology of a layout. The relocation of diagram elements is based on contracting a spanning tree."),new tu))),DU(n,J$n,Z$n,oen(x9n)),DU(n,J$n,nLn,oen($9n)),DU(n,J$n,tLn,oen(A9n)),DU(n,J$n,eLn,oen(C9n)),DU(n,J$n,iLn,oen(O9n)),DU(n,J$n,fPn,I9n),DU(n,J$n,LPn,8),DU(n,J$n,rLn,oen(N9n)),DU(n,J$n,cLn,oen(T9n)),DU(n,J$n,aLn,oen(M9n)),DU(n,J$n,oAn,(TA(),!1))}function ymn(n,t,e){var i,r,c,a,u,o,s,h;return i=n.a.o==(RG(),m4n)?JTn:ZTn,!(u=xpn(n,new TS(t,e))).a&&u.c?(KD(n.d,u),i):u.a?(r=u.a.c,o=u.a.d,e?(s=n.a.c==(Jq(),d4n)?o:r,c=n.a.c==d4n?r:o,a=n.a.g[c.i.p],h=ty(n.a.p[a.p])+ty(n.a.d[c.i.p])+c.n.b+c.a.b-ty(n.a.d[s.i.p])-s.n.b-s.a.b):(s=n.a.c==(Jq(),w4n)?o:r,c=n.a.c==w4n?r:o,h=ty(n.a.p[n.a.g[c.i.p].p])+ty(n.a.d[c.i.p])+c.n.b+c.a.b-ty(n.a.d[s.i.p])-s.n.b-s.a.b),n.a.n[n.a.g[r.i.p].p]=(TA(),!0),n.a.n[n.a.g[o.i.p].p]=!0,h):i}function kmn(n,t,e){var i,r,c,a,u,o,s;if(Lwn(n.e,t))TT(),kfn((u=Yx(t,66).Oj()?new cR(t,n):new VP(t,n)).c,u.b),TO(u,Yx(e,14));else{for(s=dwn(n.e.Tg(),t),i=Yx(n.g,119),c=0;cn.o.b)return!1;if(e=i7(n,Eit),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function Smn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(a=n.e,o=t.e,0==a)return t;if(0==o)return n;if((c=n.d)+(u=t.d)==2)return e=Gz(n.a[0],uMn),i=Gz(t.a[0],uMn),a==o?(w=WR(h=t7(e,i)),0==(b=WR(UK(h,32)))?new wQ(a,w):new C_(a,2,x4(Gy(Wot,1),MTn,25,15,[w,b]))):Utn(a<0?n7(i,e):n7(e,i));if(a==o)l=a,f=c>=u?WQ(n.a,c,t.a,u):WQ(t.a,u,n.a,c);else{if(0==(r=c!=u?c>u?1:-1:w6(n.a,t.a,c)))return bdn(),pFn;1==r?(l=a,f=GV(n.a,c,t.a,u)):(l=o,f=GV(t.a,u,n.a,c))}return SU(s=new C_(l,f.length,f)),s}function Pmn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w;return l=ny(hL(Aun(t,(gjn(),G1n)))),b=null,a==(h0(),e3n)&&r.c.i==i?b=r.c:a==i3n&&r.d.i==i&&(b=r.d),(h=u)&&l&&!b?(eD(h.e,r),w=e.Math.max(ty(fL(Aun(h.d,y1n))),ty(fL(Aun(r,y1n)))),b5(h.d,y1n,w)):(Ikn(),f=Hit,b?f=b.j:dC(Yx(Aun(i,g0n),98))&&(f=a==e3n?qit:Eit),s=function(n,t,e,i,r,c){var a,u,o,s,h,f;return a=null,s=i==(h0(),e3n)?c.c:c.d,o=X9(t),s.i==e?(a=Yx(BF(n.b,s),10))||(b5(a=Jkn(s,Yx(Aun(e,(gjn(),g0n)),98),r,function(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(r=ny(hL(Aun(u=n.i,(gjn(),I1n)))),h=0,i=0,s=new pb(n.g);s.a=n.b[r+1])r+=2;else{if(!(e=eMn?pI(e,U9(i)):KF(e,i&fTn),c=new nG(10,null,0),function(n,t,e){i_(e,n.a.c.length),QW(n.a,e,t)}(n.a,c,a-1)):(c.bm().length,pI(e=new Oy,c.bm())),0==t.e?(i=t._l())>=eMn?pI(e,U9(i)):KF(e,i&fTn):pI(e,t.bm()),Yx(c,521).b=e.a):Up(n.a,t);else for(r=0;r0&&k8(r,-6)>=0){if(k8(r,0)>=0){for(c=e+WR(r),u=h-1;u>=c;u--)f[u+1]=f[u];return f[++c]=46,o&&(f[--e]=45),Vnn(f,e,h-e+1)}for(a=2;LT(a,t7(sJ(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,o&&(f[--e]=45),Vnn(f,e,h-e)}return w=e+1,i=h,l=new $y,o&&(l.a+="-"),i-w>=1?(_F(l,f[e]),l.a+=".",l.a+=Vnn(f,e+1,h-e-1)):l.a+=Vnn(f,e,h-e),l.a+="E",k8(r,0)>0&&(l.a+="+"),l.a+=""+HK(r),l.a}(D3(n.f),oG(n.e)),n.g):(r=pjn((!n.c&&(n.c=J6(n.f)),n.c),0),0==n.e?r:(t=(!n.c&&(n.c=J6(n.f)),n.c).e<0?2:1,e=r.length,i=-n.e+e-t,(c=new Ay).a+=""+r,n.e>0&&i>=-6?i>=0?UG(c,e-oG(n.e),String.fromCharCode(46)):(c.a=l$(c.a,0,t-1)+"0."+lI(c.a,t-1),UG(c,t+1,Vnn(rFn,0,-oG(i)-1))):(e-t>=1&&(UG(c,t,String.fromCharCode(46)),++e),UG(c,e,String.fromCharCode(69)),i>0&&UG(c,++e,String.fromCharCode(43)),UG(c,++e,""+HK(D3(i)))),n.g=c.a,n.g))}function _mn(n,t,i){var r,c,a;if((c=Yx(Aun(t,(gjn(),BZn)),275))!=(uon(),mVn)){switch(run(i,"Horizontal Compaction",1),n.a=t,function(n,t){n.g=t}(r=new wfn(((a=new dJ).d=t,a.c=Yx(Aun(a.d,b1n),218),function(n){var t,e,i,r,c,a,u;for(t=!1,e=0,r=new pb(n.d.b);r.a0&&Y4(o,!0,(t9(),net)),a.k==(bon(),_zn)&&QB(o),xB(n.f,a,t)):((s=(i=Yx(fq(a7(a)),17)).c.i)==a&&(s=i.d.i),f=new mP(s,yN(dO(a.n),s.n)),xB(n.b,a,f))}(a),Fdn(a),a.a)),n.b),1===Yx(Aun(t,FZn),422).g?Uy(r,new a2(n.a)):Uy(r,(VH(),MBn)),c.g){case 1:_ln(r);break;case 2:_ln(ekn(r,(t9(),net)));break;case 3:_ln(zy(ekn(_ln(r),(t9(),net)),new gr));break;case 4:_ln(zy(ekn(_ln(r),(t9(),net)),new Gw(a)));break;case 5:_ln(function(n,t){return n.b=t,n}(r,IXn))}ekn(r,(t9(),Ztt)),r.e=!0,function(n){var t,i,r,c;for(SE(hH(new SR(null,new Nz(n.a.b,16)),new yr),new kr),function(n){var t,e,i,r,c;for(i=new t6(new Ql(n.b).a);i.b;)t=Yx((e=s1(i)).cd(),10),c=Yx(Yx(e.dd(),46).a,10),r=Yx(Yx(e.dd(),46).b,8),mN(OI(t.n),mN(dO(c.n),r))}(n),SE(hH(new SR(null,new Nz(n.a.b,16)),new jr),new Er),n.c==(g7(),bet)&&(SE(hH(WJ(new SR(null,new Nz(new Yl(n.f),1)),new Tr),new Mr),new Ww(n)),SE(hH(fH(WJ(WJ(new SR(null,new Nz(n.d.b,16)),new Sr),new Pr),new Ir),new Cr),new Qw(n))),c=new QS(JTn,JTn),t=new QS(ZTn,ZTn),r=new pb(n.a.b);r.a1&&(s=h.mg(s,n.a,o));return 1==s.c.length?Yx(TR(s,s.c.length-1),220):2==s.c.length?function(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p;return a=n.f,f=t.f,u=a==(xbn(),V8n)||a==Y8n,o=a==Q8n||a==V8n,l=f==Q8n||f==V8n,!u||f!=V8n&&f!=Y8n?a!=Q8n&&a!=J8n||f!=Q8n&&f!=J8n?o&&l?(a==Q8n?(h=n,s=t):(h=t,s=n),b=i.j+i.f,w=h.e+r.f,d=e.Math.max(b,w)-e.Math.min(i.j,h.e),c=(h.d+r.g-i.i)*d,g=i.i+i.g,p=s.d+r.g,c<=(e.Math.max(g,p)-e.Math.min(i.i,s.d))*(s.e+r.f-i.j)?n.f==Q8n?n:t:n.f==V8n?n:t):n:n.f==J8n?n:t:n.f==Y8n?n:t}(($z(0,s.c.length),Yx(s.c[0],220)),($z(1,s.c.length),Yx(s.c[1],220)),u,a):null}function Bmn(n){var t,i,r,c,a,u;for(WZ(n.a,new nt),i=new pb(n.a);i.a=e.Math.abs(r.b)?(r.b=0,a.d+a.a>u.d&&a.du.c&&a.c0){if(t=new QP(n.i,n.g),c=(e=n.i)<100?null:new Ek(e),n.ij())for(i=0;i0){for(u=n.g,s=n.i,xV(n),c=s<100?null:new Ek(s),i=0;i4){if(!n.wj(t))return!1;if(n.rk()){if(u=(e=(i=Yx(t,49)).Ug())==n.e&&(n.Dk()?i.Og(i.Vg(),n.zk())==n.Ak():-1-i.Vg()==n.aj()),n.Ek()&&!u&&!e&&i.Zg())for(r=0;r0)if(t=new t3(n.Gi()),c=(e=h)<100?null:new Ek(e),NL(n,e,t.g),r=1==e?n.Zi(4,c1(t,0),null,0,o):n.Zi(6,t,null,-1,o),n.bj()){for(i=new UO(t);i.e!=i.i.gc();)c=n.dj(hen(i),c);c?(c.Ei(r),c.Fi()):n.$i(r)}else c?(c.Ei(r),c.Fi()):n.$i(r);else NL(n,n.Vi(),n.Wi()),n.$i(n.Zi(6,(XH(),TFn),null,-1,o));else if(n.bj())if((h=n.Vi())>0){for(u=n.Wi(),s=h,NL(n,h,u),c=s<100?null:new Ek(s),i=0;i2*c?(h=new e1(f),s=DR(a)/xR(a),o=njn(h,t,new Sv,e,i,r,s),mN(OI(h.e),o),f.c=VQ(UKn,iEn,1,0,5,1),c=0,f.c[f.c.length]=h,f.c[f.c.length]=a,c=DR(h)*xR(h)+DR(a)*xR(a)):(f.c[f.c.length]=a,c+=DR(a)*xR(a));return f}(u,t,f.a,f.b,(s=r,vB(c),s));break;case 1:w=function(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(XH(),JC(n,new zu),a=nD(n),b=new ip,l=new ip,u=null,o=0;0!=a.b;)c=Yx(0==a.b?null:(S$(0!=a.b),VZ(a,a.a.a)),157),!u||DR(u)*xR(u)/21&&(o>DR(u)*xR(u)/2||0==a.b)&&(f=new e1(l),h=DR(u)/xR(u),s=njn(f,t,new Sv,e,i,r,h),mN(OI(f.e),s),u=f,b.c[b.c.length]=f,o=0,l.c=VQ(UKn,iEn,1,0,5,1)));return S4(b,l),b}(u,t,f.a,f.b,(h=r,vB(c),h));break;default:w=function(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(u=VQ(Jot,rMn,25,n.c.length,15,1),Xrn(l=new h_(new Uu),n),s=0,b=new ip;0!=l.b.c.length;)if(a=Yx(0==l.b.c.length?null:TR(l.b,0),157),s>1&&DR(a)*xR(a)/2>u[0]){for(c=0;cu[c];)++c;f=new e1(new Oz(b,0,c+1)),h=DR(a)/xR(a),o=njn(f,t,new Sv,e,i,r,h),mN(OI(f.e),o),JQ(mun(l,f)),Xrn(l,new Oz(b,c+1,b.c.length)),b.c=VQ(UKn,iEn,1,0,5,1),s=0,nK(u,u.length,0)}else null!=(0==l.b.c.length?null:TR(l.b,0))&&e2(l,0),s>0&&(u[s]=u[s-1]),u[s]+=DR(a)*xR(a),++s,b.c[b.c.length]=a;return b}(u,t,f.a,f.b,(o=r,vB(c),o))}xkn(n,(b=njn(new e1(w),t,i,f.a,f.b,r,(vB(c),c))).a,b.b,!1,!0)}function Qmn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(c=0,a=0,s=new pb(n.a);s.a.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=u.d.b)&&(p=r),d=u.d.c,p>g.a-d-h&&(p=g.a-d-h),u.n.a=t+p}}function Ymn(n,t){var e,i,r,c,a,u,o,s,h;return s="",0==t.length?n.de(oTn,aTn,-1,-1):(_N((h=Wun(t)).substr(0,3),"at ")&&(h=h.substr(3)),-1==(a=(h=h.replace(/\[.*?\]/g,"")).indexOf("("))?-1==(a=h.indexOf("@"))?(s=h,h=""):(s=Wun(h.substr(a+1)),h=Wun(h.substr(0,a))):(e=h.indexOf(")",a),s=h.substr(a+1,e-(a+1)),h=Wun(h.substr(0,a))),-1!=(a=VI(h,gun(46)))&&(h=h.substr(a+1)),(0==h.length||_N(h,"Anonymous function"))&&(h=aTn),u=LA(s,gun(58)),r=qN(s,gun(58),u-1),o=-1,i=-1,c=oTn,-1!=u&&-1!=r&&(c=s.substr(0,r),o=f$(s.substr(r+1,u-(r+1))),i=f$(s.substr(u+1))),n.de(c,h,o,i))}function Jmn(n,t,e){var i,r,c,a,u,o;if(0==t.l&&0==t.m&&0==t.h)throw hp(new Bm("divide by zero"));if(0==n.l&&0==n.m&&0==n.h)return e&&(P_n=rO(0,0,0)),rO(0,0,0);if(t.h==qTn&&0==t.m&&0==t.l)return function(n,t){return n.h==qTn&&0==n.m&&0==n.l?(t&&(P_n=rO(0,0,0)),JI((LJ(),O_n))):(t&&(P_n=rO(n.l,n.m,n.h)),rO(0,0,0))}(n,e);if(o=!1,t.h>>19!=0&&(t=h5(t),o=!o),a=function(n){var t,e,i;return 0!=((e=n.l)&e-1)||0!=((i=n.m)&i-1)||0!=((t=n.h)&t-1)||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?m0(e):0==t&&0!=i&&0==e?m0(i)+22:0!=t&&0==i&&0==e?m0(t)+44:-1}(t),c=!1,r=!1,i=!1,n.h==qTn&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return u=tln(n,a),o&&A5(u),e&&(P_n=rO(0,0,0)),u;n=JI((LJ(),I_n)),i=!0,o=!o}else n.h>>19!=0&&(c=!0,n=h5(n),i=!0,o=!o);return-1!=a?_5(n,a,o,c,e):gcn(n,t)<0?(e&&(P_n=c?h5(n):rO(n.l,n.m,n.h)),rO(0,0,0)):function(n,t,e,i,r,c){var a,u,o,s,h,f;for(a=don(t,o=E5(t)-E5(n)),u=rO(0,0,0);o>=0&&(!Irn(n,a)||(o<22?u.l|=1<>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--o;return e&&A5(u),c&&(i?(P_n=h5(n),r&&(P_n=y4(P_n,(LJ(),O_n)))):P_n=rO(n.l,n.m,n.h)),u}(i?n:rO(n.l,n.m,n.h),t,o,c,r,e)}function Zmn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(n.e&&n.c.ct.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=Yx(a.Pb(),11),V6($5(x4(Gy(B7n,1),TEn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(u=n.r.a.ec().Kc();u.Ob();)r=Yx(u.Pb(),11),V6($5(x4(Gy(B7n,1),TEn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(o=t.w.a.ec().Kc();o.Ob();)r=Yx(o.Pb(),11),V6($5(x4(Gy(B7n,1),TEn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=Yx(c.Pb(),11),V6($5(x4(Gy(B7n,1),TEn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e=0)return r=function(n,t){var e;if(CO(e=Ybn(n.Tg(),t),99))return Yx(e,18);throw hp(new Qm(mNn+t+"' is not a valid reference"))}(n,t.substr(1,c-1)),function(n,t,e){var i,r,c,a,u,o,s,h,f,l;for(o=new ip,f=t.length,a=O5(e),s=0;s=0?n._g(s,!1,!0):tfn(n,e,!1),58).Kc();c.Ob();){for(r=Yx(c.Pb(),56),h=0;h=0){i=Yx(TV(n,UZ(n,t.substr(1,e-1)),!1),58),o=0;try{o=ipn(t.substr(e+1),nTn,Yjn)}catch(n){throw CO(n=j4(n),127)?hp(new mJ(n)):hp(n)}if(o=0)return e;switch(TB(PJ(n,e))){case 2:if(_N("",U8(n,e.Hj()).ne())){if(o=$ln(n,t,u=tH(PJ(n,e)),nH(PJ(n,e))))return o;for(a=0,s=(r=Agn(n,t)).gc();a1,h=new UV(b.b);ZC(h.a)||ZC(h.b);)l=(s=Yx(ZC(h.a)?Hz(h.a):Hz(h.b),17)).c==b?s.d:s.c,e.Math.abs($5(x4(Gy(B7n,1),TEn,8,0,[l.i.n,l.n,l.a])).b-u.b)>1&&jwn(n,s,u,a,b)}}function ayn(){ayn=O,$ut=(_k(),Aut).b,xut=Yx(c1(aq(Aut.b),0),34),Lut=Yx(c1(aq(Aut.b),1),34),Nut=Yx(c1(aq(Aut.b),2),34),zut=Aut.bb,Yx(c1(aq(Aut.bb),0),34),Yx(c1(aq(Aut.bb),1),34),Xut=Aut.fb,Wut=Yx(c1(aq(Aut.fb),0),34),Yx(c1(aq(Aut.fb),1),34),Yx(c1(aq(Aut.fb),2),18),Qut=Aut.qb,Zut=Yx(c1(aq(Aut.qb),0),34),Yx(c1(aq(Aut.qb),1),18),Yx(c1(aq(Aut.qb),2),18),Yut=Yx(c1(aq(Aut.qb),3),34),Jut=Yx(c1(aq(Aut.qb),4),34),tot=Yx(c1(aq(Aut.qb),6),34),not=Yx(c1(aq(Aut.qb),5),18),Dut=Aut.j,Rut=Aut.k,Kut=Aut.q,_ut=Aut.w,Fut=Aut.B,But=Aut.A,Hut=Aut.C,qut=Aut.D,Gut=Aut._,Uut=Aut.cb,Vut=Aut.hb}function uyn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,j6(n,null)):(n.F=(vB(t),t),-1!=(i=VI(t,gun(60)))?(r=t.substr(0,i),-1==VI(t,gun(46))&&!_N(r,Xjn)&&!_N(r,BDn)&&!_N(r,HDn)&&!_N(r,qDn)&&!_N(r,GDn)&&!_N(r,zDn)&&!_N(r,UDn)&&!_N(r,XDn)&&(r=WDn),-1!=(e=LA(t,gun(62)))&&(r+=""+t.substr(e+1)),j6(n,r)):(r=t,-1==VI(t,gun(46))&&(-1!=(i=VI(t,gun(91)))&&(r=t.substr(0,i)),_N(r,Xjn)||_N(r,BDn)||_N(r,HDn)||_N(r,qDn)||_N(r,GDn)||_N(r,zDn)||_N(r,UDn)||_N(r,XDn)?r=t:(r=WDn,-1!=i&&(r+=""+t.substr(i)))),j6(n,r),r==t&&(n.F=n.D))),0!=(4&n.Db)&&0==(1&n.Db)&&K3(n,new p_(n,1,5,c,t))}function oyn(n,t){var e;if(null==t||_N(t,aEn))return null;if(0==t.length&&n.k!=(lsn(),A7n))return null;switch(n.k.g){case 1:return vtn(t,kLn)?(TA(),L_n):vtn(t,jLn)?(TA(),$_n):null;case 2:try{return d9(ipn(t,nTn,Yjn))}catch(n){if(CO(n=j4(n),127))return null;throw hp(n)}case 4:try{return gon(t)}catch(n){if(CO(n=j4(n),127))return null;throw hp(n)}case 3:return t;case 5:return F6(n),Ghn(n,t);case 6:return F6(n),function(n,t,e){var i,r,c,a,u,o,s;for(s=new cx(i=Yx(t.e&&t.e(),9),Yx(eN(i,i.length),9),0),a=0,u=(c=Ogn(e,"[\\[\\]\\s,]+")).length;a-2;default:return!1}switch(t=n.gj(),n.p){case 0:return null!=t&&ny(hL(t))!=hI(n.k,0);case 1:return null!=t&&Yx(t,217).a!=WR(n.k)<<24>>24;case 2:return null!=t&&Yx(t,172).a!=(WR(n.k)&fTn);case 6:return null!=t&&hI(Yx(t,162).a,n.k);case 5:return null!=t&&Yx(t,19).a!=WR(n.k);case 7:return null!=t&&Yx(t,184).a!=WR(n.k)<<16>>16;case 3:return null!=t&&ty(fL(t))!=n.j;case 4:return null!=t&&Yx(t,155).a!=n.j;default:return null==t?null!=n.n:!Q8(t,n.n)}}function hyn(n,t,e){var i,r,c,a;return n.Fk()&&n.Ek()&&iI(a=u_(n,Yx(e,56)))!==iI(e)?(n.Oi(t),n.Ui(t,$Y(n,0,a)),n.rk()&&(r=Yx(e,49),c=n.Dk()?n.Bk()?r.ih(n.b,nin(Yx(CZ(Cq(n.b),n.aj()),18)).n,Yx(CZ(Cq(n.b),n.aj()).Yj(),26).Bj(),null):r.ih(n.b,tnn(r.Tg(),nin(Yx(CZ(Cq(n.b),n.aj()),18))),null,null):r.ih(n.b,-1-n.aj(),null,null),!Yx(a,49).eh()&&(i=Yx(a,49),c=n.Dk()?n.Bk()?i.gh(n.b,nin(Yx(CZ(Cq(n.b),n.aj()),18)).n,Yx(CZ(Cq(n.b),n.aj()).Yj(),26).Bj(),c):i.gh(n.b,tnn(i.Tg(),nin(Yx(CZ(Cq(n.b),n.aj()),18))),null,c):i.gh(n.b,-1-n.aj(),null,c)),c&&c.Fi()),gC(n.b)&&n.$i(n.Zi(9,e,a,t,!1)),a):e}function fyn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(f=ty(fL(Aun(n,(gjn(),R0n)))),r=ty(fL(Aun(n,Y0n))),b5(b=new Yu,R0n,f+r),v=(h=t).d,g=h.c.i,m=h.d.i,p=eC(g.c),y=eC(m.c),c=new ip,l=p;l<=y;l++)Al(o=new rin(n),(bon(),Bzn)),b5(o,(Ojn(),CQn),h),b5(o,g0n,(Ran(),oit)),b5(o,_0n,b),w=Yx(TR(n.b,l),29),l==p?Hrn(o,w.a.c.length-i,w):JG(o,w),(k=ty(fL(Aun(h,y1n))))<0&&b5(h,y1n,k=0),o.o.b=k,d=e.Math.floor(k/2),whn(u=new Ion,(Ikn(),qit)),ZG(u,o),u.n.b=d,whn(s=new Ion,Eit),ZG(s,o),s.n.b=d,QG(h,u),o4(a=new jq,h),b5(a,$1n,null),YG(a,s),QG(a,v),jcn(o,h,a),c.c[c.c.length]=a,h=a;return c}function lyn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(u=Yx($on(n,(Ikn(),qit)).Kc().Pb(),11).e,f=Yx($on(n,Eit).Kc().Pb(),11).g,a=u.c.length,g=Dz(Yx(TR(n.j,0),11));a-- >0;){for($z(0,u.c.length),b=Yx(u.c[0],17),$z(0,f.c.length),r=hJ((i=Yx(f.c[0],17)).d.e,i,0),eX(b,i.d,r),YG(i,null),QG(i,null),l=b.a,t&&KD(l,new fC(g)),e=Ztn(i.a,0);e.b!=e.d.c;)KD(l,new fC(Yx(IX(e),8)));for(d=b.b,h=new pb(i.b);h.a0&&(u=e.Math.max(u,X2(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),u=e.Math.max(u,(XC(),o0(SSn),e.Math.abs(l-1)<=SSn||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),i.n.b=0,i.a.a=u}function wyn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w;if(i=Yx(GB(n.b,t),124),(s=Yx(Yx(_V(n.r,t),21),84)).dc())return i.n.d=0,void(i.n.a=0);for(h=n.u.Hc((Chn(),pit)),u=0,n.A.Hc((Ann(),nrt))&&Wdn(n,t),o=s.Kc(),f=null,b=0,l=0;o.Ob();)a=ty(fL((r=Yx(o.Pb(),111)).b.We((XA(),XHn)))),c=r.b.rf().b,f?(w=l+f.d.a+n.w+r.d.d,u=e.Math.max(u,(XC(),o0(SSn),e.Math.abs(b-a)<=SSn||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(u=e.Math.max(u,X2(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),u=e.Math.max(u,(XC(),o0(SSn),e.Math.abs(b-1)<=SSn||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),i.n.d=0,i.a.b=u}function dyn(n,t,e){var i,r,c,a,u,o;for(this.g=n,u=t.d.length,o=e.d.length,this.d=VQ(Gzn,kIn,10,u+o,0,1),a=0;a0?u1(this,this.f/this.a):null!=NO(t.g,t.d[0]).a&&null!=NO(e.g,e.d[0]).a?u1(this,(ty(NO(t.g,t.d[0]).a)+ty(NO(e.g,e.d[0]).a))/2):null!=NO(t.g,t.d[0]).a?u1(this,NO(t.g,t.d[0]).a):null!=NO(e.g,e.d[0]).a&&u1(this,NO(e.g,e.d[0]).a)}function gyn(n,t){var e,i,r,c,a,u,o,s,h;for(n.a=new HF(function(n){var t;return new cx(t=Yx(n.e&&n.e(),9),Yx(rF(t,t.length),9),t.length)}(oet)),i=new pb(t.a);i.a=1&&(g-a>0&&f>=0?(o.n.a+=d,o.n.b+=c*a):g-a<0&&h>=0&&(o.n.a+=d*g,o.n.b+=c));n.o.a=t.a,n.o.b=t.b,b5(n,(gjn(),n0n),(Ann(),new cx(i=Yx(Ak(lrt),9),Yx(eN(i,i.length),9),0)))}function myn(n){var t,e,i,r,c,a,u,o,s,h;for(i=new ip,a=new pb(n.e.a);a.a1)for(d=VQ(Wot,MTn,25,n.b.b.c.length,15,1),f=0,h=new pb(n.b.b);h.a=u&&r<=o)u<=r&&c<=o?(e[h++]=r,e[h++]=c,i+=2):u<=r?(e[h++]=r,e[h++]=o,n.b[i]=o+1,a+=2):c<=o?(e[h++]=u,e[h++]=c,i+=2):(e[h++]=u,e[h++]=o,n.b[i]=o+1);else{if(!(oZEn)&&o<10);Yy(n.c,new Et),jyn(n),function(n){ikn(n,(t9(),Ztt)),n.d=!0}(n.c),function(n){var t,i,r,c,a,u,o,s;for(a=new pb(n.a.b);a.a=2){for(a=Yx(IX(o=Ztn(e,0)),8),u=Yx(IX(o),8);u.a0&&eD(n.p,l),eD(n.o,l);d=s+(t-=r),f+=t*n.e,QW(n.a,o,d9(d)),QW(n.b,o,f),n.j=e.Math.max(n.j,d),n.k=e.Math.max(n.k,f),n.d+=t,t+=p}}(n),n.q=Yx(Aun(t,(gjn(),F1n)),260),l=Yx(Aun(n.g,_1n),19).a,a=new hi,n.q.g){case 2:case 1:default:Amn(n,a);break;case 3:for(n.q=(_bn(),G2n),Amn(n,a),s=0,o=new pb(n.a);o.an.j&&(n.q=K2n,Amn(n,a));break;case 4:for(n.q=(_bn(),G2n),Amn(n,a),f=0,c=new pb(n.b);c.an.k&&(n.q=B2n,Amn(n,a));break;case 6:Amn(n,new Aw(oG(e.Math.ceil(n.f.length*l/100))));break;case 5:Amn(n,new $w(oG(e.Math.ceil(n.d*l/100))))}(function(n,t){var e,i,r,c,a,u;for(r=new ip,e=0;e<=n.i;e++)(i=new qF(t)).p=n.i-e,r.c[r.c.length]=i;for(u=new pb(n.o);u.a=e}(this.k)}function Oyn(n,t){var e,i,r,c,a,u,o,s,f;for(u=!0,r=0,o=n.f[t.p],s=t.o.b+n.n,e=n.c[t.p][2],QW(n.a,o,d9(Yx(TR(n.a,o),19).a-1+e)),QW(n.b,o,ty(fL(TR(n.b,o)))-s+e*n.e),++o>=n.i?(++n.i,eD(n.a,d9(1)),eD(n.b,s)):(i=n.c[t.p][1],QW(n.a,o,d9(Yx(TR(n.a,o),19).a+1-i)),QW(n.b,o,ty(fL(TR(n.b,o)))+s-i*n.e)),(n.q==(_bn(),K2n)&&(Yx(TR(n.a,o),19).a>n.j||Yx(TR(n.a,o-1),19).a>n.j)||n.q==B2n&&(ty(fL(TR(n.b,o)))>n.k||ty(fL(TR(n.b,o-1)))>n.k))&&(u=!1),c=new $K(bA(u7(t).a.Kc(),new h));Vfn(c);)a=Yx(kV(c),17).c.i,n.f[a.p]==o&&(r+=Yx((f=Oyn(n,a)).a,19).a,u=u&&ny(hL(f.b)));return n.f[t.p]=o,new mP(d9(r+=n.c[t.p][0]),(TA(),!!u))}function Ayn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=new rp,u=new ip,jhn(n,i,n.d.fg(),u,l),jhn(n,r,n.d.gg(),u,l),n.b=.2*(g=dln(WJ(new SR(null,new Nz(u,16)),new Sa)),p=dln(WJ(new SR(null,new Nz(u,16)),new Pa)),e.Math.min(g,p)),a=0,o=0;o=2&&(v=Nbn(u,!0,b),!n.e&&(n.e=new xd(n)),btn(n.e,v,u,n.b)),Han(u,b),function(n){var t,i,r,c,a,u,o,s,h;for(s=new ip,u=new ip,a=new pb(n);a.a-1){for(c=new pb(u);c.a0||(Fl(o,e.Math.min(o.o,r.o-1)),_l(o,o.i-1),0==o.i&&(u.c[u.c.length]=o))}}(u),w=-1,f=new pb(u);f.ae))}(n)&&(i=(iI(Aun(n,E1n))===iI($et)?Yx(Aun(n,YZn),292):Yx(Aun(n,JZn),292))==(r4(),DVn)?($jn(),YUn):($jn(),fXn),oR(t,($un(),nzn),i)),Yx(Aun(n,c2n),377).g){case 1:oR(t,($un(),nzn),($jn(),sXn));break;case 2:yK(oR(oR(t,($un(),ZGn),($jn(),sUn)),nzn,hUn),tzn,fUn)}return iI(Aun(n,XZn))!==iI((k5(),W2n))&&oR(t,($un(),ZGn),($jn(),hXn)),t}(t)),b5(t,_Qn,Zmn(n.a,t))}function Lyn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(h=JTn,f=JTn,o=ZTn,s=ZTn,b=new pb(t.i);b.a=u&&r<=o)u<=r&&c<=o?i+=2:u<=r?(n.b[i]=o+1,a+=2):c<=o?(e[h++]=r,e[h++]=u-1,i+=2):(e[h++]=r,e[h++]=u-1,n.b[i]=o+1,a+=2);else{if(!(o0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.ue(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}(n,o,a,h=new nY(f.d,f.e)),l==a&&(l=h)),l.a[l.a[1]==f?1:0]=f.a[f.a[0]?0:1],--n.c),n.b=o.a[1],n.b&&(n.b.b=!1),e.b}function Byn(n,t,i){var r,c,a,u,o,s,h,f,l,b;if(i)for(r=-1,f=new JU(t,0);f.b0&&0==e.c&&(!t&&(t=new ip),t.c[t.c.length]=e);if(t)for(;0!=t.c.length;){if((e=Yx(KV(t,0),233)).b&&e.b.c.length>0)for(!e.b&&(e.b=new ip),c=new pb(e.b);c.ahJ(n,e,0))return new mP(r,e)}else if(ty(NO(r.g,r.d[0]).a)>ty(NO(e.g,e.d[0]).a))return new mP(r,e);for(u=(!e.e&&(e.e=new ip),e.e).Kc();u.Ob();)!(a=Yx(u.Pb(),233)).b&&(a.b=new ip),iz(0,(o=a.b).c.length),GT(o.c,0,e),a.c==o.c.length&&(t.c[t.c.length]=a)}return null}function qyn(n,t){var e,i,r,c,a,u;if(null==n)return aEn;if(null!=t.a.zc(n,t))return"[...]";for(e=new J3(tEn,"[","]"),c=0,a=(r=n).length;c=14&&u<=16?CO(i,177)?HV(e,ohn(Yx(i,177))):CO(i,190)?HV(e,Kan(Yx(i,190))):CO(i,195)?HV(e,jon(Yx(i,195))):CO(i,2012)?HV(e,_an(Yx(i,2012))):CO(i,48)?HV(e,uhn(Yx(i,48))):CO(i,364)?HV(e,Ahn(Yx(i,364))):CO(i,832)?HV(e,ahn(Yx(i,832))):CO(i,104)&&HV(e,chn(Yx(i,104))):t.a._b(i)?(e.a?yI(e.a,e.b):e.a=new SA(e.d),vI(e.a,"[...]")):HV(e,qyn(h1(i),new kR(t))):HV(e,null==i?aEn:I7(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function Gyn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g;for(w=Kon(Ywn(t,!1,!1)),r&&(w=U5(w)),g=ty(fL(jln(t,(len(),Aqn)))),S$(0!=w.b),b=Yx(w.a.a.c,8),h=Yx(ken(w,1),8),w.b>2?(S4(s=new ip,new Oz(w,1,w.b)),o4(d=new eln(yjn(s,g+n.a)),t),i.c[i.c.length]=d):d=Yx(BF(n.b,r?Kun(t):Bun(t)),266),u=Kun(t),r&&(u=Bun(t)),a=function(n,t){var i,r,c;return c=wPn,Pen(),r=bqn,c=e.Math.abs(n.b),(i=e.Math.abs(t.f-n.b))>16==-10?e=Yx(n.Cb,284).nk(t,e):n.Db>>16==-15&&(!t&&(xjn(),t=Pat),!u&&(xjn(),u=Pat),n.Cb.nh()&&(a=new yJ(n.Cb,1,13,u,t,Ren(IJ(Yx(n.Cb,59)),n),!1),e?e.Ei(a):e=a));else if(CO(n.Cb,88))n.Db>>16==-23&&(CO(t,88)||(xjn(),t=Oat),CO(u,88)||(xjn(),u=Oat),n.Cb.nh()&&(a=new yJ(n.Cb,1,10,u,t,Ren(tW(Yx(n.Cb,26)),n),!1),e?e.Ei(a):e=a));else if(CO(n.Cb,444))for(!(c=Yx(n.Cb,836)).b&&(c.b=new Xg(new Wv)),r=new Wg(new t6(new Ql(c.b.a).a));r.a.b;)e=zyn(i=Yx(s1(r.a).cd(),87),dbn(i,c),e);return e}function Uyn(n){var t,i,r,c,a,u,o,s,h,f,l,b;if((b=Yx(jln(n,(Cjn(),Jnt)),21)).dc())return null;if(o=0,u=0,b.Hc((Ann(),Zit))){for(f=Yx(jln(n,ktt),98),r=2,i=2,c=2,a=2,t=IG(n)?Yx(jln(IG(n),Pnt),103):Yx(jln(n,Pnt),103),h=new UO((!n.c&&(n.c=new m_(oct,n,9,9)),n.c));h.e!=h.i.gc();)if(s=Yx(hen(h),118),(l=Yx(jln(s,Itt),61))==(Ikn(),Hit)&&(l=Zpn(s,t),Aen(s,Itt,l)),f==(Ran(),oit))switch(l.g){case 1:r=e.Math.max(r,s.i+s.g);break;case 2:i=e.Math.max(i,s.j+s.f);break;case 3:c=e.Math.max(c,s.i+s.g);break;case 4:a=e.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:i+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}o=e.Math.max(r,c),u=e.Math.max(i,a)}return xkn(n,o,u,!0,!0)}function Xyn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(m=Yx(kW(HZ(hH(new SR(null,new Nz(t.d,16)),new td(i)),new ed(i)),mY(new H,new B,new rn,x4(Gy(wBn,1),XEn,132,0,[(C6(),aBn)]))),15),l=Yjn,f=nTn,s=new pb(t.b.j);s.a0)?s&&(h=d.p,a?++h:--h,f=!(Rbn(i=o5(Yx(TR(d.c.a,h),10)),y,e[0])||r_(i,y,e[0]))):f=!0),l=!1,(m=t.D.i)&&m.c&&u.e&&(a&&m.p>0||!a&&m.p0&&(t.a+=tEn),Jyn(Yx(hen(a),160),t);for(t.a+=pIn,u=new a$((!i.c&&(i.c=new AN(Zrt,i,5,8)),i.c));u.e!=u.i.gc();)u.e>0&&(t.a+=tEn),Jyn(Yx(hen(u),160),t);t.a+=")"}}}function Zyn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(c=Yx(Aun(n,(Ojn(),CQn)),79)){for(i=n.a,mN(r=new fC(e),function(n){var t,e,i,r;if(r=Yx(Aun(n,(Ojn(),nQn)),37)){for(i=new Pk,t=dB(n.c.i);t!=r;)t=dB(e=t.e),$$(mN(mN(i,e.n),t.c),t.d.b,t.d.d);return i}return nUn}(n)),_3(n.d.i,n.c.i)?(l=n.c,yN(f=$5(x4(Gy(B7n,1),TEn,8,0,[l.n,l.a])),e)):f=Dz(n.c),VW(i,f,i.a,i.a.a),b=Dz(n.d),null!=Aun(n,YQn)&&mN(b,Yx(Aun(n,YQn),8)),VW(i,b,i.c.b,i.c),o1(i,r),L0(a=Ywn(c,!0,!0),Yx(c1((!c.b&&(c.b=new AN(Zrt,c,4,7)),c.b),0),82)),N0(a,Yx(c1((!c.c&&(c.c=new AN(Zrt,c,5,8)),c.c),0),82)),wvn(i,a),h=new pb(n.b);h.aa?1:QI(isNaN(0),isNaN(a)))<0&&(o0(UAn),(e.Math.abs(a-1)<=UAn||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:QI(isNaN(a),isNaN(1)))<0)&&(o0(UAn),(e.Math.abs(0-u)<=UAn||0==u||isNaN(0)&&isNaN(u)?0:0u?1:QI(isNaN(0),isNaN(u)))<0)&&(o0(UAn),(e.Math.abs(u-1)<=UAn||1==u||isNaN(u)&&isNaN(1)?0:u<1?-1:u>1?1:QI(isNaN(u),isNaN(1)))<0))}function tkn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m;if(p=function(n,t,e){var i,r,c,a,u,o,s,h;for(h=new ip,c=0,c0(s=new dU(0,e),new n6(0,0,s,e)),r=0,o=new UO(n);o.e!=o.i.gc();)u=Yx(hen(o),33),i=Yx(TR(s.a,s.a.c.length-1),187),r+u.g+(0==Yx(TR(s.a,0),187).b.c.length?0:e)>t&&(r=0,c+=s.b+e,h.c[h.c.length]=s,c0(s=new dU(c,e),i=new n6(0,s.f,s,e)),r=0),0==i.b.c.length||u.f>=i.o&&u.f<=i.f||.5*i.a<=u.f&&1.5*i.a>=u.f?l7(i,u):(c0(s,a=new n6(i.s+i.r+e,s.f,s,e)),l7(a,u)),r=u.i+u.g;return h.c[h.c.length]=s,h}(t,i,n.g),c.n&&c.n&&a&&nU(c,RU(a),(P6(),jrt)),n.b)for(g=0;g0?n.g:0),++i;n.c=c,n.d=r}(n,p),c.n&&c.n&&a&&nU(c,RU(a),(P6(),jrt)),m=e.Math.max(n.d,r.a-(u.b+u.c)),o=(l=e.Math.max(n.c,r.b-(u.d+u.a)))-n.c,n.e&&n.f&&(m/l0&&(n.c[t.c.p][t.p].d+=Xln(n.i,24)*jMn*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function okn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(E=0,w=0,l=new pb(t.e);l.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o));if(i)for(u=new pb(m.e);u.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o))}o>0&&(E+=b/o,++w)}w>0?(t.a=c*E/w,t.g=w):(t.a=0,t.g=0)}function skn(n,t){var i,r,c,a,u,o,s,h,f,l;for(r=new pb(n.a.b);r.aZTn||t.o==v4n&&hr.d,r.d=e.Math.max(r.d,t),o&&i&&(r.d=e.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:i=t>r.a,r.a=e.Math.max(r.a,t),o&&i&&(r.a=e.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:i=t>r.c,r.c=e.Math.max(r.c,t),o&&i&&(r.c=e.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:i=t>r.b,r.b=e.Math.max(r.b,t),o&&i&&(r.b=e.Math.max(r.b,r.c),r.c=r.b+c)}}}(o),function(n){switch(n.q.g){case 5:Rcn(n,(Ikn(),Tit)),Rcn(n,Bit);break;case 4:byn(n,(Ikn(),Tit)),byn(n,Bit);break;default:Tsn(n,(Ikn(),Tit)),Tsn(n,Bit)}}(o),function(n){switch(n.q.g){case 5:Kcn(n,(Ikn(),Eit)),Kcn(n,qit);break;case 4:wyn(n,(Ikn(),Eit)),wyn(n,qit);break;default:Msn(n,(Ikn(),Eit)),Msn(n,qit)}}(o),function(n){var t,e,i,r,c,a,u;if(!n.A.dc()){if(n.A.Hc((Ann(),Zit))&&(Yx(GB(n.b,(Ikn(),Tit)),124).k=!0,Yx(GB(n.b,Bit),124).k=!0,t=n.q!=(Ran(),sit)&&n.q!=oit,Il(Yx(GB(n.b,Eit),124),t),Il(Yx(GB(n.b,qit),124),t),Il(n.g,t),n.A.Hc(nrt)&&(Yx(GB(n.b,Tit),124).j=!0,Yx(GB(n.b,Bit),124).j=!0,Yx(GB(n.b,Eit),124).k=!0,Yx(GB(n.b,qit),124).k=!0,n.g.k=!0)),n.A.Hc(Jit))for(n.a.j=!0,n.a.k=!0,n.g.j=!0,n.g.k=!0,u=n.B.Hc((Vgn(),ort)),c=0,a=(r=Xtn()).length;c0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}b5(n,(Ojn(),KQn),s)}if(o=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=fit&&t!=lit&&u!=Hit)switch(u.g){case 1:a.a=o.a/2;break;case 2:a.a=o.a,a.b=o.b/2;break;case 3:a.a=o.a/2,a.b=o.b;break;case 4:a.b=o.b/2}else a.a=o.a/2,a.b=o.b/2}(s,c,r,Yx(jln(t,w0n),8)),o=new UO((!t.n&&(t.n=new m_(act,t,1,7)),t.n));o.e!=o.i.gc();)!ny(hL(jln(u=Yx(hen(o),137),r0n)))&&u.a&&eD(s.f,d8(u));switch(r.g){case 2:case 1:(s.j==(Ikn(),Tit)||s.j==Bit)&&i.Fc((edn(),OVn));break;case 4:case 3:(s.j==(Ikn(),Eit)||s.j==qit)&&i.Fc((edn(),OVn))}return s}function gkn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m;for(l=null,r==(Yq(),X4n)?l=t:r==W4n&&(l=i),d=l.a.ec().Kc();d.Ob();){for(w=Yx(d.Pb(),11),g=$5(x4(Gy(B7n,1),TEn,8,0,[w.i.n,w.n,w.a])).b,m=new Qp,o=new Qp,h=new UV(w.b);ZC(h.a)||ZC(h.b);)if(ny(hL(Aun(s=Yx(ZC(h.a)?Hz(h.a):Hz(h.b),17),(Ojn(),HQn))))==c&&-1!=hJ(a,s,0)){if(p=s.d==w?s.c:s.d,v=$5(x4(Gy(B7n,1),TEn,8,0,[p.i.n,p.n,p.a])).b,e.Math.abs(v-g)<.2)continue;v1)for(XW(m,new PS(n,b=new qmn(w,m,r))),u.c[u.c.length]=b,f=m.a.ec().Kc();f.Ob();)uJ(a,Yx(f.Pb(),46).b);if(o.a.gc()>1)for(XW(o,new IS(n,b=new qmn(w,o,r))),u.c[u.c.length]=b,f=o.a.ec().Kc();f.Ob();)uJ(a,Yx(f.Pb(),46).b)}}function pkn(n){uT(n,new tun(tk(rk(nk(ik(ek(new du,C$n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Ha),C$n))),DU(n,C$n,AAn,oen(V6n)),DU(n,C$n,LPn,oen(J6n)),DU(n,C$n,HPn,oen(H6n)),DU(n,C$n,eIn,oen(q6n)),DU(n,C$n,BPn,oen(G6n)),DU(n,C$n,qPn,oen(B6n)),DU(n,C$n,FPn,oen(z6n)),DU(n,C$n,GPn,oen(W6n)),DU(n,C$n,M$n,oen(_6n)),DU(n,C$n,T$n,oen(F6n)),DU(n,C$n,I$n,oen(U6n)),DU(n,C$n,j$n,oen(X6n)),DU(n,C$n,E$n,oen(Q6n)),DU(n,C$n,S$n,oen(Y6n)),DU(n,C$n,P$n,oen(Z6n))}function vkn(n){var t;if(this.r=function(n,t){return new Mq(Yx(MF(n),62),Yx(MF(t),62))}(new Pn,new In),this.b=new C7(Yx(MF(trt),290)),this.p=new C7(Yx(MF(trt),290)),this.i=new C7(Yx(MF(JHn),290)),this.e=n,this.o=new fC(n.rf()),this.D=n.Df()||ny(hL(n.We((Cjn(),Fnt)))),this.A=Yx(n.We((Cjn(),Jnt)),21),this.B=Yx(n.We(itt),21),this.q=Yx(n.We(ktt),98),this.u=Yx(n.We(Mtt),21),!function(n){return Chn(),!(V3(sG(tK(pit,x4(Gy(Git,1),XEn,273,0,[mit])),n))>1||V3(sG(tK(git,x4(Gy(Git,1),XEn,273,0,[dit,yit])),n))>1)}(this.u))throw hp(new ly("Invalid port label placement: "+this.u));if(this.v=ny(hL(n.We(Ptt))),this.j=Yx(n.We(Qnt),21),!function(n){return Eln(),!(V3(sG(tK(Xet,x4(Gy(cit,1),XEn,93,0,[Wet])),n))>1||V3(sG(tK(Get,x4(Gy(cit,1),XEn,93,0,[qet,Uet])),n))>1||V3(sG(tK(Yet,x4(Gy(cit,1),XEn,93,0,[Qet,Vet])),n))>1)}(this.j))throw hp(new ly("Invalid node label placement: "+this.j));this.n=Yx(zrn(n,Wnt),116),this.k=ty(fL(zrn(n,Gtt))),this.d=ty(fL(zrn(n,qtt))),this.w=ty(fL(zrn(n,Ytt))),this.s=ty(fL(zrn(n,ztt))),this.t=ty(fL(zrn(n,Utt))),this.C=Yx(zrn(n,Vtt),142),this.c=2*this.d,t=!this.B.Hc((Vgn(),irt)),this.f=new Stn(0,t,0),this.g=new Stn(1,t,0),Nm(this.f,(JZ(),cHn),this.g)}function mkn(n){var t,e,i,r,c,a,u,o,s,h,f;if(null==n)throw hp(new Iy(aEn));if(s=n,o=!1,(c=n.length)>0&&(Lz(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(n=n.substr(1),--c,o=45==t)),0==c)throw hp(new Iy(YTn+s+'"'));for(;n.length>0&&(Lz(0,n.length),48==n.charCodeAt(0));)n=n.substr(1),--c;if(c>(Lpn(),Q_n)[10])throw hp(new Iy(YTn+s+'"'));for(r=0;r0&&(f=-parseInt(n.substr(0,i),10),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt(n.substr(0,a),10),n=n.substr(a),c-=a,e)e=!1;else{if(k8(f,u)<0)throw hp(new Iy(YTn+s+'"'));f=e7(f,h)}f=n7(f,i)}if(k8(f,0)>0)throw hp(new Iy(YTn+s+'"'));if(!o&&k8(f=sJ(f),0)<0)throw hp(new Iy(YTn+s+'"'));return f}function ykn(n,t){var e,i,r,c,a,u,o;if(YD(),this.a=new yO(this),this.b=n,this.c=t,this.f=G_(PJ((wsn(),wut),t)),this.f.dc())if((u=Dcn(wut,n))==t)for(this.e=!0,this.d=new ip,this.f=new fo,this.f.Fc(BRn),Yx(Imn(SJ(wut,i1(n)),""),26)==n&&this.f.Fc(OK(wut,i1(n))),r=$gn(wut,n).Kc();r.Ob();)switch(i=Yx(r.Pb(),170),TB(PJ(wut,i))){case 4:this.d.Fc(i);break;case 5:this.f.Gc(G_(PJ(wut,i)))}else if(TT(),Yx(t,66).Oj())for(this.e=!0,this.f=null,this.d=new ip,a=0,o=(null==n.i&&svn(n),n.i).length;a=0&&a0&&(Yx(GB(n.b,t),124).a.b=i)}function jkn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if((f=t.length)>0&&(Lz(0,t.length),64!=(u=t.charCodeAt(0)))){if(37==u&&(o=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(Lz(h+1,t.length),o=46==t.charCodeAt(h+1))))){if(v=_N("%",a=t.substr(1,h-1))?null:$kn(a),i=0,o)try{i=ipn(t.substr(h+2),nTn,Yjn)}catch(n){throw CO(n=j4(n),127)?hp(new mJ(n)):hp(n)}for(d=b2(n.Wg());d.Ob();)if(CO(b=X3(d),510)&&(p=(r=Yx(b,590)).d,(null==v?null==p:_N(v,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:t.substr(0,s),e=0,-1!=s)try{e=ipn(t.substr(s+1),nTn,Yjn)}catch(n){if(!CO(n=j4(n),127))throw hp(n);l=t}for(l=_N("%",l)?null:$kn(l),w=b2(n.Wg());w.Ob();)if(CO(b=X3(w),191)&&(g=(c=Yx(b,191)).ne(),(null==l?null==g:_N(l,g))&&0==e--))return c;return null}return eyn(n,t)}function Ekn(){var n,t,e;for(Ekn=O,new ZJ(1,0),new ZJ(10,0),new ZJ(0,0),iFn=VQ(vFn,TEn,240,11,0,1),rFn=VQ(Xot,sTn,25,100,15,1),cFn=x4(Gy(Jot,1),rMn,25,15,[1,5,25,125,625,3125,15625,78125,390625,1953125,9765625,48828125,244140625,1220703125,6103515625,30517578125,152587890625,762939453125,3814697265625,19073486328125,95367431640625,476837158203125,0x878678326eac9]),aFn=VQ(Wot,MTn,25,cFn.length,15,1),uFn=x4(Gy(Jot,1),rMn,25,15,[1,10,100,hTn,1e4,cMn,1e6,1e7,1e8,UTn,1e10,1e11,1e12,1e13,1e14,1e15,1e16]),oFn=VQ(Wot,MTn,25,uFn.length,15,1),sFn=VQ(vFn,TEn,240,11,0,1),n=0;nr+2&&a5((Lz(r+1,n.length),n.charCodeAt(r+1)),Gct,zct)&&a5((Lz(r+2,n.length),n.charCodeAt(r+2)),Gct,zct))if(e=$D((Lz(r+1,n.length),n.charCodeAt(r+1)),(Lz(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[u++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[u++]=e<<24>>24,i=2):224==(240&e)?(t[u++]=e<<24>>24,i=3):240==(248&e)&&(t[u++]=e<<24>>24,i=4)),i>0){if(u==i){switch(u){case 2:_F(o,((31&t[0])<<6|63&t[1])&fTn);break;case 3:_F(o,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&fTn)}u=0,i=0}}else{for(c=0;c0){if(a+i>n.length)return!1;u=Uhn(n.substr(0,a+i),t)}else u=Uhn(n,t);switch(c){case 71:return u=wun(n,a,x4(Gy(fFn,1),TEn,2,6,[STn,PTn]),t),r.e=u,!0;case 77:case 76:return function(n,t,e,i,r){return i<0?((i=wun(n,r,x4(Gy(fFn,1),TEn,2,6,[lTn,bTn,wTn,dTn,gTn,pTn,vTn,mTn,yTn,kTn,jTn,ETn]),t))<0&&(i=wun(n,r,x4(Gy(fFn,1),TEn,2,6,["Jan","Feb","Mar","Apr",gTn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}(n,t,r,u,a);case 69:case 99:return function(n,t,e,i){var r;return(r=wun(n,e,x4(Gy(fFn,1),TEn,2,6,[ITn,CTn,OTn,ATn,$Tn,LTn,NTn]),t))<0&&(r=wun(n,e,x4(Gy(fFn,1),TEn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]),t)),!(r<0||(i.d=r,0))}(n,t,a,r);case 97:return u=wun(n,a,x4(Gy(fFn,1),TEn,2,6,["AM","PM"]),t),r.b=u,!0;case 121:return function(n,t,e,i,r,c){var a,u,o;if(u=32,i<0){if(t[0]>=n.length)return!1;if(43!=(u=XB(n,t[0]))&&45!=u)return!1;if(++t[0],(i=Uhn(n,t))<0)return!1;45==u&&(i=-i)}return 32==u&&t[0]-e==2&&2==r.b&&(a=(o=(new uE).q.getFullYear()-TTn+TTn-80)%100,c.a=i==a,i+=100*(o/100|0)+(i3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}(u,a,t[0],r);case 104:12==u&&(u=0);case 75:case 72:return!(u<0||(r.f=u,r.g=!1,0));case 107:return!(u<0||(r.f=u,r.g=!0,0));case 109:return!(u<0||(r.j=u,0));case 115:return!(u<0||(r.n=u,0));case 90:if(a=0&&_N(n.substr(t,3),"GMT")||t>=0&&_N(n.substr(t,3),"UTC")?(e[0]=t+3,apn(n,e,i)):apn(n,e,i)}(n,a,t,r);default:return!1}}function Nkn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(n.e.a.$b(),n.f.a.$b(),n.c.c=VQ(UKn,iEn,1,0,5,1),n.i.c=VQ(UKn,iEn,1,0,5,1),n.g.a.$b(),t)for(a=new pb(t.a);a.a=1&&(j-h>0&&d>=0?(L1(l,l.i+k),N1(l,l.j+s*h)):j-h<0&&w>=0&&(L1(l,l.i+k*j),N1(l,l.j+s)));return Aen(n,(Cjn(),Jnt),(Ann(),new cx(a=Yx(Ak(lrt),9),Yx(eN(a,a.length),9),0))),new QS(E,f)}function Dkn(n){var t,i,r,c,a,u,o,s,h,f,l;if(f=IG(iun(Yx(c1((!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b),0),82)))==IG(iun(Yx(c1((!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c),0),82))),u=new Pk,(t=Yx(jln(n,(L6(),Met)),74))&&t.b>=2){if(0==(!n.a&&(n.a=new m_(tct,n,6,6)),n.a).i)xk(),i=new co,fY((!n.a&&(n.a=new m_(tct,n,6,6)),n.a),i);else if((!n.a&&(n.a=new m_(tct,n,6,6)),n.a).i>1)for(l=new a$((!n.a&&(n.a=new m_(tct,n,6,6)),n.a));l.e!=l.i.gc();)tan(l);wvn(t,Yx(c1((!n.a&&(n.a=new m_(tct,n,6,6)),n.a),0),202))}if(f)for(r=new UO((!n.a&&(n.a=new m_(tct,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new UO((!(i=Yx(hen(r),202)).a&&(i.a=new XO(Qrt,i,5)),i.a));s.e!=s.i.gc();)o=Yx(hen(s),469),u.a=e.Math.max(u.a,o.a),u.b=e.Math.max(u.b,o.b);for(a=new UO((!n.n&&(n.n=new m_(act,n,1,7)),n.n));a.e!=a.i.gc();)c=Yx(hen(a),137),(h=Yx(jln(c,Aet),8))&&jC(c,h.a,h.b),f&&(u.a=e.Math.max(u.a,c.i+c.g),u.b=e.Math.max(u.b,c.j+c.f));return u}function Rkn(n,t,e){var i,r,c,a,u;switch(i=t.i,c=n.i.o,r=n.i.d,u=n.n,a=$5(x4(Gy(B7n,1),TEn,8,0,[u,n.a])),n.j.g){case 1:OL(t,(OJ(),pHn)),i.d=-r.d-e-i.a,Yx(Yx(TR(t.d,0),181).We((Ojn(),kQn)),285)==(Frn(),Ret)?(lY(t,(BY(),lHn)),i.c=a.a-ty(fL(Aun(n,PQn)))-e-i.b):(lY(t,(BY(),fHn)),i.c=a.a+ty(fL(Aun(n,PQn)))+e);break;case 2:lY(t,(BY(),fHn)),i.c=c.a+r.c+e,Yx(Yx(TR(t.d,0),181).We((Ojn(),kQn)),285)==(Frn(),Ret)?(OL(t,(OJ(),pHn)),i.d=a.b-ty(fL(Aun(n,PQn)))-e-i.a):(OL(t,(OJ(),mHn)),i.d=a.b+ty(fL(Aun(n,PQn)))+e);break;case 3:OL(t,(OJ(),mHn)),i.d=c.b+r.a+e,Yx(Yx(TR(t.d,0),181).We((Ojn(),kQn)),285)==(Frn(),Ret)?(lY(t,(BY(),lHn)),i.c=a.a-ty(fL(Aun(n,PQn)))-e-i.b):(lY(t,(BY(),fHn)),i.c=a.a+ty(fL(Aun(n,PQn)))+e);break;case 4:lY(t,(BY(),lHn)),i.c=-r.b-e-i.b,Yx(Yx(TR(t.d,0),181).We((Ojn(),kQn)),285)==(Frn(),Ret)?(OL(t,(OJ(),pHn)),i.d=a.b-ty(fL(Aun(n,PQn)))-e-i.a):(OL(t,(OJ(),mHn)),i.d=a.b+ty(fL(Aun(n,PQn)))+e)}}function Kkn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O;for(w=0,S=0,s=new pb(n);s.aw&&(a&&(EI(j,b),EI(T,d9(h.b-1))),C=i.b,O+=b+t,b=0,f=e.Math.max(f,i.b+i.c+I)),L1(o,C),N1(o,O),f=e.Math.max(f,C+I+i.c),b=e.Math.max(b,l),C+=I+t;if(f=e.Math.max(f,r),(P=O+b+i.a)o&&(y=0,k+=u+v,u=0),zgn(g,i,y,k),t=e.Math.max(t,y+p.a),u=e.Math.max(u,p.b),y+=p.a+v;return g}function Fkn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;switch(h=new Nv,n.a.g){case 3:l=Yx(Aun(t.e,(Ojn(),WQn)),15),b=Yx(Aun(t.j,WQn),15),w=Yx(Aun(t.f,WQn),15),e=Yx(Aun(t.e,UQn),15),i=Yx(Aun(t.j,UQn),15),r=Yx(Aun(t.f,UQn),15),S4(a=new ip,l),b.Jc(new yc),S4(a,CO(b,152)?RV(Yx(b,152)):CO(b,131)?Yx(b,131).a:CO(b,54)?new Tm(b):new rE(b)),S4(a,w),S4(c=new ip,e),S4(c,CO(i,152)?RV(Yx(i,152)):CO(i,131)?Yx(i,131).a:CO(i,54)?new Tm(i):new rE(i)),S4(c,r),b5(t.f,WQn,a),b5(t.f,UQn,c),b5(t.f,VQn,t.f),b5(t.e,WQn,null),b5(t.e,UQn,null),b5(t.j,WQn,null),b5(t.j,UQn,null);break;case 1:C2(h,t.e.a),KD(h,t.i.n),C2(h,I3(t.j.a)),KD(h,t.a.n),C2(h,t.f.a);break;default:C2(h,t.e.a),C2(h,I3(t.j.a)),C2(h,t.f.a)}BH(t.f.a),C2(t.f.a,h),YG(t.f,t.e.c),u=Yx(Aun(t.e,(gjn(),$1n)),74),s=Yx(Aun(t.j,$1n),74),o=Yx(Aun(t.f,$1n),74),(u||s||o)&&(H_(f=new Nv,o),H_(f,s),H_(f,u),b5(t.f,$1n,f)),YG(t.j,null),QG(t.j,null),YG(t.e,null),QG(t.e,null),JG(t.a,null),JG(t.i,null),t.g&&Fkn(n,t.g)}function Bkn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;return y=n.c[($z(0,t.c.length),Yx(t.c[0],17)).p],T=n.c[($z(1,t.c.length),Yx(t.c[1],17)).p],!(y.a.e.e-y.a.a-(y.b.e.e-y.b.a)==0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)==0||!CO(v=y.b.e.f,10)||(p=Yx(v,10),j=n.i[p.p],E=p.c?hJ(p.c.a,p,0):-1,a=JTn,E>0&&(c=Yx(TR(p.c.a,E-1),10),u=n.i[c.p],M=e.Math.ceil(lO(n.n,c,p)),a=j.a.e-p.d.d-(u.a.e+c.o.b+c.d.a)-M),h=JTn,E0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)<0,d=y.a.e.e-y.a.a-(y.b.e.e-y.b.a)<0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)>0,w=y.a.e.e+y.b.aT.b.e.e+T.a.a,k=0,!g&&!d&&(b?a+l>0?k=l:h-r>0&&(k=r):w&&(a+o>0?k=o:h-m>0&&(k=m))),j.a.e+=k,j.b&&(j.d.e+=k),1)))}function Hkn(n,t,i){var r,c,a,u,o,s,h,f,l,b;if(r=new mH(t.qf().a,t.qf().b,t.rf().a,t.rf().b),c=new hC,n.c)for(u=new pb(t.wf());u.a=2&&(i=Yx(r.Kc().Pb(),111),e=n.u.Hc((Chn(),git)),c=n.u.Hc(yit),!i.a&&!e&&(2==r.gc()||c))}(n,t),e=n.u.Hc((Chn(),dit)),o=s.Kc();o.Ob();)if((u=Yx(o.Pb(),111)).c&&!(u.c.d.c.length<=0)){switch(l=u.b.rf(),(f=(h=u.c).i).b=(c=h.n,h.e.a+c.b+c.c),f.a=(r=h.n,h.e.b+r.d+r.a),t.g){case 1:u.a?(f.c=(l.a-f.b)/2,lY(h,(BY(),hHn))):a||e?(f.c=-f.b-n.s,lY(h,(BY(),lHn))):(f.c=l.a+n.s,lY(h,(BY(),fHn))),f.d=-f.a-n.t,OL(h,(OJ(),pHn));break;case 3:u.a?(f.c=(l.a-f.b)/2,lY(h,(BY(),hHn))):a||e?(f.c=-f.b-n.s,lY(h,(BY(),lHn))):(f.c=l.a+n.s,lY(h,(BY(),fHn))),f.d=l.b+n.t,OL(h,(OJ(),mHn));break;case 2:u.a?(i=n.v?f.a:Yx(TR(h.d,0),181).rf().b,f.d=(l.b-i)/2,OL(h,(OJ(),vHn))):a||e?(f.d=-f.a-n.t,OL(h,(OJ(),pHn))):(f.d=l.b+n.t,OL(h,(OJ(),mHn))),f.c=l.a+n.s,lY(h,(BY(),fHn));break;case 4:u.a?(i=n.v?f.a:Yx(TR(h.d,0),181).rf().b,f.d=(l.b-i)/2,OL(h,(OJ(),vHn))):a||e?(f.d=-f.a-n.t,OL(h,(OJ(),pHn))):(f.d=l.b+n.t,OL(h,(OJ(),mHn))),f.c=-f.b-n.s,lY(h,(BY(),lHn))}a=!1}}function Gkn(n,t){var e,i,r,c,a,u,o,s,h,f,l;if(Ljn(),0==hE(vot)){for(f=VQ(Got,TEn,117,yot.length,0,1),a=0;as&&(i.a+=IO(VQ(Xot,sTn,25,-s,15,1))),i.a+="Is",VI(o,gun(32))>=0)for(r=0;r=i.o.b/2}p?(g=Yx(Aun(i,(Ojn(),JQn)),15))?l?c=g:(r=Yx(Aun(i,QVn),15))?c=g.gc()<=r.gc()?g:r:(c=new ip,b5(i,QVn,c)):(c=new ip,b5(i,JQn,c)):(r=Yx(Aun(i,(Ojn(),QVn)),15))?f?c=r:(g=Yx(Aun(i,JQn),15))?c=r.gc()<=g.gc()?r:g:(c=new ip,b5(i,JQn,c)):(c=new ip,b5(i,QVn,c)),c.Fc(n),b5(n,(Ojn(),JVn),e),t.d==e?(QG(t,null),e.e.c.length+e.g.c.length==0&&ZG(e,null),function(n){var t,e;(t=Yx(Aun(n,(Ojn(),RQn)),10))&&(uJ((e=t.c).a,t),0==e.a.c.length&&uJ(dB(t).b,e))}(e)):(YG(t,null),e.e.c.length+e.g.c.length==0&&ZG(e,null)),BH(t.a)}function Ukn(n,t,i){var r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$;for(run(i,"MinWidth layering",1),d=t.b,M=t.a,$=Yx(Aun(t,(gjn(),R1n)),19).a,o=Yx(Aun(t,K1n),19).a,n.b=ty(fL(Aun(t,N0n))),n.d=JTn,j=new pb(M);j.a0){for(l=h<100?null:new Ek(h),w=new t3(t).g,g=VQ(Wot,MTn,25,h,15,1),i=0,m=new FZ(h),r=0;r=0;)if(null!=b?Q8(b,w[o]):iI(b)===iI(w[o])){g.length<=i&&smn(g,0,g=VQ(Wot,MTn,25,2*g.length,15,1),0,i),g[i++]=r,fY(m,w[o]);break n}if(iI(b)===iI(u))break}}if(s=m,w=m.g,h=i,i>g.length&&smn(g,0,g=VQ(Wot,MTn,25,i,15,1),0,i),i>0){for(v=!0,c=0;c=0;)Orn(n,g[a]);if(i!=h){for(r=h;--r>=i;)Orn(s,r);smn(g,0,g=VQ(Wot,MTn,25,i,15,1),0,i)}t=s}}}else for(t=function(n,t){var e,i,r;if(t.dc())return iL(),iL(),$ct;for(e=new HL(n,t.gc()),r=new UO(n);r.e!=r.i.gc();)i=hen(r),t.Hc(i)&&fY(e,i);return e}(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(Orn(n,r),v=!0);if(v){if(null!=g){for(f=1==(e=t.gc())?zG(n,4,t.Kc().Pb(),null,g[0],d):zG(n,6,t,g,g[0],d),l=e<100?null:new Ek(e),r=t.Kc();r.Ob();)l=JN(n,Yx(b=r.Pb(),72),l);l?(l.Ei(f),l.Fi()):K3(n.e,f)}else{for(l=function(n){return n<100?null:new Ek(n)}(t.gc()),r=t.Kc();r.Ob();)l=JN(n,Yx(b=r.Pb(),72),l);l&&l.Fi()}return!0}return!1}function Wkn(n,t){var i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y;for((i=new Fen(t)).a||function(n){var t,i,r,c,a;switch(c=Yx(TR(n.a,0),10),t=new rin(n),eD(n.a,t),t.o.a=e.Math.max(1,c.o.a),t.o.b=e.Math.max(1,c.o.b),t.n.a=c.n.a,t.n.b=c.n.b,Yx(Aun(c,(Ojn(),hQn)),61).g){case 4:t.n.a+=2;break;case 1:t.n.b+=2;break;case 2:t.n.a-=2;break;case 3:t.n.b-=2}ZG(r=new Ion,t),YG(i=new jq,a=Yx(TR(c.j,0),11)),QG(i,r),mN(OI(r.n),a.n),mN(OI(r.a),a.a)}(t),f=function(n){var t,e,i,r,c,a,u;for(u=new rV,a=new pb(n.a);a.a=u.b.c)&&(u.b=t),(!u.c||t.c<=u.c.c)&&(u.d=u.c,u.c=t),(!u.e||t.d>=u.e.d)&&(u.e=t),(!u.f||t.d<=u.f.d)&&(u.f=t);return i=new ben((_4(),bzn)),$U(n,jzn,new ay(x4(Gy(lzn,1),iEn,369,0,[i]))),a=new ben(gzn),$U(n,kzn,new ay(x4(Gy(lzn,1),iEn,369,0,[a]))),r=new ben(wzn),$U(n,yzn,new ay(x4(Gy(lzn,1),iEn,369,0,[r]))),c=new ben(dzn),$U(n,mzn,new ay(x4(Gy(lzn,1),iEn,369,0,[c]))),kbn(i.c,bzn),kbn(r.c,wzn),kbn(c.c,dzn),kbn(a.c,gzn),u.a.c=VQ(UKn,iEn,1,0,5,1),S4(u.a,i.c),S4(u.a,I3(r.c)),S4(u.a,c.c),S4(u.a,I3(a.c)),u}(f)),i}function Vkn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(null==i.p[t.p]){o=!0,i.p[t.p]=0,u=t,d=i.o==(RG(),v4n)?ZTn:JTn;do{c=n.b.e[u.p],a=u.c.a.c.length,i.o==v4n&&c>0||i.o==m4n&&c(a=uan(n,e))?mgn(n,t,e):mgn(n,e,t),ra?1:0}return(i=Yx(Aun(t,(Ojn(),IQn)),19).a)>(c=Yx(Aun(e,IQn),19).a)?mgn(n,t,e):mgn(n,e,t),ic?1:0}function Ykn(n,t,e,i){var r,c,a,u,o,s,f,l,b,w,d,g;if(ny(hL(jln(t,(Cjn(),ctt)))))return XH(),XH(),TFn;if(o=0!=(!t.a&&(t.a=new m_(uct,t,10,11)),t.a).i,s=!(f=function(n){var t,e,i;if(ny(hL(jln(n,(Cjn(),Fnt))))){for(i=new ip,e=new $K(bA(lbn(n).a.Kc(),new h));Vfn(e);)Whn(t=Yx(kV(e),79))&&ny(hL(jln(t,Bnt)))&&(i.c[i.c.length]=t);return i}return XH(),XH(),TFn}(t)).dc(),o||s){if(!(r=Yx(jln(t,Ltt),149)))throw hp(new ly("Resolved algorithm is not set; apply a LayoutAlgorithmResolver before computing layout."));if(g=zS(r,(zfn(),dct)),Otn(t),!o&&s&&!g)return XH(),XH(),TFn;if(u=new ip,iI(jln(t,Rnt))===iI((O8(),$et))&&(zS(r,lct)||zS(r,fct)))for(b=Udn(n,t),C2(w=new ME,(!t.a&&(t.a=new m_(uct,t,10,11)),t.a));0!=w.b;)Otn(l=Yx(0==w.b?null:(S$(0!=w.b),VZ(w,w.a.a)),33)),iI(jln(l,Rnt))===iI(Net)||zQ(l,gnt)&&!oV(r,jln(l,Ltt))?(S4(u,Ykn(n,l,e,i)),Aen(l,Rnt,Net),Fgn(l)):C2(w,(!l.a&&(l.a=new m_(uct,l,10,11)),l.a));else for(b=(!t.a&&(t.a=new m_(uct,t,10,11)),t.a).i,a=new UO((!t.a&&(t.a=new m_(uct,t,10,11)),t.a));a.e!=a.i.gc();)S4(u,Ykn(n,c=Yx(hen(a),33),e,i)),Fgn(c);for(d=new pb(u);d.a=0?G7(u):O9(G7(u)),n.Ye(k0n,b)),s=new Pk,l=!1,n.Xe(w0n)?(x$(s,Yx(n.We(w0n),8)),l=!0):function(n,t,e){n.a=t,n.b=e}(s,a.a/2,a.b/2),b.g){case 4:b5(h,x1n,(d7(),nYn)),b5(h,rQn,(i5(),UWn)),h.o.b=a.b,d<0&&(h.o.a=-d),whn(f,(Ikn(),Eit)),l||(s.a=a.a),s.a-=a.a;break;case 2:b5(h,x1n,(d7(),eYn)),b5(h,rQn,(i5(),GWn)),h.o.b=a.b,d<0&&(h.o.a=-d),whn(f,(Ikn(),qit)),l||(s.a=0);break;case 1:b5(h,pQn,(AJ(),HVn)),h.o.a=a.a,d<0&&(h.o.b=-d),whn(f,(Ikn(),Bit)),l||(s.b=a.b),s.b-=a.b;break;case 3:b5(h,pQn,(AJ(),FVn)),h.o.a=a.a,d<0&&(h.o.b=-d),whn(f,(Ikn(),Tit)),l||(s.b=0)}if(x$(f.n,s),b5(h,w0n,s),t==uit||t==sit||t==oit){if(w=0,t==uit&&n.Xe(p0n))switch(b.g){case 1:case 2:w=Yx(n.We(p0n),19).a;break;case 3:case 4:w=-Yx(n.We(p0n),19).a}else switch(b.g){case 4:case 2:w=c.b,t==sit&&(w/=r.b);break;case 1:case 3:w=c.a,t==sit&&(w/=r.a)}b5(h,KQn,w)}return b5(h,hQn,b),h}function Zkn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b;for(f=!1,s=n+1,$z(n,t.c.length),a=(h=Yx(t.c[n],200)).a,u=null,c=0;cs&&0==($z(s,t.c.length),Yx(t.c[s],200)).a.c.length;)uJ(t,($z(s,t.c.length),t.c[s]));if(!o){--c;continue}if(bpn(t,h,r,o,l,e,s,i)){f=!0;continue}if(l){if(imn(t,h,r,o,e,s,i)){f=!0;continue}if(u8(h,r)){r.c=!0,f=!0;continue}}else if(u8(h,r)){r.c=!0,f=!0;continue}if(f)continue}u8(h,r)?(r.c=!0,f=!0,o&&(o.k=!1)):ern(r.q)}else oE(),acn(h,r),--c,f=!0;return f}function njn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(g=0,P=0,h=new pb(n.b);h.ag&&(a&&(EI(E,w),EI(M,d9(f.b-1)),eD(n.d,d),o.c=VQ(UKn,iEn,1,0,5,1)),O=i.b,A+=w+t,w=0,l=e.Math.max(l,i.b+i.c+C)),o.c[o.c.length]=s,wen(s,O,A),l=e.Math.max(l,O+C+i.c),w=e.Math.max(w,b),O+=C+t,d=s;if(S4(n.a,o),eD(n.d,Yx(TR(o,o.c.length-1),157)),l=e.Math.max(l,r),(I=A+w+i.a)1&&(u=e.Math.min(u,e.Math.abs(Yx(ken(o.a,1),8).b-f.b)))));else for(d=new pb(t.j);d.ac&&(a=b.a-c,u=Yjn,r.c=VQ(UKn,iEn,1,0,5,1),c=b.a),b.a>=c&&(r.c[r.c.length]=o,o.a.b>1&&(u=e.Math.min(u,e.Math.abs(Yx(ken(o.a,o.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&u>t.o.b/2){for(ZG(w=new Ion,t),whn(w,(Ikn(),Tit)),w.n.a=t.o.a/2,ZG(g=new Ion,t),whn(g,Bit),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new pb(r);s.a=h.b?YG(o,g):YG(o,w)):(h=Yx(yD(o.a),8),(0==o.a.b?Dz(o.c):Yx(p$(o.a),8)).b>=h.b?QG(o,g):QG(o,w)),(l=Yx(Aun(o,(gjn(),$1n)),74))&&V7(l,h,!0);t.n.a=c-t.o.a/2}}function ejn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(s=t,$0(o=UX(n,RX(e),s),oX(s,rxn)),h=Yx(g1(n.g,Nhn(jG(s,_Nn))),33),i=null,(a=jG(s,"sourcePort"))&&(i=Nhn(a)),f=Yx(g1(n.j,i),118),!h)throw hp(new hy("An edge must have a source node (edge id: '"+itn(s)+sxn));if(f&&!bB(TG(f),h))throw hp(new hy("The source port of an edge must be a port of the edge's source node (edge id: '"+oX(s,rxn)+sxn));if(!o.b&&(o.b=new AN(Zrt,o,4,7)),fY(o.b,f||h),l=Yx(g1(n.g,Nhn(jG(s,lxn))),33),r=null,(u=jG(s,"targetPort"))&&(r=Nhn(u)),b=Yx(g1(n.j,r),118),!l)throw hp(new hy("An edge must have a target node (edge id: '"+itn(s)+sxn));if(b&&!bB(TG(b),l))throw hp(new hy("The target port of an edge must be a port of the edge's target node (edge id: '"+oX(s,rxn)+sxn));if(!o.c&&(o.c=new AN(Zrt,o,5,8)),fY(o.c,b||l),0==(!o.b&&(o.b=new AN(Zrt,o,4,7)),o.b).i||0==(!o.c&&(o.c=new AN(Zrt,o,5,8)),o.c).i)throw c=oX(s,rxn),hp(new hy(oxn+c+sxn));return eun(s,o),Iln(s,o),D5(n,s,o)}function ijn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P;return l=function(n,t){var i,r,c,a,u,o,s,h,f,l,b;if(n.dc())return new Pk;for(s=0,f=0,r=n.Kc();r.Ob();)c=Yx(r.Pb(),37).f,s=e.Math.max(s,c.a),f+=c.a*c.b;for(s=e.Math.max(s,e.Math.sqrt(f)*ty(fL(Aun(Yx(n.Kc().Pb(),37),(gjn(),RZn))))),l=0,b=0,o=0,i=t,u=n.Kc();u.Ob();)l+(h=(a=Yx(u.Pb(),37)).f).a>s&&(l=0,b+=o+t,o=0),bgn(a,l,b),i=e.Math.max(i,l+h.a),o=e.Math.max(o,h.b),l+=h.a+t;return new QS(i+t,b+o+t)}(QA(n,(Ikn(),Cit)),t),d=lrn(QA(n,Oit),t),k=lrn(QA(n,Kit),t),M=brn(QA(n,Fit),t),b=brn(QA(n,Mit),t),m=lrn(QA(n,Rit),t),g=lrn(QA(n,Ait),t),E=lrn(QA(n,_it),t),j=lrn(QA(n,Sit),t),S=brn(QA(n,Iit),t),v=lrn(QA(n,xit),t),y=lrn(QA(n,Nit),t),T=lrn(QA(n,Pit),t),P=brn(QA(n,Dit),t),w=brn(QA(n,$it),t),p=lrn(QA(n,Lit),t),i=N5(x4(Gy(Jot,1),rMn,25,15,[m.a,M.a,E.a,P.a])),r=N5(x4(Gy(Jot,1),rMn,25,15,[d.a,l.a,k.a,p.a])),c=v.a,a=N5(x4(Gy(Jot,1),rMn,25,15,[g.a,b.a,j.a,w.a])),h=N5(x4(Gy(Jot,1),rMn,25,15,[m.b,d.b,g.b,y.b])),s=N5(x4(Gy(Jot,1),rMn,25,15,[M.b,l.b,b.b,p.b])),f=S.b,o=N5(x4(Gy(Jot,1),rMn,25,15,[E.b,k.b,j.b,T.b])),wY(QA(n,Cit),i+c,h+f),wY(QA(n,Lit),i+c,h+f),wY(QA(n,Oit),i+c,0),wY(QA(n,Kit),i+c,h+f+s),wY(QA(n,Fit),0,h+f),wY(QA(n,Mit),i+c+r,h+f),wY(QA(n,Ait),i+c+r,0),wY(QA(n,_it),0,h+f+s),wY(QA(n,Sit),i+c+r,h+f+s),wY(QA(n,Iit),0,h),wY(QA(n,xit),i,0),wY(QA(n,Pit),0,h+f+s),wY(QA(n,$it),i+c+r,0),(u=new Pk).a=N5(x4(Gy(Jot,1),rMn,25,15,[i+r+c+a,S.a,y.a,T.a])),u.b=N5(x4(Gy(Jot,1),rMn,25,15,[h+s+f+o,v.b,P.b,w.b])),u}function rjn(n,t,i){var r,c,a,u,o,s,f;if(run(i,"Network simplex node placement",1),n.e=t,n.n=Yx(Aun(t,(Ojn(),zQn)),304),function(n){var t,i,r,c,a,u,o,s,f,l,b,w;for(n.f=new Zp,o=0,r=0,c=new pb(n.e.b);c.a=s.c.c.length?GX((bon(),Hzn),Bzn):GX((bon(),Bzn),Bzn),h*=2,c=i.a.g,i.a.g=e.Math.max(c,c+(h-c)),a=i.b.g,i.b.g=e.Math.max(a,a+(h-a)),r=t}else mln(u),Mmn(($z(0,u.c.length),Yx(u.c[0],17)).d.i)||eD(n.o,u)}(n),Ron(a)),Yen(n.f),c=Yx(Aun(t,V0n),19).a*n.f.a.c.length,Ggn(Xy(Wy(Cx(n.f),c),!1),J2(i,1)),0!=n.d.a.gc()){for(run(a=J2(i,1),"Flexible Where Space Processing",1),u=Yx(qA(YK(fH(new SR(null,new Nz(n.f.a,16)),new qc),new Dc)),19).a,o=Yx(qA(QK(fH(new SR(null,new Nz(n.f.a,16)),new Gc),new Rc)),19).a-u,s=HA(new ev,n.f),f=HA(new ev,n.f),uwn(NE(LE($E(xE(new tv,2e4),o),s),f)),SE(hH(hH(X_(n.i),new zc),new Uc),new vH(u,s,o,f)),r=n.d.a.ec().Kc();r.Ob();)Yx(r.Pb(),213).g=1;Ggn(Xy(Wy(Cx(n.f),c),!1),J2(a,1)),Ron(a)}ny(hL(Aun(t,V1n)))&&(run(a=J2(i,1),"Straight Edges Post-Processing",1),function(n){var t,e,i;for(C2(e=new ME,n.o),i=new kv;0!=e.b;)Bkn(n,t=Yx(0==e.b?null:(S$(0!=e.b),VZ(e,e.a.a)),508),!0)&&eD(i.a,t);for(;0!=i.a.c.length;)Bkn(n,t=Yx(K6(i),508),!1)}(n),Ron(a)),function(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;for(e=new pb(n.e.b);e.a0)if(r=f.gc(),s=oG(e.Math.floor((r+1)/2))-1,c=oG(e.Math.ceil((r+1)/2))-1,t.o==m4n)for(h=c;h>=s;h--)t.a[y.p]==y&&(d=Yx(f.Xb(h),46),w=Yx(d.a,10),!gE(i,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=y,t.g[y.p]=t.g[w.p],t.a[y.p]=t.g[y.p],t.f[t.g[y.p].p]=(TA(),!!(ny(t.f[t.g[y.p].p])&y.k==(bon(),Bzn))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[y.p]==y&&(p=Yx(f.Xb(h),46),g=Yx(p.a,10),!gE(i,p.b)&&b=48&&t<=57))throw hp(new wy(Kjn((GC(),oDn))));for(i=t-48;r=48&&t<=57;)if((i=10*i+t-48)<0)throw hp(new wy(Kjn((GC(),lDn))));if(e=i,44==t){if(r>=n.j)throw hp(new wy(Kjn((GC(),hDn))));if((t=XB(n.i,r++))>=48&&t<=57){for(e=t-48;r=48&&t<=57;)if((e=10*e+t-48)<0)throw hp(new wy(Kjn((GC(),lDn))));if(i>e)throw hp(new wy(Kjn((GC(),fDn))))}else e=-1}if(125!=t)throw hp(new wy(Kjn((GC(),sDn))));n.sl(r)?(Ljn(),Ljn(),c=new cW(9,c),n.d=r+1):(Ljn(),Ljn(),c=new cW(3,c),n.d=r),c.dm(i),c.cm(e),kjn(n)}}return c}function ojn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(w=new pQ(t.b),v=new pQ(t.b),l=new pQ(t.b),j=new pQ(t.b),d=new pQ(t.b),k=Ztn(t,0);k.b!=k.d.c;)for(u=new pb((m=Yx(IX(k),11)).g);u.a0,g=m.g.c.length>0,s&&g?l.c[l.c.length]=m:s?w.c[w.c.length]=m:g&&(v.c[v.c.length]=m);for(b=new pb(w);b.a1)for(b=new a$((!n.a&&(n.a=new m_(tct,n,6,6)),n.a));b.e!=b.i.gc();)tan(b);for(d=I,I>y+m?d=y+m:Ik+w?g=k+w:Cy-m&&dk-w&&gI+P?E=I+P:yC+j?T=C+j:kI-P&&EC-j&&Ti&&(f=i-1),(l=L+Xln(t,24)*jMn*h-h/2)<0?l=1:l>r&&(l=r-1),xk(),I1(c=new ro,f),C1(c,l),fY((!u.a&&(u.a=new XO(Qrt,u,5)),u.a),c)}function gjn(){gjn=O,Cjn(),A0n=Dtt,$0n=Rtt,L0n=Ktt,N0n=_tt,D0n=Ftt,R0n=Btt,F0n=qtt,H0n=ztt,q0n=Utt,B0n=Gtt,G0n=Xtt,U0n=Wtt,W0n=Ytt,_0n=Htt,Ajn(),O0n=ZJn,x0n=nZn,K0n=tZn,z0n=eZn,T0n=new DC(Att,d9(0)),M0n=QJn,S0n=YJn,P0n=JJn,c2n=SZn,Y0n=cZn,J0n=oZn,t2n=gZn,Z0n=fZn,n2n=bZn,u2n=AZn,a2n=IZn,i2n=jZn,e2n=yZn,r2n=TZn,Y1n=BJn,J1n=HJn,v1n=JYn,m1n=tJn,a0n=new RC(12),c0n=new DC(utt,a0n),g7(),b1n=new DC($nt,w1n=het),d0n=new DC(ytt,0),I0n=new DC($tt,d9(1)),RZn=new DC(mnt,OPn),r0n=ctt,g0n=ktt,k0n=Itt,c1n=Snt,xZn=pnt,E1n=Rnt,C0n=new DC(xtt,(TA(),!0)),I1n=Fnt,C1n=Bnt,n0n=Jnt,i0n=itt,t0n=ntt,t9(),a1n=new DC(Pnt,o1n=tet),U1n=Qnt,z1n=Wnt,m0n=Mtt,v0n=Ttt,y0n=Ptt,Ytn(),new DC(btt,s0n=rit),f0n=gtt,l0n=ptt,b0n=vtt,h0n=dtt,Q0n=rZn,B1n=SJn,F1n=TJn,V0n=iZn,x1n=gJn,r1n=KYn,i1n=DYn,VZn=kYn,QZn=jYn,JZn=PYn,YZn=EYn,e1n=NYn,q1n=IJn,G1n=CJn,A1n=sJn,Z1n=UJn,W1n=LJn,k1n=rJn,Q1n=_Jn,g1n=WYn,p1n=QYn,WZn=Tnt,X1n=OJn,BZn=hYn,FZn=oYn,_Zn=uYn,M1n=uJn,T1n=aJn,S1n=oJn,e0n=ttt,$1n=Gnt,y1n=Nnt,f1n=Ont,h1n=Cnt,ZZn=OYn,p0n=Ett,KZn=Ent,P1n=_nt,w0n=mtt,u0n=stt,o0n=ftt,R1n=mJn,K1n=kJn,E0n=Ott,DZn=aYn,_1n=EJn,l1n=GYn,s1n=HYn,H1n=Unt,L1n=bJn,V1n=DJn,X0n=Vtt,u1n=FYn,j0n=WJn,d1n=UYn,N1n=dJn,n1n=$Yn,O1n=qnt,D1n=vJn,t1n=LYn,XZn=mYn,zZn=gYn,qZn=wYn,GZn=dYn,UZn=vYn,HZn=lYn,j1n=cJn}function pjn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(hmn(),T=n.e,w=n.d,r=n.a,0==T)switch(t){case 0:return"0";case 1:return sMn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(j=new Ay).a+=t<0?"0E+":"0E",j.a+=-t,j.a}if(y=VQ(Xot,sTn,25,1+(m=10*w+1+7),15,1),e=m,1==w)if((u=r[0])<0){I=Gz(u,uMn);do{d=I,I=Bcn(I,10),y[--e]=48+WR(n7(d,e7(I,10)))&fTn}while(0!=k8(I,0))}else{I=u;do{d=I,I=I/10|0,y[--e]=d-10*I+48&fTn}while(0!=I)}else{smn(r,0,S=VQ(Wot,MTn,25,w,15,1),0,P=w);n:for(;;){for(E=0,s=P-1;s>=0;s--)p=Uan(t7(GK(E,32),Gz(S[s],uMn))),S[s]=WR(p),E=WR(zK(p,32));v=WR(E),g=e;do{y[--e]=48+v%10&fTn}while(0!=(v=v/10|0)&&0!=e);for(i=9-g+e,o=0;o0;o++)y[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==y[e];)++e}if(b=T<0,a=m-e-t-1,0==t)return b&&(y[--e]=45),Vnn(y,e,m-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=m-1;l>=h;l--)y[l+1]=y[l];return y[++h]=46,b&&(y[--e]=45),Vnn(y,e,m-e+1)}for(f=2;f<1-a;f++)y[--e]=48;return y[--e]=46,y[--e]=48,b&&(y[--e]=45),Vnn(y,e,m-e)}return M=e+1,c=m,k=new $y,b&&(k.a+="-"),c-M>=1?(_F(k,y[e]),k.a+=".",k.a+=Vnn(y,e+1,m-e-1)):k.a+=Vnn(y,e,m-e),k.a+="E",a>0&&(k.a+="+"),k.a+=""+a,k.a}function vjn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;switch(n.c=t,n.g=new rp,dT(),R7(new Qb(new Xm(n.c))),v=lL(jln(n.c,(Dun(),C9n))),u=Yx(jln(n.c,A9n),316),y=Yx(jln(n.c,$9n),429),c=Yx(jln(n.c,T9n),482),m=Yx(jln(n.c,O9n),430),n.j=ty(fL(jln(n.c,L9n))),a=n.a,u.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw hp(new Qm(V$n+(null!=u.f?u.f:""+u.g)))}if(n.d=new dG(a,y,c),b5(n.d,(y3(),hqn),hL(jln(n.c,S9n))),n.d.c=ny(hL(jln(n.c,M9n))),0==uq(n.c).i)return n.d;for(h=new UO(uq(n.c));h.e!=h.i.gc();){for(l=(s=Yx(hen(h),33)).g/2,f=s.f/2,k=new QS(s.i+l,s.j+f);P_(n.g,k);)$$(k,(e.Math.random()-.5)*PPn,(e.Math.random()-.5)*PPn);w=Yx(jln(s,(Cjn(),Unt)),142),d=new ez(k,new mH(k.a-l-n.j/2-w.b,k.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),eD(n.d.i,d),xB(n.g,k,new mP(d,s))}switch(m.g){case 0:if(null==v)n.d.d=Yx(TR(n.d.i,0),65);else for(p=new pb(n.d.i);p.a1&&VW(f,v,f.c.b,f.c),BZ(c)));v=m}return f}function yjn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(i=new ip,u=new ip,g=t/2,b=n.gc(),r=Yx(n.Xb(0),8),p=Yx(n.Xb(1),8),eD(i,($z(0,(w=kln(r.a,r.b,p.a,p.b,g)).c.length),Yx(w.c[0],8))),eD(u,($z(1,w.c.length),Yx(w.c[1],8))),s=2;s=0;o--)KD(e,($z(o,a.c.length),Yx(a.c[o],8)));return e}function kjn(n){var t,e,i;if(n.d>=n.j)return n.a=-1,void(n.c=1);if(t=XB(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=XB(n.i,n.d))break;if(++n.d>=n.j)throw hp(new wy(Kjn((GC(),$xn))));switch(t=XB(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw hp(new wy(Kjn((GC(),$xn))));if(61==(t=XB(n.i,n.d++)))i=16;else{if(33!=t)throw hp(new wy(Kjn((GC(),Lxn))));i=17}break;case 35:for(;n.d=n.j)throw hp(new wy(Kjn((GC(),Axn))));n.a=XB(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw hp(new wy(Kjn((GC(),Axn))));n.a=XB(n.i,n.d++);break;case 45:512==(512&n.e)&&n.d=j||!qnn(v,i))&&(i=Mz(t,f)),JG(v,i),c=new $K(bA(u7(v).a.Kc(),new h));Vfn(c);)r=Yx(kV(c),17),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&JQ(mun(w,g)));for(s=f.c.length-1;s>=0;--s)eD(t.b,($z(s,f.c.length),Yx(f.c[s],29)));t.a.c=VQ(UKn,iEn,1,0,5,1),Ron(e)}else Ron(e)}function Ejn(n){var t,e,i,r,c,a,u,o;for(n.b=1,kjn(n),t=null,0==n.c&&94==n.a?(kjn(n),Ljn(),Ljn(),zwn(t=new cU(4),0,jKn),a=new cU(4)):(Ljn(),Ljn(),a=new cU(4)),r=!0;1!=(o=n.c);){if(0==o&&93==n.a&&!r){t&&(_yn(t,a),a=t);break}if(e=n.a,i=!1,10==o)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:fmn(a,rpn(e)),i=!0;break;case 105:case 73:case 99:case 67:fmn(a,rpn(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(u=Hhn(n,e)))throw hp(new wy(Kjn((GC(),zxn))));fmn(a,u),i=!0;break;default:e=Tdn(n)}else if(24==o&&!r){if(t&&(_yn(t,a),a=t),_yn(a,Ejn(n)),0!=n.c||93!=n.a)throw hp(new wy(Kjn((GC(),Vxn))));break}if(kjn(n),!i){if(0==o){if(91==e)throw hp(new wy(Kjn((GC(),Qxn))));if(93==e)throw hp(new wy(Kjn((GC(),Yxn))));if(45==e&&!r&&93!=n.a)throw hp(new wy(Kjn((GC(),Jxn))))}if(0!=n.c||45!=n.a||45==e&&r)zwn(a,e,e);else{if(kjn(n),1==(o=n.c))throw hp(new wy(Kjn((GC(),Xxn))));if(0==o&&93==n.a)zwn(a,e,e),zwn(a,45,45);else{if(0==o&&93==n.a||24==o)throw hp(new wy(Kjn((GC(),Jxn))));if(c=n.a,0==o){if(91==c)throw hp(new wy(Kjn((GC(),Qxn))));if(93==c)throw hp(new wy(Kjn((GC(),Yxn))));if(45==c)throw hp(new wy(Kjn((GC(),Jxn))))}else 10==o&&(c=Tdn(n));if(kjn(n),e>c)throw hp(new wy(Kjn((GC(),tDn))));zwn(a,e,c)}}}r=!1}if(1==n.c)throw hp(new wy(Kjn((GC(),Xxn))));return xln(a),Lmn(a),n.b=0,kjn(n),a}function Tjn(){Tjn=O,ljn(),Qhn(Azn=new Zq,(Ikn(),Oit),Cit),Qhn(Azn,Fit,Cit),Qhn(Azn,Ait,Cit),Qhn(Azn,Rit,Cit),Qhn(Azn,Dit,Cit),Qhn(Azn,Nit,Cit),Qhn(Azn,Rit,Oit),Qhn(Azn,Cit,Mit),Qhn(Azn,Oit,Mit),Qhn(Azn,Fit,Mit),Qhn(Azn,Ait,Mit),Qhn(Azn,xit,Mit),Qhn(Azn,Rit,Mit),Qhn(Azn,Dit,Mit),Qhn(Azn,Nit,Mit),Qhn(Azn,Iit,Mit),Qhn(Azn,Cit,Kit),Qhn(Azn,Oit,Kit),Qhn(Azn,Mit,Kit),Qhn(Azn,Fit,Kit),Qhn(Azn,Ait,Kit),Qhn(Azn,xit,Kit),Qhn(Azn,Rit,Kit),Qhn(Azn,Iit,Kit),Qhn(Azn,_it,Kit),Qhn(Azn,Dit,Kit),Qhn(Azn,$it,Kit),Qhn(Azn,Nit,Kit),Qhn(Azn,Oit,Fit),Qhn(Azn,Ait,Fit),Qhn(Azn,Rit,Fit),Qhn(Azn,Nit,Fit),Qhn(Azn,Oit,Ait),Qhn(Azn,Fit,Ait),Qhn(Azn,Rit,Ait),Qhn(Azn,Ait,Ait),Qhn(Azn,Dit,Ait),Qhn(Azn,Cit,Sit),Qhn(Azn,Oit,Sit),Qhn(Azn,Mit,Sit),Qhn(Azn,Kit,Sit),Qhn(Azn,Fit,Sit),Qhn(Azn,Ait,Sit),Qhn(Azn,xit,Sit),Qhn(Azn,Rit,Sit),Qhn(Azn,_it,Sit),Qhn(Azn,Iit,Sit),Qhn(Azn,Nit,Sit),Qhn(Azn,Dit,Sit),Qhn(Azn,Lit,Sit),Qhn(Azn,Cit,_it),Qhn(Azn,Oit,_it),Qhn(Azn,Mit,_it),Qhn(Azn,Fit,_it),Qhn(Azn,Ait,_it),Qhn(Azn,xit,_it),Qhn(Azn,Rit,_it),Qhn(Azn,Iit,_it),Qhn(Azn,Nit,_it),Qhn(Azn,$it,_it),Qhn(Azn,Lit,_it),Qhn(Azn,Oit,Iit),Qhn(Azn,Fit,Iit),Qhn(Azn,Ait,Iit),Qhn(Azn,Rit,Iit),Qhn(Azn,_it,Iit),Qhn(Azn,Nit,Iit),Qhn(Azn,Dit,Iit),Qhn(Azn,Cit,Pit),Qhn(Azn,Oit,Pit),Qhn(Azn,Mit,Pit),Qhn(Azn,Fit,Pit),Qhn(Azn,Ait,Pit),Qhn(Azn,xit,Pit),Qhn(Azn,Rit,Pit),Qhn(Azn,Iit,Pit),Qhn(Azn,Nit,Pit),Qhn(Azn,Oit,Dit),Qhn(Azn,Mit,Dit),Qhn(Azn,Kit,Dit),Qhn(Azn,Ait,Dit),Qhn(Azn,Cit,$it),Qhn(Azn,Oit,$it),Qhn(Azn,Kit,$it),Qhn(Azn,Fit,$it),Qhn(Azn,Ait,$it),Qhn(Azn,xit,$it),Qhn(Azn,Rit,$it),Qhn(Azn,Rit,Lit),Qhn(Azn,Ait,Lit),Qhn(Azn,Iit,Cit),Qhn(Azn,Iit,Fit),Qhn(Azn,Iit,Mit),Qhn(Azn,xit,Cit),Qhn(Azn,xit,Oit),Qhn(Azn,xit,Kit)}function Mjn(n,t){switch(n.e){case 0:case 2:case 4:case 6:case 42:case 44:case 46:case 48:case 8:case 10:case 12:case 14:case 16:case 18:case 20:case 22:case 24:case 26:case 28:case 30:case 32:case 34:case 36:case 38:return new eq(n.b,n.a,t,n.c);case 1:return new WO(n.a,t,tnn(t.Tg(),n.c));case 43:return new QO(n.a,t,tnn(t.Tg(),n.c));case 3:return new XO(n.a,t,tnn(t.Tg(),n.c));case 45:return new VO(n.a,t,tnn(t.Tg(),n.c));case 41:return new yY(Yx(fcn(n.c),26),n.a,t,tnn(t.Tg(),n.c));case 50:return new j0(Yx(fcn(n.c),26),n.a,t,tnn(t.Tg(),n.c));case 5:return new TN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 47:return new MN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 7:return new m_(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 49:return new EN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 9:return new tA(n.a,t,tnn(t.Tg(),n.c));case 11:return new nA(n.a,t,tnn(t.Tg(),n.c));case 13:return new ZO(n.a,t,tnn(t.Tg(),n.c));case 15:return new CD(n.a,t,tnn(t.Tg(),n.c));case 17:return new eA(n.a,t,tnn(t.Tg(),n.c));case 19:return new JO(n.a,t,tnn(t.Tg(),n.c));case 21:return new YO(n.a,t,tnn(t.Tg(),n.c));case 23:return new TD(n.a,t,tnn(t.Tg(),n.c));case 25:return new $N(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 27:return new AN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 29:return new CN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 31:return new SN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 33:return new ON(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 35:return new IN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 37:return new PN(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 39:return new y_(n.a,t,tnn(t.Tg(),n.c),n.d.n);case 40:return new e3(t,tnn(t.Tg(),n.c));default:throw hp(new Im("Unknown feature style: "+n.e))}}function Sjn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;switch(run(i,"Brandes & Koepf node placement",1),n.a=t,n.c=avn(t),r=Yx(Aun(t,(gjn(),W1n)),274),w=ny(hL(Aun(t,V1n))),n.d=r==(Wcn(),hVn)&&!w||r==uVn,function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;if(!((d=t.b.c.length)<3)){for(b=VQ(Wot,MTn,25,d,15,1),f=0,h=new pb(t.b);h.aa)&&__(n.b,Yx(g.b,17));++u}c=a}}}(n,t),k=null,j=null,p=null,v=null,g0(4,UEn),g=new pQ(4),Yx(Aun(t,W1n),274).g){case 3:p=new Bgn(t,n.c.d,(RG(),v4n),(Jq(),w4n)),g.c[g.c.length]=p;break;case 1:v=new Bgn(t,n.c.d,(RG(),m4n),(Jq(),w4n)),g.c[g.c.length]=v;break;case 4:k=new Bgn(t,n.c.d,(RG(),v4n),(Jq(),d4n)),g.c[g.c.length]=k;break;case 2:j=new Bgn(t,n.c.d,(RG(),m4n),(Jq(),d4n)),g.c[g.c.length]=j;break;default:p=new Bgn(t,n.c.d,(RG(),v4n),(Jq(),w4n)),v=new Bgn(t,n.c.d,m4n,w4n),k=new Bgn(t,n.c.d,v4n,d4n),j=new Bgn(t,n.c.d,m4n,d4n),g.c[g.c.length]=k,g.c[g.c.length]=j,g.c[g.c.length]=p,g.c[g.c.length]=v}for(c=new kS(t,n.c),o=new pb(g);o.aE[s]&&(d=s),f=new pb(n.a.b);f.aAln(a))&&(l=a);for(!l&&($z(0,g.c.length),l=Yx(g.c[0],180)),d=new pb(t.b);d.a=-1900?1:0,yI(n,i>=4?x4(Gy(fFn,1),TEn,2,6,[STn,PTn])[u]:x4(Gy(fFn,1),TEn,2,6,["BC","AD"])[u]);break;case 121:!function(n,t,e){var i;switch((i=e.q.getFullYear()-TTn+TTn)<0&&(i=-i),t){case 1:n.a+=i;break;case 2:tZ(n,i%100,2);break;default:tZ(n,i,t)}}(n,i,r);break;case 77:!function(n,t,e){var i;switch(i=e.q.getMonth(),t){case 5:yI(n,x4(Gy(fFn,1),TEn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[i]);break;case 4:yI(n,x4(Gy(fFn,1),TEn,2,6,[lTn,bTn,wTn,dTn,gTn,pTn,vTn,mTn,yTn,kTn,jTn,ETn])[i]);break;case 3:yI(n,x4(Gy(fFn,1),TEn,2,6,["Jan","Feb","Mar","Apr",gTn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[i]);break;default:tZ(n,i+1,t)}}(n,i,r);break;case 107:tZ(n,0==(o=c.q.getHours())?24:o,i);break;case 83:!function(n,t,i){var r,c;k8(r=D3(i.q.getTime()),0)<0?(c=hTn-WR(Snn(sJ(r),hTn)))==hTn&&(c=0):c=WR(Snn(r,hTn)),1==t?_F(n,48+(c=e.Math.min((c+50)/100|0,9))&fTn):2==t?tZ(n,c=e.Math.min((c+5)/10|0,99),2):(tZ(n,c,3),t>3&&tZ(n,0,t-3))}(n,i,c);break;case 69:s=r.q.getDay(),yI(n,5==i?x4(Gy(fFn,1),TEn,2,6,["S","M","T","W","T","F","S"])[s]:4==i?x4(Gy(fFn,1),TEn,2,6,[ITn,CTn,OTn,ATn,$Tn,LTn,NTn])[s]:x4(Gy(fFn,1),TEn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[s]);break;case 97:c.q.getHours()>=12&&c.q.getHours()<24?yI(n,x4(Gy(fFn,1),TEn,2,6,["AM","PM"])[1]):yI(n,x4(Gy(fFn,1),TEn,2,6,["AM","PM"])[0]);break;case 104:tZ(n,0==(h=c.q.getHours()%12)?12:h,i);break;case 75:tZ(n,c.q.getHours()%12,i);break;case 72:tZ(n,c.q.getHours(),i);break;case 99:f=r.q.getDay(),5==i?yI(n,x4(Gy(fFn,1),TEn,2,6,["S","M","T","W","T","F","S"])[f]):4==i?yI(n,x4(Gy(fFn,1),TEn,2,6,[ITn,CTn,OTn,ATn,$Tn,LTn,NTn])[f]):3==i?yI(n,x4(Gy(fFn,1),TEn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[f]):tZ(n,f,1);break;case 76:l=r.q.getMonth(),5==i?yI(n,x4(Gy(fFn,1),TEn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[l]):4==i?yI(n,x4(Gy(fFn,1),TEn,2,6,[lTn,bTn,wTn,dTn,gTn,pTn,vTn,mTn,yTn,kTn,jTn,ETn])[l]):3==i?yI(n,x4(Gy(fFn,1),TEn,2,6,["Jan","Feb","Mar","Apr",gTn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[l]):tZ(n,l+1,i);break;case 81:b=r.q.getMonth()/3|0,yI(n,i<4?x4(Gy(fFn,1),TEn,2,6,["Q1","Q2","Q3","Q4"])[b]:x4(Gy(fFn,1),TEn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[b]);break;case 100:tZ(n,r.q.getDate(),i);break;case 109:tZ(n,c.q.getMinutes(),i);break;case 115:tZ(n,c.q.getSeconds(),i);break;case 122:yI(n,i<4?a.c[0]:a.c[1]);break;case 118:yI(n,a.b);break;case 90:yI(n,i<3?function(n){var t,e;return e=-n.a,t=x4(Gy(Xot,1),sTn,25,15,[43,48,48,48,48]),e<0&&(t[0]=45,e=-e),t[1]=t[1]+((e/60|0)/10|0)&fTn,t[2]=t[2]+(e/60|0)%10&fTn,t[3]=t[3]+(e%60/10|0)&fTn,t[4]=t[4]+e%10&fTn,Vnn(t,0,t.length)}(a):3==i?function(n){var t,e;return e=-n.a,t=x4(Gy(Xot,1),sTn,25,15,[43,48,48,58,48,48]),e<0&&(t[0]=45,e=-e),t[1]=t[1]+((e/60|0)/10|0)&fTn,t[2]=t[2]+(e/60|0)%10&fTn,t[4]=t[4]+(e%60/10|0)&fTn,t[5]=t[5]+e%10&fTn,Vnn(t,0,t.length)}(a):function(n){var t;return t=x4(Gy(Xot,1),sTn,25,15,[71,77,84,45,48,48,58,48,48]),n<=0&&(t[3]=43,n=-n),t[4]=t[4]+((n/60|0)/10|0)&fTn,t[5]=t[5]+(n/60|0)%10&fTn,t[7]=t[7]+(n%60/10|0)&fTn,t[8]=t[8]+n%10&fTn,Vnn(t,0,t.length)}(a.a));break;default:return!1}return!0}function Ijn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(dgn(t),o=Yx(c1((!t.b&&(t.b=new AN(Zrt,t,4,7)),t.b),0),82),h=Yx(c1((!t.c&&(t.c=new AN(Zrt,t,5,8)),t.c),0),82),u=iun(o),s=iun(h),a=0==(!t.a&&(t.a=new m_(tct,t,6,6)),t.a).i?null:Yx(c1((!t.a&&(t.a=new m_(tct,t,6,6)),t.a),0),202),j=Yx(BF(n.a,u),10),S=Yx(BF(n.a,s),10),E=null,P=null,CO(o,186)&&(CO(k=Yx(BF(n.a,o),299),11)?E=Yx(k,11):CO(k,10)&&(j=Yx(k,10),E=Yx(TR(j.j,0),11))),CO(h,186)&&(CO(M=Yx(BF(n.a,h),299),11)?P=Yx(M,11):CO(M,10)&&(S=Yx(M,10),P=Yx(TR(S.j,0),11))),!j||!S)throw hp(new by("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(o4(d=new jq,t),b5(d,(Ojn(),CQn),t),b5(d,(gjn(),$1n),null),b=Yx(Aun(i,bQn),21),j==S&&b.Fc((edn(),$Vn)),E||(h0(),y=i3n,T=null,a&&dC(Yx(Aun(j,g0n),98))&&(XX(T=new QS(a.j,a.k),EG(t)),UW(T,e),XZ(s,u)&&(y=e3n,mN(T,j.n))),E=dmn(j,T,y,i)),P||(h0(),y=e3n,I=null,a&&dC(Yx(Aun(S,g0n),98))&&(XX(I=new QS(a.b,a.c),EG(t)),UW(I,e)),P=dmn(S,I,y,dB(S))),YG(d,E),QG(d,P),(E.e.c.length>1||E.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((edn(),PVn)),l=new UO((!t.n&&(t.n=new m_(act,t,1,7)),t.n));l.e!=l.i.gc();)if(!ny(hL(jln(f=Yx(hen(l),137),r0n)))&&f.a)switch(g=d8(f),eD(d.b,g),Yx(Aun(g,f1n),272).g){case 1:case 2:b.Fc((edn(),MVn));break;case 0:b.Fc((edn(),EVn)),b5(g,f1n,(ZZ(),cet))}if(c=Yx(Aun(i,i1n),314),p=Yx(Aun(i,Z1n),315),r=c==(O0(),EWn)||p==(ain(),A2n),a&&0!=(!a.a&&(a.a=new XO(Qrt,a,5)),a.a).i&&r){for(v=Kon(a),w=new Nv,m=Ztn(v,0);m.b!=m.d.c;)KD(w,new fC(Yx(IX(m),8)));b5(d,OQn,w)}return d}function Cjn(){var n,t;Cjn=O,gnt=new Og(CLn),Ltt=new Og(OLn),qen(),pnt=new FI(sAn,vnt=H7n),new tp,mnt=new FI(hPn,null),ynt=new Og(ALn),dan(),Mnt=tK(bnt,x4(Gy(iet,1),XEn,291,0,[snt])),Tnt=new FI(jAn,Mnt),Snt=new FI(oAn,(TA(),!1)),t9(),Pnt=new FI(bAn,Int=tet),g7(),$nt=new FI(xOn,Lnt=wet),Dnt=new FI(U$n,!1),O8(),Rnt=new FI(OOn,Knt=Let),ott=new RC(12),utt=new FI(fPn,ott),Hnt=new FI(RPn,!1),qnt=new FI(NAn,!1),att=new FI(FPn,!1),Ran(),ktt=new FI(KPn,jtt=lit),Ott=new Og(AAn),Att=new Og($Pn),$tt=new Og(xPn),xtt=new Og(DPn),znt=new Nv,Gnt=new FI(EAn,znt),Ent=new FI(SAn,!1),_nt=new FI(PAn,!1),new Og($Ln),Xnt=new Mv,Unt=new FI($An,Xnt),ctt=new FI(aAn,!1),new tp,Ntt=new FI(LLn,1),new FI(NLn,!0),d9(0),new FI(xLn,d9(100)),new FI(DLn,!1),d9(0),new FI(RLn,d9(4e3)),d9(0),new FI(KLn,d9(400)),new FI(_Ln,!1),new FI(FLn,!1),new FI(BLn,!0),new FI(HLn,!1),unn(),knt=new FI(ILn,jnt=prt),Dtt=new FI(WOn,10),Rtt=new FI(VOn,10),Ktt=new FI(oPn,20),_tt=new FI(QOn,10),Ftt=new FI(NPn,2),Btt=new FI(YOn,10),qtt=new FI(JOn,0),Gtt=new FI(tAn,5),ztt=new FI(ZOn,1),Utt=new FI(nAn,1),Xtt=new FI(LPn,20),Wtt=new FI(eAn,10),Ytt=new FI(iAn,10),Htt=new Og(rAn),Qtt=new sC,Vtt=new FI(LAn,Qtt),ftt=new Og(OAn),stt=new FI(CAn,htt=!1),Vnt=new RC(5),Wnt=new FI(wAn,Vnt),Eln(),t=Yx(Ak(cit),9),Ynt=new cx(t,Yx(eN(t,t.length),9),0),Qnt=new FI(qPn,Ynt),Ytn(),btt=new FI(pAn,wtt=eit),gtt=new Og(vAn),ptt=new Og(mAn),vtt=new Og(yAn),dtt=new Og(kAn),n=Yx(Ak(lrt),9),Znt=new cx(n,Yx(eN(n,n.length),9),0),Jnt=new FI(HPn,Znt),rtt=J9((Vgn(),crt)),itt=new FI(BPn,rtt),ett=new QS(0,0),ttt=new FI(eIn,ett),ntt=new FI(lAn,!1),ZZ(),Ont=new FI(TAn,Ant=cet),Cnt=new FI(_Pn,!1),new Og(qLn),d9(1),new FI(GLn,null),mtt=new Og(IAn),Ett=new Og(MAn),Ikn(),Itt=new FI(uAn,Ctt=Hit),ytt=new Og(cAn),Chn(),Stt=J9(mit),Mtt=new FI(GPn,Stt),Ttt=new FI(dAn,!1),Ptt=new FI(gAn,!0),Fnt=new FI(hAn,!1),Bnt=new FI(fAn,!1),Nnt=new FI(sPn,1),vun(),new FI(zLn,xnt=ket),ltt=!0}function Ojn(){var n,t;Ojn=O,CQn=new Og(zPn),nQn=new Og("coordinateOrigin"),_Qn=new Og("processors"),ZVn=new _L("compoundNode",(TA(),!1)),gQn=new _L("insideConnections",!1),OQn=new Og("originalBendpoints"),AQn=new Og("originalDummyNodePosition"),$Qn=new Og("originalLabelEdge"),BQn=new Og("representedLabels"),cQn=new Og("endLabels"),aQn=new Og("endLabel.origin"),kQn=new _L("labelSide",(Frn(),Fet)),PQn=new _L("maxEdgeThickness",0),HQn=new _L("reversed",!1),FQn=new Og(UPn),TQn=new _L("longEdgeSource",null),MQn=new _L("longEdgeTarget",null),EQn=new _L("longEdgeHasLabelDummies",!1),jQn=new _L("longEdgeBeforeLabelDummy",!1),rQn=new _L("edgeConstraint",(i5(),zWn)),vQn=new Og("inLayerLayoutUnit"),pQn=new _L("inLayerConstraint",(AJ(),BVn)),mQn=new _L("inLayerSuccessorConstraint",new ip),yQn=new _L("inLayerSuccessorConstraintBetweenNonDummies",!1),RQn=new Og("portDummy"),tQn=new _L("crossingHint",d9(0)),bQn=new _L("graphProperties",new cx(t=Yx(Ak(KVn),9),Yx(eN(t,t.length),9),0)),hQn=new _L("externalPortSide",(Ikn(),Hit)),fQn=new _L("externalPortSize",new Pk),oQn=new Og("externalPortReplacedDummies"),sQn=new Og("externalPortReplacedDummy"),uQn=new _L("externalPortConnections",new cx(n=Yx(Ak(trt),9),Yx(eN(n,n.length),9),0)),KQn=new _L(OSn,0),VVn=new Og("barycenterAssociates"),JQn=new Og("TopSideComments"),QVn=new Og("BottomSideComments"),JVn=new Og("CommentConnectionPort"),dQn=new _L("inputCollect",!1),xQn=new _L("outputCollect",!1),iQn=new _L("cyclic",!1),eQn=new Og("crossHierarchyMap"),YQn=new Og("targetOffset"),new _L("splineLabelSize",new Pk),zQn=new Og("spacings"),DQn=new _L("partitionConstraint",!1),YVn=new Og("breakingPoint.info"),VQn=new Og("splines.survivingEdge"),WQn=new Og("splines.route.start"),UQn=new Og("splines.edgeChain"),NQn=new Og("originalPortConstraints"),GQn=new Og("selfLoopHolder"),XQn=new Og("splines.nsPortY"),IQn=new Og("modelOrder"),SQn=new Og("longEdgeTargetNode"),lQn=new _L(aCn,!1),qQn=new _L(aCn,!1),wQn=new Og("layerConstraints.hiddenNodes"),LQn=new Og("layerConstraints.opposidePort"),QQn=new Og("targetNode.modelOrder")}function Ajn(){Ajn=O,fZ(),FYn=new FI(uCn,BYn=FWn),rJn=new FI(oCn,(TA(),!1)),dX(),sJn=new FI(sCn,hJn=zVn),IJn=new FI(hCn,!1),CJn=new FI(fCn,!0),aYn=new FI(lCn,!1),$J(),WJn=new FI(bCn,VJn=J2n),d9(1),iZn=new FI(wCn,d9(7)),rZn=new FI(dCn,!1),cJn=new FI(gCn,!1),min(),KYn=new FI(pCn,_Yn=NWn),nun(),SJn=new FI(vCn,PJn=d2n),d7(),gJn=new FI(mCn,pJn=iYn),d9(-1),dJn=new FI(yCn,d9(-1)),d9(-1),vJn=new FI(kCn,d9(-1)),d9(-1),mJn=new FI(jCn,d9(4)),d9(-1),kJn=new FI(ECn,d9(2)),_bn(),TJn=new FI(TCn,MJn=q2n),d9(0),EJn=new FI(MCn,d9(0)),bJn=new FI(SCn,d9(Yjn)),O0(),DYn=new FI(PCn,RYn=TWn),kYn=new FI(ICn,!1),OYn=new FI(CCn,.1),NYn=new FI(OCn,!1),d9(-1),$Yn=new FI(ACn,d9(-1)),d9(-1),LYn=new FI($Cn,d9(-1)),d9(0),jYn=new FI(LCn,d9(40)),r4(),PYn=new FI(NCn,IYn=RVn),EYn=new FI(xCn,TYn=xVn),ain(),UJn=new FI(DCn,XJn=O2n),DJn=new Og(RCn),cJ(),OJn=new FI(KCn,AJn=iVn),Wcn(),LJn=new FI(_Cn,NJn=hVn),new tp,_Jn=new FI(FCn,.3),BJn=new Og(BCn),Hen(),HJn=new FI(HCn,qJn=S2n),d3(),WYn=new FI(qCn,VYn=o3n),rQ(),QYn=new FI(GCn,YYn=b3n),$6(),JYn=new FI(zCn,ZYn=v3n),tJn=new FI(UCn,.2),UYn=new FI(XCn,2),ZJn=new FI(WCn,null),tZn=new FI(VCn,10),nZn=new FI(QCn,10),eZn=new FI(YCn,20),d9(0),QJn=new FI(JCn,d9(0)),d9(0),YJn=new FI(ZCn,d9(0)),d9(0),JJn=new FI(nOn,d9(0)),uYn=new FI(tOn,!1),uon(),hYn=new FI(eOn,fYn=mVn),aY(),oYn=new FI(iOn,sYn=yWn),uJn=new FI(rOn,!1),d9(0),aJn=new FI(cOn,d9(16)),d9(0),oJn=new FI(aOn,d9(5)),F4(),SZn=new FI(uOn,PZn=P3n),cZn=new FI(oOn,10),oZn=new FI(sOn,1),f0(),gZn=new FI(hOn,pZn=OWn),fZn=new Og(fOn),wZn=d9(1),d9(0),bZn=new FI(lOn,wZn),V2(),AZn=new FI(bOn,$Zn=k3n),IZn=new Og(wOn),jZn=new FI(dOn,!0),yZn=new FI(gOn,2),TZn=new FI(pOn,!0),pon(),GYn=new FI(vOn,zYn=ZWn),psn(),HYn=new FI(mOn,qYn=bWn),k5(),mYn=new FI(yOn,yYn=W2n),vYn=new FI(kOn,!1),e9(),lYn=new FI(jOn,bYn=Izn),i8(),gYn=new FI(EOn,pYn=m2n),wYn=new FI(TOn,0),dYn=new FI(MOn,0),lJn=DWn,fJn=EWn,yJn=w2n,jJn=w2n,wJn=f2n,O8(),AYn=$et,xYn=TWn,CYn=TWn,MYn=TWn,SYn=$et,RJn=L2n,KJn=O2n,$Jn=O2n,xJn=O2n,FJn=$2n,zJn=L2n,GJn=L2n,g7(),nJn=bet,eJn=bet,iJn=v3n,XYn=fet,aZn=I3n,uZn=S3n,sZn=I3n,hZn=S3n,vZn=I3n,mZn=S3n,lZn=CWn,dZn=OWn,LZn=I3n,NZn=S3n,CZn=I3n,OZn=S3n,EZn=S3n,kZn=S3n,MZn=S3n}function $jn(){$jn=O,vUn=new vM("DIRECTION_PREPROCESSOR",0),dUn=new vM("COMMENT_PREPROCESSOR",1),mUn=new vM("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),xUn=new vM("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),nXn=new vM("PARTITION_PREPROCESSOR",4),_Un=new vM("LABEL_DUMMY_INSERTER",5),aXn=new vM("SELF_LOOP_PREPROCESSOR",6),GUn=new vM("LAYER_CONSTRAINT_PREPROCESSOR",7),JUn=new vM("PARTITION_MIDPROCESSOR",8),OUn=new vM("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),WUn=new vM("NODE_PROMOTION",10),qUn=new vM("LAYER_CONSTRAINT_POSTPROCESSOR",11),ZUn=new vM("PARTITION_POSTPROCESSOR",12),SUn=new vM("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),oXn=new vM("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),sUn=new vM("BREAKING_POINT_INSERTER",15),XUn=new vM("LONG_EDGE_SPLITTER",16),eXn=new vM("PORT_SIDE_PROCESSOR",17),DUn=new vM("INVERTED_PORT_PROCESSOR",18),tXn=new vM("PORT_LIST_SORTER",19),hXn=new vM("SORT_BY_INPUT_ORDER_OF_MODEL",20),QUn=new vM("NORTH_SOUTH_PORT_PREPROCESSOR",21),hUn=new vM("BREAKING_POINT_PROCESSOR",22),YUn=new vM(KIn,23),fXn=new vM(_In,24),rXn=new vM("SELF_LOOP_PORT_RESTORER",25),sXn=new vM("SINGLE_EDGE_GRAPH_WRAPPER",26),RUn=new vM("IN_LAYER_CONSTRAINT_PROCESSOR",27),EUn=new vM("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),KUn=new vM("LABEL_AND_NODE_SIZE_PROCESSOR",29),NUn=new vM("INNERMOST_NODE_MARGIN_CALCULATOR",30),uXn=new vM("SELF_LOOP_ROUTER",31),bUn=new vM("COMMENT_NODE_MARGIN_CALCULATOR",32),kUn=new vM("END_LABEL_PREPROCESSOR",33),BUn=new vM("LABEL_DUMMY_SWITCHER",34),lUn=new vM("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),HUn=new vM("LABEL_SIDE_SELECTOR",36),$Un=new vM("HYPEREDGE_DUMMY_MERGER",37),PUn=new vM("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),zUn=new vM("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),CUn=new vM("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),gUn=new vM("CONSTRAINTS_POSTPROCESSOR",41),wUn=new vM("COMMENT_POSTPROCESSOR",42),LUn=new vM("HYPERNODE_PROCESSOR",43),IUn=new vM("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),UUn=new vM("LONG_EDGE_JOINER",45),cXn=new vM("SELF_LOOP_POSTPROCESSOR",46),fUn=new vM("BREAKING_POINT_REMOVER",47),VUn=new vM("NORTH_SOUTH_PORT_POSTPROCESSOR",48),AUn=new vM("HORIZONTAL_COMPACTOR",49),FUn=new vM("LABEL_DUMMY_REMOVER",50),TUn=new vM("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),jUn=new vM("END_LABEL_SORTER",52),iXn=new vM("REVERSED_EDGE_RESTORER",53),yUn=new vM("END_LABEL_POSTPROCESSOR",54),MUn=new vM("HIERARCHICAL_NODE_RESIZER",55),pUn=new vM("DIRECTION_POSTPROCESSOR",56)}function Ljn(){Ljn=O,Tot=new np(7),Mot=new BR(8,94),new BR(8,64),Sot=new BR(8,36),$ot=new BR(8,65),Lot=new BR(8,122),Not=new BR(8,90),Rot=new BR(8,98),Oot=new BR(8,66),xot=new BR(8,60),Kot=new BR(8,62),Eot=new np(11),zwn(jot=new cU(4),48,57),zwn(Dot=new cU(4),48,57),zwn(Dot,65,90),zwn(Dot,95,95),zwn(Dot,97,122),zwn(Aot=new cU(4),9,9),zwn(Aot,10,10),zwn(Aot,12,12),zwn(Aot,13,13),zwn(Aot,32,32),Pot=nvn(jot),Cot=nvn(Dot),Iot=nvn(Aot),vot=new rp,mot=new rp,yot=x4(Gy(fFn,1),TEn,2,6,["Cn","Lu","Ll","Lt","Lm","Lo","Mn","Me","Mc","Nd","Nl","No","Zs","Zl","Zp","Cc","Cf",null,"Co","Cs","Pd","Ps","Pe","Pc","Po","Sm","Sc","Sk","So","Pi","Pf","L","M","N","Z","C","P","S"]),pot=x4(Gy(fFn,1),TEn,2,6,["Basic Latin","Latin-1 Supplement","Latin Extended-A","Latin Extended-B","IPA Extensions","Spacing Modifier Letters","Combining Diacritical Marks","Greek","Cyrillic","Armenian","Hebrew","Arabic","Syriac","Thaana","Devanagari","Bengali","Gurmukhi","Gujarati","Oriya","Tamil","Telugu","Kannada","Malayalam","Sinhala","Thai","Lao","Tibetan","Myanmar","Georgian","Hangul Jamo","Ethiopic","Cherokee","Unified Canadian Aboriginal Syllabics","Ogham","Runic","Khmer","Mongolian","Latin Extended Additional","Greek Extended","General Punctuation","Superscripts and Subscripts","Currency Symbols","Combining Marks for Symbols","Letterlike Symbols","Number Forms","Arrows","Mathematical Operators","Miscellaneous Technical","Control Pictures","Optical Character Recognition","Enclosed Alphanumerics","Box Drawing","Block Elements","Geometric Shapes","Miscellaneous Symbols","Dingbats","Braille Patterns","CJK Radicals Supplement","Kangxi Radicals","Ideographic Description Characters","CJK Symbols and Punctuation","Hiragana","Katakana","Bopomofo","Hangul Compatibility Jamo","Kanbun","Bopomofo Extended","Enclosed CJK Letters and Months","CJK Compatibility","CJK Unified Ideographs Extension A","CJK Unified Ideographs","Yi Syllables","Yi Radicals","Hangul Syllables",AKn,"CJK Compatibility Ideographs","Alphabetic Presentation Forms","Arabic Presentation Forms-A","Combining Half Marks","CJK Compatibility Forms","Small Form Variants","Arabic Presentation Forms-B","Specials","Halfwidth and Fullwidth Forms","Old Italic","Gothic","Deseret","Byzantine Musical Symbols","Musical Symbols","Mathematical Alphanumeric Symbols","CJK Unified Ideographs Extension B","CJK Compatibility Ideographs Supplement","Tags"]),kot=x4(Gy(Wot,1),MTn,25,15,[66304,66351,66352,66383,66560,66639,118784,119039,119040,119295,119808,120831,131072,173782,194560,195103,917504,917631])}function Njn(){Njn=O,BHn=new U2("OUT_T_L",0,(BY(),fHn),(OJ(),pHn),(JZ(),rHn),rHn,x4(Gy(YKn,1),iEn,21,0,[tK((Eln(),Wet),x4(Gy(cit,1),XEn,93,0,[Yet,Get]))])),FHn=new U2("OUT_T_C",1,hHn,pHn,rHn,cHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Yet,qet])),tK(Wet,x4(Gy(cit,1),XEn,93,0,[Yet,qet,zet]))])),HHn=new U2("OUT_T_R",2,lHn,pHn,rHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Yet,Uet]))])),$Hn=new U2("OUT_B_L",3,fHn,mHn,aHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Vet,Get]))])),AHn=new U2("OUT_B_C",4,hHn,mHn,aHn,cHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Vet,qet])),tK(Wet,x4(Gy(cit,1),XEn,93,0,[Vet,qet,zet]))])),LHn=new U2("OUT_B_R",5,lHn,mHn,aHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Vet,Uet]))])),DHn=new U2("OUT_L_T",6,lHn,mHn,rHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Get,Yet,zet]))])),xHn=new U2("OUT_L_C",7,lHn,vHn,cHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Get,Qet])),tK(Wet,x4(Gy(cit,1),XEn,93,0,[Get,Qet,zet]))])),NHn=new U2("OUT_L_B",8,lHn,pHn,aHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Get,Vet,zet]))])),_Hn=new U2("OUT_R_T",9,fHn,mHn,rHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Uet,Yet,zet]))])),KHn=new U2("OUT_R_C",10,fHn,vHn,cHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Uet,Qet])),tK(Wet,x4(Gy(cit,1),XEn,93,0,[Uet,Qet,zet]))])),RHn=new U2("OUT_R_B",11,fHn,pHn,aHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Wet,x4(Gy(cit,1),XEn,93,0,[Uet,Vet,zet]))])),CHn=new U2("IN_T_L",12,fHn,mHn,rHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,Get])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,Get,zet]))])),IHn=new U2("IN_T_C",13,hHn,mHn,rHn,cHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,qet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,qet,zet]))])),OHn=new U2("IN_T_R",14,lHn,mHn,rHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,Uet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Yet,Uet,zet]))])),SHn=new U2("IN_C_L",15,fHn,vHn,cHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,Get])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,Get,zet]))])),MHn=new U2("IN_C_C",16,hHn,vHn,cHn,cHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,qet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,qet,zet]))])),PHn=new U2("IN_C_R",17,lHn,vHn,cHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,Uet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Qet,Uet,zet]))])),EHn=new U2("IN_B_L",18,fHn,pHn,aHn,rHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,Get])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,Get,zet]))])),jHn=new U2("IN_B_C",19,hHn,pHn,aHn,cHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,qet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,qet,zet]))])),THn=new U2("IN_B_R",20,lHn,pHn,aHn,aHn,x4(Gy(YKn,1),iEn,21,0,[tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,Uet])),tK(Xet,x4(Gy(cit,1),XEn,93,0,[Vet,Uet,zet]))])),qHn=new U2(MSn,21,null,null,null,null,x4(Gy(YKn,1),iEn,21,0,[]))}function xjn(){xjn=O,vat=(YF(),gat).b,Yx(c1(aq(gat.b),0),34),Yx(c1(aq(gat.b),1),18),pat=gat.a,Yx(c1(aq(gat.a),0),34),Yx(c1(aq(gat.a),1),18),Yx(c1(aq(gat.a),2),18),Yx(c1(aq(gat.a),3),18),Yx(c1(aq(gat.a),4),18),mat=gat.o,Yx(c1(aq(gat.o),0),34),Yx(c1(aq(gat.o),1),34),kat=Yx(c1(aq(gat.o),2),18),Yx(c1(aq(gat.o),3),18),Yx(c1(aq(gat.o),4),18),Yx(c1(aq(gat.o),5),18),Yx(c1(aq(gat.o),6),18),Yx(c1(aq(gat.o),7),18),Yx(c1(aq(gat.o),8),18),Yx(c1(aq(gat.o),9),18),Yx(c1(aq(gat.o),10),18),Yx(c1(aq(gat.o),11),18),Yx(c1(aq(gat.o),12),18),Yx(c1(aq(gat.o),13),18),Yx(c1(aq(gat.o),14),18),Yx(c1(aq(gat.o),15),18),Yx(c1(cq(gat.o),0),59),Yx(c1(cq(gat.o),1),59),Yx(c1(cq(gat.o),2),59),Yx(c1(cq(gat.o),3),59),Yx(c1(cq(gat.o),4),59),Yx(c1(cq(gat.o),5),59),Yx(c1(cq(gat.o),6),59),Yx(c1(cq(gat.o),7),59),Yx(c1(cq(gat.o),8),59),Yx(c1(cq(gat.o),9),59),yat=gat.p,Yx(c1(aq(gat.p),0),34),Yx(c1(aq(gat.p),1),34),Yx(c1(aq(gat.p),2),34),Yx(c1(aq(gat.p),3),34),Yx(c1(aq(gat.p),4),18),Yx(c1(aq(gat.p),5),18),Yx(c1(cq(gat.p),0),59),Yx(c1(cq(gat.p),1),59),jat=gat.q,Yx(c1(aq(gat.q),0),34),Eat=gat.v,Yx(c1(aq(gat.v),0),18),Yx(c1(cq(gat.v),0),59),Yx(c1(cq(gat.v),1),59),Yx(c1(cq(gat.v),2),59),Tat=gat.w,Yx(c1(aq(gat.w),0),34),Yx(c1(aq(gat.w),1),34),Yx(c1(aq(gat.w),2),34),Yx(c1(aq(gat.w),3),18),Mat=gat.B,Yx(c1(aq(gat.B),0),18),Yx(c1(cq(gat.B),0),59),Yx(c1(cq(gat.B),1),59),Yx(c1(cq(gat.B),2),59),Iat=gat.Q,Yx(c1(aq(gat.Q),0),18),Yx(c1(cq(gat.Q),0),59),Cat=gat.R,Yx(c1(aq(gat.R),0),34),Oat=gat.S,Yx(c1(cq(gat.S),0),59),Yx(c1(cq(gat.S),1),59),Yx(c1(cq(gat.S),2),59),Yx(c1(cq(gat.S),3),59),Yx(c1(cq(gat.S),4),59),Yx(c1(cq(gat.S),5),59),Yx(c1(cq(gat.S),6),59),Yx(c1(cq(gat.S),7),59),Yx(c1(cq(gat.S),8),59),Yx(c1(cq(gat.S),9),59),Yx(c1(cq(gat.S),10),59),Yx(c1(cq(gat.S),11),59),Yx(c1(cq(gat.S),12),59),Yx(c1(cq(gat.S),13),59),Yx(c1(cq(gat.S),14),59),Aat=gat.T,Yx(c1(aq(gat.T),0),18),Yx(c1(aq(gat.T),2),18),$at=Yx(c1(aq(gat.T),3),18),Yx(c1(aq(gat.T),4),18),Yx(c1(cq(gat.T),0),59),Yx(c1(cq(gat.T),1),59),Yx(c1(aq(gat.T),1),18),Lat=gat.U,Yx(c1(aq(gat.U),0),34),Yx(c1(aq(gat.U),1),34),Yx(c1(aq(gat.U),2),18),Yx(c1(aq(gat.U),3),18),Yx(c1(aq(gat.U),4),18),Yx(c1(aq(gat.U),5),18),Yx(c1(cq(gat.U),0),59),Nat=gat.V,Yx(c1(aq(gat.V),0),18),xat=gat.W,Yx(c1(aq(gat.W),0),34),Yx(c1(aq(gat.W),1),34),Yx(c1(aq(gat.W),2),34),Yx(c1(aq(gat.W),3),18),Yx(c1(aq(gat.W),4),18),Yx(c1(aq(gat.W),5),18),Rat=gat.bb,Yx(c1(aq(gat.bb),0),34),Yx(c1(aq(gat.bb),1),34),Yx(c1(aq(gat.bb),2),34),Yx(c1(aq(gat.bb),3),34),Yx(c1(aq(gat.bb),4),34),Yx(c1(aq(gat.bb),5),34),Yx(c1(aq(gat.bb),6),34),Yx(c1(aq(gat.bb),7),18),Yx(c1(cq(gat.bb),0),59),Yx(c1(cq(gat.bb),1),59),Kat=gat.eb,Yx(c1(aq(gat.eb),0),34),Yx(c1(aq(gat.eb),1),34),Yx(c1(aq(gat.eb),2),34),Yx(c1(aq(gat.eb),3),34),Yx(c1(aq(gat.eb),4),34),Yx(c1(aq(gat.eb),5),34),Yx(c1(aq(gat.eb),6),18),Yx(c1(aq(gat.eb),7),18),Dat=gat.ab,Yx(c1(aq(gat.ab),0),34),Yx(c1(aq(gat.ab),1),34),Sat=gat.H,Yx(c1(aq(gat.H),0),18),Yx(c1(aq(gat.H),1),18),Yx(c1(aq(gat.H),2),18),Yx(c1(aq(gat.H),3),18),Yx(c1(aq(gat.H),4),18),Yx(c1(aq(gat.H),5),18),Yx(c1(cq(gat.H),0),59),_at=gat.db,Yx(c1(aq(gat.db),0),18),Pat=gat.M}function Djn(n){uT(n,new tun(ck(tk(rk(nk(ik(ek(new du,CIn),"ELK Layered"),"Layer-based algorithm provided by the Eclipse Layout Kernel. Arranges as many edges as possible into one direction by placing nodes into subsequent layers. This implementation supports different routing styles (straight, orthogonal, splines); if orthogonal routing is selected, arbitrary port constraints are respected, thus enabling the layout of block diagrams such as actor-oriented models or circuit schematics. Furthermore, full layout of compound graphs with cross-hierarchy edges is supported when the respective option is activated on the top level."),new Ic),CIn),tK((zfn(),vct),x4(Gy(kct,1),XEn,237,0,[dct,gct,wct,pct,lct,fct]))))),DU(n,CIn,WOn,oen(A0n)),DU(n,CIn,VOn,oen($0n)),DU(n,CIn,oPn,oen(L0n)),DU(n,CIn,QOn,oen(N0n)),DU(n,CIn,NPn,oen(D0n)),DU(n,CIn,YOn,oen(R0n)),DU(n,CIn,JOn,oen(F0n)),DU(n,CIn,ZOn,oen(H0n)),DU(n,CIn,nAn,oen(q0n)),DU(n,CIn,tAn,oen(B0n)),DU(n,CIn,LPn,oen(G0n)),DU(n,CIn,eAn,oen(U0n)),DU(n,CIn,iAn,oen(W0n)),DU(n,CIn,rAn,oen(_0n)),DU(n,CIn,WCn,oen(O0n)),DU(n,CIn,QCn,oen(x0n)),DU(n,CIn,VCn,oen(K0n)),DU(n,CIn,YCn,oen(z0n)),DU(n,CIn,$Pn,d9(0)),DU(n,CIn,JCn,oen(M0n)),DU(n,CIn,ZCn,oen(S0n)),DU(n,CIn,nOn,oen(P0n)),DU(n,CIn,uOn,oen(c2n)),DU(n,CIn,oOn,oen(Y0n)),DU(n,CIn,sOn,oen(J0n)),DU(n,CIn,hOn,oen(t2n)),DU(n,CIn,fOn,oen(Z0n)),DU(n,CIn,lOn,oen(n2n)),DU(n,CIn,bOn,oen(u2n)),DU(n,CIn,wOn,oen(a2n)),DU(n,CIn,dOn,oen(i2n)),DU(n,CIn,gOn,oen(e2n)),DU(n,CIn,pOn,oen(r2n)),DU(n,CIn,BCn,oen(Y1n)),DU(n,CIn,HCn,oen(J1n)),DU(n,CIn,zCn,oen(v1n)),DU(n,CIn,UCn,oen(m1n)),DU(n,CIn,fPn,a0n),DU(n,CIn,xOn,w1n),DU(n,CIn,cAn,0),DU(n,CIn,xPn,d9(1)),DU(n,CIn,hPn,OPn),DU(n,CIn,aAn,oen(r0n)),DU(n,CIn,KPn,oen(g0n)),DU(n,CIn,uAn,oen(k0n)),DU(n,CIn,oAn,oen(c1n)),DU(n,CIn,sAn,oen(xZn)),DU(n,CIn,OOn,oen(E1n)),DU(n,CIn,DPn,(TA(),!0)),DU(n,CIn,hAn,oen(I1n)),DU(n,CIn,fAn,oen(C1n)),DU(n,CIn,HPn,oen(n0n)),DU(n,CIn,BPn,oen(i0n)),DU(n,CIn,lAn,oen(t0n)),DU(n,CIn,bAn,o1n),DU(n,CIn,qPn,oen(U1n)),DU(n,CIn,wAn,oen(z1n)),DU(n,CIn,GPn,oen(m0n)),DU(n,CIn,dAn,oen(v0n)),DU(n,CIn,gAn,oen(y0n)),DU(n,CIn,pAn,s0n),DU(n,CIn,vAn,oen(f0n)),DU(n,CIn,mAn,oen(l0n)),DU(n,CIn,yAn,oen(b0n)),DU(n,CIn,kAn,oen(h0n)),DU(n,CIn,dCn,oen(Q0n)),DU(n,CIn,vCn,oen(B1n)),DU(n,CIn,TCn,oen(F1n)),DU(n,CIn,wCn,oen(V0n)),DU(n,CIn,mCn,oen(x1n)),DU(n,CIn,pCn,oen(r1n)),DU(n,CIn,PCn,oen(i1n)),DU(n,CIn,ICn,oen(VZn)),DU(n,CIn,LCn,oen(QZn)),DU(n,CIn,NCn,oen(JZn)),DU(n,CIn,xCn,oen(YZn)),DU(n,CIn,OCn,oen(e1n)),DU(n,CIn,hCn,oen(q1n)),DU(n,CIn,fCn,oen(G1n)),DU(n,CIn,sCn,oen(A1n)),DU(n,CIn,DCn,oen(Z1n)),DU(n,CIn,_Cn,oen(W1n)),DU(n,CIn,oCn,oen(k1n)),DU(n,CIn,FCn,oen(Q1n)),DU(n,CIn,qCn,oen(g1n)),DU(n,CIn,GCn,oen(p1n)),DU(n,CIn,jAn,oen(WZn)),DU(n,CIn,KCn,oen(X1n)),DU(n,CIn,eOn,oen(BZn)),DU(n,CIn,iOn,oen(FZn)),DU(n,CIn,tOn,oen(_Zn)),DU(n,CIn,rOn,oen(M1n)),DU(n,CIn,cOn,oen(T1n)),DU(n,CIn,aOn,oen(S1n)),DU(n,CIn,eIn,oen(e0n)),DU(n,CIn,EAn,oen($1n)),DU(n,CIn,sPn,oen(y1n)),DU(n,CIn,TAn,oen(f1n)),DU(n,CIn,_Pn,oen(h1n)),DU(n,CIn,CCn,oen(ZZn)),DU(n,CIn,MAn,oen(p0n)),DU(n,CIn,SAn,oen(KZn)),DU(n,CIn,PAn,oen(P1n)),DU(n,CIn,IAn,oen(w0n)),DU(n,CIn,CAn,oen(u0n)),DU(n,CIn,OAn,oen(o0n)),DU(n,CIn,jCn,oen(R1n)),DU(n,CIn,ECn,oen(K1n)),DU(n,CIn,AAn,oen(E0n)),DU(n,CIn,lCn,oen(DZn)),DU(n,CIn,MCn,oen(_1n)),DU(n,CIn,vOn,oen(l1n)),DU(n,CIn,mOn,oen(s1n)),DU(n,CIn,$An,oen(H1n)),DU(n,CIn,SCn,oen(L1n)),DU(n,CIn,RCn,oen(V1n)),DU(n,CIn,LAn,oen(X0n)),DU(n,CIn,uCn,oen(u1n)),DU(n,CIn,bCn,oen(j0n)),DU(n,CIn,XCn,oen(d1n)),DU(n,CIn,yCn,oen(N1n)),DU(n,CIn,ACn,oen(n1n)),DU(n,CIn,NAn,oen(O1n)),DU(n,CIn,kCn,oen(D1n)),DU(n,CIn,$Cn,oen(t1n)),DU(n,CIn,yOn,oen(XZn)),DU(n,CIn,EOn,oen(zZn)),DU(n,CIn,TOn,oen(qZn)),DU(n,CIn,MOn,oen(GZn)),DU(n,CIn,kOn,oen(UZn)),DU(n,CIn,jOn,oen(HZn)),DU(n,CIn,gCn,oen(j1n))}function Rjn(n,t){var e;return dot||(dot=new rp,got=new rp,Ljn(),Ljn(),$nn(e=new cU(4),"\t\n\r\r "),GG(dot,SKn,e),GG(got,SKn,nvn(e)),$nn(e=new cU(4),CKn),GG(dot,TKn,e),GG(got,TKn,nvn(e)),$nn(e=new cU(4),CKn),GG(dot,TKn,e),GG(got,TKn,nvn(e)),$nn(e=new cU(4),OKn),fmn(e,Yx(aG(dot,TKn),117)),GG(dot,MKn,e),GG(got,MKn,nvn(e)),$nn(e=new cU(4),"-.0:AZ__az··ÀÖØöøıĴľŁňŊžƀǃǍǰǴǵǺȗɐʨʻˁːˑ̀͠͡ͅΆΊΌΌΎΡΣώϐϖϚϚϜϜϞϞϠϠϢϳЁЌЎяёќўҁ҃҆ҐӄӇӈӋӌӐӫӮӵӸӹԱՖՙՙաֆֹֻֽֿֿׁׂ֑֣֡ׄׄאתװײءغـْ٠٩ٰڷںھۀێېۓە۪ۭۨ۰۹ँःअह़्॑॔क़ॣ०९ঁঃঅঌএঐওনপরললশহ়়াৄেৈো্ৗৗড়ঢ়য়ৣ০ৱਂਂਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹ਼਼ਾੂੇੈੋ੍ਖ਼ੜਫ਼ਫ਼੦ੴઁઃઅઋઍઍએઑઓનપરલળવહ઼ૅેૉો્ૠૠ૦૯ଁଃଅଌଏଐଓନପରଲଳଶହ଼ୃେୈୋ୍ୖୗଡ଼ଢ଼ୟୡ୦୯ஂஃஅஊஎஐஒகஙசஜஜஞடணதநபமவஷஹாூெைொ்ௗௗ௧௯ఁఃఅఌఎఐఒనపళవహాౄెైొ్ౕౖౠౡ౦౯ಂಃಅಌಎಐಒನಪಳವಹಾೄೆೈೊ್ೕೖೞೞೠೡ೦೯ംഃഅഌഎഐഒനപഹാൃെൈൊ്ൗൗൠൡ൦൯กฮะฺเ๎๐๙ກຂຄຄງຈຊຊຍຍດທນຟມຣລລວວສຫອຮະູົຽເໄໆໆ່ໍ໐໙༘༙༠༩༹༹༵༵༷༷༾ཇཉཀྵ྄ཱ྆ྋྐྕྗྗྙྭྱྷྐྵྐྵႠჅაჶᄀᄀᄂᄃᄅᄇᄉᄉᄋᄌᄎᄒᄼᄼᄾᄾᅀᅀᅌᅌᅎᅎᅐᅐᅔᅕᅙᅙᅟᅡᅣᅣᅥᅥᅧᅧᅩᅩᅭᅮᅲᅳᅵᅵᆞᆞᆨᆨᆫᆫᆮᆯᆷᆸᆺᆺᆼᇂᇫᇫᇰᇰᇹᇹḀẛẠỹἀἕἘἝἠὅὈὍὐὗὙὙὛὛὝὝὟώᾀᾴᾶᾼιιῂῄῆῌῐΐῖΊῠῬῲῴῶῼ⃐⃜⃡⃡ΩΩKÅ℮℮ↀↂ々々〇〇〡〯〱〵ぁゔ゙゚ゝゞァヺーヾㄅㄬ一龥가힣"),GG(dot,PKn,e),GG(got,PKn,nvn(e)),$nn(e=new cU(4),OKn),zwn(e,95,95),zwn(e,58,58),GG(dot,IKn,e),GG(got,IKn,nvn(e))),Yx(aG(t?dot:got,n),136)}function Kjn(n){return _N("_UI_EMFDiagnostic_marker",n)?"EMF Problem":_N("_UI_CircularContainment_diagnostic",n)?"An object may not circularly contain itself":_N(Cxn,n)?"Wrong character.":_N(Oxn,n)?"Invalid reference number.":_N(Axn,n)?"A character is required after \\.":_N($xn,n)?"'?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'?":_N(Lxn,n)?"'(?<' or '(? toIndex: ",DMn=", toIndex: ",RMn="Index: ",KMn=", Size: ",_Mn="org.eclipse.elk.alg.common",FMn={62:1},BMn="org.eclipse.elk.alg.common.compaction",HMn="Scanline/EventHandler",qMn="org.eclipse.elk.alg.common.compaction.oned",GMn="CNode belongs to another CGroup.",zMn="ISpacingsHandler/1",UMn="The ",XMn=" instance has been finished already.",WMn="The direction ",VMn=" is not supported by the CGraph instance.",QMn="OneDimensionalCompactor",YMn="OneDimensionalCompactor/lambda$0$Type",JMn="Quadruplet",ZMn="ScanlineConstraintCalculator",nSn="ScanlineConstraintCalculator/ConstraintsScanlineHandler",tSn="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",eSn="ScanlineConstraintCalculator/Timestamp",iSn="ScanlineConstraintCalculator/lambda$0$Type",rSn={169:1,45:1},cSn="org.eclipse.elk.alg.common.compaction.options",aSn="org.eclipse.elk.core.data",uSn="org.eclipse.elk.polyomino.traversalStrategy",oSn="org.eclipse.elk.polyomino.lowLevelSort",sSn="org.eclipse.elk.polyomino.highLevelSort",hSn="org.eclipse.elk.polyomino.fill",fSn={130:1},lSn="polyomino",bSn="org.eclipse.elk.alg.common.networksimplex",wSn={177:1,3:1,4:1},dSn="org.eclipse.elk.alg.common.nodespacing",gSn="org.eclipse.elk.alg.common.nodespacing.cellsystem",pSn="CENTER",vSn={212:1,326:1},mSn={3:1,4:1,5:1,595:1},ySn="LEFT",kSn="RIGHT",jSn="Vertical alignment cannot be null",ESn="BOTTOM",TSn="org.eclipse.elk.alg.common.nodespacing.internal",MSn="UNDEFINED",SSn=.01,PSn="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",ISn="LabelPlacer/lambda$0$Type",CSn="LabelPlacer/lambda$1$Type",OSn="portRatioOrPosition",ASn="org.eclipse.elk.alg.common.overlaps",$Sn="DOWN",LSn="org.eclipse.elk.alg.common.polyomino",NSn="NORTH",xSn="EAST",DSn="SOUTH",RSn="WEST",KSn="org.eclipse.elk.alg.common.polyomino.structures",_Sn="Direction",FSn="Grid is only of size ",BSn=". Requested point (",HSn=") is out of bounds.",qSn=" Given center based coordinates were (",GSn="org.eclipse.elk.graph.properties",zSn="IPropertyHolder",USn={3:1,94:1,134:1},XSn="org.eclipse.elk.alg.common.spore",WSn="org.eclipse.elk.alg.common.utils",VSn={209:1},QSn="org.eclipse.elk.core",YSn="Connected Components Compaction",JSn="org.eclipse.elk.alg.disco",ZSn="org.eclipse.elk.alg.disco.graph",nPn="org.eclipse.elk.alg.disco.options",tPn="CompactionStrategy",ePn="org.eclipse.elk.disco.componentCompaction.strategy",iPn="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",rPn="org.eclipse.elk.disco.debug.discoGraph",cPn="org.eclipse.elk.disco.debug.discoPolys",aPn="componentCompaction",uPn="org.eclipse.elk.disco",oPn="org.eclipse.elk.spacing.componentComponent",sPn="org.eclipse.elk.edge.thickness",hPn="org.eclipse.elk.aspectRatio",fPn="org.eclipse.elk.padding",lPn="org.eclipse.elk.alg.disco.transform",bPn=1.5707963267948966,wPn=17976931348623157e292,dPn={3:1,4:1,5:1,192:1},gPn={3:1,6:1,4:1,5:1,106:1,120:1},pPn="org.eclipse.elk.alg.force",vPn="ComponentsProcessor",mPn="ComponentsProcessor/1",yPn="org.eclipse.elk.alg.force.graph",kPn="Component Layout",jPn="org.eclipse.elk.alg.force.model",EPn="org.eclipse.elk.force.model",TPn="org.eclipse.elk.force.iterations",MPn="org.eclipse.elk.force.repulsivePower",SPn="org.eclipse.elk.force.temperature",PPn=.001,IPn="org.eclipse.elk.force.repulsion",CPn="org.eclipse.elk.alg.force.options",OPn=1.600000023841858,APn="org.eclipse.elk.force",$Pn="org.eclipse.elk.priority",LPn="org.eclipse.elk.spacing.nodeNode",NPn="org.eclipse.elk.spacing.edgeLabel",xPn="org.eclipse.elk.randomSeed",DPn="org.eclipse.elk.separateConnectedComponents",RPn="org.eclipse.elk.interactive",KPn="org.eclipse.elk.portConstraints",_Pn="org.eclipse.elk.edgeLabels.inline",FPn="org.eclipse.elk.omitNodeMicroLayout",BPn="org.eclipse.elk.nodeSize.options",HPn="org.eclipse.elk.nodeSize.constraints",qPn="org.eclipse.elk.nodeLabels.placement",GPn="org.eclipse.elk.portLabels.placement",zPn="origin",UPn="random",XPn="boundingBox.upLeft",WPn="boundingBox.lowRight",VPn="org.eclipse.elk.stress.fixed",QPn="org.eclipse.elk.stress.desiredEdgeLength",YPn="org.eclipse.elk.stress.dimension",JPn="org.eclipse.elk.stress.epsilon",ZPn="org.eclipse.elk.stress.iterationLimit",nIn="org.eclipse.elk.stress",tIn="ELK Stress",eIn="org.eclipse.elk.nodeSize.minimum",iIn="org.eclipse.elk.alg.force.stress",rIn="Layered layout",cIn="org.eclipse.elk.alg.layered",aIn="org.eclipse.elk.alg.layered.compaction.components",uIn="org.eclipse.elk.alg.layered.compaction.oned",oIn="org.eclipse.elk.alg.layered.compaction.oned.algs",sIn="org.eclipse.elk.alg.layered.compaction.recthull",hIn="org.eclipse.elk.alg.layered.components",fIn="NONE",lIn={3:1,6:1,4:1,9:1,5:1,122:1},bIn={3:1,6:1,4:1,5:1,141:1,106:1,120:1},wIn="org.eclipse.elk.alg.layered.compound",dIn={51:1},gIn="org.eclipse.elk.alg.layered.graph",pIn=" -> ",vIn="Not supported by LGraph",mIn="Port side is undefined",yIn={3:1,6:1,4:1,5:1,474:1,141:1,106:1,120:1},kIn={3:1,6:1,4:1,5:1,141:1,193:1,203:1,106:1,120:1},jIn={3:1,6:1,4:1,5:1,141:1,1943:1,203:1,106:1,120:1},EIn="([{\"' \t\r\n",TIn=")]}\"' \t\r\n",MIn="The given string contains parts that cannot be parsed as numbers.",SIn="org.eclipse.elk.core.math",PIn={3:1,4:1,142:1,207:1,414:1},IIn={3:1,4:1,116:1,207:1,414:1},CIn="org.eclipse.elk.layered",OIn="org.eclipse.elk.alg.layered.graph.transform",AIn="ElkGraphImporter",$In="ElkGraphImporter/lambda$0$Type",LIn="ElkGraphImporter/lambda$1$Type",NIn="ElkGraphImporter/lambda$2$Type",xIn="ElkGraphImporter/lambda$4$Type",DIn="Node margin calculation",RIn="org.eclipse.elk.alg.layered.intermediate",KIn="ONE_SIDED_GREEDY_SWITCH",_In="TWO_SIDED_GREEDY_SWITCH",FIn="No implementation is available for the layout processor ",BIn="IntermediateProcessorStrategy",HIn="Node '",qIn="FIRST_SEPARATE",GIn="LAST_SEPARATE",zIn="Odd port side processing",UIn="org.eclipse.elk.alg.layered.intermediate.compaction",XIn="org.eclipse.elk.alg.layered.intermediate.greedyswitch",WIn="org.eclipse.elk.alg.layered.p3order.counting",VIn={225:1},QIn="org.eclipse.elk.alg.layered.intermediate.loops",YIn="org.eclipse.elk.alg.layered.intermediate.loops.ordering",JIn="org.eclipse.elk.alg.layered.intermediate.loops.routing",ZIn="org.eclipse.elk.alg.layered.intermediate.preserveorder",nCn="org.eclipse.elk.alg.layered.intermediate.wrapping",tCn="org.eclipse.elk.alg.layered.options",eCn="INTERACTIVE",iCn="DEPTH_FIRST",rCn="EDGE_LENGTH",cCn="SELF_LOOPS",aCn="firstTryWithInitialOrder",uCn="org.eclipse.elk.layered.directionCongruency",oCn="org.eclipse.elk.layered.feedbackEdges",sCn="org.eclipse.elk.layered.interactiveReferencePoint",hCn="org.eclipse.elk.layered.mergeEdges",fCn="org.eclipse.elk.layered.mergeHierarchyEdges",lCn="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",bCn="org.eclipse.elk.layered.portSortingStrategy",wCn="org.eclipse.elk.layered.thoroughness",dCn="org.eclipse.elk.layered.unnecessaryBendpoints",gCn="org.eclipse.elk.layered.generatePositionAndLayerIds",pCn="org.eclipse.elk.layered.cycleBreaking.strategy",vCn="org.eclipse.elk.layered.layering.strategy",mCn="org.eclipse.elk.layered.layering.layerConstraint",yCn="org.eclipse.elk.layered.layering.layerChoiceConstraint",kCn="org.eclipse.elk.layered.layering.layerId",jCn="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",ECn="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",TCn="org.eclipse.elk.layered.layering.nodePromotion.strategy",MCn="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",SCn="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",PCn="org.eclipse.elk.layered.crossingMinimization.strategy",ICn="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",CCn="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",OCn="org.eclipse.elk.layered.crossingMinimization.semiInteractive",ACn="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",$Cn="org.eclipse.elk.layered.crossingMinimization.positionId",LCn="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",NCn="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",xCn="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",DCn="org.eclipse.elk.layered.nodePlacement.strategy",RCn="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",KCn="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",_Cn="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",FCn="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",BCn="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",HCn="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",qCn="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",GCn="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",zCn="org.eclipse.elk.layered.edgeRouting.splines.mode",UCn="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",XCn="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",WCn="org.eclipse.elk.layered.spacing.baseValue",VCn="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",QCn="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",YCn="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",JCn="org.eclipse.elk.layered.priority.direction",ZCn="org.eclipse.elk.layered.priority.shortness",nOn="org.eclipse.elk.layered.priority.straightness",tOn="org.eclipse.elk.layered.compaction.connectedComponents",eOn="org.eclipse.elk.layered.compaction.postCompaction.strategy",iOn="org.eclipse.elk.layered.compaction.postCompaction.constraints",rOn="org.eclipse.elk.layered.highDegreeNodes.treatment",cOn="org.eclipse.elk.layered.highDegreeNodes.threshold",aOn="org.eclipse.elk.layered.highDegreeNodes.treeHeight",uOn="org.eclipse.elk.layered.wrapping.strategy",oOn="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",sOn="org.eclipse.elk.layered.wrapping.correctionFactor",hOn="org.eclipse.elk.layered.wrapping.cutting.strategy",fOn="org.eclipse.elk.layered.wrapping.cutting.cuts",lOn="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",bOn="org.eclipse.elk.layered.wrapping.validify.strategy",wOn="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",dOn="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",gOn="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",pOn="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",vOn="org.eclipse.elk.layered.edgeLabels.sideSelection",mOn="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",yOn="org.eclipse.elk.layered.considerModelOrder.strategy",kOn="org.eclipse.elk.layered.considerModelOrder.noModelOrder",jOn="org.eclipse.elk.layered.considerModelOrder.components",EOn="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",TOn="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",MOn="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",SOn="layering",POn="layering.minWidth",IOn="layering.nodePromotion",COn="crossingMinimization",OOn="org.eclipse.elk.hierarchyHandling",AOn="crossingMinimization.greedySwitch",$On="nodePlacement",LOn="nodePlacement.bk",NOn="edgeRouting",xOn="org.eclipse.elk.edgeRouting",DOn="spacing",ROn="priority",KOn="compaction",_On="compaction.postCompaction",FOn="Specifies whether and how post-process compaction is applied.",BOn="highDegreeNodes",HOn="wrapping",qOn="wrapping.cutting",GOn="wrapping.validify",zOn="wrapping.multiEdge",UOn="edgeLabels",XOn="considerModelOrder",WOn="org.eclipse.elk.spacing.commentComment",VOn="org.eclipse.elk.spacing.commentNode",QOn="org.eclipse.elk.spacing.edgeEdge",YOn="org.eclipse.elk.spacing.edgeNode",JOn="org.eclipse.elk.spacing.labelLabel",ZOn="org.eclipse.elk.spacing.labelPortHorizontal",nAn="org.eclipse.elk.spacing.labelPortVertical",tAn="org.eclipse.elk.spacing.labelNode",eAn="org.eclipse.elk.spacing.nodeSelfLoop",iAn="org.eclipse.elk.spacing.portPort",rAn="org.eclipse.elk.spacing.individual",cAn="org.eclipse.elk.port.borderOffset",aAn="org.eclipse.elk.noLayout",uAn="org.eclipse.elk.port.side",oAn="org.eclipse.elk.debugMode",sAn="org.eclipse.elk.alignment",hAn="org.eclipse.elk.insideSelfLoops.activate",fAn="org.eclipse.elk.insideSelfLoops.yo",lAn="org.eclipse.elk.nodeSize.fixedGraphSize",bAn="org.eclipse.elk.direction",wAn="org.eclipse.elk.nodeLabels.padding",dAn="org.eclipse.elk.portLabels.nextToPortIfPossible",gAn="org.eclipse.elk.portLabels.treatAsGroup",pAn="org.eclipse.elk.portAlignment.default",vAn="org.eclipse.elk.portAlignment.north",mAn="org.eclipse.elk.portAlignment.south",yAn="org.eclipse.elk.portAlignment.west",kAn="org.eclipse.elk.portAlignment.east",jAn="org.eclipse.elk.contentAlignment",EAn="org.eclipse.elk.junctionPoints",TAn="org.eclipse.elk.edgeLabels.placement",MAn="org.eclipse.elk.port.index",SAn="org.eclipse.elk.commentBox",PAn="org.eclipse.elk.hypernode",IAn="org.eclipse.elk.port.anchor",CAn="org.eclipse.elk.partitioning.activate",OAn="org.eclipse.elk.partitioning.partition",AAn="org.eclipse.elk.position",$An="org.eclipse.elk.margins",LAn="org.eclipse.elk.spacing.portsSurrounding",NAn="org.eclipse.elk.interactiveLayout",xAn="org.eclipse.elk.core.util",DAn={3:1,4:1,5:1,593:1},RAn="NETWORK_SIMPLEX",KAn={123:1,51:1},_An="org.eclipse.elk.alg.layered.p1cycles",FAn="org.eclipse.elk.alg.layered.p2layers",BAn={402:1,225:1},HAn={832:1,3:1,4:1},qAn="org.eclipse.elk.alg.layered.p3order",GAn="org.eclipse.elk.alg.layered.p4nodes",zAn={3:1,4:1,5:1,840:1},UAn=1e-5,XAn="org.eclipse.elk.alg.layered.p4nodes.bk",WAn="org.eclipse.elk.alg.layered.p5edges",VAn="org.eclipse.elk.alg.layered.p5edges.orthogonal",QAn="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",YAn=1e-6,JAn="org.eclipse.elk.alg.layered.p5edges.splines",ZAn=.09999999999999998,n$n=1e-8,t$n=4.71238898038469,e$n=3.141592653589793,i$n="org.eclipse.elk.alg.mrtree",r$n="org.eclipse.elk.alg.mrtree.graph",c$n="org.eclipse.elk.alg.mrtree.intermediate",a$n="Set neighbors in level",u$n="DESCENDANTS",o$n="org.eclipse.elk.mrtree.weighting",s$n="org.eclipse.elk.mrtree.searchOrder",h$n="org.eclipse.elk.alg.mrtree.options",f$n="org.eclipse.elk.mrtree",l$n="org.eclipse.elk.tree",b$n="org.eclipse.elk.alg.radial",w$n=6.283185307179586,d$n=5e-324,g$n="org.eclipse.elk.alg.radial.intermediate",p$n="org.eclipse.elk.alg.radial.intermediate.compaction",v$n={3:1,4:1,5:1,106:1},m$n="org.eclipse.elk.alg.radial.intermediate.optimization",y$n="No implementation is available for the layout option ",k$n="org.eclipse.elk.alg.radial.options",j$n="org.eclipse.elk.radial.orderId",E$n="org.eclipse.elk.radial.radius",T$n="org.eclipse.elk.radial.compactor",M$n="org.eclipse.elk.radial.compactionStepSize",S$n="org.eclipse.elk.radial.sorter",P$n="org.eclipse.elk.radial.wedgeCriteria",I$n="org.eclipse.elk.radial.optimizationCriteria",C$n="org.eclipse.elk.radial",O$n="org.eclipse.elk.alg.radial.p1position.wedge",A$n="org.eclipse.elk.alg.radial.sorting",$$n=5.497787143782138,L$n=3.9269908169872414,N$n=2.356194490192345,x$n="org.eclipse.elk.alg.rectpacking",D$n="org.eclipse.elk.alg.rectpacking.firstiteration",R$n="org.eclipse.elk.alg.rectpacking.options",K$n="org.eclipse.elk.rectpacking.optimizationGoal",_$n="org.eclipse.elk.rectpacking.lastPlaceShift",F$n="org.eclipse.elk.rectpacking.currentPosition",B$n="org.eclipse.elk.rectpacking.desiredPosition",H$n="org.eclipse.elk.rectpacking.onlyFirstIteration",q$n="org.eclipse.elk.rectpacking.rowCompaction",G$n="org.eclipse.elk.rectpacking.expandToAspectRatio",z$n="org.eclipse.elk.rectpacking.targetWidth",U$n="org.eclipse.elk.expandNodes",X$n="org.eclipse.elk.rectpacking",W$n="org.eclipse.elk.alg.rectpacking.util",V$n="No implementation available for ",Q$n="org.eclipse.elk.alg.spore",Y$n="org.eclipse.elk.alg.spore.options",J$n="org.eclipse.elk.sporeCompaction",Z$n="org.eclipse.elk.underlyingLayoutAlgorithm",nLn="org.eclipse.elk.processingOrder.treeConstruction",tLn="org.eclipse.elk.processingOrder.spanningTreeCostFunction",eLn="org.eclipse.elk.processingOrder.preferredRoot",iLn="org.eclipse.elk.processingOrder.rootSelection",rLn="org.eclipse.elk.structure.structureExtractionStrategy",cLn="org.eclipse.elk.compaction.compactionStrategy",aLn="org.eclipse.elk.compaction.orthogonal",uLn="org.eclipse.elk.overlapRemoval.maxIterations",oLn="org.eclipse.elk.overlapRemoval.runScanline",sLn="processingOrder",hLn="overlapRemoval",fLn="org.eclipse.elk.sporeOverlap",lLn="org.eclipse.elk.alg.spore.p1structure",bLn="org.eclipse.elk.alg.spore.p2processingorder",wLn="org.eclipse.elk.alg.spore.p3execution",dLn="Invalid index: ",gLn="org.eclipse.elk.core.alg",pLn={331:1},vLn={288:1},mLn="Make sure its type is registered with the ",yLn=" utility class.",kLn="true",jLn="false",ELn="Couldn't clone property '",TLn=.05,MLn="org.eclipse.elk.core.options",SLn=1.2999999523162842,PLn="org.eclipse.elk.box",ILn="org.eclipse.elk.box.packingMode",CLn="org.eclipse.elk.algorithm",OLn="org.eclipse.elk.resolvedAlgorithm",ALn="org.eclipse.elk.bendPoints",$Ln="org.eclipse.elk.labelManager",LLn="org.eclipse.elk.scaleFactor",NLn="org.eclipse.elk.animate",xLn="org.eclipse.elk.animTimeFactor",DLn="org.eclipse.elk.layoutAncestors",RLn="org.eclipse.elk.maxAnimTime",KLn="org.eclipse.elk.minAnimTime",_Ln="org.eclipse.elk.progressBar",FLn="org.eclipse.elk.validateGraph",BLn="org.eclipse.elk.validateOptions",HLn="org.eclipse.elk.zoomToFit",qLn="org.eclipse.elk.font.name",GLn="org.eclipse.elk.font.size",zLn="org.eclipse.elk.edge.type",ULn="partitioning",XLn="nodeLabels",WLn="portAlignment",VLn="nodeSize",QLn="port",YLn="portLabels",JLn="insideSelfLoops",ZLn="org.eclipse.elk.fixed",nNn="org.eclipse.elk.random",tNn="port must have a parent node to calculate the port side",eNn="The edge needs to have exactly one edge section. Found: ",iNn="org.eclipse.elk.core.util.adapters",rNn="org.eclipse.emf.ecore",cNn="org.eclipse.elk.graph",aNn="EMapPropertyHolder",uNn="ElkBendPoint",oNn="ElkGraphElement",sNn="ElkConnectableShape",hNn="ElkEdge",fNn="ElkEdgeSection",lNn="EModelElement",bNn="ENamedElement",wNn="ElkLabel",dNn="ElkNode",gNn="ElkPort",pNn={92:1,90:1},vNn="org.eclipse.emf.common.notify.impl",mNn="The feature '",yNn="' is not a valid changeable feature",kNn="Expecting null",jNn="' is not a valid feature",ENn="The feature ID",TNn=" is not a valid feature ID",MNn=32768,SNn={105:1,92:1,90:1,56:1,49:1,97:1},PNn="org.eclipse.emf.ecore.impl",INn="org.eclipse.elk.graph.impl",CNn="Recursive containment not allowed for ",ONn="The datatype '",ANn="' is not a valid classifier",$Nn="The value '",LNn={190:1,3:1,4:1},NNn="The class '",xNn="http://www.eclipse.org/elk/ElkGraph",DNn=1024,RNn="property",KNn="value",_Nn="source",FNn="properties",BNn="identifier",HNn="height",qNn="width",GNn="parent",zNn="text",UNn="children",XNn="hierarchical",WNn="sources",VNn="targets",QNn="sections",YNn="bendPoints",JNn="outgoingShape",ZNn="incomingShape",nxn="outgoingSections",txn="incomingSections",exn="org.eclipse.emf.common.util",ixn="Severe implementation error in the Json to ElkGraph importer.",rxn="id",cxn="org.eclipse.elk.graph.json",axn="Unhandled parameter types: ",uxn="startPoint",oxn="An edge must have at least one source and one target (edge id: '",sxn="').",hxn="Referenced edge section does not exist: ",fxn=" (edge id: '",lxn="target",bxn="sourcePoint",wxn="targetPoint",dxn="group",gxn="name",pxn="connectableShape cannot be null",vxn="edge cannot be null",mxn="Passed edge is not 'simple'.",yxn="org.eclipse.elk.graph.util",kxn="The 'no duplicates' constraint is violated",jxn="targetIndex=",Exn=", size=",Txn="sourceIndex=",Mxn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1},Sxn={3:1,4:1,20:1,28:1,52:1,14:1,47:1,15:1,54:1,67:1,63:1,58:1,588:1},Pxn="logging",Ixn="measureExecutionTime",Cxn="parser.parse.1",Oxn="parser.parse.2",Axn="parser.next.1",$xn="parser.next.2",Lxn="parser.next.3",Nxn="parser.next.4",xxn="parser.factor.1",Dxn="parser.factor.2",Rxn="parser.factor.3",Kxn="parser.factor.4",_xn="parser.factor.5",Fxn="parser.factor.6",Bxn="parser.atom.1",Hxn="parser.atom.2",qxn="parser.atom.3",Gxn="parser.atom.4",zxn="parser.atom.5",Uxn="parser.cc.1",Xxn="parser.cc.2",Wxn="parser.cc.3",Vxn="parser.cc.5",Qxn="parser.cc.6",Yxn="parser.cc.7",Jxn="parser.cc.8",Zxn="parser.ope.1",nDn="parser.ope.2",tDn="parser.ope.3",eDn="parser.descape.1",iDn="parser.descape.2",rDn="parser.descape.3",cDn="parser.descape.4",aDn="parser.descape.5",uDn="parser.process.1",oDn="parser.quantifier.1",sDn="parser.quantifier.2",hDn="parser.quantifier.3",fDn="parser.quantifier.4",lDn="parser.quantifier.5",bDn="org.eclipse.emf.common.notify",wDn={415:1,672:1},dDn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1},gDn={366:1,143:1},pDn="index=",vDn={3:1,4:1,5:1,126:1},mDn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,58:1},yDn={3:1,6:1,4:1,5:1,192:1},kDn={3:1,4:1,5:1,165:1,367:1},jDn=";/?:@&=+$,",EDn="invalid authority: ",TDn="EAnnotation",MDn="ETypedElement",SDn="EStructuralFeature",PDn="EAttribute",IDn="EClassifier",CDn="EEnumLiteral",ODn="EGenericType",ADn="EOperation",$Dn="EParameter",LDn="EReference",NDn="ETypeParameter",xDn="org.eclipse.emf.ecore.util",DDn={76:1},RDn={3:1,20:1,14:1,15:1,58:1,589:1,76:1,69:1,95:1},KDn="org.eclipse.emf.ecore.util.FeatureMap$Entry",_Dn=8192,FDn=2048,BDn="byte",HDn="char",qDn="double",GDn="float",zDn="int",UDn="long",XDn="short",WDn="java.lang.Object",VDn={3:1,4:1,5:1,247:1},QDn={3:1,4:1,5:1,673:1},YDn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,69:1},JDn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,69:1,95:1},ZDn="mixed",nRn="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",tRn="kind",eRn={3:1,4:1,5:1,674:1},iRn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,76:1,69:1,95:1},rRn={20:1,28:1,52:1,14:1,15:1,58:1,69:1},cRn={47:1,125:1,279:1},aRn={72:1,332:1},uRn="The value of type '",oRn="' must be of type '",sRn=1316,hRn="http://www.eclipse.org/emf/2002/Ecore",fRn=-32768,lRn="constraints",bRn="baseType",wRn="getEStructuralFeature",dRn="getFeatureID",gRn="feature",pRn="getOperationID",vRn="operation",mRn="defaultValue",yRn="eTypeParameters",kRn="isInstance",jRn="getEEnumLiteral",ERn="eContainingClass",TRn={55:1},MRn={3:1,4:1,5:1,119:1},SRn="org.eclipse.emf.ecore.resource",PRn={92:1,90:1,591:1,1935:1},IRn="org.eclipse.emf.ecore.resource.impl",CRn="unspecified",ORn="simple",ARn="attribute",$Rn="attributeWildcard",LRn="element",NRn="elementWildcard",xRn="collapse",DRn="itemType",RRn="namespace",KRn="##targetNamespace",_Rn="whiteSpace",FRn="wildcards",BRn="http://www.eclipse.org/emf/2003/XMLType",HRn="##any",qRn="uninitialized",GRn="The multiplicity constraint is violated",zRn="org.eclipse.emf.ecore.xml.type",URn="ProcessingInstruction",XRn="SimpleAnyType",WRn="XMLTypeDocumentRoot",VRn="org.eclipse.emf.ecore.xml.type.impl",QRn="INF",YRn="processing",JRn="ENTITIES_._base",ZRn="minLength",nKn="ENTITY",tKn="NCName",eKn="IDREFS_._base",iKn="integer",rKn="token",cKn="pattern",aKn="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",uKn="\\i\\c*",oKn="[\\i-[:]][\\c-[:]]*",sKn="nonPositiveInteger",hKn="maxInclusive",fKn="NMTOKEN",lKn="NMTOKENS_._base",bKn="nonNegativeInteger",wKn="minInclusive",dKn="normalizedString",gKn="unsignedByte",pKn="unsignedInt",vKn="18446744073709551615",mKn="unsignedShort",yKn="processingInstruction",kKn="org.eclipse.emf.ecore.xml.type.internal",jKn=1114111,EKn="Internal Error: shorthands: \\u",TKn="xml:isDigit",MKn="xml:isWord",SKn="xml:isSpace",PKn="xml:isNameChar",IKn="xml:isInitialNameChar",CKn="09٠٩۰۹०९০৯੦੯૦૯୦୯௧௯౦౯೦೯൦൯๐๙໐໙༠༩",OKn="AZazÀÖØöøıĴľŁňŊžƀǃǍǰǴǵǺȗɐʨʻˁΆΆΈΊΌΌΎΡΣώϐϖϚϚϜϜϞϞϠϠϢϳЁЌЎяёќўҁҐӄӇӈӋӌӐӫӮӵӸӹԱՖՙՙաֆאתװײءغفيٱڷںھۀێېۓەەۥۦअहऽऽक़ॡঅঌএঐওনপরললশহড়ঢ়য়ৡৰৱਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹਖ਼ੜਫ਼ਫ਼ੲੴઅઋઍઍએઑઓનપરલળવહઽઽૠૠଅଌଏଐଓନପରଲଳଶହଽଽଡ଼ଢ଼ୟୡஅஊஎஐஒகஙசஜஜஞடணதநபமவஷஹఅఌఎఐఒనపళవహౠౡಅಌಎಐಒನಪಳವಹೞೞೠೡഅഌഎഐഒനപഹൠൡกฮะะาำเๅກຂຄຄງຈຊຊຍຍດທນຟມຣລລວວສຫອຮະະາຳຽຽເໄཀཇཉཀྵႠჅაჶᄀᄀᄂᄃᄅᄇᄉᄉᄋᄌᄎᄒᄼᄼᄾᄾᅀᅀᅌᅌᅎᅎᅐᅐᅔᅕᅙᅙᅟᅡᅣᅣᅥᅥᅧᅧᅩᅩᅭᅮᅲᅳᅵᅵᆞᆞᆨᆨᆫᆫᆮᆯᆷᆸᆺᆺᆼᇂᇫᇫᇰᇰᇹᇹḀẛẠỹἀἕἘἝἠὅὈὍὐὗὙὙὛὛὝὝὟώᾀᾴᾶᾼιιῂῄῆῌῐΐῖΊῠῬῲῴῶῼΩΩKÅ℮℮ↀↂ〇〇〡〩ぁゔァヺㄅㄬ一龥가힣",AKn="Private Use",$Kn="ASSIGNED",LKn="\0€ÿĀſƀɏɐʯʰ˿̀ͯͰϿЀӿ԰֏֐׿؀ۿ܀ݏހ޿ऀॿঀ৿਀੿઀૿଀୿஀௿ఀ౿ಀ೿ഀൿ඀෿฀๿຀໿ༀ࿿က႟Ⴀჿᄀᇿሀ፿Ꭰ᏿᐀ᙿ ᚟ᚠ᛿ក៿᠀᢯Ḁỿἀ῿ ⁰₟₠⃏⃐⃿℀⅏⅐↏←⇿∀⋿⌀⏿␀␿⑀⑟①⓿─╿▀▟■◿☀⛿✀➿⠀⣿⺀⻿⼀⿟⿰⿿ 〿぀ゟ゠ヿ㄀ㄯ㄰㆏㆐㆟ㆠㆿ㈀㋿㌀㏿㐀䶵一鿿ꀀ꒏꒐꓏가힣豈﫿ffﭏﭐ﷿︠︯︰﹏﹐﹯ﹰ﻾\ufeff\ufeff＀￯",NKn="UNASSIGNED",xKn={3:1,117:1},DKn="org.eclipse.emf.ecore.xml.type.util",RKn={3:1,4:1,5:1,368:1},KKn="org.eclipse.xtext.xbase.lib",_Kn="Cannot add elements to a Range",FKn="Cannot set elements in a Range",BKn="Cannot remove elements from a Range",HKn="locale",qKn="default",GKn="user.agent";e.goog=e.goog||{},e.goog.global=e.goog.global||e,Bjn={},!Array.isArray&&(Array.isArray=function(n){return"[object Array]"===Object.prototype.toString.call(n)}),!Date.now&&(Date.now=function(){return(new Date).getTime()}),Wfn(1,null,{},r),Fjn.Fb=function(n){return WI(this,n)},Fjn.Gb=function(){return this.gm},Fjn.Hb=function(){return _A(this)},Fjn.Ib=function(){return Nk(V5(this))+"@"+(W5(this)>>>0).toString(16)},Fjn.equals=function(n){return this.Fb(n)},Fjn.hashCode=function(){return this.Hb()},Fjn.toString=function(){return this.Ib()},Wfn(290,1,{290:1,2026:1},m5),Fjn.le=function(n){var t;return(t=new m5).i=4,t.c=n>1?qG(this,n-1):this,t},Fjn.me=function(){return sL(this),this.b},Fjn.ne=function(){return Nk(this)},Fjn.oe=function(){return sL(this),this.k},Fjn.pe=function(){return 0!=(4&this.i)},Fjn.qe=function(){return 0!=(1&this.i)},Fjn.Ib=function(){return LZ(this)},Fjn.i=0;var zKn,UKn=EF(Jjn,"Object",1),XKn=EF(Jjn,"Class",290);Wfn(1998,1,Zjn),EF(nEn,"Optional",1998),Wfn(1170,1998,Zjn,c),Fjn.Fb=function(n){return n===this},Fjn.Hb=function(){return 2040732332},Fjn.Ib=function(){return"Optional.absent()"},Fjn.Jb=function(n){return MF(n),gm(),zKn},EF(nEn,"Absent",1170),Wfn(628,1,{},Ty),EF(nEn,"Joiner",628);var WKn=aR(nEn,"Predicate");Wfn(582,1,{169:1,582:1,3:1,45:1},Ff),Fjn.Mb=function(n){return R5(this,n)},Fjn.Lb=function(n){return R5(this,n)},Fjn.Fb=function(n){var t;return!!CO(n,582)&&(t=Yx(n,582),sln(this.a,t.a))},Fjn.Hb=function(){return K5(this.a)+306654252},Fjn.Ib=function(){return function(n){var t,e,i,r;for(t=_F(yI(new SA("Predicates."),"and"),40),e=!0,r=new Vl(n);r.b0},Fjn.Pb=function(){if(this.c>=this.d)throw hp(new Kp);return this.Xb(this.c++)},Fjn.Tb=function(){return this.c},Fjn.Ub=function(){if(this.c<=0)throw hp(new Kp);return this.Xb(--this.c)},Fjn.Vb=function(){return this.c-1},Fjn.c=0,Fjn.d=0,EF(oEn,"AbstractIndexedListIterator",386),Wfn(699,198,uEn),Fjn.Ob=function(){return X0(this)},Fjn.Pb=function(){return bJ(this)},Fjn.e=1,EF(oEn,"AbstractIterator",699),Wfn(1986,1,{224:1}),Fjn.Zb=function(){return this.f||(this.f=this.ac())},Fjn.Fb=function(n){return f6(this,n)},Fjn.Hb=function(){return W5(this.Zb())},Fjn.dc=function(){return 0==this.gc()},Fjn.ec=function(){return FK(this)},Fjn.Ib=function(){return I7(this.Zb())},EF(oEn,"AbstractMultimap",1986),Wfn(726,1986,hEn),Fjn.$b=function(){v0(this)},Fjn._b=function(n){return Ok(this,n)},Fjn.ac=function(){return new Xj(this,this.c)},Fjn.ic=function(n){return this.hc()},Fjn.bc=function(){return new iA(this,this.c)},Fjn.jc=function(){return this.mc(this.hc())},Fjn.kc=function(){return new tm(this)},Fjn.lc=function(){return lun(this.c.vc().Nc(),new u,64,this.d)},Fjn.cc=function(n){return _V(this,n)},Fjn.fc=function(n){return h8(this,n)},Fjn.gc=function(){return this.d},Fjn.mc=function(n){return XH(),new fb(n)},Fjn.nc=function(){return new nm(this)},Fjn.oc=function(){return lun(this.c.Cc().Nc(),new a,64,this.d)},Fjn.pc=function(n,t){return new dQ(this,n,t,null)},Fjn.d=0,EF(oEn,"AbstractMapBasedMultimap",726),Wfn(1631,726,hEn),Fjn.hc=function(){return new pQ(this.a)},Fjn.jc=function(){return XH(),XH(),TFn},Fjn.cc=function(n){return Yx(_V(this,n),15)},Fjn.fc=function(n){return Yx(h8(this,n),15)},Fjn.Zb=function(){return QH(this)},Fjn.Fb=function(n){return f6(this,n)},Fjn.qc=function(n){return Yx(_V(this,n),15)},Fjn.rc=function(n){return Yx(h8(this,n),15)},Fjn.mc=function(n){return lq(Yx(n,15))},Fjn.pc=function(n,t){return kX(this,n,Yx(t,15),null)},EF(oEn,"AbstractListMultimap",1631),Wfn(732,1,fEn),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return this.c.Ob()||this.e.Ob()},Fjn.Pb=function(){var n;return this.e.Ob()||(n=Yx(this.c.Pb(),42),this.b=n.cd(),this.a=Yx(n.dd(),14),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},Fjn.Qb=function(){this.e.Qb(),this.a.dc()&&this.c.Qb(),--this.d.d},EF(oEn,"AbstractMapBasedMultimap/Itr",732),Wfn(1099,732,fEn,nm),Fjn.sc=function(n,t){return t},EF(oEn,"AbstractMapBasedMultimap/1",1099),Wfn(1100,1,{},a),Fjn.Kb=function(n){return Yx(n,14).Nc()},EF(oEn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1100),Wfn(1101,732,fEn,tm),Fjn.sc=function(n,t){return new Wj(n,t)},EF(oEn,"AbstractMapBasedMultimap/2",1101);var VKn=aR(lEn,"Map");Wfn(1967,1,bEn),Fjn.wc=function(n){S3(this,n)},Fjn.yc=function(n,t,e){return Y9(this,n,t,e)},Fjn.$b=function(){this.vc().$b()},Fjn.tc=function(n){return Fin(this,n)},Fjn._b=function(n){return!!Ian(this,n,!1)},Fjn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=Yx(t.Pb(),42).dd(),iI(n)===iI(e)||null!=n&&Q8(n,e))return!0;return!1},Fjn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!CO(n,83))return!1;if(i=Yx(n,83),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=Yx(e.Pb(),42),!this.tc(t))return!1;return!0},Fjn.xc=function(n){return eI(Ian(this,n,!1))},Fjn.Hb=function(){return W4(this.vc())},Fjn.dc=function(){return 0==this.gc()},Fjn.ec=function(){return new Yl(this)},Fjn.zc=function(n,t){throw hp(new sy("Put not supported on this map"))},Fjn.Ac=function(n){i3(this,n)},Fjn.Bc=function(n){return eI(Ian(this,n,!0))},Fjn.gc=function(){return this.vc().gc()},Fjn.Ib=function(){return Fan(this)},Fjn.Cc=function(){return new Zl(this)},EF(lEn,"AbstractMap",1967),Wfn(1987,1967,bEn),Fjn.bc=function(){return new eE(this)},Fjn.vc=function(){return _K(this)},Fjn.ec=function(){return this.g||(this.g=this.bc())},Fjn.Cc=function(){return this.i||(this.i=new iE(this))},EF(oEn,"Maps/ViewCachingAbstractMap",1987),Wfn(389,1987,bEn,Xj),Fjn.xc=function(n){return function(n,t){var e,i;return(e=Yx(x8(n.d,t),14))?(i=t,n.e.pc(i,e)):null}(this,n)},Fjn.Bc=function(n){return function(n,t){var e,i;return(e=Yx(n.d.Bc(t),14))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}(this,n)},Fjn.$b=function(){this.d==this.e.c?this.e.$b():vR(new mR(this))},Fjn._b=function(n){return R8(this.d,n)},Fjn.Ec=function(){return new zf(this)},Fjn.Dc=function(){return this.Ec()},Fjn.Fb=function(n){return this===n||Q8(this.d,n)},Fjn.Hb=function(){return W5(this.d)},Fjn.ec=function(){return this.e.ec()},Fjn.gc=function(){return this.d.gc()},Fjn.Ib=function(){return I7(this.d)},EF(oEn,"AbstractMapBasedMultimap/AsMap",389);var QKn=aR(Jjn,"Iterable");Wfn(28,1,wEn),Fjn.Jc=function(n){XW(this,n)},Fjn.Lc=function(){return this.Oc()},Fjn.Nc=function(){return new Nz(this,0)},Fjn.Oc=function(){return new SR(null,this.Nc())},Fjn.Fc=function(n){throw hp(new sy("Add not supported on this collection"))},Fjn.Gc=function(n){return C2(this,n)},Fjn.$b=function(){iH(this)},Fjn.Hc=function(n){return V7(this,n,!1)},Fjn.Ic=function(n){return m4(this,n)},Fjn.dc=function(){return 0==this.gc()},Fjn.Mc=function(n){return V7(this,n,!0)},Fjn.Pc=function(){return CK(this)},Fjn.Qc=function(n){return _in(this,n)},Fjn.Ib=function(){return Gun(this)},EF(lEn,"AbstractCollection",28);var YKn=aR(lEn,"Set");Wfn(dEn,28,gEn),Fjn.Nc=function(){return new Nz(this,1)},Fjn.Fb=function(n){return stn(this,n)},Fjn.Hb=function(){return W4(this)},EF(lEn,"AbstractSet",dEn),Wfn(1970,dEn,gEn),EF(oEn,"Sets/ImprovedAbstractSet",1970),Wfn(1971,1970,gEn),Fjn.$b=function(){this.Rc().$b()},Fjn.Hc=function(n){return vnn(this,n)},Fjn.dc=function(){return this.Rc().dc()},Fjn.Mc=function(n){var t;return!!this.Hc(n)&&(t=Yx(n,42),this.Rc().ec().Mc(t.cd()))},Fjn.gc=function(){return this.Rc().gc()},EF(oEn,"Maps/EntrySet",1971),Wfn(1097,1971,gEn,zf),Fjn.Hc=function(n){return D8(this.a.d.vc(),n)},Fjn.Kc=function(){return new mR(this.a)},Fjn.Rc=function(){return this.a},Fjn.Mc=function(n){var t;return!!D8(this.a.d.vc(),n)&&(t=Yx(n,42),pV(this.a.e,t.cd()),!0)},Fjn.Nc=function(){return Vx(this.a.d.vc().Nc(),new Uf(this.a))},EF(oEn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1097),Wfn(1098,1,{},Uf),Fjn.Kb=function(n){return WW(this.a,Yx(n,42))},EF(oEn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1098),Wfn(730,1,fEn,mR),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){var n;return n=Yx(this.b.Pb(),42),this.a=Yx(n.dd(),14),WW(this.c,n)},Fjn.Ob=function(){return this.b.Ob()},Fjn.Qb=function(){x3(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},EF(oEn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",730),Wfn(532,1970,gEn,eE),Fjn.$b=function(){this.b.$b()},Fjn.Hc=function(n){return this.b._b(n)},Fjn.Jc=function(n){MF(n),this.b.wc(new gl(n))},Fjn.dc=function(){return this.b.dc()},Fjn.Kc=function(){return new Mm(this.b.vc().Kc())},Fjn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},Fjn.gc=function(){return this.b.gc()},EF(oEn,"Maps/KeySet",532),Wfn(318,532,gEn,iA),Fjn.$b=function(){vR(new $j(this,this.b.vc().Kc()))},Fjn.Ic=function(n){return this.b.ec().Ic(n)},Fjn.Fb=function(n){return this===n||Q8(this.b.ec(),n)},Fjn.Hb=function(){return W5(this.b.ec())},Fjn.Kc=function(){return new $j(this,this.b.vc().Kc())},Fjn.Mc=function(n){var t,e;return e=0,(t=Yx(this.b.Bc(n),14))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},Fjn.Nc=function(){return this.b.ec().Nc()},EF(oEn,"AbstractMapBasedMultimap/KeySet",318),Wfn(731,1,fEn,$j),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return this.c.Ob()},Fjn.Pb=function(){return this.a=Yx(this.c.Pb(),42),this.a.cd()},Fjn.Qb=function(){var n;x3(!!this.a),n=Yx(this.a.dd(),14),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},EF(oEn,"AbstractMapBasedMultimap/KeySet/1",731),Wfn(491,389,{83:1,161:1},wL),Fjn.bc=function(){return this.Sc()},Fjn.ec=function(){return this.Tc()},Fjn.Sc=function(){return new Oj(this.c,this.Uc())},Fjn.Tc=function(){return this.b||(this.b=this.Sc())},Fjn.Uc=function(){return Yx(this.d,161)},EF(oEn,"AbstractMapBasedMultimap/SortedAsMap",491),Wfn(542,491,pEn,dL),Fjn.bc=function(){return new Aj(this.a,Yx(Yx(this.d,161),171))},Fjn.Sc=function(){return new Aj(this.a,Yx(Yx(this.d,161),171))},Fjn.ec=function(){return Yx(this.b||(this.b=new Aj(this.a,Yx(Yx(this.d,161),171))),271)},Fjn.Tc=function(){return Yx(this.b||(this.b=new Aj(this.a,Yx(Yx(this.d,161),171))),271)},Fjn.Uc=function(){return Yx(Yx(this.d,161),171)},EF(oEn,"AbstractMapBasedMultimap/NavigableAsMap",542),Wfn(490,318,vEn,Oj),Fjn.Nc=function(){return this.b.ec().Nc()},EF(oEn,"AbstractMapBasedMultimap/SortedKeySet",490),Wfn(388,490,mEn,Aj),EF(oEn,"AbstractMapBasedMultimap/NavigableKeySet",388),Wfn(541,28,wEn,dQ),Fjn.Fc=function(n){var t,e;return A7(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&tN(this)),t},Fjn.Gc=function(n){var t,e,i;return!n.dc()&&(A7(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&tN(this)),t)},Fjn.$b=function(){var n;A7(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,oK(this))},Fjn.Hc=function(n){return A7(this),this.d.Hc(n)},Fjn.Ic=function(n){return A7(this),this.d.Ic(n)},Fjn.Fb=function(n){return n===this||(A7(this),Q8(this.d,n))},Fjn.Hb=function(){return A7(this),W5(this.d)},Fjn.Kc=function(){return A7(this),new rD(this)},Fjn.Mc=function(n){var t;return A7(this),(t=this.d.Mc(n))&&(--this.f.d,oK(this)),t},Fjn.gc=function(){return bI(this)},Fjn.Nc=function(){return A7(this),this.d.Nc()},Fjn.Ib=function(){return A7(this),I7(this.d)},EF(oEn,"AbstractMapBasedMultimap/WrappedCollection",541);var JKn=aR(lEn,"List");Wfn(728,541,{20:1,28:1,14:1,15:1},LK),Fjn.ad=function(n){I2(this,n)},Fjn.Nc=function(){return A7(this),this.d.Nc()},Fjn.Vc=function(n,t){var e;A7(this),e=this.d.dc(),Yx(this.d,15).Vc(n,t),++this.a.d,e&&tN(this)},Fjn.Wc=function(n,t){var e,i,r;return!t.dc()&&(A7(this),r=this.d.gc(),(e=Yx(this.d,15).Wc(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&tN(this)),e)},Fjn.Xb=function(n){return A7(this),Yx(this.d,15).Xb(n)},Fjn.Xc=function(n){return A7(this),Yx(this.d,15).Xc(n)},Fjn.Yc=function(){return A7(this),new VC(this)},Fjn.Zc=function(n){return A7(this),new RH(this,n)},Fjn.$c=function(n){var t;return A7(this),t=Yx(this.d,15).$c(n),--this.a.d,oK(this),t},Fjn._c=function(n,t){return A7(this),Yx(this.d,15)._c(n,t)},Fjn.bd=function(n,t){return A7(this),kX(this.a,this.e,Yx(this.d,15).bd(n,t),this.b?this.b:this)},EF(oEn,"AbstractMapBasedMultimap/WrappedList",728),Wfn(1096,728,{20:1,28:1,14:1,15:1,54:1},C$),EF(oEn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1096),Wfn(620,1,fEn,rD),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return rH(this),this.b.Ob()},Fjn.Pb=function(){return rH(this),this.b.Pb()},Fjn.Qb=function(){gA(this)},EF(oEn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",620),Wfn(729,620,yEn,VC,RH),Fjn.Qb=function(){gA(this)},Fjn.Rb=function(n){var t;t=0==bI(this.a),(rH(this),Yx(this.b,125)).Rb(n),++this.a.a.d,t&&tN(this.a)},Fjn.Sb=function(){return(rH(this),Yx(this.b,125)).Sb()},Fjn.Tb=function(){return(rH(this),Yx(this.b,125)).Tb()},Fjn.Ub=function(){return(rH(this),Yx(this.b,125)).Ub()},Fjn.Vb=function(){return(rH(this),Yx(this.b,125)).Vb()},Fjn.Wb=function(n){(rH(this),Yx(this.b,125)).Wb(n)},EF(oEn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",729),Wfn(727,541,vEn,yL),Fjn.Nc=function(){return A7(this),this.d.Nc()},EF(oEn,"AbstractMapBasedMultimap/WrappedSortedSet",727),Wfn(1095,727,mEn,PC),EF(oEn,"AbstractMapBasedMultimap/WrappedNavigableSet",1095),Wfn(1094,541,gEn,kL),Fjn.Nc=function(){return A7(this),this.d.Nc()},EF(oEn,"AbstractMapBasedMultimap/WrappedSet",1094),Wfn(1103,1,{},u),Fjn.Kb=function(n){return function(n){var t;return t=n.cd(),Vx(Yx(n.dd(),14).Nc(),new Xf(t))}(Yx(n,42))},EF(oEn,"AbstractMapBasedMultimap/lambda$1$Type",1103),Wfn(1102,1,{},Xf),Fjn.Kb=function(n){return new Wj(this.a,n)},EF(oEn,"AbstractMapBasedMultimap/lambda$2$Type",1102);var ZKn,n_n,t_n,e_n,i_n=aR(lEn,"Map/Entry");Wfn(345,1,kEn),Fjn.Fb=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),bB(this.cd(),t.cd())&&bB(this.dd(),t.dd()))},Fjn.Hb=function(){var n,t;return n=this.cd(),t=this.dd(),(null==n?0:W5(n))^(null==t?0:W5(t))},Fjn.ed=function(n){throw hp(new xp)},Fjn.Ib=function(){return this.cd()+"="+this.dd()},EF(oEn,jEn,345),Wfn(1988,28,wEn),Fjn.$b=function(){this.fd().$b()},Fjn.Hc=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),function(n,t,e){var i;return!!(i=Yx(n.Zb().xc(t),14))&&i.Hc(e)}(this.fd(),t.cd(),t.dd()))},Fjn.Mc=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),jU(this.fd(),t.cd(),t.dd()))},Fjn.gc=function(){return this.fd().d},EF(oEn,"Multimaps/Entries",1988),Wfn(733,1988,wEn,Wf),Fjn.Kc=function(){return this.a.kc()},Fjn.fd=function(){return this.a},Fjn.Nc=function(){return this.a.lc()},EF(oEn,"AbstractMultimap/Entries",733),Wfn(734,733,gEn,em),Fjn.Nc=function(){return this.a.lc()},Fjn.Fb=function(n){return _on(this,n)},Fjn.Hb=function(){return O2(this)},EF(oEn,"AbstractMultimap/EntrySet",734),Wfn(735,28,wEn,Vf),Fjn.$b=function(){this.a.$b()},Fjn.Hc=function(n){return function(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(Yx(e.Pb(),14).Hc(t))return!0;return!1}(this.a,n)},Fjn.Kc=function(){return this.a.nc()},Fjn.gc=function(){return this.a.d},Fjn.Nc=function(){return this.a.oc()},EF(oEn,"AbstractMultimap/Values",735),Wfn(1989,28,{835:1,20:1,28:1,14:1}),Fjn.Jc=function(n){MF(n),eH(this).Jc(new dl(n))},Fjn.Nc=function(){var n;return lun(n=eH(this).Nc(),new y,64|1296&n.qd(),this.a.d)},Fjn.Fc=function(n){return jy(),!0},Fjn.Gc=function(n){return MF(this),MF(n),CO(n,543)?BU(Yx(n,835)):!n.dc()&&zJ(this,n.Kc())},Fjn.Hc=function(n){var t;return((t=Yx(x8(QH(this.a),n),14))?t.gc():0)>0},Fjn.Fb=function(n){return function(n,t){var e,i,r;if(t===n)return!0;if(CO(t,543)){if(r=Yx(t,835),n.a.d!=r.a.d||eH(n).gc()!=eH(r).gc())return!1;for(i=eH(r).Kc();i.Ob();)if(Sz(n,(e=Yx(i.Pb(),416)).a.cd())!=Yx(e.a.dd(),14).gc())return!1;return!0}return!1}(this,n)},Fjn.Hb=function(){return W5(eH(this))},Fjn.dc=function(){return eH(this).dc()},Fjn.Mc=function(n){return xhn(this,n,1)>0},Fjn.Ib=function(){return I7(eH(this))},EF(oEn,"AbstractMultiset",1989),Wfn(1991,1970,gEn),Fjn.$b=function(){v0(this.a.a)},Fjn.Hc=function(n){var t;return!(!CO(n,492)||(t=Yx(n,416),Yx(t.a.dd(),14).gc()<=0||Sz(this.a,t.a.cd())!=Yx(t.a.dd(),14).gc()))},Fjn.Mc=function(n){var t,e,i;return!(!CO(n,492)||(t=(e=Yx(n,416)).a.cd(),0==(i=Yx(e.a.dd(),14).gc())))&&function(n,t,e){var i,r,c;return g0(e,"oldCount"),g0(0,"newCount"),((i=Yx(x8(QH(n.a),t),14))?i.gc():0)==e&&(g0(0,"count"),(c=-((r=Yx(x8(QH(n.a),t),14))?r.gc():0))>0?jy():c<0&&xhn(n,t,-c),!0)}(this.a,t,i)},EF(oEn,"Multisets/EntrySet",1991),Wfn(1109,1991,gEn,Qf),Fjn.Kc=function(){return new Pm(_K(QH(this.a.a)).Kc())},Fjn.gc=function(){return QH(this.a.a).gc()},EF(oEn,"AbstractMultiset/EntrySet",1109),Wfn(619,726,hEn),Fjn.hc=function(){return this.gd()},Fjn.jc=function(){return this.hd()},Fjn.cc=function(n){return this.jd(n)},Fjn.fc=function(n){return this.kd(n)},Fjn.Zb=function(){return this.f||(this.f=this.ac())},Fjn.hd=function(){return XH(),XH(),SFn},Fjn.Fb=function(n){return f6(this,n)},Fjn.jd=function(n){return Yx(_V(this,n),21)},Fjn.kd=function(n){return Yx(h8(this,n),21)},Fjn.mc=function(n){return XH(),new Ny(Yx(n,21))},Fjn.pc=function(n,t){return new kL(this,n,Yx(t,21))},EF(oEn,"AbstractSetMultimap",619),Wfn(1657,619,hEn),Fjn.hc=function(){return new Vk(this.b)},Fjn.gd=function(){return new Vk(this.b)},Fjn.jc=function(){return LF(new Vk(this.b))},Fjn.hd=function(){return LF(new Vk(this.b))},Fjn.cc=function(n){return Yx(Yx(_V(this,n),21),84)},Fjn.jd=function(n){return Yx(Yx(_V(this,n),21),84)},Fjn.fc=function(n){return Yx(Yx(h8(this,n),21),84)},Fjn.kd=function(n){return Yx(Yx(h8(this,n),21),84)},Fjn.mc=function(n){return CO(n,271)?LF(Yx(n,271)):(XH(),new CA(Yx(n,84)))},Fjn.Zb=function(){return this.f||(this.f=CO(this.c,171)?new dL(this,Yx(this.c,171)):CO(this.c,161)?new wL(this,Yx(this.c,161)):new Xj(this,this.c))},Fjn.pc=function(n,t){return CO(t,271)?new PC(this,n,Yx(t,271)):new yL(this,n,Yx(t,84))},EF(oEn,"AbstractSortedSetMultimap",1657),Wfn(1658,1657,hEn),Fjn.Zb=function(){return Yx(Yx(this.f||(this.f=CO(this.c,171)?new dL(this,Yx(this.c,171)):CO(this.c,161)?new wL(this,Yx(this.c,161)):new Xj(this,this.c)),161),171)},Fjn.ec=function(){return Yx(Yx(this.i||(this.i=CO(this.c,171)?new Aj(this,Yx(this.c,171)):CO(this.c,161)?new Oj(this,Yx(this.c,161)):new iA(this,this.c)),84),271)},Fjn.bc=function(){return CO(this.c,171)?new Aj(this,Yx(this.c,171)):CO(this.c,161)?new Oj(this,Yx(this.c,161)):new iA(this,this.c)},EF(oEn,"AbstractSortedKeySortedSetMultimap",1658),Wfn(2010,1,{1947:1}),Fjn.Fb=function(n){return function(n,t){var e;return t===n||!!CO(t,664)&&(e=Yx(t,1947),stn(n.g||(n.g=new Yf(n)),e.g||(e.g=new Yf(e))))}(this,n)},Fjn.Hb=function(){return W4(this.g||(this.g=new Yf(this)))},Fjn.Ib=function(){return Fan(this.f||(this.f=new uA(this)))},EF(oEn,"AbstractTable",2010),Wfn(665,dEn,gEn,Yf),Fjn.$b=function(){Ey()},Fjn.Hc=function(n){var t,e;return!!CO(n,468)&&(t=Yx(n,682),!!(e=Yx(x8(PF(this.a),uI(t.c.e,t.b)),83))&&D8(e.vc(),new Wj(uI(t.c.c,t.a),bQ(t.c,t.b,t.a))))},Fjn.Kc=function(){return new rA(n=this.a,n.e.Hd().gc()*n.c.Hd().gc());var n},Fjn.Mc=function(n){var t,e;return!!CO(n,468)&&(t=Yx(n,682),!!(e=Yx(x8(PF(this.a),uI(t.c.e,t.b)),83))&&function(n,t){MF(n);try{return n.Mc(t)}catch(n){if(CO(n=j4(n),205)||CO(n,173))return!1;throw hp(n)}}(e.vc(),new Wj(uI(t.c.c,t.a),bQ(t.c,t.b,t.a))))},Fjn.gc=function(){return OR(this.a)},Fjn.Nc=function(){return hR((n=this.a).e.Hd().gc()*n.c.Hd().gc(),273,new Hf(n));var n},EF(oEn,"AbstractTable/CellSet",665),Wfn(1928,28,wEn,Jf),Fjn.$b=function(){Ey()},Fjn.Hc=function(n){return function(n,t){var e,i,r,c,a,u,o;for(u=0,o=(a=n.a).length;u=0?"+":"")+(i/60|0),t=YI(e.Math.abs(i)%60),(Cun(),AFn)[this.q.getDay()]+" "+$Fn[this.q.getMonth()]+" "+YI(this.q.getDate())+" "+YI(this.q.getHours())+":"+YI(this.q.getMinutes())+":"+YI(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var E_n,T_n,M_n,S_n,P_n,I_n,C_n,O_n,A_n,$_n,L_n,N_n=EF(lEn,"Date",199);Wfn(1915,199,_Tn,Tcn),Fjn.a=!1,Fjn.b=0,Fjn.c=0,Fjn.d=0,Fjn.e=0,Fjn.f=0,Fjn.g=!1,Fjn.i=0,Fjn.j=0,Fjn.k=0,Fjn.n=0,Fjn.o=0,Fjn.p=0,EF("com.google.gwt.i18n.shared.impl","DateRecord",1915),Wfn(1966,1,{}),Fjn.fe=function(){return null},Fjn.ge=function(){return null},Fjn.he=function(){return null},Fjn.ie=function(){return null},Fjn.je=function(){return null},EF(FTn,"JSONValue",1966),Wfn(216,1966,{216:1},Sl,jl),Fjn.Fb=function(n){return!!CO(n,216)&&Jz(this.a,Yx(n,216).a)},Fjn.ee=function(){return fp},Fjn.Hb=function(){return sq(this.a)},Fjn.fe=function(){return this},Fjn.Ib=function(){var n,t,e;for(e=new SA("["),t=0,n=this.a.length;t0&&(e.a+=","),mI(e,VJ(this,t));return e.a+="]",e.a},EF(FTn,"JSONArray",216),Wfn(483,1966,{483:1},El),Fjn.ee=function(){return lp},Fjn.ge=function(){return this},Fjn.Ib=function(){return TA(),""+this.a},Fjn.a=!1,EF(FTn,"JSONBoolean",483),Wfn(985,60,eTn,Cm),EF(FTn,"JSONException",985),Wfn(1023,1966,{},v),Fjn.ee=function(){return pp},Fjn.Ib=function(){return aEn},EF(FTn,"JSONNull",1023),Wfn(258,1966,{258:1},Tl),Fjn.Fb=function(n){return!!CO(n,258)&&this.a==Yx(n,258).a},Fjn.ee=function(){return bp},Fjn.Hb=function(){return ZI(this.a)},Fjn.he=function(){return this},Fjn.Ib=function(){return this.a+""},Fjn.a=0,EF(FTn,"JSONNumber",258),Wfn(183,1966,{183:1},Om,Ml),Fjn.Fb=function(n){return!!CO(n,183)&&Jz(this.a,Yx(n,183).a)},Fjn.ee=function(){return wp},Fjn.Hb=function(){return sq(this.a)},Fjn.ie=function(){return this},Fjn.Ib=function(){var n,t,e,i,r,c;for(c=new SA("{"),n=!0,i=0,r=(e=l2(this,VQ(fFn,TEn,2,0,6,1))).length;i=0?":"+this.c:"")+")"},Fjn.c=0;var tFn=EF(Jjn,"StackTraceElement",310);zjn={3:1,475:1,35:1,2:1};var eFn,iFn,rFn,cFn,aFn,uFn,oFn,sFn,hFn,fFn=EF(Jjn,rTn,2);Wfn(107,418,{475:1},Cy,Oy,MA),EF(Jjn,"StringBuffer",107),Wfn(100,418,{475:1},Ay,$y,SA),EF(Jjn,"StringBuilder",100),Wfn(687,73,VTn,Ly),EF(Jjn,"StringIndexOutOfBoundsException",687),Wfn(2043,1,{}),Wfn(844,1,{},x),Fjn.Kb=function(n){return Yx(n,78).e},EF(Jjn,"Throwable/lambda$0$Type",844),Wfn(41,60,{3:1,102:1,60:1,78:1,41:1},xp,sy),EF(Jjn,"UnsupportedOperationException",41),Wfn(240,236,{3:1,35:1,236:1,240:1},ZJ,Wk),Fjn.wd=function(n){return Ipn(this,Yx(n,240))},Fjn.ke=function(){return gon(Kmn(this))},Fjn.Fb=function(n){var t;return this===n||!!CO(n,240)&&(t=Yx(n,240),this.e==t.e&&0==Ipn(this,t))},Fjn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=D3(this.f),this.b=WR(Gz(n,-1)),this.b=33*this.b+WR(Gz(zK(n,32),-1)),this.b=17*this.b+oG(this.e),this.b):(this.b=17*b8(this.c)+oG(this.e),this.b)},Fjn.Ib=function(){return Kmn(this)},Fjn.a=0,Fjn.b=0,Fjn.d=0,Fjn.e=0,Fjn.f=0;var lFn,bFn,wFn,dFn,gFn,pFn,vFn=EF("java.math","BigDecimal",240);Wfn(91,236,{3:1,35:1,236:1,91:1},jen,wQ,C_,pan,Mtn,IC),Fjn.wd=function(n){return utn(this,Yx(n,91))},Fjn.ke=function(){return gon(pjn(this,0))},Fjn.Fb=function(n){return q7(this,n)},Fjn.Hb=function(){return b8(this)},Fjn.Ib=function(){return pjn(this,0)},Fjn.b=-2,Fjn.c=0,Fjn.d=0,Fjn.e=0;var mFn,yFn,kFn,jFn,EFn=EF("java.math","BigInteger",91);Wfn(488,1967,bEn),Fjn.$b=function(){U_(this)},Fjn._b=function(n){return P_(this,n)},Fjn.uc=function(n){return m6(this,n,this.g)||m6(this,n,this.f)},Fjn.vc=function(){return new Ql(this)},Fjn.xc=function(n){return BF(this,n)},Fjn.zc=function(n,t){return xB(this,n,t)},Fjn.Bc=function(n){return zV(this,n)},Fjn.gc=function(){return hE(this)},EF(lEn,"AbstractHashMap",488),Wfn(261,dEn,gEn,Ql),Fjn.$b=function(){this.a.$b()},Fjn.Hc=function(n){return XU(this,n)},Fjn.Kc=function(){return new t6(this.a)},Fjn.Mc=function(n){var t;return!!XU(this,n)&&(t=Yx(n,42).cd(),this.a.Bc(t),!0)},Fjn.gc=function(){return this.a.gc()},EF(lEn,"AbstractHashMap/EntrySet",261),Wfn(262,1,fEn,t6),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return s1(this)},Fjn.Ob=function(){return this.b},Fjn.Qb=function(){oY(this)},Fjn.b=!1,EF(lEn,"AbstractHashMap/EntrySetIterator",262),Wfn(417,1,fEn,Vl),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return OT(this)},Fjn.Pb=function(){return FH(this)},Fjn.Qb=function(){hB(this)},Fjn.b=0,Fjn.c=-1,EF(lEn,"AbstractList/IteratorImpl",417),Wfn(96,417,yEn,JU),Fjn.Qb=function(){hB(this)},Fjn.Rb=function(n){ZL(this,n)},Fjn.Sb=function(){return this.b>0},Fjn.Tb=function(){return this.b},Fjn.Ub=function(){return S$(this.b>0),this.a.Xb(this.c=--this.b)},Fjn.Vb=function(){return this.b-1},Fjn.Wb=function(n){M$(-1!=this.c),this.a._c(this.c,n)},EF(lEn,"AbstractList/ListIteratorImpl",96),Wfn(219,52,WEn,Oz),Fjn.Vc=function(n,t){iz(n,this.b),this.c.Vc(this.a+n,t),++this.b},Fjn.Xb=function(n){return $z(n,this.b),this.c.Xb(this.a+n)},Fjn.$c=function(n){var t;return $z(n,this.b),t=this.c.$c(this.a+n),--this.b,t},Fjn._c=function(n,t){return $z(n,this.b),this.c._c(this.a+n,t)},Fjn.gc=function(){return this.b},Fjn.a=0,Fjn.b=0,EF(lEn,"AbstractList/SubList",219),Wfn(384,dEn,gEn,Yl),Fjn.$b=function(){this.a.$b()},Fjn.Hc=function(n){return this.a._b(n)},Fjn.Kc=function(){return new Jl(this.a.vc().Kc())},Fjn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},Fjn.gc=function(){return this.a.gc()},EF(lEn,"AbstractMap/1",384),Wfn(691,1,fEn,Jl),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return this.a.Ob()},Fjn.Pb=function(){return Yx(this.a.Pb(),42).cd()},Fjn.Qb=function(){this.a.Qb()},EF(lEn,"AbstractMap/1/1",691),Wfn(226,28,wEn,Zl),Fjn.$b=function(){this.a.$b()},Fjn.Hc=function(n){return this.a.uc(n)},Fjn.Kc=function(){return new ub(this.a.vc().Kc())},Fjn.gc=function(){return this.a.gc()},EF(lEn,"AbstractMap/2",226),Wfn(294,1,fEn,ub),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return this.a.Ob()},Fjn.Pb=function(){return Yx(this.a.Pb(),42).dd()},Fjn.Qb=function(){this.a.Qb()},EF(lEn,"AbstractMap/2/1",294),Wfn(484,1,{484:1,42:1}),Fjn.Fb=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),qB(this.d,t.cd())&&qB(this.e,t.dd()))},Fjn.cd=function(){return this.d},Fjn.dd=function(){return this.e},Fjn.Hb=function(){return NC(this.d)^NC(this.e)},Fjn.ed=function(n){return YL(this,n)},Fjn.Ib=function(){return this.d+"="+this.e},EF(lEn,"AbstractMap/AbstractEntry",484),Wfn(383,484,{484:1,383:1,42:1},zT),EF(lEn,"AbstractMap/SimpleEntry",383),Wfn(1984,1,hMn),Fjn.Fb=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),qB(this.cd(),t.cd())&&qB(this.dd(),t.dd()))},Fjn.Hb=function(){return NC(this.cd())^NC(this.dd())},Fjn.Ib=function(){return this.cd()+"="+this.dd()},EF(lEn,jEn,1984),Wfn(1992,1967,pEn),Fjn.tc=function(n){return vV(this,n)},Fjn._b=function(n){return XN(this,n)},Fjn.vc=function(){return new hb(this)},Fjn.xc=function(n){return eI(c6(this,n))},Fjn.ec=function(){return new ob(this)},EF(lEn,"AbstractNavigableMap",1992),Wfn(739,dEn,gEn,hb),Fjn.Hc=function(n){return CO(n,42)&&vV(this.b,Yx(n,42))},Fjn.Kc=function(){return new gN(this.b)},Fjn.Mc=function(n){var t;return!!CO(n,42)&&(t=Yx(n,42),iY(this.b,t))},Fjn.gc=function(){return this.b.c},EF(lEn,"AbstractNavigableMap/EntrySet",739),Wfn(493,dEn,mEn,ob),Fjn.Nc=function(){return new RT(this)},Fjn.$b=function(){$m(this.a)},Fjn.Hc=function(n){return XN(this.a,n)},Fjn.Kc=function(){return new sb(new gN(new UA(this.a).b))},Fjn.Mc=function(n){return!!XN(this.a,n)&&(fG(this.a,n),!0)},Fjn.gc=function(){return this.a.c},EF(lEn,"AbstractNavigableMap/NavigableKeySet",493),Wfn(494,1,fEn,sb),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return OT(this.a.a)},Fjn.Pb=function(){return m$(this.a).cd()},Fjn.Qb=function(){hx(this.a)},EF(lEn,"AbstractNavigableMap/NavigableKeySet/1",494),Wfn(2004,28,wEn),Fjn.Fc=function(n){return JQ(mun(this,n)),!0},Fjn.Gc=function(n){return vB(n),jD(n!=this,"Can't add a queue to itself"),C2(this,n)},Fjn.$b=function(){for(;null!=YJ(this););},EF(lEn,"AbstractQueue",2004),Wfn(302,28,{4:1,20:1,28:1,14:1},ep,xz),Fjn.Fc=function(n){return CX(this,n),!0},Fjn.$b=function(){iW(this)},Fjn.Hc=function(n){return T4(new VB(this),n)},Fjn.dc=function(){return ry(this)},Fjn.Kc=function(){return new VB(this)},Fjn.Mc=function(n){return function(n,t){return!!T4(n,t)&&(a0(n),!0)}(new VB(this),n)},Fjn.gc=function(){return this.c-this.b&this.a.length-1},Fjn.Nc=function(){return new Nz(this,272)},Fjn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.lengtht&&DF(n,t,null),n},Fjn.b=0,Fjn.c=0,EF(lEn,"ArrayDeque",302),Wfn(446,1,fEn,VB),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return this.a!=this.b},Fjn.Pb=function(){return w8(this)},Fjn.Qb=function(){a0(this)},Fjn.a=0,Fjn.b=0,Fjn.c=-1,EF(lEn,"ArrayDeque/IteratorImpl",446),Wfn(12,52,fMn,ip,pQ,sx),Fjn.Vc=function(n,t){ZR(this,n,t)},Fjn.Fc=function(n){return eD(this,n)},Fjn.Wc=function(n,t){return H6(this,n,t)},Fjn.Gc=function(n){return S4(this,n)},Fjn.$b=function(){this.c=VQ(UKn,iEn,1,0,5,1)},Fjn.Hc=function(n){return-1!=hJ(this,n,0)},Fjn.Jc=function(n){WZ(this,n)},Fjn.Xb=function(n){return TR(this,n)},Fjn.Xc=function(n){return hJ(this,n,0)},Fjn.dc=function(){return 0==this.c.length},Fjn.Kc=function(){return new pb(this)},Fjn.$c=function(n){return KV(this,n)},Fjn.Mc=function(n){return uJ(this,n)},Fjn.Ud=function(n,t){Az(this,n,t)},Fjn._c=function(n,t){return QW(this,n,t)},Fjn.gc=function(){return this.c.length},Fjn.ad=function(n){JC(this,n)},Fjn.Pc=function(){return w$(this)},Fjn.Qc=function(n){return Htn(this,n)};var TFn,MFn,SFn,PFn,IFn,CFn,OFn,AFn,$Fn,LFn=EF(lEn,"ArrayList",12);Wfn(7,1,fEn,pb),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return ZC(this)},Fjn.Pb=function(){return Hz(this)},Fjn.Qb=function(){z_(this)},Fjn.a=0,Fjn.b=-1,EF(lEn,"ArrayList/1",7),Wfn(2013,e.Function,{},T),Fjn.te=function(n,t){return $9(n,t)},Wfn(154,52,lMn,ay),Fjn.Hc=function(n){return-1!=p0(this,n)},Fjn.Jc=function(n){var t,e,i,r;for(vB(n),i=0,r=(e=this.a).length;i>>0).toString(16))},Fjn.f=0,Fjn.i=ZTn;var EBn,TBn,MBn,SBn,PBn=EF(qMn,"CNode",57);Wfn(814,1,{},uv),EF(qMn,"CNode/CNodeBuilder",814),Wfn(1525,1,{},dn),Fjn.Oe=function(n,t){return 0},Fjn.Pe=function(n,t){return 0},EF(qMn,zMn,1525),Wfn(1790,1,{},gn),Fjn.Le=function(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(h=JTn,r=new pb(n.a.b);r.ae.d.c||e.d.c==r.d.c&&e.d.b0?n+this.n.d+this.n.a:0},Fjn.Se=function(){var n,t,i,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].Se());else if(this.g)c=x7(this,lcn(this,null,!0));else for(JZ(),i=0,r=(t=x4(Gy(sHn,1),XEn,232,0,[rHn,cHn,aHn])).length;i0?c+this.n.b+this.n.c:0},Fjn.Te=function(){var n,t,e,i,r;if(this.g)for(n=lcn(this,null,!1),JZ(),i=0,r=(e=x4(Gy(sHn,1),XEn,232,0,[rHn,cHn,aHn])).length;i0&&(r[0]+=this.d,i-=r[0]),r[2]>0&&(r[2]+=this.d,i-=r[2]),this.c.a=e.Math.max(0,i),this.c.d=t.d+n.d+(this.c.a-i)/2,r[1]=e.Math.max(r[1],i),MV(this,cHn,t.d+n.d+r[0]-(r[1]-i)/2,r)},Fjn.b=null,Fjn.d=0,Fjn.e=!1,Fjn.f=!1,Fjn.g=!1;var hHn,fHn,lHn,bHn=0,wHn=0;EF(gSn,"GridContainerCell",1473),Wfn(461,22,{3:1,35:1,22:1,461:1},oM);var dHn,gHn=X1(gSn,"HorizontalLabelAlignment",461,u_n,(function(){return BY(),x4(Gy(gHn,1),XEn,461,0,[fHn,hHn,lHn])}),(function(n){return BY(),rZ((mQ(),dHn),n)}));Wfn(306,212,{212:1,306:1},eG,KZ,qq),Fjn.Re=function(){return XD(this)},Fjn.Se=function(){return WD(this)},Fjn.a=0,Fjn.c=!1;var pHn,vHn,mHn,yHn=EF(gSn,"LabelCell",306);Wfn(244,326,{212:1,326:1,244:1},Stn),Fjn.Re=function(){return Dhn(this)},Fjn.Se=function(){return Rhn(this)},Fjn.Te=function(){cvn(this)},Fjn.Ue=function(){hvn(this)},Fjn.b=0,Fjn.c=0,Fjn.d=!1,EF(gSn,"StripContainerCell",244),Wfn(1626,1,YEn,En),Fjn.Mb=function(n){return function(n){return!!n&&n.k}(Yx(n,212))},EF(gSn,"StripContainerCell/lambda$0$Type",1626),Wfn(1627,1,{},Tn),Fjn.Fe=function(n){return Yx(n,212).Se()},EF(gSn,"StripContainerCell/lambda$1$Type",1627),Wfn(1628,1,YEn,Mn),Fjn.Mb=function(n){return function(n){return!!n&&n.j}(Yx(n,212))},EF(gSn,"StripContainerCell/lambda$2$Type",1628),Wfn(1629,1,{},Sn),Fjn.Fe=function(n){return Yx(n,212).Re()},EF(gSn,"StripContainerCell/lambda$3$Type",1629),Wfn(462,22,{3:1,35:1,22:1,462:1},sM);var kHn,jHn,EHn,THn,MHn,SHn,PHn,IHn,CHn,OHn,AHn,$Hn,LHn,NHn,xHn,DHn,RHn,KHn,_Hn,FHn,BHn,HHn,qHn,GHn=X1(gSn,"VerticalLabelAlignment",462,u_n,(function(){return OJ(),x4(Gy(GHn,1),XEn,462,0,[mHn,vHn,pHn])}),(function(n){return OJ(),rZ((yQ(),kHn),n)}));Wfn(789,1,{},vkn),Fjn.c=0,Fjn.d=0,Fjn.k=0,Fjn.s=0,Fjn.t=0,Fjn.v=!1,Fjn.w=0,Fjn.D=!1,EF(TSn,"NodeContext",789),Wfn(1471,1,FMn,Pn),Fjn.ue=function(n,t){return nC(Yx(n,61),Yx(t,61))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(TSn,"NodeContext/0methodref$comparePortSides$Type",1471),Wfn(1472,1,FMn,In),Fjn.ue=function(n,t){return function(n,t){var e;if(0!=(e=nC(n.b.Hf(),t.b.Hf())))return e;switch(n.b.Hf().g){case 1:case 2:return eO(n.b.sf(),t.b.sf());case 3:case 4:return eO(t.b.sf(),n.b.sf())}return 0}(Yx(n,111),Yx(t,111))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(TSn,"NodeContext/1methodref$comparePortContexts$Type",1472),Wfn(159,22,{3:1,35:1,22:1,159:1},U2);var zHn,UHn,XHn,WHn,VHn,QHn,YHn,JHn=X1(TSn,"NodeLabelLocation",159,u_n,Xtn,(function(n){return Njn(),rZ((LI(),zHn),n)}));Wfn(111,1,{111:1},gfn),Fjn.a=!1,EF(TSn,"PortContext",111),Wfn(1476,1,PEn,Cn),Fjn.td=function(n){oj(Yx(n,306))},EF(PSn,ISn,1476),Wfn(1477,1,YEn,On),Fjn.Mb=function(n){return!!Yx(n,111).c},EF(PSn,CSn,1477),Wfn(1478,1,PEn,An),Fjn.td=function(n){oj(Yx(n,111).c)},EF(PSn,"LabelPlacer/lambda$2$Type",1478),Wfn(1475,1,PEn,Ln),Fjn.td=function(n){PL(),function(n){n.b.tf(n.e)}(Yx(n,111))},EF(PSn,"NodeLabelAndSizeUtilities/lambda$0$Type",1475),Wfn(790,1,PEn,kx),Fjn.td=function(n){hT(this.b,this.c,this.a,Yx(n,181))},Fjn.a=!1,Fjn.c=!1,EF(PSn,"NodeLabelCellCreator/lambda$0$Type",790),Wfn(1474,1,PEn,Yb),Fjn.td=function(n){!function(n,t){Fon(n.c,t)}(this.a,Yx(n,181))},EF(PSn,"PortContextCreator/lambda$0$Type",1474),Wfn(1829,1,{},Nn),EF(ASn,"GreedyRectangleStripOverlapRemover",1829),Wfn(1830,1,FMn,$n),Fjn.ue=function(n,t){return function(n,t){return $9(n.c.d,t.c.d)}(Yx(n,222),Yx(t,222))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(ASn,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1830),Wfn(1786,1,{},lv),Fjn.a=5,Fjn.e=0,EF(ASn,"RectangleStripOverlapRemover",1786),Wfn(1787,1,FMn,Dn),Fjn.ue=function(n,t){return function(n,t){return $9(n.c.c,t.c.c)}(Yx(n,222),Yx(t,222))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(ASn,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1787),Wfn(1789,1,FMn,Rn),Fjn.ue=function(n,t){return function(n,t){return $9(n.c.c+n.c.b,t.c.c+t.c.b)}(Yx(n,222),Yx(t,222))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(ASn,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1789),Wfn(406,22,{3:1,35:1,22:1,406:1},hM);var ZHn,nqn,tqn,eqn,iqn,rqn=X1(ASn,"RectangleStripOverlapRemover/OverlapRemovalDirection",406,u_n,(function(){return e4(),x4(Gy(rqn,1),XEn,406,0,[YHn,WHn,VHn,QHn])}),(function(n){return e4(),rZ((zY(),ZHn),n)}));Wfn(222,1,{222:1},fK),EF(ASn,"RectangleStripOverlapRemover/RectangleNode",222),Wfn(1788,1,PEn,Jb),Fjn.td=function(n){!function(n,t){var e,i;switch(i=t.c,e=t.a,n.b.g){case 0:e.d=n.e-i.a-i.d;break;case 1:e.d+=n.e;break;case 2:e.c=n.e-i.a-i.d;break;case 3:e.c=n.e+i.d}}(this.a,Yx(n,222))},EF(ASn,"RectangleStripOverlapRemover/lambda$1$Type",1788),Wfn(1304,1,FMn,Kn),Fjn.ue=function(n,t){return function(n,t){var e,i,r,c;return e=new _n,1==(r=2==(r=(i=Yx(kW(fH(new SR(null,new Nz(n.f,16)),e),kJ(new Q,new Y,new cn,new an,x4(Gy(wBn,1),XEn,132,0,[(C6(),uBn),aBn]))),21)).gc())?1:0)&&sI(Snn(Yx(kW(hH(i.Lc(),new Fn),k3(ytn(0),new en)),162).a,2),0)&&(r=0),1==(c=2==(c=(i=Yx(kW(fH(new SR(null,new Nz(t.f,16)),e),kJ(new Q,new Y,new cn,new an,x4(Gy(wBn,1),XEn,132,0,[uBn,aBn]))),21)).gc())?1:0)&&sI(Snn(Yx(kW(hH(i.Lc(),new Bn),k3(ytn(0),new en)),162).a,2),0)&&(c=0),r0?Y_(n.a,t,e):Y_(n.b,t,e)}(this,Yx(n,46),Yx(t,167))},EF(LSn,"SuccessorCombination",777),Wfn(644,1,{},Wn),Fjn.Ce=function(n,t){var i;return function(n){var t,i,r,c,a;return i=c=Yx(n.a,19).a,r=a=Yx(n.b,19).a,t=e.Math.max(e.Math.abs(c),e.Math.abs(a)),c<=0&&c==a?(i=0,r=a-1):c==-t&&a!=t?(i=a,r=c,a>=0&&++i):(i=-a,r=c),new mP(d9(i),d9(r))}((i=Yx(n,46),Yx(t,167),i))},EF(LSn,"SuccessorJitter",644),Wfn(643,1,{},Vn),Fjn.Ce=function(n,t){var i;return function(n){var t,i;if(t=Yx(n.a,19).a,i=Yx(n.b,19).a,t>=0){if(t==i)return new mP(d9(-t-1),d9(-t-1));if(t==-i)return new mP(d9(-t),d9(i+1))}return e.Math.abs(t)>e.Math.abs(i)?new mP(d9(-t),d9(t<0?i:i+1)):new mP(d9(t+1),d9(i))}((i=Yx(n,46),Yx(t,167),i))},EF(LSn,"SuccessorLineByLine",643),Wfn(568,1,{},Qn),Fjn.Ce=function(n,t){var e;return function(n){var t,e,i,r;return t=i=Yx(n.a,19).a,e=r=Yx(n.b,19).a,0==i&&0==r?e-=1:-1==i&&r<=0?(t=0,e-=2):i<=0&&r>0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new mP(d9(t),d9(e))}((e=Yx(n,46),Yx(t,167),e))},EF(LSn,"SuccessorManhattan",568),Wfn(1356,1,{},Yn),Fjn.Ce=function(n,t){var i;return function(n){var t,i,r;return i=Yx(n.a,19).a,r=Yx(n.b,19).a,i<(t=e.Math.max(e.Math.abs(i),e.Math.abs(r)))&&r==-t?new mP(d9(i+1),d9(r)):i==t&&r=-t&&r==t?new mP(d9(i-1),d9(r)):new mP(d9(i),d9(r-1))}((i=Yx(n,46),Yx(t,167),i))},EF(LSn,"SuccessorMaxNormWindingInMathPosSense",1356),Wfn(400,1,{},Zb),Fjn.Ce=function(n,t){return Y_(this,n,t)},Fjn.c=!1,Fjn.d=!1,Fjn.e=!1,Fjn.f=!1,EF(LSn,"SuccessorQuadrantsGeneric",400),Wfn(1357,1,{},Jn),Fjn.Kb=function(n){return Yx(n,324).a},EF(LSn,"SuccessorQuadrantsGeneric/lambda$0$Type",1357),Wfn(323,22,{3:1,35:1,22:1,323:1},iM),Fjn.a=!1;var cqn,aqn=X1(KSn,_Sn,323,u_n,(function(){return Sen(),x4(Gy(aqn,1),XEn,323,0,[tqn,nqn,eqn,iqn])}),(function(n){return Sen(),rZ((UY(),cqn),n)}));Wfn(1298,1,{}),Fjn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=d9(0),r=0;r0&&L1(p,y*j),k>0&&N1(p,k*E);for(S3(n.b,new lt),t=new ip,u=new t6(new Ql(n.c).a);u.b;)i=Yx((a=s1(u)).cd(),79),e=Yx(a.dd(),395).a,r=Ywn(i,!1,!1),wvn(f=Xan(Kun(i),Kon(r),e),r),(m=_un(i))&&-1==hJ(t,m,0)&&(t.c[t.c.length]=m,OH(m,(S$(0!=f.b),Yx(f.a.a.c,8)),e));for(g=new t6(new Ql(n.d).a);g.b;)i=Yx((d=s1(g)).cd(),79),e=Yx(d.dd(),395).a,r=Ywn(i,!1,!1),f=Xan(Bun(i),U5(Kon(r)),e),wvn(f=U5(f),r),(m=Fun(i))&&-1==hJ(t,m,0)&&(t.c[t.c.length]=m,OH(m,(S$(0!=f.b),Yx(f.c.b.c,8)),e))}(r),Aen(n,Cqn,this.b),Ron(t)},Fjn.a=0,EF(JSn,"DisCoLayoutProvider",1132),Wfn(1244,1,{},ct),Fjn.c=!1,Fjn.e=0,Fjn.f=0,EF(JSn,"DisCoPolyominoCompactor",1244),Wfn(561,1,{561:1},qR),Fjn.b=!0,EF(ZSn,"DCComponent",561),Wfn(394,22,{3:1,35:1,22:1,394:1},eM),Fjn.a=!1;var pqn,vqn,mqn=X1(ZSn,"DCDirection",394,u_n,(function(){return Pen(),x4(Gy(mqn,1),XEn,394,0,[bqn,lqn,wqn,dqn])}),(function(n){return Pen(),rZ((XY(),pqn),n)}));Wfn(266,134,{3:1,266:1,94:1,134:1},eln),EF(ZSn,"DCElement",266),Wfn(395,1,{395:1},Bin),Fjn.c=0,EF(ZSn,"DCExtension",395),Wfn(755,134,USn,jk),EF(ZSn,"DCGraph",755),Wfn(481,22,{3:1,35:1,22:1,481:1},I$);var yqn,kqn,jqn,Eqn,Tqn,Mqn,Sqn,Pqn,Iqn,Cqn,Oqn,Aqn,$qn,Lqn,Nqn,xqn,Dqn,Rqn,Kqn,_qn,Fqn,Bqn=X1(nPn,tPn,481,u_n,(function(){return BE(),x4(Gy(Bqn,1),XEn,481,0,[vqn])}),(function(n){return BE(),rZ((yX(),yqn),n)}));Wfn(854,1,fSn,Fh),Fjn.Qe=function(n){j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ePn),aPn),"Connected Components Compaction Strategy"),"Strategy for packing different connected components in order to save space and enhance readability of a graph."),Eqn),(lsn(),O7n)),Bqn),J9((Qtn(),T7n))))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,iPn),aPn),"Connected Components Layout Algorithm"),"A layout algorithm that is to be applied to each connected component before the components themselves are compacted. If unspecified, the positions of the components' nodes are not altered."),N7n),fFn),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,rPn),"debug"),"DCGraph"),"Access to the DCGraph is intended for the debug view,"),L7n),UKn),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,cPn),"debug"),"List of Polyominoes"),"Access to the polyominoes is intended for the debug view,"),L7n),UKn),J9(T7n)))),Qvn((new Bh,n))},EF(nPn,"DisCoMetaDataProvider",854),Wfn(998,1,fSn,Bh),Fjn.Qe=function(n){Qvn(n)},EF(nPn,"DisCoOptions",998),Wfn(999,1,{},at),Fjn.$e=function(){return new rt},Fjn._e=function(n){},EF(nPn,"DisCoOptions/DiscoFactory",999),Wfn(562,167,{321:1,167:1,562:1},nbn),Fjn.a=0,Fjn.b=0,Fjn.c=0,Fjn.d=0,EF("org.eclipse.elk.alg.disco.structures","DCPolyomino",562),Wfn(1268,1,YEn,ut),Fjn.Mb=function(n){return $I(n)},EF(lPn,"ElkGraphComponentsProcessor/lambda$0$Type",1268),Wfn(1269,1,{},ot),Fjn.Kb=function(n){return UH(),Kun(Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$1$Type",1269),Wfn(1270,1,YEn,st),Fjn.Mb=function(n){return function(n){return UH(),Kun(n)==IG(Bun(n))}(Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$2$Type",1270),Wfn(1271,1,{},ht),Fjn.Kb=function(n){return UH(),Bun(Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$3$Type",1271),Wfn(1272,1,YEn,ft),Fjn.Mb=function(n){return function(n){return UH(),Bun(n)==IG(Kun(n))}(Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$4$Type",1272),Wfn(1273,1,YEn,tw),Fjn.Mb=function(n){return function(n,t){return UH(),n==IG(Kun(t))||n==IG(Bun(t))}(this.a,Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$5$Type",1273),Wfn(1274,1,{},ew),Fjn.Kb=function(n){return function(n,t){return UH(),n==Kun(t)?Bun(t):Kun(t)}(this.a,Yx(n,79))},EF(lPn,"ElkGraphComponentsProcessor/lambda$6$Type",1274),Wfn(1241,1,{},rW),Fjn.a=0,EF(lPn,"ElkGraphTransformer",1241),Wfn(1242,1,{},lt),Fjn.Od=function(n,t){!function(n,t,e){var i,r,c,a;n.a=e.b.d,CO(t,352)?(XW(c=Kon(r=Ywn(Yx(t,79),!1,!1)),i=new iw(n)),wvn(c,r),null!=t.We((Cjn(),Gnt))&&XW(Yx(t.We(Gnt),74),i)):((a=Yx(t,470)).Hg(a.Dg()+n.a.a),a.Ig(a.Eg()+n.a.b))}(this,Yx(n,160),Yx(t,266))},EF(lPn,"ElkGraphTransformer/OffsetApplier",1242),Wfn(1243,1,PEn,iw),Fjn.td=function(n){!function(n,t){$$(t,n.a.a.a,n.a.a.b)}(this,Yx(n,8))},EF(lPn,"ElkGraphTransformer/OffsetApplier/OffSetToChainApplier",1243),Wfn(753,1,{},bt),EF(pPn,vPn,753),Wfn(1232,1,FMn,wt),Fjn.ue=function(n,t){return function(n,t){var e,i,r;return 0==(e=Yx(Aun(t,(Bdn(),bGn)),19).a-Yx(Aun(n,bGn),19).a)?(i=yN(dO(Yx(Aun(n,(d2(),kGn)),8)),Yx(Aun(n,jGn),8)),r=yN(dO(Yx(Aun(t,kGn),8)),Yx(Aun(t,jGn),8)),$9(i.a*i.b,r.a*r.b)):e}(Yx(n,231),Yx(t,231))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(pPn,mPn,1232),Wfn(740,209,VSn,iv),Fjn.Ze=function(n,t){bbn(this,n,t)},EF(pPn,"ForceLayoutProvider",740),Wfn(357,134,{3:1,357:1,94:1,134:1}),EF(yPn,"FParticle",357),Wfn(559,357,{3:1,559:1,357:1,94:1,134:1},dF),Fjn.Ib=function(){var n;return this.a?(n=hJ(this.a.a,this,0))>=0?"b"+n+"["+YW(this.a)+"]":"b["+YW(this.a)+"]":"b_"+_A(this)},EF(yPn,"FBendpoint",559),Wfn(282,134,{3:1,282:1,94:1,134:1},rN),Fjn.Ib=function(){return YW(this)},EF(yPn,"FEdge",282),Wfn(231,134,{3:1,231:1,94:1,134:1},XV);var Hqn,qqn,Gqn,zqn,Uqn,Xqn,Wqn,Vqn,Qqn,Yqn,Jqn=EF(yPn,"FGraph",231);Wfn(447,357,{3:1,447:1,357:1,94:1,134:1},wW),Fjn.Ib=function(){return null==this.b||0==this.b.length?"l["+YW(this.a)+"]":"l_"+this.b},EF(yPn,"FLabel",447),Wfn(144,357,{3:1,144:1,357:1,94:1,134:1},GF),Fjn.Ib=function(){return Yz(this)},Fjn.b=0,EF(yPn,"FNode",144),Wfn(2003,1,{}),Fjn.bf=function(n){Kpn(this,n)},Fjn.cf=function(){trn(this)},Fjn.d=0,EF(jPn,"AbstractForceModel",2003),Wfn(631,2003,{631:1},Z3),Fjn.af=function(n,t){var i,r,c,a;return mhn(this.f,n,t),c=yN(dO(t.d),n.d),a=e.Math.sqrt(c.a*c.a+c.b*c.b),r=e.Math.max(0,a-fB(n.e)/2-fB(t.e)/2),KO(c,((i=F5(this.e,n,t))>0?-function(n,t){return n>0?e.Math.log(n/t):-100}(r,this.c)*i:function(n,t){return n>0?t/(n*n):100*t}(r,this.b)*Yx(Aun(n,(Bdn(),bGn)),19).a)/a),c},Fjn.bf=function(n){Kpn(this,n),this.a=Yx(Aun(n,(Bdn(),iGn)),19).a,this.c=ty(fL(Aun(n,mGn))),this.b=ty(fL(Aun(n,dGn)))},Fjn.df=function(n){return n0?t*t/n:t*t*100}(r=e.Math.max(0,u-fB(n.e)/2-fB(t.e)/2),this.a)*Yx(Aun(n,(Bdn(),bGn)),19).a,(i=F5(this.e,n,t))>0&&(a-=function(n,t){return n*n/t}(r,this.a)*i),KO(c,a*this.b/u),c},Fjn.bf=function(n){var t,i,r,c,a,u,o;for(Kpn(this,n),this.b=ty(fL(Aun(n,(Bdn(),yGn)))),this.c=this.b/Yx(Aun(n,iGn),19).a,r=n.e.c.length,a=0,c=0,o=new pb(n.e);o.a0},Fjn.a=0,Fjn.b=0,Fjn.c=0,EF(jPn,"FruchtermanReingoldModel",632),Wfn(849,1,fSn,qh),Fjn.Qe=function(n){j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,EPn),""),"Force Model"),"Determines the model for force calculation."),Gqn),(lsn(),O7n)),UGn),J9((Qtn(),T7n))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,TPn),""),"Iterations"),"The number of iterations on the force model."),d9(300)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,MPn),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),d9(0)),$7n),U_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,SPn),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),PPn),C7n),H_n),J9(T7n)))),xU(n,SPn,EPn,Vqn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,IPn),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),C7n),H_n),J9(T7n)))),xU(n,IPn,EPn,Uqn),Mkn((new Gh,n))},EF(CPn,"ForceMetaDataProvider",849),Wfn(424,22,{3:1,35:1,22:1,424:1},fM);var Zqn,nGn,tGn,eGn,iGn,rGn,cGn,aGn,uGn,oGn,sGn,hGn,fGn,lGn,bGn,wGn,dGn,gGn,pGn,vGn,mGn,yGn,kGn,jGn,EGn,TGn,MGn,SGn,PGn,IGn,CGn,OGn,AGn,$Gn,LGn,NGn,xGn,DGn,RGn,KGn,_Gn,FGn,BGn,HGn,qGn,GGn,zGn,UGn=X1(CPn,"ForceModelStrategy",424,u_n,(function(){return hZ(),x4(Gy(UGn,1),XEn,424,0,[Qqn,Yqn])}),(function(n){return hZ(),rZ((MW(),Zqn),n)}));Wfn(988,1,fSn,Gh),Fjn.Qe=function(n){Mkn(n)},EF(CPn,"ForceOptions",988),Wfn(989,1,{},dt),Fjn.$e=function(){return new iv},Fjn._e=function(n){},EF(CPn,"ForceOptions/ForceFactory",989),Wfn(850,1,fSn,zh),Fjn.Qe=function(n){j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,VPn),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(TA(),!1)),(lsn(),I7n)),D_n),J9((Qtn(),E7n))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,QPn),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),C7n),H_n),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[k7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,YPn),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),PGn),O7n),ezn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,JPn),""),"Stress Epsilon"),"Termination criterion for the iterative process."),PPn),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ZPn),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),d9(Yjn)),$7n),U_n),J9(T7n)))),Kyn((new Uh,n))},EF(CPn,"StressMetaDataProvider",850),Wfn(992,1,fSn,Uh),Fjn.Qe=function(n){Kyn(n)},EF(CPn,"StressOptions",992),Wfn(993,1,{},gt),Fjn.$e=function(){return new cN},Fjn._e=function(n){},EF(CPn,"StressOptions/StressFactory",993),Wfn(1128,209,VSn,cN),Fjn.Ze=function(n,t){var e,i,r,c;for(run(t,tIn,1),ny(hL(jln(n,(Wrn(),xGn))))?ny(hL(jln(n,BGn)))||rG(new Xb((dT(),new Xm(n)))):bbn(new iv,n,J2(t,1)),i=w5(n),c=(e=ovn(this.a,i)).Kc();c.Ob();)(r=Yx(c.Pb(),231)).e.c.length<=1||($mn(this.b,r),Mln(this.b),WZ(r.d,new pt));Okn(i=_kn(e)),Ron(t)},EF(iIn,"StressLayoutProvider",1128),Wfn(1129,1,PEn,pt),Fjn.td=function(n){Wvn(Yx(n,447))},EF(iIn,"StressLayoutProvider/lambda$0$Type",1129),Wfn(990,1,{},Hp),Fjn.c=0,Fjn.e=0,Fjn.g=0,EF(iIn,"StressMajorization",990),Wfn(379,22,{3:1,35:1,22:1,379:1},lM);var XGn,WGn,VGn,QGn,YGn,JGn,ZGn,nzn,tzn,ezn=X1(iIn,"StressMajorization/Dimension",379,u_n,(function(){return CJ(),x4(Gy(ezn,1),XEn,379,0,[GGn,qGn,zGn])}),(function(n){return CJ(),rZ((jQ(),XGn),n)}));Wfn(991,1,FMn,rw),Fjn.ue=function(n,t){return function(n,t,e){return $9(n[t.b],n[e.b])}(this.a,Yx(n,144),Yx(t,144))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(iIn,"StressMajorization/lambda$0$Type",991),Wfn(1229,1,{},gU),EF(cIn,"ElkLayered",1229),Wfn(1230,1,PEn,vt),Fjn.td=function(n){!function(n){var t;if((t=Yx(Aun(n,(gjn(),i1n)),314))==(O0(),TWn))throw hp(new by("The hierarchy aware processor "+t+" in child node "+n+" is only allowed if the root node specifies the same hierarchical processor."))}(Yx(n,37))},EF(cIn,"ElkLayered/lambda$0$Type",1230),Wfn(1231,1,PEn,cw),Fjn.td=function(n){!function(n,t){b5(t,(gjn(),YZn),n)}(this.a,Yx(n,37))},EF(cIn,"ElkLayered/lambda$1$Type",1231),Wfn(1263,1,{},fO),EF(cIn,"GraphConfigurator",1263),Wfn(759,1,PEn,aw),Fjn.td=function(n){ron(this.a,Yx(n,10))},EF(cIn,"GraphConfigurator/lambda$0$Type",759),Wfn(760,1,{},mt),Fjn.Kb=function(n){return Mcn(),new SR(null,new Nz(Yx(n,29).a,16))},EF(cIn,"GraphConfigurator/lambda$1$Type",760),Wfn(761,1,PEn,uw),Fjn.td=function(n){ron(this.a,Yx(n,10))},EF(cIn,"GraphConfigurator/lambda$2$Type",761),Wfn(1127,209,VSn,cv),Fjn.Ze=function(n,t){var e;e=Kvn(new wv,n),iI(jln(n,(gjn(),E1n)))===iI((O8(),$et))?_7(this.a,e,t):ofn(this.a,e,t),Tkn(new Wh,e)},EF(cIn,"LayeredLayoutProvider",1127),Wfn(356,22,{3:1,35:1,22:1,356:1},bM);var izn,rzn,czn,azn=X1(cIn,"LayeredPhases",356,u_n,(function(){return $un(),x4(Gy(azn,1),XEn,356,0,[YGn,JGn,ZGn,nzn,tzn])}),(function(n){return $un(),rZ((mZ(),izn),n)}));Wfn(1651,1,{},y0),Fjn.i=0,EF(aIn,"ComponentsToCGraphTransformer",1651),Wfn(1652,1,{},yt),Fjn.ef=function(n,t){return e.Math.min(null!=n.a?ty(n.a):n.c.i,null!=t.a?ty(t.a):t.c.i)},Fjn.ff=function(n,t){return e.Math.min(null!=n.a?ty(n.a):n.c.i,null!=t.a?ty(t.a):t.c.i)},EF(aIn,"ComponentsToCGraphTransformer/1",1652),Wfn(81,1,{81:1}),Fjn.i=0,Fjn.k=!0,Fjn.o=ZTn;var uzn,ozn,szn,hzn=EF(uIn,"CNode",81);Wfn(460,81,{460:1,81:1},zA,Etn),Fjn.Ib=function(){return""},EF(aIn,"ComponentsToCGraphTransformer/CRectNode",460),Wfn(1623,1,{},kt),EF(aIn,"OneDimensionalComponentsCompaction",1623),Wfn(1624,1,{},jt),Fjn.Kb=function(n){return function(n){return r8(),TA(),0!=Yx(n.a,81).d.e}(Yx(n,46))},Fjn.Fb=function(n){return this===n},EF(aIn,"OneDimensionalComponentsCompaction/lambda$0$Type",1624),Wfn(1625,1,{},Et),Fjn.Kb=function(n){return function(n){return r8(),TA(),!!(M7(Yx(n.a,81).j,Yx(n.b,103))||0!=Yx(n.a,81).d.e&&M7(Yx(n.a,81).j,Yx(n.b,103)))}(Yx(n,46))},Fjn.Fb=function(n){return this===n},EF(aIn,"OneDimensionalComponentsCompaction/lambda$1$Type",1625),Wfn(1654,1,{},HF),EF(uIn,"CGraph",1654),Wfn(189,1,{189:1},Ttn),Fjn.b=0,Fjn.c=0,Fjn.e=0,Fjn.g=!0,Fjn.i=ZTn,EF(uIn,"CGroup",189),Wfn(1653,1,{},Pt),Fjn.ef=function(n,t){return e.Math.max(null!=n.a?ty(n.a):n.c.i,null!=t.a?ty(t.a):t.c.i)},Fjn.ff=function(n,t){return e.Math.max(null!=n.a?ty(n.a):n.c.i,null!=t.a?ty(t.a):t.c.i)},EF(uIn,zMn,1653),Wfn(1655,1,{},rfn),Fjn.d=!1;var fzn=EF(uIn,QMn,1655);Wfn(1656,1,{},It),Fjn.Kb=function(n){return WE(),TA(),0!=Yx(Yx(n,46).a,81).d.e},Fjn.Fb=function(n){return this===n},EF(uIn,YMn,1656),Wfn(823,1,{},gR),Fjn.a=!1,Fjn.b=!1,Fjn.c=!1,Fjn.d=!1,EF(uIn,JMn,823),Wfn(1825,1,{},lK),EF(oIn,ZMn,1825);var lzn=aR(sIn,HMn);Wfn(1826,1,{369:1},yq),Fjn.Ke=function(n){!function(n,t){var e,i,r;t.a?(uF(n.b,t.b),n.a[t.b.i]=Yx(BN(n.b,t.b),81),(e=Yx(FN(n.b,t.b),81))&&(n.a[e.i]=t.b)):(!!(i=Yx(BN(n.b,t.b),81))&&i==n.a[t.b.i]&&!!i.d&&i.d!=t.b.d&&i.f.Fc(t.b),!!(r=Yx(FN(n.b,t.b),81))&&n.a[r.i]==t.b&&!!r.d&&r.d!=t.b.d&&t.b.f.Fc(r),RA(n.b,t.b))}(this,Yx(n,466))},EF(oIn,nSn,1826),Wfn(1827,1,FMn,Ct),Fjn.ue=function(n,t){return function(n,t){return $9(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}(Yx(n,81),Yx(t,81))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(oIn,tSn,1827),Wfn(466,1,{466:1},CM),Fjn.a=!1,EF(oIn,eSn,466),Wfn(1828,1,FMn,Ot),Fjn.ue=function(n,t){return function(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=$9(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}(Yx(n,466),Yx(t,466))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(oIn,iSn,1828),Wfn(140,1,{140:1},LM,ED),Fjn.Fb=function(n){var t;return null!=n&&pzn==V5(n)&&(t=Yx(n,140),qB(this.c,t.c)&&qB(this.d,t.d))},Fjn.Hb=function(){return G6(x4(Gy(UKn,1),iEn,1,5,[this.c,this.d]))},Fjn.Ib=function(){return"("+this.c+tEn+this.d+(this.a?"cx":"")+this.b+")"},Fjn.a=!0,Fjn.c=0,Fjn.d=0;var bzn,wzn,dzn,gzn,pzn=EF(sIn,"Point",140);Wfn(405,22,{3:1,35:1,22:1,405:1},wM);var vzn,mzn,yzn,kzn,jzn,Ezn,Tzn,Mzn,Szn,Pzn,Izn,Czn=X1(sIn,"Point/Quadrant",405,u_n,(function(){return _4(),x4(Gy(Czn,1),XEn,405,0,[bzn,gzn,wzn,dzn])}),(function(n){return _4(),rZ((GY(),vzn),n)}));Wfn(1642,1,{},ov),Fjn.b=null,Fjn.c=null,Fjn.d=null,Fjn.e=null,Fjn.f=null,EF(sIn,"RectilinearConvexHull",1642),Wfn(574,1,{369:1},ben),Fjn.Ke=function(n){!function(n,t){n.a.ue(t.d,n.b)>0&&(eD(n.c,new ED(t.c,t.d,n.d)),n.b=t.d)}(this,Yx(n,140))},Fjn.b=0,EF(sIn,"RectilinearConvexHull/MaximalElementsEventHandler",574),Wfn(1644,1,FMn,Mt),Fjn.ue=function(n,t){return function(n,t){return VE(),$9((vB(n),n),(vB(t),t))}(fL(n),fL(t))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1644),Wfn(1643,1,{369:1},xZ),Fjn.Ke=function(n){zbn(this,Yx(n,140))},Fjn.a=0,Fjn.b=null,Fjn.c=null,Fjn.d=null,Fjn.e=null,EF(sIn,"RectilinearConvexHull/RectangleEventHandler",1643),Wfn(1645,1,FMn,St),Fjn.ue=function(n,t){return function(n,t){return oZ(),n.c==t.c?$9(t.d,n.d):$9(n.c,t.c)}(Yx(n,140),Yx(t,140))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/lambda$0$Type",1645),Wfn(1646,1,FMn,Tt),Fjn.ue=function(n,t){return function(n,t){return oZ(),n.c==t.c?$9(n.d,t.d):$9(n.c,t.c)}(Yx(n,140),Yx(t,140))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/lambda$1$Type",1646),Wfn(1647,1,FMn,At),Fjn.ue=function(n,t){return function(n,t){return oZ(),n.c==t.c?$9(t.d,n.d):$9(t.c,n.c)}(Yx(n,140),Yx(t,140))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/lambda$2$Type",1647),Wfn(1648,1,FMn,$t),Fjn.ue=function(n,t){return function(n,t){return oZ(),n.c==t.c?$9(n.d,t.d):$9(t.c,n.c)}(Yx(n,140),Yx(t,140))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/lambda$3$Type",1648),Wfn(1649,1,FMn,Lt),Fjn.ue=function(n,t){return Nun(Yx(n,140),Yx(t,140))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(sIn,"RectilinearConvexHull/lambda$4$Type",1649),Wfn(1650,1,{},tz),EF(sIn,"Scanline",1650),Wfn(2005,1,{}),EF(hIn,"AbstractGraphPlacer",2005),Wfn(325,1,{325:1},F$),Fjn.mf=function(n){return!!this.nf(n)&&(Qhn(this.b,Yx(Aun(n,(Ojn(),uQn)),21),n),!0)},Fjn.nf=function(n){var t,e,i;for(t=Yx(Aun(n,(Ojn(),uQn)),21),i=Yx(_V(Mzn,t),21).Kc();i.Ob();)if(e=Yx(i.Pb(),21),!Yx(_V(this.b,e),15).dc())return!1;return!0},EF(hIn,"ComponentGroup",325),Wfn(765,2005,{},sv),Fjn.of=function(n){var t;for(t=new pb(this.a);t.ai?1:0}(Yx(n,37),Yx(t,37))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(hIn,"ComponentsProcessor/lambda$0$Type",1265),Wfn(570,325,{325:1,570:1},iV),Fjn.mf=function(n){return a6(this,n)},Fjn.nf=function(n){return Fbn(this,n)},EF(hIn,"ModelOrderComponentGroup",570),Wfn(1291,2005,{},Dt),Fjn.lf=function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;if(1!=n.gc()){if(n.dc())return t.a.c=VQ(UKn,iEn,1,0,5,1),t.f.a=0,void(t.f.b=0);if(iI(Aun(t,(gjn(),HZn)))===iI((e9(),Izn))){for(s=n.Kc();s.Ob();){for(p=0,d=new pb((u=Yx(s.Pb(),37)).a);d.ab&&(k=0,j+=l+c,l=0),bgn(u,k+(g=u.c).a,j+g.b),OI(g),i=e.Math.max(i,k+v.a),l=e.Math.max(l,v.b),k+=v.a+c;if(t.f.a=i,t.f.b=j+l,ny(hL(Aun(a,_Zn)))){for(bjn(r=new Nt,n,c),f=n.Kc();f.Ob();)mN(OI(Yx(f.Pb(),37).c),r.e);mN(OI(t.f),r.a)}dY(t,n)}else(m=Yx(n.Xb(0),37))!=t&&(t.a.c=VQ(UKn,iEn,1,0,5,1),Dgn(t,m,0,0),o4(t,m),HH(t.d,m.d),t.f.a=m.f.a,t.f.b=m.f.b)},EF(hIn,"SimpleRowGraphPlacer",1291),Wfn(1292,1,FMn,Rt),Fjn.ue=function(n,t){return function(n,t){var e;return 0==(e=t.p-n.p)?$9(n.f.a*n.f.b,t.f.a*t.f.b):e}(Yx(n,37),Yx(t,37))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(hIn,"SimpleRowGraphPlacer/1",1292),Wfn(1262,1,rSn,Kt),Fjn.Lb=function(n){var t;return!!(t=Yx(Aun(Yx(n,243).b,(gjn(),$1n)),74))&&0!=t.b},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){var t;return!!(t=Yx(Aun(Yx(n,243).b,(gjn(),$1n)),74))&&0!=t.b},EF(wIn,"CompoundGraphPostprocessor/1",1262),Wfn(1261,1,dIn,dv),Fjn.pf=function(n,t){Wen(this,Yx(n,37),t)},EF(wIn,"CompoundGraphPreprocessor",1261),Wfn(441,1,{441:1},c9),Fjn.c=!1,EF(wIn,"CompoundGraphPreprocessor/ExternalPort",441),Wfn(243,1,{243:1},jx),Fjn.Ib=function(){return d$(this.c)+":"+Khn(this.b)},EF(wIn,"CrossHierarchyEdge",243),Wfn(763,1,FMn,ow),Fjn.ue=function(n,t){return function(n,t,e){var i,r;return t.c==(h0(),i3n)&&e.c==e3n?-1:t.c==e3n&&e.c==i3n?1:(i=X6(t.a,n.a),r=X6(e.a,n.a),t.c==i3n?r-i:i-r)}(this,Yx(n,243),Yx(t,243))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(wIn,"CrossHierarchyEdgeComparator",763),Wfn(299,134,{3:1,299:1,94:1,134:1}),Fjn.p=0,EF(gIn,"LGraphElement",299),Wfn(17,299,{3:1,17:1,299:1,94:1,134:1},jq),Fjn.Ib=function(){return Khn(this)};var Nzn=EF(gIn,"LEdge",17);Wfn(37,299,{3:1,20:1,37:1,299:1,94:1,134:1},k0),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new pb(this.b)},Fjn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+Gun(this.a):0==this.a.c.length?"G-layered"+Gun(this.b):"G[layerless"+Gun(this.a)+", layers"+Gun(this.b)+"]"};var xzn,Dzn=EF(gIn,"LGraph",37);Wfn(657,1,{}),Fjn.qf=function(){return this.e.n},Fjn.We=function(n){return Aun(this.e,n)},Fjn.rf=function(){return this.e.o},Fjn.sf=function(){return this.e.p},Fjn.Xe=function(n){return O$(this.e,n)},Fjn.tf=function(n){this.e.n.a=n.a,this.e.n.b=n.b},Fjn.uf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},Fjn.vf=function(n){this.e.p=n},EF(gIn,"LGraphAdapters/AbstractLShapeAdapter",657),Wfn(577,1,{839:1},sw),Fjn.wf=function(){var n,t;if(!this.b)for(this.b=h$(this.a.b.c.length),t=new pb(this.a.b);t.a0&&l8((Lz(t-1,n.length),n.charCodeAt(t-1)),TIn);)--t;if(r> ",n),krn(e)),yI(mI((n.a+="[",n),e.i),"]")),n.a},Fjn.c=!0,Fjn.d=!1;var nUn,tUn,eUn,iUn,rUn=EF(gIn,"LPort",11);Wfn(397,1,$En,fw),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new lw(new pb(this.a.e))},EF(gIn,"LPort/1",397),Wfn(1290,1,fEn,lw),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return Yx(Hz(this.a),17).c},Fjn.Ob=function(){return ZC(this.a)},Fjn.Qb=function(){z_(this.a)},EF(gIn,"LPort/1/1",1290),Wfn(359,1,$En,bw),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new ww(new pb(this.a.g))},EF(gIn,"LPort/2",359),Wfn(762,1,fEn,ww),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return Yx(Hz(this.a),17).d},Fjn.Ob=function(){return ZC(this.a)},Fjn.Qb=function(){z_(this.a)},EF(gIn,"LPort/2/1",762),Wfn(1283,1,$En,IM),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new UV(this)},EF(gIn,"LPort/CombineIter",1283),Wfn(201,1,fEn,UV),Fjn.Nb=function(n){I_(this,n)},Fjn.Qb=function(){Bk()},Fjn.Ob=function(){return YA(this)},Fjn.Pb=function(){return ZC(this.a)?Hz(this.a):Hz(this.b)},EF(gIn,"LPort/CombineIter/1",201),Wfn(1285,1,rSn,Bt),Fjn.Lb=function(n){return JK(n)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),0!=Yx(n,11).e.c.length},EF(gIn,"LPort/lambda$0$Type",1285),Wfn(1284,1,rSn,Ht),Fjn.Lb=function(n){return ZK(n)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),0!=Yx(n,11).g.c.length},EF(gIn,"LPort/lambda$1$Type",1284),Wfn(1286,1,rSn,qt),Fjn.Lb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Tit)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Tit)},EF(gIn,"LPort/lambda$2$Type",1286),Wfn(1287,1,rSn,Gt),Fjn.Lb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Eit)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Eit)},EF(gIn,"LPort/lambda$3$Type",1287),Wfn(1288,1,rSn,zt),Fjn.Lb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Bit)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),Yx(n,11).j==(Ikn(),Bit)},EF(gIn,"LPort/lambda$4$Type",1288),Wfn(1289,1,rSn,Ut),Fjn.Lb=function(n){return Q2(),Yx(n,11).j==(Ikn(),qit)},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return Q2(),Yx(n,11).j==(Ikn(),qit)},EF(gIn,"LPort/lambda$5$Type",1289),Wfn(29,299,{3:1,20:1,299:1,29:1,94:1,134:1},qF),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new pb(this.a)},Fjn.Ib=function(){return"L_"+hJ(this.b.b,this,0)+Gun(this.a)},EF(gIn,"Layer",29),Wfn(1342,1,{},wv),EF(OIn,AIn,1342),Wfn(1346,1,{},Xt),Fjn.Kb=function(n){return iun(Yx(n,82))},EF(OIn,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1346),Wfn(1349,1,{},Wt),Fjn.Kb=function(n){return iun(Yx(n,82))},EF(OIn,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1349),Wfn(1343,1,PEn,dw),Fjn.td=function(n){vfn(this.a,Yx(n,118))},EF(OIn,$In,1343),Wfn(1344,1,PEn,gw),Fjn.td=function(n){vfn(this.a,Yx(n,118))},EF(OIn,LIn,1344),Wfn(1345,1,{},Vt),Fjn.Kb=function(n){return new SR(null,new Nz(function(n){return!n.c&&(n.c=new AN(Zrt,n,5,8)),n.c}(Yx(n,79)),16))},EF(OIn,NIn,1345),Wfn(1347,1,YEn,pw),Fjn.Mb=function(n){return function(n,t){return XZ(t,TG(n))}(this.a,Yx(n,33))},EF(OIn,xIn,1347),Wfn(1348,1,{},Qt),Fjn.Kb=function(n){return new SR(null,new Nz(function(n){return!n.b&&(n.b=new AN(Zrt,n,4,7)),n.b}(Yx(n,79)),16))},EF(OIn,"ElkGraphImporter/lambda$5$Type",1348),Wfn(1350,1,YEn,vw),Fjn.Mb=function(n){return function(n,t){return XZ(t,TG(n))}(this.a,Yx(n,33))},EF(OIn,"ElkGraphImporter/lambda$7$Type",1350),Wfn(1351,1,YEn,Yt),Fjn.Mb=function(n){return function(n){return Whn(n)&&ny(hL(jln(n,(gjn(),C1n))))}(Yx(n,79))},EF(OIn,"ElkGraphImporter/lambda$8$Type",1351),Wfn(1278,1,{},Wh),EF(OIn,"ElkGraphLayoutTransferrer",1278),Wfn(1279,1,YEn,mw),Fjn.Mb=function(n){return function(n,t){return UE(),!_3(t.d.i,n)}(this.a,Yx(n,17))},EF(OIn,"ElkGraphLayoutTransferrer/lambda$0$Type",1279),Wfn(1280,1,PEn,yw),Fjn.td=function(n){UE(),eD(this.a,Yx(n,17))},EF(OIn,"ElkGraphLayoutTransferrer/lambda$1$Type",1280),Wfn(1281,1,YEn,kw),Fjn.Mb=function(n){return function(n,t){return UE(),_3(t.d.i,n)}(this.a,Yx(n,17))},EF(OIn,"ElkGraphLayoutTransferrer/lambda$2$Type",1281),Wfn(1282,1,PEn,jw),Fjn.td=function(n){UE(),eD(this.a,Yx(n,17))},EF(OIn,"ElkGraphLayoutTransferrer/lambda$3$Type",1282),Wfn(1485,1,dIn,Jt),Fjn.pf=function(n,t){!function(n,t){run(t,DIn,1),SE(WJ(new SR(null,new Nz(n.b,16)),new Zt),new ne),Ron(t)}(Yx(n,37),t)},EF(RIn,"CommentNodeMarginCalculator",1485),Wfn(1486,1,{},Zt),Fjn.Kb=function(n){return new SR(null,new Nz(Yx(n,29).a,16))},EF(RIn,"CommentNodeMarginCalculator/lambda$0$Type",1486),Wfn(1487,1,PEn,ne),Fjn.td=function(n){!function(n){var t,i,r,c,a,u,o,s,h,f,l,b;if(o=n.d,l=Yx(Aun(n,(Ojn(),JQn)),15),t=Yx(Aun(n,QVn),15),l||t){if(a=ty(fL(pnn(n,(gjn(),A0n)))),u=ty(fL(pnn(n,$0n))),b=0,l){for(h=0,c=l.Kc();c.Ob();)r=Yx(c.Pb(),10),h=e.Math.max(h,r.o.b),b+=r.o.a;b+=a*(l.gc()-1),o.d+=h+u}if(i=0,t){for(h=0,c=t.Kc();c.Ob();)r=Yx(c.Pb(),10),h=e.Math.max(h,r.o.b),i+=r.o.a;i+=a*(t.gc()-1),o.a+=h+u}(s=e.Math.max(b,i))>n.o.a&&(f=(s-n.o.a)/2,o.b=e.Math.max(o.b,f),o.c=e.Math.max(o.c,f))}}(Yx(n,10))},EF(RIn,"CommentNodeMarginCalculator/lambda$1$Type",1487),Wfn(1488,1,dIn,te),Fjn.pf=function(n,t){!function(n,t){var e,i,r,c,a,u,o;for(run(t,"Comment post-processing",1),c=new pb(n.b);c.a0&&Jgn(($z(0,e.c.length),Yx(e.c[0],29)),n),e.c.length>1&&Jgn(Yx(TR(e,e.c.length-1),29),n),Ron(t)}(Yx(n,37),t)},EF(RIn,"HierarchicalPortPositionProcessor",1517),Wfn(1518,1,dIn,Vh),Fjn.pf=function(n,t){!function(n,t){var i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(n.b=t,n.a=Yx(Aun(t,(gjn(),T1n)),19).a,n.c=Yx(Aun(t,S1n),19).a,0==n.c&&(n.c=Yjn),g=new JU(t.b,0);g.b=n.a&&(r=Nvn(n,v),l=e.Math.max(l,r.b),y=e.Math.max(y,r.d),eD(o,new mP(v,r)));for(E=new ip,f=0;f0),g.a.Xb(g.c=--g.b),ZL(g,T=new qF(n.b)),S$(g.b=2){for(b=!0,e=Yx(Hz(h=new pb(r.j)),11),f=null;h.a0)}(Yx(n,17))},EF(RIn,"PartitionPreprocessor/lambda$2$Type",1577),Wfn(1578,1,PEn,ki),Fjn.td=function(n){!function(n){var t;mvn(n,!0),t=hTn,O$(n,(gjn(),M0n))&&(t+=Yx(Aun(n,M0n),19).a),b5(n,M0n,d9(t))}(Yx(n,17))},EF(RIn,"PartitionPreprocessor/lambda$3$Type",1578),Wfn(1579,1,dIn,rf),Fjn.pf=function(n,t){!function(n,t){var e,i,r,c,a,u;for(run(t,"Port order processing",1),u=Yx(Aun(n,(gjn(),j0n)),421),e=new pb(n.b);e.at.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;uwn(NE(LE(xE($E(new tv,1),100),b),g))}}}(this),function(n){var t,e,i,r,c,a,u;for(c=new ME,r=new pb(n.d.a);r.a1)for(t=HA((e=new ev,++n.b,e),n.d),u=Ztn(c,0);u.b!=u.d.c;)a=Yx(IX(u),121),uwn(NE(LE(xE($E(new tv,1),0),t),a))}(this),Ggn(Cx(this.d),new am),c=new pb(this.a.a.b);c.a=g&&(eD(a,d9(f)),m=e.Math.max(m,y[f-1]-l),o+=d,p+=y[f-1]-p,l=y[f-1],d=s[f]),d=e.Math.max(d,s[f]),++f;o+=d}(w=e.Math.min(1/m,1/t.b/o))>r&&(r=w,i=a)}return i},Fjn.Wf=function(){return!1},EF(nCn,"MSDCutIndexHeuristic",802),Wfn(1617,1,dIn,Sc),Fjn.pf=function(n,t){Cvn(Yx(n,37),t)},EF(nCn,"SingleEdgeGraphWrapper",1617),Wfn(227,22,{3:1,35:1,22:1,227:1},FM);var vWn,mWn,yWn,kWn=X1(tCn,"CenterEdgeLabelPlacementStrategy",227,u_n,(function(){return psn(),x4(Gy(kWn,1),XEn,227,0,[bWn,dWn,lWn,wWn,gWn,fWn])}),(function(n){return psn(),rZ((y1(),vWn),n)}));Wfn(422,22,{3:1,35:1,22:1,422:1},BM);var jWn,EWn,TWn,MWn,SWn=X1(tCn,"ConstraintCalculationStrategy",422,u_n,(function(){return aY(),x4(Gy(SWn,1),XEn,422,0,[mWn,yWn])}),(function(n){return aY(),rZ((AW(),jWn),n)}));Wfn(314,22,{3:1,35:1,22:1,314:1,246:1,234:1},HM),Fjn.Kf=function(){return Shn(this)},Fjn.Xf=function(){return Shn(this)};var PWn,IWn,CWn,OWn,AWn=X1(tCn,"CrossingMinimizationStrategy",314,u_n,(function(){return O0(),x4(Gy(AWn,1),XEn,314,0,[TWn,EWn,MWn])}),(function(n){return O0(),rZ((TQ(),PWn),n)}));Wfn(337,22,{3:1,35:1,22:1,337:1},qM);var $Wn,LWn,NWn,xWn,DWn,RWn,KWn=X1(tCn,"CuttingStrategy",337,u_n,(function(){return f0(),x4(Gy(KWn,1),XEn,337,0,[IWn,OWn,CWn])}),(function(n){return f0(),rZ((MQ(),$Wn),n)}));Wfn(335,22,{3:1,35:1,22:1,335:1,246:1,234:1},GM),Fjn.Kf=function(){return fln(this)},Fjn.Xf=function(){return fln(this)};var _Wn,FWn,BWn,HWn=X1(tCn,"CycleBreakingStrategy",335,u_n,(function(){return min(),x4(Gy(HWn,1),XEn,335,0,[NWn,LWn,DWn,RWn,xWn])}),(function(n){return min(),rZ((lZ(),_Wn),n)}));Wfn(419,22,{3:1,35:1,22:1,419:1},zM);var qWn,GWn,zWn,UWn,XWn=X1(tCn,"DirectionCongruency",419,u_n,(function(){return fZ(),x4(Gy(XWn,1),XEn,419,0,[FWn,BWn])}),(function(n){return fZ(),rZ((PW(),qWn),n)}));Wfn(450,22,{3:1,35:1,22:1,450:1},UM);var WWn,VWn,QWn,YWn,JWn,ZWn,nVn,tVn=X1(tCn,"EdgeConstraint",450,u_n,(function(){return i5(),x4(Gy(tVn,1),XEn,450,0,[zWn,GWn,UWn])}),(function(n){return i5(),rZ((SQ(),WWn),n)}));Wfn(276,22,{3:1,35:1,22:1,276:1},XM);var eVn,iVn,rVn,cVn=X1(tCn,"EdgeLabelSideSelection",276,u_n,(function(){return pon(),x4(Gy(cVn,1),XEn,276,0,[QWn,VWn,JWn,YWn,nVn,ZWn])}),(function(n){return pon(),rZ((T1(),eVn),n)}));Wfn(479,22,{3:1,35:1,22:1,479:1},WM);var aVn,uVn,oVn,sVn,hVn,fVn,lVn,bVn=X1(tCn,"EdgeStraighteningStrategy",479,u_n,(function(){return cJ(),x4(Gy(bVn,1),XEn,479,0,[rVn,iVn])}),(function(n){return cJ(),rZ((IW(),aVn),n)}));Wfn(274,22,{3:1,35:1,22:1,274:1},VM);var wVn,dVn,gVn,pVn,vVn,mVn,yVn,kVn=X1(tCn,"FixedAlignment",274,u_n,(function(){return Wcn(),x4(Gy(kVn,1),XEn,274,0,[hVn,sVn,lVn,oVn,fVn,uVn])}),(function(n){return Wcn(),rZ((j1(),wVn),n)}));Wfn(275,22,{3:1,35:1,22:1,275:1},QM);var jVn,EVn,TVn,MVn,SVn,PVn,IVn,CVn,OVn,AVn,$Vn,LVn=X1(tCn,"GraphCompactionStrategy",275,u_n,(function(){return uon(),x4(Gy(LVn,1),XEn,275,0,[mVn,gVn,yVn,vVn,pVn,dVn])}),(function(n){return uon(),rZ((k1(),jVn),n)}));Wfn(256,22,{3:1,35:1,22:1,256:1},YM);var NVn,xVn,DVn,RVn,KVn=X1(tCn,"GraphProperties",256,u_n,(function(){return edn(),x4(Gy(KVn,1),XEn,256,0,[TVn,SVn,PVn,IVn,CVn,OVn,$Vn,EVn,MVn,AVn])}),(function(n){return edn(),rZ((n5(),NVn),n)}));Wfn(292,22,{3:1,35:1,22:1,292:1},JM);var _Vn,FVn,BVn,HVn,qVn=X1(tCn,"GreedySwitchType",292,u_n,(function(){return r4(),x4(Gy(qVn,1),XEn,292,0,[DVn,RVn,xVn])}),(function(n){return r4(),rZ((CQ(),_Vn),n)}));Wfn(303,22,{3:1,35:1,22:1,303:1},ZM);var GVn,zVn,UVn,XVn=X1(tCn,"InLayerConstraint",303,u_n,(function(){return AJ(),x4(Gy(XVn,1),XEn,303,0,[BVn,HVn,FVn])}),(function(n){return AJ(),rZ((IQ(),GVn),n)}));Wfn(420,22,{3:1,35:1,22:1,420:1},nS);var WVn,VVn,QVn,YVn,JVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn,uQn,oQn,sQn,hQn,fQn,lQn,bQn,wQn,dQn,gQn,pQn,vQn,mQn,yQn,kQn,jQn,EQn,TQn,MQn,SQn,PQn,IQn,CQn,OQn,AQn,$Qn,LQn,NQn,xQn,DQn,RQn,KQn,_Qn,FQn,BQn,HQn,qQn,GQn,zQn,UQn,XQn,WQn,VQn,QQn,YQn,JQn,ZQn,nYn,tYn,eYn,iYn,rYn=X1(tCn,"InteractiveReferencePoint",420,u_n,(function(){return dX(),x4(Gy(rYn,1),XEn,420,0,[zVn,UVn])}),(function(n){return dX(),rZ(($W(),WVn),n)}));Wfn(163,22,{3:1,35:1,22:1,163:1},cS);var cYn,aYn,uYn,oYn,sYn,hYn,fYn,lYn,bYn,wYn,dYn,gYn,pYn,vYn,mYn,yYn,kYn,jYn,EYn,TYn,MYn,SYn,PYn,IYn,CYn,OYn,AYn,$Yn,LYn,NYn,xYn,DYn,RYn,KYn,_Yn,FYn,BYn,HYn,qYn,GYn,zYn,UYn,XYn,WYn,VYn,QYn,YYn,JYn,ZYn,nJn,tJn,eJn,iJn,rJn,cJn,aJn,uJn,oJn,sJn,hJn,fJn,lJn,bJn,wJn,dJn,gJn,pJn,vJn,mJn,yJn,kJn,jJn,EJn,TJn,MJn,SJn,PJn,IJn,CJn,OJn,AJn,$Jn,LJn,NJn,xJn,DJn,RJn,KJn,_Jn,FJn,BJn,HJn,qJn,GJn,zJn,UJn,XJn,WJn,VJn,QJn,YJn,JJn,ZJn,nZn,tZn,eZn,iZn,rZn,cZn,aZn,uZn,oZn,sZn,hZn,fZn,lZn,bZn,wZn,dZn,gZn,pZn,vZn,mZn,yZn,kZn,jZn,EZn,TZn,MZn,SZn,PZn,IZn,CZn,OZn,AZn,$Zn,LZn,NZn,xZn,DZn,RZn,KZn,_Zn,FZn,BZn,HZn,qZn,GZn,zZn,UZn,XZn,WZn,VZn,QZn,YZn,JZn,ZZn,n1n,t1n,e1n,i1n,r1n,c1n,a1n,u1n,o1n,s1n,h1n,f1n,l1n,b1n,w1n,d1n,g1n,p1n,v1n,m1n,y1n,k1n,j1n,E1n,T1n,M1n,S1n,P1n,I1n,C1n,O1n,A1n,$1n,L1n,N1n,x1n,D1n,R1n,K1n,_1n,F1n,B1n,H1n,q1n,G1n,z1n,U1n,X1n,W1n,V1n,Q1n,Y1n,J1n,Z1n,n0n,t0n,e0n,i0n,r0n,c0n,a0n,u0n,o0n,s0n,h0n,f0n,l0n,b0n,w0n,d0n,g0n,p0n,v0n,m0n,y0n,k0n,j0n,E0n,T0n,M0n,S0n,P0n,I0n,C0n,O0n,A0n,$0n,L0n,N0n,x0n,D0n,R0n,K0n,_0n,F0n,B0n,H0n,q0n,G0n,z0n,U0n,X0n,W0n,V0n,Q0n,Y0n,J0n,Z0n,n2n,t2n,e2n,i2n,r2n,c2n,a2n,u2n,o2n,s2n,h2n,f2n,l2n,b2n,w2n,d2n,g2n,p2n=X1(tCn,"LayerConstraint",163,u_n,(function(){return d7(),x4(Gy(p2n,1),XEn,163,0,[iYn,ZQn,nYn,tYn,eYn])}),(function(n){return d7(),rZ((dZ(),cYn),n)}));Wfn(848,1,fSn,of),Fjn.Qe=function(n){j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,uCn),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),BYn),(lsn(),O7n)),XWn),J9((Qtn(),T7n))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,oCn),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(TA(),!1)),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,sCn),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),hJn),O7n),rYn),J9(T7n)))),xU(n,sCn,pCn,lJn),xU(n,sCn,PCn,fJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,hCn),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,fCn),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),I7n),D_n),J9(T7n)))),j7(n,new isn(function(n,t){return n.f=t,n}(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,lCn),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),I7n),D_n),J9(M7n)),x4(Gy(fFn,1),TEn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,bCn),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),VJn),O7n),c3n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,wCn),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),d9(7)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,dCn),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,gCn),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,pCn),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),_Yn),O7n),HWn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,vCn),SOn),"Node Layering Strategy"),"Strategy for node layering."),PJn),O7n),j2n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,mCn),SOn),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),pJn),O7n),p2n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,yCn),SOn),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),d9(-1)),$7n),U_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,kCn),SOn),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),d9(-1)),$7n),U_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,jCn),POn),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),d9(4)),$7n),U_n),J9(T7n)))),xU(n,jCn,vCn,yJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ECn),POn),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),d9(2)),$7n),U_n),J9(T7n)))),xU(n,ECn,vCn,jJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,TCn),IOn),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),MJn),O7n),Q2n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,MCn),IOn),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),d9(0)),$7n),U_n),J9(T7n)))),xU(n,MCn,TCn,null),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,SCn),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),d9(Yjn)),$7n),U_n),J9(T7n)))),xU(n,SCn,vCn,wJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,PCn),COn),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),RYn),O7n),AWn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ICn),COn),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,CCn),COn),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),C7n),H_n),J9(T7n)))),xU(n,CCn,OOn,AYn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,OCn),COn),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),I7n),D_n),J9(T7n)))),xU(n,OCn,PCn,xYn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ACn),COn),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),d9(-1)),$7n),U_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,$Cn),COn),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),d9(-1)),$7n),U_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,LCn),AOn),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),d9(40)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,NCn),AOn),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),IYn),O7n),qVn),J9(T7n)))),xU(n,NCn,PCn,CYn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,xCn),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),TYn),O7n),qVn),J9(T7n)))),xU(n,xCn,PCn,MYn),xU(n,xCn,OOn,SYn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,DCn),$On),"Node Placement Strategy"),"Strategy for node placement."),XJn),O7n),z2n),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,RCn),$On),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),I7n),D_n),J9(T7n)))),xU(n,RCn,DCn,RJn),xU(n,RCn,DCn,KJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,KCn),LOn),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),AJn),O7n),bVn),J9(T7n)))),xU(n,KCn,DCn,$Jn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,_Cn),LOn),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),NJn),O7n),kVn),J9(T7n)))),xU(n,_Cn,DCn,xJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,FCn),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),C7n),H_n),J9(T7n)))),xU(n,FCn,DCn,FJn),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,BCn),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),O7n),x2n),J9(E7n)))),xU(n,BCn,DCn,zJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,HCn),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),qJn),O7n),x2n),J9(T7n)))),xU(n,HCn,DCn,GJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,qCn),NOn),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),VYn),O7n),w3n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,GCn),NOn),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),YYn),O7n),m3n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,zCn),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),ZYn),O7n),T3n),J9(T7n)))),xU(n,zCn,xOn,nJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,UCn),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),C7n),H_n),J9(T7n)))),xU(n,UCn,xOn,eJn),xU(n,UCn,zCn,iJn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,XCn),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),C7n),H_n),J9(T7n)))),xU(n,XCn,xOn,XYn),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,WCn),DOn),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,VCn),DOn),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,QCn),DOn),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,YCn),DOn),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,JCn),ROn),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),d9(0)),$7n),U_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ZCn),ROn),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),d9(0)),$7n),U_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,nOn),ROn),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),d9(0)),$7n),U_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,tOn),KOn),YSn),"Tries to further compact components (disconnected sub-graphs)."),!1),I7n),D_n),J9(T7n)))),xU(n,tOn,DPn,!0),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,eOn),_On),"Post Compaction Strategy"),FOn),fYn),O7n),LVn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,iOn),_On),"Post Compaction Constraint Calculation"),FOn),sYn),O7n),SWn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,rOn),BOn),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,cOn),BOn),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),d9(16)),$7n),U_n),J9(T7n)))),xU(n,cOn,rOn,!0),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,aOn),BOn),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),d9(5)),$7n),U_n),J9(T7n)))),xU(n,aOn,rOn,!0),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,uOn),HOn),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),PZn),O7n),F3n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,oOn),HOn),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),C7n),H_n),J9(T7n)))),xU(n,oOn,uOn,aZn),xU(n,oOn,uOn,uZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,sOn),HOn),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),C7n),H_n),J9(T7n)))),xU(n,sOn,uOn,sZn),xU(n,sOn,uOn,hZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,hOn),qOn),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),pZn),O7n),KWn),J9(T7n)))),xU(n,hOn,uOn,vZn),xU(n,hOn,uOn,mZn),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,fOn),qOn),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),L7n),JKn),J9(T7n)))),xU(n,fOn,hOn,lZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,lOn),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),wZn),$7n),U_n),J9(T7n)))),xU(n,lOn,hOn,dZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,bOn),GOn),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),$Zn),O7n),C3n),J9(T7n)))),xU(n,bOn,uOn,LZn),xU(n,bOn,uOn,NZn),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,wOn),GOn),"Valid Indices for Wrapping"),null),L7n),JKn),J9(T7n)))),xU(n,wOn,uOn,CZn),xU(n,wOn,uOn,OZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,dOn),zOn),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),I7n),D_n),J9(T7n)))),xU(n,dOn,uOn,EZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,gOn),zOn),"Distance Penalty When Improving Cuts"),null),2),C7n),H_n),J9(T7n)))),xU(n,gOn,uOn,kZn),xU(n,gOn,dOn,!0),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,pOn),zOn),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),I7n),D_n),J9(T7n)))),xU(n,pOn,uOn,MZn),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,vOn),UOn),"Edge Label Side Selection"),"Method to decide on edge label sides."),zYn),O7n),cVn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,mOn),UOn),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),qYn),O7n),kWn),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[j7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,yOn),XOn),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),yYn),O7n),n3n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,kOn),XOn),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,jOn),XOn),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),bYn),O7n),Lzn),J9(T7n)))),xU(n,jOn,DPn,null),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,EOn),XOn),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),pYn),O7n),I2n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,TOn),XOn),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),C7n),H_n),J9(T7n)))),xU(n,TOn,yOn,null),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,MOn),XOn),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),C7n),H_n),J9(T7n)))),xU(n,MOn,yOn,null),Djn((new ff,n))},EF(tCn,"LayeredMetaDataProvider",848),Wfn(986,1,fSn,ff),Fjn.Qe=function(n){Djn(n)},EF(tCn,"LayeredOptions",986),Wfn(987,1,{},Ic),Fjn.$e=function(){return new cv},Fjn._e=function(n){},EF(tCn,"LayeredOptions/LayeredFactory",987),Wfn(1372,1,{}),Fjn.a=0,EF(xAn,"ElkSpacings/AbstractSpacingsBuilder",1372),Wfn(779,1372,{},B7),EF(tCn,"LayeredSpacings/LayeredSpacingsBuilder",779),Wfn(313,22,{3:1,35:1,22:1,313:1,246:1,234:1},tS),Fjn.Kf=function(){return rbn(this)},Fjn.Xf=function(){return rbn(this)};var v2n,m2n,y2n,k2n,j2n=X1(tCn,"LayeringStrategy",313,u_n,(function(){return nun(),x4(Gy(j2n,1),XEn,313,0,[d2n,b2n,f2n,l2n,g2n,w2n])}),(function(n){return nun(),rZ((E1(),v2n),n)}));Wfn(378,22,{3:1,35:1,22:1,378:1},eS);var E2n,T2n,M2n,S2n,P2n,I2n=X1(tCn,"LongEdgeOrderingStrategy",378,u_n,(function(){return i8(),x4(Gy(I2n,1),XEn,378,0,[m2n,y2n,k2n])}),(function(n){return i8(),rZ((OQ(),E2n),n)}));Wfn(197,22,{3:1,35:1,22:1,197:1},iS);var C2n,O2n,A2n,$2n,L2n,N2n,x2n=X1(tCn,"NodeFlexibility",197,u_n,(function(){return Hen(),x4(Gy(x2n,1),XEn,197,0,[S2n,P2n,M2n,T2n])}),(function(n){return Hen(),rZ((JY(),C2n),n)}));Wfn(315,22,{3:1,35:1,22:1,315:1,246:1,234:1},rS),Fjn.Kf=function(){return hln(this)},Fjn.Xf=function(){return hln(this)};var D2n,R2n,K2n,_2n,F2n,B2n,H2n,q2n,G2n,z2n=X1(tCn,"NodePlacementStrategy",315,u_n,(function(){return ain(),x4(Gy(z2n,1),XEn,315,0,[N2n,A2n,$2n,O2n,L2n])}),(function(n){return ain(),rZ((bZ(),D2n),n)}));Wfn(260,22,{3:1,35:1,22:1,260:1},aS);var U2n,X2n,W2n,V2n,Q2n=X1(tCn,"NodePromotionStrategy",260,u_n,(function(){return _bn(),x4(Gy(Q2n,1),XEn,260,0,[q2n,K2n,B2n,_2n,F2n,R2n,H2n,G2n])}),(function(n){return _bn(),rZ((g3(),U2n),n)}));Wfn(339,22,{3:1,35:1,22:1,339:1},uS);var Y2n,J2n,Z2n,n3n=X1(tCn,"OrderingStrategy",339,u_n,(function(){return k5(),x4(Gy(n3n,1),XEn,339,0,[W2n,X2n,V2n])}),(function(n){return k5(),rZ(($Q(),Y2n),n)}));Wfn(421,22,{3:1,35:1,22:1,421:1},oS);var t3n,e3n,i3n,r3n,c3n=X1(tCn,"PortSortingStrategy",421,u_n,(function(){return $J(),x4(Gy(c3n,1),XEn,421,0,[J2n,Z2n])}),(function(n){return $J(),rZ((OW(),t3n),n)}));Wfn(452,22,{3:1,35:1,22:1,452:1},sS);var a3n,u3n,o3n,s3n,h3n=X1(tCn,"PortType",452,u_n,(function(){return h0(),x4(Gy(h3n,1),XEn,452,0,[r3n,e3n,i3n])}),(function(n){return h0(),rZ((LQ(),a3n),n)}));Wfn(375,22,{3:1,35:1,22:1,375:1},hS);var f3n,l3n,b3n,w3n=X1(tCn,"SelfLoopDistributionStrategy",375,u_n,(function(){return d3(),x4(Gy(w3n,1),XEn,375,0,[u3n,o3n,s3n])}),(function(n){return d3(),rZ((AQ(),f3n),n)}));Wfn(376,22,{3:1,35:1,22:1,376:1},fS);var d3n,g3n,p3n,v3n,m3n=X1(tCn,"SelfLoopOrderingStrategy",376,u_n,(function(){return rQ(),x4(Gy(m3n,1),XEn,376,0,[b3n,l3n])}),(function(n){return rQ(),rZ((CW(),d3n),n)}));Wfn(304,1,{304:1},pyn),EF(tCn,"Spacings",304),Wfn(336,22,{3:1,35:1,22:1,336:1},lS);var y3n,k3n,j3n,E3n,T3n=X1(tCn,"SplineRoutingMode",336,u_n,(function(){return $6(),x4(Gy(T3n,1),XEn,336,0,[g3n,p3n,v3n])}),(function(n){return $6(),rZ((xQ(),y3n),n)}));Wfn(338,22,{3:1,35:1,22:1,338:1},bS);var M3n,S3n,P3n,I3n,C3n=X1(tCn,"ValidifyStrategy",338,u_n,(function(){return V2(),x4(Gy(C3n,1),XEn,338,0,[E3n,k3n,j3n])}),(function(n){return V2(),rZ((DQ(),M3n),n)}));Wfn(377,22,{3:1,35:1,22:1,377:1},wS);var O3n,A3n,$3n,L3n,N3n,x3n,D3n,R3n,K3n,_3n,F3n=X1(tCn,"WrappingStrategy",377,u_n,(function(){return F4(),x4(Gy(F3n,1),XEn,377,0,[P3n,I3n,S3n])}),(function(n){return F4(),rZ((NQ(),O3n),n)}));Wfn(1383,1,KAn,lf),Fjn.Yf=function(n){return Yx(n,37),A3n},Fjn.pf=function(n,t){!function(n,t,e){var i,r,c,a,u,o,s,h;for(run(e,"Depth-first cycle removal",1),o=(s=t.a).c.length,n.c=new ip,n.d=VQ(Vot,wSn,25,o,16,1),n.a=VQ(Vot,wSn,25,o,16,1),n.b=new ip,c=0,u=new pb(s);u.a0?S+1:1);for(a=new pb(k.g);a.a0?S+1:1)}0==n.c[s]?KD(n.e,d):0==n.a[s]&&KD(n.f,d),++s}for(w=-1,b=1,f=new ip,n.d=Yx(Aun(t,(Ojn(),FQn)),230);A>0;){for(;0!=n.e.b;)I=Yx(mD(n.e),10),n.b[I.p]=w--,Ugn(n,I),--A;for(;0!=n.f.b;)C=Yx(mD(n.f),10),n.b[C.p]=b++,Ugn(n,C),--A;if(A>0){for(l=nTn,v=new pb(m);v.a=l&&(y>l&&(f.c=VQ(UKn,iEn,1,0,5,1),l=y),f.c[f.c.length]=d);h=n.Zf(f),n.b[h.p]=b++,Ugn(n,h),--A}}for(P=m.c.length+1,s=0;sn.b[O]&&(mvn(i,!0),b5(t,iQn,(TA(),!0)));n.a=null,n.c=null,n.b=null,BH(n.f),BH(n.e),Ron(e)}(this,Yx(n,37),t)},Fjn.Zf=function(n){return Yx(TR(n,Uen(this.d,n.c.length)),10)},EF(_An,"GreedyCycleBreaker",782),Wfn(1386,782,KAn,KP),Fjn.Zf=function(n){var t,e,i,r;for(r=null,t=Yjn,i=new pb(n);i.a0&&esn(n,u,h);for(r=new pb(h);r.a=s){S$(v.b>0),v.a.Xb(v.c=--v.b);break}g.a>h&&(c?(S4(c.b,g.b),c.a=e.Math.max(c.a,g.a),hB(v)):(eD(g.b,l),g.c=e.Math.min(g.c,h),g.a=e.Math.max(g.a,s),c=g))}c||((c=new gv).c=h,c.a=s,ZL(v,c),eD(c.b,l))}for(o=t.b,f=0,p=new pb(r);p.at.p?-1:0}(Yx(n,10),Yx(t,10))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(FAn,"StretchWidthLayerer/1",1394),Wfn(402,1,BAn),Fjn.Nf=function(n,t,e,i,r,c){},Fjn._f=function(n,t,e){return Zgn(this,n,t,e)},Fjn.Mf=function(){this.g=VQ(Zot,HAn,25,this.d,15,1),this.f=VQ(Zot,HAn,25,this.d,15,1)},Fjn.Of=function(n,t){this.e[n]=VQ(Wot,MTn,25,t[n].length,15,1)},Fjn.Pf=function(n,t,e){e[n][t].p=t,this.e[n][t]=t},Fjn.Qf=function(n,t,e,i){Yx(TR(i[n][t].j,e),11).p=this.d++},Fjn.b=0,Fjn.c=0,Fjn.d=0,EF(qAn,"AbstractBarycenterPortDistributor",402),Wfn(1633,1,FMn,od),Fjn.ue=function(n,t){return function(n,t,e){var i,r,c,a;return(c=t.j)!=(a=e.j)?c.g-a.g:(i=n.f[t.p],r=n.f[e.p],0==i&&0==r?0:0==i?-1:0==r?1:$9(i,r))}(this.a,Yx(n,11),Yx(t,11))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(qAn,"AbstractBarycenterPortDistributor/lambda$0$Type",1633),Wfn(817,1,VIn,wX),Fjn.Nf=function(n,t,e,i,r,c){},Fjn.Pf=function(n,t,e){},Fjn.Qf=function(n,t,e,i){},Fjn.Lf=function(){return!1},Fjn.Mf=function(){this.c=this.e.a,this.g=this.f.g},Fjn.Of=function(n,t){t[n][0].c.p=n},Fjn.Rf=function(){return!1},Fjn.ag=function(n,t,e,i){e?Ocn(this,n):(Gcn(this,n,i),Byn(this,n,t)),n.c.length>1&&(ny(hL(Aun(dB(($z(0,n.c.length),Yx(n.c[0],10))),(gjn(),VZn))))?Gln(n,this.d,Yx(this,660)):(XH(),JC(n,this.d)),u4(this.e,n))},Fjn.Sf=function(n,t,e,i){var r,c,a,u,o,s,h;for(t!=$R(e,n.length)&&(c=n[t-(e?1:-1)],lQ(this.f,c,e?(h0(),i3n):(h0(),e3n))),r=n[t][0],h=!i||r.k==(bon(),_zn),s=DV(n[t]),this.ag(s,h,!1,e),a=0,o=new pb(s);o.a"),n0?DG(this.a,n[t-1],n[t]):!e&&t0&&(e+=o.n.a+o.o.a/2,++f),b=new pb(o.j);b.a0&&(e/=f),g=VQ(Jot,rMn,25,i.a.c.length,15,1),u=0,s=new pb(i.a);s.a1&&(ny(hL(Aun(dB(($z(0,n.c.length),Yx(n.c[0],10))),(gjn(),VZn))))?Gln(n,this.d,this):(XH(),JC(n,this.d)),ny(hL(Aun(dB(($z(0,n.c.length),Yx(n.c[0],10))),VZn)))||u4(this.e,n))},EF(qAn,"ModelOrderBarycenterHeuristic",660),Wfn(1803,1,FMn,pd),Fjn.ue=function(n,t){return Non(this.a,Yx(n,10),Yx(t,10))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(qAn,"ModelOrderBarycenterHeuristic/lambda$0$Type",1803),Wfn(1403,1,KAn,yf),Fjn.Yf=function(n){var t;return Yx(n,37),oR(t=vC(Q3n),($un(),ZGn),($jn(),tXn)),t},Fjn.pf=function(n,t){!function(n){run(n,"No crossing minimization",1),Ron(n)}((Yx(n,37),t))},EF(qAn,"NoCrossingMinimizer",1403),Wfn(796,402,BAn,yk),Fjn.$f=function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new pb(n.j);h.a1&&(r.j==(Ikn(),Eit)?this.b[n]=!0:r.j==qit&&n>0&&(this.b[n-1]=!0))},Fjn.f=0,EF(WIn,"AllCrossingsCounter",1798),Wfn(587,1,{},s2),Fjn.b=0,Fjn.d=0,EF(WIn,"BinaryIndexedTree",587),Wfn(524,1,{},rx),EF(WIn,"CrossingsCounter",524),Wfn(1906,1,FMn,vd),Fjn.ue=function(n,t){return function(n,t,e){return eO(n.d[t.p],n.d[e.p])}(this.a,Yx(n,11),Yx(t,11))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(WIn,"CrossingsCounter/lambda$0$Type",1906),Wfn(1907,1,FMn,md),Fjn.ue=function(n,t){return function(n,t,e){return eO(n.d[t.p],n.d[e.p])}(this.a,Yx(n,11),Yx(t,11))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(WIn,"CrossingsCounter/lambda$1$Type",1907),Wfn(1908,1,FMn,yd),Fjn.ue=function(n,t){return function(n,t,e){return eO(n.d[t.p],n.d[e.p])}(this.a,Yx(n,11),Yx(t,11))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(WIn,"CrossingsCounter/lambda$2$Type",1908),Wfn(1909,1,FMn,kd),Fjn.ue=function(n,t){return function(n,t,e){return eO(n.d[t.p],n.d[e.p])}(this.a,Yx(n,11),Yx(t,11))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(WIn,"CrossingsCounter/lambda$3$Type",1909),Wfn(1910,1,PEn,jd),Fjn.td=function(n){!function(n,t){dD(),eD(n,new mP(t,d9(t.e.c.length+t.g.c.length)))}(this.a,Yx(n,11))},EF(WIn,"CrossingsCounter/lambda$4$Type",1910),Wfn(1911,1,YEn,Ed),Fjn.Mb=function(n){return function(n,t){return dD(),t!=n}(this.a,Yx(n,11))},EF(WIn,"CrossingsCounter/lambda$5$Type",1911),Wfn(1912,1,PEn,Td),Fjn.td=function(n){NP(this,n)},EF(WIn,"CrossingsCounter/lambda$6$Type",1912),Wfn(1913,1,PEn,pS),Fjn.td=function(n){var t;dD(),OX(this.b,(t=this.a,Yx(n,11),t))},EF(WIn,"CrossingsCounter/lambda$7$Type",1913),Wfn(826,1,rSn,xc),Fjn.Lb=function(n){return dD(),O$(Yx(n,11),(Ojn(),RQn))},Fjn.Fb=function(n){return this===n},Fjn.Mb=function(n){return dD(),O$(Yx(n,11),(Ojn(),RQn))},EF(WIn,"CrossingsCounter/lambda$8$Type",826),Wfn(1905,1,{},Md),EF(WIn,"HyperedgeCrossingsCounter",1905),Wfn(467,1,{35:1,467:1},fN),Fjn.wd=function(n){return function(n,t){return n.et.e?1:n.ft.f?1:W5(n)-W5(t)}(this,Yx(n,467))},Fjn.b=0,Fjn.c=0,Fjn.e=0,Fjn.f=0;var n4n=EF(WIn,"HyperedgeCrossingsCounter/Hyperedge",467);Wfn(362,1,{35:1,362:1},gH),Fjn.wd=function(n){return function(n,t){return n.ct.c?1:n.bt.b?1:n.a!=t.a?W5(n.a)-W5(t.a):n.d==(GW(),e4n)&&t.d==t4n?-1:n.d==t4n&&t.d==e4n?1:0}(this,Yx(n,362))},Fjn.b=0,Fjn.c=0;var t4n,e4n,i4n=EF(WIn,"HyperedgeCrossingsCounter/HyperedgeCorner",362);Wfn(523,22,{3:1,35:1,22:1,523:1},gS);var r4n,c4n,a4n,u4n,o4n,s4n=X1(WIn,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",523,u_n,(function(){return GW(),x4(Gy(s4n,1),XEn,523,0,[e4n,t4n])}),(function(n){return GW(),rZ((NW(),r4n),n)}));Wfn(1405,1,KAn,hf),Fjn.Yf=function(n){return Yx(Aun(Yx(n,37),(Ojn(),bQn)),21).Hc((edn(),SVn))?c4n:null},Fjn.pf=function(n,t){!function(n,t,e){var i;for(run(e,"Interactive node placement",1),n.a=Yx(Aun(t,(Ojn(),zQn)),304),i=new pb(t.b);i.a1},EF(GAn,"NetworkSimplexPlacer/lambda$18$Type",1431),Wfn(1432,1,PEn,vH),Fjn.td=function(n){!function(n,t,e,i,r){hz(),uwn(NE(LE($E(xE(new tv,0),r.d.e-n),t),r.d)),uwn(NE(LE($E(xE(new tv,0),e-r.a.e),r.a),i))}(this.c,this.b,this.d,this.a,Yx(n,401))},Fjn.c=0,Fjn.d=0,EF(GAn,"NetworkSimplexPlacer/lambda$19$Type",1432),Wfn(1415,1,{},Xc),Fjn.Kb=function(n){return hz(),new SR(null,new Nz(Yx(n,29).a,16))},EF(GAn,"NetworkSimplexPlacer/lambda$2$Type",1415),Wfn(1433,1,PEn,Cd),Fjn.td=function(n){!function(n,t){hz(),t.n.b+=n}(this.a,Yx(n,11))},Fjn.a=0,EF(GAn,"NetworkSimplexPlacer/lambda$20$Type",1433),Wfn(1434,1,{},Wc),Fjn.Kb=function(n){return hz(),new SR(null,new Nz(Yx(n,29).a,16))},EF(GAn,"NetworkSimplexPlacer/lambda$21$Type",1434),Wfn(1435,1,PEn,Od),Fjn.td=function(n){RO(this.a,Yx(n,10))},EF(GAn,"NetworkSimplexPlacer/lambda$22$Type",1435),Wfn(1436,1,YEn,Vc),Fjn.Mb=function(n){return SL(n)},EF(GAn,"NetworkSimplexPlacer/lambda$23$Type",1436),Wfn(1437,1,{},Qc),Fjn.Kb=function(n){return hz(),new SR(null,new Nz(Yx(n,29).a,16))},EF(GAn,"NetworkSimplexPlacer/lambda$24$Type",1437),Wfn(1438,1,YEn,Ad),Fjn.Mb=function(n){return function(n,t){return 2==n.j[t.p]}(this.a,Yx(n,10))},EF(GAn,"NetworkSimplexPlacer/lambda$25$Type",1438),Wfn(1439,1,PEn,yS),Fjn.td=function(n){!function(n,t,e){var i,r,c;for(r=new $K(bA(a7(e).a.Kc(),new h));Vfn(r);)ZW(i=Yx(kV(r),17))||!ZW(i)&&i.c.i.c==i.d.i.c||(c=Cbn(n,i,e,new yv)).c.length>1&&(t.c[t.c.length]=c)}(this.a,this.b,Yx(n,10))},EF(GAn,"NetworkSimplexPlacer/lambda$26$Type",1439),Wfn(1440,1,YEn,Yc),Fjn.Mb=function(n){return hz(),!ZW(Yx(n,17))},EF(GAn,"NetworkSimplexPlacer/lambda$27$Type",1440),Wfn(1441,1,YEn,Jc),Fjn.Mb=function(n){return hz(),!ZW(Yx(n,17))},EF(GAn,"NetworkSimplexPlacer/lambda$28$Type",1441),Wfn(1442,1,{},$d),Fjn.Ce=function(n,t){return AO(this.a,Yx(n,29),Yx(t,29))},EF(GAn,"NetworkSimplexPlacer/lambda$29$Type",1442),Wfn(1416,1,{},Zc),Fjn.Kb=function(n){return hz(),new SR(null,new nF(new $K(bA(o7(Yx(n,10)).a.Kc(),new h))))},EF(GAn,"NetworkSimplexPlacer/lambda$3$Type",1416),Wfn(1417,1,YEn,na),Fjn.Mb=function(n){return hz(),function(n){return hz(),!(ZW(n)||!ZW(n)&&n.c.i.c==n.d.i.c)}(Yx(n,17))},EF(GAn,"NetworkSimplexPlacer/lambda$4$Type",1417),Wfn(1418,1,PEn,Ld),Fjn.td=function(n){!function(n,t){var i,r,c,a,u,o,s,h,f,l,b;i=HA(new ev,n.f),o=n.i[t.c.i.p],l=n.i[t.d.i.p],u=t.c,f=t.d,a=u.a.b,h=f.a.b,o.b||(a+=u.n.b),l.b||(h+=f.n.b),s=oG(e.Math.max(0,a-h)),c=oG(e.Math.max(0,h-a)),b=e.Math.max(1,Yx(Aun(t,(gjn(),P0n)),19).a)*GX(t.c.i.k,t.d.i.k),r=new vS(uwn(NE(LE($E(xE(new tv,b),c),i),Yx(BF(n.k,t.c),121))),uwn(NE(LE($E(xE(new tv,b),s),i),Yx(BF(n.k,t.d),121)))),n.c[t.p]=r}(this.a,Yx(n,17))},EF(GAn,"NetworkSimplexPlacer/lambda$5$Type",1418),Wfn(1419,1,{},ta),Fjn.Kb=function(n){return hz(),new SR(null,new Nz(Yx(n,29).a,16))},EF(GAn,"NetworkSimplexPlacer/lambda$6$Type",1419),Wfn(1420,1,YEn,ea),Fjn.Mb=function(n){return hz(),Yx(n,10).k==(bon(),Hzn)},EF(GAn,"NetworkSimplexPlacer/lambda$7$Type",1420),Wfn(1421,1,{},ia),Fjn.Kb=function(n){return hz(),new SR(null,new nF(new $K(bA(a7(Yx(n,10)).a.Kc(),new h))))},EF(GAn,"NetworkSimplexPlacer/lambda$8$Type",1421),Wfn(1422,1,YEn,ra),Fjn.Mb=function(n){return hz(),function(n){return!ZW(n)&&n.c.i.c==n.d.i.c}(Yx(n,17))},EF(GAn,"NetworkSimplexPlacer/lambda$9$Type",1422),Wfn(1404,1,KAn,Sf),Fjn.Yf=function(n){return Yx(Aun(Yx(n,37),(Ojn(),bQn)),21).Hc((edn(),SVn))?b4n:null},Fjn.pf=function(n,t){!function(n,t){var i,r,c,a,u,o,s,h,f,l;for(run(t,"Simple node placement",1),l=Yx(Aun(n,(Ojn(),zQn)),304),o=0,a=new pb(n.b);a.a0?(b=(w-1)*e,u&&(b+=i),h&&(b+=i),b0&&(k-=d),Qmn(u,k),l=0,w=new pb(u.a);w.a0),o.a.Xb(o.c=--o.b)),s=.4*r*l,!a&&o.b"+this.b+" ("+((null!=(n=this.c).f?n.f:""+n.g)+")");var n},Fjn.d=0,EF(VAn,"HyperEdgeSegmentDependency",129),Wfn(520,22,{3:1,35:1,22:1,520:1},MS);var B4n,H4n,q4n,G4n,z4n,U4n,X4n,W4n,V4n=X1(VAn,"HyperEdgeSegmentDependency/DependencyType",520,u_n,(function(){return iQ(),x4(Gy(V4n,1),XEn,520,0,[_4n,K4n])}),(function(n){return iQ(),rZ((LW(),B4n),n)}));Wfn(1815,1,{},xd),EF(VAn,"HyperEdgeSegmentSplitter",1815),Wfn(1816,1,{},Ik),Fjn.a=0,Fjn.b=0,EF(VAn,"HyperEdgeSegmentSplitter/AreaRating",1816),Wfn(329,1,{329:1},Lx),Fjn.a=0,Fjn.b=0,Fjn.c=0,EF(VAn,"HyperEdgeSegmentSplitter/FreeArea",329),Wfn(1817,1,FMn,ja),Fjn.ue=function(n,t){return function(n,t){return $9(n.c-n.s,t.c-t.s)}(Yx(n,112),Yx(t,112))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(VAn,"HyperEdgeSegmentSplitter/lambda$0$Type",1817),Wfn(1818,1,PEn,yH),Fjn.td=function(n){QX(this.a,this.d,this.c,this.b,Yx(n,112))},Fjn.b=0,EF(VAn,"HyperEdgeSegmentSplitter/lambda$1$Type",1818),Wfn(1819,1,{},Ea),Fjn.Kb=function(n){return new SR(null,new Nz(Yx(n,112).e,16))},EF(VAn,"HyperEdgeSegmentSplitter/lambda$2$Type",1819),Wfn(1820,1,{},Ta),Fjn.Kb=function(n){return new SR(null,new Nz(Yx(n,112).j,16))},EF(VAn,"HyperEdgeSegmentSplitter/lambda$3$Type",1820),Wfn(1821,1,{},Ma),Fjn.Fe=function(n){return ty(fL(n))},EF(VAn,"HyperEdgeSegmentSplitter/lambda$4$Type",1821),Wfn(655,1,{},gF),Fjn.a=0,Fjn.b=0,Fjn.c=0,EF(VAn,"OrthogonalRoutingGenerator",655),Wfn(1638,1,{},Sa),Fjn.Kb=function(n){return new SR(null,new Nz(Yx(n,112).e,16))},EF(VAn,"OrthogonalRoutingGenerator/lambda$0$Type",1638),Wfn(1639,1,{},Pa),Fjn.Kb=function(n){return new SR(null,new Nz(Yx(n,112).j,16))},EF(VAn,"OrthogonalRoutingGenerator/lambda$1$Type",1639),Wfn(661,1,{}),EF(QAn,"BaseRoutingDirectionStrategy",661),Wfn(1807,661,{},Ov),Fjn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new pb(n.n);h.aPPn&&(c=n,r=new QS(l,a=f),KD(u.a,r),kpn(this,u,c,r,!1),(b=n.r)&&(r=new QS(w=ty(fL(ken(b.e,0))),a),KD(u.a,r),kpn(this,u,c,r,!1),c=b,r=new QS(w,a=t+b.o*i),KD(u.a,r),kpn(this,u,c,r,!1)),r=new QS(g,a),KD(u.a,r),kpn(this,u,c,r,!1)))},Fjn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},Fjn.fg=function(){return Ikn(),Bit},Fjn.gg=function(){return Ikn(),Tit},EF(QAn,"NorthToSouthRoutingStrategy",1807),Wfn(1808,661,{},Av),Fjn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*i,h=new pb(n.n);h.aPPn&&(c=n,r=new QS(l,a=f),KD(u.a,r),kpn(this,u,c,r,!1),(b=n.r)&&(r=new QS(w=ty(fL(ken(b.e,0))),a),KD(u.a,r),kpn(this,u,c,r,!1),c=b,r=new QS(w,a=t-b.o*i),KD(u.a,r),kpn(this,u,c,r,!1)),r=new QS(g,a),KD(u.a,r),kpn(this,u,c,r,!1)))},Fjn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},Fjn.fg=function(){return Ikn(),Tit},Fjn.gg=function(){return Ikn(),Bit},EF(QAn,"SouthToNorthRoutingStrategy",1808),Wfn(1806,661,{},$v),Fjn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new pb(n.n);h.aPPn&&(c=n,r=new QS(a=f,l),KD(u.a,r),kpn(this,u,c,r,!0),(b=n.r)&&(r=new QS(a,w=ty(fL(ken(b.e,0)))),KD(u.a,r),kpn(this,u,c,r,!0),c=b,r=new QS(a=t+b.o*i,w),KD(u.a,r),kpn(this,u,c,r,!0)),r=new QS(a,g),KD(u.a,r),kpn(this,u,c,r,!0)))},Fjn.eg=function(n){return n.i.n.b+n.n.b+n.a.b},Fjn.fg=function(){return Ikn(),Eit},Fjn.gg=function(){return Ikn(),qit},EF(QAn,"WestToEastRoutingStrategy",1806),Wfn(813,1,{},Tvn),Fjn.Ib=function(){return Gun(this.a)},Fjn.b=0,Fjn.c=!1,Fjn.d=!1,Fjn.f=0,EF(JAn,"NubSpline",813),Wfn(407,1,{407:1},Pwn,Qq),EF(JAn,"NubSpline/PolarCP",407),Wfn(1453,1,KAn,grn),Fjn.Yf=function(n){return function(n){var t,e;return T3(t=new fX,H4n),(e=Yx(Aun(n,(Ojn(),bQn)),21)).Hc((edn(),$Vn))&&T3(t,U4n),e.Hc(EVn)&&T3(t,q4n),e.Hc(OVn)&&T3(t,z4n),e.Hc(MVn)&&T3(t,G4n),t}(Yx(n,37))},Fjn.pf=function(n,t){!function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(run(i,"Spline edge routing",1),0==t.b.c.length)return t.f.a=0,void Ron(i);v=ty(fL(Aun(t,(gjn(),z0n)))),o=ty(fL(Aun(t,K0n))),u=ty(fL(Aun(t,x0n))),T=Yx(Aun(t,v1n),336)==($6(),v3n),E=ty(fL(Aun(t,m1n))),n.d=t,n.j.c=VQ(UKn,iEn,1,0,5,1),n.a.c=VQ(UKn,iEn,1,0,5,1),U_(n.k),f=oI((s=Yx(TR(t.b,0),29)).a,(ywn(),D4n)),l=oI((d=Yx(TR(t.b,t.b.c.length-1),29)).a,D4n),g=new pb(t.b),p=null,I=0;do{for(Nkn(n,p,m=g.a0?(h=0,p&&(h+=o),h+=(M-1)*u,m&&(h+=o),T&&m&&(h=e.Math.max(h,hwn(m,u,v,E))),h("+this.c+") "+this.b},Fjn.c=0,EF(JAn,"SplineEdgeRouter/Dependency",268),Wfn(455,22,{3:1,35:1,22:1,455:1},SS);var Q4n,Y4n,J4n,Z4n,n5n,t5n=X1(JAn,"SplineEdgeRouter/SideToProcess",455,u_n,(function(){return Yq(),x4(Gy(t5n,1),XEn,455,0,[X4n,W4n])}),(function(n){return Yq(),rZ((RW(),Q4n),n)}));Wfn(1454,1,YEn,ya),Fjn.Mb=function(n){return kwn(),!Yx(n,128).o},EF(JAn,"SplineEdgeRouter/lambda$0$Type",1454),Wfn(1455,1,{},ma),Fjn.Ge=function(n){return kwn(),Yx(n,128).v+1},EF(JAn,"SplineEdgeRouter/lambda$1$Type",1455),Wfn(1456,1,PEn,PS),Fjn.td=function(n){!function(n,t,e){xB(n.b,Yx(e.b,17),t)}(this.a,this.b,Yx(n,46))},EF(JAn,"SplineEdgeRouter/lambda$2$Type",1456),Wfn(1457,1,PEn,IS),Fjn.td=function(n){!function(n,t,e){xB(n.b,Yx(e.b,17),t)}(this.a,this.b,Yx(n,46))},EF(JAn,"SplineEdgeRouter/lambda$3$Type",1457),Wfn(128,1,{35:1,128:1},Ksn,qmn),Fjn.wd=function(n){return function(n,t){return n.s-t.s}(this,Yx(n,128))},Fjn.b=0,Fjn.e=!1,Fjn.f=0,Fjn.g=0,Fjn.j=!1,Fjn.k=!1,Fjn.n=0,Fjn.o=!1,Fjn.p=!1,Fjn.q=!1,Fjn.s=0,Fjn.u=0,Fjn.v=0,Fjn.F=0,EF(JAn,"SplineSegment",128),Wfn(459,1,{459:1},ka),Fjn.a=0,Fjn.b=!1,Fjn.c=!1,Fjn.d=!1,Fjn.e=!1,Fjn.f=0,EF(JAn,"SplineSegment/EdgeInformation",459),Wfn(1234,1,{},da),EF(i$n,vPn,1234),Wfn(1235,1,FMn,ga),Fjn.ue=function(n,t){return function(n,t){var e,i,r;return 0==(e=Yx(Aun(t,(cln(),U5n)),19).a-Yx(Aun(n,U5n),19).a)?(i=yN(dO(Yx(Aun(n,(ryn(),b5n)),8)),Yx(Aun(n,w5n),8)),r=yN(dO(Yx(Aun(t,b5n),8)),Yx(Aun(t,w5n),8)),$9(i.a*i.b,r.a*r.b)):e}(Yx(n,135),Yx(t,135))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(i$n,mPn,1235),Wfn(1233,1,{},fj),EF(i$n,"MrTree",1233),Wfn(393,22,{3:1,35:1,22:1,393:1,246:1,234:1},CS),Fjn.Kf=function(){return _hn(this)},Fjn.Xf=function(){return _hn(this)};var e5n,i5n=X1(i$n,"TreeLayoutPhases",393,u_n,(function(){return Krn(),x4(Gy(i5n,1),XEn,393,0,[Y4n,J4n,Z4n,n5n])}),(function(n){return Krn(),rZ((WY(),e5n),n)}));Wfn(1130,209,VSn,wN),Fjn.Ze=function(n,t){var i,r,c,a,u,o;for(ny(hL(jln(n,(cln(),H5n))))||rG(new Xb((dT(),new Xm(n)))),o4(u=new nQ,n),b5(u,(ryn(),E5n),n),function(n,t,i){var r,c,a,u,o;for(a=0,c=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));c.e!=c.i.gc();)u="",0==(!(r=Yx(hen(c),33)).n&&(r.n=new m_(act,r,1,7)),r.n).i||(u=Yx(c1((!r.n&&(r.n=new m_(act,r,1,7)),r.n),0),137).a),o4(o=new Z5(a++,t,u),r),b5(o,(ryn(),E5n),r),o.e.b=r.j+r.f/2,o.f.a=e.Math.max(r.g,1),o.e.a=r.i+r.g/2,o.f.b=e.Math.max(r.f,1),KD(t.b,o),Ysn(i.f,r,o)}(n,u,o=new rp),function(n,t,e){var i,r,c,a,u,o,s;for(a=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));a.e!=a.i.gc();)for(r=new $K(bA(lbn(c=Yx(hen(a),33)).a.Kc(),new h));Vfn(r);)Rfn(i=Yx(kV(r),79))||Rfn(i)||Whn(i)||(o=Yx(eI(Dq(e.f,c)),86),s=Yx(BF(e,iun(Yx(c1((!i.c&&(i.c=new AN(Zrt,i,5,8)),i.c),0),82))),86),o&&s&&(b5(u=new iq(o,s),(ryn(),E5n),i),o4(u,i),KD(o.d,u),KD(s.b,u),KD(t.a,u)))}(n,u,o),a=u,r=new pb(c=gpn(this.a,a));r.al&&(P=0,I+=f+E,f=0),gbn(k,u,P,I),t=e.Math.max(t,P+j.a),f=e.Math.max(f,j.b),P+=j.a+E;for(y=new rp,i=new rp,M=new pb(n);M.a"+Qz(this.c):"e_"+W5(this)},EF(r$n,"TEdge",188),Wfn(135,134,{3:1,135:1,94:1,134:1},nQ),Fjn.Ib=function(){var n,t,e,i,r;for(r=null,i=Ztn(this.b,0);i.b!=i.d.c;)r+=(null==(e=Yx(IX(i),86)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=Ztn(this.a,0);t.b!=t.d.c;)r+=((n=Yx(IX(t),188)).b&&n.c?Qz(n.b)+"->"+Qz(n.c):"e_"+W5(n))+"\n";return r};var r5n=EF(r$n,"TGraph",135);Wfn(633,502,{3:1,502:1,633:1,94:1,134:1}),EF(r$n,"TShape",633),Wfn(86,633,{3:1,502:1,86:1,633:1,94:1,134:1},Z5),Fjn.Ib=function(){return Qz(this)};var c5n,a5n,u5n,o5n,s5n,h5n,f5n=EF(r$n,"TNode",86);Wfn(255,1,$En,Dd),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return new Rd(Ztn(this.a.d,0))},EF(r$n,"TNode/2",255),Wfn(358,1,fEn,Rd),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return Yx(IX(this.a),188).c},Fjn.Ob=function(){return ij(this.a)},Fjn.Qb=function(){BZ(this.a)},EF(r$n,"TNode/2/1",358),Wfn(1840,1,dIn,bN),Fjn.pf=function(n,t){ivn(this,Yx(n,135),t)},EF(c$n,"FanProcessor",1840),Wfn(327,22,{3:1,35:1,22:1,327:1,234:1},OS),Fjn.Kf=function(){switch(this.g){case 0:return new sm;case 1:return new bN;case 2:return new Oa;case 3:return new Ia;case 4:return new $a;case 5:return new La;default:throw hp(new Qm(FIn+(null!=this.f?this.f:""+this.g)))}};var l5n,b5n,w5n,d5n,g5n,p5n,v5n,m5n,y5n,k5n,j5n,E5n,T5n,M5n,S5n,P5n,I5n,C5n,O5n,A5n,$5n,L5n,N5n,x5n,D5n,R5n,K5n,_5n,F5n,B5n,H5n,q5n,G5n,z5n,U5n,X5n,W5n,V5n,Q5n,Y5n,J5n,Z5n=X1(c$n,BIn,327,u_n,(function(){return ysn(),x4(Gy(Z5n,1),XEn,327,0,[h5n,a5n,o5n,u5n,s5n,c5n])}),(function(n){return ysn(),rZ((M1(),l5n),n)}));Wfn(1843,1,dIn,Ia),Fjn.pf=function(n,t){Pln(this,Yx(n,135),t)},Fjn.a=0,EF(c$n,"LevelHeightProcessor",1843),Wfn(1844,1,$En,Ca),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return XH(),sE(),PFn},EF(c$n,"LevelHeightProcessor/1",1844),Wfn(1841,1,dIn,Oa),Fjn.pf=function(n,t){Nsn(this,Yx(n,135),t)},Fjn.a=0,EF(c$n,"NeighborsProcessor",1841),Wfn(1842,1,$En,Aa),Fjn.Jc=function(n){XW(this,n)},Fjn.Kc=function(){return XH(),sE(),PFn},EF(c$n,"NeighborsProcessor/1",1842),Wfn(1845,1,dIn,$a),Fjn.pf=function(n,t){Sln(this,Yx(n,135),t)},Fjn.a=0,EF(c$n,"NodePositionProcessor",1845),Wfn(1839,1,dIn,sm),Fjn.pf=function(n,t){!function(n,t){var e,i,r,c,a,u,o;for(n.a.c=VQ(UKn,iEn,1,0,5,1),i=Ztn(t.b,0);i.b!=i.d.c;)0==(e=Yx(IX(i),86)).b.b&&(b5(e,(ryn(),C5n),(TA(),!0)),eD(n.a,e));switch(n.a.c.length){case 0:b5(r=new Z5(0,t,"DUMMY_ROOT"),(ryn(),C5n),(TA(),!0)),b5(r,g5n,!0),KD(t.b,r);break;case 1:break;default:for(c=new Z5(0,t,"SUPER_ROOT"),u=new pb(n.a);u.aw$n&&(c-=w$n),h=(o=Yx(jln(r,Ott),8)).a,l=o.b+n,(a=e.Math.atan2(l,h))<0&&(a+=w$n),(a+=t)>w$n&&(a-=w$n),XC(),o0(1e-10),e.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:ca?1:QI(isNaN(c),isNaN(a))}(this.a,this.b,Yx(n,33),Yx(t,33))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},Fjn.a=0,Fjn.b=0,EF(b$n,"RadialUtil/lambda$0$Type",549),Wfn(1375,1,dIn,Da),Fjn.pf=function(n,t){!function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(run(t,"Calculate Graph Size",1),t.n&&n&&nU(t,RU(n),(P6(),jrt)),o=wPn,s=wPn,a=d$n,u=d$n,l=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));l.e!=l.i.gc();)d=(h=Yx(hen(l),33)).i,g=h.j,v=h.g,r=h.f,c=Yx(jln(h,(Cjn(),Unt)),142),o=e.Math.min(o,d-c.b),s=e.Math.min(s,g-c.d),a=e.Math.max(a,d+v+c.c),u=e.Math.max(u,g+r+c.a);for(b=new QS(o-(w=Yx(jln(n,(Cjn(),utt)),116)).b,s-w.d),f=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));f.e!=f.i.gc();)L1(h=Yx(hen(f),33),h.i-b.a),N1(h,h.j-b.b);p=a-o+(w.b+w.c),i=u-s+(w.d+w.a),$1(n,p),A1(n,i),t.n&&n&&nU(t,RU(n),(P6(),jrt))}(Yx(n,33),t)},EF(g$n,"CalculateGraphSize",1375),Wfn(442,22,{3:1,35:1,22:1,442:1,234:1},NS),Fjn.Kf=function(){switch(this.g){case 0:return new Ba;case 1:return new xa;case 2:return new Da;default:throw hp(new Qm(FIn+(null!=this.f?this.f:""+this.g)))}};var v6n,m6n,y6n,k6n=X1(g$n,BIn,442,u_n,(function(){return m7(),x4(Gy(k6n,1),XEn,442,0,[g6n,w6n,d6n])}),(function(n){return m7(),rZ((KQ(),v6n),n)}));Wfn(645,1,{}),Fjn.e=1,Fjn.g=0,EF(p$n,"AbstractRadiusExtensionCompaction",645),Wfn(1772,645,{},rL),Fjn.hg=function(n){var t,e,i,r,c,a,u,o,s;for(this.c=Yx(jln(n,(eL(),s6n)),33),function(n,t){n.f=t}(this,this.c),this.d=Ven(Yx(jln(n,(_rn(),Y6n)),293)),(o=Yx(jln(n,_6n),19))&&Bl(this,o.a),Hl(this,(vB(u=fL(jln(n,(Cjn(),Xtt)))),u)),s=idn(this.c),this.d&&this.d.lg(s),function(n,t){var e,i,r;for(i=new pb(t);i.ai?1:0}(Yx(n,33),Yx(t,33))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(x$n,"RectPackingLayoutProvider/lambda$0$Type",1137),Wfn(1256,1,{},Nx),Fjn.a=0,Fjn.c=!1,EF(D$n,"AreaApproximation",1256);var l8n,b8n,w8n,d8n=aR(D$n,"BestCandidateFilter");Wfn(638,1,{526:1},Qa),Fjn.mg=function(n,t,i){var r,c,a,u,o,s;for(s=new ip,a=JTn,o=new pb(n);o.a1)for(i=new pb(n.a);i.a>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28);var n,t},Fjn.Jf=function(n){var t,e,i;for(e=0;e0&&f8((Lz(t-1,n.length),n.charCodeAt(t-1)),TIn);)--t;if(e>=t)throw hp(new Qm("The given string does not contain any numbers."));if(2!=(i=Ogn(n.substr(e,t-e),",|;|\r|\n")).length)throw hp(new Qm("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=gon(Wun(i[0])),this.b=gon(Wun(i[1]))}catch(n){throw CO(n=j4(n),127)?hp(new Qm(MIn+n)):hp(n)}},Fjn.Ib=function(){return"("+this.a+","+this.b+")"},Fjn.a=0,Fjn.b=0;var B7n=EF(SIn,"KVector",8);Wfn(74,68,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1,74:1,414:1},Nv,kk,_$),Fjn.Pc=function(){return function(n){var t,e,i;for(t=0,i=VQ(B7n,TEn,8,n.b,0,1),e=Ztn(n,0);e.b!=e.d.c;)i[t++]=Yx(IX(e),8);return i}(this)},Fjn.Jf=function(n){var t,e,i,r,c;e=Ogn(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),BH(this);try{for(t=0,r=0,i=0,c=0;t0&&(r%2==0?i=gon(e[t]):c=gon(e[t]),r>0&&r%2!=0&&KD(this,new QS(i,c)),++r),++t}catch(n){throw CO(n=j4(n),127)?hp(new Qm("The given string does not match the expected format for vectors."+n)):hp(n)}},Fjn.Ib=function(){var n,t,e;for(n=new SA("("),t=Ztn(this,0);t.b!=t.d.c;)yI(n,(e=Yx(IX(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var H7n,q7n,G7n,z7n,U7n,X7n,W7n=EF(SIn,"KVectorChain",74);Wfn(248,22,{3:1,35:1,22:1,248:1},YS);var V7n,Q7n,Y7n,J7n,Z7n,nnt,tnt,ent,int,rnt,cnt,ant,unt,ont,snt,hnt,fnt,lnt,bnt,wnt=X1(MLn,"Alignment",248,u_n,(function(){return qen(),x4(Gy(wnt,1),XEn,248,0,[H7n,z7n,U7n,X7n,q7n,G7n])}),(function(n){return qen(),rZ((m1(),V7n),n)}));Wfn(979,1,fSn,Af),Fjn.Qe=function(n){Epn(n)},EF(MLn,"BoxLayouterOptions",979),Wfn(980,1,{},xu),Fjn.$e=function(){return new Gu},Fjn._e=function(n){},EF(MLn,"BoxLayouterOptions/BoxFactory",980),Wfn(291,22,{3:1,35:1,22:1,291:1},JS);var dnt,gnt,pnt,vnt,mnt,ynt,knt,jnt,Ent,Tnt,Mnt,Snt,Pnt,Int,Cnt,Ont,Ant,$nt,Lnt,Nnt,xnt,Dnt,Rnt,Knt,_nt,Fnt,Bnt,Hnt,qnt,Gnt,znt,Unt,Xnt,Wnt,Vnt,Qnt,Ynt,Jnt,Znt,ntt,ttt,ett,itt,rtt,ctt,att,utt,ott,stt,htt,ftt,ltt,btt,wtt,dtt,gtt,ptt,vtt,mtt,ytt,ktt,jtt,Ett,Ttt,Mtt,Stt,Ptt,Itt,Ctt,Ott,Att,$tt,Ltt,Ntt,xtt,Dtt,Rtt,Ktt,_tt,Ftt,Btt,Htt,qtt,Gtt,ztt,Utt,Xtt,Wtt,Vtt,Qtt,Ytt,Jtt,Ztt,net,tet,eet,iet=X1(MLn,"ContentAlignment",291,u_n,(function(){return dan(),x4(Gy(iet,1),XEn,291,0,[bnt,lnt,fnt,snt,ont,hnt])}),(function(n){return dan(),rZ((v1(),dnt),n)}));Wfn(684,1,fSn,$f),Fjn.Qe=function(n){j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,CLn),""),"Layout Algorithm"),"Select a specific layout algorithm."),(lsn(),N7n)),fFn),J9((Qtn(),T7n))))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,OLn),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),L7n),y7n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,sAn),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),vnt),O7n),wnt),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,hPn),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,ALn),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),L7n),W7n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,jAn),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),Mnt),A7n),iet),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,oAn),""),"Debug Mode"),"Whether additional debug information shall be generated."),(TA(),!1)),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,bAn),""),_Sn),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),Int),O7n),oet),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,xOn),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),Lnt),O7n),Eet),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,U$n),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,OOn),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),Knt),O7n),Bet),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[E7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,fPn),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),ott),L7n),Zzn),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[E7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,RPn),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,NAn),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,FPn),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,KPn),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),jtt),O7n),kit),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,AAn),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),L7n),B7n),tK(E7n,x4(Gy(D7n,1),XEn,175,0,[M7n,j7n]))))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,$Pn),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),$7n),U_n),tK(E7n,x4(Gy(D7n,1),XEn,175,0,[k7n]))))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,xPn),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,DPn),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,EAn),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),znt),L7n),W7n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,SAn),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,PAn),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,$Ln),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),L7n),tst),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[j7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,$An),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),Xnt),L7n),Rzn),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,aAn),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),I7n),D_n),tK(E7n,x4(Gy(D7n,1),XEn,175,0,[k7n,M7n,j7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,LLn),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),C7n),H_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,NLn),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,xLn),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),d9(100)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,DLn),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,RLn),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),d9(4e3)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,KLn),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),d9(400)),$7n),U_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,_Ln),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,FLn),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,BLn),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,HLn),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ILn),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),jnt),O7n),yrt),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,WOn),DOn),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,VOn),DOn),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,oPn),DOn),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,QOn),DOn),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,NPn),DOn),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,YOn),DOn),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,JOn),DOn),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,tAn),DOn),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,ZOn),DOn),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,nAn),DOn),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,LPn),DOn),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,eAn),DOn),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),C7n),H_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,iAn),DOn),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),C7n),H_n),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[E7n]))))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,rAn),DOn),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),L7n),Mrt),tK(E7n,x4(Gy(D7n,1),XEn,175,0,[k7n,M7n,j7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,LAn),DOn),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),Qtt),L7n),Rzn),J9(T7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,OAn),ULn),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),$7n),U_n),tK(T7n,x4(Gy(D7n,1),XEn,175,0,[E7n]))))),xU(n,OAn,CAn,ltt),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,CAn),ULn),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),htt),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,wAn),XLn),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),Vnt),L7n),Zzn),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,qPn),XLn),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),Ynt),A7n),cit),tK(E7n,x4(Gy(D7n,1),XEn,175,0,[j7n]))))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,pAn),WLn),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),wtt),O7n),bit),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,vAn),WLn),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),O7n),bit),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,mAn),WLn),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),O7n),bit),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,yAn),WLn),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),O7n),bit),J9(E7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,kAn),WLn),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),O7n),bit),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,HPn),VLn),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),Znt),A7n),lrt),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,BPn),VLn),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),rtt),A7n),vrt),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,eIn),VLn),"Node Size Minimum"),"The minimal size to which a node can be reduced."),ett),L7n),B7n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,lAn),VLn),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),I7n),D_n),J9(T7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,TAn),UOn),"Edge Label Placement"),"Gives a hint on where to put edge labels."),Ant),O7n),det),J9(j7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,_Pn),UOn),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),I7n),D_n),J9(j7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,qLn),"font"),"Font Name"),"Font name used for a label."),N7n),fFn),J9(j7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,GLn),"font"),"Font Size"),"Font size used for a label."),$7n),U_n),J9(j7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,IAn),QLn),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),L7n),B7n),J9(M7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,MAn),QLn),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),$7n),U_n),J9(M7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,uAn),QLn),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),Ctt),O7n),trt),J9(M7n)))),j7(n,new isn(dk(wk(gk(sk(bk(fk(lk(new Fu,cAn),QLn),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),C7n),H_n),J9(M7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,GPn),YLn),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),Stt),A7n),Git),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,dAn),YLn),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,gAn),YLn),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,hAn),JLn),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),I7n),D_n),J9(E7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,fAn),JLn),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),I7n),D_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,sPn),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),C7n),H_n),J9(k7n)))),j7(n,new isn(dk(wk(gk(hk(sk(bk(fk(lk(new Fu,zLn),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),xnt),O7n),xet),J9(k7n)))),oT(n,new dz(ak(ok(uk(new pu,CIn),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),oT(n,new dz(ak(ok(uk(new pu,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),oT(n,new dz(ak(ok(uk(new pu,APn),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),oT(n,new dz(ak(ok(uk(new pu,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),oT(n,new dz(ak(ok(uk(new pu,l$n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),oT(n,new dz(ak(ok(uk(new pu,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),oT(n,new dz(ak(ok(uk(new pu,C$n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),Mgn((new Lf,n)),Epn((new Af,n)),ydn((new Nf,n))},EF(MLn,"CoreOptions",684),Wfn(103,22,{3:1,35:1,22:1,103:1},ZS);var ret,cet,aet,uet,oet=X1(MLn,_Sn,103,u_n,(function(){return t9(),x4(Gy(oet,1),XEn,103,0,[tet,net,Ztt,Jtt,eet])}),(function(n){return t9(),rZ((yZ(),ret),n)}));Wfn(272,22,{3:1,35:1,22:1,272:1},nP);var set,het,fet,bet,wet,det=X1(MLn,"EdgeLabelPlacement",272,u_n,(function(){return ZZ(),x4(Gy(det,1),XEn,272,0,[cet,aet,uet])}),(function(n){return ZZ(),rZ((GQ(),set),n)}));Wfn(218,22,{3:1,35:1,22:1,218:1},tP);var get,pet,vet,met,yet,ket,jet,Eet=X1(MLn,"EdgeRouting",218,u_n,(function(){return g7(),x4(Gy(Eet,1),XEn,218,0,[wet,fet,het,bet])}),(function(n){return g7(),rZ((tJ(),get),n)}));Wfn(312,22,{3:1,35:1,22:1,312:1},eP);var Tet,Met,Set,Pet,Iet,Cet,Oet,Aet,$et,Let,Net,xet=X1(MLn,"EdgeType",312,u_n,(function(){return vun(),x4(Gy(xet,1),XEn,312,0,[ket,met,jet,pet,yet,vet])}),(function(n){return vun(),rZ((P1(),Tet),n)}));Wfn(977,1,fSn,Lf),Fjn.Qe=function(n){Mgn(n)},EF(MLn,"FixedLayouterOptions",977),Wfn(978,1,{},Vu),Fjn.$e=function(){return new Hu},Fjn._e=function(n){},EF(MLn,"FixedLayouterOptions/FixedFactory",978),Wfn(334,22,{3:1,35:1,22:1,334:1},iP);var Det,Ret,Ket,_et,Fet,Bet=X1(MLn,"HierarchyHandling",334,u_n,(function(){return O8(),x4(Gy(Bet,1),XEn,334,0,[Let,$et,Net])}),(function(n){return O8(),rZ((qQ(),Det),n)}));Wfn(285,22,{3:1,35:1,22:1,285:1},rP);var Het,qet,Get,zet,Uet,Xet,Wet,Vet,Qet,Yet,Jet=X1(MLn,"LabelSide",285,u_n,(function(){return Frn(),x4(Gy(Jet,1),XEn,285,0,[Fet,Ret,Ket,_et])}),(function(n){return Frn(),rZ((nJ(),Het),n)}));Wfn(93,22,{3:1,35:1,22:1,93:1},cP);var Zet,nit,tit,eit,iit,rit,cit=X1(MLn,"NodeLabelPlacement",93,u_n,(function(){return Eln(),x4(Gy(cit,1),XEn,93,0,[Get,qet,Uet,Yet,Qet,Vet,Xet,Wet,zet])}),(function(n){return Eln(),rZ((n4(),Zet),n)}));Wfn(249,22,{3:1,35:1,22:1,249:1},aP);var ait,uit,oit,sit,hit,fit,lit,bit=X1(MLn,"PortAlignment",249,u_n,(function(){return Ytn(),x4(Gy(bit,1),XEn,249,0,[eit,rit,nit,tit,iit])}),(function(n){return Ytn(),rZ((kZ(),ait),n)}));Wfn(98,22,{3:1,35:1,22:1,98:1},uP);var wit,dit,git,pit,vit,mit,yit,kit=X1(MLn,"PortConstraints",98,u_n,(function(){return Ran(),x4(Gy(kit,1),XEn,98,0,[lit,fit,hit,uit,sit,oit])}),(function(n){return Ran(),rZ((n1(),wit),n)}));Wfn(273,22,{3:1,35:1,22:1,273:1},oP);var jit,Eit,Tit,Mit,Sit,Pit,Iit,Cit,Oit,Ait,$it,Lit,Nit,xit,Dit,Rit,Kit,_it,Fit,Bit,Hit,qit,Git=X1(MLn,"PortLabelPlacement",273,u_n,(function(){return Chn(),x4(Gy(Git,1),XEn,273,0,[mit,pit,vit,git,dit,yit])}),(function(n){return Chn(),rZ((S1(),jit),n)}));Wfn(61,22,{3:1,35:1,22:1,61:1},sP);var zit,Uit,Xit,Wit,Vit,Qit,Yit,Jit,Zit,nrt,trt=X1(MLn,"PortSide",61,u_n,(function(){return Ikn(),x4(Gy(trt,1),lIn,61,0,[Hit,Tit,Eit,Bit,qit])}),(function(n){return Ikn(),rZ((jZ(),zit),n)}));Wfn(981,1,fSn,Nf),Fjn.Qe=function(n){ydn(n)},EF(MLn,"RandomLayouterOptions",981),Wfn(982,1,{},Qu),Fjn.$e=function(){return new no},Fjn._e=function(n){},EF(MLn,"RandomLayouterOptions/RandomFactory",982),Wfn(374,22,{3:1,35:1,22:1,374:1},hP);var ert,irt,rrt,crt,art,urt,ort,srt,hrt,frt,lrt=X1(MLn,"SizeConstraint",374,u_n,(function(){return Ann(),x4(Gy(lrt,1),XEn,374,0,[Zit,nrt,Jit,Yit])}),(function(n){return Ann(),rZ((iJ(),ert),n)}));Wfn(259,22,{3:1,35:1,22:1,259:1},fP);var brt,wrt,drt,grt,prt,vrt=X1(MLn,"SizeOptions",259,u_n,(function(){return Vgn(),x4(Gy(vrt,1),XEn,259,0,[crt,urt,rrt,ort,srt,frt,hrt,art,irt])}),(function(n){return Vgn(),rZ((t5(),brt),n)}));Wfn(370,1,{1949:1},am),Fjn.b=!1,Fjn.c=0,Fjn.d=-1,Fjn.e=null,Fjn.f=null,Fjn.g=-1,Fjn.j=!1,Fjn.k=!1,Fjn.n=!1,Fjn.o=0,Fjn.q=0,Fjn.r=0,EF(xAn,"BasicProgressMonitor",370),Wfn(972,209,VSn,Gu),Fjn.Ze=function(n,t){var e,i,r,c,a,u,o,s,h;run(t,"Box layout",2),r=ey(fL(jln(n,(Run(),unt)))),c=Yx(jln(n,rnt),116),e=ny(hL(jln(n,Z7n))),i=ny(hL(jln(n,nnt))),0===Yx(jln(n,Y7n),311).g?(u=new sx((!n.a&&(n.a=new m_(uct,n,10,11)),n.a)),XH(),JC(u,new Vd(i)),a=u,o=Asn(n),(null==(s=fL(jln(n,Q7n)))||(vB(s),s<=0))&&(s=1.3),xkn(n,(h=Kkn(a,r,c,o.a,o.b,e,(vB(s),s))).a,h.b,!1,!0)):Vmn(n,r,c,e),Ron(t)},EF(xAn,"BoxLayoutProvider",972),Wfn(973,1,FMn,Vd),Fjn.ue=function(n,t){return function(n,t,e){var i,r,c;if(!(r=Yx(jln(t,(Run(),ant)),19))&&(r=d9(0)),!(c=Yx(jln(e,ant),19))&&(c=d9(0)),r.a>c.a)return-1;if(r.a0&&d.b>0&&xkn(g,d.a,d.b,!0,!0)),b=e.Math.max(b,g.i+g.g),w=e.Math.max(w,g.j+g.f),f=new UO((!g.n&&(g.n=new m_(act,g,1,7)),g.n));f.e!=f.i.gc();)o=Yx(hen(f),137),(T=Yx(jln(o,Aet),8))&&jC(o,T.a,T.b),b=e.Math.max(b,g.i+o.i+o.g),w=e.Math.max(w,g.j+o.j+o.f);for(k=new UO((!g.c&&(g.c=new m_(oct,g,9,9)),g.c));k.e!=k.i.gc();)for(y=Yx(hen(k),118),(T=Yx(jln(y,Aet),8))&&jC(y,T.a,T.b),j=g.i+y.i,E=g.j+y.j,b=e.Math.max(b,j+y.g),w=e.Math.max(w,E+y.f),s=new UO((!y.n&&(y.n=new m_(act,y,1,7)),y.n));s.e!=s.i.gc();)o=Yx(hen(s),137),(T=Yx(jln(o,Aet),8))&&jC(o,T.a,T.b),b=e.Math.max(b,j+o.i+o.g),w=e.Math.max(w,E+o.j+o.f);for(c=new $K(bA(lbn(g).a.Kc(),new h));Vfn(c);)l=Dkn(i=Yx(kV(c),79)),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b);for(r=new $K(bA(fbn(g).a.Kc(),new h));Vfn(r);)IG(Kun(i=Yx(kV(r),79)))!=n&&(l=Dkn(i),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b))}if(a==(g7(),het))for(p=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new $K(bA(lbn(g=Yx(hen(p),33)).a.Kc(),new h));Vfn(r);)0==(u=Npn(i=Yx(kV(r),79))).b?Aen(i,Gnt,null):Aen(i,Gnt,u);ny(hL(jln(n,(L6(),Pet))))||xkn(n,b+(m=Yx(jln(n,Cet),116)).b+m.c,w+m.d+m.a,!0,!0),Ron(t)},EF(xAn,"FixedLayoutProvider",1138),Wfn(373,134,{3:1,414:1,373:1,94:1,134:1},Yu,FJ),Fjn.Jf=function(n){var t,e,i,r,c,a,u;if(n)try{for(a=Ogn(n,";,;"),r=0,c=(i=a).length;r>16&fTn|n^(e&fTn)<<16},Fjn.Kc=function(){return new Zd(this)},Fjn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+I7(this.b)+")":null==this.b?"pair("+I7(this.a)+",null)":"pair("+I7(this.a)+","+I7(this.b)+")"},EF(xAn,"Pair",46),Wfn(983,1,fEn,Zd),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},Fjn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw hp(new Kp)},Fjn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),hp(new Lp)},Fjn.b=!1,Fjn.c=!1,EF(xAn,"Pair/1",983),Wfn(448,1,{448:1},jH),Fjn.Fb=function(n){return qB(this.a,Yx(n,448).a)&&qB(this.c,Yx(n,448).c)&&qB(this.d,Yx(n,448).d)&&qB(this.b,Yx(n,448).b)},Fjn.Hb=function(){return G6(x4(Gy(UKn,1),iEn,1,5,[this.a,this.c,this.d,this.b]))},Fjn.Ib=function(){return"("+this.a+tEn+this.c+tEn+this.d+tEn+this.b+")"},EF(xAn,"Quadruple",448),Wfn(1126,209,VSn,no),Fjn.Ze=function(n,t){var i;run(t,"Random Layout",1),0!=(!n.a&&(n.a=new m_(uct,n,10,11)),n.a).i?(function(n,t,i,r,c){var a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(y=0,g=0,d=0,w=1,m=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));m.e!=m.i.gc();)w+=FX(new $K(bA(lbn(p=Yx(hen(m),33)).a.Kc(),new h))),T=p.g,g=e.Math.max(g,T),b=p.f,d=e.Math.max(d,b),y+=T*b;for(u=y+2*r*r*w*(!n.a&&(n.a=new m_(uct,n,10,11)),n.a).i,a=e.Math.sqrt(u),s=e.Math.max(a*i,g),o=e.Math.max(a/i,d),v=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));v.e!=v.i.gc();)p=Yx(hen(v),33),M=c.b+(Xln(t,26)*mMn+Xln(t,27)*yMn)*(s-p.g),S=c.b+(Xln(t,26)*mMn+Xln(t,27)*yMn)*(o-p.f),L1(p,M),N1(p,S);for(E=s+(c.b+c.c),j=o+(c.d+c.a),k=new UO((!n.a&&(n.a=new m_(uct,n,10,11)),n.a));k.e!=k.i.gc();)for(l=new $K(bA(lbn(Yx(hen(k),33)).a.Kc(),new h));Vfn(l);)Rfn(f=Yx(kV(l),79))||djn(f,t,E,j);xkn(n,E+=c.b+c.c,j+=c.d+c.a,!1,!0)}(n,(i=Yx(jln(n,(Onn(),Vit)),19))&&0!=i.a?new jW(i.a):new c7,ey(fL(jln(n,Uit))),ey(fL(jln(n,Qit))),Yx(jln(n,Xit),116)),Ron(t)):Ron(t)},EF(xAn,"RandomLayoutProvider",1126),Wfn(553,1,{}),Fjn.qf=function(){return new QS(this.f.i,this.f.j)},Fjn.We=function(n){return Oq(n,(Cjn(),ytt))?jln(this.f,Irt):jln(this.f,n)},Fjn.rf=function(){return new QS(this.f.g,this.f.f)},Fjn.sf=function(){return this.g},Fjn.Xe=function(n){return zQ(this.f,n)},Fjn.tf=function(n){L1(this.f,n.a),N1(this.f,n.b)},Fjn.uf=function(n){$1(this.f,n.a),A1(this.f,n.b)},Fjn.vf=function(n){this.g=n},Fjn.g=0,EF(iNn,"ElkGraphAdapters/AbstractElkGraphElementAdapter",553),Wfn(554,1,{839:1},ng),Fjn.wf=function(){var n,t;if(!this.b)for(this.b=nX(JB(this.a).i),t=new UO(JB(this.a));t.e!=t.i.gc();)n=Yx(hen(t),137),eD(this.b,new Wm(n));return this.b},Fjn.b=null,EF(iNn,"ElkGraphAdapters/ElkEdgeAdapter",554),Wfn(301,553,{},Xm),Fjn.xf=function(){return hrn(this)},Fjn.a=null,EF(iNn,"ElkGraphAdapters/ElkGraphAdapter",301),Wfn(630,553,{181:1},Wm),EF(iNn,"ElkGraphAdapters/ElkLabelAdapter",630),Wfn(629,553,{680:1},e$),Fjn.wf=function(){return function(n){var t,e;if(!n.b)for(n.b=nX(Yx(n.f,33).Ag().i),e=new UO(Yx(n.f,33).Ag());e.e!=e.i.gc();)t=Yx(hen(e),137),eD(n.b,new Wm(t));return n.b}(this)},Fjn.Af=function(){var n;return!(n=Yx(jln(this.f,(Cjn(),Unt)),142))&&(n=new Mv),n},Fjn.Cf=function(){return function(n){var t,e;if(!n.e)for(n.e=nX(ZB(Yx(n.f,33)).i),e=new UO(ZB(Yx(n.f,33)));e.e!=e.i.gc();)t=Yx(hen(e),118),eD(n.e,new Ag(t));return n.e}(this)},Fjn.Ef=function(n){var t;t=new yx(n),Aen(this.f,(Cjn(),Unt),t)},Fjn.Ff=function(n){Aen(this.f,(Cjn(),utt),new mx(n))},Fjn.yf=function(){return this.d},Fjn.zf=function(){var n,t;if(!this.a)for(this.a=new ip,t=new $K(bA(fbn(Yx(this.f,33)).a.Kc(),new h));Vfn(t);)n=Yx(kV(t),79),eD(this.a,new ng(n));return this.a},Fjn.Bf=function(){var n,t;if(!this.c)for(this.c=new ip,t=new $K(bA(lbn(Yx(this.f,33)).a.Kc(),new h));Vfn(t);)n=Yx(kV(t),79),eD(this.c,new ng(n));return this.c},Fjn.Df=function(){return 0!=uq(Yx(this.f,33)).i||ny(hL(Yx(this.f,33).We((Cjn(),Fnt))))},Fjn.Gf=function(){MJ(this,(dT(),Prt))},Fjn.a=null,Fjn.b=null,Fjn.c=null,Fjn.d=null,Fjn.e=null,EF(iNn,"ElkGraphAdapters/ElkNodeAdapter",629),Wfn(1266,553,{838:1},Ag),Fjn.wf=function(){return function(n){var t,e;if(!n.b)for(n.b=nX(Yx(n.f,118).Ag().i),e=new UO(Yx(n.f,118).Ag());e.e!=e.i.gc();)t=Yx(hen(e),137),eD(n.b,new Wm(t));return n.b}(this)},Fjn.zf=function(){var n,t;if(!this.a)for(this.a=h$(Yx(this.f,118).xg().i),t=new UO(Yx(this.f,118).xg());t.e!=t.i.gc();)n=Yx(hen(t),79),eD(this.a,new ng(n));return this.a},Fjn.Bf=function(){var n,t;if(!this.c)for(this.c=h$(Yx(this.f,118).yg().i),t=new UO(Yx(this.f,118).yg());t.e!=t.i.gc();)n=Yx(hen(t),79),eD(this.c,new ng(n));return this.c},Fjn.Hf=function(){return Yx(Yx(this.f,118).We((Cjn(),Itt)),61)},Fjn.If=function(){var n,t,e,i,r,c,a;for(i=TG(Yx(this.f,118)),e=new UO(Yx(this.f,118).yg());e.e!=e.i.gc();)for(a=new UO((!(n=Yx(hen(e),79)).c&&(n.c=new AN(Zrt,n,5,8)),n.c));a.e!=a.i.gc();){if(XZ(iun(c=Yx(hen(a),82)),i))return!0;if(iun(c)==i&&ny(hL(jln(n,(Cjn(),Bnt)))))return!0}for(t=new UO(Yx(this.f,118).xg());t.e!=t.i.gc();)for(r=new UO((!(n=Yx(hen(t),79)).b&&(n.b=new AN(Zrt,n,4,7)),n.b));r.e!=r.i.gc();)if(XZ(iun(Yx(hen(r),82)),i))return!0;return!1},Fjn.a=null,Fjn.b=null,Fjn.c=null,EF(iNn,"ElkGraphAdapters/ElkPortAdapter",1266),Wfn(1267,1,FMn,to),Fjn.ue=function(n,t){return function(n,t){var e,i,r,c;if(0!=(c=Yx(jln(n,(Cjn(),Itt)),61).g-Yx(jln(t,Itt),61).g))return c;if(e=Yx(jln(n,Ett),19),i=Yx(jln(t,Ett),19),e&&i&&0!=(r=e.a-i.a))return r;switch(Yx(jln(n,Itt),61).g){case 1:return $9(n.i,t.i);case 2:return $9(n.j,t.j);case 3:return $9(t.i,n.i);case 4:return $9(t.j,n.j);default:throw hp(new Ym(mIn))}}(Yx(n,118),Yx(t,118))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(iNn,"ElkGraphAdapters/PortComparator",1267);var Ort,Art,$rt,Lrt,Nrt,xrt,Drt,Rrt,Krt,_rt,Frt,Brt,Hrt,qrt,Grt,zrt,Urt,Xrt,Wrt=aR(rNn,"EObject"),Vrt=aR(cNn,aNn),Qrt=aR(cNn,uNn),Yrt=aR(cNn,oNn),Jrt=aR(cNn,"ElkShape"),Zrt=aR(cNn,sNn),nct=aR(cNn,hNn),tct=aR(cNn,fNn),ect=aR(rNn,lNn),ict=aR(rNn,"EFactory"),rct=aR(rNn,bNn),cct=aR(rNn,"EPackage"),act=aR(cNn,wNn),uct=aR(cNn,dNn),oct=aR(cNn,gNn);Wfn(90,1,pNn),Fjn.Jg=function(){return this.Kg(),null},Fjn.Kg=function(){return null},Fjn.Lg=function(){return this.Kg(),!1},Fjn.Mg=function(){return!1},Fjn.Ng=function(n){K3(this,n)},EF(vNn,"BasicNotifierImpl",90),Wfn(97,90,SNn),Fjn.nh=function(){return gC(this)},Fjn.Og=function(n,t){return n},Fjn.Pg=function(){throw hp(new xp)},Fjn.Qg=function(n){var t;return t=nin(Yx(CZ(this.Tg(),this.Vg()),18)),this.eh().ih(this,t.n,t.f,n)},Fjn.Rg=function(n,t){throw hp(new xp)},Fjn.Sg=function(n,t,e){return opn(this,n,t,e)},Fjn.Tg=function(){var n;return this.Pg()&&(n=this.Pg().ck())?n:this.zh()},Fjn.Ug=function(){return Bfn(this)},Fjn.Vg=function(){throw hp(new xp)},Fjn.Wg=function(){var n,t;return!(t=this.ph().dk())&&this.Pg().ik((kT(),t=null==(n=Wq(svn(this.Tg())))?Vat:new n$(this,n))),t},Fjn.Xg=function(n,t){return n},Fjn.Yg=function(n){return n.Gj()?n.aj():tnn(this.Tg(),n)},Fjn.Zg=function(){var n;return(n=this.Pg())?n.fk():null},Fjn.$g=function(){return this.Pg()?this.Pg().ck():null},Fjn._g=function(n,t,e){return $en(this,n,t,e)},Fjn.ah=function(n){return TY(this,n)},Fjn.bh=function(n,t){return TV(this,n,t)},Fjn.dh=function(){var n;return!!(n=this.Pg())&&n.gk()},Fjn.eh=function(){throw hp(new xp)},Fjn.fh=function(){return rtn(this)},Fjn.gh=function(n,t,e,i){return men(this,n,t,i)},Fjn.hh=function(n,t,e){return Yx(CZ(this.Tg(),t),66).Nj().Qj(this,this.yh(),t-this.Ah(),n,e)},Fjn.ih=function(n,t,e,i){return Uq(this,n,t,i)},Fjn.jh=function(n,t,e){return Yx(CZ(this.Tg(),t),66).Nj().Rj(this,this.yh(),t-this.Ah(),n,e)},Fjn.kh=function(){return!!this.Pg()&&!!this.Pg().ek()},Fjn.lh=function(n){return uen(this,n)},Fjn.mh=function(n){return CG(this,n)},Fjn.oh=function(n){return eyn(this,n)},Fjn.ph=function(){throw hp(new xp)},Fjn.qh=function(){return this.Pg()?this.Pg().ek():null},Fjn.rh=function(){return rtn(this)},Fjn.sh=function(n,t){Vsn(this,n,t)},Fjn.th=function(n){this.ph().hk(n)},Fjn.uh=function(n){this.ph().kk(n)},Fjn.vh=function(n){this.ph().jk(n)},Fjn.wh=function(n,t){var e,i,r,c;return(c=this.Zg())&&n&&(t=Ten(c.Vk(),this,t),c.Zk(this)),(i=this.eh())&&(0!=(Ign(this,this.eh(),this.Vg()).Bb&eMn)?(r=i.fh())&&(n?!c&&r.Zk(this):r.Yk(this)):(t=(e=this.Vg())>=0?this.Qg(t):this.eh().ih(this,-1-e,null,t),t=this.Sg(null,-1,t))),this.uh(n),t},Fjn.xh=function(n){var t,e,i,r,c,a,u;if((c=tnn(e=this.Tg(),n))>=(t=this.Ah()))return Yx(n,66).Nj().Uj(this,this.yh(),c-t);if(c<=-1){if(!(a=iyn((wsn(),wut),e,n)))throw hp(new Qm(mNn+n.ne()+jNn));if(TT(),Yx(a,66).Oj()||(a=Bz(PJ(wut,a))),r=Yx((i=this.Yg(a))>=0?this._g(i,!0,!0):tfn(this,a,!0),153),(u=a.Zj())>1||-1==u)return Yx(Yx(r,215).hl(n,!1),76)}else if(n.$j())return Yx((i=this.Yg(n))>=0?this._g(i,!1,!0):tfn(this,n,!1),76);return new qP(this,n)},Fjn.yh=function(){return DJ(this)},Fjn.zh=function(){return(YF(),gat).S},Fjn.Ah=function(){return vF(this.zh())},Fjn.Bh=function(n){usn(this,n)},Fjn.Ib=function(){return Kln(this)},EF(PNn,"BasicEObjectImpl",97),Wfn(114,97,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1}),Fjn.Ch=function(n){return RJ(this)[n]},Fjn.Dh=function(n,t){DF(RJ(this),n,t)},Fjn.Eh=function(n){DF(RJ(this),n,null)},Fjn.Jg=function(){return Yx(H3(this,4),126)},Fjn.Kg=function(){throw hp(new xp)},Fjn.Lg=function(){return 0!=(4&this.Db)},Fjn.Pg=function(){throw hp(new xp)},Fjn.Fh=function(n){wtn(this,2,n)},Fjn.Rg=function(n,t){this.Db=t<<16|255&this.Db,this.Fh(n)},Fjn.Tg=function(){return Cq(this)},Fjn.Vg=function(){return this.Db>>16},Fjn.Wg=function(){var n;return kT(),null==(n=Wq(svn(Yx(H3(this,16),26)||this.zh())))?Vat:new n$(this,n)},Fjn.Mg=function(){return 0==(1&this.Db)},Fjn.Zg=function(){return Yx(H3(this,128),1935)},Fjn.$g=function(){return Yx(H3(this,16),26)},Fjn.dh=function(){return 0!=(32&this.Db)},Fjn.eh=function(){return Yx(H3(this,2),49)},Fjn.kh=function(){return 0!=(64&this.Db)},Fjn.ph=function(){throw hp(new xp)},Fjn.qh=function(){return Yx(H3(this,64),281)},Fjn.th=function(n){wtn(this,16,n)},Fjn.uh=function(n){wtn(this,128,n)},Fjn.vh=function(n){wtn(this,64,n)},Fjn.yh=function(){return dtn(this)},Fjn.Db=0,EF(PNn,"MinimalEObjectImpl",114),Wfn(115,114,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),Fjn.Fh=function(n){this.Cb=n},Fjn.eh=function(){return this.Cb},EF(PNn,"MinimalEObjectImpl/Container",115),Wfn(1985,115,{105:1,413:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),Fjn._g=function(n,t,e){return Mrn(this,n,t,e)},Fjn.jh=function(n,t,e){return fon(this,n,t,e)},Fjn.lh=function(n){return Zz(this,n)},Fjn.sh=function(n,t){J5(this,n,t)},Fjn.zh=function(){return ajn(),Hrt},Fjn.Bh=function(n){Q4(this,n)},Fjn.Ve=function(){return een(this)},Fjn.We=function(n){return jln(this,n)},Fjn.Xe=function(n){return zQ(this,n)},Fjn.Ye=function(n,t){return Aen(this,n,t)},EF(INn,"EMapPropertyHolderImpl",1985),Wfn(567,115,{105:1,469:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ro),Fjn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return $en(this,n,t,e)},Fjn.lh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return uen(this,n)},Fjn.sh=function(n,t){switch(n){case 0:return void I1(this,ty(fL(t)));case 1:return void C1(this,ty(fL(t)))}Vsn(this,n,t)},Fjn.zh=function(){return ajn(),$rt},Fjn.Bh=function(n){switch(n){case 0:return void I1(this,0);case 1:return void C1(this,0)}usn(this,n)},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?Kln(this):((n=new MA(Kln(this))).a+=" (x: ",Jk(n,this.a),n.a+=", y: ",Jk(n,this.b),n.a+=")",n.a)},Fjn.a=0,Fjn.b=0,EF(INn,"ElkBendPointImpl",567),Wfn(723,1985,{105:1,413:1,160:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),Fjn._g=function(n,t,e){return n9(this,n,t,e)},Fjn.hh=function(n,t,e){return sun(this,n,t,e)},Fjn.jh=function(n,t,e){return d4(this,n,t,e)},Fjn.lh=function(n){return z3(this,n)},Fjn.sh=function(n,t){Vcn(this,n,t)},Fjn.zh=function(){return ajn(),Drt},Fjn.Bh=function(n){A8(this,n)},Fjn.zg=function(){return this.k},Fjn.Ag=function(){return JB(this)},Fjn.Ib=function(){return V9(this)},Fjn.k=null,EF(INn,"ElkGraphElementImpl",723),Wfn(724,723,{105:1,413:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),Fjn._g=function(n,t,e){return S7(this,n,t,e)},Fjn.lh=function(n){return z7(this,n)},Fjn.sh=function(n,t){Qcn(this,n,t)},Fjn.zh=function(){return ajn(),Brt},Fjn.Bh=function(n){rnn(this,n)},Fjn.Bg=function(){return this.f},Fjn.Cg=function(){return this.g},Fjn.Dg=function(){return this.i},Fjn.Eg=function(){return this.j},Fjn.Fg=function(n,t){kC(this,n,t)},Fjn.Gg=function(n,t){jC(this,n,t)},Fjn.Hg=function(n){L1(this,n)},Fjn.Ig=function(n){N1(this,n)},Fjn.Ib=function(){return yon(this)},Fjn.f=0,Fjn.g=0,Fjn.i=0,Fjn.j=0,EF(INn,"ElkShapeImpl",724),Wfn(725,724,{105:1,413:1,82:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),Fjn._g=function(n,t,e){return bin(this,n,t,e)},Fjn.hh=function(n,t,e){return Lcn(this,n,t,e)},Fjn.jh=function(n,t,e){return Ncn(this,n,t,e)},Fjn.lh=function(n){return B5(this,n)},Fjn.sh=function(n,t){oln(this,n,t)},Fjn.zh=function(){return ajn(),Lrt},Fjn.Bh=function(n){yen(this,n)},Fjn.xg=function(){return!this.d&&(this.d=new AN(nct,this,8,5)),this.d},Fjn.yg=function(){return!this.e&&(this.e=new AN(nct,this,7,4)),this.e},EF(INn,"ElkConnectableShapeImpl",725),Wfn(352,723,{105:1,413:1,79:1,160:1,352:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},io),Fjn.Qg=function(n){return ucn(this,n)},Fjn._g=function(n,t,e){switch(n){case 3:return EG(this);case 4:return!this.b&&(this.b=new AN(Zrt,this,4,7)),this.b;case 5:return!this.c&&(this.c=new AN(Zrt,this,5,8)),this.c;case 6:return!this.a&&(this.a=new m_(tct,this,6,6)),this.a;case 7:return TA(),!this.b&&(this.b=new AN(Zrt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new AN(Zrt,this,5,8)),this.c.i<=1));case 8:return TA(),!!Rfn(this);case 9:return TA(),!!Whn(this);case 10:return TA(),!this.b&&(this.b=new AN(Zrt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new AN(Zrt,this,5,8)),0!=this.c.i)}return n9(this,n,t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?ucn(this,e):this.Cb.ih(this,-1-i,null,e)),AL(this,Yx(n,33),e);case 4:return!this.b&&(this.b=new AN(Zrt,this,4,7)),wnn(this.b,n,e);case 5:return!this.c&&(this.c=new AN(Zrt,this,5,8)),wnn(this.c,n,e);case 6:return!this.a&&(this.a=new m_(tct,this,6,6)),wnn(this.a,n,e)}return sun(this,n,t,e)},Fjn.jh=function(n,t,e){switch(t){case 3:return AL(this,null,e);case 4:return!this.b&&(this.b=new AN(Zrt,this,4,7)),Ten(this.b,n,e);case 5:return!this.c&&(this.c=new AN(Zrt,this,5,8)),Ten(this.c,n,e);case 6:return!this.a&&(this.a=new m_(tct,this,6,6)),Ten(this.a,n,e)}return d4(this,n,t,e)},Fjn.lh=function(n){switch(n){case 3:return!!EG(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new AN(Zrt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new AN(Zrt,this,5,8)),this.c.i<=1));case 8:return Rfn(this);case 9:return Whn(this);case 10:return!this.b&&(this.b=new AN(Zrt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new AN(Zrt,this,5,8)),0!=this.c.i)}return z3(this,n)},Fjn.sh=function(n,t){switch(n){case 3:return void Sbn(this,Yx(t,33));case 4:return!this.b&&(this.b=new AN(Zrt,this,4,7)),Hmn(this.b),!this.b&&(this.b=new AN(Zrt,this,4,7)),void jF(this.b,Yx(t,14));case 5:return!this.c&&(this.c=new AN(Zrt,this,5,8)),Hmn(this.c),!this.c&&(this.c=new AN(Zrt,this,5,8)),void jF(this.c,Yx(t,14));case 6:return!this.a&&(this.a=new m_(tct,this,6,6)),Hmn(this.a),!this.a&&(this.a=new m_(tct,this,6,6)),void jF(this.a,Yx(t,14))}Vcn(this,n,t)},Fjn.zh=function(){return ajn(),Nrt},Fjn.Bh=function(n){switch(n){case 3:return void Sbn(this,null);case 4:return!this.b&&(this.b=new AN(Zrt,this,4,7)),void Hmn(this.b);case 5:return!this.c&&(this.c=new AN(Zrt,this,5,8)),void Hmn(this.c);case 6:return!this.a&&(this.a=new m_(tct,this,6,6)),void Hmn(this.a)}A8(this,n)},Fjn.Ib=function(){return bmn(this)},EF(INn,"ElkEdgeImpl",352),Wfn(439,1985,{105:1,413:1,202:1,439:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},co),Fjn.Qg=function(n){return Yrn(this,n)},Fjn._g=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new XO(Qrt,this,5)),this.a;case 6:return MG(this);case 7:return t?Zen(this):this.i;case 8:return t?Jen(this):this.f;case 9:return!this.g&&(this.g=new AN(tct,this,9,10)),this.g;case 10:return!this.e&&(this.e=new AN(tct,this,10,9)),this.e;case 11:return this.d}return Mrn(this,n,t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?Yrn(this,e):this.Cb.ih(this,-1-i,null,e)),$L(this,Yx(n,79),e);case 9:return!this.g&&(this.g=new AN(tct,this,9,10)),wnn(this.g,n,e);case 10:return!this.e&&(this.e=new AN(tct,this,10,9)),wnn(this.e,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(ajn(),xrt),t),66).Nj().Qj(this,dtn(this),t-vF((ajn(),xrt)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new XO(Qrt,this,5)),Ten(this.a,n,e);case 6:return $L(this,null,e);case 9:return!this.g&&(this.g=new AN(tct,this,9,10)),Ten(this.g,n,e);case 10:return!this.e&&(this.e=new AN(tct,this,10,9)),Ten(this.e,n,e)}return fon(this,n,t,e)},Fjn.lh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!MG(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return Zz(this,n)},Fjn.sh=function(n,t){switch(n){case 1:return void x1(this,ty(fL(t)));case 2:return void R1(this,ty(fL(t)));case 3:return void O1(this,ty(fL(t)));case 4:return void D1(this,ty(fL(t)));case 5:return!this.a&&(this.a=new XO(Qrt,this,5)),Hmn(this.a),!this.a&&(this.a=new XO(Qrt,this,5)),void jF(this.a,Yx(t,14));case 6:return void Tbn(this,Yx(t,79));case 7:return void N0(this,Yx(t,82));case 8:return void L0(this,Yx(t,82));case 9:return!this.g&&(this.g=new AN(tct,this,9,10)),Hmn(this.g),!this.g&&(this.g=new AN(tct,this,9,10)),void jF(this.g,Yx(t,14));case 10:return!this.e&&(this.e=new AN(tct,this,10,9)),Hmn(this.e),!this.e&&(this.e=new AN(tct,this,10,9)),void jF(this.e,Yx(t,14));case 11:return void Y0(this,lL(t))}J5(this,n,t)},Fjn.zh=function(){return ajn(),xrt},Fjn.Bh=function(n){switch(n){case 1:return void x1(this,0);case 2:return void R1(this,0);case 3:return void O1(this,0);case 4:return void D1(this,0);case 5:return!this.a&&(this.a=new XO(Qrt,this,5)),void Hmn(this.a);case 6:return void Tbn(this,null);case 7:return void N0(this,null);case 8:return void L0(this,null);case 9:return!this.g&&(this.g=new AN(tct,this,9,10)),void Hmn(this.g);case 10:return!this.e&&(this.e=new AN(tct,this,10,9)),void Hmn(this.e);case 11:return void Y0(this,null)}Q4(this,n)},Fjn.Ib=function(){return Mfn(this)},Fjn.b=0,Fjn.c=0,Fjn.d=null,Fjn.j=0,Fjn.k=0,EF(INn,"ElkEdgeSectionImpl",439),Wfn(150,115,{105:1,92:1,90:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),Fjn._g=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab):RY(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t,e)},Fjn.hh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e)):Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Qj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.jh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e)):Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Rj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.lh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:xX(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.oh=function(n){return jkn(this,n)},Fjn.sh=function(n,t){if(0===n)return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));E7(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t)},Fjn.uh=function(n){wtn(this,128,n)},Fjn.zh=function(){return xjn(),Iat},Fjn.Bh=function(n){if(0===n)return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);r9(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.Gh=function(){this.Bb|=1},Fjn.Hh=function(n){return dpn(this,n)},Fjn.Bb=0,EF(PNn,"EModelElementImpl",150),Wfn(704,150,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},xf),Fjn.Ih=function(n,t){return Dyn(this,n,t)},Fjn.Jh=function(n){var t,e,i,r;if(this.a!=i1(n)||0!=(256&n.Bb))throw hp(new Qm(NNn+n.zb+ANn));for(e=Iq(n);0!=tW(e.a).i;){if(frn(t=Yx(hyn(e,0,CO(r=Yx(c1(tW(e.a),0),87).c,88)?Yx(r,26):(xjn(),Oat)),26)))return Yx(i=i1(t).Nh().Jh(t),49).th(n),i;e=Iq(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new rR(n):new SD(n)},Fjn.Kh=function(n,t){return fjn(this,n,t)},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.a}return RY(this,n-vF((xjn(),Mat)),CZ(Yx(H3(this,16),26)||Mat,n),t,e)},Fjn.hh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 1:return this.a&&(e=Yx(this.a,49).ih(this,4,cct,e)),T8(this,Yx(n,235),e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Mat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Mat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 1:return T8(this,null,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Mat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Mat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return xX(this,n-vF((xjn(),Mat)),CZ(Yx(H3(this,16),26)||Mat,n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void Uun(this,Yx(t,235))}E7(this,n-vF((xjn(),Mat)),CZ(Yx(H3(this,16),26)||Mat,n),t)},Fjn.zh=function(){return xjn(),Mat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void Uun(this,null)}r9(this,n-vF((xjn(),Mat)),CZ(Yx(H3(this,16),26)||Mat,n))},EF(PNn,"EFactoryImpl",704),Wfn(DNn,704,{105:1,2014:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},ao),Fjn.Ih=function(n,t){switch(n.yj()){case 12:return Yx(t,146).tg();case 13:return I7(t);default:throw hp(new Qm(ONn+n.ne()+ANn))}},Fjn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=i1(n))?Ren(t.Mh(),n):-1),n.G){case 4:return new uo;case 6:return new xv;case 7:return new Dv;case 8:return new io;case 9:return new ro;case 10:return new co;case 11:return new so;default:throw hp(new Qm(NNn+n.zb+ANn))}},Fjn.Kh=function(n,t){switch(n.yj()){case 13:case 12:return null;default:throw hp(new Qm(ONn+n.ne()+ANn))}},EF(INn,"ElkGraphFactoryImpl",DNn),Wfn(438,150,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),Fjn.Wg=function(){var n;return null==(n=Wq(svn(Yx(H3(this,16),26)||this.zh())))?(kT(),kT(),Vat):new B$(this,n)},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.ne()}return RY(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return xX(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void this.Lh(lL(t))}E7(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t)},Fjn.zh=function(){return xjn(),Cat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void this.Lh(null)}r9(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.ne=function(){return this.zb},Fjn.Lh=function(n){E2(this,n)},Fjn.Ib=function(){return B8(this)},Fjn.zb=null,EF(PNn,"ENamedElementImpl",438),Wfn(179,438,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},Sq),Fjn.Qg=function(n){return ecn(this,n)},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new d_(this,iat,this)),this.rb;case 6:return!this.vb&&(this.vb=new EN(cct,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?Yx(this.Cb,235):null:SG(this)}return RY(this,n-vF((xjn(),Lat)),CZ(Yx(H3(this,16),26)||Lat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 4:return this.sb&&(e=Yx(this.sb,49).ih(this,1,ict,e)),H8(this,Yx(n,471),e);case 5:return!this.rb&&(this.rb=new d_(this,iat,this)),wnn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new EN(cct,this,6,7)),wnn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?ecn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,7,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Lat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Lat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 4:return H8(this,null,e);case 5:return!this.rb&&(this.rb=new d_(this,iat,this)),Ten(this.rb,n,e);case 6:return!this.vb&&(this.vb=new EN(cct,this,6,7)),Ten(this.vb,n,e);case 7:return opn(this,null,7,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Lat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Lat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!SG(this)}return xX(this,n-vF((xjn(),Lat)),CZ(Yx(H3(this,16),26)||Lat,n))},Fjn.oh=function(n){return function(n,t){var e,i,r,c,a,u;if(!n.tb){for(!n.rb&&(n.rb=new d_(n,iat,n)),u=new kE((c=n.rb).i),r=new UO(c);r.e!=r.i.gc();)i=Yx(hen(r),138),(e=Yx(null==(a=i.ne())?Ysn(u.f,null,i):r7(u.g,a,i),138))&&(null==a?Ysn(u.f,null,e):r7(u.g,a,e));n.tb=u}return Yx(aG(n.tb,t),138)}(this,n)||jkn(this,n)},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void E2(this,lL(t));case 2:return void M2(this,lL(t));case 3:return void T2(this,lL(t));case 4:return void lon(this,Yx(t,471));case 5:return!this.rb&&(this.rb=new d_(this,iat,this)),Hmn(this.rb),!this.rb&&(this.rb=new d_(this,iat,this)),void jF(this.rb,Yx(t,14));case 6:return!this.vb&&(this.vb=new EN(cct,this,6,7)),Hmn(this.vb),!this.vb&&(this.vb=new EN(cct,this,6,7)),void jF(this.vb,Yx(t,14))}E7(this,n-vF((xjn(),Lat)),CZ(Yx(H3(this,16),26)||Lat,n),t)},Fjn.vh=function(n){var t,e;if(n&&this.rb)for(e=new UO(this.rb);e.e!=e.i.gc();)CO(t=hen(e),351)&&(Yx(t,351).w=null);wtn(this,64,n)},Fjn.zh=function(){return xjn(),Lat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void E2(this,null);case 2:return void M2(this,null);case 3:return void T2(this,null);case 4:return void lon(this,null);case 5:return!this.rb&&(this.rb=new d_(this,iat,this)),void Hmn(this.rb);case 6:return!this.vb&&(this.vb=new EN(cct,this,6,7)),void Hmn(this.vb)}r9(this,n-vF((xjn(),Lat)),CZ(Yx(H3(this,16),26)||Lat,n))},Fjn.Gh=function(){Srn(this)},Fjn.Mh=function(){return!this.rb&&(this.rb=new d_(this,iat,this)),this.rb},Fjn.Nh=function(){return this.sb},Fjn.Oh=function(){return this.ub},Fjn.Ph=function(){return this.xb},Fjn.Qh=function(){return this.yb},Fjn.Rh=function(n){this.ub=n},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?B8(this):((n=new MA(B8(this))).a+=" (nsURI: ",pI(n,this.yb),n.a+=", nsPrefix: ",pI(n,this.xb),n.a+=")",n.a)},Fjn.xb=null,Fjn.yb=null,EF(PNn,"EPackageImpl",179),Wfn(555,179,{105:1,2016:1,555:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},Gfn),Fjn.q=!1,Fjn.r=!1;var sct=!1;EF(INn,"ElkGraphPackageImpl",555),Wfn(354,724,{105:1,413:1,160:1,137:1,470:1,354:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},uo),Fjn.Qg=function(n){return Jrn(this,n)},Fjn._g=function(n,t,e){switch(n){case 7:return PG(this);case 8:return this.a}return S7(this,n,t,e)},Fjn.hh=function(n,t,e){var i;return 7===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Jrn(this,e):this.Cb.ih(this,-1-i,null,e)),kK(this,Yx(n,160),e)):sun(this,n,t,e)},Fjn.jh=function(n,t,e){return 7==t?kK(this,null,e):d4(this,n,t,e)},Fjn.lh=function(n){switch(n){case 7:return!!PG(this);case 8:return!_N("",this.a)}return z7(this,n)},Fjn.sh=function(n,t){switch(n){case 7:return void Xbn(this,Yx(t,160));case 8:return void x0(this,lL(t))}Qcn(this,n,t)},Fjn.zh=function(){return ajn(),Rrt},Fjn.Bh=function(n){switch(n){case 7:return void Xbn(this,null);case 8:return void x0(this,"")}rnn(this,n)},Fjn.Ib=function(){return Qon(this)},Fjn.a="",EF(INn,"ElkLabelImpl",354),Wfn(239,725,{105:1,413:1,82:1,160:1,33:1,470:1,239:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},xv),Fjn.Qg=function(n){return ocn(this,n)},Fjn._g=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new m_(oct,this,9,9)),this.c;case 10:return!this.a&&(this.a=new m_(uct,this,10,11)),this.a;case 11:return IG(this);case 12:return!this.b&&(this.b=new m_(nct,this,12,3)),this.b;case 13:return TA(),!this.a&&(this.a=new m_(uct,this,10,11)),this.a.i>0}return bin(this,n,t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new m_(oct,this,9,9)),wnn(this.c,n,e);case 10:return!this.a&&(this.a=new m_(uct,this,10,11)),wnn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?ocn(this,e):this.Cb.ih(this,-1-i,null,e)),vN(this,Yx(n,33),e);case 12:return!this.b&&(this.b=new m_(nct,this,12,3)),wnn(this.b,n,e)}return Lcn(this,n,t,e)},Fjn.jh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new m_(oct,this,9,9)),Ten(this.c,n,e);case 10:return!this.a&&(this.a=new m_(uct,this,10,11)),Ten(this.a,n,e);case 11:return vN(this,null,e);case 12:return!this.b&&(this.b=new m_(nct,this,12,3)),Ten(this.b,n,e)}return Ncn(this,n,t,e)},Fjn.lh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!IG(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new m_(uct,this,10,11)),this.a.i>0}return B5(this,n)},Fjn.sh=function(n,t){switch(n){case 9:return!this.c&&(this.c=new m_(oct,this,9,9)),Hmn(this.c),!this.c&&(this.c=new m_(oct,this,9,9)),void jF(this.c,Yx(t,14));case 10:return!this.a&&(this.a=new m_(uct,this,10,11)),Hmn(this.a),!this.a&&(this.a=new m_(uct,this,10,11)),void jF(this.a,Yx(t,14));case 11:return void Dbn(this,Yx(t,33));case 12:return!this.b&&(this.b=new m_(nct,this,12,3)),Hmn(this.b),!this.b&&(this.b=new m_(nct,this,12,3)),void jF(this.b,Yx(t,14))}oln(this,n,t)},Fjn.zh=function(){return ajn(),Krt},Fjn.Bh=function(n){switch(n){case 9:return!this.c&&(this.c=new m_(oct,this,9,9)),void Hmn(this.c);case 10:return!this.a&&(this.a=new m_(uct,this,10,11)),void Hmn(this.a);case 11:return void Dbn(this,null);case 12:return!this.b&&(this.b=new m_(nct,this,12,3)),void Hmn(this.b)}yen(this,n)},Fjn.Ib=function(){return ugn(this)},EF(INn,"ElkNodeImpl",239),Wfn(186,725,{105:1,413:1,82:1,160:1,118:1,470:1,186:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},Dv),Fjn.Qg=function(n){return Zrn(this,n)},Fjn._g=function(n,t,e){return 9==n?TG(this):bin(this,n,t,e)},Fjn.hh=function(n,t,e){var i;return 9===t?(this.Cb&&(e=(i=this.Db>>16)>=0?Zrn(this,e):this.Cb.ih(this,-1-i,null,e)),LL(this,Yx(n,33),e)):Lcn(this,n,t,e)},Fjn.jh=function(n,t,e){return 9==t?LL(this,null,e):Ncn(this,n,t,e)},Fjn.lh=function(n){return 9==n?!!TG(this):B5(this,n)},Fjn.sh=function(n,t){9!==n?oln(this,n,t):Mbn(this,Yx(t,33))},Fjn.zh=function(){return ajn(),_rt},Fjn.Bh=function(n){9!==n?yen(this,n):Mbn(this,null)},Fjn.Ib=function(){return ogn(this)},EF(INn,"ElkPortImpl",186);var hct=aR(exn,"BasicEMap/Entry");Wfn(1092,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,114:1,115:1},so),Fjn.Fb=function(n){return this===n},Fjn.cd=function(){return this.b},Fjn.Hb=function(){return _A(this)},Fjn.Uh=function(n){D0(this,Yx(n,146))},Fjn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return $en(this,n,t,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return uen(this,n)},Fjn.sh=function(n,t){switch(n){case 0:return void D0(this,Yx(t,146));case 1:return void _0(this,t)}Vsn(this,n,t)},Fjn.zh=function(){return ajn(),Frt},Fjn.Bh=function(n){switch(n){case 0:return void D0(this,null);case 1:return void _0(this,null)}usn(this,n)},Fjn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=n?W5(n):0),this.a},Fjn.dd=function(){return this.c},Fjn.Th=function(n){this.a=n},Fjn.ed=function(n){var t;return t=this.c,_0(this,n),t},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?Kln(this):(yI(yI(yI(n=new Ay,this.b?this.b.tg():aEn),pIn),xA(this.c)),n.a)},Fjn.a=-1,Fjn.c=null;var fct,lct,bct,wct,dct,gct,pct,vct,mct=EF(INn,"ElkPropertyToValueMapEntryImpl",1092);Wfn(984,1,{},lo),EF(cxn,"JsonAdapter",984),Wfn(210,60,eTn,hy),EF(cxn,"JsonImportException",210),Wfn(857,1,{},icn),EF(cxn,"JsonImporter",857),Wfn(891,1,{},kP),EF(cxn,"JsonImporter/lambda$0$Type",891),Wfn(892,1,{},jP),EF(cxn,"JsonImporter/lambda$1$Type",892),Wfn(900,1,{},tg),EF(cxn,"JsonImporter/lambda$10$Type",900),Wfn(902,1,{},EP),EF(cxn,"JsonImporter/lambda$11$Type",902),Wfn(903,1,{},TP),EF(cxn,"JsonImporter/lambda$12$Type",903),Wfn(909,1,{},$H),EF(cxn,"JsonImporter/lambda$13$Type",909),Wfn(908,1,{},AH),EF(cxn,"JsonImporter/lambda$14$Type",908),Wfn(904,1,{},MP),EF(cxn,"JsonImporter/lambda$15$Type",904),Wfn(905,1,{},SP),EF(cxn,"JsonImporter/lambda$16$Type",905),Wfn(906,1,{},PP),EF(cxn,"JsonImporter/lambda$17$Type",906),Wfn(907,1,{},IP),EF(cxn,"JsonImporter/lambda$18$Type",907),Wfn(912,1,{},eg),EF(cxn,"JsonImporter/lambda$19$Type",912),Wfn(893,1,{},ig),EF(cxn,"JsonImporter/lambda$2$Type",893),Wfn(910,1,{},rg),EF(cxn,"JsonImporter/lambda$20$Type",910),Wfn(911,1,{},cg),EF(cxn,"JsonImporter/lambda$21$Type",911),Wfn(915,1,{},ag),EF(cxn,"JsonImporter/lambda$22$Type",915),Wfn(913,1,{},ug),EF(cxn,"JsonImporter/lambda$23$Type",913),Wfn(914,1,{},og),EF(cxn,"JsonImporter/lambda$24$Type",914),Wfn(917,1,{},sg),EF(cxn,"JsonImporter/lambda$25$Type",917),Wfn(916,1,{},hg),EF(cxn,"JsonImporter/lambda$26$Type",916),Wfn(918,1,PEn,CP),Fjn.td=function(n){!function(n,t,e){var i,r;r=null,(i=jG(n,e))&&(r=osn(i)),Ftn(t,e,r)}(this.b,this.a,lL(n))},EF(cxn,"JsonImporter/lambda$27$Type",918),Wfn(919,1,PEn,OP),Fjn.td=function(n){!function(n,t,e){var i,r;r=null,(i=jG(n,e))&&(r=osn(i)),Ftn(t,e,r)}(this.b,this.a,lL(n))},EF(cxn,"JsonImporter/lambda$28$Type",919),Wfn(920,1,{},AP),EF(cxn,"JsonImporter/lambda$29$Type",920),Wfn(896,1,{},fg),EF(cxn,"JsonImporter/lambda$3$Type",896),Wfn(921,1,{},$P),EF(cxn,"JsonImporter/lambda$30$Type",921),Wfn(922,1,{},lg),EF(cxn,"JsonImporter/lambda$31$Type",922),Wfn(923,1,{},bg),EF(cxn,"JsonImporter/lambda$32$Type",923),Wfn(924,1,{},wg),EF(cxn,"JsonImporter/lambda$33$Type",924),Wfn(925,1,{},dg),EF(cxn,"JsonImporter/lambda$34$Type",925),Wfn(859,1,{},gg),EF(cxn,"JsonImporter/lambda$35$Type",859),Wfn(929,1,{},Rx),EF(cxn,"JsonImporter/lambda$36$Type",929),Wfn(926,1,PEn,pg),Fjn.td=function(n){!function(n,t){var e;nq(e=new Om,"x",t.a),nq(e,"y",t.b),nB(n,e)}(this.a,Yx(n,469))},EF(cxn,"JsonImporter/lambda$37$Type",926),Wfn(927,1,PEn,FP),Fjn.td=function(n){!function(n,t,e){Ucn(t,ksn(n,e))}(this.a,this.b,Yx(n,202))},EF(cxn,"JsonImporter/lambda$38$Type",927),Wfn(928,1,PEn,BP),Fjn.td=function(n){!function(n,t,e){Ucn(t,ksn(n,e))}(this.a,this.b,Yx(n,202))},EF(cxn,"JsonImporter/lambda$39$Type",928),Wfn(894,1,{},vg),EF(cxn,"JsonImporter/lambda$4$Type",894),Wfn(930,1,PEn,mg),Fjn.td=function(n){!function(n,t){var e;nq(e=new Om,"x",t.a),nq(e,"y",t.b),nB(n,e)}(this.a,Yx(n,8))},EF(cxn,"JsonImporter/lambda$40$Type",930),Wfn(895,1,{},yg),EF(cxn,"JsonImporter/lambda$5$Type",895),Wfn(899,1,{},kg),EF(cxn,"JsonImporter/lambda$6$Type",899),Wfn(897,1,{},jg),EF(cxn,"JsonImporter/lambda$7$Type",897),Wfn(898,1,{},Eg),EF(cxn,"JsonImporter/lambda$8$Type",898),Wfn(901,1,{},Tg),EF(cxn,"JsonImporter/lambda$9$Type",901),Wfn(948,1,PEn,Mg),Fjn.td=function(n){nB(this.a,new zF(lL(n)))},EF(cxn,"JsonMetaDataConverter/lambda$0$Type",948),Wfn(949,1,PEn,Sg),Fjn.td=function(n){!function(n,t){nB(n,new zF(null!=t.f?t.f:""+t.g))}(this.a,Yx(n,237))},EF(cxn,"JsonMetaDataConverter/lambda$1$Type",949),Wfn(950,1,PEn,Pg),Fjn.td=function(n){!function(n,t){null!=t.c&&nB(n,new zF(t.c))}(this.a,Yx(n,149))},EF(cxn,"JsonMetaDataConverter/lambda$2$Type",950),Wfn(951,1,PEn,Ig),Fjn.td=function(n){!function(n,t){nB(n,new zF(null!=t.f?t.f:""+t.g))}(this.a,Yx(n,175))},EF(cxn,"JsonMetaDataConverter/lambda$3$Type",951),Wfn(237,22,{3:1,35:1,22:1,237:1},_P);var yct,kct=X1(GSn,"GraphFeature",237,u_n,(function(){return zfn(),x4(Gy(kct,1),XEn,237,0,[vct,dct,gct,wct,pct,lct,fct,bct])}),(function(n){return zfn(),rZ((m3(),yct),n)}));Wfn(13,1,{35:1,146:1},Og,_L,FI,DC),Fjn.wd=function(n){return function(n,t){return FV(n.b,t.tg())}(this,Yx(n,146))},Fjn.Fb=function(n){return Oq(this,n)},Fjn.wg=function(){return oen(this)},Fjn.tg=function(){return this.b},Fjn.Hb=function(){return Xen(this.b)},Fjn.Ib=function(){return this.b},EF(GSn,"Property",13),Wfn(818,1,FMn,Cg),Fjn.ue=function(n,t){return function(n,t,e){var i,r;return i=Yx(t.We(n.a),35),r=Yx(e.We(n.a),35),null!=i&&null!=r?u3(i,r):null!=i?-1:null!=r?1:0}(this,Yx(n,94),Yx(t,94))},Fjn.Fb=function(n){return this===n},Fjn.ve=function(){return new Eb(this)},EF(GSn,"PropertyHolderComparator",818),Wfn(695,1,fEn,$g),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return function(n){var t;if(!n.a)throw hp(new WB);return t=n.a,n.a=IG(n.a),t}(this)},Fjn.Qb=function(){Bk()},Fjn.Ob=function(){return!!this.a},EF(yxn,"ElkGraphUtil/AncestorIterator",695);var jct=aR(exn,"EList");Wfn(67,52,{20:1,28:1,52:1,14:1,15:1,67:1,58:1}),Fjn.Vc=function(n,t){y9(this,n,t)},Fjn.Fc=function(n){return fY(this,n)},Fjn.Wc=function(n,t){return f5(this,n,t)},Fjn.Gc=function(n){return jF(this,n)},Fjn.Zh=function(){return new u$(this)},Fjn.$h=function(){return new o$(this)},Fjn._h=function(n){return b0(this,n)},Fjn.ai=function(){return!0},Fjn.bi=function(n,t){},Fjn.ci=function(){},Fjn.di=function(n,t){XQ(this,n,t)},Fjn.ei=function(n,t,e){},Fjn.fi=function(n,t){},Fjn.gi=function(n,t,e){},Fjn.Fb=function(n){return Pdn(this,n)},Fjn.Hb=function(){return L4(this)},Fjn.hi=function(){return!1},Fjn.Kc=function(){return new UO(this)},Fjn.Yc=function(){return new a$(this)},Fjn.Zc=function(n){var t;if(t=this.gc(),n<0||n>t)throw hp(new jN(n,t));return new Z_(this,n)},Fjn.ji=function(n,t){this.ii(n,this.Xc(t))},Fjn.Mc=function(n){return qJ(this,n)},Fjn.li=function(n,t){return t},Fjn._c=function(n,t){return Ken(this,n,t)},Fjn.Ib=function(){return D7(this)},Fjn.ni=function(){return!0},Fjn.oi=function(n,t){return k6(this,t)},EF(exn,"AbstractEList",67),Wfn(63,67,Mxn,go,FZ,t3),Fjn.Vh=function(n,t){return hun(this,n,t)},Fjn.Wh=function(n){return $in(this,n)},Fjn.Xh=function(n,t){X8(this,n,t)},Fjn.Yh=function(n){NV(this,n)},Fjn.pi=function(n){return AY(this,n)},Fjn.$b=function(){xV(this)},Fjn.Hc=function(n){return Fcn(this,n)},Fjn.Xb=function(n){return c1(this,n)},Fjn.qi=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)=0&&(this.$c(t),!0)},Fjn.mi=function(n,t){return this.Ui(n,this.oi(n,t))},Fjn.gc=function(){return this.Vi()},Fjn.Pc=function(){return this.Wi()},Fjn.Qc=function(n){return this.Xi(n)},Fjn.Ib=function(){return this.Yi()},EF(exn,"DelegatingEList",1995),Wfn(1996,1995,dDn),Fjn.Vh=function(n,t){return Dpn(this,n,t)},Fjn.Wh=function(n){return this.Vh(this.Vi(),n)},Fjn.Xh=function(n,t){_fn(this,n,t)},Fjn.Yh=function(n){yfn(this,n)},Fjn.ai=function(){return!this.bj()},Fjn.$b=function(){Wmn(this)},Fjn.Zi=function(n,t,e,i,r){return new _q(this,n,t,e,i,r)},Fjn.$i=function(n){K3(this.Ai(),n)},Fjn._i=function(){return null},Fjn.aj=function(){return-1},Fjn.Ai=function(){return null},Fjn.bj=function(){return!1},Fjn.cj=function(n,t){return t},Fjn.dj=function(n,t){return t},Fjn.ej=function(){return!1},Fjn.fj=function(){return!this.Ri()},Fjn.ii=function(n,t){var e,i;return this.ej()?(i=this.fj(),e=Hun(this,n,t),this.$i(this.Zi(7,d9(t),e,n,i)),e):Hun(this,n,t)},Fjn.$c=function(n){var t,e,i,r;return this.ej()?(e=null,i=this.fj(),t=this.Zi(4,r=uR(this,n),null,n,i),this.bj()&&r?(e=this.dj(r,e))?(e.Ei(t),e.Fi()):this.$i(t):e?(e.Ei(t),e.Fi()):this.$i(t),r):(r=uR(this,n),this.bj()&&r&&(e=this.dj(r,null))&&e.Fi(),r)},Fjn.mi=function(n,t){return Rpn(this,n,t)},EF(vNn,"DelegatingNotifyingListImpl",1996),Wfn(143,1,gDn),Fjn.Ei=function(n){return Pan(this,n)},Fjn.Fi=function(){vJ(this)},Fjn.xi=function(){return this.d},Fjn._i=function(){return null},Fjn.gj=function(){return null},Fjn.yi=function(n){return-1},Fjn.zi=function(){return Rwn(this)},Fjn.Ai=function(){return null},Fjn.Bi=function(){return Kwn(this)},Fjn.Ci=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},Fjn.hj=function(){return!1},Fjn.Di=function(n){var t,e,i,r,c,a,u,o;switch(this.d){case 1:case 2:switch(n.xi()){case 1:case 2:if(iI(n.Ai())===iI(this.Ai())&&this.yi(null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0}case 4:if(4===n.xi()&&iI(n.Ai())===iI(this.Ai())&&this.yi(null)==n.yi(null))return a=syn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.Ci(),this.d=6,o=new FZ(2),c<=i?(fY(o,this.n),fY(o,n.Bi()),this.g=x4(Gy(Wot,1),MTn,25,15,[this.o=c,i+1])):(fY(o,n.Bi()),fY(o,this.n),this.g=x4(Gy(Wot,1),MTn,25,15,[this.o=i,c])),this.n=o,a||(this.o=-2-this.o-1),!0;break;case 6:if(4===n.xi()&&iI(n.Ai())===iI(this.Ai())&&this.yi(null)==n.yi(null)){for(a=syn(this),i=n.Ci(),u=Yx(this.g,48),e=VQ(Wot,MTn,25,u.length+1,15,1),t=0;t>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:Zk(e,this.d)}if(Tgn(this)&&(e.a+=", touch: true"),e.a+=", position: ",Zk(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",gI(e,this.Ai()),e.a+=", feature: ",gI(e,this._i()),e.a+=", oldValue: ",gI(e,Kwn(this)),e.a+=", newValue: ",6==this.d&&CO(this.g,48)){for(t=Yx(this.g,48),e.a+="[",n=0;n10?(this.b&&this.c.j==this.a||(this.b=new kR(this),this.a=this.j),gE(this.b,n)):Fcn(this,n)},Fjn.ni=function(){return!0},Fjn.a=0,EF(exn,"AbstractEList/1",953),Wfn(295,73,VTn,jN),EF(exn,"AbstractEList/BasicIndexOutOfBoundsException",295),Wfn(40,1,fEn,UO),Fjn.Nb=function(n){I_(this,n)},Fjn.mj=function(){if(this.i.j!=this.f)throw hp(new Dp)},Fjn.nj=function(){return hen(this)},Fjn.Ob=function(){return this.e!=this.i.gc()},Fjn.Pb=function(){return this.nj()},Fjn.Qb=function(){tan(this)},Fjn.e=0,Fjn.f=0,Fjn.g=-1,EF(exn,"AbstractEList/EIterator",40),Wfn(278,40,yEn,a$,Z_),Fjn.Qb=function(){tan(this)},Fjn.Rb=function(n){Enn(this,n)},Fjn.oj=function(){var n;try{return n=this.d.Xb(--this.e),this.mj(),this.g=this.e,n}catch(n){throw CO(n=j4(n),73)?(this.mj(),hp(new Kp)):hp(n)}},Fjn.pj=function(n){Rin(this,n)},Fjn.Sb=function(){return 0!=this.e},Fjn.Tb=function(){return this.e},Fjn.Ub=function(){return this.oj()},Fjn.Vb=function(){return this.e-1},Fjn.Wb=function(n){this.pj(n)},EF(exn,"AbstractEList/EListIterator",278),Wfn(341,40,fEn,u$),Fjn.nj=function(){return fen(this)},Fjn.Qb=function(){throw hp(new xp)},EF(exn,"AbstractEList/NonResolvingEIterator",341),Wfn(385,278,yEn,o$,WN),Fjn.Rb=function(n){throw hp(new xp)},Fjn.nj=function(){var n;try{return n=this.c.ki(this.e),this.mj(),this.g=this.e++,n}catch(n){throw CO(n=j4(n),73)?(this.mj(),hp(new Kp)):hp(n)}},Fjn.oj=function(){var n;try{return n=this.c.ki(--this.e),this.mj(),this.g=this.e,n}catch(n){throw CO(n=j4(n),73)?(this.mj(),hp(new Kp)):hp(n)}},Fjn.Qb=function(){throw hp(new xp)},Fjn.Wb=function(n){throw hp(new xp)},EF(exn,"AbstractEList/NonResolvingEListIterator",385),Wfn(1982,67,mDn),Fjn.Vh=function(n,t){var e,i,r,c,a,u,o,s,h;if(0!=(i=t.gc())){for(e=d6(this,(s=null==(o=Yx(H3(this.a,4),126))?0:o.length)+i),(h=s-n)>0&&smn(o,n,e,n+i,h),u=t.Kc(),c=0;ce)throw hp(new jN(n,e));return new PB(this,n)},Fjn.$b=function(){var n,t;++this.j,t=null==(n=Yx(H3(this.a,4),126))?0:n.length,xtn(this,null),XQ(this,t,n)},Fjn.Hc=function(n){var t,e,i,r;if(null!=(t=Yx(H3(this.a,4),126)))if(null!=n){for(i=0,r=(e=t).length;i=(e=null==(t=Yx(H3(this.a,4),126))?0:t.length))throw hp(new jN(n,e));return t[n]},Fjn.Xc=function(n){var t,e,i;if(null!=(t=Yx(H3(this.a,4),126)))if(null!=n){for(e=0,i=t.length;ee)throw hp(new jN(n,e));return new SB(this,n)},Fjn.ii=function(n,t){var e,i,r;if(n>=(r=null==(e=Hnn(this))?0:e.length))throw hp(new Hm(jxn+n+Exn+r));if(t>=r)throw hp(new Hm(Txn+t+Exn+r));return i=e[t],n!=t&&(n=(a=null==(e=Yx(H3(n.a,4),126))?0:e.length))throw hp(new jN(t,a));return r=e[t],1==a?i=null:(smn(e,0,i=VQ(Oct,vDn,415,a-1,0,1),0,t),(c=a-t-1)>0&&smn(e,t+1,i,t,c)),xtn(n,i),_sn(n,t,r),r}(this,n)},Fjn.mi=function(n,t){var e,i;return i=(e=Hnn(this))[n],FC(e,n,k6(this,t)),xtn(this,e),i},Fjn.gc=function(){var n;return null==(n=Yx(H3(this.a,4),126))?0:n.length},Fjn.Pc=function(){var n,t,e;return e=null==(n=Yx(H3(this.a,4),126))?0:n.length,t=VQ(Oct,vDn,415,e,0,1),e>0&&smn(n,0,t,0,e),t},Fjn.Qc=function(n){var t,e;return(e=null==(t=Yx(H3(this.a,4),126))?0:t.length)>0&&(n.lengthe&&DF(n,e,null),n},EF(exn,"ArrayDelegatingEList",1982),Wfn(1038,40,fEn,fV),Fjn.mj=function(){if(this.b.j!=this.f||iI(Yx(H3(this.b.a,4),126))!==iI(this.a))throw hp(new Dp)},Fjn.Qb=function(){tan(this),this.a=Yx(H3(this.b.a,4),126)},EF(exn,"ArrayDelegatingEList/EIterator",1038),Wfn(706,278,yEn,b_,SB),Fjn.mj=function(){if(this.b.j!=this.f||iI(Yx(H3(this.b.a,4),126))!==iI(this.a))throw hp(new Dp)},Fjn.pj=function(n){Rin(this,n),this.a=Yx(H3(this.b.a,4),126)},Fjn.Qb=function(){tan(this),this.a=Yx(H3(this.b.a,4),126)},EF(exn,"ArrayDelegatingEList/EListIterator",706),Wfn(1039,341,fEn,lV),Fjn.mj=function(){if(this.b.j!=this.f||iI(Yx(H3(this.b.a,4),126))!==iI(this.a))throw hp(new Dp)},EF(exn,"ArrayDelegatingEList/NonResolvingEIterator",1039),Wfn(707,385,yEn,w_,PB),Fjn.mj=function(){if(this.b.j!=this.f||iI(Yx(H3(this.b.a,4),126))!==iI(this.a))throw hp(new Dp)},EF(exn,"ArrayDelegatingEList/NonResolvingEListIterator",707),Wfn(606,295,VTn,BI),EF(exn,"BasicEList/BasicIndexOutOfBoundsException",606),Wfn(696,63,Mxn,QP),Fjn.Vc=function(n,t){throw hp(new xp)},Fjn.Fc=function(n){throw hp(new xp)},Fjn.Wc=function(n,t){throw hp(new xp)},Fjn.Gc=function(n){throw hp(new xp)},Fjn.$b=function(){throw hp(new xp)},Fjn.qi=function(n){throw hp(new xp)},Fjn.Kc=function(){return this.Zh()},Fjn.Yc=function(){return this.$h()},Fjn.Zc=function(n){return this._h(n)},Fjn.ii=function(n,t){throw hp(new xp)},Fjn.ji=function(n,t){throw hp(new xp)},Fjn.$c=function(n){throw hp(new xp)},Fjn.Mc=function(n){throw hp(new xp)},Fjn._c=function(n,t){throw hp(new xp)},EF(exn,"BasicEList/UnmodifiableEList",696),Wfn(705,1,{3:1,20:1,14:1,15:1,58:1,589:1}),Fjn.Vc=function(n,t){!function(n,t,e){n.c.Vc(t,Yx(e,133))}(this,n,Yx(t,42))},Fjn.Fc=function(n){return function(n,t){return n.c.Fc(Yx(t,133))}(this,Yx(n,42))},Fjn.Jc=function(n){XW(this,n)},Fjn.Xb=function(n){return Yx(c1(this.c,n),133)},Fjn.ii=function(n,t){return Yx(this.c.ii(n,t),42)},Fjn.ji=function(n,t){!function(n,t,e){n.c.ji(t,Yx(e,133))}(this,n,Yx(t,42))},Fjn.Lc=function(){return new SR(null,new Nz(this,16))},Fjn.$c=function(n){return Yx(this.c.$c(n),42)},Fjn._c=function(n,t){return function(n,t,e){return Yx(n.c._c(t,Yx(e,133)),42)}(this,n,Yx(t,42))},Fjn.ad=function(n){I2(this,n)},Fjn.Nc=function(){return new Nz(this,16)},Fjn.Oc=function(){return new SR(null,new Nz(this,16))},Fjn.Wc=function(n,t){return this.c.Wc(n,t)},Fjn.Gc=function(n){return this.c.Gc(n)},Fjn.$b=function(){this.c.$b()},Fjn.Hc=function(n){return this.c.Hc(n)},Fjn.Ic=function(n){return m4(this.c,n)},Fjn.qj=function(){var n,t;if(null==this.d){for(this.d=VQ(Ect,yDn,63,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)tin(this,Yx(n.nj(),133));this.e=t}},Fjn.Fb=function(n){return UN(this,n)},Fjn.Hb=function(){return L4(this.c)},Fjn.Xc=function(n){return this.c.Xc(n)},Fjn.rj=function(){this.c=new Lg(this)},Fjn.dc=function(){return 0==this.f},Fjn.Kc=function(){return this.c.Kc()},Fjn.Yc=function(){return this.c.Yc()},Fjn.Zc=function(n){return this.c.Zc(n)},Fjn.sj=function(){return UQ(this)},Fjn.tj=function(n,t,e){return new Kx(n,t,e)},Fjn.uj=function(){return new vo},Fjn.Mc=function(n){return w0(this,n)},Fjn.gc=function(){return this.f},Fjn.bd=function(n,t){return new Oz(this.c,n,t)},Fjn.Pc=function(){return this.c.Pc()},Fjn.Qc=function(n){return this.c.Qc(n)},Fjn.Ib=function(){return D7(this.c)},Fjn.e=0,Fjn.f=0,EF(exn,"BasicEMap",705),Wfn(1033,63,Mxn,Lg),Fjn.bi=function(n,t){!function(n,t){tin(n.a,t)}(this,Yx(t,133))},Fjn.ei=function(n,t,e){++(this,Yx(t,133),this).a.e},Fjn.fi=function(n,t){!function(n,t){N9(n.a,t)}(this,Yx(t,133))},Fjn.gi=function(n,t,e){!function(n,t,e){N9(n.a,e),tin(n.a,t)}(this,Yx(t,133),Yx(e,133))},Fjn.di=function(n,t){A3(this.a)},EF(exn,"BasicEMap/1",1033),Wfn(1034,63,Mxn,vo),Fjn.ri=function(n){return VQ(Lct,kDn,612,n,0,1)},EF(exn,"BasicEMap/2",1034),Wfn(1035,dEn,gEn,Ng),Fjn.$b=function(){this.a.c.$b()},Fjn.Hc=function(n){return mnn(this.a,n)},Fjn.Kc=function(){return 0==this.a.f?(iL(),$ct.a):new Tk(this.a)},Fjn.Mc=function(n){var t;return t=this.a.f,ttn(this.a,n),this.a.f!=t},Fjn.gc=function(){return this.a.f},EF(exn,"BasicEMap/3",1035),Wfn(1036,28,wEn,xg),Fjn.$b=function(){this.a.c.$b()},Fjn.Hc=function(n){return Idn(this.a,n)},Fjn.Kc=function(){return 0==this.a.f?(iL(),$ct.a):new Mk(this.a)},Fjn.gc=function(){return this.a.f},EF(exn,"BasicEMap/4",1036),Wfn(1037,dEn,gEn,Dg),Fjn.$b=function(){this.a.c.$b()},Fjn.Hc=function(n){var t,e,i,r,c,a,u,o,s;if(this.a.f>0&&CO(n,42)&&(this.a.qj(),r=null==(u=(o=Yx(n,42)).cd())?0:W5(u),c=KL(this.a,r),t=this.a.d[c]))for(e=Yx(t.g,367),s=t.i,a=0;a"+this.c},Fjn.a=0;var $ct,Lct=EF(exn,"BasicEMap/EntryImpl",612);Wfn(536,1,{},oo),EF(exn,"BasicEMap/View",536),Wfn(768,1,{}),Fjn.Fb=function(n){return sln((XH(),TFn),n)},Fjn.Hb=function(){return K5((XH(),TFn))},Fjn.Ib=function(){return Gun((XH(),TFn))},EF(exn,"ECollections/BasicEmptyUnmodifiableEList",768),Wfn(1312,1,yEn,mo),Fjn.Nb=function(n){I_(this,n)},Fjn.Rb=function(n){throw hp(new xp)},Fjn.Ob=function(){return!1},Fjn.Sb=function(){return!1},Fjn.Pb=function(){throw hp(new Kp)},Fjn.Tb=function(){return 0},Fjn.Ub=function(){throw hp(new Kp)},Fjn.Vb=function(){return-1},Fjn.Qb=function(){throw hp(new xp)},Fjn.Wb=function(n){throw hp(new xp)},EF(exn,"ECollections/BasicEmptyUnmodifiableEList/1",1312),Wfn(1310,768,{20:1,14:1,15:1,58:1},Rv),Fjn.Vc=function(n,t){wj()},Fjn.Fc=function(n){return dj()},Fjn.Wc=function(n,t){return gj()},Fjn.Gc=function(n){return pj()},Fjn.$b=function(){vj()},Fjn.Hc=function(n){return!1},Fjn.Ic=function(n){return!1},Fjn.Jc=function(n){XW(this,n)},Fjn.Xb=function(n){return CI((XH(),n)),null},Fjn.Xc=function(n){return-1},Fjn.dc=function(){return!0},Fjn.Kc=function(){return this.a},Fjn.Yc=function(){return this.a},Fjn.Zc=function(n){return this.a},Fjn.ii=function(n,t){return mj()},Fjn.ji=function(n,t){yj()},Fjn.Lc=function(){return new SR(null,new Nz(this,16))},Fjn.$c=function(n){return kj()},Fjn.Mc=function(n){return jj()},Fjn._c=function(n,t){return Ej()},Fjn.gc=function(){return 0},Fjn.ad=function(n){I2(this,n)},Fjn.Nc=function(){return new Nz(this,16)},Fjn.Oc=function(){return new SR(null,new Nz(this,16))},Fjn.bd=function(n,t){return XH(),new Oz(TFn,n,t)},Fjn.Pc=function(){return CK((XH(),TFn))},Fjn.Qc=function(n){return XH(),_in(TFn,n)},EF(exn,"ECollections/EmptyUnmodifiableEList",1310),Wfn(1311,768,{20:1,14:1,15:1,58:1,589:1},Kv),Fjn.Vc=function(n,t){wj()},Fjn.Fc=function(n){return dj()},Fjn.Wc=function(n,t){return gj()},Fjn.Gc=function(n){return pj()},Fjn.$b=function(){vj()},Fjn.Hc=function(n){return!1},Fjn.Ic=function(n){return!1},Fjn.Jc=function(n){XW(this,n)},Fjn.Xb=function(n){return CI((XH(),n)),null},Fjn.Xc=function(n){return-1},Fjn.dc=function(){return!0},Fjn.Kc=function(){return this.a},Fjn.Yc=function(){return this.a},Fjn.Zc=function(n){return this.a},Fjn.ii=function(n,t){return mj()},Fjn.ji=function(n,t){yj()},Fjn.Lc=function(){return new SR(null,new Nz(this,16))},Fjn.$c=function(n){return kj()},Fjn.Mc=function(n){return jj()},Fjn._c=function(n,t){return Ej()},Fjn.gc=function(){return 0},Fjn.ad=function(n){I2(this,n)},Fjn.Nc=function(){return new Nz(this,16)},Fjn.Oc=function(){return new SR(null,new Nz(this,16))},Fjn.bd=function(n,t){return XH(),new Oz(TFn,n,t)},Fjn.Pc=function(){return CK((XH(),TFn))},Fjn.Qc=function(n){return XH(),_in(TFn,n)},Fjn.sj=function(){return XH(),XH(),MFn},EF(exn,"ECollections/EmptyUnmodifiableEMap",1311);var Nct,xct=aR(exn,"Enumerator");Wfn(281,1,{281:1},xdn),Fjn.Fb=function(n){var t;return this===n||!!CO(n,281)&&(t=Yx(n,281),this.f==t.f&&function(n,t){return null==n?null==t:vtn(n,t)}(this.i,t.i)&&QR(this.a,0!=(256&this.f)?0!=(256&t.f)?t.a:null:0!=(256&t.f)?null:t.a)&&QR(this.d,t.d)&&QR(this.g,t.g)&&QR(this.e,t.e)&&function(n,t){var e,i;if(n.j.length!=t.j.length)return!1;for(e=0,i=n.j.length;e=0?n.Bh(e):Ehn(n,t)},EF(PNn,"BasicEObjectImpl/4",1027),Wfn(1983,1,{108:1}),Fjn.bk=function(n){this.e=0==n?Fat:VQ(UKn,iEn,1,n,5,1)},Fjn.Ch=function(n){return this.e[n]},Fjn.Dh=function(n,t){this.e[n]=t},Fjn.Eh=function(n){this.e[n]=null},Fjn.ck=function(){return this.c},Fjn.dk=function(){throw hp(new xp)},Fjn.ek=function(){throw hp(new xp)},Fjn.fk=function(){return this.d},Fjn.gk=function(){return null!=this.e},Fjn.hk=function(n){this.c=n},Fjn.ik=function(n){throw hp(new xp)},Fjn.jk=function(n){throw hp(new xp)},Fjn.kk=function(n){this.d=n},EF(PNn,"BasicEObjectImpl/EPropertiesHolderBaseImpl",1983),Wfn(185,1983,{108:1},Df),Fjn.dk=function(){return this.a},Fjn.ek=function(){return this.b},Fjn.ik=function(n){this.a=n},Fjn.jk=function(n){this.b=n},EF(PNn,"BasicEObjectImpl/EPropertiesHolderImpl",185),Wfn(506,97,SNn,yo),Fjn.Kg=function(){return this.f},Fjn.Pg=function(){return this.k},Fjn.Rg=function(n,t){this.g=n,this.i=t},Fjn.Tg=function(){return 0==(2&this.j)?this.zh():this.ph().ck()},Fjn.Vg=function(){return this.i},Fjn.Mg=function(){return 0!=(1&this.j)},Fjn.eh=function(){return this.g},Fjn.kh=function(){return 0!=(4&this.j)},Fjn.ph=function(){return!this.k&&(this.k=new Df),this.k},Fjn.th=function(n){this.ph().hk(n),n?this.j|=2:this.j&=-3},Fjn.vh=function(n){this.ph().jk(n),n?this.j|=4:this.j&=-5},Fjn.zh=function(){return(YF(),gat).S},Fjn.i=0,Fjn.j=1,EF(PNn,"EObjectImpl",506),Wfn(780,506,{105:1,92:1,90:1,56:1,108:1,49:1,97:1},SD),Fjn.Ch=function(n){return this.e[n]},Fjn.Dh=function(n,t){this.e[n]=t},Fjn.Eh=function(n){this.e[n]=null},Fjn.Tg=function(){return this.d},Fjn.Yg=function(n){return tnn(this.d,n)},Fjn.$g=function(){return this.d},Fjn.dh=function(){return null!=this.e},Fjn.ph=function(){return!this.k&&(this.k=new ko),this.k},Fjn.th=function(n){this.d=n},Fjn.yh=function(){var n;return null==this.e&&(n=vF(this.d),this.e=0==n?Bat:VQ(UKn,iEn,1,n,5,1)),this},Fjn.Ah=function(){return 0},EF(PNn,"DynamicEObjectImpl",780),Wfn(1376,780,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1},rR),Fjn.Fb=function(n){return this===n},Fjn.Hb=function(){return _A(this)},Fjn.th=function(n){this.d=n,this.b=Ybn(n,"key"),this.c=Ybn(n,KNn)},Fjn.Sh=function(){var n;return-1==this.a&&(n=KJ(this,this.b),this.a=null==n?0:W5(n)),this.a},Fjn.cd=function(){return KJ(this,this.b)},Fjn.dd=function(){return KJ(this,this.c)},Fjn.Th=function(n){this.a=n},Fjn.Uh=function(n){bG(this,this.b,n)},Fjn.ed=function(n){var t;return t=KJ(this,this.c),bG(this,this.c,n),t},Fjn.a=0,EF(PNn,"DynamicEObjectImpl/BasicEMapEntry",1376),Wfn(1377,1,{108:1},ko),Fjn.bk=function(n){throw hp(new xp)},Fjn.Ch=function(n){throw hp(new xp)},Fjn.Dh=function(n,t){throw hp(new xp)},Fjn.Eh=function(n){throw hp(new xp)},Fjn.ck=function(){throw hp(new xp)},Fjn.dk=function(){return this.a},Fjn.ek=function(){return this.b},Fjn.fk=function(){return this.c},Fjn.gk=function(){throw hp(new xp)},Fjn.hk=function(n){throw hp(new xp)},Fjn.ik=function(n){this.a=n},Fjn.jk=function(n){this.b=n},Fjn.kk=function(n){this.c=n},EF(PNn,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1377),Wfn(510,150,{105:1,92:1,90:1,590:1,147:1,56:1,108:1,49:1,97:1,510:1,150:1,114:1,115:1},jo),Fjn.Qg=function(n){return tcn(this,n)},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new z$((xjn(),Dat),out,this)),this.b):(!this.b&&(this.b=new z$((xjn(),Dat),out,this)),UQ(this.b));case 3:return FG(this);case 4:return!this.a&&(this.a=new XO(Wrt,this,4)),this.a;case 5:return!this.c&&(this.c=new JO(Wrt,this,5)),this.c}return RY(this,n-vF((xjn(),pat)),CZ(Yx(H3(this,16),26)||pat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?tcn(this,e):this.Cb.ih(this,-1-i,null,e)),jK(this,Yx(n,147),e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),pat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),pat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 2:return!this.b&&(this.b=new z$((xjn(),Dat),out,this)),YN(this.b,n,e);case 3:return jK(this,null,e);case 4:return!this.a&&(this.a=new XO(Wrt,this,4)),Ten(this.a,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),pat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),pat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!FG(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return xX(this,n-vF((xjn(),pat)),CZ(Yx(H3(this,16),26)||pat,n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void function(n,t){B0(n,null==t?null:(vB(t),t))}(this,lL(t));case 2:return!this.b&&(this.b=new z$((xjn(),Dat),out,this)),void P3(this.b,t);case 3:return void Wbn(this,Yx(t,147));case 4:return!this.a&&(this.a=new XO(Wrt,this,4)),Hmn(this.a),!this.a&&(this.a=new XO(Wrt,this,4)),void jF(this.a,Yx(t,14));case 5:return!this.c&&(this.c=new JO(Wrt,this,5)),Hmn(this.c),!this.c&&(this.c=new JO(Wrt,this,5)),void jF(this.c,Yx(t,14))}E7(this,n-vF((xjn(),pat)),CZ(Yx(H3(this,16),26)||pat,n),t)},Fjn.zh=function(){return xjn(),pat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void B0(this,null);case 2:return!this.b&&(this.b=new z$((xjn(),Dat),out,this)),void this.b.c.$b();case 3:return void Wbn(this,null);case 4:return!this.a&&(this.a=new XO(Wrt,this,4)),void Hmn(this.a);case 5:return!this.c&&(this.c=new JO(Wrt,this,5)),void Hmn(this.c)}r9(this,n-vF((xjn(),pat)),CZ(Yx(H3(this,16),26)||pat,n))},Fjn.Ib=function(){return o9(this)},Fjn.d=null,EF(PNn,"EAnnotationImpl",510),Wfn(151,705,RDn,yY),Fjn.Xh=function(n,t){!function(n,t,e){Yx(n.c,69).Xh(t,e)}(this,n,Yx(t,42))},Fjn.lk=function(n,t){return function(n,t,e){return Yx(n.c,69).lk(t,e)}(this,Yx(n,42),t)},Fjn.pi=function(n){return Yx(Yx(this.c,69).pi(n),133)},Fjn.Zh=function(){return Yx(this.c,69).Zh()},Fjn.$h=function(){return Yx(this.c,69).$h()},Fjn._h=function(n){return Yx(this.c,69)._h(n)},Fjn.mk=function(n,t){return YN(this,n,t)},Fjn.Wj=function(n){return Yx(this.c,76).Wj(n)},Fjn.rj=function(){},Fjn.fj=function(){return Yx(this.c,76).fj()},Fjn.tj=function(n,t,e){var i;return(i=Yx(i1(this.b).Nh().Jh(this.b),133)).Th(n),i.Uh(t),i.ed(e),i},Fjn.uj=function(){return new Jg(this)},Fjn.Wb=function(n){P3(this,n)},Fjn.Xj=function(){Yx(this.c,76).Xj()},EF(xDn,"EcoreEMap",151),Wfn(158,151,RDn,z$),Fjn.qj=function(){var n,t,e,i,r;if(null==this.d){for(r=VQ(Ect,yDn,63,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=Yx(e.nj(),133)).Sh()&Yjn)%r.length])&&(n=r[i]=new Jg(this)),n.Fc(t);this.d=r}},EF(PNn,"EAnnotationImpl/1",158),Wfn(284,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,472:1,49:1,97:1,150:1,284:1,114:1,115:1}),Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),!!this.$j();case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q}return RY(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 9:return kF(this,e)}return Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Rj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i)}return xX(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void this.Lh(lL(t));case 2:return void s9(this,ny(hL(t)));case 3:return void l9(this,ny(hL(t)));case 4:return void _1(this,Yx(t,19).a);case 5:return void this.ok(Yx(t,19).a);case 8:return void a8(this,Yx(t,138));case 9:return void((e=fun(this,Yx(t,87),null))&&e.Fi())}E7(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t)},Fjn.zh=function(){return xjn(),Kat},Fjn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void this.Lh(null);case 2:return void s9(this,!0);case 3:return void l9(this,!0);case 4:return void _1(this,0);case 5:return void this.ok(1);case 8:return void a8(this,null);case 9:return void((t=fun(this,null,null))&&t.Fi())}r9(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.Gh=function(){fcn(this),this.Bb|=1},Fjn.Yj=function(){return fcn(this)},Fjn.Zj=function(){return this.t},Fjn.$j=function(){var n;return(n=this.t)>1||-1==n},Fjn.hi=function(){return 0!=(512&this.Bb)},Fjn.nk=function(n,t){return z8(this,n,t)},Fjn.ok=function(n){F1(this,n)},Fjn.Ib=function(){return Sfn(this)},Fjn.s=0,Fjn.t=1,EF(PNn,"ETypedElementImpl",284),Wfn(449,284,{105:1,92:1,90:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,449:1,284:1,114:1,115:1,677:1}),Fjn.Qg=function(n){return Arn(this,n)},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),!!this.$j();case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q;case 10:return TA(),0!=(this.Bb&DNn);case 11:return TA(),0!=(this.Bb&FDn);case 12:return TA(),0!=(this.Bb&nMn);case 13:return this.j;case 14:return Pbn(this);case 15:return TA(),0!=(this.Bb&_Dn);case 16:return TA(),0!=(this.Bb&MEn);case 17:return HG(this)}return RY(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?Arn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,17,e)}return Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Qj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 9:return kF(this,e);case 17:return opn(this,null,17,e)}return Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Rj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i);case 10:return 0==(this.Bb&DNn);case 11:return 0!=(this.Bb&FDn);case 12:return 0!=(this.Bb&nMn);case 13:return null!=this.j;case 14:return null!=Pbn(this);case 15:return 0!=(this.Bb&_Dn);case 16:return 0!=(this.Bb&MEn);case 17:return!!HG(this)}return xX(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void yz(this,lL(t));case 2:return void s9(this,ny(hL(t)));case 3:return void l9(this,ny(hL(t)));case 4:return void _1(this,Yx(t,19).a);case 5:return void this.ok(Yx(t,19).a);case 8:return void a8(this,Yx(t,138));case 9:return void((e=fun(this,Yx(t,87),null))&&e.Fi());case 10:return void x9(this,ny(hL(t)));case 11:return void K9(this,ny(hL(t)));case 12:return void D9(this,ny(hL(t)));case 13:return void ZP(this,lL(t));case 15:return void R9(this,ny(hL(t)));case 16:return void H9(this,ny(hL(t)))}E7(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t)},Fjn.zh=function(){return xjn(),Rat},Fjn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,88)&&rhn(bV(Yx(this.Cb,88)),4),void E2(this,null);case 2:return void s9(this,!0);case 3:return void l9(this,!0);case 4:return void _1(this,0);case 5:return void this.ok(1);case 8:return void a8(this,null);case 9:return void((t=fun(this,null,null))&&t.Fi());case 10:return void x9(this,!0);case 11:return void K9(this,!1);case 12:return void D9(this,!1);case 13:return this.i=null,void J0(this,null);case 15:return void R9(this,!1);case 16:return void H9(this,!1)}r9(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.Gh=function(){nH(PJ((wsn(),wut),this)),fcn(this),this.Bb|=1},Fjn.Gj=function(){return this.f},Fjn.zj=function(){return Pbn(this)},Fjn.Hj=function(){return HG(this)},Fjn.Lj=function(){return null},Fjn.pk=function(){return this.k},Fjn.aj=function(){return this.n},Fjn.Mj=function(){return fan(this)},Fjn.Nj=function(){var n,t,e,i,r,c,a,u,o;return this.p||((null==(e=HG(this)).i&&svn(e),e.i).length,(i=this.Lj())&&vF(HG(i)),n=(a=(r=fcn(this)).Bj())?0!=(1&a.i)?a==Vot?D_n:a==Wot?U_n:a==Zot?q_n:a==Jot?H_n:a==Qot?J_n:a==nst?nFn:a==Yot?__n:B_n:a:null,t=Pbn(this),u=r.zj(),s7(this),0!=(this.Bb&MEn)&&((c=Dcn((wsn(),wut),e))&&c!=this||(c=Bz(PJ(wut,this))))?this.p=new zP(this,c):this.$j()?this.rk()?i?0!=(this.Bb&_Dn)?n?this.sk()?this.p=new LH(47,n,this,i):this.p=new LH(5,n,this,i):this.sk()?this.p=new sW(46,this,i):this.p=new sW(4,this,i):n?this.sk()?this.p=new LH(49,n,this,i):this.p=new LH(7,n,this,i):this.sk()?this.p=new sW(48,this,i):this.p=new sW(6,this,i):0!=(this.Bb&_Dn)?n?n==i_n?this.p=new _x(50,hct,this):this.sk()?this.p=new _x(43,n,this):this.p=new _x(1,n,this):this.sk()?this.p=new Hq(42,this):this.p=new Hq(0,this):n?n==i_n?this.p=new _x(41,hct,this):this.sk()?this.p=new _x(45,n,this):this.p=new _x(3,n,this):this.sk()?this.p=new Hq(44,this):this.p=new Hq(2,this):CO(r,148)?n==Xat?this.p=new Hq(40,this):0!=(512&this.Bb)?0!=(this.Bb&_Dn)?this.p=n?new _x(9,n,this):new Hq(8,this):this.p=n?new _x(11,n,this):new Hq(10,this):0!=(this.Bb&_Dn)?this.p=n?new _x(13,n,this):new Hq(12,this):this.p=n?new _x(15,n,this):new Hq(14,this):i?(o=i.t)>1||-1==o?this.sk()?0!=(this.Bb&_Dn)?this.p=n?new LH(25,n,this,i):new sW(24,this,i):this.p=n?new LH(27,n,this,i):new sW(26,this,i):0!=(this.Bb&_Dn)?this.p=n?new LH(29,n,this,i):new sW(28,this,i):this.p=n?new LH(31,n,this,i):new sW(30,this,i):this.sk()?0!=(this.Bb&_Dn)?this.p=n?new LH(33,n,this,i):new sW(32,this,i):this.p=n?new LH(35,n,this,i):new sW(34,this,i):0!=(this.Bb&_Dn)?this.p=n?new LH(37,n,this,i):new sW(36,this,i):this.p=n?new LH(39,n,this,i):new sW(38,this,i):this.sk()?0!=(this.Bb&_Dn)?this.p=n?new _x(17,n,this):new Hq(16,this):this.p=n?new _x(19,n,this):new Hq(18,this):0!=(this.Bb&_Dn)?this.p=n?new _x(21,n,this):new Hq(20,this):this.p=n?new _x(23,n,this):new Hq(22,this):this.qk()?this.sk()?this.p=new Fx(Yx(r,26),this,i):this.p=new tG(Yx(r,26),this,i):CO(r,148)?n==Xat?this.p=new Hq(40,this):0!=(this.Bb&_Dn)?this.p=n?new SK(t,u,this,(onn(),a==Wot?rut:a==Vot?Zat:a==Qot?cut:a==Zot?iut:a==Jot?eut:a==nst?uut:a==Yot?nut:a==Xot?tut:aut)):new DH(Yx(r,148),t,u,this):this.p=n?new MK(t,u,this,(onn(),a==Wot?rut:a==Vot?Zat:a==Qot?cut:a==Zot?iut:a==Jot?eut:a==nst?uut:a==Yot?nut:a==Xot?tut:aut)):new xH(Yx(r,148),t,u,this):this.rk()?i?0!=(this.Bb&_Dn)?this.sk()?this.p=new Ux(Yx(r,26),this,i):this.p=new zx(Yx(r,26),this,i):this.sk()?this.p=new Gx(Yx(r,26),this,i):this.p=new Bx(Yx(r,26),this,i):0!=(this.Bb&_Dn)?this.sk()?this.p=new V$(Yx(r,26),this):this.p=new W$(Yx(r,26),this):this.sk()?this.p=new X$(Yx(r,26),this):this.p=new U$(Yx(r,26),this):this.sk()?i?0!=(this.Bb&_Dn)?this.p=new Xx(Yx(r,26),this,i):this.p=new Hx(Yx(r,26),this,i):0!=(this.Bb&_Dn)?this.p=new Y$(Yx(r,26),this):this.p=new Q$(Yx(r,26),this):i?0!=(this.Bb&_Dn)?this.p=new Wx(Yx(r,26),this,i):this.p=new qx(Yx(r,26),this,i):0!=(this.Bb&_Dn)?this.p=new J$(Yx(r,26),this):this.p=new KR(Yx(r,26),this)),this.p},Fjn.Ij=function(){return 0!=(this.Bb&DNn)},Fjn.qk=function(){return!1},Fjn.rk=function(){return!1},Fjn.Jj=function(){return 0!=(this.Bb&MEn)},Fjn.Oj=function(){return GJ(this)},Fjn.sk=function(){return!1},Fjn.Kj=function(){return 0!=(this.Bb&_Dn)},Fjn.tk=function(n){this.k=n},Fjn.Lh=function(n){yz(this,n)},Fjn.Ib=function(){return Qdn(this)},Fjn.e=!1,Fjn.n=0,EF(PNn,"EStructuralFeatureImpl",449),Wfn(322,449,{105:1,92:1,90:1,34:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,322:1,150:1,449:1,284:1,114:1,115:1,677:1},qv),Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),!!Bhn(this);case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q;case 10:return TA(),0!=(this.Bb&DNn);case 11:return TA(),0!=(this.Bb&FDn);case 12:return TA(),0!=(this.Bb&nMn);case 13:return this.j;case 14:return Pbn(this);case 15:return TA(),0!=(this.Bb&_Dn);case 16:return TA(),0!=(this.Bb&MEn);case 17:return HG(this);case 18:return TA(),0!=(this.Bb&MNn);case 19:return t?v4(this):uQ(this)}return RY(this,n-vF((xjn(),vat)),CZ(Yx(H3(this,16),26)||vat,n),t,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return Bhn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i);case 10:return 0==(this.Bb&DNn);case 11:return 0!=(this.Bb&FDn);case 12:return 0!=(this.Bb&nMn);case 13:return null!=this.j;case 14:return null!=Pbn(this);case 15:return 0!=(this.Bb&_Dn);case 16:return 0!=(this.Bb&MEn);case 17:return!!HG(this);case 18:return 0!=(this.Bb&MNn);case 19:return!!uQ(this)}return xX(this,n-vF((xjn(),vat)),CZ(Yx(H3(this,16),26)||vat,n))},Fjn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void yz(this,lL(t));case 2:return void s9(this,ny(hL(t)));case 3:return void l9(this,ny(hL(t)));case 4:return void _1(this,Yx(t,19).a);case 5:return void Ck(this,Yx(t,19).a);case 8:return void a8(this,Yx(t,138));case 9:return void((e=fun(this,Yx(t,87),null))&&e.Fi());case 10:return void x9(this,ny(hL(t)));case 11:return void K9(this,ny(hL(t)));case 12:return void D9(this,ny(hL(t)));case 13:return void ZP(this,lL(t));case 15:return void R9(this,ny(hL(t)));case 16:return void H9(this,ny(hL(t)));case 18:return void q9(this,ny(hL(t)))}E7(this,n-vF((xjn(),vat)),CZ(Yx(H3(this,16),26)||vat,n),t)},Fjn.zh=function(){return xjn(),vat},Fjn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,88)&&rhn(bV(Yx(this.Cb,88)),4),void E2(this,null);case 2:return void s9(this,!0);case 3:return void l9(this,!0);case 4:return void _1(this,0);case 5:return this.b=0,void F1(this,1);case 8:return void a8(this,null);case 9:return void((t=fun(this,null,null))&&t.Fi());case 10:return void x9(this,!0);case 11:return void K9(this,!1);case 12:return void D9(this,!1);case 13:return this.i=null,void J0(this,null);case 15:return void R9(this,!1);case 16:return void H9(this,!1);case 18:return void q9(this,!1)}r9(this,n-vF((xjn(),vat)),CZ(Yx(H3(this,16),26)||vat,n))},Fjn.Gh=function(){v4(this),nH(PJ((wsn(),wut),this)),fcn(this),this.Bb|=1},Fjn.$j=function(){return Bhn(this)},Fjn.nk=function(n,t){return this.b=0,this.a=null,z8(this,n,t)},Fjn.ok=function(n){Ck(this,n)},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?Qdn(this):((n=new MA(Qdn(this))).a+=" (iD: ",nj(n,0!=(this.Bb&MNn)),n.a+=")",n.a)},Fjn.b=0,EF(PNn,"EAttributeImpl",322),Wfn(351,438,{105:1,92:1,90:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1}),Fjn.uk=function(n){return n.Tg()==this},Fjn.Qg=function(n){return prn(this,n)},Fjn.Rg=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return frn(this);case 4:return this.zj();case 5:return this.F;case 6:return t?i1(this):BG(this);case 7:return!this.A&&(this.A=new VO(zat,this,7)),this.A}return RY(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?prn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,6,e)}return Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Qj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 6:return opn(this,null,6,e);case 7:return!this.A&&(this.A=new VO(zat,this,7)),Ten(this.A,n,e)}return Yx(CZ(Yx(H3(this,16),26)||this.zh(),t),66).Nj().Rj(this,dtn(this),t-vF(this.zh()),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!frn(this);case 4:return null!=this.zj();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!BG(this);case 7:return!!this.A&&0!=this.A.i}return xX(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void kz(this,lL(t));case 2:return void MC(this,lL(t));case 5:return void uyn(this,lL(t));case 7:return!this.A&&(this.A=new VO(zat,this,7)),Hmn(this.A),!this.A&&(this.A=new VO(zat,this,7)),void jF(this.A,Yx(t,14))}E7(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n),t)},Fjn.zh=function(){return xjn(),yat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,179)&&(Yx(this.Cb,179).tb=null),void E2(this,null);case 2:return j6(this,null),void B1(this,this.D);case 5:return void uyn(this,null);case 7:return!this.A&&(this.A=new VO(zat,this,7)),void Hmn(this.A)}r9(this,n-vF(this.zh()),CZ(Yx(H3(this,16),26)||this.zh(),n))},Fjn.yj=function(){var n;return-1==this.G&&(this.G=(n=i1(this))?Ren(n.Mh(),this):-1),this.G},Fjn.zj=function(){return null},Fjn.Aj=function(){return i1(this)},Fjn.vk=function(){return this.v},Fjn.Bj=function(){return frn(this)},Fjn.Cj=function(){return null!=this.D?this.D:this.B},Fjn.Dj=function(){return this.F},Fjn.wj=function(n){return Ypn(this,n)},Fjn.wk=function(n){this.v=n},Fjn.xk=function(n){N2(this,n)},Fjn.yk=function(n){this.C=n},Fjn.Lh=function(n){kz(this,n)},Fjn.Ib=function(){return nnn(this)},Fjn.C=null,Fjn.D=null,Fjn.G=-1,EF(PNn,"EClassifierImpl",351),Wfn(88,351,{105:1,92:1,90:1,26:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,88:1,351:1,150:1,473:1,114:1,115:1,676:1},Rf),Fjn.uk=function(n){return function(n,t){return t==n||Fcn(mbn(t),n)}(this,n.Tg())},Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return frn(this);case 4:return null;case 5:return this.F;case 6:return t?i1(this):BG(this);case 7:return!this.A&&(this.A=new VO(zat,this,7)),this.A;case 8:return TA(),0!=(256&this.Bb);case 9:return TA(),0!=(512&this.Bb);case 10:return Iq(this);case 11:return!this.q&&(this.q=new m_(fat,this,11,10)),this.q;case 12:return emn(this);case 13:return Uvn(this);case 14:return Uvn(this),this.r;case 15:return emn(this),this.k;case 16:return $sn(this);case 17:return Avn(this);case 18:return svn(this);case 19:return mbn(this);case 20:return emn(this),this.o;case 21:return!this.s&&(this.s=new m_(tat,this,21,17)),this.s;case 22:return tW(this);case 23:return Edn(this)}return RY(this,n-vF((xjn(),mat)),CZ(Yx(H3(this,16),26)||mat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?prn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,6,e);case 11:return!this.q&&(this.q=new m_(fat,this,11,10)),wnn(this.q,n,e);case 21:return!this.s&&(this.s=new m_(tat,this,21,17)),wnn(this.s,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),mat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),mat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 6:return opn(this,null,6,e);case 7:return!this.A&&(this.A=new VO(zat,this,7)),Ten(this.A,n,e);case 11:return!this.q&&(this.q=new m_(fat,this,11,10)),Ten(this.q,n,e);case 21:return!this.s&&(this.s=new m_(tat,this,21,17)),Ten(this.s,n,e);case 22:return Ten(tW(this),n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),mat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),mat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!frn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!BG(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0!=(256&this.Bb);case 9:return 0!=(512&this.Bb);case 10:return!(!this.u||0==tW(this.u.a).i||this.n&&sin(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=emn(this).i;case 13:return 0!=Uvn(this).i;case 14:return Uvn(this),0!=this.r.i;case 15:return emn(this),0!=this.k.i;case 16:return 0!=$sn(this).i;case 17:return 0!=Avn(this).i;case 18:return 0!=svn(this).i;case 19:return 0!=mbn(this).i;case 20:return emn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&sin(this.n);case 23:return 0!=Edn(this).i}return xX(this,n-vF((xjn(),mat)),CZ(Yx(H3(this,16),26)||mat,n))},Fjn.oh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:Ybn(this,n))||jkn(this,n)},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void kz(this,lL(t));case 2:return void MC(this,lL(t));case 5:return void uyn(this,lL(t));case 7:return!this.A&&(this.A=new VO(zat,this,7)),Hmn(this.A),!this.A&&(this.A=new VO(zat,this,7)),void jF(this.A,Yx(t,14));case 8:return void h9(this,ny(hL(t)));case 9:return void b9(this,ny(hL(t)));case 10:return Wmn(Iq(this)),void jF(Iq(this),Yx(t,14));case 11:return!this.q&&(this.q=new m_(fat,this,11,10)),Hmn(this.q),!this.q&&(this.q=new m_(fat,this,11,10)),void jF(this.q,Yx(t,14));case 21:return!this.s&&(this.s=new m_(tat,this,21,17)),Hmn(this.s),!this.s&&(this.s=new m_(tat,this,21,17)),void jF(this.s,Yx(t,14));case 22:return Hmn(tW(this)),void jF(tW(this),Yx(t,14))}E7(this,n-vF((xjn(),mat)),CZ(Yx(H3(this,16),26)||mat,n),t)},Fjn.zh=function(){return xjn(),mat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,179)&&(Yx(this.Cb,179).tb=null),void E2(this,null);case 2:return j6(this,null),void B1(this,this.D);case 5:return void uyn(this,null);case 7:return!this.A&&(this.A=new VO(zat,this,7)),void Hmn(this.A);case 8:return void h9(this,!1);case 9:return void b9(this,!1);case 10:return void(this.u&&Wmn(this.u));case 11:return!this.q&&(this.q=new m_(fat,this,11,10)),void Hmn(this.q);case 21:return!this.s&&(this.s=new m_(tat,this,21,17)),void Hmn(this.s);case 22:return void(this.n&&Hmn(this.n))}r9(this,n-vF((xjn(),mat)),CZ(Yx(H3(this,16),26)||mat,n))},Fjn.Gh=function(){var n,t;if(emn(this),Uvn(this),$sn(this),Avn(this),svn(this),mbn(this),Edn(this),xV(function(n){return!n.c&&(n.c=new Bo),n.c}(bV(this))),this.s)for(n=0,t=this.s.i;n=0;--t)c1(this,t);return bnn(this,n)},Fjn.Xj=function(){Hmn(this)},Fjn.oi=function(n,t){return z1(this,0,t)},EF(xDn,"EcoreEList",622),Wfn(496,622,JDn,TD),Fjn.ai=function(){return!1},Fjn.aj=function(){return this.c},Fjn.bj=function(){return!1},Fjn.Fk=function(){return!0},Fjn.hi=function(){return!0},Fjn.li=function(n,t){return t},Fjn.ni=function(){return!1},Fjn.c=0,EF(xDn,"EObjectEList",496),Wfn(85,496,JDn,XO),Fjn.bj=function(){return!0},Fjn.Dk=function(){return!1},Fjn.rk=function(){return!0},EF(xDn,"EObjectContainmentEList",85),Wfn(545,85,JDn,WO),Fjn.ci=function(){this.b=!0},Fjn.fj=function(){return this.b},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.b,this.b=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.b=!1},Fjn.b=!1,EF(xDn,"EObjectContainmentEList/Unsettable",545),Wfn(1140,545,JDn,EK),Fjn.ii=function(n,t){var e,i;return e=Yx(L9(this,n,t),87),gC(this.e)&&Xp(this,new jY(this.a,7,(xjn(),kat),d9(t),CO(i=e.c,88)?Yx(i,26):Oat,n)),e},Fjn.jj=function(n,t){return function(n,t,e){var i,r;return i=new yJ(n.e,3,10,null,CO(r=t.c,88)?Yx(r,26):(xjn(),Oat),Ren(n,t),!1),e?e.Ei(i):e=i,e}(this,Yx(n,87),t)},Fjn.kj=function(n,t){return function(n,t,e){var i,r;return i=new yJ(n.e,4,10,CO(r=t.c,88)?Yx(r,26):(xjn(),Oat),null,Ren(n,t),!1),e?e.Ei(i):e=i,e}(this,Yx(n,87),t)},Fjn.lj=function(n,t,e){return function(n,t,e,i){var r,c,a;return r=new yJ(n.e,1,10,CO(a=t.c,88)?Yx(a,26):(xjn(),Oat),CO(c=e.c,88)?Yx(c,26):(xjn(),Oat),Ren(n,t),!1),i?i.Ei(r):i=r,i}(this,Yx(n,87),Yx(t,87),e)},Fjn.Zi=function(n,t,e,i,r){switch(n){case 3:return zG(this,n,t,e,i,this.i>1);case 5:return zG(this,n,t,e,i,this.i-Yx(e,15).gc()>0);default:return new yJ(this.e,n,this.c,t,e,i,!0)}},Fjn.ij=function(){return!0},Fjn.fj=function(){return sin(this)},Fjn.Xj=function(){Hmn(this)},EF(PNn,"EClassImpl/1",1140),Wfn(1154,1153,wDn),Fjn.ui=function(n){var t,e,i,r,c,a,u;if(8!=(e=n.xi())){if(0==(i=function(n){switch(n.yi(null)){case 10:return 0;case 15:return 1;case 14:return 2;case 11:return 3;case 21:return 4}return-1}(n)))switch(e){case 1:case 9:null!=(u=n.Bi())&&(!(t=bV(Yx(u,473))).c&&(t.c=new Bo),qJ(t.c,n.Ai())),null!=(a=n.zi())&&0==(1&(r=Yx(a,473)).Bb)&&(!(t=bV(r)).c&&(t.c=new Bo),fY(t.c,Yx(n.Ai(),26)));break;case 3:null!=(a=n.zi())&&0==(1&(r=Yx(a,473)).Bb)&&(!(t=bV(r)).c&&(t.c=new Bo),fY(t.c,Yx(n.Ai(),26)));break;case 5:if(null!=(a=n.zi()))for(c=Yx(a,14).Kc();c.Ob();)0==(1&(r=Yx(c.Pb(),473)).Bb)&&(!(t=bV(r)).c&&(t.c=new Bo),fY(t.c,Yx(n.Ai(),26)));break;case 4:null!=(u=n.Bi())&&0==(1&(r=Yx(u,473)).Bb)&&(!(t=bV(r)).c&&(t.c=new Bo),qJ(t.c,n.Ai()));break;case 6:if(null!=(u=n.Bi()))for(c=Yx(u,14).Kc();c.Ob();)0==(1&(r=Yx(c.Pb(),473)).Bb)&&(!(t=bV(r)).c&&(t.c=new Bo),qJ(t.c,n.Ai()))}this.Hk(i)}},Fjn.Hk=function(n){Gdn(this,n)},Fjn.b=63,EF(PNn,"ESuperAdapter",1154),Wfn(1155,1154,wDn,Kg),Fjn.Hk=function(n){rhn(this,n)},EF(PNn,"EClassImpl/10",1155),Wfn(1144,696,JDn),Fjn.Vh=function(n,t){return hun(this,n,t)},Fjn.Wh=function(n){return $in(this,n)},Fjn.Xh=function(n,t){X8(this,n,t)},Fjn.Yh=function(n){NV(this,n)},Fjn.pi=function(n){return AY(this,n)},Fjn.mi=function(n,t){return HJ(this,n,t)},Fjn.lk=function(n,t){throw hp(new xp)},Fjn.Zh=function(){return new u$(this)},Fjn.$h=function(){return new o$(this)},Fjn._h=function(n){return b0(this,n)},Fjn.mk=function(n,t){throw hp(new xp)},Fjn.Wj=function(n){return this},Fjn.fj=function(){return 0!=this.i},Fjn.Wb=function(n){throw hp(new xp)},Fjn.Xj=function(){throw hp(new xp)},EF(xDn,"EcoreEList/UnmodifiableEList",1144),Wfn(319,1144,JDn,HI),Fjn.ni=function(){return!1},EF(xDn,"EcoreEList/UnmodifiableEList/FastCompare",319),Wfn(1147,319,JDn,p5),Fjn.Xc=function(n){var t,e;if(CO(n,170)&&-1!=(t=Yx(n,170).aj()))for(e=this.i;t4){if(!this.wj(n))return!1;if(this.rk()){if(a=(t=(e=Yx(n,49)).Ug())==this.b&&(this.Dk()?e.Og(e.Vg(),Yx(CZ(Cq(this.b),this.aj()).Yj(),26).Bj())==nin(Yx(CZ(Cq(this.b),this.aj()),18)).n:-1-e.Vg()==this.aj()),this.Ek()&&!a&&!t&&e.Zg())for(i=0;i1||-1==e)},Fjn.Dk=function(){var n;return!!CO(n=CZ(Cq(this.b),this.aj()),99)&&!!nin(Yx(n,18))},Fjn.Ek=function(){var n;return!!CO(n=CZ(Cq(this.b),this.aj()),99)&&0!=(Yx(n,18).Bb&eMn)},Fjn.Xc=function(n){var t,e,i;if((e=this.Qi(n))>=0)return e;if(this.Fk())for(t=0,i=this.Vi();t=0;--n)hyn(this,n,this.Oi(n));return this.Wi()},Fjn.Qc=function(n){var t;if(this.Ek())for(t=this.Vi()-1;t>=0;--t)hyn(this,t,this.Oi(t));return this.Xi(n)},Fjn.Xj=function(){Wmn(this)},Fjn.oi=function(n,t){return $Y(this,0,t)},EF(xDn,"DelegatingEcoreEList",742),Wfn(1150,742,iRn,qL),Fjn.Hi=function(n,t){!function(n,t,e){y9(tW(n.a),t,Ez(e))}(this,n,Yx(t,26))},Fjn.Ii=function(n){!function(n,t){fY(tW(n.a),Ez(t))}(this,Yx(n,26))},Fjn.Oi=function(n){var t;return CO(t=Yx(c1(tW(this.a),n),87).c,88)?Yx(t,26):(xjn(),Oat)},Fjn.Ti=function(n){var t;return CO(t=Yx(tdn(tW(this.a),n),87).c,88)?Yx(t,26):(xjn(),Oat)},Fjn.Ui=function(n,t){return function(n,t,e){var i,r,c;return(0!=(64&(c=CO(r=(i=Yx(c1(tW(n.a),t),87)).c,88)?Yx(r,26):(xjn(),Oat)).Db)?P8(n.b,c):c)==e?Bpn(i):b1(i,e),c}(this,n,Yx(t,26))},Fjn.ai=function(){return!1},Fjn.Zi=function(n,t,e,i,r){return null},Fjn.Ji=function(){return new Fg(this)},Fjn.Ki=function(){Hmn(tW(this.a))},Fjn.Li=function(n){return a9(this,n)},Fjn.Mi=function(n){var t;for(t=n.Kc();t.Ob();)if(!a9(this,t.Pb()))return!1;return!0},Fjn.Ni=function(n){var t,e,i;if(CO(n,15)&&(i=Yx(n,15)).gc()==tW(this.a).i){for(t=i.Kc(),e=new UO(this);t.Ob();)if(iI(t.Pb())!==iI(hen(e)))return!1;return!0}return!1},Fjn.Pi=function(){var n,t,e,i;for(t=1,n=new UO(tW(this.a));n.e!=n.i.gc();)t=31*t+((e=CO(i=Yx(hen(n),87).c,88)?Yx(i,26):(xjn(),Oat))?_A(e):0);return t},Fjn.Qi=function(n){var t,e,i,r;for(i=0,e=new UO(tW(this.a));e.e!=e.i.gc();){if(t=Yx(hen(e),87),iI(n)===iI(CO(r=t.c,88)?Yx(r,26):(xjn(),Oat)))return i;++i}return-1},Fjn.Ri=function(){return 0==tW(this.a).i},Fjn.Si=function(){return null},Fjn.Vi=function(){return tW(this.a).i},Fjn.Wi=function(){var n,t,e,i,r,c;for(c=tW(this.a).i,r=VQ(UKn,iEn,1,c,5,1),e=0,t=new UO(tW(this.a));t.e!=t.i.gc();)n=Yx(hen(t),87),r[e++]=CO(i=n.c,88)?Yx(i,26):(xjn(),Oat);return r},Fjn.Xi=function(n){var t,e,i,r;for(r=tW(this.a).i,n.lengthr&&DF(n,r,null),e=0,t=new UO(tW(this.a));t.e!=t.i.gc();)DF(n,e++,CO(i=Yx(hen(t),87).c,88)?Yx(i,26):(xjn(),Oat));return n},Fjn.Yi=function(){var n,t,e,i,r;for((r=new Cy).a+="[",n=tW(this.a),t=0,i=tW(this.a).i;t>16)>=0?prn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,6,e);case 9:return!this.a&&(this.a=new m_(sat,this,9,5)),wnn(this.a,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Eat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Eat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 6:return opn(this,null,6,e);case 7:return!this.A&&(this.A=new VO(zat,this,7)),Ten(this.A,n,e);case 9:return!this.a&&(this.a=new m_(sat,this,9,5)),Ten(this.a,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Eat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Eat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!frn(this);case 4:return!!x6(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!BG(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0==(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return xX(this,n-vF((xjn(),Eat)),CZ(Yx(H3(this,16),26)||Eat,n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void kz(this,lL(t));case 2:return void MC(this,lL(t));case 5:return void uyn(this,lL(t));case 7:return!this.A&&(this.A=new VO(zat,this,7)),Hmn(this.A),!this.A&&(this.A=new VO(zat,this,7)),void jF(this.A,Yx(t,14));case 8:return void f9(this,ny(hL(t)));case 9:return!this.a&&(this.a=new m_(sat,this,9,5)),Hmn(this.a),!this.a&&(this.a=new m_(sat,this,9,5)),void jF(this.a,Yx(t,14))}E7(this,n-vF((xjn(),Eat)),CZ(Yx(H3(this,16),26)||Eat,n),t)},Fjn.zh=function(){return xjn(),Eat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,179)&&(Yx(this.Cb,179).tb=null),void E2(this,null);case 2:return j6(this,null),void B1(this,this.D);case 5:return void uyn(this,null);case 7:return!this.A&&(this.A=new VO(zat,this,7)),void Hmn(this.A);case 8:return void f9(this,!0);case 9:return!this.a&&(this.a=new m_(sat,this,9,5)),void Hmn(this.a)}r9(this,n-vF((xjn(),Eat)),CZ(Yx(H3(this,16),26)||Eat,n))},Fjn.Gh=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n>16==5?Yx(this.Cb,671):null}return RY(this,n-vF((xjn(),Tat)),CZ(Yx(H3(this,16),26)||Tat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?ncn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,5,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Tat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Tat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 5:return opn(this,null,5,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Tat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Tat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!Yx(this.Cb,671))}return xX(this,n-vF((xjn(),Tat)),CZ(Yx(H3(this,16),26)||Tat,n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void E2(this,lL(t));case 2:return void K1(this,Yx(t,19).a);case 3:return void hfn(this,Yx(t,1940));case 4:return void F0(this,lL(t))}E7(this,n-vF((xjn(),Tat)),CZ(Yx(H3(this,16),26)||Tat,n),t)},Fjn.zh=function(){return xjn(),Tat},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void E2(this,null);case 2:return void K1(this,0);case 3:return void hfn(this,null);case 4:return void F0(this,null)}r9(this,n-vF((xjn(),Tat)),CZ(Yx(H3(this,16),26)||Tat,n))},Fjn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},Fjn.b=null,Fjn.c=null,Fjn.d=0,EF(PNn,"EEnumLiteralImpl",573);var Wat,Vat,Qat,Yat=aR(PNn,"EFactoryImpl/InternalEDateTimeFormat");Wfn(489,1,{2015:1},Bg),EF(PNn,"EFactoryImpl/1ClientInternalEDateTimeFormat",489),Wfn(241,115,{105:1,92:1,90:1,87:1,56:1,108:1,49:1,97:1,241:1,114:1,115:1},up),Fjn.Sg=function(n,t,e){var i;return e=opn(this,n,t,e),this.e&&CO(n,170)&&(i=dbn(this,this.e))!=this.c&&(e=zyn(this,i,e)),e},Fjn._g=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new XO(hat,this,1)),this.d;case 2:return t?Bpn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?win(this):this.a}return RY(this,n-vF((xjn(),Sat)),CZ(Yx(H3(this,16),26)||Sat,n),t,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return S8(this,null,e);case 1:return!this.d&&(this.d=new XO(hat,this,1)),Ten(this.d,n,e);case 3:return M8(this,null,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Sat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Sat)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return xX(this,n-vF((xjn(),Sat)),CZ(Yx(H3(this,16),26)||Sat,n))},Fjn.sh=function(n,t){switch(n){case 0:return void man(this,Yx(t,87));case 1:return!this.d&&(this.d=new XO(hat,this,1)),Hmn(this.d),!this.d&&(this.d=new XO(hat,this,1)),void jF(this.d,Yx(t,14));case 3:return void van(this,Yx(t,87));case 4:return void Xun(this,Yx(t,836));case 5:return void b1(this,Yx(t,138))}E7(this,n-vF((xjn(),Sat)),CZ(Yx(H3(this,16),26)||Sat,n),t)},Fjn.zh=function(){return xjn(),Sat},Fjn.Bh=function(n){switch(n){case 0:return void man(this,null);case 1:return!this.d&&(this.d=new XO(hat,this,1)),void Hmn(this.d);case 3:return void van(this,null);case 4:return void Xun(this,null);case 5:return void b1(this,null)}r9(this,n-vF((xjn(),Sat)),CZ(Yx(H3(this,16),26)||Sat,n))},Fjn.Ib=function(){var n;return(n=new SA(Kln(this))).a+=" (expression: ",wmn(this,n),n.a+=")",n.a},EF(PNn,"EGenericTypeImpl",241),Wfn(1969,1964,rRn),Fjn.Xh=function(n,t){DL(this,n,t)},Fjn.lk=function(n,t){return DL(this,this.gc(),n),t},Fjn.pi=function(n){return ken(this.Gi(),n)},Fjn.Zh=function(){return this.$h()},Fjn.Gi=function(){return new Qg(this)},Fjn.$h=function(){return this._h(0)},Fjn._h=function(n){return this.Gi().Zc(n)},Fjn.mk=function(n,t){return V7(this,n,!0),t},Fjn.ii=function(n,t){var e;return e=Urn(this,t),this.Zc(n).Rb(e),e},Fjn.ji=function(n,t){V7(this,t,!0),this.Zc(n).Rb(t)},EF(xDn,"AbstractSequentialInternalEList",1969),Wfn(486,1969,rRn,n$),Fjn.pi=function(n){return ken(this.Gi(),n)},Fjn.Zh=function(){return null==this.b?(jT(),jT(),Qat):this.Jk()},Fjn.Gi=function(){return new GI(this.a,this.b)},Fjn.$h=function(){return null==this.b?(jT(),jT(),Qat):this.Jk()},Fjn._h=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw hp(new Hm(pDn+n+", size=0"));return jT(),jT(),Qat}for(e=this.Jk(),t=0;t0;)if(t=this.c[--this.d],(!this.e||t.Gj()!=Vrt||0!=t.aj())&&(!this.Mk()||this.b.mh(t)))if(c=this.b.bh(t,this.Lk()),this.f=(TT(),Yx(t,66).Oj()),this.f||t.$j()){if(this.Lk()?(i=Yx(c,15),this.k=i):(i=Yx(c,69),this.k=this.j=i),CO(this.k,54)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j._h(this.k.gc()):this.k.Zc(this.k.gc()),this.p?hsn(this,this.p):zsn(this))return r=this.p?this.p.Ub():this.j?this.j.pi(--this.n):this.k.Xb(--this.n),this.f?((n=Yx(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},Fjn.Pb=function(){return X3(this)},Fjn.Tb=function(){return this.a},Fjn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw hp(new Kp)},Fjn.Vb=function(){return this.a-1},Fjn.Qb=function(){throw hp(new xp)},Fjn.Lk=function(){return!1},Fjn.Wb=function(n){throw hp(new xp)},Fjn.Mk=function(){return!0},Fjn.a=0,Fjn.d=0,Fjn.f=!1,Fjn.g=0,Fjn.n=0,Fjn.o=0,EF(xDn,"EContentsEList/FeatureIteratorImpl",279),Wfn(697,279,cRn,H$),Fjn.Lk=function(){return!0},EF(xDn,"EContentsEList/ResolvingFeatureIteratorImpl",697),Wfn(1157,697,cRn,G$),Fjn.Mk=function(){return!1},EF(PNn,"ENamedElementImpl/1/1",1157),Wfn(1158,279,cRn,q$),Fjn.Mk=function(){return!1},EF(PNn,"ENamedElementImpl/1/2",1158),Wfn(36,143,gDn,aW,uW,p_,kY,yJ,OV,W1,aU,V1,uU,PV,oU,J1,sU,IV,hU,Q1,fU,v_,jY,tq,Y1,lU,CV,bU),Fjn._i=function(){return hY(this)},Fjn.gj=function(){var n;return(n=hY(this))?n.zj():null},Fjn.yi=function(n){return-1==this.b&&this.a&&(this.b=this.c.Xg(this.a.aj(),this.a.Gj())),this.c.Og(this.b,n)},Fjn.Ai=function(){return this.c},Fjn.hj=function(){var n;return!!(n=hY(this))&&n.Kj()},Fjn.b=-1,EF(PNn,"ENotificationImpl",36),Wfn(399,284,{105:1,92:1,90:1,147:1,191:1,56:1,59:1,108:1,472:1,49:1,97:1,150:1,399:1,284:1,114:1,115:1},zv),Fjn.Qg=function(n){return scn(this,n)},Fjn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),(i=this.t)>1||-1==i;case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?Yx(this.Cb,26):null;case 11:return!this.d&&(this.d=new VO(zat,this,11)),this.d;case 12:return!this.c&&(this.c=new m_(lat,this,12,10)),this.c;case 13:return!this.a&&(this.a=new GL(this,this)),this.a;case 14:return IJ(this)}return RY(this,n-vF((xjn(),Aat)),CZ(Yx(H3(this,16),26)||Aat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?scn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,10,e);case 12:return!this.c&&(this.c=new m_(lat,this,12,10)),wnn(this.c,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Aat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Aat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 9:return kF(this,e);case 10:return opn(this,null,10,e);case 11:return!this.d&&(this.d=new VO(zat,this,11)),Ten(this.d,n,e);case 12:return!this.c&&(this.c=new m_(lat,this,12,10)),Ten(this.c,n,e);case 14:return Ten(IJ(this),n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Aat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Aat)),n,e)},Fjn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i);case 10:return!(this.Db>>16!=10||!Yx(this.Cb,26));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==IJ(this.a.a).i||this.b&&hin(this.b));case 14:return!!this.b&&hin(this.b)}return xX(this,n-vF((xjn(),Aat)),CZ(Yx(H3(this,16),26)||Aat,n))},Fjn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void E2(this,lL(t));case 2:return void s9(this,ny(hL(t)));case 3:return void l9(this,ny(hL(t)));case 4:return void _1(this,Yx(t,19).a);case 5:return void F1(this,Yx(t,19).a);case 8:return void a8(this,Yx(t,138));case 9:return void((e=fun(this,Yx(t,87),null))&&e.Fi());case 11:return!this.d&&(this.d=new VO(zat,this,11)),Hmn(this.d),!this.d&&(this.d=new VO(zat,this,11)),void jF(this.d,Yx(t,14));case 12:return!this.c&&(this.c=new m_(lat,this,12,10)),Hmn(this.c),!this.c&&(this.c=new m_(lat,this,12,10)),void jF(this.c,Yx(t,14));case 13:return!this.a&&(this.a=new GL(this,this)),Wmn(this.a),!this.a&&(this.a=new GL(this,this)),void jF(this.a,Yx(t,14));case 14:return Hmn(IJ(this)),void jF(IJ(this),Yx(t,14))}E7(this,n-vF((xjn(),Aat)),CZ(Yx(H3(this,16),26)||Aat,n),t)},Fjn.zh=function(){return xjn(),Aat},Fjn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void E2(this,null);case 2:return void s9(this,!0);case 3:return void l9(this,!0);case 4:return void _1(this,0);case 5:return void F1(this,1);case 8:return void a8(this,null);case 9:return void((t=fun(this,null,null))&&t.Fi());case 11:return!this.d&&(this.d=new VO(zat,this,11)),void Hmn(this.d);case 12:return!this.c&&(this.c=new m_(lat,this,12,10)),void Hmn(this.c);case 13:return void(this.a&&Wmn(this.a));case 14:return void(this.b&&Hmn(this.b))}r9(this,n-vF((xjn(),Aat)),CZ(Yx(H3(this,16),26)||Aat,n))},Fjn.Gh=function(){var n,t;if(this.c)for(n=0,t=this.c.i;ni&&DF(n,i,null),e=0,t=new UO(IJ(this.a));t.e!=t.i.gc();)DF(n,e++,Yx(hen(t),87).c||(xjn(),Pat));return n},Fjn.Yi=function(){var n,t,e,i;for((i=new Cy).a+="[",n=IJ(this.a),t=0,e=IJ(this.a).i;t1);case 5:return zG(this,n,t,e,i,this.i-Yx(e,15).gc()>0);default:return new yJ(this.e,n,this.c,t,e,i,!0)}},Fjn.ij=function(){return!0},Fjn.fj=function(){return hin(this)},Fjn.Xj=function(){Hmn(this)},EF(PNn,"EOperationImpl/2",1341),Wfn(498,1,{1938:1,498:1},GP),EF(PNn,"EPackageImpl/1",498),Wfn(16,85,JDn,m_),Fjn.zk=function(){return this.d},Fjn.Ak=function(){return this.b},Fjn.Dk=function(){return!0},Fjn.b=0,EF(xDn,"EObjectContainmentWithInverseEList",16),Wfn(353,16,JDn,EN),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectContainmentWithInverseEList/Resolving",353),Wfn(298,353,JDn,d_),Fjn.ci=function(){this.a.tb=null},EF(PNn,"EPackageImpl/2",298),Wfn(1228,1,{},Oo),EF(PNn,"EPackageImpl/3",1228),Wfn(718,43,gMn,Xv),Fjn._b=function(n){return aI(n)?hq(this,n):!!Dq(this.f,n)},EF(PNn,"EPackageRegistryImpl",718),Wfn(509,284,{105:1,92:1,90:1,147:1,191:1,56:1,2017:1,108:1,472:1,49:1,97:1,150:1,509:1,284:1,114:1,115:1},Uv),Fjn.Qg=function(n){return hcn(this,n)},Fjn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),(i=this.t)>1||-1==i;case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?Yx(this.Cb,59):null}return RY(this,n-vF((xjn(),Nat)),CZ(Yx(H3(this,16),26)||Nat,n),t,e)},Fjn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),wnn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?hcn(this,e):this.Cb.ih(this,-1-i,null,e)),opn(this,n,10,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Nat),t),66).Nj().Qj(this,dtn(this),t-vF((xjn(),Nat)),n,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 9:return kF(this,e);case 10:return opn(this,null,10,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),Nat),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),Nat)),n,e)},Fjn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i);case 10:return!(this.Db>>16!=10||!Yx(this.Cb,59))}return xX(this,n-vF((xjn(),Nat)),CZ(Yx(H3(this,16),26)||Nat,n))},Fjn.zh=function(){return xjn(),Nat},EF(PNn,"EParameterImpl",509),Wfn(99,449,{105:1,92:1,90:1,147:1,191:1,56:1,18:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,99:1,449:1,284:1,114:1,115:1,677:1},cL),Fjn._g=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return TA(),0!=(256&this.Bb);case 3:return TA(),0!=(512&this.Bb);case 4:return d9(this.s);case 5:return d9(this.t);case 6:return TA(),(r=this.t)>1||-1==r;case 7:return TA(),this.s>=1;case 8:return t?fcn(this):this.r;case 9:return this.q;case 10:return TA(),0!=(this.Bb&DNn);case 11:return TA(),0!=(this.Bb&FDn);case 12:return TA(),0!=(this.Bb&nMn);case 13:return this.j;case 14:return Pbn(this);case 15:return TA(),0!=(this.Bb&_Dn);case 16:return TA(),0!=(this.Bb&MEn);case 17:return HG(this);case 18:return TA(),0!=(this.Bb&MNn);case 19:return TA(),!(!(i=nin(this))||0==(i.Bb&MNn));case 20:return TA(),0!=(this.Bb&eMn);case 21:return t?nin(this):this.b;case 22:return t?O5(this):dV(this);case 23:return!this.a&&(this.a=new JO(eat,this,23)),this.a}return RY(this,n-vF((xjn(),xat)),CZ(Yx(H3(this,16),26)||xat,n),t,e)},Fjn.lh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==pB(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==pB(this.q).i);case 10:return 0==(this.Bb&DNn);case 11:return 0!=(this.Bb&FDn);case 12:return 0!=(this.Bb&nMn);case 13:return null!=this.j;case 14:return null!=Pbn(this);case 15:return 0!=(this.Bb&_Dn);case 16:return 0!=(this.Bb&MEn);case 17:return!!HG(this);case 18:return 0!=(this.Bb&MNn);case 19:return!!(t=nin(this))&&0!=(t.Bb&MNn);case 20:return 0==(this.Bb&eMn);case 21:return!!this.b;case 22:return!!dV(this);case 23:return!!this.a&&0!=this.a.i}return xX(this,n-vF((xjn(),xat)),CZ(Yx(H3(this,16),26)||xat,n))},Fjn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void yz(this,lL(t));case 2:return void s9(this,ny(hL(t)));case 3:return void l9(this,ny(hL(t)));case 4:return void _1(this,Yx(t,19).a);case 5:return void F1(this,Yx(t,19).a);case 8:return void a8(this,Yx(t,138));case 9:return void((e=fun(this,Yx(t,87),null))&&e.Fi());case 10:return void x9(this,ny(hL(t)));case 11:return void K9(this,ny(hL(t)));case 12:return void D9(this,ny(hL(t)));case 13:return void ZP(this,lL(t));case 15:return void R9(this,ny(hL(t)));case 16:return void H9(this,ny(hL(t)));case 18:return void function(n,t){G9(n,t),CO(n.Cb,88)&&rhn(bV(Yx(n.Cb,88)),2)}(this,ny(hL(t)));case 20:return void z9(this,ny(hL(t)));case 21:return void Q0(this,Yx(t,18));case 23:return!this.a&&(this.a=new JO(eat,this,23)),Hmn(this.a),!this.a&&(this.a=new JO(eat,this,23)),void jF(this.a,Yx(t,14))}E7(this,n-vF((xjn(),xat)),CZ(Yx(H3(this,16),26)||xat,n),t)},Fjn.zh=function(){return xjn(),xat},Fjn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return CO(this.Cb,88)&&rhn(bV(Yx(this.Cb,88)),4),void E2(this,null);case 2:return void s9(this,!0);case 3:return void l9(this,!0);case 4:return void _1(this,0);case 5:return void F1(this,1);case 8:return void a8(this,null);case 9:return void((t=fun(this,null,null))&&t.Fi());case 10:return void x9(this,!0);case 11:return void K9(this,!1);case 12:return void D9(this,!1);case 13:return this.i=null,void J0(this,null);case 15:return void R9(this,!1);case 16:return void H9(this,!1);case 18:return G9(this,!1),void(CO(this.Cb,88)&&rhn(bV(Yx(this.Cb,88)),2));case 20:return void z9(this,!0);case 21:return void Q0(this,null);case 23:return!this.a&&(this.a=new JO(eat,this,23)),void Hmn(this.a)}r9(this,n-vF((xjn(),xat)),CZ(Yx(H3(this,16),26)||xat,n))},Fjn.Gh=function(){O5(this),nH(PJ((wsn(),wut),this)),fcn(this),this.Bb|=1},Fjn.Lj=function(){return nin(this)},Fjn.qk=function(){var n;return!!(n=nin(this))&&0!=(n.Bb&MNn)},Fjn.rk=function(){return 0!=(this.Bb&MNn)},Fjn.sk=function(){return 0!=(this.Bb&eMn)},Fjn.nk=function(n,t){return this.c=null,z8(this,n,t)},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?Qdn(this):((n=new MA(Qdn(this))).a+=" (containment: ",nj(n,0!=(this.Bb&MNn)),n.a+=", resolveProxies: ",nj(n,0!=(this.Bb&eMn)),n.a+=")",n.a)},EF(PNn,"EReferenceImpl",99),Wfn(548,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,548:1,114:1,115:1},Ao),Fjn.Fb=function(n){return this===n},Fjn.cd=function(){return this.b},Fjn.dd=function(){return this.c},Fjn.Hb=function(){return _A(this)},Fjn.Uh=function(n){!function(n,t){R0(n,null==t?null:(vB(t),t))}(this,lL(n))},Fjn.ed=function(n){return function(n,t){var e;return e=n.c,K0(n,t),e}(this,lL(n))},Fjn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return RY(this,n-vF((xjn(),Dat)),CZ(Yx(H3(this,16),26)||Dat,n),t,e)},Fjn.lh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return xX(this,n-vF((xjn(),Dat)),CZ(Yx(H3(this,16),26)||Dat,n))},Fjn.sh=function(n,t){switch(n){case 0:return void function(n,t){R0(n,null==t?null:(vB(t),t))}(this,lL(t));case 1:return void K0(this,lL(t))}E7(this,n-vF((xjn(),Dat)),CZ(Yx(H3(this,16),26)||Dat,n),t)},Fjn.zh=function(){return xjn(),Dat},Fjn.Bh=function(n){switch(n){case 0:return void R0(this,null);case 1:return void K0(this,null)}r9(this,n-vF((xjn(),Dat)),CZ(Yx(H3(this,16),26)||Dat,n))},Fjn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:Xen(n)),this.a},Fjn.Th=function(n){this.a=n},Fjn.Ib=function(){var n;return 0!=(64&this.Db)?Kln(this):((n=new MA(Kln(this))).a+=" (key: ",pI(n,this.b),n.a+=", value: ",pI(n,this.c),n.a+=")",n.a)},Fjn.a=-1,Fjn.b=null,Fjn.c=null;var Jat,Zat,nut,tut,eut,iut,rut,cut,aut,uut,out=EF(PNn,"EStringToStringMapEntryImpl",548),sut=aR(xDn,"FeatureMap/Entry/Internal");Wfn(565,1,aRn),Fjn.Ok=function(n){return this.Pk(Yx(n,49))},Fjn.Pk=function(n){return this.Ok(n)},Fjn.Fb=function(n){var t,e;return this===n||!!CO(n,72)&&(t=Yx(n,72)).ak()==this.c&&(null==(e=this.dd())?null==t.dd():Q8(e,t.dd()))},Fjn.ak=function(){return this.c},Fjn.Hb=function(){var n;return n=this.dd(),W5(this.c)^(null==n?0:W5(n))},Fjn.Ib=function(){var n,t;return t=i1((n=this.c).Hj()).Ph(),n.ne(),(null!=t&&0!=t.length?t+":"+n.ne():n.ne())+"="+this.dd()},EF(PNn,"EStructuralFeatureImpl/BasicFeatureMapEntry",565),Wfn(776,565,aRn,FL),Fjn.Pk=function(n){return new FL(this.c,n)},Fjn.dd=function(){return this.a},Fjn.Qk=function(n,t,e){return function(n,t,e,i,r){var c;return e&&(c=tnn(t.Tg(),n.c),r=e.gh(t,-1-(-1==c?i:c),null,r)),r}(this,n,this.a,t,e)},Fjn.Rk=function(n,t,e){return function(n,t,e,i,r){var c;return e&&(c=tnn(t.Tg(),n.c),r=e.ih(t,-1-(-1==c?i:c),null,r)),r}(this,n,this.a,t,e)},EF(PNn,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",776),Wfn(1314,1,{},zP),Fjn.Pj=function(n,t,e,i,r){return Yx(TY(n,this.b),215).nl(this.a).Wj(i)},Fjn.Qj=function(n,t,e,i,r){return Yx(TY(n,this.b),215).el(this.a,i,r)},Fjn.Rj=function(n,t,e,i,r){return Yx(TY(n,this.b),215).fl(this.a,i,r)},Fjn.Sj=function(n,t,e){return Yx(TY(n,this.b),215).nl(this.a).fj()},Fjn.Tj=function(n,t,e,i){Yx(TY(n,this.b),215).nl(this.a).Wb(i)},Fjn.Uj=function(n,t,e){return Yx(TY(n,this.b),215).nl(this.a)},Fjn.Vj=function(n,t,e){Yx(TY(n,this.b),215).nl(this.a).Xj()},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1314),Wfn(89,1,{},_x,LH,Hq,sW),Fjn.Pj=function(n,t,e,i,r){var c;if(null==(c=t.Ch(e))&&t.Dh(e,c=Mjn(this,n)),!r)switch(this.e){case 50:case 41:return Yx(c,589).sj();case 40:return Yx(c,215).kl()}return c},Fjn.Qj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))&&t.Dh(e,c=Mjn(this,n)),Yx(c,69).lk(i,r)},Fjn.Rj=function(n,t,e,i,r){var c;return null!=(c=t.Ch(e))&&(r=Yx(c,69).mk(i,r)),r},Fjn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&Yx(i,76).fj()},Fjn.Tj=function(n,t,e,i){var r;!(r=Yx(t.Ch(e),76))&&t.Dh(e,r=Mjn(this,n)),r.Wb(i)},Fjn.Uj=function(n,t,e){var i;return null==(i=t.Ch(e))&&t.Dh(e,i=Mjn(this,n)),CO(i,76)?Yx(i,76):new Ug(Yx(t.Ch(e),15))},Fjn.Vj=function(n,t,e){var i;!(i=Yx(t.Ch(e),76))&&t.Dh(e,i=Mjn(this,n)),i.Xj()},Fjn.b=0,Fjn.e=0,EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateMany",89),Wfn(504,1,{}),Fjn.Qj=function(n,t,e,i,r){throw hp(new xp)},Fjn.Rj=function(n,t,e,i,r){throw hp(new xp)},Fjn.Uj=function(n,t,e){return new NH(this,n,t,e)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingle",504),Wfn(1331,1,DDn,NH),Fjn.Wj=function(n){return this.a.Pj(this.c,this.d,this.b,n,!0)},Fjn.fj=function(){return this.a.Sj(this.c,this.d,this.b)},Fjn.Wb=function(n){this.a.Tj(this.c,this.d,this.b,n)},Fjn.Xj=function(){this.a.Vj(this.c,this.d,this.b)},Fjn.b=0,EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1331),Wfn(769,504,{},tG),Fjn.Pj=function(n,t,e,i,r){return Ign(n,n.eh(),n.Vg())==this.b?this.sk()&&i?Bfn(n):n.eh():null},Fjn.Qj=function(n,t,e,i,r){var c,a;return n.eh()&&(r=(c=n.Vg())>=0?n.Qg(r):n.eh().ih(n,-1-c,null,r)),a=tnn(n.Tg(),this.e),n.Sg(i,a,r)},Fjn.Rj=function(n,t,e,i,r){var c;return c=tnn(n.Tg(),this.e),n.Sg(null,c,r)},Fjn.Sj=function(n,t,e){var i;return i=tnn(n.Tg(),this.e),!!n.eh()&&n.Vg()==i},Fjn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!Ypn(this.a,i))throw hp(new Vm(uRn+(CO(i,56)?gan(Yx(i,56).Tg()):LZ(V5(i)))+oRn+this.a+"'"));if(r=n.eh(),a=tnn(n.Tg(),this.e),iI(i)!==iI(r)||n.Vg()!=a&&null!=i){if(ccn(n,Yx(i,56)))throw hp(new Qm(CNn+n.Ib()));o=null,r&&(o=(c=n.Vg())>=0?n.Qg(o):n.eh().ih(n,-1-c,null,o)),(u=Yx(i,49))&&(o=u.gh(n,tnn(u.Tg(),this.b),null,o)),(o=n.Sg(u,a,o))&&o.Fi()}else n.Lg()&&n.Mg()&&K3(n,new p_(n,1,a,i,i))},Fjn.Vj=function(n,t,e){var i,r,c;n.eh()?(c=(i=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-i,null,null),r=tnn(n.Tg(),this.e),(c=n.Sg(null,r,c))&&c.Fi()):n.Lg()&&n.Mg()&&K3(n,new v_(n,1,this.e,null,null))},Fjn.sk=function(){return!1},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",769),Wfn(1315,769,{},Fx),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1315),Wfn(563,504,{}),Fjn.Pj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))?this.b:iI(c)===iI(Jat)?null:c},Fjn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&(iI(i)===iI(Jat)||!Q8(i,this.b))},Fjn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=null==(c=t.Ch(e))?this.b:iI(c)===iI(Jat)?null:c,null==i?null!=this.c?(t.Dh(e,null),i=this.b):null!=this.b?t.Dh(e,Jat):t.Dh(e,null):(this.Sk(i),t.Dh(e,i)),K3(n,this.d.Tk(n,1,this.e,r,i))):null==i?null!=this.c?t.Dh(e,null):null!=this.b?t.Dh(e,Jat):t.Dh(e,null):(this.Sk(i),t.Dh(e,i))},Fjn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=null==(r=t.Ch(e))?this.b:iI(r)===iI(Jat)?null:r,t.Eh(e),K3(n,this.d.Tk(n,1,this.e,i,this.b))):t.Eh(e)},Fjn.Sk=function(n){throw hp(new Ap)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",563),Wfn(sRn,1,{},$o),Fjn.Tk=function(n,t,e,i,r){return new v_(n,t,e,i,r)},Fjn.Uk=function(n,t,e,i,r,c){return new tq(n,t,e,i,r,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",sRn),Wfn(1332,sRn,{},Lo),Fjn.Tk=function(n,t,e,i,r){return new CV(n,t,e,ny(hL(i)),ny(hL(r)))},Fjn.Uk=function(n,t,e,i,r,c){return new bU(n,t,e,ny(hL(i)),ny(hL(r)),c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1332),Wfn(1333,sRn,{},No),Fjn.Tk=function(n,t,e,i,r){return new W1(n,t,e,Yx(i,217).a,Yx(r,217).a)},Fjn.Uk=function(n,t,e,i,r,c){return new aU(n,t,e,Yx(i,217).a,Yx(r,217).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1333),Wfn(1334,sRn,{},xo),Fjn.Tk=function(n,t,e,i,r){return new V1(n,t,e,Yx(i,172).a,Yx(r,172).a)},Fjn.Uk=function(n,t,e,i,r,c){return new uU(n,t,e,Yx(i,172).a,Yx(r,172).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1334),Wfn(1335,sRn,{},Do),Fjn.Tk=function(n,t,e,i,r){return new PV(n,t,e,ty(fL(i)),ty(fL(r)))},Fjn.Uk=function(n,t,e,i,r,c){return new oU(n,t,e,ty(fL(i)),ty(fL(r)),c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1335),Wfn(1336,sRn,{},Ro),Fjn.Tk=function(n,t,e,i,r){return new J1(n,t,e,Yx(i,155).a,Yx(r,155).a)},Fjn.Uk=function(n,t,e,i,r,c){return new sU(n,t,e,Yx(i,155).a,Yx(r,155).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1336),Wfn(1337,sRn,{},Ko),Fjn.Tk=function(n,t,e,i,r){return new IV(n,t,e,Yx(i,19).a,Yx(r,19).a)},Fjn.Uk=function(n,t,e,i,r,c){return new hU(n,t,e,Yx(i,19).a,Yx(r,19).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1337),Wfn(1338,sRn,{},_o),Fjn.Tk=function(n,t,e,i,r){return new Q1(n,t,e,Yx(i,162).a,Yx(r,162).a)},Fjn.Uk=function(n,t,e,i,r,c){return new fU(n,t,e,Yx(i,162).a,Yx(r,162).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1338),Wfn(1339,sRn,{},Fo),Fjn.Tk=function(n,t,e,i,r){return new Y1(n,t,e,Yx(i,184).a,Yx(r,184).a)},Fjn.Uk=function(n,t,e,i,r,c){return new lU(n,t,e,Yx(i,184).a,Yx(r,184).a,c)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1339),Wfn(1317,563,{},xH),Fjn.Sk=function(n){if(!this.a.wj(n))throw hp(new Vm(uRn+V5(n)+oRn+this.a+"'"))},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1317),Wfn(1318,563,{},MK),Fjn.Sk=function(n){},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1318),Wfn(770,563,{}),Fjn.Sj=function(n,t,e){return null!=t.Ch(e)},Fjn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=!0,null==(c=t.Ch(e))?(r=!1,c=this.b):iI(c)===iI(Jat)&&(c=null),null==i?null!=this.c?(t.Dh(e,null),i=this.b):t.Dh(e,Jat):(this.Sk(i),t.Dh(e,i)),K3(n,this.d.Uk(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.Dh(e,null):t.Dh(e,Jat):(this.Sk(i),t.Dh(e,i))},Fjn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=!0,null==(r=t.Ch(e))?(i=!1,r=this.b):iI(r)===iI(Jat)&&(r=null),t.Eh(e),K3(n,this.d.Uk(n,2,this.e,r,this.b,i))):t.Eh(e)},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",770),Wfn(1319,770,{},DH),Fjn.Sk=function(n){if(!this.a.wj(n))throw hp(new Vm(uRn+V5(n)+oRn+this.a+"'"))},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1319),Wfn(1320,770,{},SK),Fjn.Sk=function(n){},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1320),Wfn(398,504,{},KR),Fjn.Pj=function(n,t,e,i,r){var c,a,u,o,s;if(s=t.Ch(e),this.Kj()&&iI(s)===iI(Jat))return null;if(this.sk()&&i&&null!=s){if((u=Yx(s,49)).kh()&&u!=(o=P8(n,u))){if(!Ypn(this.a,o))throw hp(new Vm(uRn+V5(o)+oRn+this.a+"'"));t.Dh(e,s=o),this.rk()&&(c=Yx(o,49),a=u.ih(n,this.b?tnn(u.Tg(),this.b):-1-tnn(n.Tg(),this.e),null,null),!c.eh()&&(a=c.gh(n,this.b?tnn(c.Tg(),this.b):-1-tnn(n.Tg(),this.e),null,a)),a&&a.Fi()),n.Lg()&&n.Mg()&&K3(n,new v_(n,9,this.e,u,o))}return s}return s},Fjn.Qj=function(n,t,e,i,r){var c,a;return iI(a=t.Ch(e))===iI(Jat)&&(a=null),t.Dh(e,i),this.bj()?iI(a)!==iI(i)&&null!=a&&(r=(c=Yx(a,49)).ih(n,tnn(c.Tg(),this.b),null,r)):this.rk()&&null!=a&&(r=Yx(a,49).ih(n,-1-tnn(n.Tg(),this.e),null,r)),n.Lg()&&n.Mg()&&(!r&&(r=new Ek(4)),r.Ei(new v_(n,1,this.e,a,i))),r},Fjn.Rj=function(n,t,e,i,r){var c;return iI(c=t.Ch(e))===iI(Jat)&&(c=null),t.Eh(e),n.Lg()&&n.Mg()&&(!r&&(r=new Ek(4)),this.Kj()?r.Ei(new v_(n,2,this.e,c,null)):r.Ei(new v_(n,1,this.e,c,null))),r},Fjn.Sj=function(n,t,e){return null!=t.Ch(e)},Fjn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!Ypn(this.a,i))throw hp(new Vm(uRn+(CO(i,56)?gan(Yx(i,56).Tg()):LZ(V5(i)))+oRn+this.a+"'"));u=null!=(o=t.Ch(e)),this.Kj()&&iI(o)===iI(Jat)&&(o=null),a=null,this.bj()?iI(o)!==iI(i)&&(null!=o&&(a=(r=Yx(o,49)).ih(n,tnn(r.Tg(),this.b),null,a)),null!=i&&(a=(r=Yx(i,49)).gh(n,tnn(r.Tg(),this.b),null,a))):this.rk()&&iI(o)!==iI(i)&&(null!=o&&(a=Yx(o,49).ih(n,-1-tnn(n.Tg(),this.e),null,a)),null!=i&&(a=Yx(i,49).gh(n,-1-tnn(n.Tg(),this.e),null,a))),null==i&&this.Kj()?t.Dh(e,Jat):t.Dh(e,i),n.Lg()&&n.Mg()?(c=new tq(n,1,this.e,o,i,this.Kj()&&!u),a?(a.Ei(c),a.Fi()):K3(n,c)):a&&a.Fi()},Fjn.Vj=function(n,t,e){var i,r,c,a,u;a=null!=(u=t.Ch(e)),this.Kj()&&iI(u)===iI(Jat)&&(u=null),c=null,null!=u&&(this.bj()?c=(i=Yx(u,49)).ih(n,tnn(i.Tg(),this.b),null,c):this.rk()&&(c=Yx(u,49).ih(n,-1-tnn(n.Tg(),this.e),null,c))),t.Eh(e),n.Lg()&&n.Mg()?(r=new tq(n,this.Kj()?2:1,this.e,u,null,a),c?(c.Ei(r),c.Fi()):K3(n,r)):c&&c.Fi()},Fjn.bj=function(){return!1},Fjn.rk=function(){return!1},Fjn.sk=function(){return!1},Fjn.Kj=function(){return!1},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",398),Wfn(564,398,{},U$),Fjn.rk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",564),Wfn(1323,564,{},X$),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1323),Wfn(772,564,{},W$),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",772),Wfn(1325,772,{},V$),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1325),Wfn(640,564,{},Bx),Fjn.bj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",640),Wfn(1324,640,{},Gx),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1324),Wfn(773,640,{},zx),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",773),Wfn(1326,773,{},Ux),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1326),Wfn(641,398,{},Q$),Fjn.sk=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",641),Wfn(1327,641,{},Y$),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1327),Wfn(774,641,{},Hx),Fjn.bj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",774),Wfn(1328,774,{},Xx),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1328),Wfn(1321,398,{},J$),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1321),Wfn(771,398,{},qx),Fjn.bj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",771),Wfn(1322,771,{},Wx),Fjn.Kj=function(){return!0},EF(PNn,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1322),Wfn(775,565,aRn,cB),Fjn.Pk=function(n){return new cB(this.a,this.c,n)},Fjn.dd=function(){return this.b},Fjn.Qk=function(n,t,e){return function(n,t,e,i){return e&&(i=e.gh(t,tnn(e.Tg(),n.c.Lj()),null,i)),i}(this,n,this.b,e)},Fjn.Rk=function(n,t,e){return function(n,t,e,i){return e&&(i=e.ih(t,tnn(e.Tg(),n.c.Lj()),null,i)),i}(this,n,this.b,e)},EF(PNn,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",775),Wfn(1329,1,DDn,Ug),Fjn.Wj=function(n){return this.a},Fjn.fj=function(){return CO(this.a,95)?Yx(this.a,95).fj():!this.a.dc()},Fjn.Wb=function(n){this.a.$b(),this.a.Gc(Yx(n,15))},Fjn.Xj=function(){CO(this.a,95)?Yx(this.a,95).Xj():this.a.$b()},EF(PNn,"EStructuralFeatureImpl/SettingMany",1329),Wfn(1330,565,aRn,fW),Fjn.Ok=function(n){return new BL((ayn(),tot),this.b.Ih(this.a,n))},Fjn.dd=function(){return null},Fjn.Qk=function(n,t,e){return e},Fjn.Rk=function(n,t,e){return e},EF(PNn,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1330),Wfn(642,565,aRn,BL),Fjn.Ok=function(n){return new BL(this.c,n)},Fjn.dd=function(){return this.a},Fjn.Qk=function(n,t,e){return e},Fjn.Rk=function(n,t,e){return e},EF(PNn,"EStructuralFeatureImpl/SimpleFeatureMapEntry",642),Wfn(391,497,Mxn,Bo),Fjn.ri=function(n){return VQ(rat,iEn,26,n,0,1)},Fjn.ni=function(){return!1},EF(PNn,"ESuperAdapter/1",391),Wfn(444,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,836:1,49:1,97:1,150:1,444:1,114:1,115:1},Ho),Fjn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new _R(this,hat,this)),this.a}return RY(this,n-vF((xjn(),_at)),CZ(Yx(H3(this,16),26)||_at,n),t,e)},Fjn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Ten(this.Ab,n,e);case 2:return!this.a&&(this.a=new _R(this,hat,this)),Ten(this.a,n,e)}return Yx(CZ(Yx(H3(this,16),26)||(xjn(),_at),t),66).Nj().Rj(this,dtn(this),t-vF((xjn(),_at)),n,e)},Fjn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return xX(this,n-vF((xjn(),_at)),CZ(Yx(H3(this,16),26)||_at,n))},Fjn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),Hmn(this.Ab),!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void jF(this.Ab,Yx(t,14));case 1:return void E2(this,lL(t));case 2:return!this.a&&(this.a=new _R(this,hat,this)),Hmn(this.a),!this.a&&(this.a=new _R(this,hat,this)),void jF(this.a,Yx(t,14))}E7(this,n-vF((xjn(),_at)),CZ(Yx(H3(this,16),26)||_at,n),t)},Fjn.zh=function(){return xjn(),_at},Fjn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new m_(Zct,this,0,3)),void Hmn(this.Ab);case 1:return void E2(this,null);case 2:return!this.a&&(this.a=new _R(this,hat,this)),void Hmn(this.a)}r9(this,n-vF((xjn(),_at)),CZ(Yx(H3(this,16),26)||_at,n))},EF(PNn,"ETypeParameterImpl",444),Wfn(445,85,JDn,_R),Fjn.cj=function(n,t){return function(n,t,e){var i,r;for(e=men(t,n.e,-1-n.c,e),r=new Wg(new t6(new Ql(EB(n.a).a).a));r.a.b;)e=zyn(i=Yx(s1(r.a).cd(),87),dbn(i,n.a),e);return e}(this,Yx(n,87),t)},Fjn.dj=function(n,t){return function(n,t,e){var i,r;for(e=Uq(t,n.e,-1-n.c,e),r=new Wg(new t6(new Ql(EB(n.a).a).a));r.a.b;)e=zyn(i=Yx(s1(r.a).cd(),87),dbn(i,n.a),e);return e}(this,Yx(n,87),t)},EF(PNn,"ETypeParameterImpl/1",445),Wfn(634,43,gMn,Wv),Fjn.ec=function(){return new Xg(this)},EF(PNn,"ETypeParameterImpl/2",634),Wfn(556,dEn,gEn,Xg),Fjn.Fc=function(n){return kN(this,Yx(n,87))},Fjn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=Yx(e.Pb(),87),null==xB(this.a,t,"")&&(i=!0);return i},Fjn.$b=function(){U_(this.a)},Fjn.Hc=function(n){return P_(this.a,n)},Fjn.Kc=function(){return new Wg(new t6(new Ql(this.a).a))},Fjn.Mc=function(n){return hQ(this,n)},Fjn.gc=function(){return hE(this.a)},EF(PNn,"ETypeParameterImpl/2/1",556),Wfn(557,1,fEn,Wg),Fjn.Nb=function(n){I_(this,n)},Fjn.Pb=function(){return Yx(s1(this.a).cd(),87)},Fjn.Ob=function(){return this.a.b},Fjn.Qb=function(){oY(this.a)},EF(PNn,"ETypeParameterImpl/2/1/1",557),Wfn(1276,43,gMn,Vv),Fjn._b=function(n){return aI(n)?hq(this,n):!!Dq(this.f,n)},Fjn.xc=function(n){var t;return CO(t=aI(n)?aG(this,n):eI(Dq(this.f,n)),837)?(t=Yx(t,837)._j(),xB(this,Yx(n,235),t),t):null!=t?t:null==n?(ET(),mut):null},EF(PNn,"EValidatorRegistryImpl",1276),Wfn(1313,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,1941:1,49:1,97:1,150:1,114:1,115:1},qo),Fjn.Ih=function(n,t){switch(n.yj()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:I7(t);case 25:return r1(t);case 27:case 28:return function(n){return CO(n,172)?""+Yx(n,172).a:null==n?null:I7(n)}(t);case 29:return null==t?null:gO(Grt[0],Yx(t,199));case 41:return null==t?"":Nk(Yx(t,290));case 42:return I7(t);case 50:return lL(t);default:throw hp(new Qm(ONn+n.ne()+ANn))}},Fjn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=i1(n))?Ren(t.Mh(),n):-1),n.G){case 0:return new qv;case 1:return new jo;case 2:return new Rf;case 4:return new Bp;case 5:return new Gv;case 6:return new Fp;case 7:return new xf;case 10:return new yo;case 11:return new zv;case 12:return new Sq;case 13:return new Uv;case 14:return new cL;case 17:return new Ao;case 18:return new up;case 19:return new Ho;default:throw hp(new Qm(NNn+n.zb+ANn))}},Fjn.Kh=function(n,t){switch(n.yj()){case 20:return null==t?null:new Wk(t);case 21:return null==t?null:new IC(t);case 23:case 22:return null==t?null:function(n){if(vtn(kLn,n))return TA(),L_n;if(vtn(jLn,n))return TA(),$_n;throw hp(new Qm("Expecting true or false"))}(t);case 26:case 24:return null==t?null:iZ(ipn(t,-128,127)<<24>>24);case 25:return function(n){var t,e,i,r,c,a,u;if(null==n)return null;for(u=n.length,a=VQ(Yot,LNn,25,r=(u+1)/2|0,15,1),u%2!=0&&(a[--r]=Odn((Lz(u-1,n.length),n.charCodeAt(u-1)))),e=0,i=0;e>24;return a}(t);case 27:return function(n){var t;if(null==n)return null;t=0;try{t=ipn(n,nTn,Yjn)&fTn}catch(e){if(!CO(e=j4(e),127))throw hp(e);t=xJ(n)[0]}return k4(t)}(t);case 28:return function(n){var t;if(null==n)return null;t=0;try{t=ipn(n,nTn,Yjn)&fTn}catch(e){if(!CO(e=j4(e),127))throw hp(e);t=xJ(n)[0]}return k4(t)}(t);case 29:return function(n){var t,e;if(null==n)return null;for(t=null,e=0;e>16);case 50:return t;default:throw hp(new Qm(ONn+n.ne()+ANn))}},EF(PNn,"EcoreFactoryImpl",1313),Wfn(547,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,1939:1,49:1,97:1,150:1,179:1,547:1,114:1,115:1,675:1},$B),Fjn.gb=!1,Fjn.hb=!1;var hut,fut=!1;EF(PNn,"EcorePackageImpl",547),Wfn(1184,1,{837:1},Go),Fjn._j=function(){return EA(),yut},EF(PNn,"EcorePackageImpl/1",1184),Wfn(1193,1,TRn,zo),Fjn.wj=function(n){return CO(n,147)},Fjn.xj=function(n){return VQ(ect,iEn,147,n,0,1)},EF(PNn,"EcorePackageImpl/10",1193),Wfn(1194,1,TRn,Uo),Fjn.wj=function(n){return CO(n,191)},Fjn.xj=function(n){return VQ(rct,iEn,191,n,0,1)},EF(PNn,"EcorePackageImpl/11",1194),Wfn(1195,1,TRn,Xo),Fjn.wj=function(n){return CO(n,56)},Fjn.xj=function(n){return VQ(Wrt,iEn,56,n,0,1)},EF(PNn,"EcorePackageImpl/12",1195),Wfn(1196,1,TRn,Wo),Fjn.wj=function(n){return CO(n,399)},Fjn.xj=function(n){return VQ(fat,QDn,59,n,0,1)},EF(PNn,"EcorePackageImpl/13",1196),Wfn(1197,1,TRn,Vo),Fjn.wj=function(n){return CO(n,235)},Fjn.xj=function(n){return VQ(cct,iEn,235,n,0,1)},EF(PNn,"EcorePackageImpl/14",1197),Wfn(1198,1,TRn,Qo),Fjn.wj=function(n){return CO(n,509)},Fjn.xj=function(n){return VQ(lat,iEn,2017,n,0,1)},EF(PNn,"EcorePackageImpl/15",1198),Wfn(1199,1,TRn,Yo),Fjn.wj=function(n){return CO(n,99)},Fjn.xj=function(n){return VQ(bat,VDn,18,n,0,1)},EF(PNn,"EcorePackageImpl/16",1199),Wfn(1200,1,TRn,Jo),Fjn.wj=function(n){return CO(n,170)},Fjn.xj=function(n){return VQ(tat,VDn,170,n,0,1)},EF(PNn,"EcorePackageImpl/17",1200),Wfn(1201,1,TRn,Zo),Fjn.wj=function(n){return CO(n,472)},Fjn.xj=function(n){return VQ(nat,iEn,472,n,0,1)},EF(PNn,"EcorePackageImpl/18",1201),Wfn(1202,1,TRn,ns),Fjn.wj=function(n){return CO(n,548)},Fjn.xj=function(n){return VQ(out,kDn,548,n,0,1)},EF(PNn,"EcorePackageImpl/19",1202),Wfn(1185,1,TRn,ts),Fjn.wj=function(n){return CO(n,322)},Fjn.xj=function(n){return VQ(eat,VDn,34,n,0,1)},EF(PNn,"EcorePackageImpl/2",1185),Wfn(1203,1,TRn,es),Fjn.wj=function(n){return CO(n,241)},Fjn.xj=function(n){return VQ(hat,eRn,87,n,0,1)},EF(PNn,"EcorePackageImpl/20",1203),Wfn(1204,1,TRn,is),Fjn.wj=function(n){return CO(n,444)},Fjn.xj=function(n){return VQ(zat,iEn,836,n,0,1)},EF(PNn,"EcorePackageImpl/21",1204),Wfn(1205,1,TRn,rs),Fjn.wj=function(n){return rI(n)},Fjn.xj=function(n){return VQ(D_n,TEn,476,n,8,1)},EF(PNn,"EcorePackageImpl/22",1205),Wfn(1206,1,TRn,cs),Fjn.wj=function(n){return CO(n,190)},Fjn.xj=function(n){return VQ(Yot,TEn,190,n,0,2)},EF(PNn,"EcorePackageImpl/23",1206),Wfn(1207,1,TRn,as),Fjn.wj=function(n){return CO(n,217)},Fjn.xj=function(n){return VQ(__n,TEn,217,n,0,1)},EF(PNn,"EcorePackageImpl/24",1207),Wfn(1208,1,TRn,us),Fjn.wj=function(n){return CO(n,172)},Fjn.xj=function(n){return VQ(B_n,TEn,172,n,0,1)},EF(PNn,"EcorePackageImpl/25",1208),Wfn(1209,1,TRn,os),Fjn.wj=function(n){return CO(n,199)},Fjn.xj=function(n){return VQ(N_n,TEn,199,n,0,1)},EF(PNn,"EcorePackageImpl/26",1209),Wfn(1210,1,TRn,ss),Fjn.wj=function(n){return!1},Fjn.xj=function(n){return VQ(est,iEn,2110,n,0,1)},EF(PNn,"EcorePackageImpl/27",1210),Wfn(1211,1,TRn,hs),Fjn.wj=function(n){return cI(n)},Fjn.xj=function(n){return VQ(H_n,TEn,333,n,7,1)},EF(PNn,"EcorePackageImpl/28",1211),Wfn(1212,1,TRn,fs),Fjn.wj=function(n){return CO(n,58)},Fjn.xj=function(n){return VQ(jct,dPn,58,n,0,1)},EF(PNn,"EcorePackageImpl/29",1212),Wfn(1186,1,TRn,ls),Fjn.wj=function(n){return CO(n,510)},Fjn.xj=function(n){return VQ(Zct,{3:1,4:1,5:1,1934:1},590,n,0,1)},EF(PNn,"EcorePackageImpl/3",1186),Wfn(1213,1,TRn,bs),Fjn.wj=function(n){return CO(n,573)},Fjn.xj=function(n){return VQ(xct,iEn,1940,n,0,1)},EF(PNn,"EcorePackageImpl/30",1213),Wfn(1214,1,TRn,ws),Fjn.wj=function(n){return CO(n,153)},Fjn.xj=function(n){return VQ(Eut,dPn,153,n,0,1)},EF(PNn,"EcorePackageImpl/31",1214),Wfn(1215,1,TRn,ds),Fjn.wj=function(n){return CO(n,72)},Fjn.xj=function(n){return VQ(Xat,MRn,72,n,0,1)},EF(PNn,"EcorePackageImpl/32",1215),Wfn(1216,1,TRn,gs),Fjn.wj=function(n){return CO(n,155)},Fjn.xj=function(n){return VQ(q_n,TEn,155,n,0,1)},EF(PNn,"EcorePackageImpl/33",1216),Wfn(1217,1,TRn,ps),Fjn.wj=function(n){return CO(n,19)},Fjn.xj=function(n){return VQ(U_n,TEn,19,n,0,1)},EF(PNn,"EcorePackageImpl/34",1217),Wfn(1218,1,TRn,vs),Fjn.wj=function(n){return CO(n,290)},Fjn.xj=function(n){return VQ(XKn,iEn,290,n,0,1)},EF(PNn,"EcorePackageImpl/35",1218),Wfn(1219,1,TRn,ms),Fjn.wj=function(n){return CO(n,162)},Fjn.xj=function(n){return VQ(J_n,TEn,162,n,0,1)},EF(PNn,"EcorePackageImpl/36",1219),Wfn(1220,1,TRn,ys),Fjn.wj=function(n){return CO(n,83)},Fjn.xj=function(n){return VQ(VKn,iEn,83,n,0,1)},EF(PNn,"EcorePackageImpl/37",1220),Wfn(1221,1,TRn,ks),Fjn.wj=function(n){return CO(n,591)},Fjn.xj=function(n){return VQ(vut,iEn,591,n,0,1)},EF(PNn,"EcorePackageImpl/38",1221),Wfn(1222,1,TRn,js),Fjn.wj=function(n){return!1},Fjn.xj=function(n){return VQ(ist,iEn,2111,n,0,1)},EF(PNn,"EcorePackageImpl/39",1222),Wfn(1187,1,TRn,Es),Fjn.wj=function(n){return CO(n,88)},Fjn.xj=function(n){return VQ(rat,iEn,26,n,0,1)},EF(PNn,"EcorePackageImpl/4",1187),Wfn(1223,1,TRn,Ts),Fjn.wj=function(n){return CO(n,184)},Fjn.xj=function(n){return VQ(nFn,TEn,184,n,0,1)},EF(PNn,"EcorePackageImpl/40",1223),Wfn(1224,1,TRn,Ms),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(PNn,"EcorePackageImpl/41",1224),Wfn(1225,1,TRn,Ss),Fjn.wj=function(n){return CO(n,588)},Fjn.xj=function(n){return VQ(Tct,iEn,588,n,0,1)},EF(PNn,"EcorePackageImpl/42",1225),Wfn(1226,1,TRn,Ps),Fjn.wj=function(n){return!1},Fjn.xj=function(n){return VQ(rst,TEn,2112,n,0,1)},EF(PNn,"EcorePackageImpl/43",1226),Wfn(1227,1,TRn,Is),Fjn.wj=function(n){return CO(n,42)},Fjn.xj=function(n){return VQ(i_n,DEn,42,n,0,1)},EF(PNn,"EcorePackageImpl/44",1227),Wfn(1188,1,TRn,Cs),Fjn.wj=function(n){return CO(n,138)},Fjn.xj=function(n){return VQ(iat,iEn,138,n,0,1)},EF(PNn,"EcorePackageImpl/5",1188),Wfn(1189,1,TRn,Os),Fjn.wj=function(n){return CO(n,148)},Fjn.xj=function(n){return VQ(cat,iEn,148,n,0,1)},EF(PNn,"EcorePackageImpl/6",1189),Wfn(1190,1,TRn,As),Fjn.wj=function(n){return CO(n,457)},Fjn.xj=function(n){return VQ(oat,iEn,671,n,0,1)},EF(PNn,"EcorePackageImpl/7",1190),Wfn(1191,1,TRn,$s),Fjn.wj=function(n){return CO(n,573)},Fjn.xj=function(n){return VQ(sat,iEn,678,n,0,1)},EF(PNn,"EcorePackageImpl/8",1191),Wfn(1192,1,TRn,Ls),Fjn.wj=function(n){return CO(n,471)},Fjn.xj=function(n){return VQ(ict,iEn,471,n,0,1)},EF(PNn,"EcorePackageImpl/9",1192),Wfn(1025,1982,mDn,Um),Fjn.bi=function(n,t){!function(n,t){var e,i,r;if(t.vi(n.a),null!=(r=Yx(H3(n.a,8),1936)))for(e=0,i=r.length;e0){if(Lz(0,n.length),47==n.charCodeAt(0)){for(c=new pQ(4),r=1,t=1;t0&&(n=n.substr(0,e))}return function(n,t){var e,i,r,c,a,u;for(c=null,r=new k_((!n.a&&(n.a=new Vg(n)),n.a));ufn(r);)if(emn(a=(e=Yx(abn(r),56)).Tg()),null!=(i=(u=a.o)&&e.mh(u)?RN(v4(u),e.ah(u)):null)&&_N(i,t)){c=e;break}return c}(this,n)},Fjn.Xk=function(){return this.c},Fjn.Ib=function(){return Nk(this.gm)+"@"+(W5(this)>>>0).toString(16)+" uri='"+this.d+"'"},Fjn.b=!1,EF(IRn,"ResourceImpl",781),Wfn(1379,781,PRn,Yg),EF(IRn,"BinaryResourceImpl",1379),Wfn(1169,694,Sxn),Fjn.si=function(n){return CO(n,56)?function(n,t){return n.a?t.Wg().Kc():Yx(t.Wg(),69).Zh()}(this,Yx(n,56)):CO(n,591)?new UO(Yx(n,591).Vk()):iI(n)===iI(this.f)?Yx(n,14).Kc():(iL(),$ct.a)},Fjn.Ob=function(){return ufn(this)},Fjn.a=!1,EF(xDn,"EcoreUtil/ContentTreeIterator",1169),Wfn(1380,1169,Sxn,k_),Fjn.si=function(n){return iI(n)===iI(this.f)?Yx(n,15).Kc():new hX(Yx(n,56))},EF(IRn,"ResourceImpl/5",1380),Wfn(648,1994,YDn,Vg),Fjn.Hc=function(n){return this.i<=4?Fcn(this,n):CO(n,49)&&Yx(n,49).Zg()==this.a},Fjn.bi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},Fjn.di=function(n,t){0==n?this.a.b||(this.a.b=!0):XQ(this,n,t)},Fjn.fi=function(n,t){},Fjn.gi=function(n,t,e){},Fjn.aj=function(){return 2},Fjn.Ai=function(){return this.a},Fjn.bj=function(){return!0},Fjn.cj=function(n,t){return Yx(n,49).wh(this.a,t)},Fjn.dj=function(n,t){return Yx(n,49).wh(null,t)},Fjn.ej=function(){return!1},Fjn.hi=function(){return!0},Fjn.ri=function(n){return VQ(Wrt,iEn,56,n,0,1)},Fjn.ni=function(){return!1},EF(IRn,"ResourceImpl/ContentsEList",648),Wfn(957,1964,WEn,Qg),Fjn.Zc=function(n){return this.a._h(n)},Fjn.gc=function(){return this.a.gc()},EF(xDn,"AbstractSequentialInternalEList/1",957),Wfn(624,1,{},OD),EF(xDn,"BasicExtendedMetaData",624),Wfn(1160,1,{},UP),Fjn.$k=function(){return null},Fjn._k=function(){return-2==this.a&&(n=this,t=function(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=ynn((!e.b&&(e.b=new z$((xjn(),Dat),out,e)),e.b),tRn)))for(i=1;i<(wsn(),lut).length;++i)if(_N(lut[i],r))return i;return 0}(this.d,this.b),n.a=t),this.a;var n,t},Fjn.al=function(){return null},Fjn.bl=function(){return XH(),XH(),TFn},Fjn.ne=function(){return this.c==qRn&&(n=this,t=ktn(this.d,this.b),n.c=t),this.c;var n,t},Fjn.cl=function(){return 0},Fjn.a=-2,Fjn.c=qRn,EF(xDn,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1160),Wfn(1161,1,{},mU),Fjn.$k=function(){return this.a==(wV(),gut)&&function(n,t){n.a=t}(this,(n=this.f,t=this.b,(i=t.Hh(n.a))&&(!i.b&&(i.b=new z$((xjn(),Dat),out,i)),null!=(e=lL(ynn(i.b,bRn)))&&CO(c=-1==(r=e.lastIndexOf("#"))?Z$(n,t.Aj(),e):0==r?EY(n,null,e.substr(1)):EY(n,e.substr(0,r),e.substr(r+1)),148))?Yx(c,148):null)),this.a;var n,t,e,i,r,c},Fjn._k=function(){return 0},Fjn.al=function(){return this.c==(wV(),gut)&&function(n,t){n.c=t}(this,(n=this.f,t=this.b,(e=t.Hh(n.a))&&(!e.b&&(e.b=new z$((xjn(),Dat),out,e)),null!=(r=lL(ynn(e.b,DRn)))&&CO(c=-1==(i=r.lastIndexOf("#"))?Z$(n,t.Aj(),r):0==i?EY(n,null,r.substr(1)):EY(n,r.substr(0,i),r.substr(i+1)),148))?Yx(c,148):null)),this.c;var n,t,e,i,r,c},Fjn.bl=function(){return!this.d&&(n=this,t=function(n,t){var e,i,r,c,a,u,o,s,h;if((e=t.Hh(n.a))&&null!=(o=lL(ynn((!e.b&&(e.b=new z$((xjn(),Dat),out,e)),e.b),"memberTypes")))){for(s=new ip,a=0,u=(c=Ogn(o,"\\w")).length;ae?t:e;s<=f;++s)s==e?u=i++:(c=r[s],h=w.rl(c.ak()),s==t&&(o=s!=f||h?i:i-1),h&&++i);return l=Yx(L9(n,t,e),72),u!=o&&Xp(n,new jY(n.e,7,a,d9(u),b.dd(),o)),l}return Yx(L9(n,t,e),72)}(this,n,t)},Fjn.li=function(n,t){return function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(CO(a=e.ak(),99)&&0!=(Yx(a,18).Bb&eMn)&&(l=Yx(e.dd(),49),(d=P8(n.e,l))!=l)){if(_O(n,t,zan(n,0,h=VX(a,d))),f=null,gC(n.e)&&(i=iyn((wsn(),wut),n.e.Tg(),a))!=CZ(n.e.Tg(),n.c)){for(g=dwn(n.e.Tg(),a),u=0,c=Yx(n.g,119),o=0;o=0;)if(t=n[this.c],this.k.rl(t.ak()))return this.j=this.f?t:t.dd(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},EF(xDn,"BasicFeatureMap/FeatureEIterator",410),Wfn(662,410,yEn,qI),Fjn.Lk=function(){return!0},EF(xDn,"BasicFeatureMap/ResolvingFeatureEIterator",662),Wfn(955,486,rRn,vO),Fjn.Gi=function(){return this},EF(xDn,"EContentsEList/1",955),Wfn(956,486,rRn,GI),Fjn.Lk=function(){return!1},EF(xDn,"EContentsEList/2",956),Wfn(954,279,cRn,mO),Fjn.Nk=function(n){},Fjn.Ob=function(){return!1},Fjn.Sb=function(){return!1},EF(xDn,"EContentsEList/FeatureIteratorImpl/1",954),Wfn(825,585,JDn,ZO),Fjn.ci=function(){this.a=!0},Fjn.fj=function(){return this.a},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.a,this.a=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.a=!1},Fjn.a=!1,EF(xDn,"EDataTypeEList/Unsettable",825),Wfn(1849,585,JDn,nA),Fjn.hi=function(){return!0},EF(xDn,"EDataTypeUniqueEList",1849),Wfn(1850,825,JDn,tA),Fjn.hi=function(){return!0},EF(xDn,"EDataTypeUniqueEList/Unsettable",1850),Wfn(139,85,JDn,VO),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectContainmentEList/Resolving",139),Wfn(1163,545,JDn,QO),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectContainmentEList/Unsettable/Resolving",1163),Wfn(748,16,JDn,TN),Fjn.ci=function(){this.a=!0},Fjn.fj=function(){return this.a},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.a,this.a=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.a=!1},Fjn.a=!1,EF(xDn,"EObjectContainmentWithInverseEList/Unsettable",748),Wfn(1173,748,JDn,MN),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1173),Wfn(743,496,JDn,YO),Fjn.ci=function(){this.a=!0},Fjn.fj=function(){return this.a},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.a,this.a=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.a=!1},Fjn.a=!1,EF(xDn,"EObjectEList/Unsettable",743),Wfn(328,496,JDn,JO),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectResolvingEList",328),Wfn(1641,743,JDn,eA),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectResolvingEList/Unsettable",1641),Wfn(1381,1,{},Ns),EF(xDn,"EObjectValidator",1381),Wfn(546,496,JDn,y_),Fjn.zk=function(){return this.d},Fjn.Ak=function(){return this.b},Fjn.bj=function(){return!0},Fjn.Dk=function(){return!0},Fjn.b=0,EF(xDn,"EObjectWithInverseEList",546),Wfn(1176,546,JDn,SN),Fjn.Ck=function(){return!0},EF(xDn,"EObjectWithInverseEList/ManyInverse",1176),Wfn(625,546,JDn,PN),Fjn.ci=function(){this.a=!0},Fjn.fj=function(){return this.a},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.a,this.a=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.a=!1},Fjn.a=!1,EF(xDn,"EObjectWithInverseEList/Unsettable",625),Wfn(1175,625,JDn,CN),Fjn.Ck=function(){return!0},EF(xDn,"EObjectWithInverseEList/Unsettable/ManyInverse",1175),Wfn(749,546,JDn,IN),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectWithInverseResolvingEList",749),Wfn(31,749,JDn,AN),Fjn.Ck=function(){return!0},EF(xDn,"EObjectWithInverseResolvingEList/ManyInverse",31),Wfn(750,625,JDn,ON),Fjn.Ek=function(){return!0},Fjn.li=function(n,t){return $fn(this,n,Yx(t,56))},EF(xDn,"EObjectWithInverseResolvingEList/Unsettable",750),Wfn(1174,750,JDn,$N),Fjn.Ck=function(){return!0},EF(xDn,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1174),Wfn(1164,622,JDn),Fjn.ai=function(){return 0==(1792&this.b)},Fjn.ci=function(){this.b|=1},Fjn.Bk=function(){return 0!=(4&this.b)},Fjn.bj=function(){return 0!=(40&this.b)},Fjn.Ck=function(){return 0!=(16&this.b)},Fjn.Dk=function(){return 0!=(8&this.b)},Fjn.Ek=function(){return 0!=(this.b&FDn)},Fjn.rk=function(){return 0!=(32&this.b)},Fjn.Fk=function(){return 0!=(this.b&DNn)},Fjn.wj=function(n){return this.d?_X(this.d,n):this.ak().Yj().wj(n)},Fjn.fj=function(){return 0!=(2&this.b)?0!=(1&this.b):0!=this.i},Fjn.hi=function(){return 0!=(128&this.b)},Fjn.Xj=function(){var n;Hmn(this),0!=(2&this.b)&&(gC(this.e)?(n=0!=(1&this.b),this.b&=-2,Xp(this,new OV(this.e,2,tnn(this.e.Tg(),this.ak()),n,!1))):this.b&=-2)},Fjn.ni=function(){return 0==(1536&this.b)},Fjn.b=0,EF(xDn,"EcoreEList/Generic",1164),Wfn(1165,1164,JDn,eq),Fjn.ak=function(){return this.a},EF(xDn,"EcoreEList/Dynamic",1165),Wfn(747,63,Mxn,Jg),Fjn.ri=function(n){return H1(this.a.a,n)},EF(xDn,"EcoreEMap/1",747),Wfn(746,85,JDn,g_),Fjn.bi=function(n,t){tin(this.b,Yx(t,133))},Fjn.di=function(n,t){A3(this.b)},Fjn.ei=function(n,t,e){var i;++(i=this.b,Yx(t,133),i).e},Fjn.fi=function(n,t){N9(this.b,Yx(t,133))},Fjn.gi=function(n,t,e){N9(this.b,Yx(e,133)),iI(e)===iI(t)&&Yx(e,133).Th(function(n){return null==n?0:W5(n)}(Yx(t,133).cd())),tin(this.b,Yx(t,133))},EF(xDn,"EcoreEMap/DelegateEObjectContainmentEList",746),Wfn(1171,151,RDn,j0),EF(xDn,"EcoreEMap/Unsettable",1171),Wfn(1172,746,JDn,LN),Fjn.ci=function(){this.a=!0},Fjn.fj=function(){return this.a},Fjn.Xj=function(){var n;Hmn(this),gC(this.e)?(n=this.a,this.a=!1,K3(this.e,new OV(this.e,2,this.c,n,!1))):this.a=!1},Fjn.a=!1,EF(xDn,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1172),Wfn(1168,228,gMn,pF),Fjn.a=!1,Fjn.b=!1,EF(xDn,"EcoreUtil/Copier",1168),Wfn(745,1,fEn,hX),Fjn.Nb=function(n){I_(this,n)},Fjn.Ob=function(){return jnn(this)},Fjn.Pb=function(){var n;return jnn(this),n=this.b,this.b=null,n},Fjn.Qb=function(){this.a.Qb()},EF(xDn,"EcoreUtil/ProperContentIterator",745),Wfn(1382,1381,{},Kf),EF(xDn,"EcoreValidator",1382),aR(xDn,"FeatureMapUtil/Validator"),Wfn(1260,1,{1942:1},xs),Fjn.rl=function(n){return!0},EF(xDn,"FeatureMapUtil/1",1260),Wfn(757,1,{1942:1},ykn),Fjn.rl=function(n){var t;return this.c==n||(null==(t=hL(BF(this.a,n)))?function(n,t){var e;return n.f==jut?(e=TB(PJ((wsn(),wut),t)),n.e?4==e&&t!=(dfn(),Put)&&t!=(dfn(),Tut)&&t!=(dfn(),Mut)&&t!=(dfn(),Sut):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(Bz(PJ((wsn(),wut),t)))||n.d.Hc(iyn((wsn(),wut),n.b,t))))||!(!n.f||!Kbn((wsn(),n.f),tH(PJ(wut,t))))&&(e=TB(PJ(wut,t)),n.e?4==e:2==e)}(this,n)?(LV(this.a,n,(TA(),L_n)),!0):(LV(this.a,n,(TA(),$_n)),!1):t==(TA(),L_n))},Fjn.e=!1,EF(xDn,"FeatureMapUtil/BasicValidator",757),Wfn(758,43,gMn,yO),EF(xDn,"FeatureMapUtil/BasicValidator/Cache",758),Wfn(501,52,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,69:1,95:1},VP),Fjn.Vc=function(n,t){$wn(this.c,this.b,n,t)},Fjn.Fc=function(n){return Rgn(this.c,this.b,n)},Fjn.Wc=function(n,t){return function(n,t,e,i){var r,c,a,u,o,s,h,f;if(0==i.gc())return!1;if(TT(),a=(o=Yx(t,66).Oj())?i:new FZ(i.gc()),Lwn(n.e,t)){if(t.hi())for(h=i.Kc();h.Ob();)fvn(n,t,s=h.Pb(),CO(t,99)&&0!=(Yx(t,18).Bb&eMn))||(c=VX(t,s),a.Fc(c));else if(!o)for(h=i.Kc();h.Ob();)c=VX(t,s=h.Pb()),a.Fc(c)}else{for(f=dwn(n.e.Tg(),t),r=Yx(n.g,119),u=0;u1)throw hp(new Qm(GRn));o||(c=VX(t,i.Kc().Pb()),a.Fc(c))}return f5(n,fsn(n,t,e),a)}(this.c,this.b,n,t)},Fjn.Gc=function(n){return TO(this,n)},Fjn.Xh=function(n,t){!function(n,t,e,i){n.j=-1,Afn(n,fsn(n,t,e),(TT(),Yx(t,66).Mj().Ok(i)))}(this.c,this.b,n,t)},Fjn.lk=function(n,t){return Ydn(this.c,this.b,n,t)},Fjn.pi=function(n){return amn(this.c,this.b,n,!1)},Fjn.Zh=function(){return mC(this.c,this.b)},Fjn.$h=function(){return n=this.c,new Y3(this.b,n);var n},Fjn._h=function(n){return function(n,t,e){var i,r;for(r=new Y3(t,n),i=0;i0)if((i-=r.length-t)>=0){for(c.a+="0.";i>rFn.length;i-=rFn.length)ER(c,rFn);QL(c,rFn,oG(i)),yI(c,r.substr(t))}else yI(c,l$(r,t,oG(i=t-i))),c.a+=".",yI(c,lI(r,oG(i)));else{for(yI(c,r.substr(t));i<-rFn.length;i+=rFn.length)ER(c,rFn);QL(c,rFn,oG(-i))}return c.a}(Yx(t,240));case 15:case 14:return null==t?null:function(n){return n==JTn?QRn:n==ZTn?"-INF":""+n}(ty(fL(t)));case 17:return yan((ayn(),t));case 18:return yan(t);case 21:case 20:return null==t?null:function(n){return n==JTn?QRn:n==ZTn?"-INF":""+n}(Yx(t,155).a);case 27:return oL(Yx(t,190));case 30:return Yin((ayn(),Yx(t,15)));case 31:return Yin(Yx(t,15));case 40:case 59:case 48:return function(n){return null==n?null:I7(n)}((ayn(),t));case 42:return kan((ayn(),t));case 43:return kan(t);default:throw hp(new Qm(ONn+n.ne()+ANn))}},Fjn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=i1(n))?Ren(t.Mh(),n):-1),n.G){case 0:return new Qv;case 1:return new Rs;case 2:return new Jv;case 3:return new Yv;default:throw hp(new Qm(NNn+n.zb+ANn))}},Fjn.Kh=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;switch(n.yj()){case 5:case 52:case 4:return t;case 6:return sen(t);case 8:case 7:return null==t?null:function(n){if(n=Vvn(n,!0),_N(kLn,n)||_N("1",n))return TA(),L_n;if(_N(jLn,n)||_N("0",n))return TA(),$_n;throw hp(new fy("Invalid boolean value: '"+n+"'"))}(t);case 9:return null==t?null:iZ(ipn((i=Vvn(t,!0)).length>0&&(Lz(0,i.length),43==i.charCodeAt(0))?i.substr(1):i,-128,127)<<24>>24);case 10:return null==t?null:iZ(ipn((r=Vvn(t,!0)).length>0&&(Lz(0,r.length),43==r.charCodeAt(0))?r.substr(1):r,-128,127)<<24>>24);case 11:return lL(fjn(this,(ayn(),Dut),t));case 12:return lL(fjn(this,(ayn(),Rut),t));case 13:return null==t?null:new Wk(Vvn(t,!0));case 15:case 14:return function(n){var t,e,i,r;if(null==n)return null;if(i=Vvn(n,!0),r=QRn.length,_N(i.substr(i.length-r,r),QRn))if(4==(e=i.length)){if(Lz(0,i.length),43==(t=i.charCodeAt(0)))return iot;if(45==t)return eot}else if(3==e)return iot;return gon(i)}(t);case 16:return lL(fjn(this,(ayn(),Kut),t));case 17:return Qnn((ayn(),t));case 18:return Qnn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return Vvn(t,!0);case 21:case 20:return function(n){var t,e,i,r;if(null==n)return null;if(i=Vvn(n,!0),r=QRn.length,_N(i.substr(i.length-r,r),QRn))if(4==(e=i.length)){if(Lz(0,i.length),43==(t=i.charCodeAt(0)))return cot;if(45==t)return rot}else if(3==e)return cot;return new Vp(i)}(t);case 22:return lL(fjn(this,(ayn(),_ut),t));case 23:return lL(fjn(this,(ayn(),Fut),t));case 24:return lL(fjn(this,(ayn(),But),t));case 25:return lL(fjn(this,(ayn(),Hut),t));case 26:return lL(fjn(this,(ayn(),qut),t));case 27:return ztn(t);case 30:return Ynn((ayn(),t));case 31:return Ynn(t);case 32:return null==t?null:d9(ipn((h=Vvn(t,!0)).length>0&&(Lz(0,h.length),43==h.charCodeAt(0))?h.substr(1):h,nTn,Yjn));case 33:return null==t?null:new IC((f=Vvn(t,!0)).length>0&&(Lz(0,f.length),43==f.charCodeAt(0))?f.substr(1):f);case 34:return null==t?null:d9(ipn((l=Vvn(t,!0)).length>0&&(Lz(0,l.length),43==l.charCodeAt(0))?l.substr(1):l,nTn,Yjn));case 36:return null==t?null:ytn(mkn((b=Vvn(t,!0)).length>0&&(Lz(0,b.length),43==b.charCodeAt(0))?b.substr(1):b));case 37:return null==t?null:ytn(mkn((w=Vvn(t,!0)).length>0&&(Lz(0,w.length),43==w.charCodeAt(0))?w.substr(1):w));case 40:case 59:case 48:return function(n){var t;return null==n?null:new IC((t=Vvn(n,!0)).length>0&&(Lz(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}((ayn(),t));case 42:return Jnn((ayn(),t));case 43:return Jnn(t);case 44:return null==t?null:new IC((d=Vvn(t,!0)).length>0&&(Lz(0,d.length),43==d.charCodeAt(0))?d.substr(1):d);case 45:return null==t?null:new IC((g=Vvn(t,!0)).length>0&&(Lz(0,g.length),43==g.charCodeAt(0))?g.substr(1):g);case 46:return Vvn(t,!1);case 47:return lL(fjn(this,(ayn(),Gut),t));case 49:return lL(fjn(this,(ayn(),Uut),t));case 50:return null==t?null:g9(ipn((p=Vvn(t,!0)).length>0&&(Lz(0,p.length),43==p.charCodeAt(0))?p.substr(1):p,fRn,32767)<<16>>16);case 51:return null==t?null:g9(ipn((c=Vvn(t,!0)).length>0&&(Lz(0,c.length),43==c.charCodeAt(0))?c.substr(1):c,fRn,32767)<<16>>16);case 53:return lL(fjn(this,(ayn(),Vut),t));case 55:return null==t?null:g9(ipn((a=Vvn(t,!0)).length>0&&(Lz(0,a.length),43==a.charCodeAt(0))?a.substr(1):a,fRn,32767)<<16>>16);case 56:return null==t?null:g9(ipn((u=Vvn(t,!0)).length>0&&(Lz(0,u.length),43==u.charCodeAt(0))?u.substr(1):u,fRn,32767)<<16>>16);case 57:return null==t?null:ytn(mkn((o=Vvn(t,!0)).length>0&&(Lz(0,o.length),43==o.charCodeAt(0))?o.substr(1):o));case 58:return null==t?null:ytn(mkn((s=Vvn(t,!0)).length>0&&(Lz(0,s.length),43==s.charCodeAt(0))?s.substr(1):s));case 60:return null==t?null:d9(ipn((e=Vvn(t,!0)).length>0&&(Lz(0,e.length),43==e.charCodeAt(0))?e.substr(1):e,nTn,Yjn));case 61:return null==t?null:d9(ipn(Vvn(t,!0),nTn,Yjn));default:throw hp(new Qm(ONn+n.ne()+ANn))}},EF(VRn,"XMLTypeFactoryImpl",1919),Wfn(586,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1,1945:1,586:1},AB),Fjn.N=!1,Fjn.O=!1;var sot,hot,fot,lot,bot,wot=!1;EF(VRn,"XMLTypePackageImpl",586),Wfn(1852,1,{837:1},Ks),Fjn._j=function(){return Fpn(),_ot},EF(VRn,"XMLTypePackageImpl/1",1852),Wfn(1861,1,TRn,_s),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/10",1861),Wfn(1862,1,TRn,Fs),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/11",1862),Wfn(1863,1,TRn,Bs),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/12",1863),Wfn(1864,1,TRn,Hs),Fjn.wj=function(n){return cI(n)},Fjn.xj=function(n){return VQ(H_n,TEn,333,n,7,1)},EF(VRn,"XMLTypePackageImpl/13",1864),Wfn(1865,1,TRn,qs),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/14",1865),Wfn(1866,1,TRn,Gs),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/15",1866),Wfn(1867,1,TRn,zs),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/16",1867),Wfn(1868,1,TRn,Us),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/17",1868),Wfn(1869,1,TRn,Xs),Fjn.wj=function(n){return CO(n,155)},Fjn.xj=function(n){return VQ(q_n,TEn,155,n,0,1)},EF(VRn,"XMLTypePackageImpl/18",1869),Wfn(1870,1,TRn,Ws),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/19",1870),Wfn(1853,1,TRn,Vs),Fjn.wj=function(n){return CO(n,843)},Fjn.xj=function(n){return VQ(Cut,iEn,843,n,0,1)},EF(VRn,"XMLTypePackageImpl/2",1853),Wfn(1871,1,TRn,Qs),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/20",1871),Wfn(1872,1,TRn,Ys),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/21",1872),Wfn(1873,1,TRn,Js),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/22",1873),Wfn(1874,1,TRn,Zs),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/23",1874),Wfn(1875,1,TRn,nh),Fjn.wj=function(n){return CO(n,190)},Fjn.xj=function(n){return VQ(Yot,TEn,190,n,0,2)},EF(VRn,"XMLTypePackageImpl/24",1875),Wfn(1876,1,TRn,th),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/25",1876),Wfn(1877,1,TRn,eh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/26",1877),Wfn(1878,1,TRn,ih),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/27",1878),Wfn(1879,1,TRn,rh),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/28",1879),Wfn(1880,1,TRn,ch),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/29",1880),Wfn(1854,1,TRn,ah),Fjn.wj=function(n){return CO(n,667)},Fjn.xj=function(n){return VQ(aot,iEn,2021,n,0,1)},EF(VRn,"XMLTypePackageImpl/3",1854),Wfn(1881,1,TRn,uh),Fjn.wj=function(n){return CO(n,19)},Fjn.xj=function(n){return VQ(U_n,TEn,19,n,0,1)},EF(VRn,"XMLTypePackageImpl/30",1881),Wfn(1882,1,TRn,oh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/31",1882),Wfn(1883,1,TRn,sh),Fjn.wj=function(n){return CO(n,162)},Fjn.xj=function(n){return VQ(J_n,TEn,162,n,0,1)},EF(VRn,"XMLTypePackageImpl/32",1883),Wfn(1884,1,TRn,hh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/33",1884),Wfn(1885,1,TRn,fh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/34",1885),Wfn(1886,1,TRn,lh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/35",1886),Wfn(1887,1,TRn,bh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/36",1887),Wfn(1888,1,TRn,wh),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/37",1888),Wfn(1889,1,TRn,dh),Fjn.wj=function(n){return CO(n,15)},Fjn.xj=function(n){return VQ(JKn,dPn,15,n,0,1)},EF(VRn,"XMLTypePackageImpl/38",1889),Wfn(1890,1,TRn,gh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/39",1890),Wfn(1855,1,TRn,ph),Fjn.wj=function(n){return CO(n,668)},Fjn.xj=function(n){return VQ(uot,iEn,2022,n,0,1)},EF(VRn,"XMLTypePackageImpl/4",1855),Wfn(1891,1,TRn,vh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/40",1891),Wfn(1892,1,TRn,mh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/41",1892),Wfn(1893,1,TRn,yh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/42",1893),Wfn(1894,1,TRn,kh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/43",1894),Wfn(1895,1,TRn,jh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/44",1895),Wfn(1896,1,TRn,Eh),Fjn.wj=function(n){return CO(n,184)},Fjn.xj=function(n){return VQ(nFn,TEn,184,n,0,1)},EF(VRn,"XMLTypePackageImpl/45",1896),Wfn(1897,1,TRn,Th),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/46",1897),Wfn(1898,1,TRn,Mh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/47",1898),Wfn(1899,1,TRn,Sh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/48",1899),Wfn(TTn,1,TRn,Ph),Fjn.wj=function(n){return CO(n,184)},Fjn.xj=function(n){return VQ(nFn,TEn,184,n,0,1)},EF(VRn,"XMLTypePackageImpl/49",TTn),Wfn(1856,1,TRn,Ih),Fjn.wj=function(n){return CO(n,669)},Fjn.xj=function(n){return VQ(oot,iEn,2023,n,0,1)},EF(VRn,"XMLTypePackageImpl/5",1856),Wfn(1901,1,TRn,Ch),Fjn.wj=function(n){return CO(n,162)},Fjn.xj=function(n){return VQ(J_n,TEn,162,n,0,1)},EF(VRn,"XMLTypePackageImpl/50",1901),Wfn(1902,1,TRn,Oh),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/51",1902),Wfn(1903,1,TRn,Ah),Fjn.wj=function(n){return CO(n,19)},Fjn.xj=function(n){return VQ(U_n,TEn,19,n,0,1)},EF(VRn,"XMLTypePackageImpl/52",1903),Wfn(1857,1,TRn,$h),Fjn.wj=function(n){return aI(n)},Fjn.xj=function(n){return VQ(fFn,TEn,2,n,6,1)},EF(VRn,"XMLTypePackageImpl/6",1857),Wfn(1858,1,TRn,Lh),Fjn.wj=function(n){return CO(n,190)},Fjn.xj=function(n){return VQ(Yot,TEn,190,n,0,2)},EF(VRn,"XMLTypePackageImpl/7",1858),Wfn(1859,1,TRn,Nh),Fjn.wj=function(n){return rI(n)},Fjn.xj=function(n){return VQ(D_n,TEn,476,n,8,1)},EF(VRn,"XMLTypePackageImpl/8",1859),Wfn(1860,1,TRn,xh),Fjn.wj=function(n){return CO(n,217)},Fjn.xj=function(n){return VQ(__n,TEn,217,n,0,1)},EF(VRn,"XMLTypePackageImpl/9",1860),Wfn(50,60,eTn,wy),EF(kKn,"RegEx/ParseException",50),Wfn(820,1,{},Dh),Fjn.sl=function(n){return n16*e)throw hp(new wy(Kjn((GC(),iDn))));e=16*e+r}if(125!=this.a)throw hp(new wy(Kjn((GC(),rDn))));if(e>jKn)throw hp(new wy(Kjn((GC(),cDn))));n=e}else{if(r=0,0!=this.c||(r=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(e=r,kjn(this),0!=this.c||(r=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));n=e=16*e+r}break;case 117:if(i=0,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));n=t=16*t+i;break;case 118:if(kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if(t=16*t+i,kjn(this),0!=this.c||(i=din(this.a))<0)throw hp(new wy(Kjn((GC(),eDn))));if((t=16*t+i)>jKn)throw hp(new wy(Kjn((GC(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw hp(new wy(Kjn((GC(),aDn))))}return n},Fjn.ul=function(n){var t;switch(n){case 100:t=32==(32&this.e)?Gkn("Nd",!0):(Ljn(),jot);break;case 68:t=32==(32&this.e)?Gkn("Nd",!1):(Ljn(),Pot);break;case 119:t=32==(32&this.e)?Gkn("IsWord",!0):(Ljn(),Dot);break;case 87:t=32==(32&this.e)?Gkn("IsWord",!1):(Ljn(),Cot);break;case 115:t=32==(32&this.e)?Gkn("IsSpace",!0):(Ljn(),Aot);break;case 83:t=32==(32&this.e)?Gkn("IsSpace",!1):(Ljn(),Iot);break;default:throw hp(new Im(EKn+n.toString(16)))}return t},Fjn.vl=function(n){var t,e,i,r,c,a,u,o,s,h,f;for(this.b=1,kjn(this),t=null,0==this.c&&94==this.a?(kjn(this),n?(Ljn(),Ljn(),s=new cU(5)):(Ljn(),Ljn(),zwn(t=new cU(4),0,jKn),s=new cU(4))):(Ljn(),Ljn(),s=new cU(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:fmn(s,this.ul(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.Ll(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=Hhn(this,e)))throw hp(new wy(Kjn((GC(),zxn))));fmn(s,h),i=!0;break;default:e=this.tl()}else if(20==f){if((c=b$(this.i,58,this.d))<0)throw hp(new wy(Kjn((GC(),Uxn))));if(a=!0,94==XB(this.i,this.d)&&(++this.d,a=!1),!(u=bY(l$(this.i,this.d,c),a,512==(512&this.e))))throw hp(new wy(Kjn((GC(),Wxn))));if(fmn(s,u),i=!0,c+1>=this.j||93!=XB(this.i,c+1))throw hp(new wy(Kjn((GC(),Uxn))));this.d=c+2}if(kjn(this),!i)if(0!=this.c||45!=this.a)zwn(s,e,e);else{if(kjn(this),1==(f=this.c))throw hp(new wy(Kjn((GC(),Xxn))));0==f&&93==this.a?(zwn(s,e,e),zwn(s,45,45)):(o=this.a,10==f&&(o=this.tl()),kjn(this),zwn(s,e,o))}(this.e&DNn)==DNn&&0==this.c&&44==this.a&&kjn(this)}if(1==this.c)throw hp(new wy(Kjn((GC(),Xxn))));return t&&(_yn(t,s),s=t),xln(s),Lmn(s),this.b=0,kjn(this),s},Fjn.wl=function(){var n,t,e,i;for(e=this.vl(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw hp(new wy(Kjn((GC(),nDn))));if(kjn(this),9!=this.c)throw hp(new wy(Kjn((GC(),Zxn))));if(t=this.vl(!1),4==i)fmn(e,t);else if(45==n)_yn(e,t);else{if(38!=n)throw hp(new Im("ASSERT"));Eyn(e,t)}}return kjn(this),e},Fjn.xl=function(){var n,t;return n=this.a-48,Ljn(),Ljn(),t=new nG(12,null,n),!this.g&&(this.g=new Jp),Up(this.g,new Zg(n)),kjn(this),t},Fjn.yl=function(){return kjn(this),Ljn(),$ot},Fjn.zl=function(){return kjn(this),Ljn(),Oot},Fjn.Al=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Bl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Cl=function(){return kjn(this),r6()},Fjn.Dl=function(){return kjn(this),Ljn(),Not},Fjn.El=function(){return kjn(this),Ljn(),Rot},Fjn.Fl=function(){var n;if(this.d>=this.j||64!=(65504&(n=XB(this.i,this.d++))))throw hp(new wy(Kjn((GC(),Bxn))));return kjn(this),Ljn(),Ljn(),new BR(0,n-64)},Fjn.Gl=function(){return kjn(this),function(){var n,t,e,i,r,c;if(Ljn(),qot)return qot;for(fmn(n=new cU(4),Gkn($Kn,!0)),_yn(n,Gkn("M",!0)),_yn(n,Gkn("C",!0)),c=new cU(4),i=0;i<11;i++)zwn(c,i,i);return fmn(t=new cU(4),Gkn("M",!0)),zwn(t,4448,4607),zwn(t,65438,65439),Rmn(r=new HC(2),n),Rmn(r,Tot),(e=new HC(2)).$l(VR(c,Gkn("L",!0))),e.$l(t),e=new tF(r,e=new cW(3,e)),qot=e}()},Fjn.Hl=function(){return kjn(this),Ljn(),Kot},Fjn.Il=function(){var n;return Ljn(),Ljn(),n=new BR(0,105),kjn(this),n},Fjn.Jl=function(){return kjn(this),Ljn(),xot},Fjn.Kl=function(){return kjn(this),Ljn(),Lot},Fjn.Ll=function(n,t){return this.tl()},Fjn.Ml=function(){return kjn(this),Ljn(),Mot},Fjn.Nl=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw hp(new wy(Kjn((GC(),Kxn))));if(i=-1,t=null,49<=(n=XB(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new Jp),Up(this.g,new Zg(i)),++this.d,41!=XB(this.i,this.d))throw hp(new wy(Kjn((GC(),xxn))));++this.d}else switch(63==n&&--this.d,kjn(this),(t=ujn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));break;default:throw hp(new wy(Kjn((GC(),_xn))))}if(kjn(this),e=null,2==(r=etn(this)).e){if(2!=r.em())throw hp(new wy(Kjn((GC(),Fxn))));e=r.am(1),r=r.am(0)}if(7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),Ljn(),Ljn(),new nZ(i,t,r,e)},Fjn.Ol=function(){return kjn(this),Ljn(),Sot},Fjn.Pl=function(){var n;if(kjn(this),n=T_(24,etn(this)),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Ql=function(){var n;if(kjn(this),n=T_(20,etn(this)),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Rl=function(){var n;if(kjn(this),n=T_(22,etn(this)),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Sl=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d=this.j)throw hp(new wy(Kjn((GC(),Dxn))));if(45==t){for(++this.d;this.d=this.j)throw hp(new wy(Kjn((GC(),Dxn))))}if(58==t){if(++this.d,kjn(this),i=xF(etn(this),n,e),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));kjn(this)}else{if(41!=t)throw hp(new wy(Kjn((GC(),Rxn))));++this.d,kjn(this),i=xF(etn(this),n,e)}return i},Fjn.Tl=function(){var n;if(kjn(this),n=T_(21,etn(this)),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Ul=function(){var n;if(kjn(this),n=T_(23,etn(this)),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Vl=function(){var n,t;if(kjn(this),n=this.f++,t=M_(etn(this),n),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),t},Fjn.Wl=function(){var n;if(kjn(this),n=M_(etn(this),0),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Xl=function(n){return kjn(this),5==this.c?(kjn(this),VR(n,(Ljn(),Ljn(),new cW(9,n)))):VR(n,(Ljn(),Ljn(),new cW(3,n)))},Fjn.Yl=function(n){var t;return kjn(this),Ljn(),Ljn(),t=new HC(2),5==this.c?(kjn(this),Rmn(t,Tot),Rmn(t,n)):(Rmn(t,n),Rmn(t,Tot)),t},Fjn.Zl=function(n){return kjn(this),5==this.c?(kjn(this),Ljn(),Ljn(),new cW(9,n)):(Ljn(),Ljn(),new cW(3,n))},Fjn.a=0,Fjn.b=0,Fjn.c=0,Fjn.d=0,Fjn.e=0,Fjn.f=1,Fjn.g=null,Fjn.j=0,EF(kKn,"RegEx/RegexParser",820),Wfn(1824,820,{},Zv),Fjn.sl=function(n){return!1},Fjn.tl=function(){return Tdn(this)},Fjn.ul=function(n){return rpn(n)},Fjn.vl=function(n){return Ejn(this)},Fjn.wl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.xl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.yl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.zl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Al=function(){return kjn(this),rpn(67)},Fjn.Bl=function(){return kjn(this),rpn(73)},Fjn.Cl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Dl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.El=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Fl=function(){return kjn(this),rpn(99)},Fjn.Gl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Hl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Il=function(){return kjn(this),rpn(105)},Fjn.Jl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Kl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Ll=function(n,t){return fmn(n,rpn(t)),-1},Fjn.Ml=function(){return kjn(this),Ljn(),Ljn(),new BR(0,94)},Fjn.Nl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Ol=function(){return kjn(this),Ljn(),Ljn(),new BR(0,36)},Fjn.Pl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Ql=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Rl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Sl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Tl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Ul=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Vl=function(){var n;if(kjn(this),n=M_(etn(this),0),7!=this.c)throw hp(new wy(Kjn((GC(),xxn))));return kjn(this),n},Fjn.Wl=function(){throw hp(new wy(Kjn((GC(),uDn))))},Fjn.Xl=function(n){return kjn(this),VR(n,(Ljn(),Ljn(),new cW(3,n)))},Fjn.Yl=function(n){var t;return kjn(this),Ljn(),Ljn(),Rmn(t=new HC(2),n),Rmn(t,Tot),t},Fjn.Zl=function(n){return kjn(this),Ljn(),Ljn(),new cW(3,n)};var dot=null,got=null;EF(kKn,"RegEx/ParserForXMLSchema",1824),Wfn(117,1,xKn,np),Fjn.$l=function(n){throw hp(new Im("Not supported."))},Fjn._l=function(){return-1},Fjn.am=function(n){return null},Fjn.bm=function(){return null},Fjn.cm=function(n){},Fjn.dm=function(n){},Fjn.em=function(){return 0},Fjn.Ib=function(){return this.fm(0)},Fjn.fm=function(n){return 11==this.e?".":""},Fjn.e=0;var pot,vot,mot,yot,kot,jot,Eot,Tot,Mot,Sot,Pot,Iot,Cot,Oot,Aot,$ot,Lot,Not,xot,Dot,Rot,Kot,_ot,Fot,Bot=null,Hot=null,qot=null,Got=EF(kKn,"RegEx/Token",117);Wfn(136,117,{3:1,136:1,117:1},cU),Fjn.fm=function(n){var t,e,i;if(4==this.e)if(this==Eot)e=".";else if(this==jot)e="\\d";else if(this==Dot)e="\\w";else if(this==Aot)e="\\s";else{for((i=new Cy).a+="[",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?pI(i,jvn(this.b[t])):(pI(i,jvn(this.b[t])),i.a+="-",pI(i,jvn(this.b[t+1])));i.a+="]",e=i.a}else if(this==Pot)e="\\D";else if(this==Cot)e="\\W";else if(this==Iot)e="\\S";else{for((i=new Cy).a+="[^",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?pI(i,jvn(this.b[t])):(pI(i,jvn(this.b[t])),i.a+="-",pI(i,jvn(this.b[t+1])));i.a+="]",e=i.a}return e},Fjn.a=!1,Fjn.c=!1,EF(kKn,"RegEx/RangeToken",136),Wfn(584,1,{584:1},Zg),Fjn.a=0,EF(kKn,"RegEx/RegexParser/ReferencePosition",584),Wfn(583,1,{3:1,583:1},Mj),Fjn.Fb=function(n){var t;return null!=n&&!!CO(n,583)&&(t=Yx(n,583),_N(this.b,t.b)&&this.a==t.a)},Fjn.Hb=function(){return Xen(this.b+"/"+fwn(this.a))},Fjn.Ib=function(){return this.c.fm(this.a)},Fjn.a=0,EF(kKn,"RegEx/RegularExpression",583),Wfn(223,117,xKn,BR),Fjn._l=function(){return this.a},Fjn.fm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+iN(this.a&fTn);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=eMn?"\\v"+l$(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+iN(this.a&fTn)}break;case 8:e=this==Mot||this==Sot?""+iN(this.a&fTn):"\\"+iN(this.a&fTn);break;default:e=null}return e},Fjn.a=0,EF(kKn,"RegEx/Token/CharToken",223),Wfn(309,117,xKn,cW),Fjn.am=function(n){return this.a},Fjn.cm=function(n){this.b=n},Fjn.dm=function(n){this.c=n},Fjn.em=function(){return 1},Fjn.fm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.fm(n)+"*";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw hp(new Im("Token#toString(): CLOSURE "+this.c+tEn+this.b));t=this.a.fm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.fm(n)+"*?";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw hp(new Im("Token#toString(): NONGREEDYCLOSURE "+this.c+tEn+this.b));t=this.a.fm(n)+"{"+this.c+",}?"}return t},Fjn.b=0,Fjn.c=0,EF(kKn,"RegEx/Token/ClosureToken",309),Wfn(821,117,xKn,tF),Fjn.am=function(n){return 0==n?this.a:this.b},Fjn.em=function(){return 2},Fjn.fm=function(n){return 3==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+":9==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+?":this.a.fm(n)+""+this.b.fm(n)},EF(kKn,"RegEx/Token/ConcatToken",821),Wfn(1822,117,xKn,nZ),Fjn.am=function(n){if(0==n)return this.d;if(1==n)return this.b;throw hp(new Im("Internal Error: "+n))},Fjn.em=function(){return this.b?2:1},Fjn.fm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},Fjn.c=0,EF(kKn,"RegEx/Token/ConditionToken",1822),Wfn(1823,117,xKn,rU),Fjn.am=function(n){return this.b},Fjn.em=function(){return 1},Fjn.fm=function(n){return"(?"+(0==this.a?"":fwn(this.a))+(0==this.c?"":fwn(this.c))+":"+this.b.fm(n)+")"},Fjn.a=0,Fjn.c=0,EF(kKn,"RegEx/Token/ModifierToken",1823),Wfn(822,117,xKn,rB),Fjn.am=function(n){return this.a},Fjn.em=function(){return 1},Fjn.fm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.fm(n)+")":"("+this.a.fm(n)+")";break;case 20:t="(?="+this.a.fm(n)+")";break;case 21:t="(?!"+this.a.fm(n)+")";break;case 22:t="(?<="+this.a.fm(n)+")";break;case 23:t="(?"+this.a.fm(n)+")"}return t},Fjn.b=0,EF(kKn,"RegEx/Token/ParenToken",822),Wfn(521,117,{3:1,117:1,521:1},nG),Fjn.bm=function(){return this.b},Fjn.fm=function(n){return 12==this.e?"\\"+this.a:function(n){var t,e,i,r;for(r=n.length,t=null,i=0;i=0?(t||(t=new Oy,i>0&&pI(t,n.substr(0,i))),t.a+="\\",KF(t,e&fTn)):t&&KF(t,e&fTn);return t?t.a:n}(this.b)},Fjn.a=0,EF(kKn,"RegEx/Token/StringToken",521),Wfn(465,117,xKn,HC),Fjn.$l=function(n){Rmn(this,n)},Fjn.am=function(n){return Yx(lB(this.a,n),117)},Fjn.em=function(){return this.a?this.a.a.c.length:0},Fjn.fm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=Yx(lB(this.a,0),117),r=3==(e=Yx(lB(this.a,1),117)).e&&e.am(0)==t?t.fm(n)+"+":9==e.e&&e.am(0)==t?t.fm(n)+"+?":t.fm(n)+""+e.fm(n);else{for(c=new Cy,i=0;i=n.c.b:n.a<=n.c.b))throw hp(new Kp);return t=n.a,n.a+=n.c.c,++n.b,d9(t)}(this)},Fjn.Ub=function(){return function(n){if(n.b<=0)throw hp(new Kp);return--n.b,n.a-=n.c.c,d9(n.a)}(this)},Fjn.Wb=function(n){Yx(n,19),function(){throw hp(new sy(FKn))}()},Fjn.Ob=function(){return this.c.c<0?this.a>=this.c.b:this.a<=this.c.b},Fjn.Sb=function(){return this.b>0},Fjn.Tb=function(){return this.b},Fjn.Vb=function(){return this.b-1},Fjn.Qb=function(){throw hp(new sy(BKn))},Fjn.a=0,Fjn.b=0,EF(KKn,"ExclusiveRange/RangeIterator",254);var zot,Uot,Xot=MB(HDn,"C"),Wot=MB(zDn,"I"),Vot=MB(Xjn,"Z"),Qot=MB(UDn,"J"),Yot=MB(BDn,"B"),Jot=MB(qDn,"D"),Zot=MB(GDn,"F"),nst=MB(XDn,"S"),tst=aR("org.eclipse.elk.core.labels","ILabelManager"),est=aR(exn,"DiagnosticChain"),ist=aR(SRn,"ResourceSet"),rst=EF(exn,"InvocationTargetException",null),cst=(_y(),function(n){return _y(),function(){return sX(n,this,arguments)}}),ast=ast=function(n,t,e,i){Cj();var r=Hjn;function c(){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};!function(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e);var i=Object.assign({},t),r=!1;try{n.resolve("web-worker"),r=!0}catch(n){}if(t.workerUrl)if(r){var c=n("web-worker");i.workerFactory=function(n){return new c(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!i.workerFactory){var a=n("./elk-worker.min.js").Worker;i.workerFactory=function(n){return new a(n)}}return function(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,i))}return function(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=i,i.default=i},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3)},1639:function(n,t,e){"use strict";e.d(t,{diagram:function(){return v}});var i=e(1813),r=e(7274),c=e(6076),a=e(9339),u=e(7295);e(7484),e(7967),e(7856);const o=new u;let s={};const h={};let f={};const l=(n,t,e)=>{const i={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return i.TD=i.TB,a.l.info("abc88",e,t,n),i[e][t][n]},b=(n,t,e)=>{if(a.l.info("getNextPort abc88",{node:n,edgeDirection:t,graphDirection:e}),!s[n])switch(e){case"TB":case"TD":s[n]={inPosition:"north",outPosition:"south"};break;case"BT":s[n]={inPosition:"south",outPosition:"north"};break;case"RL":s[n]={inPosition:"east",outPosition:"west"};break;case"LR":s[n]={inPosition:"west",outPosition:"east"}}const i="in"===t?s[n].inPosition:s[n].outPosition;return"in"===t?s[n].inPosition=l(s[n].inPosition,t,e):s[n].outPosition=l(s[n].outPosition,t,e),i},w=function(n,t,e,i,c){const a=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=f[i].offset;return{x:r.posX,y:r.posY}}(t.sourceId,t.targetId,c),u=t.sections[0].startPoint,o=t.sections[0].endPoint,s=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+a.x,n.y+a.y])),h=[[u.x+a.x,u.y+a.y],...s,[o.x+a.x,o.y+a.y]],l=(0,r.jvg)().curve(r.c_6),b=n.insert("path").attr("d",l(h)).attr("class","path "+e.classes).attr("fill","none"),w=n.insert("g").attr("class","edgeLabel"),d=(0,r.Ys)(w.node().appendChild(t.labelEl)),g=d.node().firstChild.getBoundingClientRect();d.attr("width",g.width),d.attr("height",g.height),w.attr("transform",`translate(${t.labels[0].x+a.x}, ${t.labels[0].y+a.y})`),function(n,t,e,i){let r="";switch(i&&(r=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,r=r.replace(/\(/g,"\\("),r=r.replace(/\)/g,"\\)")),t.arrowTypeStart){case"arrow_cross":n.attr("marker-start","url("+r+"#"+e+"-crossStart)");break;case"arrow_point":n.attr("marker-start","url("+r+"#"+e+"-pointStart)");break;case"arrow_barb":n.attr("marker-start","url("+r+"#"+e+"-barbStart)");break;case"arrow_circle":n.attr("marker-start","url("+r+"#"+e+"-circleStart)");break;case"aggregation":n.attr("marker-start","url("+r+"#"+e+"-aggregationStart)");break;case"extension":n.attr("marker-start","url("+r+"#"+e+"-extensionStart)");break;case"composition":n.attr("marker-start","url("+r+"#"+e+"-compositionStart)");break;case"dependency":n.attr("marker-start","url("+r+"#"+e+"-dependencyStart)");break;case"lollipop":n.attr("marker-start","url("+r+"#"+e+"-lollipopStart)")}switch(t.arrowTypeEnd){case"arrow_cross":n.attr("marker-end","url("+r+"#"+e+"-crossEnd)");break;case"arrow_point":n.attr("marker-end","url("+r+"#"+e+"-pointEnd)");break;case"arrow_barb":n.attr("marker-end","url("+r+"#"+e+"-barbEnd)");break;case"arrow_circle":n.attr("marker-end","url("+r+"#"+e+"-circleEnd)");break;case"aggregation":n.attr("marker-end","url("+r+"#"+e+"-aggregationEnd)");break;case"extension":n.attr("marker-end","url("+r+"#"+e+"-extensionEnd)");break;case"composition":n.attr("marker-end","url("+r+"#"+e+"-compositionEnd)");break;case"dependency":n.attr("marker-end","url("+r+"#"+e+"-dependencyEnd)");break;case"lollipop":n.attr("marker-end","url("+r+"#"+e+"-lollipopEnd)")}}(b,e,i.type,i.arrowMarkerAbsolute)},d=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(f[t])})),d(n.children,t)}))},g=(n,t,e,i,r,c,u)=>{e.forEach((function(e){if(e)if(f[e.id].offset={posX:e.x+n,posY:e.y+t,x:n,y:t,depth:u,width:e.width,height:e.height},"group"===e.type){const i=r.insert("g").attr("class","subgraph");i.insert("rect").attr("class","subgraph subgraph-lvl-"+u%5+" node").attr("x",e.x+n).attr("y",e.y+t).attr("width",e.width).attr("height",e.height);const c=i.insert("g").attr("class","label"),o=(0,a.c)().flowchart.htmlLabels?e.labelData.width/2:0;c.attr("transform",`translate(${e.labels[0].x+n+e.x+o}, ${e.labels[0].y+t+e.y+3})`),c.node().appendChild(e.labelData.labelNode),a.l.info("Id (UGH)= ",e.type,e.labels)}else a.l.info("Id (UGH)= ",e.id),e.el.attr("transform",`translate(${e.x+n+e.width/2}, ${e.y+t+e.height/2})`)})),e.forEach((function(e){e&&"group"===e.type&&g(n+e.x,t+e.y,e.children,i,r,c,u+1)}))},p={getClasses:function(n,t){return a.l.info("Extracting classes"),t.db.getClasses()},draw:async function(n,t,e,i){var u;f={},s={};const l=(0,r.Ys)("body").append("div").attr("style","height:400px").attr("id","cy");let p={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(a.l.info("Drawing flowchart using v3 renderer",o),i.db.getDirection()){case"BT":p.layoutOptions["elk.direction"]="UP";break;case"TB":p.layoutOptions["elk.direction"]="DOWN";break;case"LR":p.layoutOptions["elk.direction"]="RIGHT";break;case"RL":p.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:v,flowchart:m}=(0,a.c)();let y;"sandbox"===v&&(y=(0,r.Ys)("#i"+t));const k="sandbox"===v?(0,r.Ys)(y.nodes()[0].contentDocument.body):(0,r.Ys)("body"),j="sandbox"===v?y.nodes()[0].contentDocument:document,E=k.select(`[id="${t}"]`);(0,c.a)(E,["point","circle","cross"],i.type,i.arrowMarkerAbsolute);const T=i.db.getVertices();let M;const S=i.db.getSubGraphs();a.l.info("Subgraphs - ",S);for(let n=S.length-1;n>=0;n--)M=S[n],i.db.addVertex(M.id,{text:M.title,type:M.labelType},"group",void 0,M.classes,M.dir);const P=E.insert("g").attr("class","subgraphs"),I=function(n){const t={parentById:{},childrenById:{}},e=n.getSubGraphs();return a.l.info("Subgraphs - ",e),e.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),e.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(i.db);p=await async function(n,t,e,i,r,u,o){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let o="default";e.classes.length>0&&(o=e.classes.join(" ")),o+=" flowchart-label";const h=(0,a.k)(e.styles);let l=void 0!==e.text?e.text:e.id;const b={width:0,height:0},w=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let d=0,g="",p={};switch(e.type){case"round":d=5,g="rect";break;case"square":case"group":default:g="rect";break;case"diamond":g="question",p={portConstraints:"FIXED_SIDE"};break;case"hexagon":g="hexagon";break;case"odd":case"odd_right":g="rect_left_inv_arrow";break;case"lean_right":g="lean_right";break;case"lean_left":g="lean_left";break;case"trapezoid":g="trapezoid";break;case"inv_trapezoid":g="inv_trapezoid";break;case"circle":g="circle";break;case"ellipse":g="ellipse";break;case"stadium":g="stadium";break;case"subroutine":g="subroutine";break;case"cylinder":g="cylinder";break;case"doublecircle":g="doublecircle"}const v={labelStyle:h.labelStyle,shape:g,labelText:l,labelType:e.labelType,rx:d,ry:d,class:o,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:r.db.getTooltip(e.id)||"",domId:r.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:(0,a.c)().flowchart.padding};let m,y;if("group"!==v.type)y=await(0,c.e)(s,v,e.dir),m=y.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await(0,c.l)(s,v,void 0,!0);b.width=t.width,b.wrappingWidth=(0,a.c)().flowchart.wrappingWidth,b.height=t.height,b.labelNode=n.node(),v.labelData=b}const k={id:e.id,ports:"diamond"===e.type?w:[],layoutOptions:p,labelText:l,labelData:b,domId:r.db.lookUpDomId(e.id),width:null==m?void 0:m.width,height:null==m?void 0:m.height,type:e.type,el:y,parent:u.parentById[e.id]};f[v.id]=k}))),o}(T,t,k,j,i,I,p);const C=E.insert("g").attr("class","edges edgePath"),O=i.db.getEdges();p=function(n,t,e,i){a.l.info("abc78 edges = ",n);const u=i.insert("g").attr("class","edgeLabels");let o,s,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=(0,a.k)(n.defaultStyle);o=t.style,s=t.labelStyle}return n.forEach((function(t){const i="L-"+t.start+"-"+t.end;void 0===l[i]?(l[i]=0,a.l.info("abc78 new entry",i,l[i])):(l[i]++,a.l.info("abc78 new entry",i,l[i]));let d=i+"-"+l[i];a.l.info("abc78 new link id to be used is",i,d,l[i]);const g="LS-"+t.start,p="LE-"+t.end,v={style:"",labelStyle:""};switch(v.minlen=t.length||1,"arrow_open"===t.type?v.arrowhead="none":v.arrowhead="normal",v.arrowTypeStart="arrow_open",v.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":v.arrowTypeStart="arrow_cross";case"arrow_cross":v.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":v.arrowTypeStart="arrow_point";case"arrow_point":v.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":v.arrowTypeStart="arrow_circle";case"arrow_circle":v.arrowTypeEnd="arrow_circle"}let m="",y="";switch(t.stroke){case"normal":m="fill:none;",void 0!==o&&(m=o),void 0!==s&&(y=s),v.thickness="normal",v.pattern="solid";break;case"dotted":v.thickness="normal",v.pattern="dotted",v.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":v.thickness="thick",v.pattern="solid",v.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=(0,a.k)(t.style);m=n.style,y=n.labelStyle}v.style=v.style+=m,v.labelStyle=v.labelStyle+=y,void 0!==t.interpolate?v.curve=(0,a.o)(t.interpolate,r.c_6):void 0!==n.defaultInterpolate?v.curve=(0,a.o)(n.defaultInterpolate,r.c_6):v.curve=(0,a.o)(h.curve,r.c_6),void 0===t.text?void 0!==t.style&&(v.arrowheadStyle="fill: #333"):(v.arrowheadStyle="fill: #333",v.labelpos="c"),v.labelType=t.labelType,v.label=t.text.replace(a.e.lineBreakRegex,"\n"),void 0===t.style&&(v.style=v.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),v.labelStyle=v.labelStyle.replace("color:","fill:"),v.id=d,v.classes="flowchart-link "+g+" "+p;const k=(0,c.f)(u,v),{source:j,target:E,sourceId:T,targetId:M}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=f[e],u=f[i];return a&&u?("diamond"===a.type&&(e=`${e}-${b(e,"out",t)}`),"diamond"===u.type&&(i=`${i}-${b(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);a.l.debug("abc78 source and target",j,E),e.edges.push({id:"e"+t.start+t.end,sources:[j],targets:[E],sourceId:T,targetId:M,labelEl:k,labels:[{width:v.width,height:v.height,orgWidth:v.width,orgHeight:v.height,text:v.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:v})})),e}(O,i,p,E),Object.keys(f).forEach((n=>{const t=f[n];t.parent||p.children.push(t),void 0!==I.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),d(p.children,I),a.l.info("after layout",JSON.stringify(p,null,2));const A=await o.layout(p);g(0,0,A.children,E,P,i,0),a.l.info("after layout",A),null==(u=A.edges)||u.map((n=>{w(C,n,n.edgeData,i,I)})),(0,a.p)({},E,m.diagramPadding,m.useMaxWidth),l.remove()}},v={db:i.d,renderer:p,parser:i.p,styles:n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/642-12e7dea2.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/642-12e7dea2.chunk.min.js new file mode 100644 index 000000000..af4bae088 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/642-12e7dea2.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[642],{7642:function(t,e,a){a.d(e,{diagram:function(){return f}});var i=a(1535),n=a(7274),d=a(3771),r=a(5625),s=a(9339);a(7484),a(7967),a(7856);const o={},c=(t,e,a)=>{const i=(0,s.c)().state.padding,n=2*(0,s.c)().state.padding,d=t.node().getBBox(),r=d.width,o=d.x,c=t.append("text").attr("x",0).attr("y",(0,s.c)().state.titleShift).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),g=c.node().getBBox().width+n;let p,h=Math.max(g,r);h===r&&(h+=n);const l=t.node().getBBox();e.doc,p=o-i,g>r&&(p=(r-h)/2+i),Math.abs(o-l.x)r&&(p=o-(g-r)/2);const x=1-(0,s.c)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+(0,s.c)().state.textHeight+(0,s.c)().state.titleShift+1).attr("rx","0"),c.attr("x",p+i),g<=r&&c.attr("x",o+(h-n)/2-g/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",3*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",l.height+3+2*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t},g=function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit)})(n),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2)})(n),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=(0,s.c)().state.forkWidth,i=(0,s.c)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding)})(n,e),"note"===e.type&&((t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,s.c)().state.padding),i=e.append("g"),{textWidth:n,textHeight:d}=((t,e,a,i)=>{let n=0;const d=i.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let r=t.replace(/\r\n/g,"
        ");r=r.replace(/\n/g,"
        ");const o=r.split(s.e.lineBreakRegex);let c=1.25*(0,s.c)().state.noteMargin;for(const t of o){const e=t.trim();if(e.length>0){const t=d.append("tspan");t.text(e),0===c&&(c+=t.node().getBBox().height),n+=c,t.attr("x",0+(0,s.c)().state.noteMargin),t.attr("y",0+n+1.25*(0,s.c)().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:n}})(t,0,0,i);a.attr("height",d+2*(0,s.c)().state.noteMargin),a.attr("width",n+2*(0,s.c)().state.noteMargin)})(e.note.text,n),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,s.c)().state.textHeight).attr("class","divider").attr("x2",2*(0,s.c)().state.textHeight).attr("y1",0).attr("y2",0)})(n),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+2*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id).node().getBBox();t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",a.width+2*(0,s.c)().state.padding).attr("height",a.height+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius)})(n,e),"default"===e.type&&e.descriptions.length>0&&((t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+1.3*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),i=a.height,n=t.append("text").attr("x",(0,s.c)().state.padding).attr("y",i+.4*(0,s.c)().state.padding+(0,s.c)().state.dividerMargin+(0,s.c)().state.textHeight).attr("class","state-description");let d=!0,r=!0;e.descriptions.forEach((function(t){d||(function(t,e,a){const i=t.append("tspan").attr("x",2*(0,s.c)().state.padding).text(e);a||i.attr("dy",(0,s.c)().state.textHeight)}(n,t,r),r=!1),d=!1}));const o=t.append("line").attr("x1",(0,s.c)().state.padding).attr("y1",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("y2",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("class","descr-divider"),c=n.node().getBBox(),g=Math.max(c.width,a.width);o.attr("x2",g+3*(0,s.c)().state.padding),t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",g+2*(0,s.c)().state.padding).attr("height",c.height+i+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius)})(n,e);const d=n.node().getBBox();return i.width=d.width+2*(0,s.c)().state.padding,i.height=d.height+2*(0,s.c)().state.padding,r=i,o[a]=r,i;var r};let p,h=0;const l={},x=(t,e,a,o,u,f,y)=>{const w=new r.k({compound:!0,multigraph:!0});let b,B=!0;for(b=0;b{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))):s.l.debug("No Node "+t+": "+JSON.stringify(w.node(t)))}));let M=v.getBBox();w.edges().forEach((function(t){void 0!==t&&void 0!==w.edge(t)&&(s.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(w.edge(t))),function(t,e,a){e.points=e.points.filter((t=>!Number.isNaN(t.y)));const d=e.points,r=(0,n.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.$0Z),o=t.append("path").attr("d",r(d)).attr("id","edge"+h).attr("class","transition");let c="";if((0,s.c)().state.arrowMarkerAbsolute&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),o.attr("marker-end","url("+c+"#"+function(t){switch(t){case i.d.relationType.AGGREGATION:return"aggregation";case i.d.relationType.EXTENSION:return"extension";case i.d.relationType.COMPOSITION:return"composition";case i.d.relationType.DEPENDENCY:return"dependency"}}(i.d.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:d}=s.u.calcLabelPosition(e.points),r=s.e.getRows(a.title);let o=0;const c=[];let g=0,p=0;for(let t=0;t<=r.length;t++){const e=i.append("text").attr("text-anchor","middle").text(r[t]).attr("x",n).attr("y",d+o),a=e.node().getBBox();if(g=Math.max(g,a.width),p=Math.min(p,a.x),s.l.info(a.x,n,d+o),0===o){const t=e.node().getBBox();o=t.height,s.l.info("Title height",o,d)}c.push(e)}let h=o*r.length;if(r.length>1){const t=(r.length-1)*o*.5;c.forEach(((e,a)=>e.attr("y",d+a*o-t))),h=o*r.length}const l=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-g/2-(0,s.c)().state.padding/2).attr("y",d-h/2-(0,s.c)().state.padding/2-3.5).attr("width",g+(0,s.c)().state.padding).attr("height",h+(0,s.c)().state.padding),s.l.info(l)}h++}(e,w.edge(t),w.edge(t).relation))})),M=v.getBBox();const S={id:a||"root",label:a||"root",width:0,height:0};return S.width=M.width+2*p.padding,S.height=M.height+2*p.padding,s.l.debug("Doc rendered",S,w),S},u={setConf:function(){},draw:function(t,e,a,i){p=(0,s.c)().state;const d=(0,s.c)().securityLevel;let r;"sandbox"===d&&(r=(0,n.Ys)("#i"+e));const o="sandbox"===d?(0,n.Ys)(r.nodes()[0].contentDocument.body):(0,n.Ys)("body"),c="sandbox"===d?r.nodes()[0].contentDocument:document;s.l.debug("Rendering diagram "+t);const g=o.select(`[id='${e}']`);g.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z");const h=i.db.getRootDoc();x(h,g,void 0,!1,o,c,i);const l=p.padding,u=g.node().getBBox(),f=u.width+2*l,y=u.height+2*l,w=1.75*f;(0,s.i)(g,y,w,p.useMaxWidth),g.attr("viewBox",`${u.x-p.padding} ${u.y-p.padding} `+f+" "+y)}},f={parser:i.p,db:i.d,renderer:u,styles:i.s,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,i.d.clear()}}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/662-17acb8f4.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/662-17acb8f4.chunk.min.js new file mode 100644 index 000000000..b6a9e76c8 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/662-17acb8f4.chunk.min.js @@ -0,0 +1,2 @@ +/*! For license information please see 662-17acb8f4.chunk.min.js.LICENSE.txt */ +(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[662],{4182:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).FDLayoutConstants;function i(){}for(var a in r)i[a]=r[a];i.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,i.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,i.DEFAULT_COMPONENT_SEPERATION=60,i.TILE=!0,i.TILING_PADDING_VERTICAL=10,i.TILING_PADDING_HORIZONTAL=10,i.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutEdge;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraph;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraphManager;function i(e){r.call(this,e)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutNode,i=n(0).IMath;function a(e,t,n,i){r.call(this,e,t,n,i)}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];a.prototype.move=function(){var e=this.graphManager.getLayout();this.displacementX=e.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=e.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementX=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementX)),Math.abs(this.displacementY)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementY=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),e.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},a.prototype.propogateDisplacementToChildren=function(e,t){for(var n,r=this.getChild().getNodes(),i=0;i0)this.positionNodesRadially(e);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(n),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},m.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%u.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),t=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(t),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var n=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(n,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},m.prototype.getPositionsData=function(){for(var e=this.graphManager.getAllNodes(),t={},n=0;n1)for(s=0;sr&&(r=Math.floor(o.y)),a=Math.floor(o.x+l.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(c.WORLD_CENTER_X-o.x/2,c.WORLD_CENTER_Y-o.y/2))},m.radialLayout=function(e,t,n){var r=Math.max(this.maxDiagonalInTree(e),l.DEFAULT_RADIAL_SEPARATION);m.branchRadialLayout(t,null,0,359,0,r);var i=v.calculateBounds(e),a=new y;a.setDeviceOrgX(i.getMinX()),a.setDeviceOrgY(i.getMinY()),a.setWorldOrgX(n.x),a.setWorldOrgY(n.y);for(var o=0;o1;){var y=v[0];v.splice(0,1);var b=c.indexOf(y);b>=0&&c.splice(b,1),g--,h--}d=null!=t?(c.indexOf(v[0])+1)%g:0;for(var x=Math.abs(r-n)/h,w=d;p!=h;w=++w%g){var E=c[w].getOtherEnd(e);if(E!=t){var _=(n+p*x)%360,T=(_+x)%360;m.branchRadialLayout(E,e,_,T,i+a,a),p++}}},m.maxDiagonalInTree=function(e){for(var t=g.MIN_VALUE,n=0;nt&&(t=r)}return t},m.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},m.prototype.groupZeroDegreeMembers=function(){var e=this,t={};this.memberGroups={},this.idToDummyNode={};for(var n=[],r=this.graphManager.getAllNodes(),i=0;i1){var r="DummyCompound_"+n;e.memberGroups[r]=t[n];var i=t[n][0].getParent(),a=new o(e.graphManager);a.id=r,a.paddingLeft=i.paddingLeft||0,a.paddingRight=i.paddingRight||0,a.paddingBottom=i.paddingBottom||0,a.paddingTop=i.paddingTop||0,e.idToDummyNode[r]=a;var s=e.getGraphManager().add(e.newGraph(),a),l=i.getChild();l.add(a);for(var u=0;u=0;e--){var t=this.compoundOrder[e],n=t.id,r=t.paddingLeft,i=t.paddingTop;this.adjustLocations(this.tiledMemberPack[n],t.rect.x,t.rect.y,r,i)}},m.prototype.repopulateZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack;Object.keys(t).forEach((function(n){var r=e.idToDummyNode[n],i=r.paddingLeft,a=r.paddingTop;e.adjustLocations(t[n],r.rect.x,r.rect.y,i,a)}))},m.prototype.getToBeTiled=function(e){var t=e.id;if(null!=this.toBeTiled[t])return this.toBeTiled[t];var n=e.getChild();if(null==n)return this.toBeTiled[t]=!1,!1;for(var r=n.getNodes(),i=0;i0)return this.toBeTiled[t]=!1,!1;if(null!=a.getChild()){if(!this.getToBeTiled(a))return this.toBeTiled[t]=!1,!1}else this.toBeTiled[a.id]=!1}return this.toBeTiled[t]=!0,!0},m.prototype.getNodeDegree=function(e){e.id;for(var t=e.getEdges(),n=0,r=0;rl&&(l=c.rect.height)}n+=l+e.verticalPadding}},m.prototype.tileCompoundMembers=function(e,t){var n=this;this.tiledMemberPack=[],Object.keys(e).forEach((function(r){var i=t[r];n.tiledMemberPack[r]=n.tileNodes(e[r],i.paddingLeft+i.paddingRight),i.rect.width=n.tiledMemberPack[r].width,i.rect.height=n.tiledMemberPack[r].height}))},m.prototype.tileNodes=function(e,t){var n={rows:[],rowWidth:[],rowHeight:[],width:0,height:t,verticalPadding:l.TILING_PADDING_VERTICAL,horizontalPadding:l.TILING_PADDING_HORIZONTAL};e.sort((function(e,t){return e.rect.width*e.rect.height>t.rect.width*t.rect.height?-1:e.rect.width*e.rect.height0&&(a+=e.horizontalPadding),e.rowWidth[n]=a,e.width0&&(o+=e.verticalPadding);var s=0;o>e.rowHeight[n]&&(s=e.rowHeight[n],e.rowHeight[n]=o,s=e.rowHeight[n]-s),e.height+=s,e.rows[n].push(t)},m.prototype.getShortestRowIndex=function(e){for(var t=-1,n=Number.MAX_VALUE,r=0;rn&&(t=r,n=e.rowWidth[r]);return t},m.prototype.canAddHorizontal=function(e,t,n){var r=this.getShortestRowIndex(e);if(r<0)return!0;var i=e.rowWidth[r];if(i+e.horizontalPadding+t<=e.width)return!0;var a,o,s=0;return e.rowHeight[r]0&&(s=n+e.verticalPadding-e.rowHeight[r]),a=e.width-i>=t+e.horizontalPadding?(e.height+s)/(i+t+e.horizontalPadding):(e.height+s)/e.width,s=n+e.verticalPadding,(o=e.widtha&&t!=n){r.splice(-1,1),e.rows[n].push(i),e.rowWidth[t]=e.rowWidth[t]-a,e.rowWidth[n]=e.rowWidth[n]+a,e.width=e.rowWidth[instance.getLongestRowIndex(e)];for(var o=Number.MIN_VALUE,s=0;so&&(o=r[s].height);t>0&&(o+=e.verticalPadding);var l=e.rowHeight[t]+e.rowHeight[n];e.rowHeight[t]=o,e.rowHeight[n]0)for(var c=i;c<=a;c++)l[0]+=this.grid[c][o-1].length+this.grid[c][o].length-1;if(a0)for(c=o;c<=s;c++)l[3]+=this.grid[i-1][c].length+this.grid[i][c].length-1;for(var h,d,p=g.MAX_VALUE,f=0;f0&&(o=n.getGraphManager().add(n.newGraph(),a),this.processChildrenList(o,h,n))}},h.prototype.stop=function(){return this.stopped=!0,this};var p=function(e){e("layout","cose-bilkent",h)};"undefined"!=typeof cytoscape&&p(cytoscape),e.exports=p}])},e.exports=r(n(4182))},1377:function(e,t,n){e.exports=function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);nt?1:0},z=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,i,a,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+R+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t}(e)},Y={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},X=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i=t||n<0||h&&e-u>=a}function f(){var e=$();if(g(e))return v(e);s=setTimeout(f,function(e){var n=t-(e-l);return h?me(n,a-(e-u)):n}(e))}function v(e){return s=void 0,d&&r?p(e):(r=i=void 0,o)}function y(){var e=$(),n=g(e);if(r=arguments,i=this,l=e,n){if(void 0===s)return function(e){return u=e,s=setTimeout(f,t),c?p(e):o}(l);if(h)return clearTimeout(s),s=setTimeout(f,t),p(l)}return void 0===s&&(s=setTimeout(f,t)),o}return t=ve(t)||0,U(n)&&(c=!!n.leading,a=(h="maxWait"in n)?ye(ve(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),y.cancel=function(){void 0!==s&&clearTimeout(s),u=0,r=l=i=s=void 0},y.flush=function(){return void 0===s?o:v($())},y},xe=l?l.performance:null,we=xe&&xe.now?function(){return xe.now()}:function(){return Date.now()},Ee=function(){if(l){if(l.requestAnimationFrame)return function(e){l.requestAnimationFrame(e)};if(l.mozRequestAnimationFrame)return function(e){l.mozRequestAnimationFrame(e)};if(l.webkitRequestAnimationFrame)return function(e){l.webkitRequestAnimationFrame(e)};if(l.msRequestAnimationFrame)return function(e){l.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(we())}),1e3/60)}}(),_e=function(e){return Ee(e)},Te=we,De=9261,Ce=5381,Ne=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:De;!(t=e.next()).done;)n=65599*n+t.value|0;return n},Ae=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:De)+e|0},Le=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ce;return(t<<5)+t+e|0},ke=function(e){return 2097152*e[0]+e[1]},Se=function(e,t){return[Ae(e[0],t[0]),Le(e[1],t[1])]},Ie=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return Ne({next:function(){return r=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Qe=function(e){e.splice(0,e.length)},Je=function(e,t,n){return n&&(t=S(n,t)),e[t]},et=function(e,t,n,r){n&&(t=S(n,t)),e[t]=r},tt="undefined"!=typeof Map?Map:function(){function e(){t(this,e),this._obj={}}return i(e,[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}]),e}(),nt=function(){function e(n){if(t(this,e),this._obj=Object.create(null),this.size=0,null!=n){var r;r=null!=n.instanceString&&n.instanceString()===this.instanceString()?n.toArray():n;for(var i=0;i2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&T(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new rt,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];y(t.classes)?l=t.classes:f(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,i,a,o){var s;if(null==i&&(i=0),null==o&&(o=n),i<0)throw new Error("lo must be non-negative");for(null==a&&(a=e.length);in;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;af;0<=f?++d:--d)v.push(a(e,r));return v},g=function(e,t,r,i){var a,o,s;for(null==i&&(i=n),a=e[r];r>t&&i(a,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=a},f=function(e,t,r){var i,a,o,s,l;for(null==r&&(r=n),a=e.length,l=t,o=e[t],i=2*t+1;i0;){var _=b.pop(),T=v(_),D=_.id();if(h[D]=T,T!==1/0)for(var C=_.neighborhood().intersect(p),N=0;N0)for(n.unshift(t);c[i];){var a=c[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},ht={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t0;){if(l=v.pop(),u=l.id(),y.delete(u),w++,u===d){for(var E=[],_=i,T=d,D=b[T];E.unshift(_),null!=D&&E.unshift(D),null!=(_=m[T]);)D=b[T=_.id()];return{found:!0,distance:p[u],path:this.spawn(E),steps:w}}f[u]=!0;for(var C=l._private.edges,N=0;NN&&(p[C]=N,m[C]=D,b[C]=w),!i){var A=D*u+T;!i&&p[A]>N&&(p[A]=N,m[A]=T,b[A]=w)}}}for(var L=0;L1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=b(e);;){if(null==i)return t.spawn();var o=m(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},hasNegativeWeightCycle:g,negativeWeightCycles:v}}},mt=Math.sqrt(2),bt=function(e,t,n){0===n.length&&Ve("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],i=r[1],a=r[2],o=t[i],s=t[a],l=n,u=l.length-1;u>=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;pr;){var i=Math.floor(Math.random()*t.length);t=bt(i,e,t),n--}return t},wt={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/mt);if(!(i<2)){for(var l=[],u=0;u0?1:e<0?-1:0},At=function(e,t){return Math.sqrt(Lt(e,t))},Lt=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},kt=function(e){for(var t=e.length,n=0,r=0;r=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},Pt=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},Rt=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Bt=function(e){var t,n,r,i,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===a.length)t=n=r=i=a[0];else if(2===a.length)t=r=a[0],i=n=a[1];else if(4===a.length){var s=o(a,4);t=s[0],n=s[1],r=s[2],i=s[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Ft=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},zt=function(e,t){return!(e.x1>t.x2||t.x1>e.x2||e.x2t.y2||t.y1>e.y2)},Gt=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},Yt=function(e,t){return Gt(e,t.x1,t.y1)&&Gt(e,t.x2,t.y2)},Xt=function(e,t,n,r,i,a,o){var s,l=sn(i,a),u=i/2,c=a/2,h=r-c-o;if((s=en(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=en(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=en(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=en(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=Qt(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=Qt(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=Qt(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,_=r+c-l;return(g=Qt(e,t,n,r,E,_,l+o)).length>0&&g[0]<=E&&g[1]>=_?[g[0],g[1]]:[]},Vt=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Ut=function(e,t,n,r,i,a,o,s,l){var u=Math.min(n,o,i)-l,c=Math.max(n,o,i)+l,h=Math.min(r,s,a)-l,d=Math.max(r,s,a)+l;return!(ec||td)},jt=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g,f,v,y,m,b,x,w=[];u=9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,c=3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,h=1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,0===(l=1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s)&&(l=1e-5),f=-27*(h/=l)+(u/=l)*(9*(c/=l)-u*u*2),p=(g=(3*c-u*u)/9)*g*g+(f/=54)*f,(d=w)[1]=0,b=u/3,p>0?(y=(y=f+Math.sqrt(p))<0?-Math.pow(-y,1/3):Math.pow(y,1/3),m=(m=f-Math.sqrt(p))<0?-Math.pow(-m,1/3):Math.pow(m,1/3),d[0]=-b+y+m,b+=(y+m)/2,d[4]=d[2]=-b,b=Math.sqrt(3)*(-m+y)/2,d[3]=b,d[5]=-b):(d[5]=d[3]=0,0===p?(x=f<0?-Math.pow(-f,1/3):Math.pow(f,1/3),d[0]=2*x-b,d[4]=d[2]=-(x+b)):(v=(g=-g)*g*g,v=Math.acos(f/Math.sqrt(v)),x=2*Math.sqrt(g),d[0]=-b+x*Math.cos(v/3),d[2]=-b+x*Math.cos((v+2*Math.PI)/3),d[4]=-b+x*Math.cos((v+4*Math.PI)/3)));for(var E=[],_=0;_<6;_+=2)Math.abs(w[_+1])<1e-7&&w[_]>=0&&w[_]<=1&&E.push(w[_]);E.push(1),E.push(0);for(var T,D,C,N=-1,A=0;A=0?Cl?(e-i)*(e-i)+(t-a)*(t-a):u-h},Ht=function(e,t,n){for(var r,i,a,o,s=0,l=0;l=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},Wt=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g0){var f=Kt(c,-l);h=$t(f)}else h=c;return Ht(e,t,h)},$t=function(e){for(var t,n,r,i,a,o,s,l,u=new Array(e.length/2),c=0;c=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},Jt=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},en=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?Jt(e,n,o)===o?[o,s]:Jt(e,n,i)===i?[i,a]:Jt(i,o,n)===n?[n,r]:[]:[]},tn=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y0){var m=Kt(f,-s);u=$t(m)}else u=f}else u=n;for(var b=0;bu&&(u=t)},get:function(e){return l[e]}},h=0;h0?b.edgesTo(m)[0]:m.edgesTo(b)[0];var x=r(y);m=m.id(),h[m]>h[f]+x&&(h[m]=h[f]+x,d.nodes.indexOf(m)<0?d.push(m):d.updateItem(m),u[m]=0,l[m]=[]),h[m]==h[f]+x&&(u[m]=u[m]+u[f],l[m].push(f))}else for(var w=0;w0;){for(var D=n.pop(),C=0;C0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i}(c,l,t,r);return function(e){for(var t=0;t5&&void 0!==arguments[5]?arguments[5]:An,o=r,s=0;s=2?On(e,t,n,0,Sn,In):On(e,t,n,0,kn)},squaredEuclidean:function(e,t,n){return On(e,t,n,0,Sn)},manhattan:function(e,t,n){return On(e,t,n,0,kn)},max:function(e,t,n){return On(e,t,n,-1/0,Mn)}};function Rn(e,t,n,r,i,a){var o;return o=v(e)?e:Pn[e]||Pn.euclidean,0===t&&v(e)?o(i,a):o(t,n,r,i,a)}Pn["squared-euclidean"]=Pn.squaredEuclidean,Pn.squaredeuclidean=Pn.squaredEuclidean;var Bn=Ke({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),Fn=function(e){return Bn(e)},zn=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return Rn(e,r.length,a,(function(e){return r[e](t)}),o,s)},Gn=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;ln)return!1;return!0},Un=function(e,t,n){for(var r=0;ri&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;vn[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;io&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;u=N?(A=N,N=k,L=S):k>A&&(A=k);for(var I=0;I0?1:0;T[_%u.minIterations*t+F]=z,B+=z}if(B>0&&(_>=u.minIterations-1||_==u.maxIterations-1)){for(var G=0,Y=0;Y0&&r.push(i);return r}(t,a,o),U=function(e,t,n){for(var r=ur(e,t,n),i=0;il&&(s=u,l=c)}n[i]=a[s]}return ur(e,t,n)}(t,r,V),j={},q=0;q1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],v=[];for(v=p(i);1!=v.length;)0==c[v[0]].length?(g.unshift(l.getElementById(v.shift())),g.unshift(l.getElementById(v.shift()))):v=p(v.shift()).concat(v);for(var y in g.unshift(l.getElementById(v.shift())),c)if(c[y].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},gr=function(){var e=this,t={},n=0,r=0,i=[],a=[],o={},s=function s(l,u,c){l===c&&(r+=1),t[u]={id:n,low:n++,cutVertex:!1};var h,d,p,g,f=e.getElementById(u).connectedEdges().intersection(e);0===f.size()?i.push(e.spawn(e.getElementById(u))):f.forEach((function(n){h=n.source().id(),d=n.target().id(),(p=h===u?d:h)!==c&&(g=n.id(),o[g]||(o[g]=!0,a.push({x:u,y:p,edge:n})),p in t?t[u].low=Math.min(t[u].low,t[p].id):(s(l,p,u),t[u].low=Math.min(t[u].low,t[p].low),t[u].id<=t[p].low&&(t[u].cutVertex=!0,function(n,r){for(var o=a.length-1,s=[],l=e.spawn();a[o].x!=n||a[o].y!=r;)s.push(a.pop().edge),o--;s.push(a.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),i=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(i.filter((function(e){return e.isLoop()}))):l.merge(i)}))})),i.push(l)}(u,p))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,s(n,n),t[n].cutVertex=r>1)}}));var l=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(l),components:i}},fr=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},vr={};[ot,ct,ht,pt,ft,yt,wt,hn,pn,fn,yn,Nn,Zn,ar,hr,pr,{hopcroftTarjanBiconnected:gr,htbc:gr,htb:gr,hopcroftTarjanBiconnectedComponents:gr},{tarjanStronglyConnected:fr,tsc:fr,tscc:fr,tarjanStronglyConnectedComponents:fr}].forEach((function(e){z(vr,e)}));var yr=function e(t){if(!(this instanceof e))return new e(t);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof t&&t.call(this,this.fulfill.bind(this),this.reject.bind(this))};yr.prototype={fulfill:function(e){return mr(this,1,"fulfillValue",e)},reject:function(e){return mr(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new yr;return n.onFulfilled.push(wr(e,r,"fulfill")),n.onRejected.push(wr(t,r,"reject")),br(n),r.proxy}};var mr=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,br(e)),e},br=function(e){1===e.state?xr(e,"onFulfilled",e.fulfillValue):2===e.state&&xr(e,"onRejected",e.rejectReason)},xr=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var i=function(){for(var e=0;e0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n-1};var ci=function(e,t){var n=this.__data__,r=ai(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this};function hi(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){y(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,i=[],a=0,o=n.length;a0&&this.spawn(i).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};Ki.className=Ki.classNames=Ki.classes;var Zi={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:M,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};Zi.variable="(?:[\\w-.]|(?:\\\\"+Zi.metaChar+"))+",Zi.className="(?:[\\w-]|(?:\\\\"+Zi.metaChar+"))+",Zi.value=Zi.string+"|"+Zi.number,Zi.id=Zi.variable,function(){var e,t,n;for(e=Zi.comparatorOp.split("|"),n=0;n=0||"="!==t&&(Zi.comparatorOp+="|\\!"+t)}();var Qi=0,Ji=1,ea=2,ta=3,na=4,ra=5,ia=6,aa=7,oa=8,sa=9,la=10,ua=11,ca=12,ha=13,da=14,pa=15,ga=16,fa=17,va=18,ya=19,ma=20,ba=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return function(e,t){return-1*F(e,t)}(e.selector,t.selector)})),xa=function(){for(var e,t={},n=0;n0&&u.edgeCount>0)return je("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return je("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&je("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return f(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(i,a){return i.checks.reduce((function(o,s,l){return o+(a===i&&0===l?"$":"")+function(i,a){var o=i.type,s=i.value;switch(o){case Qi:var l=e(s);return l.substring(0,l.length-1);case ta:var u=i.field,c=i.operator;return"["+u+n(e(c))+t(s)+"]";case ra:var h=i.operator,d=i.field;return"["+e(h)+d+"]";case na:return"["+i.field+"]";case ia:var p=i.operator;return"[["+i.field+n(e(p))+t(s)+"]]";case aa:return s;case oa:return"#"+s;case sa:return"."+s;case fa:case pa:return r(i.parent,a)+n(">")+r(i.child,a);case va:case ga:return r(i.ancestor,a)+" "+r(i.descendant,a);case ya:var g=r(i.left,a),f=r(i.subject,a),v=r(i.right,a);return g+(g.length>0?" ":"")+f+v;case ma:return""}}(s,a)}),"")},i="",a=0;a1&&a=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(i=o||s?""+e:"",a=""+n),u&&(e=i=i.toLowerCase(),n=a=a.toLowerCase()),t){case"*=":r=i.indexOf(a)>=0;break;case"$=":r=i.indexOf(a,i.length-a.length)>=0;break;case"^=":r=0===i.indexOf(a);break;case"=":r=e===n;break;case">":h=!0,r=e>n;break;case">=":h=!0,r=e>=n;break;case"<":h=!0,r=e0;){var u=i.shift();t(u),a.add(u.id()),o&&r(i,a,u)}return e}function Ga(e,t,n){if(n.isParent())for(var r=n._private.children,i=0;i1&&void 0!==arguments[1])||arguments[1],Ga)},Fa.forEachUp=function(e){return za(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Ya)},Fa.forEachUpAndDown=function(e){return za(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Xa)},Fa.ancestors=Fa.parents,(Pa=Ra={data:Wi.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:Wi.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:Wi.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:Wi.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:Wi.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:Wi.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=Pa.data,Pa.removeAttr=Pa.removeData;var Va,Ua,ja=Ra,qa={};function Ha(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,i=n[0],a=i._private.edges,o=0;ot})),minIndegree:Wa("indegree",(function(e,t){return et})),minOutdegree:Wa("outdegree",(function(e,t){return et}))}),z(qa,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r0,c=u;u&&(l=l[0]);var h=c?l.position():{x:0,y:0};return i={x:s.x-h.x,y:s.y-h.y},void 0===e?i:i[e]}for(var d=0;d0,y=v;v&&(g=g[0]);var b=y?g.position():{x:0,y:0};void 0!==t?p.position(e,t+b[e]):void 0!==i&&p.position({x:i.x+b.x,y:i.y+b.y})}}else if(!a)return;return this}}).modelPosition=Va.point=Va.position,Va.modelPositions=Va.points=Va.positions,Va.renderedPoint=Va.renderedPosition,Va.relativePoint=Va.relativePosition;var Za,Qa,Ja=Ua;Za=Qa={},Qa.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),i=n.pan(),a=t.x1*r+i.x,o=t.x2*r+i.x,s=t.y1*r+i.y,l=t.y2*r+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},Qa.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},Qa.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,i={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},a=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==a.w&&0!==a.h||((a={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-a.w/2,a.x2=o.x+a.w/2,a.y1=o.y-a.h/2,a.y2=o.y+a.h/2);var s=i.width.left.value;"px"===i.width.left.units&&i.width.val>0&&(s=100*s/i.width.val);var l=i.width.right.value;"px"===i.width.right.units&&i.width.val>0&&(l=100*l/i.width.val);var u=i.height.top.value;"px"===i.height.top.units&&i.height.val>0&&(u=100*u/i.height.val);var c=i.height.bottom.value;"px"===i.height.bottom.units&&i.height.val>0&&(c=100*c/i.height.val);var h=y(i.width.val-a.w,s,l),d=h.biasDiff,p=h.biasComplementDiff,g=y(i.height.val-a.h,u,c),f=g.biasDiff,v=g.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(a.w,a.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(a.w,i.width.val),o.x=(-d+a.x1+a.x2+p)/2,t.autoHeight=Math.max(a.h,i.height.val),o.y=(-f+a.y1+a.y2+v)/2}function y(e,t,n){var r=0,i=0,a=t+n;return e>0&&a>0&&(r=t/a*e,i=n/a*e),{biasDiff:r,biasComplementDiff:i}}}for(var r=0;re.x2?r:e.x2,e.y1=ne.y2?i:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},no=function(e,t){return null==t?e:to(e,t.x1,t.y1,t.x2,t.y2)},ro=function(e,t,n){return Je(e,t,n)},io=function(e,t,n){if(!t.cy().headless()){var r,i,a=t._private,o=a.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,i=o.srcY):"target"===n?(r=o.tgtX,i=o.tgtY):(r=o.midX,i=o.midY);var l=a.arrowBounds=a.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=i-s,u.x2=r+s,u.y2=i+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,Rt(u,1),to(e,u.x1,u.y1,u.x2,u.y2)}}},ao=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var i=t._private,a=i.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),h=t.pstyle("text-valign"),d=ro(a,"labelWidth",n),p=ro(a,"labelHeight",n),g=ro(a,"labelX",n),f=ro(a,"labelY",n),v=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,_=p,T=d,D=T/2,C=_/2;if(m)o=g-D,s=g+D,l=f-C,u=f+C;else{switch(c.value){case"left":o=g-T,s=g;break;case"center":o=g-D,s=g+D;break;case"right":o=g,s=g+T}switch(h.value){case"top":l=f-_,u=f;break;case"center":l=f-C,u=f+C;break;case"bottom":l=f,u=f+_}}o+=v-Math.max(x,w)-E-2,s+=v+Math.max(x,w)+E+2,l+=y-Math.max(x,w)-E-2,u+=y+Math.max(x,w)+E+2;var N=n||"main",A=i.labelBounds,L=A[N]=A[N]||{};L.x1=o,L.y1=l,L.x2=s,L.y2=u,L.w=s-o,L.h=u-l;var k=m&&"autorotate"===b.strValue,S=null!=b.pfValue&&0!==b.pfValue;if(k||S){var I=k?ro(i.rstyle,"labelAngle",n):b.pfValue,M=Math.cos(I),O=Math.sin(I),P=(o+s)/2,R=(l+u)/2;if(!m){switch(c.value){case"left":P=s;break;case"right":P=o}switch(h.value){case"top":R=u;break;case"bottom":R=l}}var B=function(e,t){return{x:(e-=P)*M-(t-=R)*O+P,y:e*O+t*M+R}},F=B(o,l),z=B(o,u),G=B(s,l),Y=B(s,u);o=Math.min(F.x,z.x,G.x,Y.x),s=Math.max(F.x,z.x,G.x,Y.x),l=Math.min(F.y,z.y,G.y,Y.y),u=Math.max(F.y,z.y,G.y,Y.y)}var X=N+"Rot",V=A[X]=A[X]||{};V.x1=o,V.y1=l,V.x2=s,V.y2=u,V.w=s-o,V.h=u-l,to(e,o,l,s,u),to(i.labelBounds.all,o,l,s,u)}return e}},oo=function(e){var t=0,n=function(e){return(e?1:0)<(r=A[1].x)){var L=n;n=r,r=L}if(i>(a=A[1].y)){var k=i;i=a,a=k}to(d,n-_,i-_,r+_,a+_)}}else if("bezier"===N||"unbundled-bezier"===N||"segments"===N||"taxi"===N){var S;switch(N){case"bezier":case"unbundled-bezier":S=v.bezierPts;break;case"segments":case"taxi":S=v.linePts}if(null!=S)for(var I=0;I(r=P.x)){var R=n;n=r,r=R}if((i=O.y)>(a=P.y)){var B=i;i=a,a=B}to(d,n-=_,i-=_,r+=_,a+=_)}if(c&&t.includeEdges&&f&&(io(d,e,"mid-source"),io(d,e,"mid-target"),io(d,e,"source"),io(d,e,"target")),c&&"yes"===e.pstyle("ghost").value){var F=e.pstyle("ghost-offset-x").pfValue,z=e.pstyle("ghost-offset-y").pfValue;to(d,d.x1+F,d.y1+z,d.x2+F,d.y2+z)}var G=p.bodyBounds=p.bodyBounds||{};Ft(G,d),Bt(G,y),Rt(G,1),c&&(n=d.x1,r=d.x2,i=d.y1,a=d.y2,to(d,n-E,i-E,r+E,a+E));var Y=p.overlayBounds=p.overlayBounds||{};Ft(Y,d),Bt(Y,y),Rt(Y,1);var X=p.labelBounds=p.labelBounds||{};null!=X.all?((l=X.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):X.all=Ot(),c&&t.includeLabels&&(t.includeMainLabels&&ao(d,e,null),f&&(t.includeSourceLabels&&ao(d,e,"source"),t.includeTargetLabels&&ao(d,e,"target")))}return d.x1=eo(d.x1),d.y1=eo(d.y1),d.x2=eo(d.x2),d.y2=eo(d.y2),d.w=eo(d.x2-d.x1),d.h=eo(d.y2-d.y1),d.w>0&&d.h>0&&b&&(Bt(d,y),Rt(d,1)),d}(e,uo),r.bbCache=n,r.bbCachePosKey=o):n=r.bbCache,!a){var c=e.isNode();n=Ot(),(t.includeNodes&&c||t.includeEdges&&!c)&&(t.includeOverlays?no(n,r.overlayBounds):no(n,r.bodyBounds)),t.includeLabels&&(t.includeMainLabels&&(!i||t.includeSourceLabels&&t.includeTargetLabels)?no(n,r.labelBounds.all):(t.includeMainLabels&&no(n,r.labelBounds.mainRot),t.includeSourceLabels&&no(n,r.labelBounds.sourceRot),t.includeTargetLabels&&no(n,r.labelBounds.targetRot))),n.w=n.x2-n.x1,n.h=n.y2-n.y1}return n},uo={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeMainLabels:!0,includeSourceLabels:!0,includeTargetLabels:!0,includeOverlays:!0,includeUnderlays:!0,useCache:!0},co=oo(uo),ho=Ke(uo);Qa.boundingBox=function(e){var t;if(1!==this.length||null==this[0]._private.bbCache||this[0]._private.styleDirty||void 0!==e&&void 0!==e.useCache&&!0!==e.useCache){t=Ot();var n=ho(e=e||uo),r=this;if(r.cy().styleEnabled())for(var i=0;i0&&void 0!==arguments[0]?arguments[0]:No,t=arguments.length>1?arguments[1]:void 0,n=0;n=0;s--)o(s);return this},Lo.removeAllListeners=function(){return this.removeListener("*")},Lo.emit=Lo.trigger=function(e,t,n){var r=this.listeners,i=r.length;return this.emitting++,y(t)||(t=[t]),Io(this,(function(e,a){null!=n&&(r=[{event:a.event,type:a.type,namespace:a.namespace,callback:n}],i=r.length);for(var o=function(n){var i=r[n];if(i.type===a.type&&(!i.namespace||i.namespace===a.namespace||".*"===i.namespace)&&e.eventMatches(e.context,i,a)){var o=[a];null!=t&&function(e,t){for(var n=0;n1&&!r){var i=this.length-1,a=this[i],o=a._private.data.id;this[i]=void 0,this[e]=a,n.set(o,{ele:a,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var i=r.index;return this.unmergeAt(i),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&f(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r=0;t--)e(this[t])&&this.unmergeAt(t);return this},map:function(e,t){for(var n=[],r=this,i=0;ir&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,i=this,a=0;a=0&&i1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){this.cleanStyle();var i=n._private.style[e];return null!=i?i:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=n.style();if(m(e)){var i=e;r.applyBypass(this,i,false),this.emitAndNotify("style")}else if(f(e)){if(void 0===t){var a=this[0];return a?r.getStylePropertyValue(a,e):void 0}r.applyBypass(this,e,t,false),this.emitAndNotify("style")}else if(void 0===e){var o=this[0];return o?r.getRawStyle(o):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=t.style(),r=this;if(void 0===e)for(var i=0;i0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),rs.neighbourhood=rs.neighborhood,rs.closedNeighbourhood=rs.closedNeighborhood,rs.openNeighbourhood=rs.openNeighborhood,z(rs,{source:Ba((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:Ba((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:ss({attr:"source"}),targets:ss({attr:"target"})}),z(rs,{edgesWith:Ba(ls(),"edgesWith"),edgesTo:Ba(ls({thisIsSrc:!0}),"edgesTo")}),z(rs,{connectedEdges:Ba((function(e){for(var t=[],n=0;n0);return a},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),rs.componentsOf=rs.components;var cs=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var i=new tt,a=!1;if(t){if(t.length>0&&m(t[0])&&!E(t[0])){a=!0;for(var o=[],s=new rt,l=0,u=t.length;l0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this,a=i.cy(),o=a._private,s=[],l=[],u=0,c=i.length;u0){for(var B=e.length===i.length?i:new cs(a,e),F=0;F0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],i={},a=n._private.cy;function o(e){var n=i[e.id()];t&&e.removed()||n||(i[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n0&&(e?_.emitAndNotify("remove"):t&&_.emit("remove"));for(var T=0;T=.001?function(t,r){for(var a=0;a0?i=l:r=l}while(Math.abs(s)>a&&++uh&&Math.abs(s.v)>h;);return a?function(e){return u[e*(u.length-1)|0]}:c}}(),fs=function(e,t,n,r){var i=ps(e,t,n,r);return function(e,t,n){return e+(t-e)*i(n)}},vs={linear:function(e,t,n){return e+(t-e)*n},ease:fs(.25,.1,.25,1),"ease-in":fs(.42,0,1,1),"ease-out":fs(0,0,.58,1),"ease-in-out":fs(.42,0,.58,1),"ease-in-sine":fs(.47,0,.745,.715),"ease-out-sine":fs(.39,.575,.565,1),"ease-in-out-sine":fs(.445,.05,.55,.95),"ease-in-quad":fs(.55,.085,.68,.53),"ease-out-quad":fs(.25,.46,.45,.94),"ease-in-out-quad":fs(.455,.03,.515,.955),"ease-in-cubic":fs(.55,.055,.675,.19),"ease-out-cubic":fs(.215,.61,.355,1),"ease-in-out-cubic":fs(.645,.045,.355,1),"ease-in-quart":fs(.895,.03,.685,.22),"ease-out-quart":fs(.165,.84,.44,1),"ease-in-out-quart":fs(.77,0,.175,1),"ease-in-quint":fs(.755,.05,.855,.06),"ease-out-quint":fs(.23,1,.32,1),"ease-in-out-quint":fs(.86,0,.07,1),"ease-in-expo":fs(.95,.05,.795,.035),"ease-out-expo":fs(.19,1,.22,1),"ease-in-out-expo":fs(1,0,0,1),"ease-in-circ":fs(.6,.04,.98,.335),"ease-out-circ":fs(.075,.82,.165,1),"ease-in-out-circ":fs(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return vs.linear;var r=gs(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":fs};function ys(e,t,n,r,i){if(1===r)return n;if(t===n)return n;var a=i(t,n,r);return null==e||((e.roundValue||e.color)&&(a=Math.round(a)),void 0!==e.min&&(a=Math.max(a,e.min)),void 0!==e.max&&(a=Math.min(a,e.max))),a}function ms(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function bs(e,t,n,r,i){var a=null!=i?i.type:null;n<0?n=0:n>1&&(n=1);var o=ms(e,i),s=ms(t,i);if(b(o)&&b(s))return ys(a,o,s,n,r);if(y(o)&&y(s)){for(var l=[],u=0;u0?("spring"===h&&d.push(o.duration),o.easingImpl=vs[h].apply(null,d)):o.easingImpl=vs[h]}var p,g=o.easingImpl;if(p=0===o.duration?1:(n-l)/o.duration,o.applying&&(p=o.progress),p<0?p=0:p>1&&(p=1),null==o.delay){var v=o.startPosition,y=o.position;if(y&&i&&!e.locked()){var m={};ws(v.x,y.x)&&(m.x=bs(v.x,y.x,p,g)),ws(v.y,y.y)&&(m.y=bs(v.y,y.y,p,g)),e.position(m)}var b=o.startPan,x=o.pan,w=a.pan,E=null!=x&&r;E&&(ws(b.x,x.x)&&(w.x=bs(b.x,x.x,p,g)),ws(b.y,x.y)&&(w.y=bs(b.y,x.y,p,g)),e.emit("pan"));var _=o.startZoom,T=o.zoom,D=null!=T&&r;D&&(ws(_,T)&&(a.zoom=Mt(a.minZoom,bs(_,T,p,g),a.maxZoom)),e.emit("zoom")),(E||D)&&e.emit("viewport");var C=o.style;if(C&&C.length>0&&i){for(var N=0;N=0;t--)(0,e[t])();e.splice(0,e.length)},c=a.length-1;c>=0;c--){var h=a[c],d=h._private;d.stopped?(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.frames)):(d.playing||d.applying)&&(d.playing&&d.applying&&(d.applying=!1),d.started||Es(0,h,e),xs(t,h,e,n),d.applying&&(d.applying=!1),u(d.frames),null!=d.step&&d.step(e),h.completed()&&(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.completes)),s=!0)}return n||0!==a.length||0!==o.length||r.push(t),s}for(var a=!1,o=0;o0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var Ts={animate:Wi.animate(),animation:Wi.animation(),animated:Wi.animated(),clearQueue:Wi.clearQueue(),delay:Wi.delay(),delayAnimation:Wi.delayAnimation(),stop:Wi.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){_s(n,e)}),t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&_e((function(n){_s(n,e),t()}))}()}}},Ds={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&E(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},Cs=function(e){return f(e)?new Ia(e):e},Ns={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new Ao(Ds,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,Cs(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,Cs(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,Cs(t),n),this},once:function(e,t,n){return this.emitter().one(e,Cs(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};Wi.eventAliasesOn(Ns);var As={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};As.jpeg=As.jpg;var Ls={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n,r=e.name,i=t.extension("layout",r);if(null!=i)return n=f(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$(),new i(z({},e,{cy:t,eles:n}));Ve("No such layout `"+r+"` found. Did you forget to import it and `cytoscape.use()` it?")}else Ve("A `name` must be specified to make a layout");else Ve("Layout options must be specified to make a layout")}};Ls.createLayout=Ls.makeLayout=Ls.layout;var ks={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var i=this.renderer();!this.destroyed()&&i&&i.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};Is.invalidateDimensions=Is.resize;var Ms={collection:function(e,t){return f(e)?this.$(e):w(e)?e.collection():y(e)?(t||(t={}),new cs(this,e,t.unique,t.removed)):new cs(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};Ms.elements=Ms.filter=Ms.$;var Os={},Ps="t";Os.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r0;if(d||h&&p){var g=void 0;d&&p||d?g=u.properties:p&&(g=u.mappedProperties);for(var f=0;f1&&(v=1),s.color){var E=i.valueMin[0],_=i.valueMax[0],T=i.valueMin[1],D=i.valueMax[1],C=i.valueMin[2],N=i.valueMax[2],A=null==i.valueMin[3]?1:i.valueMin[3],L=null==i.valueMax[3]?1:i.valueMax[3],k=[Math.round(E+(_-E)*v),Math.round(T+(D-T)*v),Math.round(C+(N-C)*v),Math.round(A+(L-A)*v)];n={bypass:i.bypass,name:i.name,value:k,strValue:"rgb("+k[0]+", "+k[1]+", "+k[2]+")"}}else{if(!s.number)return!1;var S=i.valueMin+(i.valueMax-i.valueMin)*v;n=this.parse(i.name,S,i.bypass,d)}if(!n)return f(),!1;n.mapping=i,i=n;break;case o.data:for(var I=i.field.split("."),M=h.data,O=0;O0&&a>0){for(var s={},l=!1,u=0;u0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:a,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1)},Os.checkTrigger=function(e,t,n,r,i,a){var o=this.properties[t],s=i(o);null!=s&&s(n,r)&&a(o)},Os.checkZOrderTrigger=function(e,t,n,r){var i=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){i._private.cy.notify("zorder",e)}))},Os.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(i){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache(),!i.triggersBoundsOfParallelBeziers||("curve-style"!==t||"bezier"!==n&&"bezier"!==r)&&("display"!==t||"none"!==n&&"none"!==r)||e.parallelEdges().forEach((function(e){e.isBundledBezier()&&e.dirtyBoundingBoxCache()}))}))},Os.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r)};var Rs={applyBypass:function(e,t,n,r){var i=[];if("*"===t||"**"===t){if(void 0!==n)for(var a=0;at.length?a.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(a=a.replace(/[/][*](\s|.)+?[*][/]/g,"");!a.match(/^\s*$/);){var l=a.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){je("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+a);break}t=l[0];var u=l[1];if("core"!==u&&new Ia(u).invalid)je("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();else{var c=l[2],h=!1;n=c;for(var d=[];!n.match(/^\s*$/);){var p=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!p){je("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),h=!0;break}r=p[0];var g=p[1],f=p[2];this.properties[g]?i.parse(g,f)?(d.push({name:g,val:f}),s()):(je("Skipping property: Invalid property definition in: "+r),s()):(je("Skipping property: Invalid property name in: "+r),s())}if(h){o();break}i.selector(u);for(var v=0;v=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var d=s.data;return{name:e,value:u,strValue:""+t,mapped:d,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(h.multiple)return!1;var p=s.mapData;if(!h.color&&!h.number)return!1;var g=this.parse(e,c[4]);if(!g||g.mapped)return!1;var m=this.parse(e,c[5]);if(!m||m.mapped)return!1;if(g.pfValue===m.pfValue||g.strValue===m.strValue)return je("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+g.strValue+"`"),this.parse(e,g.strValue);if(h.color){var x=g.value,w=m.value;if(!(x[0]!==w[0]||x[1]!==w[1]||x[2]!==w[2]||x[3]!==w[3]&&(null!=x[3]&&1!==x[3]||null!=w[3]&&1!==w[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:p,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:g.value,valueMax:m.value,bypass:n}}}if(h.multiple&&"multiple"!==r){var E;if(E=l?t.split(/\s+/):y(t)?t:[t],h.evenMultiple&&E.length%2!=0)return null;for(var _=[],T=[],D=[],C="",N=!1,A=0;A0?" ":"")+k.strValue}return h.validate&&!h.validate(_,T)?null:h.singleEnum&&N?1===_.length&&f(_[0])?{name:e,value:_[0],strValue:_[0],bypass:n}:null:{name:e,value:_,pfValue:D,strValue:C,bypass:n,units:T}}var S,I,O=function(){for(var r=0;rh.max||h.strictMax&&t===h.max))return null;var z={name:e,value:t,strValue:""+t+(P||""),units:P,bypass:n};return h.unitless||"px"!==P&&"em"!==P?z.pfValue=t:z.pfValue="px"!==P&&P?this.getEmSizeInPixels()*t:t,"ms"!==P&&"s"!==P||(z.pfValue="ms"===P?t:1e3*t),"deg"!==P&&"rad"!==P||(z.pfValue="rad"===P?t:(S=t,Math.PI*S/180)),"%"===P&&(z.pfValue=t/100),z}if(h.propList){var Y=[],X=""+t;if("none"===X);else{for(var V=X.split(/\s*,\s*|\s+/),U=0;U0&&s>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:a=(a=(a=Math.min((o-2*t)/n.w,(s-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:a)=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,i=r.pan,a=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),b(e)?n=e:m(e)&&(n=e.level,null!=e.position?t=Et(e.position,a,i):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)t.maxZoom||!t.zoomingEnabled?a=!0:(t.zoom=s,i.push("zoom"))}if(r&&(!a||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;b(l.x)&&(t.pan.x=l.x,o=!1),b(l.y)&&(t.pan.y=l.y,o=!1),o||i.push("pan")}return i.length>0&&(i.push("viewport"),this.emit(i.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(f(e)){var n=e;e=this.mutableElements().filter(n)}else w(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),i=this.width(),a=this.height();return{x:(i-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(a-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container;return n.sizeCache=n.sizeCache||(r?(e=this.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};qs.centre=qs.center,qs.autolockNodes=qs.autolock,qs.autoungrabifyNodes=qs.autoungrabify;var Hs={data:Wi.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:Wi.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:Wi.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:Wi.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};Hs.attr=Hs.data,Hs.removeAttr=Hs.removeData;var Ws=function(e){var t=this,n=(e=z({},e)).container;n&&!x(n)&&x(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var i=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var a=void 0!==l&&void 0!==n&&!e.headless,o=e;o.layout=z({name:a?"grid":"null"},o.layout),o.renderer=z({name:a?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},u=this._private={container:n,ready:!1,options:o,elements:new cs(this),listeners:[],aniEles:new cs(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?a:o.styleEnabled,zoom:b(o.zoom)?o.zoom:1,pan:{x:m(o.pan)&&b(o.pan.x)?o.pan.x:0,y:m(o.pan)&&b(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});u.styleEnabled&&t.setStyle([]);var c=z({},o,o.renderer);t.initRenderer(c);!function(e,t){if(e.some(N))return _r.all(e).then(t);t(e)}([o.style,o.elements],(function(e){var n=e[0],a=e[1];u.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var i=t.mutableElements();i.length>0&&i.remove(),null!=e&&(m(e)||y(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var a=z({},t._private.options.layout);a.eles=t.elements(),t.layout(a).run()}(a,(function(){t.startAnimationLoop(),u.ready=!0,v(o.ready)&&t.on("ready",o.ready);for(var e=0;e0,u=Ot(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(w(n.roots))e=n.roots;else if(y(n.roots)){for(var c=[],h=0;h0;){var I=L.shift(),M=A(I,k);if(M)I.outgoers().filter((function(e){return e.isNode()&&i.has(e)})).forEach(S);else if(null===M){je("Detected double maximal shift for node `"+I.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}N();var O=0;if(n.avoidOverlap)for(var P=0;P0&&b[0].length<=3?l/2:0),h=2*Math.PI/b[r].length*i;return 0===r&&1===b[0].length&&(c=1),{x:W+c*Math.cos(h),y:$+c*Math.sin(h)}}return{x:W+(i+1-(a+1)/2)*o,y:(r+1)*s}})),this};var tl={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function nl(e){this.options=z({},tl,e)}nl.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));for(var o,s=Ot(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=(void 0===t.sweep?2*Math.PI-2*Math.PI/a.length:t.sweep)/Math.max(1,a.length-1),c=0,h=0;h1&&t.avoidOverlap){c*=1.75;var f=Math.cos(u)-Math.cos(0),v=Math.sin(u)-Math.sin(0),y=Math.sqrt(c*c/(f*f+v*v));o=Math.max(y,o)}return r.nodes().layoutPositions(this,t,(function(e,n){var r=t.startAngle+n*u*(i?1:-1),a=o*Math.cos(r),s=o*Math.sin(r);return{x:l.x+a,y:l.y+s}})),this};var rl,il={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function al(e){this.options=z({},il,e)}al.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,i=t.eles,a=i.nodes().not(":parent"),o=Ot(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s={x:o.x1+o.w/2,y:o.y1+o.h/2},l=[],u=0,c=0;c0&&Math.abs(y[0].value-b.value)>=f&&(y=[],v.push(y)),y.push(b)}var x=u+t.minNodeSpacing;if(!t.avoidOverlap){var w=v.length>0&&v[0].length>1,E=(Math.min(o.w,o.h)/2-x)/(v.length+w?1:0);x=Math.min(x,E)}for(var _=0,T=0;T1&&t.avoidOverlap){var A=Math.cos(N)-Math.cos(0),L=Math.sin(N)-Math.sin(0),k=Math.sqrt(x*x/(A*A+L*L));_=Math.max(k,_)}D.r=_,_+=x}if(t.equidistant){for(var S=0,I=0,M=0;M=e.numIter||(gl(r,e),r.temperature=r.temperature*e.coolingFactor,r.temperature=e.animationThreshold&&a(),_e(t)):(Cl(r,e),s())}();else{for(;u;)u=o(l),l++;Cl(r,e),s()}return this},sl.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},sl.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var ll=function(e,t,n){for(var r=n.eles.edges(),i=n.eles.nodes(),a=Ot(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:i.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:a.w,clientHeight:a.h,boundingBox:a},s=n.eles.components(),l={},u=0;u0)for(o.graphSet.push(E),u=0;ur.count?0:r.graph},cl=function e(t,n,r,i){var a=i.graphSet[r];if(-10)var s=(u=r.nodeOverlap*o)*i/(f=Math.sqrt(i*i+a*a)),l=u*a/f;else{var u,c=bl(e,i,a),h=bl(t,-1*i,-1*a),d=h.x-c.x,p=h.y-c.y,g=d*d+p*p,f=Math.sqrt(g);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/g)*d/f,l=u*p/f}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},ml=function(e,t,n,r){if(n>0)var i=e.maxX-t.minX;else i=t.maxX-e.minX;if(r>0)var a=e.maxY-t.minY;else a=t.maxY-e.minY;return i>=0&&a>=0?Math.sqrt(i*i+a*a):0},bl=function(e,t,n){var r=e.positionX,i=e.positionY,a=e.height||1,o=e.width||1,s=n/t,l=a/o,u={};return 0===t&&0n?(u.x=r,u.y=i+a/2,u):0t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=i-o*n/2/t,u):0=l)?(u.x=r+a*t/2/n,u.y=i+a/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-a*t/2/n,u.y=i-a/2,u):u},xl=function(e,t){for(var n=0;n1){var g=t.gravity*h/p,f=t.gravity*d/p;c.offsetX+=g,c.offsetY+=f}}}}},El=function(e,t){var n=[],r=0,i=-1;for(n.push.apply(n,e.graphSet[0]),i+=e.graphSet[0].length;r<=i;){var a=n[r++],o=e.idToIndex[a],s=e.layoutNodes[o],l=s.children;if(0n)var i={x:n*e/r,y:n*t/r};else i={x:e,y:t};return i},Dl=function e(t,n){var r=t.parentId;if(null!=r){var i=n.layoutNodes[n.idToIndex[r]],a=!1;return(null==i.maxX||t.maxX+i.padRight>i.maxX)&&(i.maxX=t.maxX+i.padRight,a=!0),(null==i.minX||t.minX-i.padLefti.maxY)&&(i.maxY=t.maxY+i.padBottom,a=!0),(null==i.minY||t.minY-i.padTopg&&(h+=p+t.componentSpacing,c=0,d=0,p=0)}}},Nl={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Al(e){this.options=z({},Nl,e)}Al.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));var a=Ot(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===a.h||0===a.w)r.nodes().layoutPositions(this,t,(function(e){return{x:a.x1,y:a.y1}}));else{var o=i.size(),s=Math.sqrt(o*a.h/a.w),l=Math.round(s),u=Math.round(a.w/a.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},h=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},d=t.rows,p=null!=t.cols?t.cols:t.columns;if(null!=d&&null!=p)l=d,u=p;else if(null!=d&&null==p)l=d,u=Math.ceil(o/l);else if(null==d&&null!=p)u=p,l=Math.ceil(o/u);else if(u*l>o){var g=c(),f=h();(g-1)*f>=o?c(g-1):(f-1)*g>=o&&h(f-1)}else for(;u*l=o?h(y+1):c(v+1)}var m=a.w/u,b=a.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x=u&&(S=0,k++)},M={},O=0;O(r=qt(e,t,x[w],x[w+1],x[w+2],x[w+3])))return v(n,r),!0}else if("bezier"===a.edgeType||"multibezier"===a.edgeType||"self"===a.edgeType||"compound"===a.edgeType)for(x=a.allpts,w=0;w+5(r=jt(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return v(n,r),!0;m=m||i.source,b=b||i.target;var E=o.getArrowWidth(l,c),_=[{name:"source",x:a.arrowStartX,y:a.arrowStartY,angle:a.srcArrowAngle},{name:"target",x:a.arrowEndX,y:a.arrowEndY,angle:a.tgtArrowAngle},{name:"mid-source",x:a.midX,y:a.midY,angle:a.midsrcArrowAngle},{name:"mid-target",x:a.midX,y:a.midY,angle:a.midtgtArrowAngle}];for(w=0;w<_.length;w++){var T=_[w],D=s.arrowShapes[n.pstyle(T.name+"-arrow-shape").value],C=n.pstyle("width").pfValue;if(D.roughCollide(e,t,E,T.angle,{x:T.x,y:T.y},C,d)&&D.collide(e,t,E,T.angle,{x:T.x,y:T.y},C,d))return v(n),!0}h&&u.length>0&&(y(m),y(b))}function b(e,t,n){return Je(e,t,n)}function x(n,r){var i,a=n._private,o=g;i=r?r+"-":"",n.boundingBox();var s=a.labelBounds[r||"main"],l=n.pstyle(i+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(a.rscratch,"labelX",r),c=b(a.rscratch,"labelY",r),h=b(a.rscratch,"labelAngle",r),d=n.pstyle(i+"text-margin-x").pfValue,p=n.pstyle(i+"text-margin-y").pfValue,f=s.x1-o-d,y=s.x2+o-d,m=s.y1-o-p,x=s.y2+o-p;if(h){var w=Math.cos(h),E=Math.sin(h),_=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},T=_(f,m),D=_(f,x),C=_(y,m),N=_(y,x),A=[T.x+d,T.y+p,C.x+d,C.y+p,N.x+d,N.y+p,D.x+d,D.y+p];if(Ht(e,t,A))return v(n),!0}else if(Gt(s,e,t))return v(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){for(var i=this.getCachedZSortedEles().interactive,a=[],o=Math.min(e,n),s=Math.max(e,n),l=Math.min(t,r),u=Math.max(t,r),c=Ot({x1:e=o,y1:t=l,x2:n=s,y2:r=u}),h=0;h0?Math.max(e-t,0):Math.min(e+t,0)},N=C(T,E),A=C(D,_),L=!1;"auto"===v?f=Math.abs(N)>Math.abs(A)?i:r:v===l||v===s?(f=r,L=!0):v!==a&&v!==o||(f=i,L=!0);var k,S=f===r,I=S?A:N,M=S?D:T,O=Nt(M),P=!1;L&&(m||x)||!(v===s&&M<0||v===l&&M>0||v===a&&M>0||v===o&&M<0)||(I=(O*=-1)*Math.abs(I),P=!0);var R=function(e){return Math.abs(e)=Math.abs(I)},B=R(k=m?(b<0?1+b:b)*I:(b<0?I:0)+b*O),F=R(Math.abs(I)-Math.abs(k));if(!B&&!F||P)if(S){var z=u.y1+k+(g?h/2*O:0),G=u.x1,Y=u.x2;n.segpts=[G,z,Y,z]}else{var X=u.x1+k+(g?c/2*O:0),V=u.y1,U=u.y2;n.segpts=[X,V,X,U]}else if(S){var j=Math.abs(M)<=h/2,q=Math.abs(T)<=d/2;if(j){var H=(u.x1+u.x2)/2,W=u.y1,$=u.y2;n.segpts=[H,W,H,$]}else if(q){var K=(u.y1+u.y2)/2,Z=u.x1,Q=u.x2;n.segpts=[Z,K,Q,K]}else n.segpts=[u.x1,u.y2]}else{var J=Math.abs(M)<=c/2,ee=Math.abs(D)<=p/2;if(J){var te=(u.y1+u.y2)/2,ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else if(ee){var ie=(u.x1+u.x2)/2,ae=u.y1,oe=u.y2;n.segpts=[ie,ae,ie,oe]}else n.segpts=[u.x2,u.y1]}},Xl.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,i=t.tgtPos,a=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,h=!b(n.startX)||!b(n.startY),d=!b(n.arrowStartX)||!b(n.arrowStartY),p=!b(n.endX)||!b(n.endY),g=!b(n.arrowEndX)||!b(n.arrowEndY),f=this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth*3,v=At({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),y=vd.poolIndex()){var p=h;h=d,d=p}var g=s.srcPos=h.position(),f=s.tgtPos=d.position(),v=s.srcW=h.outerWidth(),y=s.srcH=h.outerHeight(),m=s.tgtW=d.outerWidth(),x=s.tgtH=d.outerHeight(),w=s.srcShape=n.nodeShapes[t.getNodeShape(h)],E=s.tgtShape=n.nodeShapes[t.getNodeShape(d)];s.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var _=0;_0){var X=u,V=Lt(X,Tt(t)),U=Lt(X,Tt(Y)),j=V;U2&&Lt(X,{x:Y[2],y:Y[3]})0){var ie=c,ae=Lt(ie,Tt(t)),oe=Lt(ie,Tt(re)),se=ae;oe2&&Lt(ie,{x:re[2],y:re[3]})=u||m){c={cp:f,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-d)/x.length,E=x.t1-x.t0,_=s?x.t0+E*w:x.t1-E*w;_=Mt(0,_,1),t=It(b.p0,b.p1,b.p2,_),i=function(e,t,n,r){var i=Mt(0,r-.001,1),a=Mt(0,r+.001,1),o=It(e,t,n,i),s=It(e,t,n,a);return $l(o,s)}(b.p0,b.p1,b.p2,_);break;case"straight":case"segments":case"haystack":for(var T,D,C,N,A=0,L=r.allpts.length,k=0;k+3=u));k+=2);var S=(u-D)/T;S=Mt(0,S,1),t=function(e,t,n,r){var i=t.x-e.x,a=t.y-e.y,o=At(e,t),s=i/o,l=a/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(C,N,S),i=$l(C,N)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,i)}};u("source"),u("target"),this.applyLabelDimensions(e)}},Hl.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},Hl.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),i=this.calculateLabelDimensions(e,r),a=e.pstyle("line-height").pfValue,o=e.pstyle("text-wrap").strValue,s=Je(n.rscratch,"labelWrapCachedLines",t)||[],l="wrap"!==o?1:Math.max(s.length,1),u=i.height/l,c=u*a,h=i.width,d=i.height+(l-1)*(a-1)*u;et(n.rstyle,"labelWidth",t,h),et(n.rscratch,"labelWidth",t,h),et(n.rstyle,"labelHeight",t,d),et(n.rscratch,"labelHeight",t,d),et(n.rscratch,"labelLineHeight",t,c)},Hl.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",i=e.pstyle(r+"label").strValue,a=e.pstyle("text-transform").value,o=function(e,r){return r?(et(n.rscratch,e,t,r),r):Je(n.rscratch,e,t)};if(!i)return"";"none"==a||("uppercase"==a?i=i.toUpperCase():"lowercase"==a&&(i=i.toLowerCase()));var s=e.pstyle("text-wrap").value;if("wrap"===s){var l=o("labelKey");if(null!=l&&o("labelWrapKey")===l)return o("labelWrapCachedText");for(var u=i.split("\n"),c=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,d=[],p=/[\s\u200b]+/,g=h?"":" ",f=0;fc){for(var b=v.split(p),x="",w=0;wT);N++)D+=i[N],N===i.length-1&&(C=!0);return C||(D+="…"),D}return i},Hl.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},Hl.calculateLabelDimensions=function(e,t){var n=Ie(t,e._private.labelDimsKey),r=this.labelDimCache||(this.labelDimCache=[]),i=r[n];if(null!=i)return i;var a=e.pstyle("font-style").strValue,o=e.pstyle("font-size").pfValue,s=e.pstyle("font-family").strValue,l=e.pstyle("font-weight").strValue,u=this.labelCalcCanvas,c=this.labelCalcCanvasContext;if(!u){u=this.labelCalcCanvas=document.createElement("canvas"),c=this.labelCalcCanvasContext=u.getContext("2d");var h=u.style;h.position="absolute",h.left="-9999px",h.top="-9999px",h.zIndex="-1",h.visibility="hidden",h.pointerEvents="none"}c.font="".concat(a," ").concat(l," ").concat(o,"px ").concat(s);for(var d=0,p=0,g=t.split("\n"),f=0;f1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r=e.desktopTapThreshold2}var N=i(t);v&&(e.hoverData.tapholdCancelled=!0);n=!0,r(f,["mousemove","vmousemove","tapdrag"],t,{x:c[0],y:c[1]});var A=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:c[0],y:c[1]}}),g[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(v){var L={originalEvent:t,type:"cxtdrag",position:{x:c[0],y:c[1]}};m?m.emit(L):o.emit(L),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&f===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:c[0],y:c[1]}}),e.hoverData.cxtOver=f,f&&f.emit({originalEvent:t,type:"cxtdragover",position:{x:c[0],y:c[1]}}))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var k;if(e.hoverData.justStartedPan){var S=e.hoverData.mdownPos;k={x:(c[0]-S[0])*s,y:(c[1]-S[1])*s},e.hoverData.justStartedPan=!1}else k={x:x[0]*s,y:x[1]*s};o.panBy(k),o.emit("dragpan"),e.hoverData.dragged=!0}c=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=g[4]||null!=m&&!m.pannable()){if(m&&m.pannable()&&m.active()&&m.unactivate(),m&&m.grabbed()||f==y||(y&&r(y,["mouseout","tapdragout"],t,{x:c[0],y:c[1]}),f&&r(f,["mouseover","tapdragover"],t,{x:c[0],y:c[1]}),e.hoverData.last=f),m)if(v){if(o.boxSelectionEnabled()&&N)m&&m.grabbed()&&(h(w),m.emit("freeon"),w.emit("free"),e.dragData.didDrag&&(m.emit("dragfreeon"),w.emit("dragfree"))),A();else if(m&&m.grabbed()&&e.nodeIsDraggable(m)){var I=!e.dragData.didDrag;I&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||u(w,{inDragLayer:!0});var M={x:0,y:0};if(b(x[0])&&b(x[1])&&(M.x+=x[0],M.y+=x[1],I)){var O=e.hoverData.dragDelta;O&&b(O[0])&&b(O[1])&&(M.x+=O[0],M.y+=O[1])}e.hoverData.draggingEles=!0,w.silentShift(M).emit("position drag"),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(x[0]),t.push(x[1])):(t[0]+=x[0],t[1]+=x[1])}();n=!0}else v&&(e.hoverData.dragging||!o.boxSelectionEnabled()||!N&&o.panningEnabled()&&o.userPanningEnabled()?!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()&&a(m,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,g[4]=0,e.data.bgActivePosistion=Tt(d),e.redrawHint("select",!0),e.redraw()):A(),m&&m.pannable()&&m.active()&&m.unactivate());return g[2]=c[0],g[3]=c[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if(e.hoverData.capture){e.hoverData.capture=!1;var a=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,d=i(t);if(e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate(),3===e.hoverData.which){var p={originalEvent:t,type:"cxttapend",position:{x:o[0],y:o[1]}};if(c?c.emit(p):a.emit(p),!e.hoverData.cxtDragged){var g={originalEvent:t,type:"cxttap",position:{x:o[0],y:o[1]}};c?c.emit(g):a.emit(g)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=a.multiClickDebounceTime()?(m&&clearTimeout(m),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(m=setTimeout((function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),a.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||i(t)||(a.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=a.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===a.selectionType()||d?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):d||(a.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var f=a.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),f.length>0&&e.redrawHint("eles",!0),a.emit({type:"boxend",originalEvent:t,position:{x:o[0],y:o[1]}});"additive"===a.selectionType()||d||a.$(n).unmerge(f).unselect(),f.emit("box").stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit("boxselect"),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var v=c&&c.grabbed();h(u),v&&(c.emit("freeon"),u.emit("free"),e.dragData.didDrag&&(c.emit("dragfreeon"),u.emit("dragfree")))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null}}),!1);var _,T,D,C,N,A,L,k,S,I,M,O,P,R=function(t){if(!e.scrollingPage){var n=e.cy,r=n.zoom(),i=n.pan(),a=e.projectIntoViewport(t.clientX,t.clientY),o=[a[0]*r+i.x,a[1]*r+i.y];if(e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.cxtStarted||0!==e.selection[4])t.preventDefault();else if(n.panningEnabled()&&n.userPanningEnabled()&&n.zoomingEnabled()&&n.userZoomingEnabled()){var s;t.preventDefault(),e.data.wheelZooming=!0,clearTimeout(e.data.wheelTimeout),e.data.wheelTimeout=setTimeout((function(){e.data.wheelZooming=!1,e.redrawHint("eles",!0),e.redraw()}),150),s=null!=t.deltaY?t.deltaY/-250:null!=t.wheelDeltaY?t.wheelDeltaY/1e3:t.wheelDelta/1e3,s*=e.wheelSensitivity,1===t.deltaMode&&(s*=33);var l=n.zoom()*Math.pow(10,s);"gesturechange"===t.type&&(l=e.gestureStartZoom*t.scale),n.zoom({level:l,renderedPosition:{x:o[0],y:o[1]}}),n.emit("gesturechange"===t.type?"pinchzoom":"scrollzoom")}}};e.registerBinding(e.container,"wheel",R,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||R(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var B,F,z,G,Y,X,V,U=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},j=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",B=function(t){if(e.hasTouchStarted=!0,E(t)){p(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,i=e.touchData.now,a=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);i[0]=o[0],i[1]=o[1]}if(t.touches[1]&&(o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),i[2]=o[0],i[3]=o[1]),t.touches[2]&&(o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),i[4]=o[0],i[5]=o[1]),t.touches[1]){e.touchData.singleTouchMoved=!0,h(e.dragData.touchDragEles);var l=e.findContainerClientCoords();S=l[0],I=l[1],M=l[2],O=l[3],_=t.touches[0].clientX-S,T=t.touches[0].clientY-I,D=t.touches[1].clientX-S,C=t.touches[1].clientY-I,P=0<=_&&_<=M&&0<=D&&D<=M&&0<=T&&T<=O&&0<=C&&C<=O;var d=n.pan(),g=n.zoom();N=U(_,T,D,C),A=j(_,T,D,C),k=[((L=[(_+D)/2,(T+C)/2])[0]-d.x)/g,(L[1]-d.y)/g];if(A<4e4&&!t.touches[2]){var f=e.findNearestElement(i[0],i[1],!0,!0),v=e.findNearestElement(i[2],i[3],!0,!0);return f&&f.isNode()?(f.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=f):v&&v.isNode()?(v.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=v):n.emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var y=e.findNearestElements(i[0],i[1],!0,!0),m=y[0];if(null!=m&&(m.activate(),e.touchData.start=m,e.touchData.starts=y,e.nodeIsGrabbable(m))){var b=e.dragData.touchDragEles=n.collection(),x=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),m.selected()?(x=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),u(x,{addToList:b})):c(m,{addToList:b}),s(m);var w=function(e){return{originalEvent:t,type:e,position:{x:i[0],y:i[1]}}};m.emit(w("grabon")),x?x.forEach((function(e){e.emit(w("grab"))})):m.emit(w("grab"))}r(m,["touchstart","tapstart","vmousedown"],t,{x:i[0],y:i[1]}),null==m&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:i[0],y:i[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var R=e.touchData.startPosition=[null,null,null,null,null,null],B=0;B=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var w=t.touches[0].clientX-S,L=t.touches[0].clientY-I,M=t.touches[1].clientX-S,O=t.touches[1].clientY-I,R=j(w,L,M,O);if(R/A>=2.25||R>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var B={originalEvent:t,type:"cxttapend",position:{x:s[0],y:s[1]}};e.touchData.start?(e.touchData.start.unactivate().emit(B),e.touchData.start=null):o.emit(B)}}if(n&&e.touchData.cxt){B={originalEvent:t,type:"cxtdrag",position:{x:s[0],y:s[1]}},e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(B):o.emit(B),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var F=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&F===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:s[0],y:s[1]}}),e.touchData.cxtOver=F,F&&F.emit({originalEvent:t,type:"cxtdragover",position:{x:s[0],y:s[1]}}))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:s[0],y:s[1]}}),e.touchData.selecting=!0,e.touchData.didSelect=!0,i[4]=1,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),ee=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var z=0;z0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",z=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",G=function(t){var i=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var a=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o,s=e.cy,l=s.zoom(),u=e.touchData.now,c=e.touchData.earlier;if(t.touches[0]){var d=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);u[0]=d[0],u[1]=d[1]}if(t.touches[1]&&(d=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),u[2]=d[0],u[3]=d[1]),t.touches[2]&&(d=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),u[4]=d[0],u[5]=d[1]),i&&i.unactivate(),e.touchData.cxt){if(o={originalEvent:t,type:"cxttapend",position:{x:u[0],y:u[1]}},i?i.emit(o):s.emit(o),!e.touchData.cxtDragged){var p={originalEvent:t,type:"cxttap",position:{x:u[0],y:u[1]}};i?i.emit(p):s.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&s.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var g=s.collection(e.getAllInBox(a[0],a[1],a[2],a[3]));a[0]=void 0,a[1]=void 0,a[2]=void 0,a[3]=void 0,a[4]=0,e.redrawHint("select",!0),s.emit({type:"boxend",originalEvent:t,position:{x:u[0],y:u[1]}});g.emit("box").stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit("boxselect"),g.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=i&&i.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var f=e.dragData.touchDragEles;if(null!=i){var v=i._private.grabbed;h(f),e.redrawHint("drag",!0),e.redrawHint("eles",!0),v&&(i.emit("freeon"),f.emit("free"),e.dragData.didDrag&&(i.emit("dragfreeon"),f.emit("dragfree"))),r(i,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]}),i.unactivate(),e.touchData.start=null}else{var y=e.findNearestElement(u[0],u[1],!0,!0);r(y,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]})}var m=e.touchData.startPosition[0]-u[0],b=m*m,x=e.touchData.startPosition[1]-u[1],w=(b+x*x)*l*l;e.touchData.singleTouchMoved||(i||s.$(":selected").unselect(["tapunselect"]),r(i,["tap","vclick"],t,{x:u[0],y:u[1]}),Y=!1,t.timeStamp-V<=s.multiClickDebounceTime()?(X&&clearTimeout(X),Y=!0,V=null,r(i,["dbltap","vdblclick"],t,{x:u[0],y:u[1]})):(X=setTimeout((function(){Y||r(i,["onetap","voneclick"],t,{x:u[0],y:u[1]})}),s.multiClickDebounceTime()),V=t.timeStamp)),null!=i&&!e.dragData.didDrag&&i._private.selectable&&w2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),k=1;k0)return f[0]}return null},d=Object.keys(c),p=0;p0?l:Xt(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=sn(r,i),l=2*s;if(Wt(e,t,this.points,a,o,r,i-l,[0,-1],n))return!0;if(Wt(e,t,this.points,a,o,r-l,i,[0,-1],n))return!0;var u=r/2+2*n,c=i/2+2*n;return!!Ht(e,t,[a-u,o-c,a-u,o,a+u,o,a+u,o-c])||!!Zt(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!Zt(e,t,l,l,a-r/2+s,o+i/2-s,n)}}},registerNodeShapes:function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",rn(3,0)),this.generateRoundPolygon("round-triangle",rn(3,0)),this.generatePolygon("rectangle",rn(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",rn(5,0)),this.generateRoundPolygon("round-pentagon",rn(5,0)),this.generatePolygon("hexagon",rn(6,0)),this.generateRoundPolygon("round-hexagon",rn(6,0)),this.generatePolygon("heptagon",rn(7,0)),this.generateRoundPolygon("round-heptagon",rn(7,0)),this.generatePolygon("octagon",rn(8,0)),this.generateRoundPolygon("round-octagon",rn(8,0));var r=new Array(20),i=on(5,0),a=on(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s=e.deqFastCost*f)break}else if(i){if(p>=e.deqCost*l||p>=e.deqAvgCost*s)break}else if(g>=e.deqNoDrawCost*su)break;var v=e.deq(t,h,c);if(!(v.length>0))break;for(var y=0;y0&&(e.onDeqd(t,u),!i&&e.shouldRedraw(t,u,h,c)&&r())}),i(t))}}},uu=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Ge;t(this,e),this.idsByKey=new tt,this.keyForId=new tt,this.cachesByLvl=new tt,this.lvls=[],this.getKey=n,this.doesEleInvalidateKey=r}return i(e,[{key:"getIdsFor",value:function(e){null==e&&Ve("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new rt,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new tt,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}]),e}(),cu={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},hu=Ke({getKey:null,doesEleInvalidateKey:Ge,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:ze,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),du=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=hu(t);z(n,r),n.lookup=new uu(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},pu=du.prototype;pu.reasons=cu,pu.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},pu.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},pu.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new lt((function(e,t){return t.reqs-e.reqs}))},pu.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},pu.getElement=function(e,t,n,r,i){var a=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!a.allowEdgeTxrCaching&&e.isEdge()||!a.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(Ct(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,h=t.w*u,d=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,d))return null;var p,g=l.get(e,r);if(g&&g.invalidated&&(g.invalidated=!1,g.texture.invalidatedWidth-=g.width),g)return g;if(p=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||h>1024)return null;var f=a.getTextureQueue(p),v=f[f.length-2],y=function(){return a.recycleTexture(p,h)||a.addTexture(p,h)};v||(v=f[f.length-1]),v||(v=y()),v.width-v.usedWidthr;N--)D=a.getElement(e,t,n,N,cu.downscale);C()}else{var A;if(!x&&!w&&!E)for(var L=r-1;L>=-4;L--){var k=l.get(e,L);if(k){A=k;break}}if(b(A))return a.queueElement(e,r),A;v.context.translate(v.usedWidth,0),v.context.scale(u,u),this.drawElement(v.context,e,t,d,!1),v.context.scale(1/u,1/u),v.context.translate(-v.usedWidth,0)}return g={x:v.usedWidth,texture:v,level:r,scale:u,width:h,height:c,scaledLabelShown:d},v.usedWidth+=Math.ceil(h+8),v.eleCaches.push(g),l.set(e,r,g),a.checkTextureFullness(v),g},pu.invalidateElements=function(e){for(var t=0;t=.2*e.width&&this.retireTexture(e)},pu.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?Ze(t,e):e.fullnessChecks++},pu.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;Ze(n,e),e.retired=!0;for(var i=e.eleCaches,a=0;a=t)return a.retired=!1,a.usedWidth=0,a.invalidatedWidth=0,a.fullnessChecks=0,Qe(a.eleCaches),a.context.setTransform(1,0,0,1,0,0),a.context.clearRect(0,0,a.width,a.height),Ze(r,a),n.push(a),a}},pu.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),i=this.getKey(e),a=r[i];if(a)a.level=Math.max(a.level,t),a.eles.merge(e),a.reqs++,n.updateItem(a);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:i};n.push(o),r[i]=o}},pu.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),i=[],a=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=a.hasCache(u,s.level);if(r[l]=null,!c){i.push(s);var h=t.getBoundingBox(u);t.getElement(u,h,e,s.level,cu.dequeue)}}return i},pu.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),i=n[r];null!=i&&(1===i.eles.length?(i.reqs=Fe,t.updateItem(i),t.pop(),n[r]=null):i.eles.unmerge(e))},pu.onDequeue=function(e){this.onDequeues.push(e)},pu.offDequeue=function(e){Ze(this.onDequeues,e)},pu.setupDequeueing=lu({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},i=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};i(1),i(-1);for(var a=c.length-1;a>=0;a--){var o=c[a];o.invalid&&Ze(c,o)}}();var h=function(t){var i=(t=t||{}).after;if(function(){if(!o){o=Ot();for(var t=0;t16e6)return null;var a=r.makeLayer(o,n);if(null!=i){var s=c.indexOf(i)+1;c.splice(s,0,a)}else(void 0===t.insert||t.insert)&&c.unshift(a);return a};if(r.skipping&&!a)return null;for(var d=null,p=e.length/1,g=!a,f=0;f=p||!Yt(d.bb,v.boundingBox()))&&!(d=h({insert:!0,after:d})))return null;s||g?r.queueLayer(d,v):r.drawEleInLayer(d,v,n,t),d.eles.push(v),m[n]=d}}return s||(g?null:c)},fu.getEleLevelForLayerLevel=function(e,t){return e},fu.drawEleInLayer=function(e,t,n,r){var i=this.renderer,a=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),i.setImgSmoothing(a,!1),i.drawCachedElement(a,t,null,null,n,true),i.setImgSmoothing(a,!0))},fu.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,i=0;i0)return!1;if(a.invalid)return!1;r+=a.eles.length}return r===t.length},fu.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r0){e=!0;break}}return e},fu.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=Te(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},fu.invalidateLayer=function(e){if(this.lastInvalidationTime=Te(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];Ze(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var i=0;i3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!a||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=a?t.pstyle("opacity").value:1,c=a?t.pstyle("line-opacity").value:1,h=t.pstyle("curve-style").value,d=t.pstyle("line-style").value,p=t.pstyle("width").pfValue,g=t.pstyle("line-cap").value,f=u*c,v=u*c,y=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:f;"straight-triangle"===h?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=p,e.lineCap=g,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,d),e.lineCap="butt")},m=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:v;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var b=t.pstyle("ghost-offset-x").pfValue,x=t.pstyle("ghost-offset-y").pfValue,w=t.pstyle("ghost-opacity").value,E=f*w;e.translate(b,x),y(E),m(E),e.translate(-b,-x)}i&&o.drawEdgeUnderlay(e,t),y(),m(),i&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},Mu=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var i=this,a=i.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||a?t.lineCap="round":t.lineCap="butt",i.colorStrokeStyle(t,l[0],l[1],l[2],r),i.drawEdgePath(n,t,o.allpts,"solid")}}}};Iu.drawEdgeOverlay=Mu("overlay"),Iu.drawEdgeUnderlay=Mu("underlay"),Iu.drawEdgePath=function(e,t,n,r){var i,a=e._private.rscratch,o=t,s=!1,l=this.usePaths(),u=e.pstyle("line-dash-pattern").pfValue,c=e.pstyle("line-dash-offset").pfValue;if(l){var h=n.join("$");a.pathCacheKey&&a.pathCacheKey===h?(i=t=a.pathCache,s=!0):(i=t=new Path2D,a.pathCacheKey=h,a.pathCache=i)}if(o.setLineDash)switch(r){case"dotted":o.setLineDash([1,1]);break;case"dashed":o.setLineDash(u),o.lineDashOffset=c;break;case"solid":o.setLineDash([])}if(!s&&!a.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),a.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var d=2;d+35&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(a&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),h=t.pstyle("source-label"),d=t.pstyle("target-label");if(u||(!c||!c.value)&&(!h||!h.value)&&(!d||!d.value))return;e.textAlign="center",e.textBaseline="bottom"}var p,g=!n;n&&(p=n,e.translate(-p.x1,-p.y1)),null==i?(o.drawText(e,t,null,g,a),t.isEdge()&&(o.drawText(e,t,"source",g,a),o.drawText(e,t,"target",g,a))):o.drawText(e,t,i,g,a),n&&e.translate(p.x1,p.y1)},Pu.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,i=t.pstyle("font-size").pfValue+"px",a=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+i+" "+a,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Pu.getTextAngle=function(e,t){var n=e._private.rscratch,r=t?t+"-":"",i=e.pstyle(r+"text-rotation"),a=Je(n,"labelAngle",t);return"autorotate"===i.strValue?e.isEdge()?a:0:"none"===i.strValue?0:i.pfValue},Pu.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=t._private.rscratch,o=i?t.effectiveOpacity():1;if(!i||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=Je(a,"labelX",n),c=Je(a,"labelY",n),h=this.getLabelText(t,n);if(null!=h&&""!==h&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,i);var d,p=n?n+"-":"",g=Je(a,"labelWidth",n),f=Je(a,"labelHeight",n),v=t.pstyle(p+"text-margin-x").pfValue,y=t.pstyle(p+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=v,c+=y,0!==(d=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(d),u=0,c=0),x){case"top":break;case"center":c+=f/2;break;case"bottom":c+=f}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,_=t.pstyle("text-border-width").pfValue,T=t.pstyle("text-background-padding").pfValue;if(w>0||_>0&&E>0){var D=u-T;switch(b){case"left":D-=g;break;case"center":D-=g/2}var C=c-f-T,N=g+2*T,A=f+2*T;if(w>0){var L=e.fillStyle,k=t.pstyle("text-background-color").value;e.fillStyle="rgba("+k[0]+","+k[1]+","+k[2]+","+w*o+")",0===t.pstyle("text-background-shape").strValue.indexOf("round")?function(e,t,n,r,i){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:5;e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath(),e.fill()}(e,D,C,N,A,2):e.fillRect(D,C,N,A),e.fillStyle=L}if(_>0&&E>0){var S=e.strokeStyle,I=e.lineWidth,M=t.pstyle("text-border-color").value,O=t.pstyle("text-border-style").value;if(e.strokeStyle="rgba("+M[0]+","+M[1]+","+M[2]+","+E*o+")",e.lineWidth=_,e.setLineDash)switch(O){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=_/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(e.strokeRect(D,C,N,A),"double"===O){var P=_/2;e.strokeRect(D+P,C+P,N-2*P,A-2*P)}e.setLineDash&&e.setLineDash([]),e.lineWidth=I,e.strokeStyle=S}}var R=2*t.pstyle("text-outline-width").pfValue;if(R>0&&(e.lineWidth=R),"wrap"===t.pstyle("text-wrap").value){var B=Je(a,"labelWrapCachedLines",n),F=Je(a,"labelLineHeight",n),z=g/2,G=this.getLabelJustification(t);switch("auto"===G||("left"===b?"left"===G?u+=-g:"center"===G&&(u+=-z):"center"===b?"left"===G?u+=-z:"right"===G&&(u+=z):"right"===b&&("center"===G?u+=z:"right"===G&&(u+=g))),x){case"top":case"center":case"bottom":c-=(B.length-1)*F}for(var Y=0;Y0&&e.strokeText(B[Y],u,c),e.fillText(B[Y],u,c),c+=F}else R>0&&e.strokeText(h,u,c),e.fillText(h,u,c);0!==d&&(e.rotate(-d),e.translate(-s,-l))}}};var Ru={drawNode:function(e,t,n){var r,i,a=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,h=t.position();if(b(h.x)&&b(h.y)&&(!s||t.visible())){var d,p,g=s?t.effectiveOpacity():1,f=l.usePaths(),v=!1,y=t.padding();r=t.width()+2*y,i=t.height()+2*y,n&&(p=n,e.translate(-p.x1,-p.y1));for(var m=t.pstyle("background-image").value,x=new Array(m.length),w=new Array(m.length),E=0,_=0;_0&&void 0!==arguments[0]?arguments[0]:A;l.eleFillStyle(e,t,n)},M=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:S;l.colorStrokeStyle(e,L[0],L[1],L[2],t)},O=t.pstyle("shape").strValue,P=t.pstyle("shape-polygon-points").pfValue;if(f){e.translate(h.x,h.y);var R=l.nodePathCache=l.nodePathCache||[],B=Me("polygon"===O?O+","+P.join(","):O,""+i,""+r),F=R[B];null!=F?(d=F,v=!0,c.pathCache=d):(d=new Path2D,R[B]=c.pathCache=d)}var z=function(){if(!v){var n=h;f&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(d||e,n.x,n.y,r,i)}f?e.fill(d):e.fill()},G=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:g,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=u.backgrounding,a=0,o=0;o0&&void 0!==arguments[0]&&arguments[0],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:g;l.hasPie(t)&&(l.drawPie(e,t,a),n&&(f||l.nodeShapes[l.getNodeShape(t)].draw(e,h.x,h.y,r,i)))},X=function(){var t=(C>0?C:-C)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:g),n=C>0?0:255;0!==C&&(l.colorFillStyle(e,n,n,n,t),f?e.fill(d):e.fill())},V=function(){if(N>0){if(e.lineWidth=N,e.lineCap="butt",e.setLineDash)switch(k){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}if(f?e.stroke(d):e.stroke(),"double"===k){e.lineWidth=N/3;var t=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(d):e.stroke(),e.globalCompositeOperation=t}e.setLineDash&&e.setLineDash([])}};if("yes"===t.pstyle("ghost").value){var U=t.pstyle("ghost-offset-x").pfValue,j=t.pstyle("ghost-offset-y").pfValue,q=t.pstyle("ghost-opacity").value,H=q*g;e.translate(U,j),I(q*A),z(),G(H,!0),M(q*S),V(),Y(0!==C||0!==N),G(H,!1),X(H),e.translate(-U,-j)}f&&e.translate(-h.x,-h.y),o&&l.drawNodeUnderlay(e,t,h,r,i),f&&e.translate(h.x,h.y),I(),z(),G(g,!0),M(),V(),Y(0!==C||0!==N),G(g,!1),X(),f&&e.translate(-h.x,-h.y),l.drawElementText(e,t,null,a),o&&l.drawNodeOverlay(e,t,h,r,i),n&&e.translate(p.x1,p.y1)}}},Bu=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n,r,i,a){if(n.visible()){var o=n.pstyle("".concat(e,"-padding")).pfValue,s=n.pstyle("".concat(e,"-opacity")).value,l=n.pstyle("".concat(e,"-color")).value,u=n.pstyle("".concat(e,"-shape")).value;if(s>0){if(r=r||n.position(),null==i||null==a){var c=n.padding();i=n.width()+2*c,a=n.height()+2*c}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,i+2*o,a+2*o),t.fill()}}}};Ru.drawNodeOverlay=Bu("overlay"),Ru.drawNodeUnderlay=Bu("underlay"),Ru.hasPie=function(e){return(e=e[0])._private.hasPie},Ru.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var i=t.cy().style(),a=t.pstyle("pie-size"),o=r.x,s=r.y,l=t.width(),u=t.height(),c=Math.min(l,u)/2,h=0;this.usePaths()&&(o=0,s=0),"%"===a.units?c*=a.pfValue:void 0!==a.pfValue&&(c=a.pfValue/2);for(var d=1;d<=i.pieBackgroundN;d++){var p=t.pstyle("pie-"+d+"-background-size").value,g=t.pstyle("pie-"+d+"-background-color").value,f=t.pstyle("pie-"+d+"-background-opacity").value*n,v=p/100;v+h>1&&(v=1-h);var y=1.5*Math.PI+2*Math.PI*h,m=y+2*Math.PI*v;0===p||h>=1||h+v>1||(e.beginPath(),e.moveTo(o,s),e.arc(o,s,c,y,m),e.closePath(),this.colorFillStyle(e,g[0],g[1],g[2],f),e.fill(),h+=v)}};var Fu={};Fu.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/t},Fu.paintCache=function(e){for(var t,n=this.paintCaches=this.paintCaches||[],r=!0,i=0;io.minMbLowQualFrames&&(o.motionBlurPxRatio=o.mbPxRBlurry)),o.clearingMotionBlur&&(o.motionBlurPxRatio=1),o.textureDrawLastFrame&&!h&&(c[o.NODE]=!0,c[o.SELECT_BOX]=!0);var m=l.style(),b=l.zoom(),x=void 0!==i?i:b,w=l.pan(),E={x:w.x,y:w.y},_={zoom:b,pan:{x:w.x,y:w.y}},T=o.prevViewport;void 0===T||_.zoom!==T.zoom||_.pan.x!==T.pan.x||_.pan.y!==T.pan.y||f&&!g||(o.motionBlurPxRatio=1),a&&(E=a),x*=s,E.x*=s,E.y*=s;var D=o.getCachedZSortedEles();function C(e,t,n,r,i){var a=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",o.colorFillStyle(e,255,255,255,o.motionBlurTransparency),e.fillRect(t,n,r,i),e.globalCompositeOperation=a}function N(e,r){var s,l,c,h;o.clearingMotionBlur||e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]?(s=E,l=x,c=o.canvasWidth,h=o.canvasHeight):(s={x:w.x*p,y:w.y*p},l=b*p,c=o.canvasWidth*p,h=o.canvasHeight*p),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?C(e,0,0,c,h):t||void 0!==r&&!r||e.clearRect(0,0,c,h),n||(e.translate(s.x,s.y),e.scale(l,l)),a&&e.translate(a.x,a.y),i&&e.scale(i,i)}if(h||(o.textureDrawLastFrame=!1),h){if(o.textureDrawLastFrame=!0,!o.textureCache){o.textureCache={},o.textureCache.bb=l.mutableElements().boundingBox(),o.textureCache.texture=o.data.bufferCanvases[o.TEXTURE_BUFFER];var A=o.data.bufferContexts[o.TEXTURE_BUFFER];A.setTransform(1,0,0,1,0,0),A.clearRect(0,0,o.canvasWidth*o.textureMult,o.canvasHeight*o.textureMult),o.render({forcedContext:A,drawOnlyNodeLayer:!0,forcedPxRatio:s*o.textureMult}),(_=o.textureCache.viewport={zoom:l.zoom(),pan:l.pan(),width:o.canvasWidth,height:o.canvasHeight}).mpan={x:(0-_.pan.x)/_.zoom,y:(0-_.pan.y)/_.zoom}}c[o.DRAG]=!1,c[o.NODE]=!1;var L=u.contexts[o.NODE],k=o.textureCache.texture;_=o.textureCache.viewport,L.setTransform(1,0,0,1,0,0),d?C(L,0,0,_.width,_.height):L.clearRect(0,0,_.width,_.height);var S=m.core("outside-texture-bg-color").value,I=m.core("outside-texture-bg-opacity").value;o.colorFillStyle(L,S[0],S[1],S[2],I),L.fillRect(0,0,_.width,_.height),b=l.zoom(),N(L,!1),L.clearRect(_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s),L.drawImage(k,_.mpan.x,_.mpan.y,_.width/_.zoom/s,_.height/_.zoom/s)}else o.textureOnViewport&&!t&&(o.textureCache=null);var M=l.extent(),O=o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming||o.hoverData.draggingEles||o.cy.animated(),P=o.hideEdgesOnViewport&&O,R=[];if(R[o.NODE]=!c[o.NODE]&&d&&!o.clearedForMotionBlur[o.NODE]||o.clearingMotionBlur,R[o.NODE]&&(o.clearedForMotionBlur[o.NODE]=!0),R[o.DRAG]=!c[o.DRAG]&&d&&!o.clearedForMotionBlur[o.DRAG]||o.clearingMotionBlur,R[o.DRAG]&&(o.clearedForMotionBlur[o.DRAG]=!0),c[o.NODE]||n||r||R[o.NODE]){var B=d&&!R[o.NODE]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]:u.contexts[o.NODE]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.nondrag,s,M):o.drawLayeredElements(L,D.nondrag,s,M),o.debug&&o.drawDebugPoints(L,D.nondrag),n||d||(c[o.NODE]=!1)}if(!r&&(c[o.DRAG]||n||R[o.DRAG])&&(B=d&&!R[o.DRAG]&&1!==p,N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]:u.contexts[o.DRAG]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.drag,s,M):o.drawCachedElements(L,D.drag,s,M),o.debug&&o.drawDebugPoints(L,D.drag),n||d||(c[o.DRAG]=!1)),o.showFps||!r&&c[o.SELECT_BOX]&&!n){if(N(L=t||u.contexts[o.SELECT_BOX]),1==o.selection[4]&&(o.hoverData.selecting||o.touchData.selecting)){b=o.cy.zoom();var F=m.core("selection-box-border-width").value/b;L.lineWidth=F,L.fillStyle="rgba("+m.core("selection-box-color").value[0]+","+m.core("selection-box-color").value[1]+","+m.core("selection-box-color").value[2]+","+m.core("selection-box-opacity").value+")",L.fillRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]),F>0&&(L.strokeStyle="rgba("+m.core("selection-box-border-color").value[0]+","+m.core("selection-box-border-color").value[1]+","+m.core("selection-box-border-color").value[2]+","+m.core("selection-box-opacity").value+")",L.strokeRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]))}if(u.bgActivePosistion&&!o.hoverData.selecting){b=o.cy.zoom();var z=u.bgActivePosistion;L.fillStyle="rgba("+m.core("active-bg-color").value[0]+","+m.core("active-bg-color").value[1]+","+m.core("active-bg-color").value[2]+","+m.core("active-bg-opacity").value+")",L.beginPath(),L.arc(z.x,z.y,m.core("active-bg-size").pfValue/b,0,2*Math.PI),L.fill()}var G=o.lastRedrawTime;if(o.showFps&&G){G=Math.round(G);var Y=Math.round(1e3/G);L.setTransform(1,0,0,1,0,0),L.fillStyle="rgba(255, 0, 0, 0.75)",L.strokeStyle="rgba(255, 0, 0, 0.75)",L.lineWidth=1,L.fillText("1 frame = "+G+" ms = "+Y+" fps",0,20);L.strokeRect(0,30,250,20),L.fillRect(0,30,250*Math.min(Y/60,1),20)}n||(c[o.SELECT_BOX]=!1)}if(d&&1!==p){var X=u.contexts[o.NODE],V=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE],U=u.contexts[o.DRAG],j=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG],q=function(e,t,n){e.setTransform(1,0,0,1,0,0),n||!y?e.clearRect(0,0,o.canvasWidth,o.canvasHeight):C(e,0,0,o.canvasWidth,o.canvasHeight);var r=p;e.drawImage(t,0,0,o.canvasWidth*r,o.canvasHeight*r,0,0,o.canvasWidth,o.canvasHeight)};(c[o.NODE]||R[o.NODE])&&(q(X,V,R[o.NODE]),c[o.NODE]=!1),(c[o.DRAG]||R[o.DRAG])&&(q(U,j,R[o.DRAG]),c[o.DRAG]=!1)}o.prevViewport=_,o.clearingMotionBlur&&(o.clearingMotionBlur=!1,o.motionBlurCleared=!0,o.motionBlur=!0),d&&(o.motionBlurTimeout=setTimeout((function(){o.motionBlurTimeout=null,o.clearedForMotionBlur[o.NODE]=!1,o.clearedForMotionBlur[o.DRAG]=!1,o.motionBlur=!1,o.clearingMotionBlur=!h,o.mbFrames=0,c[o.NODE]=!0,c[o.DRAG]=!0,o.redraw()}),100)),t||l.emit("render")};for(var zu={drawPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*a[0],n+s*a[1]);for(var l=1;l0&&a>0){d.clearRect(0,0,i,a),d.globalCompositeOperation="source-over";var p=this.getCachedZSortedEles();if(e.full)d.translate(-n.x1*l,-n.y1*l),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(n.x1*l,n.y1*l);else{var g=t.pan(),f={x:g.x*l,y:g.y*l};l*=t.zoom(),d.translate(f.x,f.y),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(-f.x,-f.y)}e.bg&&(d.globalCompositeOperation="destination-over",d.fillStyle=e.bg,d.rect(0,0,i,a),d.fill())}return h},qu.png=function(e){return Wu(e,this.bufferCanvasImage(e),"image/png")},qu.jpg=function(e){return Wu(e,this.bufferCanvasImage(e),"image/jpeg")};var $u=Zu,Ku=Zu.prototype;function Zu(e){var t=this;t.data={canvases:new Array(Ku.CANVAS_LAYERS),contexts:new Array(Ku.CANVAS_LAYERS),canvasNeedsRedraw:new Array(Ku.CANVAS_LAYERS),bufferCanvases:new Array(Ku.BUFFER_COUNT),bufferContexts:new Array(Ku.CANVAS_LAYERS)};var n="-webkit-tap-highlight-color",r="rgba(0,0,0,0)";t.data.canvasContainer=document.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[n]=r,i.position="relative",i.zIndex="0",i.overflow="hidden";var a=e.cy.container();a.appendChild(t.data.canvasContainer),a.style[n]=r;var o={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};u&&u.userAgent.match(/msie|trident|edge/i)&&(o["-ms-touch-action"]="none",o["touch-action"]="none");for(var s=0;st&&(this.rect.x-=(this.labelWidth-t)/2,this.setWidth(this.labelWidth)),this.labelHeight>n&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-n)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-n),this.setHeight(this.labelHeight))}}},u.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},u.prototype.transform=function(e){var t=this.rect.x;t>o.WORLD_BOUNDARY?t=o.WORLD_BOUNDARY:t<-o.WORLD_BOUNDARY&&(t=-o.WORLD_BOUNDARY);var n=this.rect.y;n>o.WORLD_BOUNDARY?n=o.WORLD_BOUNDARY:n<-o.WORLD_BOUNDARY&&(n=-o.WORLD_BOUNDARY);var r=new l(t,n),i=e.inverseTransformPoint(r);this.setLocation(i.x,i.y)},u.prototype.getLeft=function(){return this.rect.x},u.prototype.getRight=function(){return this.rect.x+this.rect.width},u.prototype.getTop=function(){return this.rect.y},u.prototype.getBottom=function(){return this.rect.y+this.rect.height},u.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},e.exports=u},function(e,t,n){"use strict";function r(e,t){null==e&&null==t?(this.x=0,this.y=0):(this.x=e,this.y=t)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(e){this.x=e},r.prototype.setY=function(e){this.y=e},r.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(0),o=n(6),s=n(3),l=n(1),u=n(13),c=n(12),h=n(11);function d(e,t,n){r.call(this,n),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=e,null!=t&&t instanceof o?this.graphManager=t:null!=t&&t instanceof Layout&&(this.graphManager=t.graphManager)}for(var p in d.prototype=Object.create(r.prototype),r)d[p]=r[p];d.prototype.getNodes=function(){return this.nodes},d.prototype.getEdges=function(){return this.edges},d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getParent=function(){return this.parent},d.prototype.getLeft=function(){return this.left},d.prototype.getRight=function(){return this.right},d.prototype.getTop=function(){return this.top},d.prototype.getBottom=function(){return this.bottom},d.prototype.isConnected=function(){return this.isConnected},d.prototype.add=function(e,t,n){if(null==t&&null==n){var r=e;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var i=e;if(!(this.getNodes().indexOf(t)>-1&&this.getNodes().indexOf(n)>-1))throw"Source or target not in graph!";if(t.owner!=n.owner||t.owner!=this)throw"Both owners must be this graph!";return t.owner!=n.owner?null:(i.source=t,i.target=n,i.isInterGraph=!1,this.getEdges().push(i),t.edges.push(i),n!=t&&n.edges.push(i),i)},d.prototype.remove=function(e){var t=e;if(e instanceof s){if(null==t)throw"Node is null!";if(null==t.owner||t.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var n=t.edges.slice(),r=n.length,i=0;i-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(a.source.edges.splice(u,1),a.target!=a.source&&a.target.edges.splice(c,1),-1==(o=a.source.owner.getEdges().indexOf(a)))throw"Not in owner's edge list!";a.source.owner.getEdges().splice(o,1)}},d.prototype.updateLeftTop=function(){for(var e,t,n,r=i.MAX_VALUE,a=i.MAX_VALUE,o=this.getNodes(),s=o.length,l=0;l(e=u.getTop())&&(r=e),a>(t=u.getLeft())&&(a=t)}return r==i.MAX_VALUE?null:(n=null!=o[0].getParent().paddingLeft?o[0].getParent().paddingLeft:this.margin,this.left=a-n,this.top=r-n,new c(this.left,this.top))},d.prototype.updateBounds=function(e){for(var t,n,r,a,o,s=i.MAX_VALUE,l=-i.MAX_VALUE,c=i.MAX_VALUE,h=-i.MAX_VALUE,d=this.nodes,p=d.length,g=0;g(t=f.getLeft())&&(s=t),l<(n=f.getRight())&&(l=n),c>(r=f.getTop())&&(c=r),h<(a=f.getBottom())&&(h=a)}var v=new u(s,c,l-s,h-c);s==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),o=null!=d[0].getParent().paddingLeft?d[0].getParent().paddingLeft:this.margin,this.left=v.x-o,this.right=v.x+v.width+o,this.top=v.y-o,this.bottom=v.y+v.height+o},d.calculateBounds=function(e){for(var t,n,r,a,o=i.MAX_VALUE,s=-i.MAX_VALUE,l=i.MAX_VALUE,c=-i.MAX_VALUE,h=e.length,d=0;d(t=p.getLeft())&&(o=t),s<(n=p.getRight())&&(s=n),l>(r=p.getTop())&&(l=r),c<(a=p.getBottom())&&(c=a)}return new u(o,l,s-o,c-l)},d.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},d.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},d.prototype.calcEstimatedSize=function(){for(var e=0,t=this.nodes,n=t.length,r=0;r=this.nodes.length){var l=0;i.forEach((function(t){t.owner==e&&l++})),l==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},e.exports=d},function(e,t,n){"use strict";var r,i=n(1);function a(e){r=n(5),this.layout=e,this.graphs=[],this.edges=[]}a.prototype.addRoot=function(){var e=this.layout.newGraph(),t=this.layout.newNode(null),n=this.add(e,t);return this.setRootGraph(n),this.rootGraph},a.prototype.add=function(e,t,n,r,i){if(null==n&&null==r&&null==i){if(null==e)throw"Graph is null!";if(null==t)throw"Parent node is null!";if(this.graphs.indexOf(e)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(e),null!=e.parent)throw"Already has a parent!";if(null!=t.child)throw"Already has a child!";return e.parent=t,t.child=e,e}i=n,n=e;var a=(r=t).getOwner(),o=i.getOwner();if(null==a||a.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==o||o.getGraphManager()!=this)throw"Target not in this graph mgr!";if(a==o)return n.isInterGraph=!1,a.add(n,r,i);if(n.isInterGraph=!0,n.source=r,n.target=i,this.edges.indexOf(n)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(n),null==n.source||null==n.target)throw"Edge source and/or target is null!";if(-1!=n.source.edges.indexOf(n)||-1!=n.target.edges.indexOf(n))throw"Edge already in source and/or target incidency list!";return n.source.edges.push(n),n.target.edges.push(n),n},a.prototype.remove=function(e){if(e instanceof r){var t=e;if(t.getGraphManager()!=this)throw"Graph not in this graph mgr";if(t!=this.rootGraph&&(null==t.parent||t.parent.graphManager!=this))throw"Invalid parent node!";for(var n,a=[],o=(a=a.concat(t.getEdges())).length,s=0;s=t.getRight()?n[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight()):t.getX()<=e.getX()&&t.getRight()>=e.getRight()&&(n[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight())),e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()?n[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()):t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()&&(n[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()));var a=Math.abs((t.getCenterY()-e.getCenterY())/(t.getCenterX()-e.getCenterX()));t.getCenterY()===e.getCenterY()&&t.getCenterX()===e.getCenterX()&&(a=1);var o=a*n[0],s=n[1]/a;n[0]o)return n[0]=r,n[1]=l,n[2]=a,n[3]=b,!1;if(ia)return n[0]=s,n[1]=i,n[2]=y,n[3]=o,!1;if(ra?(n[0]=c,n[1]=h,_=!0):(n[0]=u,n[1]=l,_=!0):D===N&&(r>a?(n[0]=s,n[1]=l,_=!0):(n[0]=d,n[1]=h,_=!0)),-C===N?a>r?(n[2]=m,n[3]=b,T=!0):(n[2]=y,n[3]=v,T=!0):C===N&&(a>r?(n[2]=f,n[3]=v,T=!0):(n[2]=x,n[3]=b,T=!0)),_&&T)return!1;if(r>a?i>o?(A=this.getCardinalDirection(D,N,4),L=this.getCardinalDirection(C,N,2)):(A=this.getCardinalDirection(-D,N,3),L=this.getCardinalDirection(-C,N,1)):i>o?(A=this.getCardinalDirection(-D,N,1),L=this.getCardinalDirection(-C,N,3)):(A=this.getCardinalDirection(D,N,2),L=this.getCardinalDirection(C,N,4)),!_)switch(A){case 1:S=l,k=r+-g/N,n[0]=k,n[1]=S;break;case 2:k=d,S=i+p*N,n[0]=k,n[1]=S;break;case 3:S=h,k=r+g/N,n[0]=k,n[1]=S;break;case 4:k=c,S=i+-p*N,n[0]=k,n[1]=S}if(!T)switch(L){case 1:M=v,I=a+-E/N,n[2]=I,n[3]=M;break;case 2:I=x,M=o+w*N,n[2]=I,n[3]=M;break;case 3:M=b,I=a+E/N,n[2]=I,n[3]=M;break;case 4:I=m,M=o+-w*N,n[2]=I,n[3]=M}}return!1},i.getCardinalDirection=function(e,t,n){return e>t?n:1+n%4},i.getIntersection=function(e,t,n,i){if(null==i)return this.getIntersection2(e,t,n);var a,o,s,l,u,c,h,d=e.x,p=e.y,g=t.x,f=t.y,v=n.x,y=n.y,m=i.x,b=i.y;return 0==(h=(a=f-p)*(l=v-m)-(o=b-y)*(s=d-g))?null:new r((s*(c=m*y-v*b)-l*(u=g*p-d*f))/h,(o*u-a*c)/h)},i.angleOfVector=function(e,t,n,r){var i=void 0;return e!==n?(i=Math.atan((r-t)/(n-e)),n0?1:e<0?-1:0},r.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},r.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},e.exports=r},function(e,t,n){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,e.exports=r},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n0&&t;){for(s.push(u[0]);s.length>0&&t;){var c=s[0];s.splice(0,1),o.add(c);var h=c.getEdges();for(a=0;a-1&&u.splice(f,1)}o=new Set,l=new Map}else e=[]}return e},d.prototype.createDummyNodesForBendpoints=function(e){for(var t=[],n=e.source,r=this.graphManager.calcLowestCommonAncestor(e.source,e.target),i=0;i0){for(var i=this.edgeToDummyNodes.get(n),a=0;a=0&&t.splice(h,1),c.getNeighborsList().forEach((function(e){if(n.indexOf(e)<0){var t=r.get(e)-1;1==t&&l.push(e),r.set(e,t)}}))}n=n.concat(l),1!=t.length&&2!=t.length||(i=!0,a=t[0])}return a},d.prototype.setGraphManager=function(e){this.graphManager=e},e.exports=d},function(e,t,n){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},e.exports=r},function(e,t,n){"use strict";var r=n(4);function i(e,t){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(e){this.lworldOrgX=e},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(e){this.lworldOrgY=e},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(e){this.lworldExtX=e},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(e){this.lworldExtY=e},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(e){this.ldeviceOrgX=e},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(e){this.ldeviceOrgY=e},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(e){this.ldeviceExtX=e},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(e){this.ldeviceExtY=e},i.prototype.transformX=function(e){var t=0,n=this.lworldExtX;return 0!=n&&(t=this.ldeviceOrgX+(e-this.lworldOrgX)*this.ldeviceExtX/n),t},i.prototype.transformY=function(e){var t=0,n=this.lworldExtY;return 0!=n&&(t=this.ldeviceOrgY+(e-this.lworldOrgY)*this.ldeviceExtY/n),t},i.prototype.inverseTransformX=function(e){var t=0,n=this.ldeviceExtX;return 0!=n&&(t=this.lworldOrgX+(e-this.ldeviceOrgX)*this.lworldExtX/n),t},i.prototype.inverseTransformY=function(e){var t=0,n=this.ldeviceExtY;return 0!=n&&(t=this.lworldOrgY+(e-this.ldeviceOrgY)*this.lworldExtY/n),t},i.prototype.inverseTransformPoint=function(e){return new r(this.inverseTransformX(e.x),this.inverseTransformY(e.y))},e.exports=i},function(e,t,n){"use strict";var r=n(15),i=n(7),a=n(0),o=n(8),s=n(9);function l(){r.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=i.DEFAULT_EDGE_LENGTH,this.springConstant=i.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=i.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}for(var u in l.prototype=Object.create(r.prototype),r)l[u]=r[u];l.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},l.prototype.calcIdealEdgeLengths=function(){for(var e,t,n,r,o,s,l=this.getGraphManager().getAllEdges(),u=0;ui.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(e>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},l.prototype.calcSpringForces=function(){for(var e,t=this.getAllEdges(),n=0;n0&&void 0!==arguments[0])||arguments[0],s=arguments.length>1&&void 0!==arguments[1]&&arguments[1],l=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o&&this.updateGrid(),a=new Set,e=0;e(l=t.getEstimatedSize()*this.gravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i,e.gravitationForceY=-this.gravityConstant*a):(o>(l=t.getEstimatedSize()*this.compoundGravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i*this.compoundGravityConstant,e.gravitationForceY=-this.gravityConstant*a*this.compoundGravityConstant)},l.prototype.isConverged=function(){var e,t=!1;return this.totalIterations>this.maxIterations/3&&(t=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),e=this.totalDisplacement=s.length||u>=s[0].length))for(var c=0;ce}}]),e}();e.exports=a},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:1,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.sequence1=t,this.sequence2=n,this.match_score=r,this.mismatch_penalty=i,this.gap_penalty=a,this.iMax=t.length+1,this.jMax=n.length+1,this.grid=new Array(this.iMax);for(var o=0;o=0;n--){var r=this.listeners[n];r.event===e&&r.callback===t&&this.listeners.splice(n,1)}},i.emit=function(e,t){for(var n=0;n2&&E.push("'"+this.terminals_[b]+"'");D=c.showPosition?"Parse error on line "+(s+1)+":\n"+c.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(s+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(D,{text:c.match,token:this.terminals_[f]||f,line:c.yylineno,loc:p,expected:E})}if(y[0]instanceof Array&&y.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+f);switch(y[0]){case 1:t.push(f),r.push(c.yytext),i.push(c.yylloc),t.push(y[1]),f=null,l=c.yyleng,o=c.yytext,s=c.yylineno,p=c.yylloc;break;case 2:if(x=this.productions_[y[1]][1],T.$=r[r.length-x],T._$={first_line:i[i.length-(x||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(x||1)].first_column,last_column:i[i.length-1].last_column},g&&(T._$.range=[i[i.length-(x||1)].range[0],i[i.length-1].range[1]]),void 0!==(m=this.performAction.apply(T,[o,l,s,h.yy,y[1],r,i].concat(u))))return m;x&&(t=t.slice(0,-1*x*2),r=r.slice(0,-1*x),i=i.slice(0,-1*x)),t.push(this.productions_[y[1]][0]),r.push(T.$),i.push(T._$),w=a[t[t.length-2]][t[t.length-1]],t.push(w);break;case 3:return!0}}return!0}},m={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;at[0].length)){if(t=n,r=a,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[a])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,n,r){switch(n){case 0:return e.getLogger().trace("Found comment",t.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:e.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return e.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:e.getLogger().trace("end icon"),this.popState();break;case 10:return e.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return e.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return e.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return e.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:e.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return e.getLogger().trace("description:",t.yytext),"NODE_DESCR";case 27:return this.popState(),e.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),e.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),e.getLogger().trace("node end ...",t.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),e.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),e.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return e.getLogger().trace("Long description:",t.yytext),20}},rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};function b(){this.yy={}}return y.lexer=m,b.prototype=y,y.Parser=b,new b}());h.parser=h;const d=h,p=e=>(0,r.d)(e,(0,r.c)());let g=[],f=0,v={};const y={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},m=(e,t)=>{v[e]=t},b=e=>{switch(e){case y.DEFAULT:return"no-border";case y.RECT:return"rect";case y.ROUNDED_RECT:return"rounded-rect";case y.CIRCLE:return"circle";case y.CLOUD:return"cloud";case y.BANG:return"bang";case y.HEXAGON:return"hexgon";default:return"no-border"}};let x;const w=e=>v[e],E=Object.freeze(Object.defineProperty({__proto__:null,addNode:(e,t,n,i)=>{r.l.info("addNode",e,t,n,i);const a=(0,r.c)(),o={id:f++,nodeId:p(t),level:e,descr:p(n),type:i,children:[],width:(0,r.c)().mindmap.maxNodeWidth};switch(o.type){case y.ROUNDED_RECT:case y.RECT:case y.HEXAGON:o.padding=2*a.mindmap.padding;break;default:o.padding=a.mindmap.padding}const s=function(e){for(let t=g.length-1;t>=0;t--)if(g[t].level{g=[],f=0,v={}},decorateNode:e=>{const t=g[g.length-1];e&&e.icon&&(t.icon=p(e.icon)),e&&e.class&&(t.class=p(e.class))},getElementById:w,getLogger:()=>r.l,getMindmap:()=>g.length>0?g[0]:null,getNodeById:e=>g[e],getType:(e,t)=>{switch(r.l.debug("In get type",e,t),e){case"[":return y.RECT;case"(":return")"===t?y.ROUNDED_RECT:y.CLOUD;case"((":return y.CIRCLE;case")":return y.CLOUD;case"))":return y.BANG;case"{{":return y.HEXAGON;default:return y.DEFAULT}},nodeType:y,get parseError(){return x},sanitizeText:p,setElementForId:m,setErrorHandler:e=>{x=e},type2Str:b},Symbol.toStringTag,{value:"Module"}));function _(e,t,n,r){(function(e,t,n,r){const i=r.htmlLabels,o=n%11,s=e.append("g");t.section=o;let l="section-"+o;o<0&&(l+=" section-root"),s.attr("class",(t.class?t.class+" ":"")+"mindmap-node "+l);const u=s.append("g"),c=s.append("g"),h=t.descr.replace(/()/g,"\n");(0,a.c)(c,h,{useHtmlLabels:i,width:t.width,classes:"mindmap-node-label"}),i||c.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const d=c.node().getBBox(),p=r.fontSize.replace?r.fontSize.replace("px",""):r.fontSize;if(t.height=d.height+1.1*p*.5+t.padding,t.width=d.width+2*t.padding,t.icon)if(t.type===y.CIRCLE)t.height+=50,t.width+=50,s.append("foreignObject").attr("height","50px").attr("width",t.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+o+" "+t.icon),c.attr("transform","translate("+t.width/2+", "+(t.height/2-1.5*t.padding)+")");else{t.width+=50;const e=t.height;t.height=Math.max(e,60);const n=Math.abs(t.height-e);s.append("foreignObject").attr("width","60px").attr("height",t.height).attr("style","text-align: center;margin-top:"+n/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+o+" "+t.icon),c.attr("transform","translate("+(25+t.width/2)+", "+(n/2+t.padding/2)+")")}else if(i){const e=(t.width-d.width)/2,n=(t.height-d.height)/2;c.attr("transform","translate("+e+", "+n+")")}else{const e=t.width/2,n=t.padding/2;c.attr("transform","translate("+e+", "+n+")")}switch(t.type){case y.DEFAULT:!function(e,t,n){e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 ${t.height-5} v${10-t.height} q0,-5 5,-5 h${t.width-10} q5,0 5,5 v${t.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",t.height).attr("x2",t.width).attr("y2",t.height)}(u,t,o);break;case y.ROUNDED_RECT:!function(e,t){e.append("rect").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("height",t.height).attr("rx",t.padding).attr("ry",t.padding).attr("width",t.width)}(u,t);break;case y.RECT:!function(e,t){e.append("rect").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("height",t.height).attr("width",t.width)}(u,t);break;case y.CIRCLE:u.attr("transform","translate("+t.width/2+", "+ +t.height/2+")"),function(e,t){e.append("circle").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("r",t.width/2)}(u,t);break;case y.CLOUD:!function(e,t){const n=t.width,r=t.height,i=.15*n,a=.25*n,o=.35*n,s=.2*n;e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 0 a${i},${i} 0 0,1 ${.25*n},${-1*n*.1}\n a${o},${o} 1 0,1 ${.4*n},${-1*n*.1}\n a${a},${a} 1 0,1 ${.35*n},${1*n*.2}\n\n a${i},${i} 1 0,1 ${.15*n},${1*r*.35}\n a${s},${s} 1 0,1 ${-1*n*.15},${1*r*.65}\n\n a${a},${i} 1 0,1 ${-1*n*.25},${.15*n}\n a${o},${o} 1 0,1 ${-1*n*.5},0\n a${i},${i} 1 0,1 ${-1*n*.25},${-1*n*.15}\n\n a${i},${i} 1 0,1 ${-1*n*.1},${-1*r*.35}\n a${s},${s} 1 0,1 ${.1*n},${-1*r*.65}\n\n H0 V0 Z`)}(u,t);break;case y.BANG:!function(e,t){const n=t.width,r=t.height,i=.15*n;e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 0 a${i},${i} 1 0,0 ${.25*n},${-1*r*.1}\n a${i},${i} 1 0,0 ${.25*n},0\n a${i},${i} 1 0,0 ${.25*n},0\n a${i},${i} 1 0,0 ${.25*n},${1*r*.1}\n\n a${i},${i} 1 0,0 ${.15*n},${1*r*.33}\n a${.8*i},${.8*i} 1 0,0 0,${1*r*.34}\n a${i},${i} 1 0,0 ${-1*n*.15},${1*r*.33}\n\n a${i},${i} 1 0,0 ${-1*n*.25},${.15*r}\n a${i},${i} 1 0,0 ${-1*n*.25},0\n a${i},${i} 1 0,0 ${-1*n*.25},0\n a${i},${i} 1 0,0 ${-1*n*.25},${-1*r*.15}\n\n a${i},${i} 1 0,0 ${-1*n*.1},${-1*r*.33}\n a${.8*i},${.8*i} 1 0,0 0,${-1*r*.34}\n a${i},${i} 1 0,0 ${.1*n},${-1*r*.33}\n\n H0 V0 Z`)}(u,t);break;case y.HEXAGON:!function(e,t){const n=t.height,r=n/4,i=t.width-t.padding+2*r;!function(e,t,n,r,i){e.insert("polygon",":first-child").attr("points",r.map((function(e){return e.x+","+e.y})).join(" ")).attr("transform","translate("+(i.width-t)/2+", "+n+")")}(e,i,n,[{x:r,y:0},{x:i-r,y:0},{x:i,y:-n/2},{x:i-r,y:-n},{x:r,y:-n},{x:0,y:-n/2}],t)}(u,t)}m(t.id,s),t.height})(e,t,n,r),t.children&&t.children.forEach(((t,i)=>{_(e,t,n<0?i:n,r)}))}function T(e,t,n,r){t.add({group:"nodes",data:{id:e.id,labelText:e.descr,height:e.height,width:e.width,level:r,nodeId:e.id,padding:e.padding,type:e.type},position:{x:e.x,y:e.y}}),e.children&&e.children.forEach((i=>{T(i,t,n,r+1),t.add({group:"edges",data:{id:`${e.id}_${i.id}`,source:e.id,target:i.id,depth:r,section:i.section}})}))}function D(e,t){return new Promise((n=>{const a=(0,i.Ys)("body").append("div").attr("id","cy").attr("style","display:none"),s=o({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});a.remove(),T(e,s,t,0),s.nodes().forEach((function(e){e.layoutDimensions=()=>{const t=e.data();return{w:t.width,h:t.height}}})),s.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),s.ready((e=>{r.l.info("Ready",e),n(s)}))}))}o.use(s);const C={db:E,renderer:{draw:async(e,t,n,a)=>{const o=(0,r.c)();o.htmlLabels=!1,r.l.debug("Rendering mindmap diagram\n"+e,a.parser);const s=(0,r.c)().securityLevel;let l;"sandbox"===s&&(l=(0,i.Ys)("#i"+t));const u=("sandbox"===s?(0,i.Ys)(l.nodes()[0].contentDocument.body):(0,i.Ys)("body")).select("#"+t);u.append("g");const c=a.db.getMindmap(),h=u.append("g");h.attr("class","mindmap-edges");const d=u.append("g");d.attr("class","mindmap-nodes"),_(d,c,-1,o);const p=await D(c,o);!function(e,t){t.edges().map(((t,n)=>{const i=t.data();if(t[0]._private.bodyBounds){const a=t[0]._private.rscratch;r.l.trace("Edge: ",n,i),e.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}}))}(h,p),function(e){e.nodes().map(((e,t)=>{const n=e.data();n.x=e.position().x,n.y=e.position().y,function(e){const t=w(e.id),n=e.x||0,r=e.y||0;t.attr("transform","translate("+n+","+r+")")}(n);const i=w(n.nodeId);r.l.info("Id:",t,"Position: (",e.position().x,", ",e.position().y,")",n),i.attr("transform",`translate(${e.position().x-n.width/2}, ${e.position().y-n.height/2})`),i.attr("attr",`apa-${t})`)}))}(p),(0,r.p)(void 0,u,o.mindmap.padding,o.mindmap.useMaxWidth)}},parser:d,styles:e=>`\n .edge {\n stroke-width: 3;\n }\n ${(e=>{let t="";for(let t=0;t{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,function(e){const t=Object.keys(e);for(const n of t)a[n]=e[n]}(e.flowchart),r.f.clear(),r.f.setGen("gen-1")}}},8912:function(e,t,n){n.d(t,{a:function(){return g},f:function(){return w}});var r=n(5625),l=n(7274),o=n(9339),a=n(6476),i=n(3349),s=n(5971),c=n(1767),d=(e,t)=>s.Z.lang.round(c.Z.parse(e)[t]),p=n(1117);const b={},u=function(e,t,n,r,l,a){const s=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let c="default";r.classes.length>0&&(c=r.classes.join(" ")),c+=" flowchart-label";const d=(0,o.k)(r.styles);let p,b=void 0!==r.text?r.text:r.id;if(o.l.info("vertex",r,r.labelType),"markdown"===r.labelType)o.l.info("vertex",r,r.labelType);else if((0,o.n)((0,o.c)().flowchart.htmlLabels)){const e={label:b.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``))};p=(0,i.a)(s,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",d.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let u=0,f="";switch(r.type){case"round":u=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}t.setNode(r.id,{labelStyle:d.labelStyle,shape:f,labelText:b,labelType:r.labelType,rx:u,ry:u,class:c,style:d.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:a.db.getTooltip(r.id)||"",domId:a.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:d.labelStyle,labelType:r.labelType,shape:f,labelText:b,rx:u,ry:u,class:c,style:d.style,id:r.id,domId:a.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:(0,o.c)().flowchart.padding})}))},f=function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,i=0,s={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}e.forEach((function(n){i++;const c="L-"+n.start+"-"+n.end;void 0===s[c]?(s[c]=0,o.l.info("abc78 new entry",c,s[c])):(s[c]++,o.l.info("abc78 new entry",c,s[c]));let d=c+"-"+s[c];o.l.info("abc78 new link id to be used is",c,d,s[c]);const p="LS-"+n.start,u="LE-"+n.end,f={style:"",labelStyle:""};switch(f.minlen=n.length||1,"arrow_open"===n.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let w="",g="";switch(n.stroke){case"normal":w="fill:none;",void 0!==r&&(w=r),void 0!==a&&(g=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=(0,o.k)(n.style);w=e.style,g=e.labelStyle}f.style=f.style+=w,f.labelStyle=f.labelStyle+=g,void 0!==n.interpolate?f.curve=(0,o.o)(n.interpolate,l.c_6):void 0!==e.defaultInterpolate?f.curve=(0,o.o)(e.defaultInterpolate,l.c_6):f.curve=(0,o.o)(b.curve,l.c_6),void 0===n.text?void 0!==n.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=n.labelType,f.label=n.text.replace(o.e.lineBreakRegex,"\n"),void 0===n.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=d,f.classes="flowchart-link "+p+" "+u,t.setEdge(n.start,n.end,f,i)}))},w={setConf:function(e){const t=Object.keys(e);for(const n of t)b[n]=e[n]},addVertices:u,addEdges:f,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,i){o.l.info("Drawing flowchart");let s=i.db.getDirection();void 0===s&&(s="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),p=d.nodeSpacing||50,b=d.rankSpacing||50;let w;"sandbox"===c&&(w=(0,l.Ys)("#i"+t));const g="sandbox"===c?(0,l.Ys)(w.nodes()[0].contentDocument.body):(0,l.Ys)("body"),h="sandbox"===c?w.nodes()[0].contentDocument:document,y=new r.k({multigraph:!0,compound:!0}).setGraph({rankdir:s,nodesep:p,ranksep:b,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=i.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let e=x.length-1;e>=0;e--)k=x[e],o.l.info("Subgraph - ",k),i.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=i.db.getVertices(),m=i.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.td_)("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=d,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return p.Z(r,l,o,.5)})(e.edgeLabelBackground)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/729-32b017b3.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/729-32b017b3.chunk.min.js new file mode 100644 index 000000000..27f28799d --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/729-32b017b3.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[729],{7729:function(t,e,r){r.d(e,{diagram:function(){return C}});var i=r(9339),n=r(7274),c=(r(7484),r(7967),r(7856),function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,4],r=[1,7],i=[1,5],n=[1,9],c=[1,6],a=[2,6],s=[1,16],o=[6,8,14,20,22,24,25,27,29,32,37,40,50,55],l=[8,14,20,22,24,25,27,29,32,37,40],h=[8,13,14,20,22,24,25,27,29,32,37,40],m=[1,26],u=[6,8,14,50,55],y=[8,14,55],p=[1,53],g=[1,52],d=[8,14,30,33,35,38,55],b=[1,67],f=[1,68],k=[1,69],$=[8,14,33,35,42,55],_={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,GG:6,document:7,EOF:8,":":9,DIR:10,options:11,body:12,OPT:13,NL:14,line:15,statement:16,commitStatement:17,mergeStatement:18,cherryPickStatement:19,acc_title:20,acc_title_value:21,acc_descr:22,acc_descr_value:23,acc_descr_multiline_value:24,section:25,branchStatement:26,CHECKOUT:27,ref:28,BRANCH:29,ORDER:30,NUM:31,CHERRY_PICK:32,COMMIT_ID:33,STR:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,openDirective:46,typeDirective:47,closeDirective:48,argDirective:49,open_directive:50,type_directive:51,arg_directive:52,close_directive:53,ID:54,";":55,$accept:0,$end:1},terminals_:{2:"error",6:"GG",8:"EOF",9:":",10:"DIR",13:"OPT",14:"NL",20:"acc_title",21:"acc_title_value",22:"acc_descr",23:"acc_descr_value",24:"acc_descr_multiline_value",25:"section",27:"CHECKOUT",29:"BRANCH",30:"ORDER",31:"NUM",32:"CHERRY_PICK",33:"COMMIT_ID",34:"STR",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",50:"open_directive",51:"type_directive",52:"arg_directive",53:"close_directive",54:"ID",55:";"},productions_:[0,[3,2],[3,2],[3,3],[3,4],[3,5],[7,0],[7,2],[11,2],[11,1],[12,0],[12,2],[15,2],[15,1],[16,1],[16,1],[16,1],[16,2],[16,2],[16,1],[16,1],[16,1],[16,2],[26,2],[26,4],[19,3],[19,5],[19,5],[19,5],[19,5],[18,2],[18,4],[18,4],[18,4],[18,6],[18,6],[18,6],[18,6],[18,6],[18,6],[18,8],[18,8],[18,8],[18,8],[18,8],[18,8],[17,2],[17,3],[17,3],[17,5],[17,5],[17,3],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,3],[17,5],[17,5],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[41,0],[41,1],[39,1],[39,1],[39,1],[5,3],[5,5],[46,1],[47,1],[49,1],[48,1],[28,1],[28,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,n,c,a){var s=c.length-1;switch(n){case 3:return c[s];case 4:return c[s-1];case 5:return i.setDirection(c[s-3]),c[s-1];case 7:i.setOptions(c[s-1]),this.$=c[s];break;case 8:c[s-1]+=c[s],this.$=c[s-1];break;case 10:this.$=[];break;case 11:c[s-1].push(c[s]),this.$=c[s-1];break;case 12:this.$=c[s-1];break;case 17:this.$=c[s].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=c[s].trim(),i.setAccDescription(this.$);break;case 20:i.addSection(c[s].substr(8)),this.$=c[s].substr(8);break;case 22:i.checkout(c[s]);break;case 23:i.branch(c[s]);break;case 24:i.branch(c[s-2],c[s]);break;case 25:i.cherryPick(c[s],"",void 0);break;case 26:i.cherryPick(c[s-2],"",c[s]);break;case 27:case 29:i.cherryPick(c[s-2],"","");break;case 28:i.cherryPick(c[s],"",c[s-2]);break;case 30:i.merge(c[s],"","","");break;case 31:i.merge(c[s-2],c[s],"","");break;case 32:i.merge(c[s-2],"",c[s],"");break;case 33:i.merge(c[s-2],"","",c[s]);break;case 34:i.merge(c[s-4],c[s],"",c[s-2]);break;case 35:i.merge(c[s-4],"",c[s],c[s-2]);break;case 36:i.merge(c[s-4],"",c[s-2],c[s]);break;case 37:i.merge(c[s-4],c[s-2],c[s],"");break;case 38:i.merge(c[s-4],c[s-2],"",c[s]);break;case 39:i.merge(c[s-4],c[s],c[s-2],"");break;case 40:i.merge(c[s-6],c[s-4],c[s-2],c[s]);break;case 41:i.merge(c[s-6],c[s],c[s-4],c[s-2]);break;case 42:i.merge(c[s-6],c[s-4],c[s],c[s-2]);break;case 43:i.merge(c[s-6],c[s-2],c[s-4],c[s]);break;case 44:i.merge(c[s-6],c[s],c[s-2],c[s-4]);break;case 45:i.merge(c[s-6],c[s-2],c[s],c[s-4]);break;case 46:i.commit(c[s]);break;case 47:i.commit("","",i.commitType.NORMAL,c[s]);break;case 48:i.commit("","",c[s],"");break;case 49:i.commit("","",c[s],c[s-2]);break;case 50:i.commit("","",c[s-2],c[s]);break;case 51:i.commit("",c[s],i.commitType.NORMAL,"");break;case 52:i.commit("",c[s-2],i.commitType.NORMAL,c[s]);break;case 53:i.commit("",c[s],i.commitType.NORMAL,c[s-2]);break;case 54:i.commit("",c[s-2],c[s],"");break;case 55:i.commit("",c[s],c[s-2],"");break;case 56:i.commit("",c[s-4],c[s-2],c[s]);break;case 57:i.commit("",c[s-4],c[s],c[s-2]);break;case 58:i.commit("",c[s-2],c[s-4],c[s]);break;case 59:i.commit("",c[s],c[s-4],c[s-2]);break;case 60:i.commit("",c[s],c[s-2],c[s-4]);break;case 61:i.commit("",c[s-2],c[s],c[s-4]);break;case 62:i.commit(c[s],"",i.commitType.NORMAL,"");break;case 63:i.commit(c[s],"",i.commitType.NORMAL,c[s-2]);break;case 64:i.commit(c[s-2],"",i.commitType.NORMAL,c[s]);break;case 65:i.commit(c[s-2],"",c[s],"");break;case 66:i.commit(c[s],"",c[s-2],"");break;case 67:i.commit(c[s],c[s-2],i.commitType.NORMAL,"");break;case 68:i.commit(c[s-2],c[s],i.commitType.NORMAL,"");break;case 69:i.commit(c[s-4],"",c[s-2],c[s]);break;case 70:i.commit(c[s-4],"",c[s],c[s-2]);break;case 71:i.commit(c[s-2],"",c[s-4],c[s]);break;case 72:i.commit(c[s],"",c[s-4],c[s-2]);break;case 73:i.commit(c[s],"",c[s-2],c[s-4]);break;case 74:i.commit(c[s-2],"",c[s],c[s-4]);break;case 75:i.commit(c[s-4],c[s],c[s-2],"");break;case 76:i.commit(c[s-4],c[s-2],c[s],"");break;case 77:i.commit(c[s-2],c[s],c[s-4],"");break;case 78:i.commit(c[s],c[s-2],c[s-4],"");break;case 79:i.commit(c[s],c[s-4],c[s-2],"");break;case 80:i.commit(c[s-2],c[s-4],c[s],"");break;case 81:i.commit(c[s-4],c[s],i.commitType.NORMAL,c[s-2]);break;case 82:i.commit(c[s-4],c[s-2],i.commitType.NORMAL,c[s]);break;case 83:i.commit(c[s-2],c[s],i.commitType.NORMAL,c[s-4]);break;case 84:i.commit(c[s],c[s-2],i.commitType.NORMAL,c[s-4]);break;case 85:i.commit(c[s],c[s-4],i.commitType.NORMAL,c[s-2]);break;case 86:i.commit(c[s-2],c[s-4],i.commitType.NORMAL,c[s]);break;case 87:i.commit(c[s-6],c[s-4],c[s-2],c[s]);break;case 88:i.commit(c[s-6],c[s-4],c[s],c[s-2]);break;case 89:i.commit(c[s-6],c[s-2],c[s-4],c[s]);break;case 90:i.commit(c[s-6],c[s],c[s-4],c[s-2]);break;case 91:i.commit(c[s-6],c[s-2],c[s],c[s-4]);break;case 92:i.commit(c[s-6],c[s],c[s-2],c[s-4]);break;case 93:i.commit(c[s-4],c[s-6],c[s-2],c[s]);break;case 94:i.commit(c[s-4],c[s-6],c[s],c[s-2]);break;case 95:i.commit(c[s-2],c[s-6],c[s-4],c[s]);break;case 96:i.commit(c[s],c[s-6],c[s-4],c[s-2]);break;case 97:i.commit(c[s-2],c[s-6],c[s],c[s-4]);break;case 98:i.commit(c[s],c[s-6],c[s-2],c[s-4]);break;case 99:i.commit(c[s],c[s-4],c[s-2],c[s-6]);break;case 100:i.commit(c[s-2],c[s-4],c[s],c[s-6]);break;case 101:i.commit(c[s],c[s-2],c[s-4],c[s-6]);break;case 102:i.commit(c[s-2],c[s],c[s-4],c[s-6]);break;case 103:i.commit(c[s-4],c[s-2],c[s],c[s-6]);break;case 104:i.commit(c[s-4],c[s],c[s-2],c[s-6]);break;case 105:i.commit(c[s-2],c[s-4],c[s-6],c[s]);break;case 106:i.commit(c[s],c[s-4],c[s-6],c[s-2]);break;case 107:i.commit(c[s-2],c[s],c[s-6],c[s-4]);break;case 108:i.commit(c[s],c[s-2],c[s-6],c[s-4]);break;case 109:i.commit(c[s-4],c[s-2],c[s-6],c[s]);break;case 110:i.commit(c[s-4],c[s],c[s-6],c[s-2]);break;case 111:this.$="";break;case 112:this.$=c[s];break;case 113:this.$=i.commitType.NORMAL;break;case 114:this.$=i.commitType.REVERSE;break;case 115:this.$=i.commitType.HIGHLIGHT;break;case 118:i.parseDirective("%%{","open_directive");break;case 119:i.parseDirective(c[s],"type_directive");break;case 120:c[s]=c[s].trim().replace(/'/g,'"'),i.parseDirective(c[s],"arg_directive");break;case 121:i.parseDirective("}%%","close_directive","gitGraph")}},table:[{3:1,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{1:[3]},{3:10,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{3:11,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{7:12,8:a,9:[1,13],10:[1,14],11:15,14:s},t(o,[2,124]),t(o,[2,125]),t(o,[2,126]),{47:17,51:[1,18]},{51:[2,118]},{1:[2,1]},{1:[2,2]},{8:[1,19]},{7:20,8:a,11:15,14:s},{9:[1,21]},t(l,[2,10],{12:22,13:[1,23]}),t(h,[2,9]),{9:[1,25],48:24,53:m},t([9,53],[2,119]),{1:[2,3]},{8:[1,27]},{7:28,8:a,11:15,14:s},{8:[2,7],14:[1,31],15:29,16:30,17:32,18:33,19:34,20:[1,35],22:[1,36],24:[1,37],25:[1,38],26:39,27:[1,40],29:[1,44],32:[1,43],37:[1,42],40:[1,41]},t(h,[2,8]),t(u,[2,116]),{49:45,52:[1,46]},t(u,[2,121]),{1:[2,4]},{8:[1,47]},t(l,[2,11]),{4:48,8:r,14:i,55:c},t(l,[2,13]),t(y,[2,14]),t(y,[2,15]),t(y,[2,16]),{21:[1,49]},{23:[1,50]},t(y,[2,19]),t(y,[2,20]),t(y,[2,21]),{28:51,34:p,54:g},t(y,[2,111],{41:54,33:[1,57],34:[1,59],35:[1,55],38:[1,56],42:[1,58]}),{28:60,34:p,54:g},{33:[1,61],35:[1,62]},{28:63,34:p,54:g},{48:64,53:m},{53:[2,120]},{1:[2,5]},t(l,[2,12]),t(y,[2,17]),t(y,[2,18]),t(y,[2,22]),t(d,[2,122]),t(d,[2,123]),t(y,[2,46]),{34:[1,65]},{39:66,43:b,44:f,45:k},{34:[1,70]},{34:[1,71]},t(y,[2,112]),t(y,[2,30],{33:[1,72],35:[1,74],38:[1,73]}),{34:[1,75]},{34:[1,76],36:[1,77]},t(y,[2,23],{30:[1,78]}),t(u,[2,117]),t(y,[2,47],{33:[1,80],38:[1,79],42:[1,81]}),t(y,[2,48],{33:[1,83],35:[1,82],42:[1,84]}),t($,[2,113]),t($,[2,114]),t($,[2,115]),t(y,[2,51],{35:[1,85],38:[1,86],42:[1,87]}),t(y,[2,62],{33:[1,90],35:[1,88],38:[1,89]}),{34:[1,91]},{39:92,43:b,44:f,45:k},{34:[1,93]},t(y,[2,25],{35:[1,94]}),{33:[1,95]},{33:[1,96]},{31:[1,97]},{39:98,43:b,44:f,45:k},{34:[1,99]},{34:[1,100]},{34:[1,101]},{34:[1,102]},{34:[1,103]},{34:[1,104]},{39:105,43:b,44:f,45:k},{34:[1,106]},{34:[1,107]},{39:108,43:b,44:f,45:k},{34:[1,109]},t(y,[2,31],{35:[1,111],38:[1,110]}),t(y,[2,32],{33:[1,113],35:[1,112]}),t(y,[2,33],{33:[1,114],38:[1,115]}),{34:[1,116],36:[1,117]},{34:[1,118]},{34:[1,119]},t(y,[2,24]),t(y,[2,49],{33:[1,120],42:[1,121]}),t(y,[2,53],{38:[1,122],42:[1,123]}),t(y,[2,63],{33:[1,125],38:[1,124]}),t(y,[2,50],{33:[1,126],42:[1,127]}),t(y,[2,55],{35:[1,128],42:[1,129]}),t(y,[2,66],{33:[1,131],35:[1,130]}),t(y,[2,52],{38:[1,132],42:[1,133]}),t(y,[2,54],{35:[1,134],42:[1,135]}),t(y,[2,67],{35:[1,137],38:[1,136]}),t(y,[2,64],{33:[1,139],38:[1,138]}),t(y,[2,65],{33:[1,141],35:[1,140]}),t(y,[2,68],{35:[1,143],38:[1,142]}),{39:144,43:b,44:f,45:k},{34:[1,145]},{34:[1,146]},{34:[1,147]},{34:[1,148]},{39:149,43:b,44:f,45:k},t(y,[2,26]),t(y,[2,27]),t(y,[2,28]),t(y,[2,29]),{34:[1,150]},{34:[1,151]},{39:152,43:b,44:f,45:k},{34:[1,153]},{39:154,43:b,44:f,45:k},{34:[1,155]},{34:[1,156]},{34:[1,157]},{34:[1,158]},{34:[1,159]},{34:[1,160]},{34:[1,161]},{39:162,43:b,44:f,45:k},{34:[1,163]},{34:[1,164]},{34:[1,165]},{39:166,43:b,44:f,45:k},{34:[1,167]},{39:168,43:b,44:f,45:k},{34:[1,169]},{34:[1,170]},{34:[1,171]},{39:172,43:b,44:f,45:k},{34:[1,173]},t(y,[2,37],{35:[1,174]}),t(y,[2,38],{38:[1,175]}),t(y,[2,36],{33:[1,176]}),t(y,[2,39],{35:[1,177]}),t(y,[2,34],{38:[1,178]}),t(y,[2,35],{33:[1,179]}),t(y,[2,60],{42:[1,180]}),t(y,[2,73],{33:[1,181]}),t(y,[2,61],{42:[1,182]}),t(y,[2,84],{38:[1,183]}),t(y,[2,74],{33:[1,184]}),t(y,[2,83],{38:[1,185]}),t(y,[2,59],{42:[1,186]}),t(y,[2,72],{33:[1,187]}),t(y,[2,58],{42:[1,188]}),t(y,[2,78],{35:[1,189]}),t(y,[2,71],{33:[1,190]}),t(y,[2,77],{35:[1,191]}),t(y,[2,57],{42:[1,192]}),t(y,[2,85],{38:[1,193]}),t(y,[2,56],{42:[1,194]}),t(y,[2,79],{35:[1,195]}),t(y,[2,80],{35:[1,196]}),t(y,[2,86],{38:[1,197]}),t(y,[2,70],{33:[1,198]}),t(y,[2,81],{38:[1,199]}),t(y,[2,69],{33:[1,200]}),t(y,[2,75],{35:[1,201]}),t(y,[2,76],{35:[1,202]}),t(y,[2,82],{38:[1,203]}),{34:[1,204]},{39:205,43:b,44:f,45:k},{34:[1,206]},{34:[1,207]},{39:208,43:b,44:f,45:k},{34:[1,209]},{34:[1,210]},{34:[1,211]},{34:[1,212]},{39:213,43:b,44:f,45:k},{34:[1,214]},{39:215,43:b,44:f,45:k},{34:[1,216]},{34:[1,217]},{34:[1,218]},{34:[1,219]},{34:[1,220]},{34:[1,221]},{34:[1,222]},{39:223,43:b,44:f,45:k},{34:[1,224]},{34:[1,225]},{34:[1,226]},{39:227,43:b,44:f,45:k},{34:[1,228]},{39:229,43:b,44:f,45:k},{34:[1,230]},{34:[1,231]},{34:[1,232]},{39:233,43:b,44:f,45:k},t(y,[2,40]),t(y,[2,42]),t(y,[2,41]),t(y,[2,43]),t(y,[2,45]),t(y,[2,44]),t(y,[2,101]),t(y,[2,102]),t(y,[2,99]),t(y,[2,100]),t(y,[2,104]),t(y,[2,103]),t(y,[2,108]),t(y,[2,107]),t(y,[2,106]),t(y,[2,105]),t(y,[2,110]),t(y,[2,109]),t(y,[2,98]),t(y,[2,97]),t(y,[2,96]),t(y,[2,95]),t(y,[2,93]),t(y,[2,94]),t(y,[2,92]),t(y,[2,91]),t(y,[2,90]),t(y,[2,89]),t(y,[2,87]),t(y,[2,88])],defaultActions:{9:[2,118],10:[2,1],11:[2,2],19:[2,3],27:[2,4],46:[2,120],47:[2,5]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=[0],r=[],i=[null],n=[],c=this.table,a="",s=0,o=0,l=n.slice.call(arguments,1),h=Object.create(this.lexer),m={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(m.yy[u]=this.yy[u]);h.setInput(t,m.yy),m.yy.lexer=h,m.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var y=h.yylloc;n.push(y);var p=h.options&&h.options.ranges;"function"==typeof m.yy.parseError?this.parseError=m.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,d,b,f,k,$,_,x,v,w={};;){if(d=e[e.length-1],this.defaultActions[d]?b=this.defaultActions[d]:(null==g&&(v=void 0,"number"!=typeof(v=r.pop()||h.lex()||1)&&(v instanceof Array&&(v=(r=v).pop()),v=this.symbols_[v]||v),g=v),b=c[d]&&c[d][g]),void 0===b||!b.length||!b[0]){var T;for(k in x=[],c[d])this.terminals_[k]&&k>2&&x.push("'"+this.terminals_[k]+"'");T=h.showPosition?"Parse error on line "+(s+1)+":\n"+h.showPosition()+"\nExpecting "+x.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(s+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(T,{text:h.match,token:this.terminals_[g]||g,line:h.yylineno,loc:y,expected:x})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+d+", token: "+g);switch(b[0]){case 1:e.push(g),i.push(h.yytext),n.push(h.yylloc),e.push(b[1]),g=null,o=h.yyleng,a=h.yytext,s=h.yylineno,y=h.yylloc;break;case 2:if($=this.productions_[b[1]][1],w.$=i[i.length-$],w._$={first_line:n[n.length-($||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-($||1)].first_column,last_column:n[n.length-1].last_column},p&&(w._$.range=[n[n.length-($||1)].range[0],n[n.length-1].range[1]]),void 0!==(f=this.performAction.apply(w,[a,o,s,m.yy,b[1],i,n].concat(l))))return f;$&&(e=e.slice(0,-1*$*2),i=i.slice(0,-1*$),n=n.slice(0,-1*$)),e.push(this.productions_[b[1]][0]),i.push(w.$),n.push(w._$),_=c[e[e.length-2]][e[e.length-1]],e.push(_);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var c in n)this[c]=n[c];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),c=0;ce[0].length)){if(e=r,i=c,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,n[c])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("open_directive"),50;case 1:return this.begin("type_directive"),51;case 2:return this.popState(),this.begin("arg_directive"),9;case 3:return this.popState(),this.popState(),53;case 4:return 52;case 5:return this.begin("acc_title"),20;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),22;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 34:case 38:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:return 14;case 13:case 14:break;case 15:return 6;case 16:return 40;case 17:return 33;case 18:return 38;case 19:return 42;case 20:return 43;case 21:return 44;case 22:return 45;case 23:return 35;case 24:return 29;case 25:return 30;case 26:return 37;case 27:return 32;case 28:return 27;case 29:case 30:return 10;case 31:return 9;case 32:return"CARET";case 33:this.begin("options");break;case 35:return 13;case 36:return 36;case 37:this.begin("string");break;case 39:return 34;case 40:return 31;case 41:return 54;case 42:return 8}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},options:{rules:[34,35],inclusive:!1},string:{rules:[38,39],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43],inclusive:!0}}};function v(){this.yy={}}return _.lexer=x,v.prototype=_,_.Parser=v,new v}());c.parser=c;const a=c;let s=(0,i.c)().gitGraph.mainBranchName,o=(0,i.c)().gitGraph.mainBranchOrder,l={},h=null,m={};m[s]={name:s,order:o};let u={};u[s]=h;let y=s,p="LR",g=0;function d(){return(0,i.y)({length:7})}let b={};const f=function(t){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0===u[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{y=t;const e=u[y];h=l[e]}};function k(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function $(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const n=[r,e.id,e.seq];for(let t in u)u[t]===e.id&&n.push(t);if(i.l.debug(n.join(" ")),e.parents&&2==e.parents.length){const r=l[e.parents[0]];k(t,e,r),t.push(l[e.parents[1]])}else{if(0==e.parents.length)return;{const r=l[e.parents];k(t,e,r)}}$(t=function(t,e){const r=Object.create(null);return t.reduce(((t,e)=>{const i=e.id;return r[i]||(r[i]=!0,t.push(e)),t}),[])}(t))}const _=function(){const t=Object.keys(l).map((function(t){return l[t]}));return t.forEach((function(t){i.l.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},x={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},v={parseDirective:function(t,e,r){i.m.parseDirective(this,t,e,r)},getConfig:()=>(0,i.c)().gitGraph,setDirection:function(t){p=t},setOptions:function(t){i.l.debug("options str",t),t=(t=t&&t.trim())||"{}";try{b=JSON.parse(t)}catch(t){i.l.error("error while parsing gitGraph options",t.message)}},getOptions:function(){return b},commit:function(t,e,r,n){i.l.debug("Entering commit:",t,e,r,n),e=i.e.sanitizeText(e,(0,i.c)()),t=i.e.sanitizeText(t,(0,i.c)()),n=i.e.sanitizeText(n,(0,i.c)());const c={id:e||g+"-"+d(),message:t,seq:g++,type:r||x.NORMAL,tag:n||"",parents:null==h?[]:[h.id],branch:y};h=c,l[c.id]=c,u[y]=c.id,i.l.debug("in pushCommit "+c.id)},branch:function(t,e){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0!==u[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}u[t]=null!=h?h.id:null,m[t]={name:t,order:e?parseInt(e,10):null},f(t),i.l.debug("in createBranch")},merge:function(t,e,r,n){t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)());const c=l[u[y]],a=l[u[t]];if(y===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Current branch ('+y+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===u[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===a||!a){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(c===a){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==l[e]){let i=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw i.hash={text:"merge "+t+e+r+n,token:"merge "+t+e+r+n,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+n]},i}const s={id:e||g+"-"+d(),message:"merged branch "+t+" into "+y,seq:g++,parents:[null==h?null:h.id,u[t]],branch:y,type:x.MERGE,customType:r,customId:!!e,tag:n||""};h=s,l[s.id]=s,u[y]=s.id,i.l.debug(u),i.l.debug("in mergeBranch")},cherryPick:function(t,e,r){if(i.l.debug("Entering cherryPick:",t,e,r),t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)()),r=i.e.sanitizeText(r,(0,i.c)()),!t||void 0===l[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let n=l[t],c=n.branch;if(n.type===x.MERGE){let r=new Error('Incorrect usage of "cherryPick". Source commit should not be a merge commit');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}if(!e||void 0===l[e]){if(c===y){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const a=l[u[y]];if(void 0===a||!a){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+y+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const s={id:g+"-"+d(),message:"cherry-picked "+n+" into "+y,seq:g++,parents:[null==h?null:h.id,n.id],branch:y,type:x.CHERRY_PICK,tag:r??"cherry-pick:"+n.id};h=s,l[s.id]=s,u[y]=s.id,i.l.debug(u),i.l.debug("in cherryPick")}},checkout:f,prettyPrint:function(){i.l.debug(l),$([_()[0]])},clear:function(){l={},h=null;let t=(0,i.c)().gitGraph.mainBranchName,e=(0,i.c)().gitGraph.mainBranchOrder;u={},u[t]=null,m={},m[t]={name:t,order:e},y=t,g=0,(0,i.v)()},getBranchesAsObjArray:function(){return Object.values(m).map(((t,e)=>null!==t.order?t:{...t,order:parseFloat(`0.${e}`,10)})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return u},getCommits:function(){return l},getCommitsArray:_,getCurrentBranch:function(){return y},getDirection:function(){return p},getHead:function(){return h},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,setDiagramTitle:i.r,getDiagramTitle:i.t,commitType:x};let w={};let T={},E={},L=[],M=0,A="LR";const I=t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|/gi):Array.isArray(t)?t:[];for(const t of r){const r=document.createElementNS("http://www.w3.org/2000/svg","tspan");r.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),r.setAttribute("dy","1em"),r.setAttribute("x","0"),r.setAttribute("class","row"),r.textContent=t.trim(),e.appendChild(r)}return e},R=(t,e,r)=>{const n=(0,i.z)().gitGraph,c=t.append("g").attr("class","commit-bullets"),a=t.append("g").attr("class","commit-labels");let s=0;"TB"===A&&(s=30),Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)).forEach((t=>{const i=e[t],o="TB"===A?s+10:T[i.branch].pos,l="TB"===A?T[i.branch].pos:s+10;if(r){let t,e=void 0!==i.customType&&""!==i.customType?i.customType:i.type;switch(e){case 0:default:t="commit-normal";break;case 1:t="commit-reverse";break;case 2:t="commit-highlight";break;case 3:t="commit-merge";break;case 4:t="commit-cherry-pick"}if(2===e){const e=c.append("rect");e.attr("x",l-10),e.attr("y",o-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${i.id} commit-highlight${T[i.branch].index%8} ${t}-outer`),c.append("rect").attr("x",l-6).attr("y",o-6).attr("height",12).attr("width",12).attr("class",`commit ${i.id} commit${T[i.branch].index%8} ${t}-inner`)}else if(4===e)c.append("circle").attr("cx",l).attr("cy",o).attr("r",10).attr("class",`commit ${i.id} ${t}`),c.append("circle").attr("cx",l-3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),c.append("circle").attr("cx",l+3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),c.append("line").attr("x1",l+3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`),c.append("line").attr("x1",l-3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`);else{const r=c.append("circle");if(r.attr("cx",l),r.attr("cy",o),r.attr("r",3===i.type?9:10),r.attr("class",`commit ${i.id} commit${T[i.branch].index%8}`),3===e){const e=c.append("circle");e.attr("cx",l),e.attr("cy",o),e.attr("r",6),e.attr("class",`commit ${t} ${i.id} commit${T[i.branch].index%8}`)}1===e&&c.append("path").attr("d",`M ${l-5},${o-5}L${l+5},${o+5}M${l-5},${o+5}L${l+5},${o-5}`).attr("class",`commit ${t} ${i.id} commit${T[i.branch].index%8}`)}}if(E[i.id]="TB"===A?{x:l,y:s+10}:{x:s+10,y:o},r){const t=4,e=2;if(4!==i.type&&(i.customId&&3===i.type||3!==i.type)&&n.showCommitLabel){const r=a.append("g"),c=r.insert("rect").attr("class","commit-label-bkg"),h=r.append("text").attr("x",s).attr("y",o+25).attr("class","commit-label").text(i.id);let m=h.node().getBBox();if(c.attr("x",s+10-m.width/2-e).attr("y",o+13.5).attr("width",m.width+2*e).attr("height",m.height+2*e),"TB"===A&&(c.attr("x",l-(m.width+4*t+5)).attr("y",o-12),h.attr("x",l-(m.width+4*t)).attr("y",o+m.height-12)),"TB"!==A&&h.attr("x",s+10-m.width/2),n.rotateCommitLabel)if("TB"===A)h.attr("transform","rotate(-45, "+l+", "+o+")"),c.attr("transform","rotate(-45, "+l+", "+o+")");else{let t=-7.5-(m.width+10)/25*9.5,e=10+m.width/25*8.5;r.attr("transform","translate("+t+", "+e+") rotate(-45, "+s+", "+o+")")}}if(i.tag){const r=a.insert("polygon"),n=a.append("circle"),c=a.append("text").attr("y",o-16).attr("class","tag-label").text(i.tag);let h=c.node().getBBox();c.attr("x",s+10-h.width/2);const m=h.height/2,u=o-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${s-h.width/2-t/2},${u+e}\n ${s-h.width/2-t/2},${u-e}\n ${s+10-h.width/2-t},${u-m-e}\n ${s+10+h.width/2+t},${u-m-e}\n ${s+10+h.width/2+t},${u+m+e}\n ${s+10-h.width/2-t},${u+m+e}`),n.attr("cx",s-h.width/2+t/2).attr("cy",u).attr("r",1.5).attr("class","tag-hole"),"TB"===A&&(r.attr("class","tag-label-bkg").attr("points",`\n ${l},${s+e}\n ${l},${s-e}\n ${l+10},${s-m-e}\n ${l+10+h.width+t},${s-m-e}\n ${l+10+h.width+t},${s+m+e}\n ${l+10},${s+m+e}`).attr("transform","translate(12,12) rotate(45, "+l+","+s+")"),n.attr("cx",l+t/2).attr("cy",s).attr("transform","translate(12,12) rotate(45, "+l+","+s+")"),c.attr("x",l+5).attr("y",s+3).attr("transform","translate(14,14) rotate(45, "+l+","+s+")"))}}s+=50,s>M&&(M=s)}))},O=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(L.every((t=>Math.abs(t-i)>=10)))return L.push(i),i;const n=Math.abs(t-e);return O(t,e-n/5,r+1)},C={parser:a,db:v,renderer:{draw:function(t,e,r,c){T={},E={},w={},M=0,L=[],A="LR";const a=(0,i.z)(),s=a.gitGraph;i.l.debug("in gitgraph renderer",t+"\n","id:",e,r),w=c.db.getCommits();const o=c.db.getBranchesAsObjArray();A=c.db.getDirection();const l=(0,n.Ys)(`[id="${e}"]`);let h=0;o.forEach(((t,e)=>{const r=I(t.name),i=l.append("g"),n=i.insert("g").attr("class","branchLabel"),c=n.insert("g").attr("class","label branch-label");c.node().appendChild(r);let a=r.getBBox();T[t.name]={pos:h,index:e},h+=50+(s.rotateCommitLabel?40:0)+("TB"===A?a.width/2:0),c.remove(),n.remove(),i.remove()})),R(l,w,!1),s.showBranches&&((t,e)=>{const r=(0,i.z)().gitGraph,n=t.append("g");e.forEach(((t,e)=>{const i=e%8,c=T[t.name].pos,a=n.append("line");a.attr("x1",0),a.attr("y1",c),a.attr("x2",M),a.attr("y2",c),a.attr("class","branch branch"+i),"TB"===A&&(a.attr("y1",30),a.attr("x1",c),a.attr("y2",M),a.attr("x2",c)),L.push(c);let s=t.name;const o=I(s),l=n.insert("rect"),h=n.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+i);h.node().appendChild(o);let m=o.getBBox();l.attr("class","branchLabelBkg label"+i).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),h.attr("transform","translate("+(-m.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(c-m.height/2-1)+")"),"TB"===A&&(l.attr("x",c-m.width/2-10).attr("y",0),h.attr("transform","translate("+(c-m.width/2-5)+", 0)")),"TB"!==A&&l.attr("transform","translate(-19, "+(c-m.height/2)+")")}))})(l,o),((t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{((t,e,r,i)=>{const n=E[e.id],c=E[r.id],a=((t,e,r)=>Object.keys(r).filter((i=>r[i].branch===e.branch&&r[i].seq>t.seq&&r[i].seq0)(e,r,i);let s,o="",l="",h=0,m=0,u=T[r.branch].index;if(a){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10,u=T[r.branch].index;const t=n.yc.x&&(o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,u=T[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${c.y-h} ${l} ${n.x-m} ${c.y} L ${c.x} ${c.y}`),n.x===c.x&&(u=T[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x+h} ${n.y} ${o} ${n.x+m} ${c.y+h} L ${c.x} ${c.y}`)):(n.yc.y&&(o="A 20 20, 0, 0, 0,",h=20,m=20,u=T[e.branch].index,s=`M ${n.x} ${n.y} L ${c.x-h} ${n.y} ${o} ${c.x} ${n.y-m} L ${c.x} ${c.y}`),n.y===c.y&&(u=T[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${c.y-h} ${o} ${n.x+m} ${c.y} L ${c.x} ${c.y}`));t.append("path").attr("d",s).attr("class","arrow arrow"+u%8)})(r,e[t],i,e)}))}))})(l,w),R(l,w,!0),i.u.insertTitle(l,"gitTitleText",s.titleTopMargin,c.db.getDiagramTitle()),(0,i.A)(void 0,l,s.diagramPadding,s.useMaxWidth??a.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/747-b55f0f97.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/747-b55f0f97.chunk.min.js new file mode 100644 index 000000000..4f692264b --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/747-b55f0f97.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[747],{6747:function(e,t,l){l.d(t,{diagram:function(){return f}});var n=l(1423),o=l(7274),a=l(5625),i=l(9339),s=l(6476);l(7484),l(7967),l(7856),l(3771),l(9368);const d=e=>i.e.sanitizeText(e,(0,i.c)());let r={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const c=function(e,t,l,n,o){const a=Object.keys(e);i.l.info("keys:",a),i.l.info(e),a.filter((t=>e[t].parent==o)).forEach((function(l){var a,s;const r=e[l],c=r.cssClasses.join(" "),p=r.label??r.id,b={labelStyle:"",shape:"class_box",labelText:d(p),classData:r,rx:0,ry:0,class:c,style:"",id:r.id,domId:r.domId,tooltip:n.db.getTooltip(r.id,o)||"",haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:(null==(a=(0,i.c)().flowchart)?void 0:a.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,b),o&&t.setParent(r.id,o),i.l.info("setNode",b)}))};function p(e){let t;switch(e){case 0:t="aggregation";break;case 1:t="extension";break;case 2:t="composition";break;case 3:t="dependency";break;case 4:t="lollipop";break;default:t="none"}return t}const b={setConf:function(e){r={...r,...e}},draw:async function(e,t,l,n){i.l.info("Drawing class - ",t);const b=(0,i.c)().flowchart??(0,i.c)().class,f=(0,i.c)().securityLevel;i.l.info("config:",b);const u=(null==b?void 0:b.nodeSpacing)??50,g=(null==b?void 0:b.rankSpacing)??50,y=new a.k({multigraph:!0,compound:!0}).setGraph({rankdir:n.db.getDirection(),nodesep:u,ranksep:g,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),h=n.db.getNamespaces(),v=n.db.getClasses(),w=n.db.getRelations(),k=n.db.getNotes();let x;i.l.info(w),function(e,t,l,n){const o=Object.keys(e);i.l.info("keys:",o),i.l.info(e),o.forEach((function(l){var o,a;const s=e[l],r={shape:"rect",id:s.id,domId:s.domId,labelText:d(s.id),labelStyle:"",style:"fill: none; stroke: black",padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(a=(0,i.c)().class)?void 0:a.padding)};t.setNode(s.id,r),c(s.classes,t,0,n,s.id),i.l.info("setNode",r)}))}(h,y,0,n),c(v,y,0,n),function(e,t){const l=(0,i.c)().flowchart;let n=0;e.forEach((function(e){var a;n++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:"id"+n,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:p(e.relation.type1),arrowTypeEnd:p(e.relation.type2),style:"fill:none",labelStyle:"",curve:(0,i.o)(null==l?void 0:l.curve,o.c_6)};if(i.l.info(s,e),void 0!==e.style){const t=(0,i.k)(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null==(a=(0,i.c)().flowchart)?void 0:a.htmlLabels)??(0,i.c)().htmlLabels?(s.labelType="html",s.label=''+e.text+""):(s.labelType="text",s.label=e.text.replace(i.e.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,n)}))}(w,y),function(e,t,l,n){i.l.info(e),e.forEach((function(e,a){var s,c;const p=e,b=p.text,f={labelStyle:"",shape:"note",labelText:d(b),noteData:p,rx:0,ry:0,class:"",style:"",id:p.id,domId:p.id,tooltip:"",type:"note",padding:(null==(s=(0,i.c)().flowchart)?void 0:s.padding)??(null==(c=(0,i.c)().class)?void 0:c.padding)};if(t.setNode(p.id,f),i.l.info("setNode",f),!p.class||!(p.class in n))return;const u=l+a,g={id:`edgeNote${u}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:(0,i.o)(r.curve,o.c_6)};t.setEdge(p.id,p.class,g,u)}))}(k,y,w.length+1,v),"sandbox"===f&&(x=(0,o.Ys)("#i"+t));const m="sandbox"===f?(0,o.Ys)(x.nodes()[0].contentDocument.body):(0,o.Ys)("body"),T=m.select(`[id="${t}"]`),S=m.select("#"+t+" g");if(await(0,s.r)(S,y,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),i.u.insertTitle(T,"classTitleText",(null==b?void 0:b.titleTopMargin)??5,n.db.getDiagramTitle()),(0,i.p)(y,T,null==b?void 0:b.diagramPadding,null==b?void 0:b.useMaxWidth),!(null==b?void 0:b.htmlLabels)){const e="sandbox"===f?x.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),n=e.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",l.width),n.setAttribute("height",l.height),t.insertBefore(n,t.firstChild)}}}},f={parser:n.p,db:n.d,renderer:b,styles:n.s,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,n.d.clear()}}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/76-732e78f1.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/76-732e78f1.chunk.min.js new file mode 100644 index 000000000..a670775a0 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/76-732e78f1.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[76],{6076:function(t,e,r){r.d(e,{a:function(){return o},b:function(){return M},c:function(){return d},d:function(){return N},e:function(){return T},f:function(){return Y},g:function(){return I},h:function(){return H},i:function(){return u},l:function(){return c},p:function(){return E},s:function(){return B},u:function(){return h}});var a=r(9339),n=r(7274),i=r(3506),s=r(7863);const l={extension:(t,e,r)=>{a.l.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",e+"-extensionStart").attr("class","marker extension "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},composition:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-compositionStart").attr("class","marker composition "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},aggregation:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},dependency:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},lollipop:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","white").attr("cx",6).attr("cy",7).attr("r",6)},point:(t,e)=>{t.append("marker").attr("id",e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",10).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",0).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},circle:(t,e)=>{t.append("marker").attr("id",e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},cross:(t,e)=>{t.append("marker").attr("id",e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},barb:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}},o=(t,e,r,a)=>{e.forEach((e=>{l[e](t,r,a)}))},d=(t,e,r,i)=>{let s=t||"";if("object"==typeof s&&(s=s[0]),(0,a.n)((0,a.c)().flowchart.htmlLabels)){return s=s.replace(/\\n|\n/g,"
        "),a.l.info("vertexText"+s),function(t){const e=(0,n.Ys)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),a=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s;return r.html('"+a+""),(s=t.labelStyle)&&r.attr("style",s),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:i,label:(0,a.L)(s).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>``)),labelStyle:e.replace("fill:","color:")})}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let a=[];a="string"==typeof s?s.split(/\\n|\n|/gi):Array.isArray(s)?s:[];for(const e of a){const a=document.createElementNS("http://www.w3.org/2000/svg","tspan");a.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),a.setAttribute("dy","1em"),a.setAttribute("x","0"),r?a.setAttribute("class","title-row"):a.setAttribute("class","row"),a.textContent=e.trim(),t.appendChild(a)}return t}},c=async(t,e,r,s)=>{let l;const o=e.useHtmlLabels||(0,a.n)((0,a.c)().flowchart.htmlLabels);l=r||"node default";const c=t.insert("g").attr("class",l).attr("id",e.domId||e.id),h=c.insert("g").attr("class","label").attr("style",e.labelStyle);let p;p=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const g=h.node();let y;y="markdown"===e.labelType?(0,i.c)(h,(0,a.d)((0,a.L)(p),(0,a.c)()),{useHtmlLabels:o,width:e.width||(0,a.c)().flowchart.wrappingWidth,classes:"markdown-node-label"}):g.appendChild(d((0,a.d)((0,a.L)(p),(0,a.c)()),e.labelStyle,!1,s));let f=y.getBBox();const u=e.padding/2;if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=y.children[0],e=(0,n.Ys)(y),r=t.getElementsByTagName("img");if(r){const t=""===p.replace(/]*>/g,"").trim();await Promise.all([...r].map((e=>new Promise((r=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,a.c)().fontSize?(0,a.c)().fontSize:window.getComputedStyle(document.body).fontSize,r=5;e.style.width=parseInt(t,10)*r+"px"}else e.style.width="100%";r(e)}setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}f=t.getBoundingClientRect(),e.attr("width",f.width),e.attr("height",f.height)}return o?h.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"):h.attr("transform","translate(0, "+-f.height/2+")"),e.centerLabel&&h.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"),h.insert("rect",":first-child"),{shapeSvg:c,bbox:f,halfPadding:u,label:h}},h=(t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height};function p(t,e,r,a){return t.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}function g(t,e,r,a){var n=t.x,i=t.y,s=n-a.x,l=i-a.y,o=Math.sqrt(e*e*l*l+r*r*s*s),d=Math.abs(e*r*s/o);a.x0}const u=(t,e)=>{var r,a,n=t.x,i=t.y,s=e.x-n,l=e.y-i,o=t.width/2,d=t.height/2;return Math.abs(l)*o>Math.abs(s)*d?(l<0&&(d=-d),r=0===l?0:d*s/l,a=d):(s<0&&(o=-o),r=o,a=0===s?0:o*l/s),{x:n+r,y:i+a}},x={node:function(t,e){return t.intersect(e)},circle:function(t,e,r){return g(t,e,e,r)},ellipse:g,polygon:function(t,e,r){var a=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var o=a-t.width/2-s,d=n-t.height/2-l,c=0;c1&&i.sort((function(t,e){var a=t.x-r.x,n=t.y-r.y,i=Math.sqrt(a*a+n*n),s=e.x-r.x,l=e.y-r.y,o=Math.sqrt(s*s+l*l);return it?" "+t:"",w=(t,e)=>`${e||"node default"}${b(t.classes)} ${b(t.class)}`,m=async(t,e)=>{const{shapeSvg:r,bbox:n}=await c(t,e,w(e,void 0),!0),i=n.width+e.padding+(n.height+e.padding),s=[{x:i/2,y:0},{x:i,y:-i/2},{x:i/2,y:-i},{x:0,y:-i/2}];a.l.info("Question main (Circle)");const l=p(r,i,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return a.l.warn("Intersect called"),x.polygon(e,s,t)},r};function k(t,e,r,n){const i=[],s=t=>{i.push(t,0)},l=t=>{i.push(0,t)};e.includes("t")?(a.l.debug("add top border"),s(r)):l(r),e.includes("r")?(a.l.debug("add right border"),s(n)):l(n),e.includes("b")?(a.l.debug("add bottom border"),s(r)):l(r),e.includes("l")?(a.l.debug("add left border"),s(n)):l(n),t.attr("stroke-dasharray",i.join(" "))}const L=(t,e,r)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===r&&(n=10,i=70);const s=a.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return h(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return x.rect(e,t)},a},v={rhombus:m,question:m,rect:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await c(t,e,"node "+e.classes+" "+e.class,!0),s=r.insert("rect",":first-child"),l=n.width+e.padding,o=n.height+e.padding;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",l).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(s,e.props.borders,l,o),t.delete("borders")),t.forEach((t=>{a.l.warn(`Unknown node property ${t}`)}))}return h(e,s),e.intersect=function(t){return x.rect(e,t)},r},labelRect:async(t,e)=>{const{shapeSvg:r}=await c(t,e,"label",!0);a.l.trace("Classes = ",e.class);const n=r.insert("rect",":first-child");if(n.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(k(n,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{a.l.warn(`Unknown node property ${t}`)}))}return h(e,n),e.intersect=function(t){return x.rect(e,t)},r},rectWithTitle:(t,e)=>{let r;r=e.classes?"node "+e.classes:"node default";const i=t.insert("g").attr("class",r).attr("id",e.domId||e.id),s=i.insert("rect",":first-child"),l=i.insert("line"),o=i.insert("g").attr("class","label"),c=e.labelText.flat?e.labelText.flat():e.labelText;let p="";p="object"==typeof c?c[0]:c,a.l.info("Label text abc79",p,c,"object"==typeof c);const g=o.node().appendChild(d(p,e.labelStyle,!0,!0));let y={width:0,height:0};if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=g.children[0],e=(0,n.Ys)(g);y=t.getBoundingClientRect(),e.attr("width",y.width),e.attr("height",y.height)}a.l.info("Text 2",c);const f=c.slice(1,c.length);let u=g.getBBox();const b=o.node().appendChild(d(f.join?f.join("
        "):f,e.labelStyle,!0,!0));if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=b.children[0],e=(0,n.Ys)(b);y=t.getBoundingClientRect(),e.attr("width",y.width),e.attr("height",y.height)}const w=e.padding/2;return(0,n.Ys)(b).attr("transform","translate( "+(y.width>u.width?0:(u.width-y.width)/2)+", "+(u.height+w+5)+")"),(0,n.Ys)(g).attr("transform","translate( "+(y.width{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);return r.insert("polygon",":first-child").attr("points",[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}].map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return x.circle(e,14,t)},r},circle:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await c(t,e,w(e,void 0),!0),s=r.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),a.l.info("Circle main"),h(e,s),e.intersect=function(t){return a.l.info("Circle intersect",e,n.width/2+i,t),x.circle(e,n.width/2+i,t)},r},doublecircle:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await c(t,e,w(e,void 0),!0),s=r.insert("g",":first-child"),l=s.insert("circle"),o=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+5).attr("width",n.width+e.padding+10).attr("height",n.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),a.l.info("DoubleCircle main"),h(e,l),e.intersect=function(t){return a.l.info("DoubleCircle intersect",e,n.width/2+i+5,t),x.circle(e,n.width/2+i+5,t)},r},stadium:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.height+e.padding,i=a.width+n/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return h(e,s),e.intersect=function(t){return x.rect(e,t)},r},hexagon:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.height+e.padding,i=n/4,s=a.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],o=p(r,s,n,l);return o.attr("style",e.style),h(e,o),e.intersect=function(t){return x.polygon(e,l,t)},r},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return p(r,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return x.polygon(e,s,t)},r},lean_right:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},lean_left:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},inv_trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},cylinder:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=n/2,s=i/(2.5+n/50),l=a.height+s+e.padding,o="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,d=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",o).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return h(e,d),e.intersect=function(t){const r=x.rect(e,t),a=r.x-e.x;if(0!=i&&(Math.abs(a)e.height/2-s)){let n=s*s*(1-a*a/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),r.y+=n}return r},r},start:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),h(e,a),e.intersect=function(t){return x.circle(e,7,t)},r},end:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child"),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),a.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),h(e,n),e.intersect=function(t){return x.circle(e,7,t)},r},note:async(t,e)=>{e.useHtmlLabels||(0,a.c)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:r,bbox:n,halfPadding:i}=await c(t,e,"node "+e.classes,!0);a.l.info("Classes = ",e.classes);const s=r.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),h(e,s),e.intersect=function(t){return x.rect(e,t)},r},subroutine:async(t,e)=>{const{shapeSvg:r,bbox:a}=await c(t,e,w(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=p(r,n,i,s);return l.attr("style",e.style),h(e,l),e.intersect=function(t){return x.polygon(e,s,t)},r},fork:L,join:L,class_box:(t,e)=>{const r=e.padding/2;let i;i=e.classes?"node "+e.classes:"node default";const l=t.insert("g").attr("class",i).attr("id",e.domId||e.id),o=l.insert("rect",":first-child"),c=l.insert("line"),p=l.insert("line");let g=0,y=4;const f=l.insert("g").attr("class","label");let u=0;const b=e.classData.annotations&&e.classData.annotations[0],w=e.classData.annotations[0]?"«"+e.classData.annotations[0]+"»":"",m=f.node().appendChild(d(w,e.labelStyle,!0,!0));let k=m.getBBox();if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=m.children[0],e=(0,n.Ys)(m);k=t.getBoundingClientRect(),e.attr("width",k.width),e.attr("height",k.height)}e.classData.annotations[0]&&(y+=k.height+4,g+=k.width);let L=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,a.c)().flowchart.htmlLabels?L+="<"+e.classData.type+">":L+="<"+e.classData.type+">");const v=f.node().appendChild(d(L,e.labelStyle,!0,!0));(0,n.Ys)(v).attr("class","classTitle");let S=v.getBBox();if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=v.children[0],e=(0,n.Ys)(v);S=t.getBoundingClientRect(),e.attr("width",S.width),e.attr("height",S.height)}y+=S.height+4,S.width>g&&(g=S.width);const T=[];e.classData.members.forEach((t=>{const r=(0,s.p)(t);let i=r.displayText;(0,a.c)().flowchart.htmlLabels&&(i=i.replace(//g,">"));const l=f.node().appendChild(d(i,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let o=l.getBBox();if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=l.children[0],e=(0,n.Ys)(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>g&&(g=o.width),y+=o.height+4,T.push(l)})),y+=8;const B=[];if(e.classData.methods.forEach((t=>{const r=(0,s.p)(t);let i=r.displayText;(0,a.c)().flowchart.htmlLabels&&(i=i.replace(//g,">"));const l=f.node().appendChild(d(i,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let o=l.getBBox();if((0,a.n)((0,a.c)().flowchart.htmlLabels)){const t=l.children[0],e=(0,n.Ys)(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>g&&(g=o.width),y+=o.height+4,B.push(l)})),y+=8,b){let t=(g-k.width)/2;(0,n.Ys)(m).attr("transform","translate( "+(-1*g/2+t)+", "+-1*y/2+")"),u=k.height+4}let M=(g-S.width)/2;return(0,n.Ys)(v).attr("transform","translate( "+(-1*g/2+M)+", "+(-1*y/2+u)+")"),u+=S.height+4,c.attr("class","divider").attr("x1",-g/2-r).attr("x2",g/2+r).attr("y1",-y/2-r+8+u).attr("y2",-y/2-r+8+u),u+=8,T.forEach((t=>{(0,n.Ys)(t).attr("transform","translate( "+-g/2+", "+(-1*y/2+u+4)+")");const e=null==t?void 0:t.getBBox();u+=((null==e?void 0:e.height)??0)+4})),u+=8,p.attr("class","divider").attr("x1",-g/2-r).attr("x2",g/2+r).attr("y1",-y/2-r+8+u).attr("y2",-y/2-r+8+u),u+=8,B.forEach((t=>{(0,n.Ys)(t).attr("transform","translate( "+-g/2+", "+(-1*y/2+u)+")");const e=null==t?void 0:t.getBBox();u+=((null==e?void 0:e.height)??0)+4})),o.attr("class","outer title-state").attr("x",-g/2-r).attr("y",-y/2-r).attr("width",g+e.padding).attr("height",y+e.padding),h(e,o),e.intersect=function(t){return x.rect(e,t)},l}};let S={};const T=async(t,e,r)=>{let n,i;if(e.link){let s;"sandbox"===(0,a.c)().securityLevel?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s),i=await v[e.shape](n,e,r)}else i=await v[e.shape](t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),S[e.id]=n,e.haveCallback&&S[e.id].attr("class",S[e.id].attr("class")+" clickable"),n},B=(t,e)=>{S[e.id]=t},M=()=>{S={}},E=t=>{const e=S[t.id];a.l.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r};let C={},P={};const N=()=>{C={},P={}},Y=(t,e)=>{const r=(0,a.n)((0,a.c)().flowchart.htmlLabels),s="markdown"===e.labelType?(0,i.c)(t,e.label,{style:e.labelStyle,useHtmlLabels:r,addSvgBackground:!0}):d(e.label,e.labelStyle);a.l.info("abc82",e,e.labelType);const l=t.insert("g").attr("class","edgeLabel"),o=l.insert("g").attr("class","label");o.node().appendChild(s);let c,h=s.getBBox();if(r){const t=s.children[0],e=(0,n.Ys)(s);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}if(o.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),C[e.id]=l,e.width=h.width,e.height=h.height,e.startLabelLeft){const r=d(e.startLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),P[e.id]||(P[e.id]={}),P[e.id].startLeft=a,_(c,e.startLabelLeft)}if(e.startLabelRight){const r=d(e.startLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=a.node().appendChild(r),n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),P[e.id]||(P[e.id]={}),P[e.id].startRight=a,_(c,e.startLabelRight)}if(e.endLabelLeft){const r=d(e.endLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),P[e.id]||(P[e.id]={}),P[e.id].endLeft=a,_(c,e.endLabelLeft)}if(e.endLabelRight){const r=d(e.endLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),P[e.id]||(P[e.id]={}),P[e.id].endRight=a,_(c,e.endLabelRight)}return s};function _(t,e){(0,a.c)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}const H=(t,e)=>{a.l.info("Moving label abc78 ",t.id,t.label,C[t.id]);let r=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){const n=C[t.id];let i=t.x,s=t.y;if(r){const n=a.u.calcLabelPosition(r);a.l.info("Moving label "+t.label+" from (",i,",",s,") to (",n.x,",",n.y,") abc78"),e.updatedPath&&(i=n.x,s=n.y)}n.attr("transform","translate("+i+", "+s+")")}if(t.startLabelLeft){const e=P[t.id].startLeft;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.startLabelRight){const e=P[t.id].startRight;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.endLabelLeft){const e=P[t.id].endLeft;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.endLabelRight){const e=P[t.id].endRight;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}},R=(t,e)=>{a.l.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach((t=>{if(a.l.info("abc88 checking point",t,e),((t,e)=>{const r=t.x,a=t.y,n=Math.abs(e.x-r),i=Math.abs(e.y-a),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||i)a.l.warn("abc88 outside",t,n),n=t,i||r.push(t);else{const s=((t,e,r)=>{a.l.warn(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const n=t.x,i=t.y,s=Math.abs(n-r.x),l=t.width/2;let o=r.xMath.abs(n-e.x)*d){let t=r.y{l=l||t.x===s.x&&t.y===s.y})),r.some((t=>t.x===s.x&&t.y===s.y))?a.l.warn("abc88 no intersect",s,r):r.push(s),i=!0}})),a.l.warn("abc88 returning points",r),r},I=function(t,e,r,i,s,l){let o=r.points,d=!1;const c=l.node(e.v);var h=l.node(e.w);a.l.info("abc88 InsertEdge: ",r),h.intersect&&c.intersect&&(o=o.slice(1,r.points.length-1),o.unshift(c.intersect(o[0])),a.l.info("Last point",o[o.length-1],h,h.intersect(o[o.length-1])),o.push(h.intersect(o[o.length-1]))),r.toCluster&&(a.l.info("to cluster abc88",i[r.toCluster]),o=R(r.points,i[r.toCluster].node),d=!0),r.fromCluster&&(a.l.info("from cluster abc88",i[r.fromCluster]),o=R(o.reverse(),i[r.fromCluster].node).reverse(),d=!0);const p=o.filter((t=>!Number.isNaN(t.y)));let g;g=("graph"===s||"flowchart"===s)&&r.curve||n.$0Z;const y=(0,n.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(g);let f;switch(r.thickness){case"normal":f="edge-thickness-normal";break;case"thick":case"invisible":f="edge-thickness-thick";break;default:f=""}switch(r.pattern){case"solid":f+=" edge-pattern-solid";break;case"dotted":f+=" edge-pattern-dotted";break;case"dashed":f+=" edge-pattern-dashed"}const u=t.append("path").attr("d",y(p)).attr("id",r.id).attr("class"," "+f+(r.classes?" "+r.classes:"")).attr("style",r.style);let x="";switch(((0,a.c)().flowchart.arrowMarkerAbsolute||(0,a.c)().state.arrowMarkerAbsolute)&&(x=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,x=x.replace(/\(/g,"\\("),x=x.replace(/\)/g,"\\)")),a.l.info("arrowTypeStart",r.arrowTypeStart),a.l.info("arrowTypeEnd",r.arrowTypeEnd),r.arrowTypeStart){case"arrow_cross":u.attr("marker-start","url("+x+"#"+s+"-crossStart)");break;case"arrow_point":u.attr("marker-start","url("+x+"#"+s+"-pointStart)");break;case"arrow_barb":u.attr("marker-start","url("+x+"#"+s+"-barbStart)");break;case"arrow_circle":u.attr("marker-start","url("+x+"#"+s+"-circleStart)");break;case"aggregation":u.attr("marker-start","url("+x+"#"+s+"-aggregationStart)");break;case"extension":u.attr("marker-start","url("+x+"#"+s+"-extensionStart)");break;case"composition":u.attr("marker-start","url("+x+"#"+s+"-compositionStart)");break;case"dependency":u.attr("marker-start","url("+x+"#"+s+"-dependencyStart)");break;case"lollipop":u.attr("marker-start","url("+x+"#"+s+"-lollipopStart)")}switch(r.arrowTypeEnd){case"arrow_cross":u.attr("marker-end","url("+x+"#"+s+"-crossEnd)");break;case"arrow_point":u.attr("marker-end","url("+x+"#"+s+"-pointEnd)");break;case"arrow_barb":u.attr("marker-end","url("+x+"#"+s+"-barbEnd)");break;case"arrow_circle":u.attr("marker-end","url("+x+"#"+s+"-circleEnd)");break;case"aggregation":u.attr("marker-end","url("+x+"#"+s+"-aggregationEnd)");break;case"extension":u.attr("marker-end","url("+x+"#"+s+"-extensionEnd)");break;case"composition":u.attr("marker-end","url("+x+"#"+s+"-compositionEnd)");break;case"dependency":u.attr("marker-end","url("+x+"#"+s+"-dependencyEnd)");break;case"lollipop":u.attr("marker-end","url("+x+"#"+s+"-lollipopEnd)")}let b={};return d&&(b.updatedPath=o),b.originalPath=r.points,b}},7863:function(t,e,r){r.d(e,{p:function(){return l},s:function(){return c}});var a=r(7274),n=r(9339);let i=0;const s=function(t){let e=t.id;return t.type&&(e+="<"+t.type+">"),e},l=function(t){let e="",r="",a="",i="",s=t.substring(0,1),l=t.substring(t.length-1,t.length);s.match(/[#+~-]/)&&(i=s);let o=/[\s\w)~]/;l.match(o)||(r=d(l));const c=""===i?0:1;let h=""===r?t.length:t.length-1;const p=(t=t.substring(c,h)).indexOf("("),g=t.indexOf(")");if(p>1&&g>p&&g<=t.length){let s=t.substring(0,p).trim();const l=t.substring(p+1,g);if(e=i+s+"("+(0,n.x)(l.trim())+")",g0&&(k+=e.cssClasses.join(" "));const L=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*r.padding).attr("height",m.height+r.padding+.5*r.dividerMargin).attr("class",k).node().getBBox().width;return c.node().childNodes.forEach((function(t){t.setAttribute("x",(L-t.getBBox().width)/2)})),e.tooltip&&c.insert("title").text(e.tooltip),f.attr("x2",L),b.attr("x2",L),l.width=L,l.height=m.height+r.padding+.5*r.dividerMargin,l},drawEdge:function(t,e,r,s,l){const o=function(t){switch(t){case l.db.relationType.AGGREGATION:return"aggregation";case l.db.relationType.EXTENSION:return"extension";case l.db.relationType.COMPOSITION:return"composition";case l.db.relationType.DEPENDENCY:return"dependency";case l.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const d=e.points,c=(0,a.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(a.$0Z),h=t.append("path").attr("d",c(d)).attr("id","edge"+i).attr("class","relation");let p,g,y="";s.arrowMarkerAbsolute&&(y=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,y=y.replace(/\(/g,"\\("),y=y.replace(/\)/g,"\\)")),1==r.relation.lineType&&h.attr("class","relation dashed-line"),10==r.relation.lineType&&h.attr("class","relation dotted-line"),"none"!==r.relation.type1&&h.attr("marker-start","url("+y+"#"+o(r.relation.type1)+"Start)"),"none"!==r.relation.type2&&h.attr("marker-end","url("+y+"#"+o(r.relation.type2)+"End)");const f=e.points.length;let u,x,b,w,m=n.u.calcLabelPosition(e.points);if(p=m.x,g=m.y,f%2!=0&&f>1){let t=n.u.calcCardinalityPosition("none"!==r.relation.type1,e.points,e.points[0]),a=n.u.calcCardinalityPosition("none"!==r.relation.type2,e.points,e.points[f-1]);n.l.debug("cardinality_1_point "+JSON.stringify(t)),n.l.debug("cardinality_2_point "+JSON.stringify(a)),u=t.x,x=t.y,b=a.x,w=a.y}if(void 0!==r.title){const e=t.append("g").attr("class","classLabel"),a=e.append("text").attr("class","label").attr("x",p).attr("y",g).attr("fill","red").attr("text-anchor","middle").text(r.title);window.label=a;const n=a.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",n.x-s.padding/2).attr("y",n.y-s.padding/2).attr("width",n.width+s.padding).attr("height",n.height+s.padding)}n.l.info("Rendering relation "+JSON.stringify(r)),void 0!==r.relationTitle1&&"none"!==r.relationTitle1&&t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",u).attr("y",x).attr("fill","black").attr("font-size","6").text(r.relationTitle1),void 0!==r.relationTitle2&&"none"!==r.relationTitle2&&t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",b).attr("y",w).attr("fill","black").attr("font-size","6").text(r.relationTitle2),i++},drawNote:function(t,e,r,a){n.l.debug("Rendering note ",e,r);const i=e.id,s={id:i,text:e.text,width:0,height:0},l=t.append("g").attr("id",i).attr("class","classGroup");let o=l.append("text").attr("y",r.textHeight+r.padding).attr("x",0);const d=JSON.parse(`"${e.text}"`).split("\n");d.forEach((function(t){n.l.debug(`Adding line: ${t}`),o.append("tspan").text(t).attr("class","title").attr("dy",r.textHeight)}));const c=l.node().getBBox(),h=l.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",c.width+2*r.padding).attr("height",c.height+d.length*r.textHeight+r.padding+.5*r.dividerMargin).node().getBBox().width;return o.node().childNodes.forEach((function(t){t.setAttribute("x",(h-t.getBBox().width)/2)})),s.width=h,s.height=c.height+d.length*r.textHeight+r.padding+.5*r.dividerMargin,s},parseMember:l}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/771-942a62df.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/771-942a62df.chunk.min.js new file mode 100644 index 000000000..d37846174 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/771-942a62df.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[771],{3771:function(n,e,t){t.d(e,{bK:function(){return ge}});var r=t(870),o=t(6749),i=t(3402),u=t(2002),a=t(7961),c=t(3836),f=t(6446),s=t(5625);class d{constructor(){var n={};n._next=n._prev=n,this._sentinel=n}dequeue(){var n=this._sentinel,e=n._prev;if(e!==n)return h(e),e}enqueue(n){var e=this._sentinel;n._prev&&n._next&&h(n),n._next=e._next,e._next._prev=n,e._next=n,n._prev=e}toString(){for(var n=[],e=this._sentinel,t=e._prev;t!==e;)n.push(JSON.stringify(t,v)),t=t._prev;return"["+n.join(", ")+"]"}}function h(n){n._prev._next=n._next,n._next._prev=n._prev,delete n._next,delete n._prev}function v(n,e){if("_next"!==n&&"_prev"!==n)return e}var l=u.Z(1);function Z(n,e,t,o,i){var u=i?[]:void 0;return r.Z(n.inEdges(o.v),(function(r){var o=n.edge(r),a=n.node(r.v);i&&u.push({v:r.v,w:r.w}),a.out-=o,g(e,t,a)})),r.Z(n.outEdges(o.v),(function(r){var o=n.edge(r),i=r.w,u=n.node(i);u.in-=o,g(e,t,u)})),n.removeNode(o.v),u}function g(n,e,t){t.out?t.in?n[t.out-t.in+e].enqueue(t):n[n.length-1].enqueue(t):n[0].enqueue(t)}function p(n){var e="greedy"===n.graph().acyclicer?function(n,e){if(n.nodeCount()<=1)return[];var t=function(n,e){var t=new s.k,o=0,i=0;r.Z(n.nodes(),(function(n){t.setNode(n,{v:n,in:0,out:0})})),r.Z(n.edges(),(function(n){var r=t.edge(n.v,n.w)||0,u=e(n),a=r+u;t.setEdge(n.v,n.w,a),i=Math.max(i,t.node(n.v).out+=u),o=Math.max(o,t.node(n.w).in+=u)}));var u=f.Z(i+o+3).map((function(){return new d})),a=o+1;return r.Z(t.nodes(),(function(n){g(u,a,t.node(n))})),{graph:t,buckets:u,zeroIdx:a}}(n,e||l),o=function(n,e,t){for(var r,o=[],i=e[e.length-1],u=e[0];n.nodeCount();){for(;r=u.dequeue();)Z(n,e,t,r);for(;r=i.dequeue();)Z(n,e,t,r);if(n.nodeCount())for(var a=e.length-2;a>0;--a)if(r=e[a].dequeue()){o=o.concat(Z(n,e,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx);return a.Z(c.Z(o,(function(e){return n.outEdges(e.v,e.w)})))}(n,function(n){return function(e){return n.edge(e).weight}}(n)):function(n){var e=[],t={},o={};return r.Z(n.nodes(),(function u(a){i.Z(o,a)||(o[a]=!0,t[a]=!0,r.Z(n.outEdges(a),(function(n){i.Z(t,n.w)?e.push(n):u(n.w)})),delete t[a])})),e}(n);r.Z(e,(function(e){var t=n.edge(e);n.removeEdge(e),t.forwardName=e.name,t.reversed=!0,n.setEdge(e.w,e.v,t,o.Z("rev"))}))}var b=t(6841),w=t(3032),m=t(3688),y=t(2714),_=function(n,e,t){for(var r=-1,o=n.length;++re},k=t(9203),j=function(n){return n&&n.length?_(n,k.Z,E):void 0},x=function(n){var e=null==n?0:n.length;return e?n[e-1]:void 0},N=t(4752),C=t(2693),I=t(7058),O=function(n,e){var t={};return e=(0,I.Z)(e,3),(0,C.Z)(n,(function(n,r,o){(0,N.Z)(t,r,e(n,r,o))})),t},L=t(9360),M=function(n,e){return nMath.abs(u)*f?(a<0&&(f=-f),t=f*u/a,r=f):(u<0&&(c=-c),t=c,r=c*a/u),{x:o+t,y:i+r}}function D(n){var e=c.Z(f.Z(G(n)+1),(function(){return[]}));return r.Z(n.nodes(),(function(t){var r=n.node(t),o=r.rank;L.Z(o)||(e[o][r.order]=t)})),e}function B(n,e,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),P(n,"border",o,e)}function G(n){return j(c.Z(n.nodes(),(function(e){var t=n.node(e).rank;if(!L.Z(t))return t})))}function V(n,e){var t=S();try{return e()}finally{console.log(n+" time: "+(S()-t)+"ms")}}function z(n,e){return e()}function q(n,e,t,r,o,i){var u={width:0,height:0,rank:i,borderType:e},a=o[e][i-1],c=P(n,"border",u,t);o[e][i]=c,n.setParent(c,r),a&&n.setEdge(a,c,{weight:1})}function U(n){r.Z(n.nodes(),(function(e){Y(n.node(e))})),r.Z(n.edges(),(function(e){Y(n.edge(e))}))}function Y(n){var e=n.width;n.width=n.height,n.height=e}function $(n){n.y=-n.y}function J(n){var e=n.x;n.x=n.y,n.y=e}var K=function(n,e){return n&&n.length?_(n,(0,I.Z)(e,2),M):void 0};function W(n){var e={};r.Z(n.sources(),(function t(r){var o=n.node(r);if(i.Z(e,r))return o.rank;e[r]=!0;var u=A(c.Z(n.outEdges(r),(function(e){return t(e.w)-n.edge(e).minlen})));return u!==Number.POSITIVE_INFINITY&&null!=u||(u=0),o.rank=u}))}function H(n,e){return n.node(e.w).rank-n.node(e.v).rank-n.edge(e).minlen}function Q(n){var e,t,r=new s.k({directed:!1}),o=n.nodes()[0],i=n.nodeCount();for(r.setNode(o,{});X(r,n)-1?r[o?n[i]:i]:void 0}),sn=t(2489);u.Z(1),u.Z(1),t(8448),t(6155),t(1922);var dn=t(7771);t(8533),(0,t(4193).Z)("length"),RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var hn="\\ud800-\\udfff",vn="["+hn+"]",ln="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",Zn="\\ud83c[\\udffb-\\udfff]",gn="[^"+hn+"]",pn="(?:\\ud83c[\\udde6-\\uddff]){2}",bn="[\\ud800-\\udbff][\\udc00-\\udfff]",wn="(?:"+ln+"|"+Zn+")?",mn="[\\ufe0e\\ufe0f]?",yn=mn+wn+"(?:\\u200d(?:"+[gn,pn,bn].join("|")+")"+mn+wn+")*",_n="(?:"+[gn+ln+"?",ln,pn,bn,vn].join("|")+")";function En(n,e,t){dn.Z(e)||(e=[e]);var o=(n.isDirected()?n.successors:n.neighbors).bind(n),i=[],u={};return r.Z(e,(function(e){if(!n.hasNode(e))throw new Error("Graph does not have node: "+e);kn(n,e,"post"===t,u,o,i)})),i}function kn(n,e,t,o,u,a){i.Z(o,e)||(o[e]=!0,t||a.push(e),r.Z(u(e),(function(e){kn(n,e,t,o,u,a)})),t&&a.push(e))}function jn(n){n=function(n){var e=(new s.k).setGraph(n.graph());return r.Z(n.nodes(),(function(t){e.setNode(t,n.node(t))})),r.Z(n.edges(),(function(t){var r=e.edge(t.v,t.w)||{weight:0,minlen:1},o=n.edge(t);e.setEdge(t.v,t.w,{weight:r.weight+o.weight,minlen:Math.max(r.minlen,o.minlen)})})),e}(n),W(n);var e,t=Q(n);for(Cn(t),xn(t,n);e=On(t);)Mn(t,n,e,Ln(t,n,e))}function xn(n,e){var t=function(n,e){return En(n,e,"post")}(n,n.nodes());t=t.slice(0,t.length-1),r.Z(t,(function(t){!function(n,e,t){var r=n.node(t).parent;n.edge(t,r).cutvalue=Nn(n,e,t)}(n,e,t)}))}function Nn(n,e,t){var o=n.node(t).parent,i=!0,u=e.edge(t,o),a=0;return u||(i=!1,u=e.edge(o,t)),a=u.weight,r.Z(e.nodeEdges(t),(function(r){var u,c,f=r.v===t,s=f?r.w:r.v;if(s!==o){var d=f===i,h=e.edge(r).weight;if(a+=d?h:-h,u=t,c=s,n.hasEdge(u,c)){var v=n.edge(t,s).cutvalue;a+=d?-v:v}}})),a}function Cn(n,e){arguments.length<2&&(e=n.nodes()[0]),In(n,{},1,e)}function In(n,e,t,o,u){var a=t,c=n.node(o);return e[o]=!0,r.Z(n.neighbors(o),(function(r){i.Z(e,r)||(t=In(n,e,t,r,o))})),c.low=a,c.lim=t++,u?c.parent=u:delete c.parent,t}function On(n){return fn(n.edges(),(function(e){return n.edge(e).cutvalue<0}))}function Ln(n,e,t){var r=t.v,o=t.w;e.hasEdge(r,o)||(r=t.w,o=t.v);var i=n.node(r),u=n.node(o),a=i,c=!1;i.lim>u.lim&&(a=u,c=!0);var f=sn.Z(e.edges(),(function(e){return c===An(0,n.node(e.v),a)&&c!==An(0,n.node(e.w),a)}));return K(f,(function(n){return H(e,n)}))}function Mn(n,e,t,o){var i=t.v,u=t.w;n.removeEdge(i,u),n.setEdge(o.v,o.w,{}),Cn(n),xn(n,e),function(n,e){var t=fn(n.nodes(),(function(n){return!e.node(n).parent})),o=function(n,e){return En(n,e,"pre")}(n,t);o=o.slice(1),r.Z(o,(function(t){var r=n.node(t).parent,o=e.edge(t,r),i=!1;o||(o=e.edge(r,t),i=!0),e.node(t).rank=e.node(r).rank+(i?o.minlen:-o.minlen)}))}(n,e)}function An(n,e,t){return t.low<=e.lim&&e.lim<=t.lim}function Rn(n){switch(n.graph().ranker){case"network-simplex":default:!function(n){jn(n)}(n);break;case"tight-tree":!function(n){W(n),Q(n)}(n);break;case"longest-path":Sn(n)}}RegExp(Zn+"(?="+Zn+")|"+_n+yn,"g"),new Error,t(5351),jn.initLowLimValues=Cn,jn.initCutValues=xn,jn.calcCutValue=Nn,jn.leaveEdge=On,jn.enterEdge=Ln,jn.exchangeEdges=Mn;var Sn=W;var Pn=t(4657),Tn=t(4283);function Fn(n){var e=P(n,"root",{},"_root"),t=function(n){var e={};function t(o,i){var u=n.children(o);u&&u.length&&r.Z(u,(function(n){t(n,i+1)})),e[o]=i}return r.Z(n.children(),(function(n){t(n,1)})),e}(n),o=j(Pn.Z(t))-1,i=2*o+1;n.graph().nestingRoot=e,r.Z(n.edges(),(function(e){n.edge(e).minlen*=i}));var u=function(n){return Tn.Z(n.edges(),(function(e,t){return e+n.edge(t).weight}),0)}(n)+1;r.Z(n.children(),(function(r){Dn(n,e,i,u,o,t,r)})),n.graph().nodeRankFactor=i}function Dn(n,e,t,o,i,u,a){var c=n.children(a);if(c.length){var f=B(n,"_bt"),s=B(n,"_bb"),d=n.node(a);n.setParent(f,a),d.borderTop=f,n.setParent(s,a),d.borderBottom=s,r.Z(c,(function(r){Dn(n,e,t,o,i,u,r);var c=n.node(r),d=c.borderTop?c.borderTop:r,h=c.borderBottom?c.borderBottom:r,v=c.borderTop?o:2*o,l=d!==h?1:i-u[a]+1;n.setEdge(f,d,{weight:v,minlen:l,nestingEdge:!0}),n.setEdge(h,s,{weight:v,minlen:l,nestingEdge:!0})})),n.parent(a)||n.setEdge(e,f,{weight:0,minlen:i+u[a]})}else a!==e&&n.setEdge(e,a,{weight:0,minlen:t})}var Bn=t(9103),Gn=function(n){return(0,Bn.Z)(n,5)};var Vn=t(2954),zn=function(n,e){return function(n,e,t){for(var r=-1,o=n.length,i=e.length,u={};++re||i&&u&&c&&!a&&!f||r&&u&&c||!t&&c||!o)return 1;if(!r&&!i&&!f&&n=a?c:c*("desc"==t[r]?-1:1)}return n.index-e.index}(n,e,t)}))},Hn=t(9581),Qn=t(439),Xn=(0,Hn.Z)((function(n,e){if(null==n)return[];var t=e.length;return t>1&&(0,Qn.Z)(n,e[0],e[1])?e=[]:t>2&&(0,Qn.Z)(e[0],e[1],e[2])&&(e=[e[0]]),Wn(n,(0,qn.Z)(e,1),[])}));function ne(n,e){for(var t=0,r=1;r0;)e%2&&(t+=s[e+1]),s[e=e-1>>1]+=n.weight;d+=n.weight*t}))),d}function te(n,e){var t,o=function(n,e){var t={lhs:[],rhs:[]};return r.Z(n,(function(n){var e;e=n,i.Z(e,"barycenter")?t.lhs.push(n):t.rhs.push(n)})),t}(n),u=o.lhs,c=Xn(o.rhs,(function(n){return-n.i})),f=[],s=0,d=0,h=0;u.sort((t=!!e,function(n,e){return n.barycentere.barycenter?1:t?e.i-n.i:n.i-e.i})),h=re(f,c,h),r.Z(u,(function(n){h+=n.vs.length,f.push(n.vs),s+=n.barycenter*n.weight,d+=n.weight,h=re(f,c,h)}));var v={vs:a.Z(f)};return d&&(v.barycenter=s/d,v.weight=d),v}function re(n,e,t){for(var r;e.length&&(r=x(e)).i<=t;)e.pop(),n.push(r.vs),t++;return t}function oe(n,e,t,o){var u=n.children(e),f=n.node(e),s=f?f.borderLeft:void 0,d=f?f.borderRight:void 0,h={};s&&(u=sn.Z(u,(function(n){return n!==s&&n!==d})));var v=function(n,e){return c.Z(e,(function(e){var t=n.inEdges(e);if(t.length){var r=Tn.Z(t,(function(e,t){var r=n.edge(t),o=n.node(t.v);return{sum:e.sum+r.weight*o.order,weight:e.weight+r.weight}}),{sum:0,weight:0});return{v:e,barycenter:r.sum/r.weight,weight:r.weight}}return{v:e}}))}(n,u);r.Z(v,(function(e){if(n.children(e.v).length){var r=oe(n,e.v,t,o);h[e.v]=r,i.Z(r,"barycenter")&&(u=e,a=r,L.Z(u.barycenter)?(u.barycenter=a.barycenter,u.weight=a.weight):(u.barycenter=(u.barycenter*u.weight+a.barycenter*a.weight)/(u.weight+a.weight),u.weight+=a.weight))}var u,a}));var l=function(n,e){var t={};return r.Z(n,(function(n,e){var r=t[n.v]={indegree:0,in:[],out:[],vs:[n.v],i:e};L.Z(n.barycenter)||(r.barycenter=n.barycenter,r.weight=n.weight)})),r.Z(e.edges(),(function(n){var e=t[n.v],r=t[n.w];L.Z(e)||L.Z(r)||(r.indegree++,e.out.push(t[n.w]))})),function(n){var e=[];function t(n){return function(e){var t,r,o,i;e.merged||(L.Z(e.barycenter)||L.Z(n.barycenter)||e.barycenter>=n.barycenter)&&(r=e,o=0,i=0,(t=n).weight&&(o+=t.barycenter*t.weight,i+=t.weight),r.weight&&(o+=r.barycenter*r.weight,i+=r.weight),t.vs=r.vs.concat(t.vs),t.barycenter=o/i,t.weight=i,t.i=Math.min(r.i,t.i),r.merged=!0)}}function o(e){return function(t){t.in.push(e),0==--t.indegree&&n.push(t)}}for(;n.length;){var i=n.pop();e.push(i),r.Z(i.in.reverse(),t(i)),r.Z(i.out,o(i))}return c.Z(sn.Z(e,(function(n){return!n.merged})),(function(n){return w.Z(n,["vs","i","barycenter","weight"])}))}(sn.Z(t,(function(n){return!n.indegree})))}(v,t);!function(n,e){r.Z(n,(function(n){n.vs=a.Z(n.vs.map((function(n){return e[n]?e[n].vs:n})))}))}(l,h);var Z=te(l,o);if(s&&(Z.vs=a.Z([s,Z.vs,d]),n.predecessors(s).length)){var g=n.node(n.predecessors(s)[0]),p=n.node(n.predecessors(d)[0]);i.Z(Z,"barycenter")||(Z.barycenter=0,Z.weight=0),Z.barycenter=(Z.barycenter*Z.weight+g.order+p.order)/(Z.weight+2),Z.weight+=2}return Z}function ie(n,e,t){return c.Z(e,(function(e){return function(n,e,t){var u=function(n){for(var e;n.hasNode(e=o.Z("_root")););return e}(n),a=new s.k({compound:!0}).setGraph({root:u}).setDefaultNodeLabel((function(e){return n.node(e)}));return r.Z(n.nodes(),(function(o){var c=n.node(o),f=n.parent(o);(c.rank===e||c.minRank<=e&&e<=c.maxRank)&&(a.setNode(o),a.setParent(o,f||u),r.Z(n[t](o),(function(e){var t=e.v===o?e.w:e.v,r=a.edge(t,o),i=L.Z(r)?0:r.weight;a.setEdge(t,o,{weight:n.edge(e).weight+i})})),i.Z(c,"minRank")&&a.setNode(o,{borderLeft:c.borderLeft[e],borderRight:c.borderRight[e]}))})),a}(n,e,t)}))}function ue(n,e){var t=new s.k;r.Z(n,(function(n){var o=n.graph().root,i=oe(n,o,t,e);r.Z(i.vs,(function(e,t){n.node(e).order=t})),function(n,e,t){var o,i={};r.Z(t,(function(t){for(var r,u,a=n.parent(t);a;){if((r=n.parent(a))?(u=i[r],i[r]=a):(u=o,o=a),u&&u!==a)return void e.setEdge(u,a);a=r}}))}(n,t,i.vs)}))}function ae(n,e){r.Z(e,(function(e){r.Z(e,(function(e,t){n.node(e).order=t}))}))}var ce=t(8882),fe=function(n,e){return n&&(0,C.Z)(n,(0,ce.Z)(e))},se=t(5381),de=t(7590),he=function(n,e){return null==n?n:(0,se.Z)(n,(0,ce.Z)(e),de.Z)};function ve(n,e,t){if(e>t){var r=e;e=t,t=r}var o=n[e];o||(n[e]=o={}),o[t]=!0}function le(n,e,t){if(e>t){var r=e;e=t,t=r}return i.Z(n[e],t)}function Ze(n){var e,t=D(n),o=b.Z(function(n,e){var t={};return Tn.Z(e,(function(e,o){var i=0,u=0,a=e.length,c=x(o);return r.Z(o,(function(e,f){var s=function(n,e){if(n.node(e).dummy)return fn(n.predecessors(e),(function(e){return n.node(e).dummy}))}(n,e),d=s?n.node(s).order:a;(s||e===c)&&(r.Z(o.slice(u,f+1),(function(e){r.Z(n.predecessors(e),(function(r){var o=n.node(r),u=o.order;!(ua)&&ve(t,e,c)}))}))}return Tn.Z(e,(function(e,t){var i,u=-1,a=0;return r.Z(t,(function(r,c){if("border"===n.node(r).dummy){var f=n.predecessors(r);f.length&&(i=n.node(f[0]).order,o(t,a,c,u,i),a=c,u=i)}o(t,a,t.length,i,e.length)})),t})),t}(n,t)),u={};r.Z(["u","d"],(function(a){e="u"===a?t:Pn.Z(t).reverse(),r.Z(["l","r"],(function(t){"r"===t&&(e=c.Z(e,(function(n){return Pn.Z(n).reverse()})));var f=("u"===a?n.predecessors:n.successors).bind(n),d=function(n,e,t,o){var i={},u={},a={};return r.Z(e,(function(n){r.Z(n,(function(n,e){i[n]=n,u[n]=n,a[n]=e}))})),r.Z(e,(function(n){var e=-1;r.Z(n,(function(n){var r=o(n);if(r.length){r=Xn(r,(function(n){return a[n]}));for(var c=(r.length-1)/2,f=Math.floor(c),s=Math.ceil(c);f<=s;++f){var d=r[f];u[n]===n&&ec||f>e[o].lim));for(i=o,o=r;(o=n.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(n,e,o.v,o.w),u=i.path,a=i.lca,c=0,f=u[c],s=!0;t!==o.w;){if(r=n.node(t),s){for(;(f=u[c])!==a&&n.node(f).maxRank=2);var v=ne(n,u=D(n));v-1},p=function(n,e,t){for(var r=-1,o=null==n?0:n.length;++r=200){var f=e?null:_(n);if(f)return(0,m.Z)(f);u=!1,o=b.Z,c=new v.Z}else c=e?[]:a;n:for(;++r1?r.setNode(n,e):r.setNode(n)})),this}setNode(n,e){return r.Z(this._nodes,n)?(arguments.length>1&&(this._nodes[n]=e),this):(this._nodes[n]=arguments.length>1?e:this._defaultNodeLabelFn(n),this._isCompound&&(this._parent[n]=C,this._children[n]={},this._children[C][n]=!0),this._in[n]={},this._preds[n]={},this._out[n]={},this._sucs[n]={},++this._nodeCount,this)}node(n){return this._nodes[n]}hasNode(n){return r.Z(this._nodes,n)}removeNode(n){var e=this;if(r.Z(this._nodes,n)){var t=function(n){e.removeEdge(e._edgeObjs[n])};delete this._nodes[n],this._isCompound&&(this._removeFromParentsChildList(n),delete this._parent[n],f.Z(this.children(n),(function(n){e.setParent(n)})),delete this._children[n]),f.Z(u.Z(this._in[n]),t),delete this._in[n],delete this._preds[n],f.Z(u.Z(this._out[n]),t),delete this._out[n],delete this._sucs[n],--this._nodeCount}return this}setParent(n,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(s.Z(e))e=C;else{for(var t=e+="";!s.Z(t);t=this.parent(t))if(t===n)throw new Error("Setting "+e+" as parent of "+n+" would create a cycle");this.setNode(e)}return this.setNode(n),this._removeFromParentsChildList(n),this._parent[n]=e,this._children[e][n]=!0,this}_removeFromParentsChildList(n){delete this._children[this._parent[n]][n]}parent(n){if(this._isCompound){var e=this._parent[n];if(e!==C)return e}}children(n){if(s.Z(n)&&(n=C),this._isCompound){var e=this._children[n];if(e)return u.Z(e)}else{if(n===C)return this.nodes();if(this.hasNode(n))return[]}}predecessors(n){var e=this._preds[n];if(e)return u.Z(e)}successors(n){var e=this._sucs[n];if(e)return u.Z(e)}neighbors(n){var e=this.predecessors(n);if(e)return k(e,this.successors(n))}isLeaf(n){return 0===(this.isDirected()?this.successors(n):this.neighbors(n)).length}filterNodes(n){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var t=this;f.Z(this._nodes,(function(t,r){n(r)&&e.setNode(r,t)})),f.Z(this._edgeObjs,(function(n){e.hasNode(n.v)&&e.hasNode(n.w)&&e.setEdge(n,t.edge(n))}));var r={};function o(n){var i=t.parent(n);return void 0===i||e.hasNode(i)?(r[n]=i,i):i in r?r[i]:o(i)}return this._isCompound&&f.Z(e.nodes(),(function(n){e.setParent(n,o(n))})),e}setDefaultEdgeLabel(n){return i.Z(n)||(n=o.Z(n)),this._defaultEdgeLabelFn=n,this}edgeCount(){return this._edgeCount}edges(){return j.Z(this._edgeObjs)}setPath(n,e){var t=this,r=arguments;return x.Z(n,(function(n,o){return r.length>1?t.setEdge(n,o,e):t.setEdge(n,o),o})),this}setEdge(){var n,e,t,o,i=!1,u=arguments[0];"object"==typeof u&&null!==u&&"v"in u?(n=u.v,e=u.w,t=u.name,2===arguments.length&&(o=arguments[1],i=!0)):(n=u,e=arguments[1],t=arguments[3],arguments.length>2&&(o=arguments[2],i=!0)),n=""+n,e=""+e,s.Z(t)||(t=""+t);var a=A(this._isDirected,n,e,t);if(r.Z(this._edgeLabels,a))return i&&(this._edgeLabels[a]=o),this;if(!s.Z(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(n),this.setNode(e),this._edgeLabels[a]=i?o:this._defaultEdgeLabelFn(n,e,t);var c=function(n,e,t,r){var o=""+e,i=""+t;if(!n&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};return r&&(a.name=r),a}(this._isDirected,n,e,t);return n=c.v,e=c.w,Object.freeze(c),this._edgeObjs[a]=c,L(this._preds[e],n),L(this._sucs[n],e),this._in[e][a]=c,this._out[n][a]=c,this._edgeCount++,this}edge(n,e,t){var r=1===arguments.length?R(this._isDirected,arguments[0]):A(this._isDirected,n,e,t);return this._edgeLabels[r]}hasEdge(n,e,t){var o=1===arguments.length?R(this._isDirected,arguments[0]):A(this._isDirected,n,e,t);return r.Z(this._edgeLabels,o)}removeEdge(n,e,t){var r=1===arguments.length?R(this._isDirected,arguments[0]):A(this._isDirected,n,e,t),o=this._edgeObjs[r];return o&&(n=o.v,e=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],M(this._preds[e],n),M(this._sucs[n],e),delete this._in[e][r],delete this._out[n][r],this._edgeCount--),this}inEdges(n,e){var t=this._in[n];if(t){var r=j.Z(t);return e?a.Z(r,(function(n){return n.v===e})):r}}outEdges(n,e){var t=this._out[n];if(t){var r=j.Z(t);return e?a.Z(r,(function(n){return n.w===e})):r}}nodeEdges(n,e){var t=this.inEdges(n,e);if(t)return t.concat(this.outEdges(n,e))}}function L(n,e){n[e]?n[e]++:n[e]=1}function M(n,e){--n[e]||delete n[e]}function A(n,e,t,r){var o=""+e,i=""+t;if(!n&&o>i){var u=o;o=i,i=u}return o+I+i+I+(s.Z(r)?N:r)}function R(n,e){return A(n,e.v,e.w,e.name)}O.prototype._nodeCount=0,O.prototype._edgeCount=0},5625:function(n,e,t){t.d(e,{k:function(){return r.k}});var r=t(5351)},5084:function(n,e,t){t.d(e,{Z:function(){return i}});var r=t(520);function o(n){var e=-1,t=null==n?0:n.length;for(this.__data__=new r.Z;++e0&&o(s)?t>1?n(s,t-1,o,i,u):(0,r.Z)(u,s):i||(u[u.length]=s)}return u}},2693:function(n,e,t){var r=t(5381),o=t(7179);e.Z=function(n,e){return n&&(0,r.Z)(n,e,o.Z)}},3317:function(n,e,t){var r=t(1036),o=t(2656);e.Z=function(n,e){for(var t=0,i=(e=(0,r.Z)(e,n)).length;null!=n&&ts))return!1;var h=c.get(n),v=c.get(e);if(h&&v)return h==e&&v==n;var l=-1,Z=!0,g=2&t?new o.Z:void 0;for(c.set(n,e),c.set(e,n);++l2?e[2]:void 0;for(f&&(0,i.Z)(e[0],e[1],f)&&(r=1);++t68?1900:2e3)},o=function(t){return function(e){this[t]=+e}},c=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],l=function(t){var e=r[t];return e&&(e.indexOf?e:e.s.concat(e.f))},d=function(t,e){var n,i=r.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},u={A:[s,function(t){this.afternoon=d(t,!1)}],a:[s,function(t){this.afternoon=d(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[i,o("seconds")],ss:[i,o("seconds")],m:[i,o("minutes")],mm:[i,o("minutes")],H:[i,o("hours")],h:[i,o("hours")],HH:[i,o("hours")],hh:[i,o("hours")],D:[i,o("day")],DD:[n,o("day")],Do:[s,function(t){var e=r.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],M:[i,o("month")],MM:[n,o("month")],MMM:[s,function(t){var e=l("months"),n=(l("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[s,function(t){var e=l("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,o("year")],YY:[n,function(t){this.year=a(t)}],YYYY:[/\d{4}/,o("year")],Z:c,ZZ:c};function h(n){var i,s;i=n,s=r&&r.formats;for(var a=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),o=a.length,c=0;c-1)return new Date(("X"===e?1e3:1)*t);var i=h(e)(t),s=i.year,r=i.month,a=i.day,o=i.hours,c=i.minutes,l=i.seconds,d=i.milliseconds,u=i.zone,f=new Date,y=a||(s||r?1:f.getDate()),m=s||f.getFullYear(),k=0;s&&!r||(k=r>0?r-1:f.getMonth());var p=o||0,g=c||0,b=l||0,v=d||0;return u?new Date(Date.UTC(m,k,y,p,g,b,v+60*u.offset*1e3)):n?new Date(Date.UTC(m,k,y,p,g,b,v)):new Date(m,k,y,p,g,b,v)}catch(t){return new Date("")}}(e,o,i),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),r={}}else if(o instanceof Array)for(var f=o.length,y=1;y<=f;y+=1){a[1]=o[y-1];var m=n.apply(this,a);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}y===f&&(this.$d=new Date(""))}else s.call(this,t)}}}()},9542:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},9773:function(t,e,n){"use strict";n.d(e,{diagram:function(){return X}});var i=n(7967),s=n(7484),r=n(9542),a=n(285),o=n(8734),c=n(9339),l=n(7274),d=(n(7856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,3],n=[1,5],i=[7,9,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,33,34,36,43,48],s=[1,32],r=[1,33],a=[1,34],o=[1,35],c=[1,36],l=[1,37],d=[1,38],u=[1,15],h=[1,16],f=[1,17],y=[1,18],m=[1,19],k=[1,20],p=[1,21],g=[1,22],b=[1,24],v=[1,25],x=[1,26],T=[1,27],_=[1,28],w=[1,30],$=[1,39],D=[1,42],S=[5,7,9,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,33,34,36,43,48],C={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,gantt:5,document:6,EOF:7,line:8,SPACE:9,statement:10,NL:11,weekday:12,weekday_monday:13,weekday_tuesday:14,weekday_wednesday:15,weekday_thursday:16,weekday_friday:17,weekday_saturday:18,weekday_sunday:19,dateFormat:20,inclusiveEndDates:21,topAxis:22,axisFormat:23,tickInterval:24,excludes:25,includes:26,todayMarker:27,title:28,acc_title:29,acc_title_value:30,acc_descr:31,acc_descr_value:32,acc_descr_multiline_value:33,section:34,clickStatement:35,taskTxt:36,taskData:37,openDirective:38,typeDirective:39,closeDirective:40,":":41,argDirective:42,click:43,callbackname:44,callbackargs:45,href:46,clickStatementDebug:47,open_directive:48,type_directive:49,arg_directive:50,close_directive:51,$accept:0,$end:1},terminals_:{2:"error",5:"gantt",7:"EOF",9:"SPACE",11:"NL",13:"weekday_monday",14:"weekday_tuesday",15:"weekday_wednesday",16:"weekday_thursday",17:"weekday_friday",18:"weekday_saturday",19:"weekday_sunday",20:"dateFormat",21:"inclusiveEndDates",22:"topAxis",23:"axisFormat",24:"tickInterval",25:"excludes",26:"includes",27:"todayMarker",28:"title",29:"acc_title",30:"acc_title_value",31:"acc_descr",32:"acc_descr_value",33:"acc_descr_multiline_value",34:"section",36:"taskTxt",37:"taskData",41:":",43:"click",44:"callbackname",45:"callbackargs",46:"href",48:"open_directive",49:"type_directive",50:"arg_directive",51:"close_directive"},productions_:[0,[3,2],[3,3],[6,0],[6,2],[8,2],[8,1],[8,1],[8,1],[12,1],[12,1],[12,1],[12,1],[12,1],[12,1],[12,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[10,1],[10,1],[10,2],[10,1],[4,4],[4,6],[35,2],[35,3],[35,3],[35,4],[35,3],[35,4],[35,2],[47,2],[47,3],[47,3],[47,4],[47,3],[47,4],[47,2],[38,1],[39,1],[42,1],[40,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 2:return r[o-1];case 3:case 7:case 8:this.$=[];break;case 4:r[o-1].push(r[o]),this.$=r[o-1];break;case 5:case 6:this.$=r[o];break;case 9:i.setWeekday("monday");break;case 10:i.setWeekday("tuesday");break;case 11:i.setWeekday("wednesday");break;case 12:i.setWeekday("thursday");break;case 13:i.setWeekday("friday");break;case 14:i.setWeekday("saturday");break;case 15:i.setWeekday("sunday");break;case 16:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 17:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 18:i.TopAxis(),this.$=r[o].substr(8);break;case 19:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 20:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 21:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 22:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 23:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 25:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 26:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 27:case 28:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 29:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 31:i.addTask(r[o-1],r[o]),this.$="task";break;case 35:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 36:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 37:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 38:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 39:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 40:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 41:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 42:case 48:this.$=r[o-1]+" "+r[o];break;case 43:case 44:case 46:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 45:case 47:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o];break;case 49:i.parseDirective("%%{","open_directive");break;case 50:i.parseDirective(r[o],"type_directive");break;case 51:r[o]=r[o].trim().replace(/'/g,'"'),i.parseDirective(r[o],"arg_directive");break;case 52:i.parseDirective("}%%","close_directive","gantt")}},table:[{3:1,4:2,5:e,38:4,48:n},{1:[3]},{3:6,4:2,5:e,38:4,48:n},t(i,[2,3],{6:7}),{39:8,49:[1,9]},{49:[2,49]},{1:[2,1]},{4:31,7:[1,10],8:11,9:[1,12],10:13,11:[1,14],12:23,13:s,14:r,15:a,16:o,17:c,18:l,19:d,20:u,21:h,22:f,23:y,24:m,25:k,26:p,27:g,28:b,29:v,31:x,33:T,34:_,35:29,36:w,38:4,43:$,48:n},{40:40,41:[1,41],51:D},t([41,51],[2,50]),t(i,[2,8],{1:[2,2]}),t(i,[2,4]),{4:31,10:43,12:23,13:s,14:r,15:a,16:o,17:c,18:l,19:d,20:u,21:h,22:f,23:y,24:m,25:k,26:p,27:g,28:b,29:v,31:x,33:T,34:_,35:29,36:w,38:4,43:$,48:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(i,[2,19]),t(i,[2,20]),t(i,[2,21]),t(i,[2,22]),t(i,[2,23]),t(i,[2,24]),t(i,[2,25]),{30:[1,44]},{32:[1,45]},t(i,[2,28]),t(i,[2,29]),t(i,[2,30]),{37:[1,46]},t(i,[2,32]),t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),t(i,[2,12]),t(i,[2,13]),t(i,[2,14]),t(i,[2,15]),{44:[1,47],46:[1,48]},{11:[1,49]},{42:50,50:[1,51]},{11:[2,52]},t(i,[2,5]),t(i,[2,26]),t(i,[2,27]),t(i,[2,31]),t(i,[2,35],{45:[1,52],46:[1,53]}),t(i,[2,41],{44:[1,54]}),t(S,[2,33]),{40:55,51:D},{51:[2,51]},t(i,[2,36],{46:[1,56]}),t(i,[2,37]),t(i,[2,39],{45:[1,57]}),{11:[1,58]},t(i,[2,38]),t(i,[2,40]),t(S,[2,34])],defaultActions:{5:[2,49],6:[2,1],42:[2,52],51:[2,51]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=[0],n=[],i=[null],s=[],r=this.table,a="",o=0,c=0,l=s.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var h in this.yy)Object.prototype.hasOwnProperty.call(this.yy,h)&&(u.yy[h]=this.yy[h]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var f=d.yylloc;s.push(f);var y=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,k,p,g,b,v,x,T,_,w={};;){if(k=e[e.length-1],this.defaultActions[k]?p=this.defaultActions[k]:(null==m&&(_=void 0,"number"!=typeof(_=n.pop()||d.lex()||1)&&(_ instanceof Array&&(_=(n=_).pop()),_=this.symbols_[_]||_),m=_),p=r[k]&&r[k][m]),void 0===p||!p.length||!p[0]){var $;for(b in T=[],r[k])this.terminals_[b]&&b>2&&T.push("'"+this.terminals_[b]+"'");$=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError($,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:f,expected:T})}if(p[0]instanceof Array&&p.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+m);switch(p[0]){case 1:e.push(m),i.push(d.yytext),s.push(d.yylloc),e.push(p[1]),m=null,c=d.yyleng,a=d.yytext,o=d.yylineno,f=d.yylloc;break;case 2:if(v=this.productions_[p[1]][1],w.$=i[i.length-v],w._$={first_line:s[s.length-(v||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(v||1)].first_column,last_column:s[s.length-1].last_column},y&&(w._$.range=[s[s.length-(v||1)].range[0],s[s.length-1].range[1]]),void 0!==(g=this.performAction.apply(w,[a,c,o,u.yy,p[1],i,s].concat(l))))return g;v&&(e=e.slice(0,-1*v*2),i=i.slice(0,-1*v),s=s.slice(0,-1*v)),e.push(this.productions_[p[1]][0]),i.push(w.$),s.push(w._$),x=r[e[e.length-2]][e[e.length-1]],e.push(x);break;case 3:return!0}}return!0}},E={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),48;case 1:return this.begin("type_directive"),49;case 2:return this.popState(),this.begin("arg_directive"),41;case 3:return this.popState(),this.popState(),51;case 4:return 50;case 5:return this.begin("acc_title"),29;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),31;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 20:case 23:case 26:case 29:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:case 13:case 14:case 16:case 17:case 18:break;case 15:return 11;case 19:this.begin("href");break;case 21:return 46;case 22:this.begin("callbackname");break;case 24:this.popState(),this.begin("callbackargs");break;case 25:return 44;case 27:return 45;case 28:this.begin("click");break;case 30:return 43;case 31:return 5;case 32:return 20;case 33:return 21;case 34:return 22;case 35:return 23;case 36:return 24;case 37:return 26;case 38:return 25;case 39:return 27;case 40:return 13;case 41:return 14;case 42:return 15;case 43:return 16;case 44:return 17;case 45:return 18;case 46:return 19;case 47:return"date";case 48:return 28;case 49:return"accDescription";case 50:return 34;case 51:return 36;case 52:return 37;case 53:return 41;case 54:return 7;case 55:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[26,27],inclusive:!1},callbackname:{rules:[23,24,25],inclusive:!1},href:{rules:[20,21],inclusive:!1},click:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,22,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],inclusive:!0}}};function M(){this.yy={}}return C.lexer=E,M.prototype=C,C.Parser=M,new M}());d.parser=d;const u=d;s.extend(r),s.extend(a),s.extend(o);let h,f="",y="",m="",k=[],p=[],g={},b=[],v=[],x="",T="";const _=["active","done","crit","milestone"];let w=[],$=!1,D=!1,S="sunday",C=0;const E=function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim())))},M=function(t,e,n,i){if(!n.length||t.manualEndTime)return;let r,a;r=t.startTime instanceof Date?s(t.startTime):s(t.startTime,e,!0),r=r.add(1,"d"),a=t.endTime instanceof Date?s(t.endTime):s(t.endTime,e,!0);const[o,c]=Y(r,a,e,n,i);t.endTime=o.toDate(),t.renderEndTime=c},Y=function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=E(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]},A=function(t,e,n){n=n.trim();const i=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==i){let t=null;if(i[1].split(" ").forEach((function(e){let n=N(e);void 0!==n&&(t?n.endTime>t.endTime&&(t=n):t=n)})),t)return t.endTime;{const t=new Date;return t.setHours(0,0,0,0),t}}let r=s(n,e.trim(),!0);if(r.isValid())return r.toDate();{c.l.debug("Invalid date:"+n),c.l.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},L=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},F=function(t,e,n,i=!1){n=n.trim();let r=s(n,e.trim(),!0);if(r.isValid())return i&&(r=r.add(1,"d")),r.toDate();let a=s(t);const[o,c]=L(n);if(!Number.isNaN(o)){const t=a.add(o,c);t.isValid()&&(a=t)}return a.toDate()};let I=0;const O=function(t){return void 0===t?(I+=1,"task"+I):t};let W,z,B=[];const P={},N=function(t){const e=P[t];return B[e]},H=function(){const t=function(t){const e=B[t];let n="";switch(B[t].raw.startTime.type){case"prevTaskEnd":{const t=N(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=A(0,f,B[t].raw.startTime.startData),n&&(B[t].startTime=n)}return B[t].startTime&&(B[t].endTime=F(B[t].startTime,f,B[t].raw.endTime.data,$),B[t].endTime&&(B[t].processed=!0,B[t].manualEndTime=s(B[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),M(B[t],f,p,k))),B[t].processed};let e=!0;for(const[n,i]of B.entries())t(n),e=e&&i.processed;return e},j=function(t,e){t.split(",").forEach((function(t){let n=N(t);void 0!==n&&n.classes.push(e)}))},Z=function(t,e){w.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))},G={parseDirective:function(t,e,n){c.m.parseDirective(this,t,e,n)},getConfig:()=>(0,c.c)().gantt,clear:function(){b=[],v=[],x="",w=[],I=0,W=void 0,z=void 0,B=[],f="",y="",T="",h=void 0,m="",k=[],p=[],$=!1,D=!1,C=0,g={},(0,c.v)(),S="sunday"},setDateFormat:function(t){f=t},getDateFormat:function(){return f},enableInclusiveEndDates:function(){$=!0},endDatesAreInclusive:function(){return $},enableTopAxis:function(){D=!0},topAxisEnabled:function(){return D},setAxisFormat:function(t){y=t},getAxisFormat:function(){return y},setTickInterval:function(t){h=t},getTickInterval:function(){return h},setTodayMarker:function(t){m=t},getTodayMarker:function(){return m},setAccTitle:c.s,getAccTitle:c.g,setDiagramTitle:c.r,getDiagramTitle:c.t,setDisplayMode:function(t){T=t},getDisplayMode:function(){return T},setAccDescription:c.b,getAccDescription:c.a,addSection:function(t){x=t,b.push(t)},getSections:function(){return b},getTasks:function(){let t=H(),e=0;for(;!t&&e<10;)t=H(),e++;return v=B,v},addTask:function(t,e){const n={section:x,type:x,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};V(i,s,_);for(let t=0;t{c.u.runFunc(e,...i)}))}(t,e,n)})),j(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==(0,c.c)().securityLevel&&(n=(0,i.Nm)(e)),t.split(",").forEach((function(t){void 0!==N(t)&&(Z(t,(()=>{window.open(n,"_self")})),g[t]=n)})),j(t,"clickable")},getLinks:function(){return g},bindFunctions:function(t){w.forEach((function(e){e(t)}))},parseDuration:L,isInvalidDate:E,setWeekday:function(t){S=t},getWeekday:function(){return S}};function V(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)}))}const R={monday:l.Ox9,tuesday:l.YDX,wednesday:l.EFj,thursday:l.Igq,friday:l.y2j,saturday:l.LqH,sunday:l.Zyz},q=(t,e)=>{let n=[...t].map((()=>-1/0)),i=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),s=0;for(const t of i)for(let i=0;i=n[i]){n[i]=t.endTime,t.order=i+e,i>s&&(s=i);break}return s};let U;const X={parser:u,db:G,renderer:{setConf:function(){c.l.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,i){const r=(0,c.c)().gantt,a=(0,c.c)().securityLevel;let o;"sandbox"===a&&(o=(0,l.Ys)("#i"+e));const d="sandbox"===a?(0,l.Ys)(o.nodes()[0].contentDocument.body):(0,l.Ys)("body"),u="sandbox"===a?o.nodes()[0].contentDocument:document,h=u.getElementById(e);U=h.parentElement.offsetWidth,void 0===U&&(U=1200),void 0!==r.useWidth&&(U=r.useWidth);const f=i.db.getTasks();let y=[];for(const t of f)y.push(t.type);y=function(t){const e={},n=[];for(let i=0,s=t.length;ie.type===t)).length}h.setAttribute("viewBox","0 0 "+U+" "+k);const p=d.select(`[id="${e}"]`),g=(0,l.Xf)().domain([(0,l.VV$)(f,(function(t){return t.startTime})),(0,l.Fp7)(f,(function(t){return t.endTime}))]).rangeRound([0,U-r.leftPadding-r.rightPadding]);f.sort((function(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:nt?Math.min(t,e):e),0),h=c.reduce(((t,{endTime:e})=>t?Math.max(t,e):e),0),f=i.db.getDateFormat();if(!u||!h)return;const y=[];let m=null,k=s(u);for(;k.valueOf()<=h;)i.db.isInvalidDate(k,f,l,d)?m?m.end=k:m={start:k,end:k}:m&&(y.push(m),m=null),k=k.add(1,"d");p.append("g").selectAll("rect").data(y).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return g(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return g(e)-g(t.start)})).attr("height",o-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(g(e.start)+n+.5*(g(e.end)-g(e.start))).toString()+"px "+(i*t+.5*o).toString()+"px"})).attr("class","exclude-range")}(d,h,f,0,a,t,i.db.getExcludes(),i.db.getIncludes()),function(t,e,n,s){let a=(0,l.LLu)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.i$Z)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));const o=/^([1-9]\d*)(minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==o){const t=o[1],e=o[2],n=i.db.getWeekday()||r.weekday;switch(e){case"minute":a.ticks(l.Z_i.every(t));break;case"hour":a.ticks(l.WQD.every(t));break;case"day":a.ticks(l.rr1.every(t));break;case"week":a.ticks(R[n].every(t));break;case"month":a.ticks(l.F0B.every(t))}}if(p.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(a).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=(0,l.F5q)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.i$Z)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==o){const t=o[1],e=o[2],s=i.db.getWeekday()||r.weekday;switch(e){case"minute":n.ticks(l.Z_i.every(t));break;case"hour":n.ticks(l.WQD.every(t));break;case"day":n.ticks(l.rr1.every(t));break;case"week":n.ticks(R[s].every(t));break;case"month":n.ticks(l.F0B.every(t))}}p.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(f,h,0,a),function(t,n,s,a,o,d,u){const h=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));p.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+s-2})).attr("width",(function(){return u-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of y.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const f=p.append("g").selectAll("rect").data(t).enter(),m=i.db.getLinks();if(f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))-.5*o:g(t.startTime)+a})).attr("y",(function(t,e){return t.order*n+s})).attr("width",(function(t){return t.milestone?o:g(t.renderEndTime||t.endTime)-g(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))).toString()+"px "+(e*n+s+.5*o).toString()+"px"})).attr("class",(function(t){let e="";t.classes.length>0&&(e=t.classes.join(" "));let n=0;for(const[e,i]of y.entries())t.type===i&&(n=e%r.numberSectionStyles);let i="";return t.active?t.crit?i+=" activeCrit":i=" active":t.done?i=t.crit?" doneCrit":" done":t.crit&&(i+=" crit"),0===i.length&&(i=" task"),t.milestone&&(i=" milestone "+i),i+=n,i+=" "+e,"task"+i})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=g(t.startTime),n=g(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(g(t.endTime)-g(t.startTime))-.5*o),t.milestone&&(n=e+o);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>u?e+a-5:n+a+5:(n-e)/2+e+a})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+s})).attr("text-height",o).attr("class",(function(t){const e=g(t.startTime);let n=g(t.endTime);t.milestone&&(n=e+o);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let a=0;for(const[e,n]of y.entries())t.type===n&&(a=e%r.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+a:"activeText"+a),t.done?c=t.crit?c+" doneCritText"+a:c+" doneText"+a:t.crit&&(c=c+" critText"+a),t.milestone&&(c+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>u?s+" taskTextOutsideLeft taskTextOutside"+a+" "+c:s+" taskTextOutsideRight taskTextOutside"+a+" "+c+" width-"+i:s+" taskText taskText"+a+" "+c+" width-"+i})),"sandbox"===(0,c.c)().securityLevel){let t;t=(0,l.Ys)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==m[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",m[t.id]),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)}))}}(t,d,h,f,o,0,n),function(t,e){let n=0;const i=Object.keys(m).map((t=>[t,m[t]]));p.append("g").selectAll("text").data(i).enter().append((function(t){const e=t[0].split(c.e.lineBreakRegex),n=-(e.length-1)/2,i=u.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[t,n]of e.entries()){const e=u.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttribute("alignment-baseline","central"),e.setAttribute("x","10"),t>0&&e.setAttribute("dy","1em"),e.textContent=n,i.appendChild(e)}return i})).attr("x",10).attr("y",(function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a`\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n // text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n\n // .taskText:not([font-size]) {\n // font-size: ${t.ganttFontSize};\n // }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n // font-size: ${t.ganttFontSize};\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor} ;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n`}}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/81-4e653aac.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/81-4e653aac.chunk.min.js new file mode 100644 index 000000000..ff41b6ce4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/81-4e653aac.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[81],{3349:function(e,t,n){n.d(t,{a:function(){return l}});var r=n(6225);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.bg(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},6225:function(e,t,n){n.d(t,{$p:function(){return d},O1:function(){return a},WR:function(){return p},bF:function(){return o},bg:function(){return c}});var r=n(7514),l=n(3234);function o(e,t){return!!e.children(t).length}function a(e){return s(e.v)+":"+s(e.w)+":"+s(e.name)}var i=/:/g;function s(e){return e?String(e).replace(i,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.Z(n)){var o=n.transition;if(l.Z(o))return o(e)}return e}},3081:function(e,t,n){n.d(t,{diagram:function(){return a}});var r=n(1813),l=n(8912),o=n(9339);n(7274),n(5625),n(3771),n(9368),n(7484),n(7967),n(7856);const a={parser:r.p,db:r.f,renderer:l.f,styles:l.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,(0,o.q)({flowchart:{arrowMarkerAbsolute:e.arrowMarkerAbsolute}}),l.f.setConf(e.flowchart),r.f.clear(),r.f.setGen("gen-2")}}},8912:function(e,t,n){n.d(t,{a:function(){return h},f:function(){return w}});var r=n(5625),l=n(7274),o=n(9339),a=n(6476),i=n(3349),s=n(5971),c=n(1767),d=(e,t)=>s.Z.lang.round(c.Z.parse(e)[t]),p=n(1117);const b={},u=function(e,t,n,r,l,a){const s=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let c="default";r.classes.length>0&&(c=r.classes.join(" ")),c+=" flowchart-label";const d=(0,o.k)(r.styles);let p,b=void 0!==r.text?r.text:r.id;if(o.l.info("vertex",r,r.labelType),"markdown"===r.labelType)o.l.info("vertex",r,r.labelType);else if((0,o.n)((0,o.c)().flowchart.htmlLabels)){const e={label:b.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``))};p=(0,i.a)(s,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",d.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let u=0,f="";switch(r.type){case"round":u=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}t.setNode(r.id,{labelStyle:d.labelStyle,shape:f,labelText:b,labelType:r.labelType,rx:u,ry:u,class:c,style:d.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:a.db.getTooltip(r.id)||"",domId:a.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:d.labelStyle,labelType:r.labelType,shape:f,labelText:b,rx:u,ry:u,class:c,style:d.style,id:r.id,domId:a.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:(0,o.c)().flowchart.padding})}))},f=function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,i=0,s={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}e.forEach((function(n){i++;const c="L-"+n.start+"-"+n.end;void 0===s[c]?(s[c]=0,o.l.info("abc78 new entry",c,s[c])):(s[c]++,o.l.info("abc78 new entry",c,s[c]));let d=c+"-"+s[c];o.l.info("abc78 new link id to be used is",c,d,s[c]);const p="LS-"+n.start,u="LE-"+n.end,f={style:"",labelStyle:""};switch(f.minlen=n.length||1,"arrow_open"===n.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let w="",h="";switch(n.stroke){case"normal":w="fill:none;",void 0!==r&&(w=r),void 0!==a&&(h=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=(0,o.k)(n.style);w=e.style,h=e.labelStyle}f.style=f.style+=w,f.labelStyle=f.labelStyle+=h,void 0!==n.interpolate?f.curve=(0,o.o)(n.interpolate,l.c_6):void 0!==e.defaultInterpolate?f.curve=(0,o.o)(e.defaultInterpolate,l.c_6):f.curve=(0,o.o)(b.curve,l.c_6),void 0===n.text?void 0!==n.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=n.labelType,f.label=n.text.replace(o.e.lineBreakRegex,"\n"),void 0===n.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=d,f.classes="flowchart-link "+p+" "+u,t.setEdge(n.start,n.end,f,i)}))},w={setConf:function(e){const t=Object.keys(e);for(const n of t)b[n]=e[n]},addVertices:u,addEdges:f,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,i){o.l.info("Drawing flowchart");let s=i.db.getDirection();void 0===s&&(s="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),p=d.nodeSpacing||50,b=d.rankSpacing||50;let w;"sandbox"===c&&(w=(0,l.Ys)("#i"+t));const h="sandbox"===c?(0,l.Ys)(w.nodes()[0].contentDocument.body):(0,l.Ys)("body"),g="sandbox"===c?w.nodes()[0].contentDocument:document,y=new r.k({multigraph:!0,compound:!0}).setGraph({rankdir:s,nodesep:p,ranksep:b,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=i.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let e=x.length-1;e>=0;e--)k=x[e],o.l.info("Subgraph - ",k),i.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=i.db.getVertices(),m=i.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.td_)("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=d,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return p.Z(r,l,o,.5)})(e.edgeLabelBackground)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/813-0d3c16f5.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/813-0d3c16f5.chunk.min.js new file mode 100644 index 000000000..0e855b092 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/813-0d3c16f5.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[813],{1813:function(t,e,s){s.d(e,{d:function(){return ut},f:function(){return st},p:function(){return n}});var u=s(7274),i=s(9339),r=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,9],s=[1,7],u=[1,6],i=[1,8],r=[1,20,21,22,23,38,45,47,49,53,69,92,93,94,95,96,97,110,113,114,117,119,122,123,124,129,130,131,132],n=[2,10],a=[1,20],c=[1,21],o=[1,22],l=[1,23],h=[1,30],A=[1,32],d=[1,33],p=[1,34],y=[1,56],E=[1,55],f=[1,36],k=[1,37],D=[1,38],g=[1,39],b=[1,40],_=[1,51],F=[1,53],T=[1,49],C=[1,54],S=[1,50],B=[1,57],m=[1,52],v=[1,58],x=[1,59],L=[1,41],I=[1,42],R=[1,43],N=[1,44],$=[1,62],O=[1,67],P=[1,20,21,22,23,38,43,45,47,49,53,69,92,93,94,95,96,97,110,113,114,117,119,122,123,124,129,130,131,132],w=[1,71],U=[1,70],V=[1,72],G=[20,21,23,84,86],M=[1,98],K=[1,103],Y=[1,102],j=[1,99],X=[1,95],z=[1,101],H=[1,97],W=[1,104],Q=[1,100],q=[1,105],Z=[1,96],J=[20,21,22,23,84,86],tt=[20,21,22,23,55,84,86],et=[20,21,22,23,40,53,55,57,59,61,63,65,67,69,72,74,76,77,79,84,86,97,110,113,114,117,119,122,123,124],st=[20,21,23],ut=[20,21,23,53,69,84,86,97,110,113,114,117,119,122,123,124],it=[1,12,20,21,22,23,24,38,43,45,47,49,53,69,92,93,94,95,96,97,110,113,114,117,119,122,123,124,129,130,131,132],rt=[53,69,97,110,113,114,117,119,122,123,124],nt=[1,134],at=[1,133],ct=[1,141],ot=[1,155],lt=[1,156],ht=[1,157],At=[1,158],dt=[1,143],pt=[1,145],yt=[1,149],Et=[1,150],ft=[1,151],kt=[1,152],Dt=[1,153],gt=[1,154],bt=[1,159],_t=[1,160],Ft=[1,139],Tt=[1,140],Ct=[1,147],St=[1,142],Bt=[1,146],mt=[1,144],vt=[20,21,22,23,38,43,45,47,49,53,69,92,93,94,95,96,97,110,113,114,117,119,122,123,124,129,130,131,132],xt=[1,162],Lt=[20,21,22,23,26,53,69,97,113,114,117,119,122,123,124],It=[1,182],Rt=[1,178],Nt=[1,179],$t=[1,183],Ot=[1,180],Pt=[1,181],wt=[12,21,22,24],Ut=[86,124,127],Vt=[20,21,22,23,24,26,38,40,43,53,69,84,92,93,94,95,96,97,98,113,117,119,122,123,124],Gt=[22,114],Mt=[42,58,60,62,64,66,71,73,75,76,78,80,124,125,126],Kt=[1,250],Yt=[1,248],jt=[1,252],Xt=[1,246],zt=[1,247],Ht=[1,249],Wt=[1,251],Qt=[1,253],qt=[1,270],Zt=[20,21,23,114],Jt=[20,21,22,23,69,92,113,114,117,118,119,120],te={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,openDirective:6,typeDirective:7,closeDirective:8,separator:9,":":10,argDirective:11,open_directive:12,type_directive:13,arg_directive:14,close_directive:15,graphConfig:16,document:17,line:18,statement:19,SEMI:20,NEWLINE:21,SPACE:22,EOF:23,GRAPH:24,NODIR:25,DIR:26,FirstStmtSeperator:27,ending:28,endToken:29,spaceList:30,spaceListNewline:31,verticeStatement:32,styleStatement:33,linkStyleStatement:34,classDefStatement:35,classStatement:36,clickStatement:37,subgraph:38,textNoTags:39,SQS:40,text:41,SQE:42,end:43,direction:44,acc_title:45,acc_title_value:46,acc_descr:47,acc_descr_value:48,acc_descr_multiline_value:49,link:50,node:51,styledVertex:52,AMP:53,vertex:54,STYLE_SEPARATOR:55,idString:56,DOUBLECIRCLESTART:57,DOUBLECIRCLEEND:58,PS:59,PE:60,"(-":61,"-)":62,STADIUMSTART:63,STADIUMEND:64,SUBROUTINESTART:65,SUBROUTINEEND:66,VERTEX_WITH_PROPS_START:67,"NODE_STRING[field]":68,COLON:69,"NODE_STRING[value]":70,PIPE:71,CYLINDERSTART:72,CYLINDEREND:73,DIAMOND_START:74,DIAMOND_STOP:75,TAGEND:76,TRAPSTART:77,TRAPEND:78,INVTRAPSTART:79,INVTRAPEND:80,linkStatement:81,arrowText:82,TESTSTR:83,START_LINK:84,edgeText:85,LINK:86,edgeTextToken:87,STR:88,MD_STR:89,textToken:90,keywords:91,STYLE:92,LINKSTYLE:93,CLASSDEF:94,CLASS:95,CLICK:96,DOWN:97,UP:98,textNoTagsToken:99,stylesOpt:100,"idString[vertex]":101,"idString[class]":102,CALLBACKNAME:103,CALLBACKARGS:104,HREF:105,LINK_TARGET:106,"STR[link]":107,"STR[tooltip]":108,alphaNum:109,DEFAULT:110,numList:111,INTERPOLATE:112,NUM:113,COMMA:114,style:115,styleComponent:116,NODE_STRING:117,UNIT:118,BRKT:119,PCT:120,idStringToken:121,MINUS:122,MULT:123,UNICODE_TEXT:124,TEXT:125,TAGSTART:126,EDGE_TEXT:127,alphaNumToken:128,direction_tb:129,direction_bt:130,direction_rl:131,direction_lr:132,$accept:0,$end:1},terminals_:{2:"error",10:":",12:"open_directive",13:"type_directive",14:"arg_directive",15:"close_directive",20:"SEMI",21:"NEWLINE",22:"SPACE",23:"EOF",24:"GRAPH",25:"NODIR",26:"DIR",38:"subgraph",40:"SQS",42:"SQE",43:"end",45:"acc_title",46:"acc_title_value",47:"acc_descr",48:"acc_descr_value",49:"acc_descr_multiline_value",53:"AMP",55:"STYLE_SEPARATOR",57:"DOUBLECIRCLESTART",58:"DOUBLECIRCLEEND",59:"PS",60:"PE",61:"(-",62:"-)",63:"STADIUMSTART",64:"STADIUMEND",65:"SUBROUTINESTART",66:"SUBROUTINEEND",67:"VERTEX_WITH_PROPS_START",68:"NODE_STRING[field]",69:"COLON",70:"NODE_STRING[value]",71:"PIPE",72:"CYLINDERSTART",73:"CYLINDEREND",74:"DIAMOND_START",75:"DIAMOND_STOP",76:"TAGEND",77:"TRAPSTART",78:"TRAPEND",79:"INVTRAPSTART",80:"INVTRAPEND",83:"TESTSTR",84:"START_LINK",86:"LINK",88:"STR",89:"MD_STR",92:"STYLE",93:"LINKSTYLE",94:"CLASSDEF",95:"CLASS",96:"CLICK",97:"DOWN",98:"UP",101:"idString[vertex]",102:"idString[class]",103:"CALLBACKNAME",104:"CALLBACKARGS",105:"HREF",106:"LINK_TARGET",107:"STR[link]",108:"STR[tooltip]",110:"DEFAULT",112:"INTERPOLATE",113:"NUM",114:"COMMA",117:"NODE_STRING",118:"UNIT",119:"BRKT",120:"PCT",122:"MINUS",123:"MULT",124:"UNICODE_TEXT",125:"TEXT",126:"TAGSTART",127:"EDGE_TEXT",129:"direction_tb",130:"direction_bt",131:"direction_rl",132:"direction_lr"},productions_:[0,[3,1],[3,2],[5,4],[5,6],[6,1],[7,1],[11,1],[8,1],[4,2],[17,0],[17,2],[18,1],[18,1],[18,1],[18,1],[18,1],[16,2],[16,2],[16,2],[16,3],[28,2],[28,1],[29,1],[29,1],[29,1],[27,1],[27,1],[27,2],[31,2],[31,2],[31,1],[31,1],[30,2],[30,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,2],[19,9],[19,6],[19,4],[19,1],[19,2],[19,2],[19,1],[9,1],[9,1],[9,1],[32,3],[32,4],[32,2],[32,1],[51,1],[51,5],[52,1],[52,3],[54,4],[54,4],[54,6],[54,4],[54,4],[54,4],[54,8],[54,4],[54,4],[54,4],[54,6],[54,4],[54,4],[54,4],[54,4],[54,4],[54,1],[50,2],[50,3],[50,3],[50,1],[50,3],[85,1],[85,2],[85,1],[85,1],[81,1],[82,3],[41,1],[41,2],[41,1],[41,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[39,1],[39,2],[39,1],[39,1],[35,5],[36,5],[37,2],[37,4],[37,3],[37,5],[37,3],[37,5],[37,5],[37,7],[37,2],[37,4],[37,2],[37,4],[37,4],[37,6],[33,5],[34,5],[34,5],[34,9],[34,9],[34,7],[34,7],[111,1],[111,3],[100,1],[100,3],[115,1],[115,2],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[121,1],[90,1],[90,1],[90,1],[90,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[99,1],[87,1],[87,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[56,1],[56,2],[109,1],[109,2],[44,1],[44,1],[44,1],[44,1]],performAction:function(t,e,s,u,i,r,n){var a=r.length-1;switch(i){case 5:u.parseDirective("%%{","open_directive");break;case 6:u.parseDirective(r[a],"type_directive");break;case 7:r[a]=r[a].trim().replace(/'/g,'"'),u.parseDirective(r[a],"arg_directive");break;case 8:u.parseDirective("}%%","close_directive","flowchart");break;case 10:case 36:case 37:case 38:case 39:case 40:this.$=[];break;case 11:(!Array.isArray(r[a])||r[a].length>0)&&r[a-1].push(r[a]),this.$=r[a-1];break;case 12:case 184:case 57:case 79:case 182:this.$=r[a];break;case 19:u.setDirection("TB"),this.$="TB";break;case 20:u.setDirection(r[a-1]),this.$=r[a-1];break;case 35:this.$=r[a-1].nodes;break;case 41:this.$=u.addSubGraph(r[a-6],r[a-1],r[a-4]);break;case 42:this.$=u.addSubGraph(r[a-3],r[a-1],r[a-3]);break;case 43:this.$=u.addSubGraph(void 0,r[a-1],void 0);break;case 45:this.$=r[a].trim(),u.setAccTitle(this.$);break;case 46:case 47:this.$=r[a].trim(),u.setAccDescription(this.$);break;case 51:u.addLink(r[a-2].stmt,r[a],r[a-1]),this.$={stmt:r[a],nodes:r[a].concat(r[a-2].nodes)};break;case 52:u.addLink(r[a-3].stmt,r[a-1],r[a-2]),this.$={stmt:r[a-1],nodes:r[a-1].concat(r[a-3].nodes)};break;case 53:this.$={stmt:r[a-1],nodes:r[a-1]};break;case 54:this.$={stmt:r[a],nodes:r[a]};break;case 55:case 129:case 131:this.$=[r[a]];break;case 56:this.$=r[a-4].concat(r[a]);break;case 58:this.$=r[a-2],u.setClass(r[a-2],r[a]);break;case 59:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"square");break;case 60:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"doublecircle");break;case 61:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"circle");break;case 62:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"ellipse");break;case 63:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"stadium");break;case 64:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"subroutine");break;case 65:this.$=r[a-7],u.addVertex(r[a-7],r[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[r[a-5],r[a-3]]]));break;case 66:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"cylinder");break;case 67:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"round");break;case 68:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"diamond");break;case 69:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"hexagon");break;case 70:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"odd");break;case 71:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"trapezoid");break;case 72:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"inv_trapezoid");break;case 73:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_right");break;case 74:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_left");break;case 75:this.$=r[a],u.addVertex(r[a]);break;case 76:r[a-1].text=r[a],this.$=r[a-1];break;case 77:case 78:r[a-2].text=r[a-1],this.$=r[a-2];break;case 80:var c=u.destructLink(r[a],r[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:r[a-1]};break;case 81:case 87:case 102:case 104:this.$={text:r[a],type:"text"};break;case 82:case 88:case 103:this.$={text:r[a-1].text+""+r[a],type:r[a-1].type};break;case 83:case 89:this.$={text:r[a],type:"string"};break;case 84:case 90:case 105:this.$={text:r[a],type:"markdown"};break;case 85:c=u.destructLink(r[a]),this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 86:this.$=r[a-1];break;case 106:this.$=r[a-4],u.addClass(r[a-2],r[a]);break;case 107:this.$=r[a-4],u.setClass(r[a-2],r[a]);break;case 108:case 116:this.$=r[a-1],u.setClickEvent(r[a-1],r[a]);break;case 109:case 117:this.$=r[a-3],u.setClickEvent(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 110:this.$=r[a-2],u.setClickEvent(r[a-2],r[a-1],r[a]);break;case 111:this.$=r[a-4],u.setClickEvent(r[a-4],r[a-3],r[a-2]),u.setTooltip(r[a-4],r[a]);break;case 112:this.$=r[a-2],u.setLink(r[a-2],r[a]);break;case 113:this.$=r[a-4],u.setLink(r[a-4],r[a-2]),u.setTooltip(r[a-4],r[a]);break;case 114:this.$=r[a-4],u.setLink(r[a-4],r[a-2],r[a]);break;case 115:this.$=r[a-6],u.setLink(r[a-6],r[a-4],r[a]),u.setTooltip(r[a-6],r[a-2]);break;case 118:this.$=r[a-1],u.setLink(r[a-1],r[a]);break;case 119:this.$=r[a-3],u.setLink(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 120:this.$=r[a-3],u.setLink(r[a-3],r[a-2],r[a]);break;case 121:this.$=r[a-5],u.setLink(r[a-5],r[a-4],r[a]),u.setTooltip(r[a-5],r[a-2]);break;case 122:this.$=r[a-4],u.addVertex(r[a-2],void 0,void 0,r[a]);break;case 123:this.$=r[a-4],u.updateLink([r[a-2]],r[a]);break;case 124:this.$=r[a-4],u.updateLink(r[a-2],r[a]);break;case 125:this.$=r[a-8],u.updateLinkInterpolate([r[a-6]],r[a-2]),u.updateLink([r[a-6]],r[a]);break;case 126:this.$=r[a-8],u.updateLinkInterpolate(r[a-6],r[a-2]),u.updateLink(r[a-6],r[a]);break;case 127:this.$=r[a-6],u.updateLinkInterpolate([r[a-4]],r[a]);break;case 128:this.$=r[a-6],u.updateLinkInterpolate(r[a-4],r[a]);break;case 130:case 132:r[a-2].push(r[a]),this.$=r[a-2];break;case 134:this.$=r[a-1]+r[a];break;case 183:case 185:this.$=r[a-1]+""+r[a];break;case 186:this.$={stmt:"dir",value:"TB"};break;case 187:this.$={stmt:"dir",value:"BT"};break;case 188:this.$={stmt:"dir",value:"RL"};break;case 189:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},{1:[3]},{1:[2,1]},{3:10,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},t(r,n,{17:11}),{7:12,13:[1,13]},{16:14,21:s,22:u,24:i},{16:15,21:s,22:u,24:i},{25:[1,16],26:[1,17]},{13:[2,5]},{1:[2,2]},{1:[2,9],18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,44:31,45:A,47:d,49:p,51:35,52:45,53:y,54:46,56:47,69:E,92:f,93:k,94:D,95:g,96:b,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x,129:L,130:I,131:R,132:N},{8:60,10:[1,61],15:$},t([10,15],[2,6]),t(r,[2,17]),t(r,[2,18]),t(r,[2,19]),{20:[1,64],21:[1,65],22:O,27:63,30:66},t(P,[2,11]),t(P,[2,12]),t(P,[2,13]),t(P,[2,14]),t(P,[2,15]),t(P,[2,16]),{9:68,20:w,21:U,23:V,50:69,81:73,84:[1,74],86:[1,75]},{9:76,20:w,21:U,23:V},{9:77,20:w,21:U,23:V},{9:78,20:w,21:U,23:V},{9:79,20:w,21:U,23:V},{9:80,20:w,21:U,23:V},{9:82,20:w,21:U,22:[1,81],23:V},t(P,[2,44]),{46:[1,83]},{48:[1,84]},t(P,[2,47]),t(G,[2,54],{30:85,22:O}),{22:[1,86]},{22:[1,87]},{22:[1,88]},{22:[1,89]},{26:M,53:K,69:Y,88:[1,93],97:j,103:[1,90],105:[1,91],109:92,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z,128:94},t(P,[2,186]),t(P,[2,187]),t(P,[2,188]),t(P,[2,189]),t(J,[2,55]),t(J,[2,57],{55:[1,106]}),t(tt,[2,75],{121:119,40:[1,107],53:y,57:[1,108],59:[1,109],61:[1,110],63:[1,111],65:[1,112],67:[1,113],69:E,72:[1,114],74:[1,115],76:[1,116],77:[1,117],79:[1,118],97:_,110:F,113:T,114:C,117:S,119:B,122:m,123:v,124:x}),t(et,[2,182]),t(et,[2,143]),t(et,[2,144]),t(et,[2,145]),t(et,[2,146]),t(et,[2,147]),t(et,[2,148]),t(et,[2,149]),t(et,[2,150]),t(et,[2,151]),t(et,[2,152]),t(et,[2,153]),{9:120,20:w,21:U,23:V},{11:121,14:[1,122]},t(st,[2,8]),t(r,[2,20]),t(r,[2,26]),t(r,[2,27]),{21:[1,123]},t(ut,[2,34],{30:124,22:O}),t(P,[2,35]),{51:125,52:45,53:y,54:46,56:47,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},t(it,[2,48]),t(it,[2,49]),t(it,[2,50]),t(rt,[2,79],{82:126,71:[1,128],83:[1,127]}),{85:129,87:130,88:[1,131],89:[1,132],124:nt,127:at},t([53,69,71,83,97,110,113,114,117,119,122,123,124],[2,85]),t(P,[2,36]),t(P,[2,37]),t(P,[2,38]),t(P,[2,39]),t(P,[2,40]),{22:ct,24:ot,26:lt,38:ht,39:135,43:At,53:dt,69:pt,84:yt,88:[1,137],89:[1,138],91:148,92:Et,93:ft,94:kt,95:Dt,96:gt,97:bt,98:_t,99:136,113:Ft,117:Tt,119:Ct,122:St,123:Bt,124:mt},t(vt,n,{17:161}),t(P,[2,45]),t(P,[2,46]),t(G,[2,53],{53:xt}),{53:y,56:163,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},{110:[1,164],111:165,113:[1,166]},{53:y,56:167,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},{53:y,56:168,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},t(st,[2,108],{22:[1,169],104:[1,170]}),{88:[1,171]},t(st,[2,116],{128:173,22:[1,172],26:M,53:K,69:Y,97:j,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z}),t(st,[2,118],{22:[1,174]}),t(Lt,[2,184]),t(Lt,[2,171]),t(Lt,[2,172]),t(Lt,[2,173]),t(Lt,[2,174]),t(Lt,[2,175]),t(Lt,[2,176]),t(Lt,[2,177]),t(Lt,[2,178]),t(Lt,[2,179]),t(Lt,[2,180]),t(Lt,[2,181]),{53:y,56:175,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},{41:176,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:184,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:186,59:[1,185],76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:187,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:188,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:189,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{117:[1,190]},{41:191,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:192,74:[1,193],76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:194,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:195,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{41:196,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},t(et,[2,183]),t(wt,[2,3]),{8:197,15:$},{15:[2,7]},t(r,[2,28]),t(ut,[2,33]),t(G,[2,51],{30:198,22:O}),t(rt,[2,76],{22:[1,199]}),{22:[1,200]},{41:201,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{86:[1,202],87:203,124:nt,127:at},t(Ut,[2,81]),t(Ut,[2,83]),t(Ut,[2,84]),t(Ut,[2,169]),t(Ut,[2,170]),{9:205,20:w,21:U,22:ct,23:V,24:ot,26:lt,38:ht,40:[1,204],43:At,53:dt,69:pt,84:yt,91:148,92:Et,93:ft,94:kt,95:Dt,96:gt,97:bt,98:_t,99:206,113:Ft,117:Tt,119:Ct,122:St,123:Bt,124:mt},t(Vt,[2,102]),t(Vt,[2,104]),t(Vt,[2,105]),t(Vt,[2,158]),t(Vt,[2,159]),t(Vt,[2,160]),t(Vt,[2,161]),t(Vt,[2,162]),t(Vt,[2,163]),t(Vt,[2,164]),t(Vt,[2,165]),t(Vt,[2,166]),t(Vt,[2,167]),t(Vt,[2,168]),t(Vt,[2,91]),t(Vt,[2,92]),t(Vt,[2,93]),t(Vt,[2,94]),t(Vt,[2,95]),t(Vt,[2,96]),t(Vt,[2,97]),t(Vt,[2,98]),t(Vt,[2,99]),t(Vt,[2,100]),t(Vt,[2,101]),{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:[1,207],44:31,45:A,47:d,49:p,51:35,52:45,53:y,54:46,56:47,69:E,92:f,93:k,94:D,95:g,96:b,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x,129:L,130:I,131:R,132:N},{22:O,30:208},{22:[1,209],53:y,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:119,122:m,123:v,124:x},{22:[1,210]},{22:[1,211],114:[1,212]},t(Gt,[2,129]),{22:[1,213],53:y,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:119,122:m,123:v,124:x},{22:[1,214],53:y,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:119,122:m,123:v,124:x},{88:[1,215]},t(st,[2,110],{22:[1,216]}),t(st,[2,112],{22:[1,217]}),{88:[1,218]},t(Lt,[2,185]),{88:[1,219],106:[1,220]},t(J,[2,58],{121:119,53:y,69:E,97:_,110:F,113:T,114:C,117:S,119:B,122:m,123:v,124:x}),{42:[1,221],76:It,90:222,124:$t,125:Ot,126:Pt},t(Mt,[2,87]),t(Mt,[2,89]),t(Mt,[2,90]),t(Mt,[2,154]),t(Mt,[2,155]),t(Mt,[2,156]),t(Mt,[2,157]),{58:[1,223],76:It,90:222,124:$t,125:Ot,126:Pt},{41:224,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{60:[1,225],76:It,90:222,124:$t,125:Ot,126:Pt},{62:[1,226],76:It,90:222,124:$t,125:Ot,126:Pt},{64:[1,227],76:It,90:222,124:$t,125:Ot,126:Pt},{66:[1,228],76:It,90:222,124:$t,125:Ot,126:Pt},{69:[1,229]},{73:[1,230],76:It,90:222,124:$t,125:Ot,126:Pt},{75:[1,231],76:It,90:222,124:$t,125:Ot,126:Pt},{41:232,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},{42:[1,233],76:It,90:222,124:$t,125:Ot,126:Pt},{76:It,78:[1,234],80:[1,235],90:222,124:$t,125:Ot,126:Pt},{76:It,78:[1,237],80:[1,236],90:222,124:$t,125:Ot,126:Pt},{9:238,20:w,21:U,23:V},t(G,[2,52],{53:xt}),t(rt,[2,78]),t(rt,[2,77]),{71:[1,239],76:It,90:222,124:$t,125:Ot,126:Pt},t(rt,[2,80]),t(Ut,[2,82]),{41:240,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},t(vt,n,{17:241}),t(Vt,[2,103]),t(P,[2,43]),{52:242,53:y,54:46,56:47,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},{22:Kt,69:Yt,92:jt,100:243,113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},{22:Kt,69:Yt,92:jt,100:254,112:[1,255],113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},{22:Kt,69:Yt,92:jt,100:256,112:[1,257],113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},{113:[1,258]},{22:Kt,69:Yt,92:jt,100:259,113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},{53:y,56:260,69:E,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x},t(st,[2,109]),{88:[1,261]},{88:[1,262],106:[1,263]},t(st,[2,117]),t(st,[2,119],{22:[1,264]}),t(st,[2,120]),t(tt,[2,59]),t(Mt,[2,88]),t(tt,[2,60]),{60:[1,265],76:It,90:222,124:$t,125:Ot,126:Pt},t(tt,[2,67]),t(tt,[2,62]),t(tt,[2,63]),t(tt,[2,64]),{117:[1,266]},t(tt,[2,66]),t(tt,[2,68]),{75:[1,267],76:It,90:222,124:$t,125:Ot,126:Pt},t(tt,[2,70]),t(tt,[2,71]),t(tt,[2,73]),t(tt,[2,72]),t(tt,[2,74]),t(wt,[2,4]),t([22,53,69,97,110,113,114,117,119,122,123,124],[2,86]),{42:[1,268],76:It,90:222,124:$t,125:Ot,126:Pt},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:[1,269],44:31,45:A,47:d,49:p,51:35,52:45,53:y,54:46,56:47,69:E,92:f,93:k,94:D,95:g,96:b,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x,129:L,130:I,131:R,132:N},t(J,[2,56]),t(st,[2,122],{114:qt}),t(Zt,[2,131],{116:271,22:Kt,69:Yt,92:jt,113:Xt,117:zt,118:Ht,119:Wt,120:Qt}),t(Jt,[2,133]),t(Jt,[2,135]),t(Jt,[2,136]),t(Jt,[2,137]),t(Jt,[2,138]),t(Jt,[2,139]),t(Jt,[2,140]),t(Jt,[2,141]),t(Jt,[2,142]),t(st,[2,123],{114:qt}),{22:[1,272]},t(st,[2,124],{114:qt}),{22:[1,273]},t(Gt,[2,130]),t(st,[2,106],{114:qt}),t(st,[2,107],{121:119,53:y,69:E,97:_,110:F,113:T,114:C,117:S,119:B,122:m,123:v,124:x}),t(st,[2,111]),t(st,[2,113],{22:[1,274]}),t(st,[2,114]),{106:[1,275]},{60:[1,276]},{71:[1,277]},{75:[1,278]},{9:279,20:w,21:U,23:V},t(P,[2,42]),{22:Kt,69:Yt,92:jt,113:Xt,115:280,116:245,117:zt,118:Ht,119:Wt,120:Qt},t(Jt,[2,134]),{26:M,53:K,69:Y,97:j,109:281,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z,128:94},{26:M,53:K,69:Y,97:j,109:282,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z,128:94},{106:[1,283]},t(st,[2,121]),t(tt,[2,61]),{41:284,76:It,88:Rt,89:Nt,90:177,124:$t,125:Ot,126:Pt},t(tt,[2,69]),t(vt,n,{17:285}),t(Zt,[2,132],{116:271,22:Kt,69:Yt,92:jt,113:Xt,117:zt,118:Ht,119:Wt,120:Qt}),t(st,[2,127],{128:173,22:[1,286],26:M,53:K,69:Y,97:j,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z}),t(st,[2,128],{128:173,22:[1,287],26:M,53:K,69:Y,97:j,113:X,114:z,117:H,119:W,122:Q,123:q,124:Z}),t(st,[2,115]),{42:[1,288],76:It,90:222,124:$t,125:Ot,126:Pt},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:[1,289],44:31,45:A,47:d,49:p,51:35,52:45,53:y,54:46,56:47,69:E,92:f,93:k,94:D,95:g,96:b,97:_,110:F,113:T,114:C,117:S,119:B,121:48,122:m,123:v,124:x,129:L,130:I,131:R,132:N},{22:Kt,69:Yt,92:jt,100:290,113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},{22:Kt,69:Yt,92:jt,100:291,113:Xt,115:244,116:245,117:zt,118:Ht,119:Wt,120:Qt},t(tt,[2,65]),t(P,[2,41]),t(st,[2,125],{114:qt}),t(st,[2,126],{114:qt})],defaultActions:{2:[2,1],9:[2,5],10:[2,2],122:[2,7]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=[0],s=[],u=[null],i=[],r=this.table,n="",a=0,c=0,o=i.slice.call(arguments,1),l=Object.create(this.lexer),h={yy:{}};for(var A in this.yy)Object.prototype.hasOwnProperty.call(this.yy,A)&&(h.yy[A]=this.yy[A]);l.setInput(t,h.yy),h.yy.lexer=l,h.yy.parser=this,void 0===l.yylloc&&(l.yylloc={});var d=l.yylloc;i.push(d);var p=l.options&&l.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,E,f,k,D,g,b,_,F,T={};;){if(E=e[e.length-1],this.defaultActions[E]?f=this.defaultActions[E]:(null==y&&(F=void 0,"number"!=typeof(F=s.pop()||l.lex()||1)&&(F instanceof Array&&(F=(s=F).pop()),F=this.symbols_[F]||F),y=F),f=r[E]&&r[E][y]),void 0===f||!f.length||!f[0]){var C;for(D in _=[],r[E])this.terminals_[D]&&D>2&&_.push("'"+this.terminals_[D]+"'");C=l.showPosition?"Parse error on line "+(a+1)+":\n"+l.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(a+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(C,{text:l.match,token:this.terminals_[y]||y,line:l.yylineno,loc:d,expected:_})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+y);switch(f[0]){case 1:e.push(y),u.push(l.yytext),i.push(l.yylloc),e.push(f[1]),y=null,c=l.yyleng,n=l.yytext,a=l.yylineno,d=l.yylloc;break;case 2:if(g=this.productions_[f[1]][1],T.$=u[u.length-g],T._$={first_line:i[i.length-(g||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(g||1)].first_column,last_column:i[i.length-1].last_column},p&&(T._$.range=[i[i.length-(g||1)].range[0],i[i.length-1].range[1]]),void 0!==(k=this.performAction.apply(T,[n,c,a,h.yy,f[1],u,i].concat(o))))return k;g&&(e=e.slice(0,-1*g*2),u=u.slice(0,-1*g),i=i.slice(0,-1*g)),e.push(this.productions_[f[1]][0]),u.push(T.$),i.push(T._$),b=r[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},ee={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in i)this[r]=i[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),r=0;re[0].length)){if(e=s,u=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:return this.begin("acc_title"),45;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),47;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 13:case 16:case 19:case 22:case 32:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:this.begin("callbackname");break;case 14:this.popState(),this.begin("callbackargs");break;case 15:return 103;case 17:return 104;case 18:return"MD_STR";case 20:this.begin("md_string");break;case 21:return"STR";case 23:this.pushState("string");break;case 24:return 92;case 25:return 110;case 26:return 93;case 27:return 112;case 28:return 94;case 29:return 95;case 30:return 105;case 31:this.begin("click");break;case 33:return 96;case 34:case 35:case 36:return t.lex.firstGraph()&&this.begin("dir"),24;case 37:return 38;case 38:return 43;case 39:case 40:case 41:case 42:return 106;case 43:return this.popState(),25;case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:return this.popState(),26;case 54:return 129;case 55:return 130;case 56:return 131;case 57:return 132;case 58:return 113;case 59:case 100:return 119;case 60:return 55;case 61:return 69;case 62:case 101:return 53;case 63:return 20;case 64:return 114;case 65:case 99:return 123;case 66:case 69:case 72:return this.popState(),86;case 67:return this.pushState("edgeText"),84;case 68:case 71:case 74:return 127;case 70:return this.pushState("thickEdgeText"),84;case 73:return this.pushState("dottedEdgeText"),84;case 75:return 86;case 76:return this.popState(),62;case 77:case 113:return"TEXT";case 78:return this.pushState("ellipseText"),61;case 79:return this.popState(),64;case 80:return this.pushState("text"),63;case 81:return this.popState(),66;case 82:return this.pushState("text"),65;case 83:return 67;case 84:return this.pushState("text"),76;case 85:return this.popState(),73;case 86:return this.pushState("text"),72;case 87:return this.popState(),58;case 88:return this.pushState("text"),57;case 89:return this.popState(),78;case 90:return this.popState(),80;case 91:return 125;case 92:return this.pushState("trapText"),77;case 93:return this.pushState("trapText"),79;case 94:return 126;case 95:return 76;case 96:return 98;case 97:return"SEP";case 98:return 97;case 102:return 117;case 103:return 122;case 104:return 124;case 105:return this.popState(),71;case 106:return this.pushState("text"),71;case 107:return this.popState(),60;case 108:return this.pushState("text"),59;case 109:return this.popState(),42;case 110:return this.pushState("text"),40;case 111:return this.popState(),75;case 112:return this.pushState("text"),74;case 114:return"QUOTE";case 115:return 21;case 116:return 22;case 117:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|(?!\)+))/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},arg_directive:{rules:[3,4,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},type_directive:{rules:[2,3,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},open_directive:{rules:[1,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},callbackargs:{rules:[16,17,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},callbackname:{rules:[13,14,15,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},href:{rules:[20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},click:{rules:[20,23,32,33,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},dottedEdgeText:{rules:[20,23,72,74,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},thickEdgeText:{rules:[20,23,69,71,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},edgeText:{rules:[20,23,66,68,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},trapText:{rules:[20,23,75,78,80,82,86,88,89,90,91,92,93,106,108,110,112],inclusive:!1},ellipseText:{rules:[20,23,75,76,77,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},text:{rules:[20,23,75,78,79,80,81,82,85,86,87,88,92,93,105,106,107,108,109,110,111,112,113],inclusive:!1},vertex:{rules:[20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},dir:{rules:[20,23,43,44,45,46,47,48,49,50,51,52,53,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},acc_descr_multiline:{rules:[10,11,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},acc_descr:{rules:[8,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},acc_title:{rules:[6,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},md_string:{rules:[18,19,20,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},string:{rules:[20,21,22,23,75,78,80,82,86,88,92,93,106,108,110,112],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,20,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,40,41,42,54,55,56,57,58,59,60,61,62,63,64,65,66,67,69,70,72,73,75,78,80,82,83,84,86,88,92,93,94,95,96,97,98,99,100,101,102,103,104,106,108,110,112,114,115,116,117],inclusive:!0}}};function se(){this.yy={}}return te.lexer=ee,se.prototype=te,te.Parser=se,new se}();r.parser=r;const n=r;let a,c,o=0,l=(0,i.c)(),h={},A=[],d={},p=[],y={},E={},f=0,k=!0,D=[];const g=t=>i.e.sanitizeText(t,l),b=function(t,e,s){i.m.parseDirective(this,t,e,s)},_=function(t){const e=Object.keys(h);for(const s of e)if(h[s].id===t)return h[s].domId;return t},F=function(t,e,s,u,r,n,a={}){let c,A=t;void 0!==A&&0!==A.trim().length&&(void 0===h[A]&&(h[A]={id:A,labelType:"text",domId:"flowchart-"+A+"-"+o,styles:[],classes:[]}),o++,void 0!==e?(l=(0,i.c)(),c=g(e.text.trim()),h[A].labelType=e.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),h[A].text=c):void 0===h[A].text&&(h[A].text=t),void 0!==s&&(h[A].type=s),null!=u&&u.forEach((function(t){h[A].styles.push(t)})),null!=r&&r.forEach((function(t){h[A].classes.push(t)})),void 0!==n&&(h[A].dir=n),void 0===h[A].props?h[A].props=a:void 0!==a&&Object.assign(h[A].props,a))},T=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};i.l.info("abc78 Got edge...",u);const r=s.text;void 0!==r&&(u.text=g(r.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=r.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),A.push(u)},C=function(t,e,s){let u,r;for(i.l.info("addLink (abc78)",t,e,s),u=0;u/)&&(a="LR"),a.match(/.*v/)&&(a="TB"),"TD"===a&&(a="TB")},x=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==h[s]&&h[s].classes.push(e),void 0!==y[s]&&y[s].classes.push(e)}))},L=function(t,e,s){t.split(",").forEach((function(t){void 0!==h[t]&&(h[t].link=i.u.formatUrl(e,l),h[t].linkTarget=s)})),x(t,"clickable")},I=function(t){if(E.hasOwnProperty(t))return E[t]},R=function(t,e,s){t.split(",").forEach((function(t){!function(t,e,s){let u=_(t);if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;let r=[];if("string"==typeof s){r=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0),(0,u.Ys)(this).classed("hover",!1)}))};D.push(U);const V=function(t="gen-1"){h={},d={},A=[],D=[U],p=[],y={},f=0,E={},k=!0,c=t,(0,i.v)()},G=t=>{c=t||"gen-2"},M=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},K=function(t,e,s){let u=t.text.trim(),r=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let n=[];const{nodeList:a,dir:o}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(n.concat.apply(n,e));if(n=a,"gen-1"===c)for(let t=0;t2e3)return;if(X[j]=e,p[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u=0){const s=z(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},H=function(t){return X[t]},W=function(){j=-1,p.length>0&&z("none",p.length-1)},Q=function(){return p},q=()=>!!k&&(k=!1,!0),Z=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",r=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let n=((t,e)=>{const s=e.length;let u=0;for(let t=0;t{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},J=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},tt=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{J(e,u)||s.push(t.nodes[i])})),{nodes:s}},et={firstGraph:q},st={parseDirective:b,defaultConfig:()=>i.K.flowchart,setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,addVertex:F,lookUpDomId:_,addLink:C,updateLinkInterpolate:S,updateLink:B,addClass:m,setDirection:v,setClass:x,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(E["gen-1"===c?_(t):t]=g(e))}))},getTooltip:I,setClickEvent:R,setLink:L,bindFunctions:N,getDirection:$,getVertices:O,getEdges:P,getClasses:w,clear:V,setGen:G,defaultStyle:M,addSubGraph:K,getDepthFirstPos:H,indexNodes:W,getSubGraphs:Q,destructLink:Z,lex:et,exists:J,makeUniq:tt,setDiagramTitle:i.r,getDiagramTitle:i.t},ut=Object.freeze(Object.defineProperty({__proto__:null,addClass:m,addLink:C,addSingleLink:T,addSubGraph:K,addVertex:F,bindFunctions:N,clear:V,default:st,defaultStyle:M,destructLink:Z,firstGraph:q,getClasses:w,getDepthFirstPos:H,getDirection:$,getEdges:P,getSubGraphs:Q,getTooltip:I,getVertices:O,indexNodes:W,lex:et,lookUpDomId:_,parseDirective:b,setClass:x,setClickEvent:R,setDirection:v,setGen:G,setLink:L,updateLink:B,updateLinkInterpolate:S},Symbol.toStringTag,{value:"Module"}))}}]); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/940-25dfc794.chunk.min.js b/docs/themes/hugo-geekdoc/static/js/940-25dfc794.chunk.min.js new file mode 100644 index 000000000..23c85b61f --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/940-25dfc794.chunk.min.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkgeekdoc=self.webpackChunkgeekdoc||[]).push([[940],{5940:function(t,e,n){n.d(e,{diagram:function(){return M}});var i=n(9339),s=n(7274),r=n(6500),a=n(2281),o=n(7201),c=(n(7484),n(7967),n(7856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,2],n=[1,5],i=[6,9,11,17,18,20,22,23,26,27,28],s=[1,15],r=[1,16],a=[1,17],o=[1,18],c=[1,19],l=[1,23],h=[1,24],d=[1,27],u=[4,6,9,11,17,18,20,22,23,26,27,28],p={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,period_statement:24,event_statement:25,period:26,event:27,open_directive:28,type_directive:29,arg_directive:30,close_directive:31,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",26:"period",27:"event",28:"open_directive",29:"type_directive",30:"arg_directive",31:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[24,1],[25,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 3:case 7:case 8:this.$=[];break;case 4:r[o-1].push(r[o]),this.$=r[o-1];break;case 5:case 6:this.$=r[o];break;case 11:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 12:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 13:case 14:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 15:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 19:i.addTask(r[o],0,""),this.$=r[o];break;case 20:i.addEvent(r[o].substr(2)),this.$=r[o];break;case 21:i.parseDirective("%%{","open_directive");break;case 22:i.parseDirective(r[o],"type_directive");break;case 23:r[o]=r[o].trim().replace(/'/g,'"'),i.parseDirective(r[o],"arg_directive");break;case 24:i.parseDirective("}%%","close_directive","timeline")}},table:[{3:1,4:e,7:3,12:4,28:n},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,28:n},{13:8,29:[1,9]},{29:[2,21]},{6:[1,10],7:22,8:11,9:[1,12],10:13,11:[1,14],12:4,17:s,18:r,20:a,22:o,23:c,24:20,25:21,26:l,27:h,28:n},{1:[2,2]},{14:25,15:[1,26],31:d},t([15,31],[2,22]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:22,10:28,12:4,17:s,18:r,20:a,22:o,23:c,24:20,25:21,26:l,27:h,28:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),{19:[1,29]},{21:[1,30]},t(i,[2,14]),t(i,[2,15]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(i,[2,19]),t(i,[2,20]),{11:[1,31]},{16:32,30:[1,33]},{11:[2,24]},t(i,[2,5]),t(i,[2,12]),t(i,[2,13]),t(u,[2,9]),{14:34,31:d},{31:[2,23]},{11:[1,35]},t(u,[2,10])],defaultActions:{5:[2,21],7:[2,2],27:[2,24],33:[2,23]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=[0],n=[],i=[null],s=[],r=this.table,a="",o=0,c=0,l=s.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(d.yy[u]=this.yy[u]);h.setInput(t,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;s.push(p);var g=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,f,m,_,b,v,k,x,S,w={};;){if(f=e[e.length-1],this.defaultActions[f]?m=this.defaultActions[f]:(null==y&&(S=void 0,"number"!=typeof(S=n.pop()||h.lex()||1)&&(S instanceof Array&&(S=(n=S).pop()),S=this.symbols_[S]||S),y=S),m=r[f]&&r[f][y]),void 0===m||!m.length||!m[0]){var $;for(b in x=[],r[f])this.terminals_[b]&&b>2&&x.push("'"+this.terminals_[b]+"'");$=h.showPosition?"Parse error on line "+(o+1)+":\n"+h.showPosition()+"\nExpecting "+x.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError($,{text:h.match,token:this.terminals_[y]||y,line:h.yylineno,loc:p,expected:x})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+y);switch(m[0]){case 1:e.push(y),i.push(h.yytext),s.push(h.yylloc),e.push(m[1]),y=null,c=h.yyleng,a=h.yytext,o=h.yylineno,p=h.yylloc;break;case 2:if(v=this.productions_[m[1]][1],w.$=i[i.length-v],w._$={first_line:s[s.length-(v||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(v||1)].first_column,last_column:s[s.length-1].last_column},g&&(w._$.range=[s[s.length-(v||1)].range[0],s[s.length-1].range[1]]),void 0!==(_=this.performAction.apply(w,[a,c,o,d.yy,m[1],i,s].concat(l))))return _;v&&(e=e.slice(0,-1*v*2),i=i.slice(0,-1*v),s=s.slice(0,-1*v)),e.push(this.productions_[m[1]][0]),i.push(w.$),s.push(w._$),k=r[e[e.length-2]][e[e.length-1]],e.push(k);break;case 3:return!0}}return!0}},g={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){return this.next()||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),28;case 1:return this.begin("type_directive"),29;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),31;case 4:return 30;case 5:case 6:case 8:case 9:break;case 7:return 11;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 27;case 21:return 26;case 22:return 6;case 23:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23],inclusive:!0}}};function y(){this.yy={}}return p.lexer=g,y.prototype=p,p.Parser=y,new y}());c.parser=c;const l=c;let h="",d=0;const u=[],p=[],g=[],y=()=>i.M,f=(t,e,n)=>{(0,i.D)(globalThis,t,e,n)},m=function(){u.length=0,p.length=0,h="",g.length=0,(0,i.v)()},_=function(t){h=t,u.push(t)},b=function(){return u},v=function(){let t=w(),e=0;for(;!t&&e<100;)t=w(),e++;return p.push(...g),p},k=function(t,e,n){const i={id:d++,section:h,type:h,task:t,score:e||0,events:n?[n]:[]};g.push(i)},x=function(t){g.find((t=>t.id===d-1)).events.push(t)},S=function(t){const e={section:h,type:h,description:t,task:t,classes:[]};p.push(e)},w=function(){let t=!0;for(const[e,n]of g.entries())g[e].processed,t=t&&n.processed;return t},$={clear:m,getCommonDb:y,addSection:_,getSections:b,getTasks:v,addTask:k,addTaskOrg:S,addEvent:x,parseDirective:f},E=Object.freeze(Object.defineProperty({__proto__:null,addEvent:x,addSection:_,addTask:k,addTaskOrg:S,clear:m,default:$,getCommonDb:y,getSections:b,getTasks:v,parseDirective:f},Symbol.toStringTag,{value:"Module"}));function I(t,e){t.each((function(){var t,n=(0,s.Ys)(this),i=n.text().split(/(\s+|
        )/).reverse(),r=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),c=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let s=0;se||"
        "===t)&&(r.pop(),c.text(r.join(" ").trim()),r="
        "===t?[""]:[t],c=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const D=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),c=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(I,e.width).node().getBBox(),l=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=c.height+1.1*l*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)}(a,e,s),e},T=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(I,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},C=function(t,e,n,s,r,a,o,c,l,h,d){var u;for(const c of e){const e={descr:c.task,section:n,number:n,width:150,padding:20,maxHeight:a};i.l.debug("taskNode",e);const p=t.append("g").attr("class","taskWrapper"),g=D(p,e,n,o).height;if(i.l.debug("taskHeight after draw",g),p.attr("transform",`translate(${s}, ${r})`),a=Math.max(a,g),c.events){const e=t.append("g").attr("class","lineWrapper");let i=a;r+=100,i+=L(t,c.events,n,s,r,o),r-=100,e.append("line").attr("x1",s+95).attr("y1",r+a).attr("x2",s+95).attr("y2",r+a+(d?a:h)+l+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}s+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},L=function(t,e,n,s,r,a){let o=0;const c=r;r+=100;for(const c of e){const e={descr:c,section:n,number:n,width:150,padding:20,maxHeight:50};i.l.debug("eventNode",e);const l=t.append("g").attr("class","eventWrapper"),h=D(l,e,n,a).height;o+=h,l.attr("transform",`translate(${s}, ${r})`),r=r+10+h}return r=c,o},M={db:E,renderer:{setConf:()=>{},draw:function(t,e,n,r){var a,o;const c=(0,i.c)(),l=c.leftMargin??50;i.l.debug("timeline",r.db);const h=c.securityLevel;let d;"sandbox"===h&&(d=(0,s.Ys)("#i"+e));const u=("sandbox"===h?(0,s.Ys)(d.nodes()[0].contentDocument.body):(0,s.Ys)("body")).select("#"+e);u.append("g");const p=r.db.getTasks(),g=r.db.getCommonDb().getDiagramTitle();i.l.debug("task",p),u.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z");const y=r.db.getSections();i.l.debug("sections",y);let f=0,m=0,_=0,b=0,v=50+l,k=50;b=50;let x=0,S=!0;y.forEach((function(t){const e=T(u,{number:x,descr:t,section:x,width:150,padding:20,maxHeight:f},c);i.l.debug("sectionHeight before draw",e),f=Math.max(f,e+20)}));let w=0,$=0;i.l.debug("tasks.length",p.length);for(const[t,e]of p.entries()){const n={number:t,descr:e,section:e.section,width:150,padding:20,maxHeight:m},s=T(u,n,c);i.l.debug("taskHeight before draw",s),m=Math.max(m,s+20),w=Math.max(w,e.events.length);let r=0;for(let t=0;t0?y.forEach((t=>{const e=p.filter((e=>e.section===t)),n={number:x,descr:t,section:x,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:f};i.l.debug("sectionNode",n);const s=u.append("g"),r=D(s,n,x,c);i.l.debug("sectionNode output",r),s.attr("transform",`translate(${v}, 50)`),k+=f+50,e.length>0&&C(u,e,x,v,k,m,c,0,$,f,!1),v+=200*Math.max(e.length,1),k=50,x++})):(S=!1,C(u,p,x,v,k,m,c,0,$,f,!0));const E=u.node().getBBox();i.l.debug("bounds",E),g&&u.append("text").text(g).attr("x",E.width/2-l).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),_=S?f+m+150:m+100,u.append("g").attr("class","lineWrapper").append("line").attr("x1",l).attr("y1",_).attr("x2",E.width+3*l).attr("y2",_).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.p)(void 0,u,(null==(a=c.timeline)?void 0:a.padding)??50,(null==(o=c.timeline)?void 0:o.useMaxWidth)??!1)}},parser:l,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let e=0;er.length(this._area)&&(i--,n--)}return e||this},keys:function(t){return this.each((function(t,e,n){n.push(t)}),t||[])},get:function(t,e){var n,i=r.get(this._area,this._in(t));return"function"==typeof e&&(n=e,e=null),null!==i?r.parse(i,n):null!=e?e:i},getAll:function(t){return this.each((function(t,e,n){n[t]=e}),t||{})},transact:function(t,e,n){var r=this.get(t,n),i=e(r);return this.set(t,void 0===i?r:i),this},set:function(t,e,n){var i,s=this.get(t);return null!=s&&!1===n?e:("function"==typeof n&&(i=n,n=void 0),r.set(this._area,this._in(t),r.stringify(e,i),n)||s)},setAll:function(t,e){var n,r;for(var i in t)r=t[i],this.set(i,r,e)!==r&&(n=!0);return n},add:function(t,e,n){var i=this.get(t);if(i instanceof Array)e=i.concat(e);else if(null!==i){var s=typeof i;if(s===typeof e&&"object"===s){for(var o in e)i[o]=e[o];e=i}else e=i+e}return r.set(this._area,this._in(t),r.stringify(e,n)),e},remove:function(t,e){var n=this.get(t,e);return r.remove(this._area,this._in(t)),n},clear:function(){return this._ns?this.each((function(t){r.remove(this._area,this._in(t))}),1):r.clear(this._area),this},clearAll:function(){var t=this._area;for(var e in r.areas)r.areas.hasOwnProperty(e)&&(this._area=r.areas[e],this.clear());return this._area=t,this},_in:function(t){return"string"!=typeof t&&(t=r.stringify(t)),this._ns?this._ns+t:t},_out:function(t){return this._ns?t&&0===t.indexOf(this._ns)?t.substring(this._ns.length):void 0:t}},storage:function(t){return r.inherit(r.storageAPI,{items:{},name:t})},storageAPI:{length:0,has:function(t){return this.items.hasOwnProperty(t)},key:function(t){var e=0;for(var n in this.items)if(this.has(n)&&t===e++)return n},setItem:function(t,e){this.has(t)||this.length++,this.items[t]=e},removeItem:function(t){this.has(t)&&(delete this.items[t],this.length--)},getItem:function(t){return this.has(t)?this.items[t]:null},clear:function(){for(var t in this.items)this.removeItem(t)}}},(i=r.Store("local",function(){try{return localStorage}catch(t){}}())).local=i,i._=r,i.area("session",function(){try{return sessionStorage}catch(t){}}()),i.area("page",r.storage("page")),"function"==typeof n&&void 0!==n.amd?n("store2",[],(function(){return i})):t.exports?t.exports=i:(e.store&&(r.conflict=e.store),e.store=i)},6914:function(t,e,n){"use strict";n.r(e),n.d(e,{COLOR_THEME_AUTO:function(){return s},COLOR_THEME_DARK:function(){return r},COLOR_THEME_LIGHT:function(){return i},THEME:function(){return o},TOGGLE_COLOR_THEMES:function(){return a}});const r="dark",i="light",s="auto",o="hugo-geekdoc",a=[s,r,i]}},e={};function n(r){var i=e[r];if(void 0!==i)return i.exports;var s=e[r]={exports:{}};return t[r].call(s.exports,s,s.exports,n),s.exports}n.d=function(t,e){for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},function(){const t=n(1860),{TOGGLE_COLOR_THEMES:e,THEME:r,COLOR_THEME_AUTO:i}=n(6914);function s(n=!0){if(t.isFake())return;let s=t.namespace(r),o=document.documentElement,a=e.includes(s.get("color-theme"))?s.get("color-theme"):i;o.setAttribute("class","color-toggle-"+a),a===i?o.removeAttribute("color-theme"):o.setAttribute("color-theme",a),n||location.reload()}s(),document.addEventListener("DOMContentLoaded",(n=>{document.getElementById("gdoc-color-theme").onclick=function(){let n=t.namespace(r),o=n.get("color-theme")||i,a=function(t=[],e){let n=t.indexOf(e),r=0;return n{t(document.body)})).catch((t=>console.error(t)))}))},3491:function(t,e,o){t.exports=o.p+"fonts/KaTeX_AMS-Regular.woff"},5537:function(t,e,o){t.exports=o.p+"fonts/KaTeX_AMS-Regular.woff2"},282:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Caligraphic-Bold.woff"},4842:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Caligraphic-Bold.woff2"},1420:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Caligraphic-Regular.woff"},5148:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Caligraphic-Regular.woff2"},3873:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Fraktur-Bold.woff"},7925:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Fraktur-Bold.woff2"},7206:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Fraktur-Regular.woff"},1872:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Fraktur-Regular.woff2"},7888:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Bold.woff"},7823:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Bold.woff2"},6062:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-BoldItalic.woff"},8216:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-BoldItalic.woff2"},1411:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Italic.woff"},4968:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Italic.woff2"},9430:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Regular.woff"},556:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Main-Regular.woff2"},2379:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Math-BoldItalic.woff"},7312:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Math-BoldItalic.woff2"},8212:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Math-Italic.woff"},621:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Math-Italic.woff2"},3958:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Bold.woff"},8516:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Bold.woff2"},208:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Italic.woff"},9471:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Italic.woff2"},9229:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Regular.woff"},4671:function(t,e,o){t.exports=o.p+"fonts/KaTeX_SansSerif-Regular.woff2"},2629:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Script-Regular.woff"},9875:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Script-Regular.woff2"},8493:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size1-Regular.woff"},2986:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size1-Regular.woff2"},8398:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size2-Regular.woff"},4118:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size2-Regular.woff2"},498:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size3-Regular.woff"},8932:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size3-Regular.woff2"},8718:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size4-Regular.woff"},7633:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Size4-Regular.woff2"},2422:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Typewriter-Regular.woff"},4313:function(t,e,o){t.exports=o.p+"fonts/KaTeX_Typewriter-Regular.woff2"}},f={};function i(t){var e=f[t];if(void 0!==e)return e.exports;var o=f[t]={exports:{}};return r[t].call(o.exports,o,o.exports,i),o.exports}i.m=r,e=Object.getPrototypeOf?function(t){return Object.getPrototypeOf(t)}:function(t){return t.__proto__},i.t=function(o,n){if(1&n&&(o=this(o)),8&n)return o;if("object"==typeof o&&o){if(4&n&&o.__esModule)return o;if(16&n&&"function"==typeof o.then)return o}var r=Object.create(null);i.r(r);var f={};t=t||[null,e({}),e([]),e(e)];for(var a=2&n&&o;"object"==typeof a&&!~t.indexOf(a);a=e(a))Object.getOwnPropertyNames(a).forEach((function(t){f[t]=function(){return o[t]}}));return f.default=function(){return o},i.d(r,f),r},i.d=function(t,e){for(var o in e)i.o(e,o)&&!i.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},i.f={},i.e=function(t){return Promise.all(Object.keys(i.f).reduce((function(e,o){return i.f[o](t,e),e}),[]))},i.u=function(t){return"js/"+t+"-341f79d9.chunk.min.js"},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o={},n="geekdoc:",i.l=function(t,e,r,f){if(o[t])o[t].push(e);else{var a,u;if(void 0!==r)for(var c=document.getElementsByTagName("script"),s=0;s-1&&!t;)t=o[n--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),i.p=t+"../"}(),function(){var t={793:0};i.f.j=function(e,o){var n=i.o(t,e)?t[e]:void 0;if(0!==n)if(n)o.push(n[2]);else{var r=new Promise((function(o,r){n=t[e]=[o,r]}));o.push(n[2]=r);var f=i.p+i.u(e),a=new Error;i.l(f,(function(o){if(i.o(t,e)&&(0!==(n=t[e])&&(t[e]=void 0),n)){var r=o&&("load"===o.type?"missing":o.type),f=o&&o.target&&o.target.src;a.message="Loading chunk "+e+" failed.\n("+r+": "+f+")",a.name="ChunkLoadError",a.type=r,a.request=f,n[1](a)}}),"chunk-"+e,e)}};var e=function(e,o){var n,r,f=o[0],a=o[1],u=o[2],c=0;if(f.some((function(e){return 0!==t[e]}))){for(n in a)i.o(a,n)&&(i.m[n]=a[n]);u&&u(i)}for(e&&e(o);c1&&void 0!==arguments[1]?arguments[1]:{container:document.body},n="";return"string"==typeof t?n=f(t,e):t instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==t?void 0:t.type)?n=f(t.value,e):(n=a()(t),l("copy")),n};function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}function y(t){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},y(t)}function h(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===y(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=i()(t,"click",(function(t){return e.onClick(t)}))}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget,n=this.action(e)||"copy",o=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.action,n=void 0===e?"copy":e,o=t.container,r=t.target,c=t.text;if("copy"!==n&&"cut"!==n)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==r){if(!r||"object"!==p(r)||1!==r.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===n&&r.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===n&&(r.hasAttribute("readonly")||r.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return c?d(c,{container:o}):r?"cut"===n?s(r):d(r,{container:o}):void 0}({action:n,container:this.container,target:this.target(e),text:this.text(e)});this.emit(o?"success":"error",{action:n,text:o,trigger:e,clearSelection:function(){e&&e.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(t){return m("action",t)}},{key:"defaultTarget",value:function(t){var e=m("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return m("text",t)}},{key:"destroy",value:function(){this.listener.destroy()}}],o=[{key:"copy",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{container:document.body};return d(t,e)}},{key:"cut",value:function(t){return s(t)}},{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach((function(t){n=n&&!!document.queryCommandSupported(t)})),n}}],n&&h(e.prototype,n),o&&h(e,o),a}(r()),S=b},828:function(t){if("undefined"!=typeof Element&&!Element.prototype.matches){var e=Element.prototype;e.matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector}t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var o=n(828);function r(t,e,n,o,r){var i=c.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}function c(t,e,n,r){return function(n){n.delegateTarget=o(n.target,e),n.delegateTarget&&r.call(t,n)}}t.exports=function(t,e,n,o,c){return"function"==typeof t.addEventListener?r.apply(null,arguments):"function"==typeof n?r.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,(function(t){return r(t,e,n,o,c)})))}},879:function(t,e){e.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},e.nodeList=function(t){var n=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in t&&(0===t.length||e.node(t[0]))},e.string=function(t){return"string"==typeof t||t instanceof String},e.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var o=n(879),r=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!o.string(e))throw new TypeError("Second argument must be a String");if(!o.fn(n))throw new TypeError("Third argument must be a Function");if(o.node(t))return function(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}(t,e,n);if(o.nodeList(t))return function(t,e,n){return Array.prototype.forEach.call(t,(function(t){t.addEventListener(e,n)})),{destroy:function(){Array.prototype.forEach.call(t,(function(t){t.removeEventListener(e,n)}))}}}(t,e,n);if(o.string(t))return function(t,e,n){return r(document.body,t,e,n)}(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}},817:function(t){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o',e.setAttribute("data-clipboard-text",n),e.setAttribute("data-copy-feedback","Copied!"),e.setAttribute("role","button"),e.setAttribute("aria-label","Copy"),t.classList.add("gdoc-post__codecontainer"),t.insertBefore(e,t.firstChild)}}n.r(e),n.d(e,{createCopyButton:function(){return o}})}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.d=function(t,e){for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},function(){const{createCopyButton:t}=n(3243),e=n(2152);document.addEventListener("DOMContentLoaded",(function(n){new e(".clip").on("success",(function(t){const e=t.trigger;e.hasAttribute("data-copy-feedback")&&(e.classList.add("gdoc-post__codecopy--success","gdoc-post__codecopy--out"),e.querySelector(".gdoc-icon.copy").classList.add("hidden"),e.querySelector(".gdoc-icon.check").classList.remove("hidden"),setTimeout((function(){e.classList.remove("gdoc-post__codecopy--success","gdoc-post__codecopy--out"),e.querySelector(".gdoc-icon.copy").classList.remove("hidden"),e.querySelector(".gdoc-icon.check").classList.add("hidden")}),3e3)),t.clearSelection()})),document.querySelectorAll(".highlight").forEach((e=>t(e)))}))}()}(); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/main-924a1933.bundle.min.js.LICENSE.txt b/docs/themes/hugo-geekdoc/static/js/main-924a1933.bundle.min.js.LICENSE.txt new file mode 100644 index 000000000..5161813c4 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/main-924a1933.bundle.min.js.LICENSE.txt @@ -0,0 +1,6 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ diff --git a/docs/themes/hugo-geekdoc/static/js/mermaid-d305d450.bundle.min.js b/docs/themes/hugo-geekdoc/static/js/mermaid-d305d450.bundle.min.js new file mode 100644 index 000000000..5b10c0e1e --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/mermaid-d305d450.bundle.min.js @@ -0,0 +1 @@ +!function(){var t,e,n={1860:function(t){!function(e,n){var r={version:"2.14.2",areas:{},apis:{},nsdelim:".",inherit:function(t,e){for(var n in t)e.hasOwnProperty(n)||Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n));return e},stringify:function(t,e){return void 0===t||"function"==typeof t?t+"":JSON.stringify(t,e||r.replace)},parse:function(t,e){try{return JSON.parse(t,e||r.revive)}catch(e){return t}},fn:function(t,e){for(var n in r.storeAPI[t]=e,r.apis)r.apis[n][t]=e},get:function(t,e){return t.getItem(e)},set:function(t,e,n){t.setItem(e,n)},remove:function(t,e){t.removeItem(e)},key:function(t,e){return t.key(e)},length:function(t){return t.length},clear:function(t){t.clear()},Store:function(t,e,n){var i=r.inherit(r.storeAPI,(function(t,e,n){return 0===arguments.length?i.getAll():"function"==typeof e?i.transact(t,e,n):void 0!==e?i.set(t,e,n):"string"==typeof t||"number"==typeof t?i.get(t):"function"==typeof t?i.each(t):t?i.setAll(t,e):i.clear()}));i._id=t;try{var a="__store2_test";e.setItem(a,"ok"),i._area=e,e.removeItem(a)}catch(t){i._area=r.storage("fake")}return i._ns=n||"",r.areas[t]||(r.areas[t]=i._area),r.apis[i._ns+i._id]||(r.apis[i._ns+i._id]=i),i},storeAPI:{area:function(t,e){var n=this[t];return n&&n.area||(n=r.Store(t,e,this._ns),this[t]||(this[t]=n)),n},namespace:function(t,e,n){if(n=n||this._delim||r.nsdelim,!t)return this._ns?this._ns.substring(0,this._ns.length-n.length):"";var i=t,a=this[i];if(!(a&&a.namespace||((a=r.Store(this._id,this._area,this._ns+i+n))._delim=n,this[i]||(this[i]=a),e)))for(var o in r.areas)a.area(o,r.areas[o]);return a},isFake:function(t){return t?(this._real=this._area,this._area=r.storage("fake")):!1===t&&(this._area=this._real||this._area),"fake"===this._area.name},toString:function(){return"store"+(this._ns?"."+this.namespace():"")+"["+this._id+"]"},has:function(t){return this._area.has?this._area.has(this._in(t)):!!(this._in(t)in this._area)},size:function(){return this.keys().length},each:function(t,e){for(var n=0,i=r.length(this._area);nr.length(this._area)&&(i--,n--)}return e||this},keys:function(t){return this.each((function(t,e,n){n.push(t)}),t||[])},get:function(t,e){var n,i=r.get(this._area,this._in(t));return"function"==typeof e&&(n=e,e=null),null!==i?r.parse(i,n):null!=e?e:i},getAll:function(t){return this.each((function(t,e,n){n[t]=e}),t||{})},transact:function(t,e,n){var r=this.get(t,n),i=e(r);return this.set(t,void 0===i?r:i),this},set:function(t,e,n){var i,a=this.get(t);return null!=a&&!1===n?e:("function"==typeof n&&(i=n,n=void 0),r.set(this._area,this._in(t),r.stringify(e,i),n)||a)},setAll:function(t,e){var n,r;for(var i in t)r=t[i],this.set(i,r,e)!==r&&(n=!0);return n},add:function(t,e,n){var i=this.get(t);if(i instanceof Array)e=i.concat(e);else if(null!==i){var a=typeof i;if(a===typeof e&&"object"===a){for(var o in e)i[o]=e[o];e=i}else e=i+e}return r.set(this._area,this._in(t),r.stringify(e,n)),e},remove:function(t,e){var n=this.get(t,e);return r.remove(this._area,this._in(t)),n},clear:function(){return this._ns?this.each((function(t){r.remove(this._area,this._in(t))}),1):r.clear(this._area),this},clearAll:function(){var t=this._area;for(var e in r.areas)r.areas.hasOwnProperty(e)&&(this._area=r.areas[e],this.clear());return this._area=t,this},_in:function(t){return"string"!=typeof t&&(t=r.stringify(t)),this._ns?this._ns+t:t},_out:function(t){return this._ns?t&&0===t.indexOf(this._ns)?t.substring(this._ns.length):void 0:t}},storage:function(t){return r.inherit(r.storageAPI,{items:{},name:t})},storageAPI:{length:0,has:function(t){return this.items.hasOwnProperty(t)},key:function(t){var e=0;for(var n in this.items)if(this.has(n)&&t===e++)return n},setItem:function(t,e){this.has(t)||this.length++,this.items[t]=e},removeItem:function(t){this.has(t)&&(delete this.items[t],this.length--)},getItem:function(t){return this.has(t)?this.items[t]:null},clear:function(){for(var t in this.items)this.removeItem(t)}}},i=r.Store("local",function(){try{return localStorage}catch(t){}}());i.local=i,i._=r,i.area("session",function(){try{return sessionStorage}catch(t){}}()),i.area("page",r.storage("page")),"function"==typeof n&&void 0!==n.amd?n("store2",[],(function(){return i})):t.exports?t.exports=i:(e.store&&(r.conflict=e.store),e.store=i)}(this,this&&this.define)},6914:function(t,e,n){"use strict";n.r(e),n.d(e,{COLOR_THEME_AUTO:function(){return a},COLOR_THEME_DARK:function(){return r},COLOR_THEME_LIGHT:function(){return i},THEME:function(){return o},TOGGLE_COLOR_THEMES:function(){return s}});const r="dark",i="light",a="auto",o="hugo-geekdoc",s=[a,r,i]}},r={};function i(t){var e=r[t];if(void 0!==e)return e.exports;var a=r[t]={exports:{}};return n[t].call(a.exports,a,a.exports,i),a.exports}i.m=n,i.d=function(t,e){for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.f={},i.e=function(t){return Promise.all(Object.keys(i.f).reduce((function(e,n){return i.f[n](t,e),e}),[]))},i.u=function(t){return"js/"+t+"-"+{19:"86f47ecd",76:"732e78f1",81:"4e653aac",118:"f1de6a20",361:"f7cd601a",423:"897d7f17",430:"cc171d93",433:"f2655a46",438:"760c9ed3",476:"86e5cf96",506:"6950d52c",519:"8d0cec7f",535:"dcead599",545:"8e970b03",546:"560b35c2",579:"9222afff",626:"1706197a",637:"86fbbecd",639:"88c6538a",642:"12e7dea2",662:"17acb8f4",728:"5df4a5e5",729:"32b017b3",747:"b55f0f97",771:"942a62df",773:"8f0c4fb8",813:"0d3c16f5",940:"25dfc794"}[t]+".chunk.min.js"},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},t={},e="geekdoc:",i.l=function(n,r,a,o){if(t[n])t[n].push(r);else{var s,c;if(void 0!==a)for(var u=document.getElementsByTagName("script"),f=0;f-1&&!t;)t=n[r--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),i.p=t+"../"}(),function(){var t={552:0};i.f.j=function(e,n){var r=i.o(t,e)?t[e]:void 0;if(0!==r)if(r)n.push(r[2]);else{var a=new Promise((function(n,i){r=t[e]=[n,i]}));n.push(r[2]=a);var o=i.p+i.u(e),s=new Error;i.l(o,(function(n){if(i.o(t,e)&&(0!==(r=t[e])&&(t[e]=void 0),r)){var a=n&&("load"===n.type?"missing":n.type),o=n&&n.target&&n.target.src;s.message="Loading chunk "+e+" failed.\n("+a+": "+o+")",s.name="ChunkLoadError",s.type=a,s.request=o,r[1](s)}}),"chunk-"+e,e)}};var e=function(e,n){var r,a,o=n[0],s=n[1],c=n[2],u=0;if(o.some((function(e){return 0!==t[e]}))){for(r in s)i.o(s,r)&&(i.m[r]=s[r]);c&&c(i)}for(e&&e(n);u{t.initialize({flowchart:{useMaxWidth:!0},theme:u,themeVariables:{darkMode:c}})})).catch((t=>console.error(t)))}))}()}(); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js b/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js new file mode 100644 index 000000000..43fd84df9 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js @@ -0,0 +1,2 @@ +/*! For license information please see search-9719be99.bundle.min.js.LICENSE.txt */ +!function(){var t={3129:function(){!function(t){"use strict";var e;function n(t){return void 0===t||t}function r(t){const e=Array(t);for(let n=0;n=r))));l++);if(n)return i?A(c,r,0):void(e[e.length]=c)}return!n&&c}function A(t,e,n){return t=1===t.length?t[0]:[].concat.apply([],t),n||t.length>e?t.slice(n,n+e):t}function z(t,e,n,r){return t=n?(t=t[(r=r&&e>n)?e:n])&&t[r?n:e]:t[e]}function I(t,e,n,r,o){let i=0;if(t.constructor===Array)if(o)-1!==(e=t.indexOf(e))?1e||n)&&(o=o.slice(n,n+e)),r&&(o=F.call(this,o)),{tag:t,result:o}}function F(t){const e=Array(t.length);for(let n,r=0;r=this.m&&(l||!d[v])){var a=j(h,r,p),s="";switch(this.C){case"full":if(2a;c--)if(c-a>=this.m){var u=j(h,r,p,i,a);L(this,d,s=v.substring(a,c),u,t,n)}break}case"reverse":if(1=this.m&&L(this,d,s,j(h,r,p,i,c),t,n);s=""}case"forward":if(1=this.m&&L(this,d,s,a,t,n);break}default:if(this.F&&(a=Math.min(a/this.F(e,v,p)|0,h-1)),L(this,d,v,a,t,n),l&&1=this.m&&!i[v]){i[v]=1;const e=this.h&&v>a;L(this,f,e?a:v,j(s+(r/2>s?0:1),r,p,c-1,u-1),t,n,e?v:a)}}}}this.D||(this.register[t]=1)}}return this},e.search=function(t,e,n){n||(!e&&s(t)?t=(n=t).query:s(e)&&(n=e));let r,a,c,u=[],f=0;if(n){t=n.query||t,e=n.limit,f=n.offset||0;var d=n.context;a=n.suggest}if(t&&(r=(t=this.encode(""+t)).length,1=this.m&&!n[e]){if(!(this.s||a||this.map[e]))return u;l[i++]=e,n[e]=1}r=(t=l).length}if(!r)return u;e||(e=100),n=0,(d=this.depth&&1o?0:o+e),(n=n>o?o:n)<0&&(n+=o),o=e>n?0:n-e>>>0,e>>>=0;for(var i=Array(o);++r=o?t:r(t,e,n)}},4429:function(t,e,n){var r=n(5639)["__core-js_shared__"];t.exports=r},5189:function(t,e,n){var r=n(4174),o=n(1119),i=n(1243),a=n(1469);t.exports=function(t,e){return function(n,s){var c=a(n)?r:o,u=e?e():{};return c(n,t,i(s,2),u)}}},9291:function(t,e,n){var r=n(8612);t.exports=function(t,e){return function(n,o){if(null==n)return n;if(!r(n))return t(n,o);for(var i=n.length,a=e?i:-1,s=Object(n);(e?a--:++af))return!1;var l=c.get(t),h=c.get(e);if(l&&h)return l==e&&h==t;var p=-1,v=!0,y=2&n?new r:void 0;for(c.set(t,e),c.set(e,t);++p-1&&t%1==0&&t-1}},4705:function(t,e,n){var r=n(8470);t.exports=function(t,e){var n=this.__data__,o=r(n,t);return o<0?(++this.size,n.push([t,e])):n[o][1]=e,this}},4785:function(t,e,n){var r=n(1989),o=n(8407),i=n(7071);t.exports=function(){this.size=0,this.__data__={hash:new r,map:new(i||o),string:new r}}},1285:function(t,e,n){var r=n(5050);t.exports=function(t){var e=r(this,t).delete(t);return this.size-=e?1:0,e}},6e3:function(t,e,n){var r=n(5050);t.exports=function(t){return r(this,t).get(t)}},9916:function(t,e,n){var r=n(5050);t.exports=function(t){return r(this,t).has(t)}},5265:function(t,e,n){var r=n(5050);t.exports=function(t,e){var n=r(this,t),o=n.size;return n.set(t,e),this.size+=n.size==o?0:1,this}},8776:function(t){t.exports=function(t){var e=-1,n=Array(t.size);return t.forEach((function(t,r){n[++e]=[r,t]})),n}},2634:function(t){t.exports=function(t,e){return function(n){return null!=n&&n[t]===e&&(void 0!==e||t in Object(n))}}},4523:function(t,e,n){var r=n(8306);t.exports=function(t){var e=r(t,(function(t){return 500===n.size&&n.clear(),t})),n=e.cache;return e}},4536:function(t,e,n){var r=n(852)(Object,"create");t.exports=r},6916:function(t,e,n){var r=n(5569)(Object.keys,Object);t.exports=r},1167:function(t,e,n){t=n.nmd(t);var r=n(1957),o=e&&!e.nodeType&&e,i=o&&t&&!t.nodeType&&t,a=i&&i.exports===o&&r.process,s=function(){try{return i&&i.require&&i.require("util").types||a&&a.binding&&a.binding("util")}catch(t){}}();t.exports=s},2333:function(t){var e=Object.prototype.toString;t.exports=function(t){return e.call(t)}},5569:function(t){t.exports=function(t,e){return function(n){return t(e(n))}}},5639:function(t,e,n){var r=n(1957),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();t.exports=i},619:function(t){t.exports=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this}},2385:function(t){t.exports=function(t){return this.__data__.has(t)}},1814:function(t){t.exports=function(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[++e]=t})),n}},7465:function(t,e,n){var r=n(8407);t.exports=function(){this.__data__=new r,this.size=0}},3779:function(t){t.exports=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n}},7599:function(t){t.exports=function(t){return this.__data__.get(t)}},4758:function(t){t.exports=function(t){return this.__data__.has(t)}},4309:function(t,e,n){var r=n(8407),o=n(7071),i=n(3369);t.exports=function(t,e){var n=this.__data__;if(n instanceof r){var a=n.__data__;if(!o||a.length<199)return a.push([t,e]),this.size=++n.size,this;n=this.__data__=new i(a)}return n.set(t,e),this.size=n.size,this}},8016:function(t,e,n){var r=n(8983),o=n(2689),i=n(1903);t.exports=function(t){return o(t)?i(t):r(t)}},3140:function(t,e,n){var r=n(4286),o=n(2689),i=n(676);t.exports=function(t){return o(t)?i(t):r(t)}},5514:function(t,e,n){var r=n(4523),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,i=/\\(\\)?/g,a=r((function(t){var e=[];return 46===t.charCodeAt(0)&&e.push(""),t.replace(o,(function(t,n,r,o){e.push(r?o.replace(i,"$1"):n||t)})),e}));t.exports=a},327:function(t,e,n){var r=n(3448);t.exports=function(t){if("string"==typeof t||r(t))return t;var e=t+"";return"0"==e&&1/t==-1/0?"-0":e}},346:function(t){var e=Function.prototype.toString;t.exports=function(t){if(null!=t){try{return e.call(t)}catch(t){}try{return t+""}catch(t){}}return""}},7990:function(t){var e=/\s/;t.exports=function(t){for(var n=t.length;n--&&e.test(t.charAt(n)););return n}},1903:function(t){var e="\\ud800-\\udfff",n="["+e+"]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",o="\\ud83c[\\udffb-\\udfff]",i="[^"+e+"]",a="(?:\\ud83c[\\udde6-\\uddff]){2}",s="[\\ud800-\\udbff][\\udc00-\\udfff]",c="(?:"+r+"|"+o+")?",u="[\\ufe0e\\ufe0f]?",f=u+c+"(?:\\u200d(?:"+[i,a,s].join("|")+")"+u+c+")*",d="(?:"+[i+r+"?",r,a,s,n].join("|")+")",l=RegExp(o+"(?="+o+")|"+d+f,"g");t.exports=function(t){for(var e=l.lastIndex=0;l.test(t);)++e;return e}},676:function(t){var e="\\ud800-\\udfff",n="["+e+"]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",o="\\ud83c[\\udffb-\\udfff]",i="[^"+e+"]",a="(?:\\ud83c[\\udde6-\\uddff]){2}",s="[\\ud800-\\udbff][\\udc00-\\udfff]",c="(?:"+r+"|"+o+")?",u="[\\ufe0e\\ufe0f]?",f=u+c+"(?:\\u200d(?:"+[i,a,s].join("|")+")"+u+c+")*",d="(?:"+[i+r+"?",r,a,s,n].join("|")+")",l=RegExp(o+"(?="+o+")|"+d+f,"g");t.exports=function(t){return t.match(l)||[]}},7813:function(t){t.exports=function(t,e){return t===e||t!=t&&e!=e}},7361:function(t,e,n){var r=n(7786);t.exports=function(t,e,n){var o=null==t?void 0:r(t,e);return void 0===o?n:o}},7739:function(t,e,n){var r=n(9465),o=n(5189),i=Object.prototype.hasOwnProperty,a=o((function(t,e,n){i.call(t,n)?t[n].push(e):r(t,n,[e])}));t.exports=a},9095:function(t,e,n){var r=n(13),o=n(222);t.exports=function(t,e){return null!=t&&o(t,e,r)}},6557:function(t){t.exports=function(t){return t}},5694:function(t,e,n){var r=n(9454),o=n(7005),i=Object.prototype,a=i.hasOwnProperty,s=i.propertyIsEnumerable,c=r(function(){return arguments}())?r:function(t){return o(t)&&a.call(t,"callee")&&!s.call(t,"callee")};t.exports=c},1469:function(t){var e=Array.isArray;t.exports=e},8612:function(t,e,n){var r=n(3560),o=n(1780);t.exports=function(t){return null!=t&&o(t.length)&&!r(t)}},4144:function(t,e,n){t=n.nmd(t);var r=n(5639),o=n(5062),i=e&&!e.nodeType&&e,a=i&&t&&!t.nodeType&&t,s=a&&a.exports===i?r.Buffer:void 0,c=(s?s.isBuffer:void 0)||o;t.exports=c},3560:function(t,e,n){var r=n(4239),o=n(3218);t.exports=function(t){if(!o(t))return!1;var e=r(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},1780:function(t){t.exports=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},3218:function(t){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},7005:function(t){t.exports=function(t){return null!=t&&"object"==typeof t}},6347:function(t,e,n){var r=n(3933),o=n(7518),i=n(1167),a=i&&i.isRegExp,s=a?o(a):r;t.exports=s},3448:function(t,e,n){var r=n(4239),o=n(7005);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==r(t)}},6719:function(t,e,n){var r=n(8749),o=n(7518),i=n(1167),a=i&&i.isTypedArray,s=a?o(a):r;t.exports=s},3674:function(t,e,n){var r=n(4636),o=n(280),i=n(8612);t.exports=function(t){return i(t)?r(t):o(t)}},8306:function(t,e,n){var r=n(3369);function o(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=e?e.apply(this,r):r[0],i=n.cache;if(i.has(o))return i.get(o);var a=t.apply(this,r);return n.cache=i.set(o,a)||i,a};return n.cache=new(o.Cache||r),n}o.Cache=r,t.exports=o},9601:function(t,e,n){var r=n(371),o=n(9152),i=n(5403),a=n(327);t.exports=function(t){return i(t)?r(a(t)):o(t)}},479:function(t){t.exports=function(){return[]}},5062:function(t){t.exports=function(){return!1}},8601:function(t,e,n){var r=n(4841);t.exports=function(t){return t?Infinity===(t=r(t))||t===-1/0?17976931348623157e292*(t<0?-1:1):t==t?t:0:0===t?t:0}},554:function(t,e,n){var r=n(8601);t.exports=function(t){var e=r(t),n=e%1;return e==e?n?e-n:e:0}},4841:function(t,e,n){var r=n(7561),o=n(3218),i=n(3448),a=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;t.exports=function(t){if("number"==typeof t)return t;if(i(t))return NaN;if(o(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=o(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=r(t);var n=s.test(t);return n||c.test(t)?u(t.slice(2),n?2:8):a.test(t)?NaN:+t}},9833:function(t,e,n){var r=n(531);t.exports=function(t){return null==t?"":r(t)}},9138:function(t,e,n){var r=n(531),o=n(180),i=n(2689),a=n(3218),s=n(6347),c=n(8016),u=n(3140),f=n(554),d=n(9833),l=/\w*$/;t.exports=function(t,e){var n=30,h="...";if(a(e)){var p="separator"in e?e.separator:p;n="length"in e?f(e.length):n,h="omission"in e?r(e.omission):h}var v=(t=d(t)).length;if(i(t)){var y=u(t);v=y.length}if(n>=v)return t;var m=n-c(h);if(m<1)return h;var g=y?o(y,0,m).join(""):t.slice(0,m);if(void 0===p)return g+h;if(y&&(m+=g.length-m),s(p)){if(t.slice(m).search(p)){var x,$=g;for(p.global||(p=RegExp(p.source,d(l.exec(p))+"g")),p.lastIndex=0;x=p.exec($);)var b=x.index;g=g.slice(0,void 0===b?m:b)}}else if(t.indexOf(r(p),m)!=m){var _=g.lastIndexOf(p);_>-1&&(g=g.slice(0,_))}return g+h}},9707:function(t,e,n){"use strict";function r(t,e){const n=typeof t;if(n!==typeof e)return!1;if(Array.isArray(t)){if(!Array.isArray(e))return!1;const n=t.length;if(n!==e.length)return!1;for(let o=0;o1?e[i.href]=t:(i.hash="",""===r?n=i:d(t,e,n))}}else if(!0!==t&&!1!==t)return e;const i=n.href+(r?"#"+r:"");if(void 0!==e[i])throw new Error(`Duplicate schema URI "${i}".`);if(e[i]=t,!0===t||!1===t)return e;if(void 0===t.__absolute_uri__&&Object.defineProperty(t,"__absolute_uri__",{enumerable:!1,value:i}),t.$ref&&void 0===t.__absolute_ref__){const e=new URL(t.$ref,n.href);e.hash=e.hash,Object.defineProperty(t,"__absolute_ref__",{enumerable:!1,value:e.href})}if(t.$recursiveRef&&void 0===t.__absolute_recursive_ref__){const e=new URL(t.$recursiveRef,n.href);e.hash=e.hash,Object.defineProperty(t,"__absolute_recursive_ref__",{enumerable:!1,value:e.href})}t.$anchor&&(e[new URL("#"+t.$anchor,n.href).href]=t);for(let i in t){if(u[i])continue;const a=`${r}/${o(i)}`,f=t[i];if(Array.isArray(f)){if(s[i]){const t=f.length;for(let r=0;rt.length>1&&t.length<80&&(/^P\d+([.,]\d+)?W$/.test(t)||/^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(t)&&/^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(t)),uri:function(t){return b.test(t)&&_.test(t)},"uri-reference":v(/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i),"uri-template":v(/^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i),url:v(/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu),email:t=>{if('"'===t[0])return!1;const[e,n,...r]=t.split("@");return!(!e||!n||0!==r.length||e.length>64||n.length>253)&&"."!==e[0]&&!e.endsWith(".")&&!e.includes("..")&&!(!/^[a-z0-9.-]+$/i.test(n)||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(e))&&n.split(".").every((t=>/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(t)))},hostname:v(/^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i),ipv4:v(/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/),ipv6:v(/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i),regex:function(t){if(w.test(t))return!1;try{return new RegExp(t),!0}catch(t){return!1}},uuid:v(/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i),"json-pointer":v(/^(?:\/(?:[^~/]|~0|~1)*)*$/),"json-pointer-uri-fragment":v(/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i),"relative-json-pointer":v(/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/)},m={...y,date:v(/^\d\d\d\d-[0-1]\d-[0-3]\d$/),time:v(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i),"date-time":v(/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i),"uri-reference":v(/^(?:(?:[a-z][a-z0-9+-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i)};function g(t){const e=t.match(l);if(!e)return!1;const n=+e[1],r=+e[2],o=+e[3];return r>=1&&r<=12&&o>=1&&o<=(2==r&&function(t){return t%4==0&&(t%100!=0||t%400==0)}(n)?29:h[r])}function x(t,e){const n=e.match(p);if(!n)return!1;const r=+n[1],o=+n[2],i=+n[3],a=!!n[5];return(r<=23&&o<=59&&i<=59||23==r&&59==o&&60==i)&&(!t||a)}const $=/t|\s/i,b=/\/|:/,_=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,w=/[^\\]\\Z/;function k(t){let e,n=0,r=t.length,o=0;for(;o=55296&&e<=56319&&or(t,e)))||ct.push({instanceLocation:c,keyword:"enum",keywordLocation:`${u}/enum`,error:`Instance does not match any of ${JSON.stringify($)}.`}):$.some((e=>t===e))||ct.push({instanceLocation:c,keyword:"enum",keywordLocation:`${u}/enum`,error:`Instance does not match any of ${JSON.stringify($)}.`})),void 0!==_){const e=`${u}/not`;j(t,_,n,i,a,s,c,e).valid&&ct.push({instanceLocation:c,keyword:"not",keywordLocation:e,error:'Instance matched "not" schema.'})}let ut=[];if(void 0!==w){const e=`${u}/anyOf`,r=ct.length;let o=!1;for(let r=0;r{const u=Object.create(f),d=j(t,r,n,i,a,!0===y?s:null,c,`${e}/${o}`,u);return ct.push(...d.errors),d.valid&&ut.push(u),d.valid})).length;1===o?ct.length=r:ct.splice(r,0,{instanceLocation:c,keyword:"oneOf",keywordLocation:e,error:`Instance does not match exactly one subschema (${o} matches).`})}if("object"!==h&&"array"!==h||Object.assign(f,...ut),void 0!==A){const e=`${u}/if`;if(j(t,A,n,i,a,s,c,e,f).valid){if(void 0!==z){const r=j(t,z,n,i,a,s,c,`${u}/then`,f);r.valid||ct.push({instanceLocation:c,keyword:"if",keywordLocation:e,error:'Instance does not match "then" schema.'},...r.errors)}}else if(void 0!==I){const r=j(t,I,n,i,a,s,c,`${u}/else`,f);r.valid||ct.push({instanceLocation:c,keyword:"if",keywordLocation:e,error:'Instance does not match "else" schema.'},...r.errors)}}if("object"===h){if(void 0!==b)for(const e of b)e in t||ct.push({instanceLocation:c,keyword:"required",keywordLocation:`${u}/required`,error:`Instance does not have required property "${e}".`});const e=Object.keys(t);if(void 0!==M&&e.lengthF&&ct.push({instanceLocation:c,keyword:"maxProperties",keywordLocation:`${u}/maxProperties`,error:`Instance does not have at least ${F} properties.`}),void 0!==D){const e=`${u}/propertyNames`;for(const r in t){const t=`${c}/${o(r)}`,u=j(r,D,n,i,a,s,t,e);u.valid||ct.push({instanceLocation:c,keyword:"propertyNames",keywordLocation:e,error:`Property name "${r}" does not match schema.`},...u.errors)}}if(void 0!==q){const e=`${u}/dependantRequired`;for(const n in q)if(n in t){const r=q[n];for(const o of r)o in t||ct.push({instanceLocation:c,keyword:"dependentRequired",keywordLocation:e,error:`Instance has "${n}" but does not have "${o}".`})}}if(void 0!==N)for(const e in N){const r=`${u}/dependentSchemas`;if(e in t){const u=j(t,N[e],n,i,a,s,c,`${r}/${o(e)}`,f);u.valid||ct.push({instanceLocation:c,keyword:"dependentSchemas",keywordLocation:r,error:`Instance has "${e}" but does not match dependant schema.`},...u.errors)}}if(void 0!==T){const e=`${u}/dependencies`;for(const r in T)if(r in t){const u=T[r];if(Array.isArray(u))for(const n of u)n in t||ct.push({instanceLocation:c,keyword:"dependencies",keywordLocation:e,error:`Instance has "${r}" but does not have "${n}".`});else{const f=j(t,u,n,i,a,s,c,`${e}/${o(r)}`);f.valid||ct.push({instanceLocation:c,keyword:"dependencies",keywordLocation:e,error:`Instance has "${r}" but does not match dependant schema.`},...f.errors)}}}const r=Object.create(null);let d=!1;if(void 0!==E){const e=`${u}/properties`;for(const u in E){if(!(u in t))continue;const l=`${c}/${o(u)}`,h=j(t[u],E[u],n,i,a,s,l,`${e}/${o(u)}`);if(h.valid)f[u]=r[u]=!0;else if(d=a,ct.push({instanceLocation:c,keyword:"properties",keywordLocation:e,error:`Property "${u}" does not match schema.`},...h.errors),d)break}}if(!d&&void 0!==S){const e=`${u}/patternProperties`;for(const u in S){const l=new RegExp(u),h=S[u];for(const p in t){if(!l.test(p))continue;const v=`${c}/${o(p)}`,y=j(t[p],h,n,i,a,s,v,`${e}/${o(u)}`);y.valid?f[p]=r[p]=!0:(d=a,ct.push({instanceLocation:c,keyword:"patternProperties",keywordLocation:e,error:`Property "${p}" matches pattern "${u}" but does not match associated schema.`},...y.errors))}}}if(d||void 0===C){if(!d&&void 0!==R){const e=`${u}/unevaluatedProperties`;for(const r in t)if(!f[r]){const u=`${c}/${o(r)}`,d=j(t[r],R,n,i,a,s,u,e);d.valid?f[r]=!0:ct.push({instanceLocation:c,keyword:"unevaluatedProperties",keywordLocation:e,error:`Property "${r}" does not match unevaluated properties schema.`},...d.errors)}}}else{const e=`${u}/additionalProperties`;for(const u in t){if(r[u])continue;const l=`${c}/${o(u)}`,h=j(t[u],C,n,i,a,s,l,e);h.valid?f[u]=!0:(d=a,ct.push({instanceLocation:c,keyword:"additionalProperties",keywordLocation:e,error:`Property "${u}" does not match additional properties schema.`},...h.errors))}}}else if("array"===h){void 0!==Y&&t.length>Y&&ct.push({instanceLocation:c,keyword:"maxItems",keywordLocation:`${u}/maxItems`,error:`Array has too many items (${t.length} > ${Y}).`}),void 0!==K&&t.length=(J||0)&&(ct.length=o),void 0===J&&void 0===W&&0===d?ct.splice(o,0,{instanceLocation:c,keyword:"contains",keywordLocation:r,error:"Array does not contain item matching schema."}):void 0!==J&&dW&&ct.push({instanceLocation:c,keyword:"maxContains",keywordLocation:`${u}/maxContains`,error:`Array may contain at most ${W} items matching schema. ${d} items were found.`})}if(!d&&void 0!==G){const r=`${u}/unevaluatedItems`;for(;o=Q||t>Q)&&ct.push({instanceLocation:c,keyword:"maximum",keywordLocation:`${u}/maximum`,error:`${t} is greater than ${et?"or equal to ":""} ${Q}.`})):(void 0!==Z&&tQ&&ct.push({instanceLocation:c,keyword:"maximum",keywordLocation:`${u}/maximum`,error:`${t} is greater than ${Q}.`}),void 0!==tt&&t<=tt&&ct.push({instanceLocation:c,keyword:"exclusiveMinimum",keywordLocation:`${u}/exclusiveMinimum`,error:`${t} is less than ${tt}.`}),void 0!==et&&t>=et&&ct.push({instanceLocation:c,keyword:"exclusiveMaximum",keywordLocation:`${u}/exclusiveMaximum`,error:`${t} is greater than or equal to ${et}.`})),void 0!==nt){const e=t%nt;Math.abs(0-e)>=1.1920929e-7&&Math.abs(nt-e)>=1.1920929e-7&&ct.push({instanceLocation:c,keyword:"multipleOf",keywordLocation:`${u}/multipleOf`,error:`${t} is not a multiple of ${nt}.`})}}else if("string"===h){const e=void 0===rt&&void 0===ot?0:k(t);void 0!==rt&&eot&&ct.push({instanceLocation:c,keyword:"maxLength",keywordLocation:`${u}/maxLength`,error:`String is too long (${e} > ${ot}).`}),void 0===it||new RegExp(it).test(t)||ct.push({instanceLocation:c,keyword:"pattern",keywordLocation:`${u}/pattern`,error:"String does not match pattern."}),void 0!==P&&m[P]&&!m[P](t)&&ct.push({instanceLocation:c,keyword:"format",keywordLocation:`${u}/format`,error:`String does not match format "${P}".`})}return{valid:0===ct.length,errors:ct}}class L{constructor(t,e="2019-09",n=!0){this.schema=t,this.draft=e,this.shortCircuit=n,this.lookup=d(t)}validate(t){return j(t,this.schema,this.draft,this.lookup,this.shortCircuit)}addSchema(t,e){e&&(t={...t,$id:e}),d(t,this.lookup)}}}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={id:r,loaded:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}n.d=function(t,e){for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.nmd=function(t){return t.paths=[],t.children||(t.children=[]),t},function(){const t=n(7739),e=n(9138),{FlexSearch:r}=n(3129),{Validator:o}=n(9707);function i(t,e){t.removeEventListener("focus",i);const n=e.indexConfig?e.indexConfig:{tokenize:"forward"},o=e.dataFile;n.document={key:"id",index:["title","content","description"],store:["title","href","parent","description"]};const a=new r.Document(n);window.geekdocSearchIndex=a,c(o,(function(t){t.forEach((t=>{window.geekdocSearchIndex.add(t)}))}))}function a(t,n,r){const o=[];for(const i of t){const t=document.createElement("li"),a=t.appendChild(document.createElement("a")),s=a.appendChild(document.createElement("span"));if(a.href=i.href,s.classList.add("gdoc-search__entry--title"),s.textContent=i.title,a.classList.add("gdoc-search__entry"),!0===r){const t=a.appendChild(document.createElement("span"));t.classList.add("gdoc-search__entry--description"),t.textContent=e(i.description,{length:55,separator:" "})}n?n.appendChild(t):o.push(t)}return o}function s(t){if(!t.ok)throw Error("Failed to fetch '"+t.url+"': "+t.statusText);return t}function c(t,e){fetch(t).then(s).then((t=>t.json())).then((t=>e(t))).catch((function(t){t instanceof AggregateError?(console.error(t.message),t.errors.forEach((t=>{console.error(t)}))):console.error(t)}))}document.addEventListener("DOMContentLoaded",(function(e){const n=document.querySelector("#gdoc-search-input"),r=document.querySelector("#gdoc-search-results"),s=(u=n?n.dataset.siteBaseUrl:"",(f=document.createElement("a")).href=u,f.pathname);var u,f;const d=n?n.dataset.siteLang:"",l=new o({type:"object",properties:{dataFile:{type:"string"},indexConfig:{type:["object","null"]},showParent:{type:"boolean"},showDescription:{type:"boolean"}},additionalProperties:!1});var h,p;n&&c((h=s,(p="/search/"+d+".config.min.json")?h.replace(/\/+$/,"")+"/"+p.replace(/^\/+/,""):h),(function(e){const o=l.validate(e);if(!o.valid)throw AggregateError(o.errors.map((t=>new Error("Validation error: "+t.error))),"Schema validation failed");n&&(n.addEventListener("focus",(()=>{i(n,e)})),n.addEventListener("keyup",(()=>{!function(e,n,r){for(;n.firstChild;)n.removeChild(n.firstChild);if(!e.value)return n.classList.remove("has-hits");let o=function(t){const e=[],n=new Map;for(const r of t)for(const t of r.result)n.has(t.doc.href)||(n.set(t.doc.href,!0),e.push(t.doc));return e}(window.geekdocSearchIndex.search(e.value,{enrich:!0,limit:5}));if(o.length<1)return n.classList.remove("has-hits");n.classList.add("has-hits"),!0===r.showParent&&(o=t(o,(t=>t.parent)));const i=[];if(!0===r.showParent)for(const t in o){const e=document.createElement("li"),n=e.appendChild(document.createElement("span")),s=e.appendChild(document.createElement("ul"));t||n.remove(),n.classList.add("gdoc-search__section"),n.textContent=t,a(o[t],s,r.showDescription),i.push(e)}else{const t=document.createElement("li"),e=t.appendChild(document.createElement("span")),n=t.appendChild(document.createElement("ul"));e.textContent="Results",a(o,n,r.showDescription),i.push(t)}i.forEach((t=>{n.appendChild(t)}))}(n,r,e)})))}))}))}()}(); \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js.LICENSE.txt b/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js.LICENSE.txt new file mode 100644 index 000000000..1c041611b --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/js/search-9719be99.bundle.min.js.LICENSE.txt @@ -0,0 +1,7 @@ +/**! + * FlexSearch.js v0.7.31 (Compact) + * Copyright 2018-2022 Nextapps GmbH + * Author: Thomas Wilkerling + * Licence: Apache-2.0 + * https://github.com/nextapps-de/flexsearch + */ diff --git a/docs/themes/hugo-geekdoc/static/katex-66092164.min.css b/docs/themes/hugo-geekdoc/static/katex-66092164.min.css new file mode 100644 index 000000000..ec20ebe3b --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/katex-66092164.min.css @@ -0,0 +1 @@ +@font-face{font-family:"KaTeX_AMS";src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Caligraphic";src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype");font-weight:bold;font-style:normal}@font-face{font-family:"KaTeX_Caligraphic";src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Fraktur";src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype");font-weight:bold;font-style:normal}@font-face{font-family:"KaTeX_Fraktur";src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Main";src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype");font-weight:bold;font-style:normal}@font-face{font-family:"KaTeX_Main";src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype");font-weight:bold;font-style:italic}@font-face{font-family:"KaTeX_Main";src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype");font-weight:normal;font-style:italic}@font-face{font-family:"KaTeX_Main";src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Math";src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype");font-weight:bold;font-style:italic}@font-face{font-family:"KaTeX_Math";src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype");font-weight:normal;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype");font-weight:bold;font-style:normal}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype");font-weight:normal;font-style:italic}@font-face{font-family:"KaTeX_SansSerif";src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Script";src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Size1";src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Size2";src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Size3";src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Size4";src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}@font-face{font-family:"KaTeX_Typewriter";src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype");font-weight:normal;font-style:normal}.katex{font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none !important}.katex *{border-color:currentColor}.katex .katex-version::after{content:"0.16.8"}.katex .katex-mathml{position:absolute;clip:rect(1px, 1px, 1px, 1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}.katex .katex-html>.newline{display:block}.katex .base{position:relative;display:inline-block;white-space:nowrap;width:-moz-min-content;width:min-content}.katex .strut{display:inline-block}.katex .textbf{font-weight:bold}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:bold}.katex .boldsymbol{font-family:KaTeX_Math;font-weight:bold;font-style:italic}.katex .amsrm{font-family:KaTeX_AMS}.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:bold}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{display:inline-table;table-layout:fixed;border-collapse:collapse}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;vertical-align:bottom;position:relative}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}.katex .vbox{display:inline-flex;flex-direction:column;align-items:baseline}.katex .hbox{display:inline-flex;flex-direction:row;width:100%}.katex .thinbox{display:inline-flex;flex-direction:row;width:0;max-width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .underline .underline-line,.katex .hline,.katex .hdashline,.katex .rule{min-height:1px}.katex .mspace{display:inline-block}.katex .llap,.katex .rlap,.katex .clap{width:0;position:relative}.katex .llap>.inner,.katex .rlap>.inner,.katex .clap>.inner{position:absolute}.katex .llap>.fix,.katex .rlap>.fix,.katex .clap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .rlap>.inner,.katex .clap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{display:inline-block;border:solid 0;position:relative}.katex .overline .overline-line,.katex .underline .underline-line,.katex .hline{display:inline-block;width:100%;border-bottom-style:solid}.katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-0.55555556em}.katex .sizing.reset-size1.size1,.katex .fontsize-ensurer.reset-size1.size1{font-size:1em}.katex .sizing.reset-size1.size2,.katex .fontsize-ensurer.reset-size1.size2{font-size:1.2em}.katex .sizing.reset-size1.size3,.katex .fontsize-ensurer.reset-size1.size3{font-size:1.4em}.katex .sizing.reset-size1.size4,.katex .fontsize-ensurer.reset-size1.size4{font-size:1.6em}.katex .sizing.reset-size1.size5,.katex .fontsize-ensurer.reset-size1.size5{font-size:1.8em}.katex .sizing.reset-size1.size6,.katex .fontsize-ensurer.reset-size1.size6{font-size:2em}.katex .sizing.reset-size1.size7,.katex .fontsize-ensurer.reset-size1.size7{font-size:2.4em}.katex .sizing.reset-size1.size8,.katex .fontsize-ensurer.reset-size1.size8{font-size:2.88em}.katex .sizing.reset-size1.size9,.katex .fontsize-ensurer.reset-size1.size9{font-size:3.456em}.katex .sizing.reset-size1.size10,.katex .fontsize-ensurer.reset-size1.size10{font-size:4.148em}.katex .sizing.reset-size1.size11,.katex .fontsize-ensurer.reset-size1.size11{font-size:4.976em}.katex .sizing.reset-size2.size1,.katex .fontsize-ensurer.reset-size2.size1{font-size:.83333333em}.katex .sizing.reset-size2.size2,.katex .fontsize-ensurer.reset-size2.size2{font-size:1em}.katex .sizing.reset-size2.size3,.katex .fontsize-ensurer.reset-size2.size3{font-size:1.16666667em}.katex .sizing.reset-size2.size4,.katex .fontsize-ensurer.reset-size2.size4{font-size:1.33333333em}.katex .sizing.reset-size2.size5,.katex .fontsize-ensurer.reset-size2.size5{font-size:1.5em}.katex .sizing.reset-size2.size6,.katex .fontsize-ensurer.reset-size2.size6{font-size:1.66666667em}.katex .sizing.reset-size2.size7,.katex .fontsize-ensurer.reset-size2.size7{font-size:2em}.katex .sizing.reset-size2.size8,.katex .fontsize-ensurer.reset-size2.size8{font-size:2.4em}.katex .sizing.reset-size2.size9,.katex .fontsize-ensurer.reset-size2.size9{font-size:2.88em}.katex .sizing.reset-size2.size10,.katex .fontsize-ensurer.reset-size2.size10{font-size:3.45666667em}.katex .sizing.reset-size2.size11,.katex .fontsize-ensurer.reset-size2.size11{font-size:4.14666667em}.katex .sizing.reset-size3.size1,.katex .fontsize-ensurer.reset-size3.size1{font-size:.71428571em}.katex .sizing.reset-size3.size2,.katex .fontsize-ensurer.reset-size3.size2{font-size:.85714286em}.katex .sizing.reset-size3.size3,.katex .fontsize-ensurer.reset-size3.size3{font-size:1em}.katex .sizing.reset-size3.size4,.katex .fontsize-ensurer.reset-size3.size4{font-size:1.14285714em}.katex .sizing.reset-size3.size5,.katex .fontsize-ensurer.reset-size3.size5{font-size:1.28571429em}.katex .sizing.reset-size3.size6,.katex .fontsize-ensurer.reset-size3.size6{font-size:1.42857143em}.katex .sizing.reset-size3.size7,.katex .fontsize-ensurer.reset-size3.size7{font-size:1.71428571em}.katex .sizing.reset-size3.size8,.katex .fontsize-ensurer.reset-size3.size8{font-size:2.05714286em}.katex .sizing.reset-size3.size9,.katex .fontsize-ensurer.reset-size3.size9{font-size:2.46857143em}.katex .sizing.reset-size3.size10,.katex .fontsize-ensurer.reset-size3.size10{font-size:2.96285714em}.katex .sizing.reset-size3.size11,.katex .fontsize-ensurer.reset-size3.size11{font-size:3.55428571em}.katex .sizing.reset-size4.size1,.katex .fontsize-ensurer.reset-size4.size1{font-size:.625em}.katex .sizing.reset-size4.size2,.katex .fontsize-ensurer.reset-size4.size2{font-size:.75em}.katex .sizing.reset-size4.size3,.katex .fontsize-ensurer.reset-size4.size3{font-size:.875em}.katex .sizing.reset-size4.size4,.katex .fontsize-ensurer.reset-size4.size4{font-size:1em}.katex .sizing.reset-size4.size5,.katex .fontsize-ensurer.reset-size4.size5{font-size:1.125em}.katex .sizing.reset-size4.size6,.katex .fontsize-ensurer.reset-size4.size6{font-size:1.25em}.katex .sizing.reset-size4.size7,.katex .fontsize-ensurer.reset-size4.size7{font-size:1.5em}.katex .sizing.reset-size4.size8,.katex .fontsize-ensurer.reset-size4.size8{font-size:1.8em}.katex .sizing.reset-size4.size9,.katex .fontsize-ensurer.reset-size4.size9{font-size:2.16em}.katex .sizing.reset-size4.size10,.katex .fontsize-ensurer.reset-size4.size10{font-size:2.5925em}.katex .sizing.reset-size4.size11,.katex .fontsize-ensurer.reset-size4.size11{font-size:3.11em}.katex .sizing.reset-size5.size1,.katex .fontsize-ensurer.reset-size5.size1{font-size:.55555556em}.katex .sizing.reset-size5.size2,.katex .fontsize-ensurer.reset-size5.size2{font-size:.66666667em}.katex .sizing.reset-size5.size3,.katex .fontsize-ensurer.reset-size5.size3{font-size:.77777778em}.katex .sizing.reset-size5.size4,.katex .fontsize-ensurer.reset-size5.size4{font-size:.88888889em}.katex .sizing.reset-size5.size5,.katex .fontsize-ensurer.reset-size5.size5{font-size:1em}.katex .sizing.reset-size5.size6,.katex .fontsize-ensurer.reset-size5.size6{font-size:1.11111111em}.katex .sizing.reset-size5.size7,.katex .fontsize-ensurer.reset-size5.size7{font-size:1.33333333em}.katex .sizing.reset-size5.size8,.katex .fontsize-ensurer.reset-size5.size8{font-size:1.6em}.katex .sizing.reset-size5.size9,.katex .fontsize-ensurer.reset-size5.size9{font-size:1.92em}.katex .sizing.reset-size5.size10,.katex .fontsize-ensurer.reset-size5.size10{font-size:2.30444444em}.katex .sizing.reset-size5.size11,.katex .fontsize-ensurer.reset-size5.size11{font-size:2.76444444em}.katex .sizing.reset-size6.size1,.katex .fontsize-ensurer.reset-size6.size1{font-size:.5em}.katex .sizing.reset-size6.size2,.katex .fontsize-ensurer.reset-size6.size2{font-size:.6em}.katex .sizing.reset-size6.size3,.katex .fontsize-ensurer.reset-size6.size3{font-size:.7em}.katex .sizing.reset-size6.size4,.katex .fontsize-ensurer.reset-size6.size4{font-size:.8em}.katex .sizing.reset-size6.size5,.katex .fontsize-ensurer.reset-size6.size5{font-size:.9em}.katex .sizing.reset-size6.size6,.katex .fontsize-ensurer.reset-size6.size6{font-size:1em}.katex .sizing.reset-size6.size7,.katex .fontsize-ensurer.reset-size6.size7{font-size:1.2em}.katex .sizing.reset-size6.size8,.katex .fontsize-ensurer.reset-size6.size8{font-size:1.44em}.katex .sizing.reset-size6.size9,.katex .fontsize-ensurer.reset-size6.size9{font-size:1.728em}.katex .sizing.reset-size6.size10,.katex .fontsize-ensurer.reset-size6.size10{font-size:2.074em}.katex .sizing.reset-size6.size11,.katex .fontsize-ensurer.reset-size6.size11{font-size:2.488em}.katex .sizing.reset-size7.size1,.katex .fontsize-ensurer.reset-size7.size1{font-size:.41666667em}.katex .sizing.reset-size7.size2,.katex .fontsize-ensurer.reset-size7.size2{font-size:.5em}.katex .sizing.reset-size7.size3,.katex .fontsize-ensurer.reset-size7.size3{font-size:.58333333em}.katex .sizing.reset-size7.size4,.katex .fontsize-ensurer.reset-size7.size4{font-size:.66666667em}.katex .sizing.reset-size7.size5,.katex .fontsize-ensurer.reset-size7.size5{font-size:.75em}.katex .sizing.reset-size7.size6,.katex .fontsize-ensurer.reset-size7.size6{font-size:.83333333em}.katex .sizing.reset-size7.size7,.katex .fontsize-ensurer.reset-size7.size7{font-size:1em}.katex .sizing.reset-size7.size8,.katex .fontsize-ensurer.reset-size7.size8{font-size:1.2em}.katex .sizing.reset-size7.size9,.katex .fontsize-ensurer.reset-size7.size9{font-size:1.44em}.katex .sizing.reset-size7.size10,.katex .fontsize-ensurer.reset-size7.size10{font-size:1.72833333em}.katex .sizing.reset-size7.size11,.katex .fontsize-ensurer.reset-size7.size11{font-size:2.07333333em}.katex .sizing.reset-size8.size1,.katex .fontsize-ensurer.reset-size8.size1{font-size:.34722222em}.katex .sizing.reset-size8.size2,.katex .fontsize-ensurer.reset-size8.size2{font-size:.41666667em}.katex .sizing.reset-size8.size3,.katex .fontsize-ensurer.reset-size8.size3{font-size:.48611111em}.katex .sizing.reset-size8.size4,.katex .fontsize-ensurer.reset-size8.size4{font-size:.55555556em}.katex .sizing.reset-size8.size5,.katex .fontsize-ensurer.reset-size8.size5{font-size:.625em}.katex .sizing.reset-size8.size6,.katex .fontsize-ensurer.reset-size8.size6{font-size:.69444444em}.katex .sizing.reset-size8.size7,.katex .fontsize-ensurer.reset-size8.size7{font-size:.83333333em}.katex .sizing.reset-size8.size8,.katex .fontsize-ensurer.reset-size8.size8{font-size:1em}.katex .sizing.reset-size8.size9,.katex .fontsize-ensurer.reset-size8.size9{font-size:1.2em}.katex .sizing.reset-size8.size10,.katex .fontsize-ensurer.reset-size8.size10{font-size:1.44027778em}.katex .sizing.reset-size8.size11,.katex .fontsize-ensurer.reset-size8.size11{font-size:1.72777778em}.katex .sizing.reset-size9.size1,.katex .fontsize-ensurer.reset-size9.size1{font-size:.28935185em}.katex .sizing.reset-size9.size2,.katex .fontsize-ensurer.reset-size9.size2{font-size:.34722222em}.katex .sizing.reset-size9.size3,.katex .fontsize-ensurer.reset-size9.size3{font-size:.40509259em}.katex .sizing.reset-size9.size4,.katex .fontsize-ensurer.reset-size9.size4{font-size:.46296296em}.katex .sizing.reset-size9.size5,.katex .fontsize-ensurer.reset-size9.size5{font-size:.52083333em}.katex .sizing.reset-size9.size6,.katex .fontsize-ensurer.reset-size9.size6{font-size:.5787037em}.katex .sizing.reset-size9.size7,.katex .fontsize-ensurer.reset-size9.size7{font-size:.69444444em}.katex .sizing.reset-size9.size8,.katex .fontsize-ensurer.reset-size9.size8{font-size:.83333333em}.katex .sizing.reset-size9.size9,.katex .fontsize-ensurer.reset-size9.size9{font-size:1em}.katex .sizing.reset-size9.size10,.katex .fontsize-ensurer.reset-size9.size10{font-size:1.20023148em}.katex .sizing.reset-size9.size11,.katex .fontsize-ensurer.reset-size9.size11{font-size:1.43981481em}.katex .sizing.reset-size10.size1,.katex .fontsize-ensurer.reset-size10.size1{font-size:.24108004em}.katex .sizing.reset-size10.size2,.katex .fontsize-ensurer.reset-size10.size2{font-size:.28929605em}.katex .sizing.reset-size10.size3,.katex .fontsize-ensurer.reset-size10.size3{font-size:.33751205em}.katex .sizing.reset-size10.size4,.katex .fontsize-ensurer.reset-size10.size4{font-size:.38572806em}.katex .sizing.reset-size10.size5,.katex .fontsize-ensurer.reset-size10.size5{font-size:.43394407em}.katex .sizing.reset-size10.size6,.katex .fontsize-ensurer.reset-size10.size6{font-size:.48216008em}.katex .sizing.reset-size10.size7,.katex .fontsize-ensurer.reset-size10.size7{font-size:.57859209em}.katex .sizing.reset-size10.size8,.katex .fontsize-ensurer.reset-size10.size8{font-size:.69431051em}.katex .sizing.reset-size10.size9,.katex .fontsize-ensurer.reset-size10.size9{font-size:.83317261em}.katex .sizing.reset-size10.size10,.katex .fontsize-ensurer.reset-size10.size10{font-size:1em}.katex .sizing.reset-size10.size11,.katex .fontsize-ensurer.reset-size10.size11{font-size:1.19961427em}.katex .sizing.reset-size11.size1,.katex .fontsize-ensurer.reset-size11.size1{font-size:.20096463em}.katex .sizing.reset-size11.size2,.katex .fontsize-ensurer.reset-size11.size2{font-size:.24115756em}.katex .sizing.reset-size11.size3,.katex .fontsize-ensurer.reset-size11.size3{font-size:.28135048em}.katex .sizing.reset-size11.size4,.katex .fontsize-ensurer.reset-size11.size4{font-size:.32154341em}.katex .sizing.reset-size11.size5,.katex .fontsize-ensurer.reset-size11.size5{font-size:.36173633em}.katex .sizing.reset-size11.size6,.katex .fontsize-ensurer.reset-size11.size6{font-size:.40192926em}.katex .sizing.reset-size11.size7,.katex .fontsize-ensurer.reset-size11.size7{font-size:.48231511em}.katex .sizing.reset-size11.size8,.katex .fontsize-ensurer.reset-size11.size8{font-size:.57877814em}.katex .sizing.reset-size11.size9,.katex .fontsize-ensurer.reset-size11.size9{font-size:.69453376em}.katex .sizing.reset-size11.size10,.katex .fontsize-ensurer.reset-size11.size10{font-size:.83360129em}.katex .sizing.reset-size11.size11,.katex .fontsize-ensurer.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter{position:relative}.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .op-limits>.vlist-t{text-align:center}.katex .accent>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex svg path{stroke:none}.katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}.katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}.katex .stretchy::before,.katex .stretchy::after{content:""}.katex .hide-tail{width:100%;position:relative;overflow:hidden}.katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}.katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}.katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}.katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}.katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .x-arrow,.katex .mover,.katex .munder{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{box-sizing:border-box;border:.04em solid}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-0.2em;margin-right:-0.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{box-sizing:border-box;border-top:.049em solid;border-right:.049em solid;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num::before{counter-increment:katexEqnNo;content:"(" counter(katexEqnNo) ")"}.katex .mml-eqn-num::before{counter-increment:mmlEqnNo;content:"(" counter(mmlEqnNo) ")"}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;position:absolute;left:calc(50% + .3em);text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{text-align:left;padding-left:2em}body{counter-reset:katexEqnNo mmlEqnNo} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/main-252d384c.min.css b/docs/themes/hugo-geekdoc/static/main-252d384c.min.css new file mode 100644 index 000000000..67aaa2047 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/main-252d384c.min.css @@ -0,0 +1 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0;line-height:1.2em}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}.flex{display:flex}.flex-auto{flex:1 1 auto}.flex-25{flex:1 1 25%}.flex-inline{display:inline-flex}.flex-even{flex:1 1}.flex-wrap{flex-wrap:wrap}.flex-grid{flex-direction:column;border:1px solid var(--accent-color);border-radius:.15rem;background:var(--accent-color-lite)}.flex-gap{flex-wrap:wrap;gap:1rem}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.align-center{align-items:center}.mx-auto{margin:0 auto}.text-center{text-align:center}.text-right{text-align:right}.no-wrap{white-space:nowrap}.hidden{display:none !important}.svg-sprite{position:absolute;width:0;height:0;overflow:hidden}.table-wrap{overflow:auto;margin:1rem 0}.table-wrap>table{margin:0 !important}.badge-placeholder{display:inline-block;min-width:4rem}@font-face{font-family:"Liberation Sans";src:url("fonts/LiberationSans-Bold.woff2") format("woff2"),url("fonts/LiberationSans-Bold.woff") format("woff");font-weight:bold;font-style:normal;font-display:swap}@font-face{font-family:"Liberation Sans";src:url("fonts/LiberationSans-BoldItalic.woff2") format("woff2"),url("fonts/LiberationSans-BoldItalic.woff") format("woff");font-weight:bold;font-style:italic;font-display:swap}@font-face{font-family:"Liberation Sans";src:url("fonts/LiberationSans-Italic.woff2") format("woff2"),url("fonts/LiberationSans-Italic.woff") format("woff");font-weight:normal;font-style:italic;font-display:swap}@font-face{font-family:"Liberation Sans";src:url("fonts/LiberationSans.woff2") format("woff2"),url("fonts/LiberationSans.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}@font-face{font-family:"Liberation Mono";src:url("fonts/LiberationMono.woff2") format("woff2"),url("fonts/LiberationMono.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}@font-face{font-family:"Metropolis";src:url("fonts/Metropolis.woff2") format("woff2"),url("fonts/Metropolis.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}@font-face{font-family:"GeekdocIcons";src:url("fonts/GeekdocIcons.woff2") format("woff2"),url("fonts/GeekdocIcons.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}body{font-family:"Liberation Sans",sans-serif}code,.gdoc-error__title{font-family:"Liberation Mono",monospace}.gdoc-header{font-family:"Metropolis",sans-serif}:root,:root[color-theme=light]{--code-max-height: none;--header-background: rgb(32, 83, 117);--header-font-color: rgb(255, 255, 255);--body-background: white;--body-font-color: rgb(52, 58, 64);--mark-color: rgb(255, 171, 0);--button-background: #22597d;--button-border-color: rgb(32, 83, 117);--link-color: rgb(10, 83, 154);--link-color-visited: rgb(119, 73, 191);--hint-link-color: rgb(10, 83, 154);--hint-link-color-visited: rgb(119, 73, 191);--accent-color-dark: rgb(206, 212, 218);--accent-color: rgb(233, 236, 239);--accent-color-lite: rgb(248, 249, 250);--control-icons: #b2bac1;--footer-background: rgb(17, 43, 60);--footer-font-color: rgb(255, 255, 255);--footer-link-color: rgb(246, 107, 14);--footer-link-color-visited: rgb(246, 107, 14);--code-background: rgb(248, 249, 250);--code-accent-color: #e6eaed;--code-accent-color-lite: #f2f4f6;--code-font-color: rgb(70, 70, 70);--code-copy-background: rgb(248, 249, 250);--code-copy-font-color: #6c6c6c;--code-copy-border-color: #797979;--code-copy-success-color: rgb(0, 200, 83)}:root .dark-mode-dim .gdoc-markdown img,:root[color-theme=light] .dark-mode-dim .gdoc-markdown img{filter:none}:root .gdoc-markdown .gdoc-hint,:root .gdoc-markdown .gdoc-props__tag,:root .gdoc-markdown .admonitionblock,:root[color-theme=light] .gdoc-markdown .gdoc-hint,:root[color-theme=light] .gdoc-markdown .gdoc-props__tag,:root[color-theme=light] .gdoc-markdown .admonitionblock{filter:none}:root .gdoc-markdown .gdoc-hint__title,:root .gdoc-markdown .admonitionblock table td:first-child,:root[color-theme=light] .gdoc-markdown .gdoc-hint__title,:root[color-theme=light] .gdoc-markdown .admonitionblock table td:first-child{background-color:rgba(134,142,150,.05)}:root .chroma,:root[color-theme=light] .chroma{color:var(--code-font-color)}:root .chroma .lntable td:nth-child(2) code .hl,:root[color-theme=light] .chroma .lntable td:nth-child(2) code .hl{width:auto;margin-left:-0.5em;padding:0 .5em}:root .highlight pre.chroma,:root[color-theme=light] .highlight pre.chroma{width:100%;overflow:auto;max-height:var(--code-max-height)}:root .chroma .lntable,:root[color-theme=light] .chroma .lntable{border:1px solid var(--code-accent-color);border-radius:.15rem;border-spacing:0;padding:0;margin:0;width:100%;display:block;max-height:var(--code-max-height);overflow:auto}:root .chroma .lntable pre.chroma,:root[color-theme=light] .chroma .lntable pre.chroma{max-height:none;border-radius:0;margin:0}:root .chroma .lntable td:first-child code,:root[color-theme=light] .chroma .lntable td:first-child code{background-color:var(--code-accent-color-lite);border-right:1px solid var(--code-accent-color);padding-left:0;padding-right:0;border-radius:0}:root .chroma .lntable td:nth-child(2),:root[color-theme=light] .chroma .lntable td:nth-child(2){width:100%;margin-left:2rem}:root .chroma .x,:root[color-theme=light] .chroma .x{color:inherit}:root .chroma .err,:root[color-theme=light] .chroma .err{color:#a61717;background-color:#e3d2d2}:root .chroma .lntd,:root[color-theme=light] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}:root .chroma .hl,:root[color-theme=light] .chroma .hl{display:block;width:100%;background-color:#ffc}:root .chroma .lnt,:root[color-theme=light] .chroma .lnt{padding:0 .8em}:root .chroma .ln,:root[color-theme=light] .chroma .ln{margin-right:.4em;padding:0 .4em 0 .4em}:root .chroma .k,:root[color-theme=light] .chroma .k{color:#000;font-weight:bold}:root .chroma .kc,:root[color-theme=light] .chroma .kc{color:#000;font-weight:bold}:root .chroma .kd,:root[color-theme=light] .chroma .kd{color:#000;font-weight:bold}:root .chroma .kn,:root[color-theme=light] .chroma .kn{color:#000;font-weight:bold}:root .chroma .kp,:root[color-theme=light] .chroma .kp{color:#000;font-weight:bold}:root .chroma .kr,:root[color-theme=light] .chroma .kr{color:#000;font-weight:bold}:root .chroma .kt,:root[color-theme=light] .chroma .kt{color:#458;font-weight:bold}:root .chroma .n,:root[color-theme=light] .chroma .n{color:inherit}:root .chroma .na,:root[color-theme=light] .chroma .na{color:#006767}:root .chroma .nb,:root[color-theme=light] .chroma .nb{color:#556165}:root .chroma .bp,:root[color-theme=light] .chroma .bp{color:#676767}:root .chroma .nc,:root[color-theme=light] .chroma .nc{color:#458;font-weight:bold}:root .chroma .no,:root[color-theme=light] .chroma .no{color:#006767}:root .chroma .nd,:root[color-theme=light] .chroma .nd{color:#3c5d5d;font-weight:bold}:root .chroma .ni,:root[color-theme=light] .chroma .ni{color:purple}:root .chroma .ne,:root[color-theme=light] .chroma .ne{color:#900;font-weight:bold}:root .chroma .nf,:root[color-theme=light] .chroma .nf{color:#900;font-weight:bold}:root .chroma .fm,:root[color-theme=light] .chroma .fm{color:inherit}:root .chroma .nl,:root[color-theme=light] .chroma .nl{color:#900;font-weight:bold}:root .chroma .nn,:root[color-theme=light] .chroma .nn{color:#555}:root .chroma .nx,:root[color-theme=light] .chroma .nx{color:inherit}:root .chroma .py,:root[color-theme=light] .chroma .py{color:inherit}:root .chroma .nt,:root[color-theme=light] .chroma .nt{color:navy}:root .chroma .nv,:root[color-theme=light] .chroma .nv{color:#006767}:root .chroma .vc,:root[color-theme=light] .chroma .vc{color:#006767}:root .chroma .vg,:root[color-theme=light] .chroma .vg{color:#006767}:root .chroma .vi,:root[color-theme=light] .chroma .vi{color:#006767}:root .chroma .vm,:root[color-theme=light] .chroma .vm{color:inherit}:root .chroma .l,:root[color-theme=light] .chroma .l{color:inherit}:root .chroma .ld,:root[color-theme=light] .chroma .ld{color:inherit}:root .chroma .s,:root[color-theme=light] .chroma .s{color:#d14}:root .chroma .sa,:root[color-theme=light] .chroma .sa{color:#d14}:root .chroma .sb,:root[color-theme=light] .chroma .sb{color:#d14}:root .chroma .sc,:root[color-theme=light] .chroma .sc{color:#d14}:root .chroma .dl,:root[color-theme=light] .chroma .dl{color:#d14}:root .chroma .sd,:root[color-theme=light] .chroma .sd{color:#d14}:root .chroma .s2,:root[color-theme=light] .chroma .s2{color:#d14}:root .chroma .se,:root[color-theme=light] .chroma .se{color:#d14}:root .chroma .sh,:root[color-theme=light] .chroma .sh{color:#d14}:root .chroma .si,:root[color-theme=light] .chroma .si{color:#d14}:root .chroma .sx,:root[color-theme=light] .chroma .sx{color:#d14}:root .chroma .sr,:root[color-theme=light] .chroma .sr{color:#009926}:root .chroma .s1,:root[color-theme=light] .chroma .s1{color:#d14}:root .chroma .ss,:root[color-theme=light] .chroma .ss{color:#990073}:root .chroma .m,:root[color-theme=light] .chroma .m{color:#027e83}:root .chroma .mb,:root[color-theme=light] .chroma .mb{color:#027e83}:root .chroma .mf,:root[color-theme=light] .chroma .mf{color:#027e83}:root .chroma .mh,:root[color-theme=light] .chroma .mh{color:#027e83}:root .chroma .mi,:root[color-theme=light] .chroma .mi{color:#027e83}:root .chroma .il,:root[color-theme=light] .chroma .il{color:#027e83}:root .chroma .mo,:root[color-theme=light] .chroma .mo{color:#027e83}:root .chroma .o,:root[color-theme=light] .chroma .o{color:#000;font-weight:bold}:root .chroma .ow,:root[color-theme=light] .chroma .ow{color:#000;font-weight:bold}:root .chroma .p,:root[color-theme=light] .chroma .p{color:inherit}:root .chroma .c,:root[color-theme=light] .chroma .c{color:#676765;font-style:italic}:root .chroma .ch,:root[color-theme=light] .chroma .ch{color:#676765;font-style:italic}:root .chroma .cm,:root[color-theme=light] .chroma .cm{color:#676765;font-style:italic}:root .chroma .c1,:root[color-theme=light] .chroma .c1{color:#676765;font-style:italic}:root .chroma .cs,:root[color-theme=light] .chroma .cs{color:#676767;font-weight:bold;font-style:italic}:root .chroma .cp,:root[color-theme=light] .chroma .cp{color:#676767;font-weight:bold;font-style:italic}:root .chroma .cpf,:root[color-theme=light] .chroma .cpf{color:#676767;font-weight:bold;font-style:italic}:root .chroma .g,:root[color-theme=light] .chroma .g{color:inherit}:root .chroma .gd,:root[color-theme=light] .chroma .gd{color:#000;background-color:#fdd}:root .chroma .ge,:root[color-theme=light] .chroma .ge{color:#000;font-style:italic}:root .chroma .gr,:root[color-theme=light] .chroma .gr{color:#a00}:root .chroma .gh,:root[color-theme=light] .chroma .gh{color:#676767}:root .chroma .gi,:root[color-theme=light] .chroma .gi{color:#000;background-color:#dfd}:root .chroma .go,:root[color-theme=light] .chroma .go{color:#6f6f6f}:root .chroma .gp,:root[color-theme=light] .chroma .gp{color:#555}:root .chroma .gs,:root[color-theme=light] .chroma .gs{font-weight:bold}:root .chroma .gu,:root[color-theme=light] .chroma .gu{color:#5f5f5f}:root .chroma .gt,:root[color-theme=light] .chroma .gt{color:#a00}:root .chroma .gl,:root[color-theme=light] .chroma .gl{text-decoration:underline}:root .chroma .w,:root[color-theme=light] .chroma .w{color:#bbb}@media(prefers-color-scheme: light){:root{--header-background: rgb(32, 83, 117);--header-font-color: rgb(255, 255, 255);--body-background: white;--body-font-color: rgb(52, 58, 64);--mark-color: rgb(255, 171, 0);--button-background: #22597d;--button-border-color: rgb(32, 83, 117);--link-color: rgb(10, 83, 154);--link-color-visited: rgb(119, 73, 191);--hint-link-color: rgb(10, 83, 154);--hint-link-color-visited: rgb(119, 73, 191);--accent-color-dark: rgb(206, 212, 218);--accent-color: rgb(233, 236, 239);--accent-color-lite: rgb(248, 249, 250);--control-icons: #b2bac1;--footer-background: rgb(17, 43, 60);--footer-font-color: rgb(255, 255, 255);--footer-link-color: rgb(246, 107, 14);--footer-link-color-visited: rgb(246, 107, 14);--code-background: rgb(248, 249, 250);--code-accent-color: #e6eaed;--code-accent-color-lite: #f2f4f6;--code-font-color: rgb(70, 70, 70);--code-copy-background: rgb(248, 249, 250);--code-copy-font-color: #6c6c6c;--code-copy-border-color: #797979;--code-copy-success-color: rgb(0, 200, 83)}:root .dark-mode-dim .gdoc-markdown img{filter:none}:root .gdoc-markdown .gdoc-hint,:root .gdoc-markdown .gdoc-props__tag,:root .gdoc-markdown .admonitionblock{filter:none}:root .gdoc-markdown .gdoc-hint__title,:root .gdoc-markdown .admonitionblock table td:first-child{background-color:rgba(134,142,150,.05)}:root .chroma{color:var(--code-font-color)}:root .chroma .lntable td:nth-child(2) code .hl{width:auto;margin-left:-0.5em;padding:0 .5em}:root .highlight pre.chroma{width:100%;overflow:auto;max-height:var(--code-max-height)}:root .chroma .lntable{border:1px solid var(--code-accent-color);border-radius:.15rem;border-spacing:0;padding:0;margin:0;width:100%;display:block;max-height:var(--code-max-height);overflow:auto}:root .chroma .lntable pre.chroma{max-height:none;border-radius:0;margin:0}:root .chroma .lntable td:first-child code{background-color:var(--code-accent-color-lite);border-right:1px solid var(--code-accent-color);padding-left:0;padding-right:0;border-radius:0}:root .chroma .lntable td:nth-child(2){width:100%;margin-left:2rem}:root .chroma .x{color:inherit}:root .chroma .err{color:#a61717;background-color:#e3d2d2}:root .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}:root .chroma .hl{display:block;width:100%;background-color:#ffc}:root .chroma .lnt{padding:0 .8em}:root .chroma .ln{margin-right:.4em;padding:0 .4em 0 .4em}:root .chroma .k{color:#000;font-weight:bold}:root .chroma .kc{color:#000;font-weight:bold}:root .chroma .kd{color:#000;font-weight:bold}:root .chroma .kn{color:#000;font-weight:bold}:root .chroma .kp{color:#000;font-weight:bold}:root .chroma .kr{color:#000;font-weight:bold}:root .chroma .kt{color:#458;font-weight:bold}:root .chroma .n{color:inherit}:root .chroma .na{color:#006767}:root .chroma .nb{color:#556165}:root .chroma .bp{color:#676767}:root .chroma .nc{color:#458;font-weight:bold}:root .chroma .no{color:#006767}:root .chroma .nd{color:#3c5d5d;font-weight:bold}:root .chroma .ni{color:purple}:root .chroma .ne{color:#900;font-weight:bold}:root .chroma .nf{color:#900;font-weight:bold}:root .chroma .fm{color:inherit}:root .chroma .nl{color:#900;font-weight:bold}:root .chroma .nn{color:#555}:root .chroma .nx{color:inherit}:root .chroma .py{color:inherit}:root .chroma .nt{color:navy}:root .chroma .nv{color:#006767}:root .chroma .vc{color:#006767}:root .chroma .vg{color:#006767}:root .chroma .vi{color:#006767}:root .chroma .vm{color:inherit}:root .chroma .l{color:inherit}:root .chroma .ld{color:inherit}:root .chroma .s{color:#d14}:root .chroma .sa{color:#d14}:root .chroma .sb{color:#d14}:root .chroma .sc{color:#d14}:root .chroma .dl{color:#d14}:root .chroma .sd{color:#d14}:root .chroma .s2{color:#d14}:root .chroma .se{color:#d14}:root .chroma .sh{color:#d14}:root .chroma .si{color:#d14}:root .chroma .sx{color:#d14}:root .chroma .sr{color:#009926}:root .chroma .s1{color:#d14}:root .chroma .ss{color:#990073}:root .chroma .m{color:#027e83}:root .chroma .mb{color:#027e83}:root .chroma .mf{color:#027e83}:root .chroma .mh{color:#027e83}:root .chroma .mi{color:#027e83}:root .chroma .il{color:#027e83}:root .chroma .mo{color:#027e83}:root .chroma .o{color:#000;font-weight:bold}:root .chroma .ow{color:#000;font-weight:bold}:root .chroma .p{color:inherit}:root .chroma .c{color:#676765;font-style:italic}:root .chroma .ch{color:#676765;font-style:italic}:root .chroma .cm{color:#676765;font-style:italic}:root .chroma .c1{color:#676765;font-style:italic}:root .chroma .cs{color:#676767;font-weight:bold;font-style:italic}:root .chroma .cp{color:#676767;font-weight:bold;font-style:italic}:root .chroma .cpf{color:#676767;font-weight:bold;font-style:italic}:root .chroma .g{color:inherit}:root .chroma .gd{color:#000;background-color:#fdd}:root .chroma .ge{color:#000;font-style:italic}:root .chroma .gr{color:#a00}:root .chroma .gh{color:#676767}:root .chroma .gi{color:#000;background-color:#dfd}:root .chroma .go{color:#6f6f6f}:root .chroma .gp{color:#555}:root .chroma .gs{font-weight:bold}:root .chroma .gu{color:#5f5f5f}:root .chroma .gt{color:#a00}:root .chroma .gl{text-decoration:underline}:root .chroma .w{color:#bbb}}:root[color-theme=dark]{--header-background: rgb(32, 83, 117);--header-font-color: rgb(255, 255, 255);--body-background: #29363e;--body-font-color: #c2cfd7;--mark-color: rgb(255, 171, 0);--button-background: #22597d;--button-border-color: rgb(32, 83, 117);--link-color: rgb(110, 168, 212);--link-color-visited: rgb(186, 142, 240);--hint-link-color: rgb(10, 83, 154);--hint-link-color-visited: rgb(119, 73, 191);--accent-color-dark: #192125;--accent-color: #212b32;--accent-color-lite: #253138;--control-icons: #b2bac1;--footer-background: rgb(17, 43, 60);--footer-font-color: rgb(255, 255, 255);--footer-link-color: rgb(246, 107, 14);--footer-link-color-visited: rgb(246, 107, 14);--code-background: #232e35;--code-accent-color: #1b2329;--code-accent-color-lite: #1f292f;--code-font-color: rgb(185, 185, 185);--code-copy-background: #232e35;--code-copy-font-color: #939393;--code-copy-border-color: #868686;--code-copy-success-color: rgba(0, 200, 83, 0.45)}:root[color-theme=dark] .dark-mode-dim .gdoc-markdown img{filter:brightness(0.75) grayscale(0.2)}:root[color-theme=dark] .gdoc-markdown .gdoc-hint,:root[color-theme=dark] .gdoc-markdown .gdoc-props__tag,:root[color-theme=dark] .gdoc-markdown .admonitionblock{filter:saturate(2.5) brightness(0.85)}:root[color-theme=dark] .gdoc-markdown .gdoc-hint a,:root[color-theme=dark] .gdoc-markdown .admonitionblock a{color:var(--hint-link-color)}:root[color-theme=dark] .gdoc-markdown .gdoc-hint a:visited,:root[color-theme=dark] .gdoc-markdown .admonitionblock a:visited{color:var(--hint-link-color-visited)}:root[color-theme=dark] .gdoc-markdown .gdoc-hint__title,:root[color-theme=dark] .gdoc-markdown .admonitionblock table td:first-child{background-color:rgba(134,142,150,.15)}:root[color-theme=dark] .chroma{color:var(--code-font-color)}:root[color-theme=dark] .chroma .lntable td:nth-child(2) code .hl{width:auto;margin-left:-0.5em;padding:0 .5em}:root[color-theme=dark] .highlight pre.chroma{width:100%;overflow:auto;max-height:var(--code-max-height)}:root[color-theme=dark] .chroma .lntable{border:1px solid var(--code-accent-color);border-radius:.15rem;border-spacing:0;padding:0;margin:0;width:100%;display:block;max-height:var(--code-max-height);overflow:auto}:root[color-theme=dark] .chroma .lntable pre.chroma{max-height:none;border-radius:0;margin:0}:root[color-theme=dark] .chroma .lntable td:first-child code{background-color:var(--code-accent-color-lite);border-right:1px solid var(--code-accent-color);padding-left:0;padding-right:0;border-radius:0}:root[color-theme=dark] .chroma .lntable td:nth-child(2){width:100%;margin-left:2rem}:root[color-theme=dark] .chroma .x{color:inherit}:root[color-theme=dark] .chroma .err{color:inherit}:root[color-theme=dark] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}:root[color-theme=dark] .chroma .hl{display:block;width:100%;background-color:#4f1605}:root[color-theme=dark] .chroma .lnt{padding:0 .8em}:root[color-theme=dark] .chroma .ln{margin-right:.4em;padding:0 .4em 0 .4em;color:#b3b3b3}:root[color-theme=dark] .chroma .k{color:#ff79c6}:root[color-theme=dark] .chroma .kc{color:#ff79c6}:root[color-theme=dark] .chroma .kd{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .kn{color:#ff79c6}:root[color-theme=dark] .chroma .kp{color:#ff79c6}:root[color-theme=dark] .chroma .kr{color:#ff79c6}:root[color-theme=dark] .chroma .kt{color:#8be9fd}:root[color-theme=dark] .chroma .n{color:inherit}:root[color-theme=dark] .chroma .na{color:#50fa7b}:root[color-theme=dark] .chroma .nb{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .bp{color:inherit}:root[color-theme=dark] .chroma .nc{color:#50fa7b}:root[color-theme=dark] .chroma .no{color:inherit}:root[color-theme=dark] .chroma .nd{color:inherit}:root[color-theme=dark] .chroma .ni{color:inherit}:root[color-theme=dark] .chroma .ne{color:inherit}:root[color-theme=dark] .chroma .nf{color:#50fa7b}:root[color-theme=dark] .chroma .fm{color:inherit}:root[color-theme=dark] .chroma .nl{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .nn{color:inherit}:root[color-theme=dark] .chroma .nx{color:inherit}:root[color-theme=dark] .chroma .py{color:inherit}:root[color-theme=dark] .chroma .nt{color:#ff79c6}:root[color-theme=dark] .chroma .nv{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .vc{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .vg{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .vi{color:#8be9fd;font-style:italic}:root[color-theme=dark] .chroma .vm{color:inherit}:root[color-theme=dark] .chroma .l{color:inherit}:root[color-theme=dark] .chroma .ld{color:inherit}:root[color-theme=dark] .chroma .s{color:#f1fa8c}:root[color-theme=dark] .chroma .sa{color:#f1fa8c}:root[color-theme=dark] .chroma .sb{color:#f1fa8c}:root[color-theme=dark] .chroma .sc{color:#f1fa8c}:root[color-theme=dark] .chroma .dl{color:#f1fa8c}:root[color-theme=dark] .chroma .sd{color:#f1fa8c}:root[color-theme=dark] .chroma .s2{color:#f1fa8c}:root[color-theme=dark] .chroma .se{color:#f1fa8c}:root[color-theme=dark] .chroma .sh{color:#f1fa8c}:root[color-theme=dark] .chroma .si{color:#f1fa8c}:root[color-theme=dark] .chroma .sx{color:#f1fa8c}:root[color-theme=dark] .chroma .sr{color:#f1fa8c}:root[color-theme=dark] .chroma .s1{color:#f1fa8c}:root[color-theme=dark] .chroma .ss{color:#f1fa8c}:root[color-theme=dark] .chroma .m{color:#bd93f9}:root[color-theme=dark] .chroma .mb{color:#bd93f9}:root[color-theme=dark] .chroma .mf{color:#bd93f9}:root[color-theme=dark] .chroma .mh{color:#bd93f9}:root[color-theme=dark] .chroma .mi{color:#bd93f9}:root[color-theme=dark] .chroma .il{color:#bd93f9}:root[color-theme=dark] .chroma .mo{color:#bd93f9}:root[color-theme=dark] .chroma .o{color:#ff79c6}:root[color-theme=dark] .chroma .ow{color:#ff79c6}:root[color-theme=dark] .chroma .p{color:inherit}:root[color-theme=dark] .chroma .c{color:#96a6d8}:root[color-theme=dark] .chroma .ch{color:#96a6d8}:root[color-theme=dark] .chroma .cm{color:#96a6d8}:root[color-theme=dark] .chroma .c1{color:#96a6d8}:root[color-theme=dark] .chroma .cs{color:#96a6d8}:root[color-theme=dark] .chroma .cp{color:#ff79c6}:root[color-theme=dark] .chroma .cpf{color:#ff79c6}:root[color-theme=dark] .chroma .g{color:inherit}:root[color-theme=dark] .chroma .gd{color:#d98f90}:root[color-theme=dark] .chroma .ge{text-decoration:underline}:root[color-theme=dark] .chroma .gr{color:inherit}:root[color-theme=dark] .chroma .gh{font-weight:bold;color:inherit}:root[color-theme=dark] .chroma .gi{font-weight:bold}:root[color-theme=dark] .chroma .go{color:#8f9ea8}:root[color-theme=dark] .chroma .gp{color:inherit}:root[color-theme=dark] .chroma .gs{color:inherit}:root[color-theme=dark] .chroma .gu{font-weight:bold}:root[color-theme=dark] .chroma .gt{color:inherit}:root[color-theme=dark] .chroma .gl{text-decoration:underline}:root[color-theme=dark] .chroma .w{color:inherit}:root[code-theme=dark]{--code-background: #232e35;--code-accent-color: #1b2329;--code-accent-color-lite: #1f292f;--code-font-color: rgb(185, 185, 185);--code-copy-background: #232e35;--code-copy-font-color: #939393;--code-copy-border-color: #868686;--code-copy-success-color: rgba(0, 200, 83, 0.45)}:root[code-theme=dark] .chroma{color:var(--code-font-color)}:root[code-theme=dark] .chroma .lntable td:nth-child(2) code .hl{width:auto;margin-left:-0.5em;padding:0 .5em}:root[code-theme=dark] .highlight pre.chroma{width:100%;overflow:auto;max-height:var(--code-max-height)}:root[code-theme=dark] .chroma .lntable{border:1px solid var(--code-accent-color);border-radius:.15rem;border-spacing:0;padding:0;margin:0;width:100%;display:block;max-height:var(--code-max-height);overflow:auto}:root[code-theme=dark] .chroma .lntable pre.chroma{max-height:none;border-radius:0;margin:0}:root[code-theme=dark] .chroma .lntable td:first-child code{background-color:var(--code-accent-color-lite);border-right:1px solid var(--code-accent-color);padding-left:0;padding-right:0;border-radius:0}:root[code-theme=dark] .chroma .lntable td:nth-child(2){width:100%;margin-left:2rem}:root[code-theme=dark] .chroma .x{color:inherit}:root[code-theme=dark] .chroma .err{color:inherit}:root[code-theme=dark] .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}:root[code-theme=dark] .chroma .hl{display:block;width:100%;background-color:#4f1605}:root[code-theme=dark] .chroma .lnt{padding:0 .8em}:root[code-theme=dark] .chroma .ln{margin-right:.4em;padding:0 .4em 0 .4em;color:#b3b3b3}:root[code-theme=dark] .chroma .k{color:#ff79c6}:root[code-theme=dark] .chroma .kc{color:#ff79c6}:root[code-theme=dark] .chroma .kd{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .kn{color:#ff79c6}:root[code-theme=dark] .chroma .kp{color:#ff79c6}:root[code-theme=dark] .chroma .kr{color:#ff79c6}:root[code-theme=dark] .chroma .kt{color:#8be9fd}:root[code-theme=dark] .chroma .n{color:inherit}:root[code-theme=dark] .chroma .na{color:#50fa7b}:root[code-theme=dark] .chroma .nb{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .bp{color:inherit}:root[code-theme=dark] .chroma .nc{color:#50fa7b}:root[code-theme=dark] .chroma .no{color:inherit}:root[code-theme=dark] .chroma .nd{color:inherit}:root[code-theme=dark] .chroma .ni{color:inherit}:root[code-theme=dark] .chroma .ne{color:inherit}:root[code-theme=dark] .chroma .nf{color:#50fa7b}:root[code-theme=dark] .chroma .fm{color:inherit}:root[code-theme=dark] .chroma .nl{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .nn{color:inherit}:root[code-theme=dark] .chroma .nx{color:inherit}:root[code-theme=dark] .chroma .py{color:inherit}:root[code-theme=dark] .chroma .nt{color:#ff79c6}:root[code-theme=dark] .chroma .nv{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .vc{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .vg{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .vi{color:#8be9fd;font-style:italic}:root[code-theme=dark] .chroma .vm{color:inherit}:root[code-theme=dark] .chroma .l{color:inherit}:root[code-theme=dark] .chroma .ld{color:inherit}:root[code-theme=dark] .chroma .s{color:#f1fa8c}:root[code-theme=dark] .chroma .sa{color:#f1fa8c}:root[code-theme=dark] .chroma .sb{color:#f1fa8c}:root[code-theme=dark] .chroma .sc{color:#f1fa8c}:root[code-theme=dark] .chroma .dl{color:#f1fa8c}:root[code-theme=dark] .chroma .sd{color:#f1fa8c}:root[code-theme=dark] .chroma .s2{color:#f1fa8c}:root[code-theme=dark] .chroma .se{color:#f1fa8c}:root[code-theme=dark] .chroma .sh{color:#f1fa8c}:root[code-theme=dark] .chroma .si{color:#f1fa8c}:root[code-theme=dark] .chroma .sx{color:#f1fa8c}:root[code-theme=dark] .chroma .sr{color:#f1fa8c}:root[code-theme=dark] .chroma .s1{color:#f1fa8c}:root[code-theme=dark] .chroma .ss{color:#f1fa8c}:root[code-theme=dark] .chroma .m{color:#bd93f9}:root[code-theme=dark] .chroma .mb{color:#bd93f9}:root[code-theme=dark] .chroma .mf{color:#bd93f9}:root[code-theme=dark] .chroma .mh{color:#bd93f9}:root[code-theme=dark] .chroma .mi{color:#bd93f9}:root[code-theme=dark] .chroma .il{color:#bd93f9}:root[code-theme=dark] .chroma .mo{color:#bd93f9}:root[code-theme=dark] .chroma .o{color:#ff79c6}:root[code-theme=dark] .chroma .ow{color:#ff79c6}:root[code-theme=dark] .chroma .p{color:inherit}:root[code-theme=dark] .chroma .c{color:#96a6d8}:root[code-theme=dark] .chroma .ch{color:#96a6d8}:root[code-theme=dark] .chroma .cm{color:#96a6d8}:root[code-theme=dark] .chroma .c1{color:#96a6d8}:root[code-theme=dark] .chroma .cs{color:#96a6d8}:root[code-theme=dark] .chroma .cp{color:#ff79c6}:root[code-theme=dark] .chroma .cpf{color:#ff79c6}:root[code-theme=dark] .chroma .g{color:inherit}:root[code-theme=dark] .chroma .gd{color:#d98f90}:root[code-theme=dark] .chroma .ge{text-decoration:underline}:root[code-theme=dark] .chroma .gr{color:inherit}:root[code-theme=dark] .chroma .gh{font-weight:bold;color:inherit}:root[code-theme=dark] .chroma .gi{font-weight:bold}:root[code-theme=dark] .chroma .go{color:#8f9ea8}:root[code-theme=dark] .chroma .gp{color:inherit}:root[code-theme=dark] .chroma .gs{color:inherit}:root[code-theme=dark] .chroma .gu{font-weight:bold}:root[code-theme=dark] .chroma .gt{color:inherit}:root[code-theme=dark] .chroma .gl{text-decoration:underline}:root[code-theme=dark] .chroma .w{color:inherit}@media(prefers-color-scheme: dark){:root{--header-background: rgb(32, 83, 117);--header-font-color: rgb(255, 255, 255);--body-background: #29363e;--body-font-color: #c2cfd7;--mark-color: rgb(255, 171, 0);--button-background: #22597d;--button-border-color: rgb(32, 83, 117);--link-color: rgb(110, 168, 212);--link-color-visited: rgb(186, 142, 240);--hint-link-color: rgb(10, 83, 154);--hint-link-color-visited: rgb(119, 73, 191);--accent-color-dark: #192125;--accent-color: #212b32;--accent-color-lite: #253138;--control-icons: #b2bac1;--footer-background: rgb(17, 43, 60);--footer-font-color: rgb(255, 255, 255);--footer-link-color: rgb(246, 107, 14);--footer-link-color-visited: rgb(246, 107, 14);--code-background: #232e35;--code-accent-color: #1b2329;--code-accent-color-lite: #1f292f;--code-font-color: rgb(185, 185, 185);--code-copy-background: #232e35;--code-copy-font-color: #939393;--code-copy-border-color: #868686;--code-copy-success-color: rgba(0, 200, 83, 0.45)}:root .dark-mode-dim .gdoc-markdown img{filter:brightness(0.75) grayscale(0.2)}:root .gdoc-markdown .gdoc-hint,:root .gdoc-markdown .gdoc-props__tag,:root .gdoc-markdown .admonitionblock{filter:saturate(2.5) brightness(0.85)}:root .gdoc-markdown .gdoc-hint a,:root .gdoc-markdown .admonitionblock a{color:var(--hint-link-color)}:root .gdoc-markdown .gdoc-hint a:visited,:root .gdoc-markdown .admonitionblock a:visited{color:var(--hint-link-color-visited)}:root .gdoc-markdown .gdoc-hint__title,:root .gdoc-markdown .admonitionblock table td:first-child{background-color:rgba(134,142,150,.15)}:root .chroma{color:var(--code-font-color)}:root .chroma .lntable td:nth-child(2) code .hl{width:auto;margin-left:-0.5em;padding:0 .5em}:root .highlight pre.chroma{width:100%;overflow:auto;max-height:var(--code-max-height)}:root .chroma .lntable{border:1px solid var(--code-accent-color);border-radius:.15rem;border-spacing:0;padding:0;margin:0;width:100%;display:block;max-height:var(--code-max-height);overflow:auto}:root .chroma .lntable pre.chroma{max-height:none;border-radius:0;margin:0}:root .chroma .lntable td:first-child code{background-color:var(--code-accent-color-lite);border-right:1px solid var(--code-accent-color);padding-left:0;padding-right:0;border-radius:0}:root .chroma .lntable td:nth-child(2){width:100%;margin-left:2rem}:root .chroma .x{color:inherit}:root .chroma .err{color:inherit}:root .chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}:root .chroma .hl{display:block;width:100%;background-color:#4f1605}:root .chroma .lnt{padding:0 .8em}:root .chroma .ln{margin-right:.4em;padding:0 .4em 0 .4em;color:#b3b3b3}:root .chroma .k{color:#ff79c6}:root .chroma .kc{color:#ff79c6}:root .chroma .kd{color:#8be9fd;font-style:italic}:root .chroma .kn{color:#ff79c6}:root .chroma .kp{color:#ff79c6}:root .chroma .kr{color:#ff79c6}:root .chroma .kt{color:#8be9fd}:root .chroma .n{color:inherit}:root .chroma .na{color:#50fa7b}:root .chroma .nb{color:#8be9fd;font-style:italic}:root .chroma .bp{color:inherit}:root .chroma .nc{color:#50fa7b}:root .chroma .no{color:inherit}:root .chroma .nd{color:inherit}:root .chroma .ni{color:inherit}:root .chroma .ne{color:inherit}:root .chroma .nf{color:#50fa7b}:root .chroma .fm{color:inherit}:root .chroma .nl{color:#8be9fd;font-style:italic}:root .chroma .nn{color:inherit}:root .chroma .nx{color:inherit}:root .chroma .py{color:inherit}:root .chroma .nt{color:#ff79c6}:root .chroma .nv{color:#8be9fd;font-style:italic}:root .chroma .vc{color:#8be9fd;font-style:italic}:root .chroma .vg{color:#8be9fd;font-style:italic}:root .chroma .vi{color:#8be9fd;font-style:italic}:root .chroma .vm{color:inherit}:root .chroma .l{color:inherit}:root .chroma .ld{color:inherit}:root .chroma .s{color:#f1fa8c}:root .chroma .sa{color:#f1fa8c}:root .chroma .sb{color:#f1fa8c}:root .chroma .sc{color:#f1fa8c}:root .chroma .dl{color:#f1fa8c}:root .chroma .sd{color:#f1fa8c}:root .chroma .s2{color:#f1fa8c}:root .chroma .se{color:#f1fa8c}:root .chroma .sh{color:#f1fa8c}:root .chroma .si{color:#f1fa8c}:root .chroma .sx{color:#f1fa8c}:root .chroma .sr{color:#f1fa8c}:root .chroma .s1{color:#f1fa8c}:root .chroma .ss{color:#f1fa8c}:root .chroma .m{color:#bd93f9}:root .chroma .mb{color:#bd93f9}:root .chroma .mf{color:#bd93f9}:root .chroma .mh{color:#bd93f9}:root .chroma .mi{color:#bd93f9}:root .chroma .il{color:#bd93f9}:root .chroma .mo{color:#bd93f9}:root .chroma .o{color:#ff79c6}:root .chroma .ow{color:#ff79c6}:root .chroma .p{color:inherit}:root .chroma .c{color:#96a6d8}:root .chroma .ch{color:#96a6d8}:root .chroma .cm{color:#96a6d8}:root .chroma .c1{color:#96a6d8}:root .chroma .cs{color:#96a6d8}:root .chroma .cp{color:#ff79c6}:root .chroma .cpf{color:#ff79c6}:root .chroma .g{color:inherit}:root .chroma .gd{color:#d98f90}:root .chroma .ge{text-decoration:underline}:root .chroma .gr{color:inherit}:root .chroma .gh{font-weight:bold;color:inherit}:root .chroma .gi{font-weight:bold}:root .chroma .go{color:#8f9ea8}:root .chroma .gp{color:inherit}:root .chroma .gs{color:inherit}:root .chroma .gu{font-weight:bold}:root .chroma .gt{color:inherit}:root .chroma .gl{text-decoration:underline}:root .chroma .w{color:inherit}}html{font-size:16px;letter-spacing:.33px;scroll-behavior:smooth}html.color-toggle-hidden #gdoc-color-theme{display:none}html.color-toggle-light #gdoc-color-theme .gdoc_brightness_light{display:inline-block}html.color-toggle-light #gdoc-color-theme .gdoc_brightness_auto,html.color-toggle-light #gdoc-color-theme .gdoc_brightness_dark{display:none}html.color-toggle-dark #gdoc-color-theme .gdoc_brightness_dark{display:inline-block}html.color-toggle-dark #gdoc-color-theme .gdoc_brightness_auto,html.color-toggle-dark #gdoc-color-theme .gdoc_brightness_light{display:none}html.color-toggle-auto #gdoc-color-theme .gdoc_brightness_light{display:none}html.color-toggle-auto #gdoc-color-theme .gdoc_brightness_dark{display:none}html.color-toggle-auto #gdoc-color-theme .gdoc_brightness_auto{display:inline-block}html,body{min-width:20rem;overflow-x:hidden}body{text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}body *{box-sizing:inherit}h1,h2,h3,h4,h5,h6{font-weight:normal;display:flex;align-items:center}h4,h5,h6{font-size:1rem !important}a{text-decoration:none;color:var(--link-color)}a:hover{text-decoration:underline}a:visited{color:var(--link-color-visited)}i.gdoc-icon{font-family:"GeekdocIcons";font-style:normal}img{vertical-align:middle}#gdoc-color-theme{cursor:pointer}.fake-link:hover{background-image:linear-gradient(var(--link-color), var(--link-color));background-position:0 100%;background-size:100% 1px;background-repeat:no-repeat;text-decoration:none}.wrapper{display:flex;flex-direction:column;min-height:100vh;color:var(--body-font-color);background:var(--body-background);font-weight:normal}.container{width:100%;max-width:82rem;margin:0 auto;padding:1.25rem}svg.gdoc-icon{display:inline-block;width:1.25rem;height:1.25rem;vertical-align:middle;stroke-width:0;stroke:currentColor;fill:currentColor;position:relative}.gdoc-header{background:var(--header-background);color:var(--header-font-color);border-bottom:.3em solid var(--footer-background)}.gdoc-header__link,.gdoc-header__link:visited{color:var(--header-font-color)}.gdoc-header__link:hover{text-decoration:none}.gdoc-header svg.gdoc-icon{width:2rem;height:2rem}.gdoc-brand{font-size:2rem;line-height:2rem}.gdoc-brand__img{margin-right:1rem;width:2rem;height:2rem}.gdoc-menu-header__items{display:flex}.gdoc-menu-header__items>span{margin-left:.5rem}.gdoc-menu-header__control,.gdoc-menu-header__home{display:none}.gdoc-menu-header__control svg.gdoc-icon,.gdoc-menu-header__home svg.gdoc-icon{cursor:pointer}.gdoc-nav{flex:0 0 18rem}.gdoc-nav nav{width:18rem;padding:1rem 2rem 1rem 0}.gdoc-nav nav>ul>li>*{font-weight:normal}.gdoc-nav nav section{margin-top:2rem}.gdoc-nav__control{display:none;margin:0;padding:0}.gdoc-nav__control svg.gdoc-icon{cursor:pointer}.gdoc-nav__control svg.gdoc-icon.gdoc_menu{display:inline-block}.gdoc-nav__control svg.gdoc-icon.gdoc_arrow_back{display:none}.gdoc-nav__list{padding-left:1rem;margin:0;padding:0;list-style:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.gdoc-nav__list ul{padding-left:1rem}.gdoc-nav__list li{margin:.75rem 0}.gdoc-nav__list svg.gdoc-icon{margin-right:.25rem}.gdoc-nav__toggle{display:none}.gdoc-nav__toggle~label{cursor:pointer}.gdoc-nav__toggle~label svg.gdoc-icon.toggle{width:1rem;height:1rem}.gdoc-nav__toggle:not(:checked)~ul,.gdoc-nav__toggle:not(:checked)~label svg.gdoc-icon.gdoc_keyboard_arrow_down{display:none}.gdoc-nav__toggle:not(:checked)~label svg.gdoc-icon.gdoc_keyboard_arrow_left{display:block}.gdoc-nav__toggle:checked~ul,.gdoc-nav__toggle:checked~label svg.gdoc-icon.gdoc_keyboard_arrow_down{display:block}.gdoc-nav__toggle:checked~label svg.gdoc-icon.gdoc_keyboard_arrow_left{display:none}.gdoc-nav--main>ul>li>span,.gdoc-nav--main>ul>li>span>a,.gdoc-nav--main>ul>li>label,.gdoc-nav--main>ul>li>label>a{font-weight:bold}.gdoc-nav__entry,.gdoc-language__entry{flex:1;color:var(--body-font-color)}.gdoc-nav__entry:hover,.gdoc-nav__entry.is-active,.gdoc-language__entry:hover,.gdoc-language__entry.is-active{text-decoration:underline;text-decoration-style:dashed !important}.gdoc-nav__entry:visited,.gdoc-language__entry:visited{color:var(--body-font-color)}.gdoc-search__list,.gdoc-language__list{background:var(--body-background);border-radius:.15rem;box-shadow:0 1px 3px 0 var(--accent-color-dark),0 1px 2px 0 var(--accent-color);position:absolute;margin:0;padding:.5rem .25rem !important;list-style:none;top:calc(100% + 0.5rem);z-index:2}.gdoc-page{min-width:18rem;flex-grow:1;padding:1rem 0}.gdoc-page h1,.gdoc-page h2,.gdoc-page h3,.gdoc-page h4,.gdoc-page h5,.gdoc-page h6{font-weight:600}.gdoc-page__header,.gdoc-page__footer{margin-bottom:1.5rem}.gdoc-page__header svg.gdoc-icon,.gdoc-page__footer svg.gdoc-icon{color:var(--control-icons)}.gdoc-page__header a,.gdoc-page__header a:visited,.gdoc-page__footer a,.gdoc-page__footer a:visited{color:var(--link-color)}.gdoc-page__header{background:var(--accent-color-lite);padding:.5rem 1rem;border-radius:.15rem}.gdoc-page__nav:hover{background-image:linear-gradient(var(--link-color), var(--link-color));background-position:0 100%;background-size:100% 1px;background-repeat:no-repeat}.gdoc-page__anchorwrap{gap:.5em}.gdoc-page__anchorwrap:hover .gdoc-page__anchor svg.gdoc-icon{color:var(--control-icons)}.gdoc-page__anchor svg.gdoc-icon{width:1.85em;height:1.85em;color:rgba(0,0,0,0)}.gdoc-page__anchor:focus svg.gdoc-icon{color:var(--control-icons)}.gdoc-page__footer{margin-top:2rem}.gdoc-page__footer a:hover{text-decoration:none}.gdoc-post{word-wrap:break-word;border-top:1px dashed #868e96;padding:2rem 0}.gdoc-post:first-of-type{padding-top:0}.gdoc-post__header h1{margin-top:0}.gdoc-post__header a,.gdoc-post__header a:visited{color:var(--body-font-color);text-decoration:none}.gdoc-post__header a:hover{background:none;text-decoration:underline;color:var(--body-font-color)}.gdoc-post:first-child{border-top:0}.gdoc-post:first-child h1{margin-top:0}.gdoc-post__readmore{margin:2rem 0}.gdoc-post__readmore a,.gdoc-post__readmore a:hover,.gdoc-post__readmore a:visited{color:var(--link-color);text-decoration:none !important}.gdoc-post__meta span svg.gdoc-icon{margin-left:-5px}.gdoc-post__meta>span{margin:.25rem 0}.gdoc-post__meta>span:not(:last-child){margin-right:.5rem}.gdoc-post__meta svg.gdoc-icon{font-size:1.25rem}.gdoc-post__meta .gdoc-button{margin:0 .125rem 0 0}.gdoc-post__meta--head{margin-bottom:2rem}.gdoc-post__codecontainer{position:relative}.gdoc-post__codecontainer:hover>.gdoc-post__codecopy{visibility:visible}.gdoc-post__codecopy{visibility:hidden;position:absolute;top:.5rem;right:.5rem;border:1.5px solid var(--code-copy-border-color);border-radius:.15rem;background:var(--code-copy-background);width:2rem;height:2rem}.gdoc-post__codecopy svg.gdoc-icon{top:0;width:1.25rem;height:1.25rem;color:var(--code-copy-font-color)}.gdoc-post__codecopy:hover{cursor:pointer}.gdoc-post__codecopy--success{border-color:var(--code-copy-success-color)}.gdoc-post__codecopy--success svg.gdoc-icon{color:var(--code-copy-success-color)}.gdoc-post__codecopy--out{transition:visibility 2s ease-out}.gdoc-footer{background:var(--footer-background);color:var(--footer-font-color)}.gdoc-footer .fake-link:hover{background-image:linear-gradient(var(--footer-link-color), var(--footer-link-color))}.gdoc-footer__item{line-height:2rem}.gdoc-footer__item--row{margin-right:1rem}.gdoc-footer__link{color:var(--footer-link-color)}.gdoc-footer__link:visited{color:var(--footer-link-color-visited)}.gdoc-search{position:relative}.gdoc-search svg.gdoc-icon{position:absolute;left:.5rem;color:var(--control-icons);width:1.25rem;height:1.25rem}.gdoc-search::after{display:block;content:"";clear:both}.gdoc-search__input{width:100%;padding:.5rem;padding-left:2rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;border:1px solid rgba(0,0,0,0);border-radius:.15rem;background:var(--accent-color-lite);color:var(--body-font-color)}.gdoc-search__input:focus{outline:none !important;border:1px solid var(--accent-color)}.gdoc-search__list{visibility:hidden;left:0;width:100%}.gdoc-search__list ul{list-style:none;padding-left:0}.gdoc-search__list>li>span{font-weight:bold}.gdoc-search__list>li+li{margin-top:.25rem}.gdoc-search__list svg.gdoc-icon{margin-right:.25rem}.gdoc-search__section{display:flex;flex-direction:column;padding:.25rem !important}.gdoc-search__entry{display:flex;flex-direction:column;color:var(--body-font-color);padding:.25rem !important;border-radius:.15rem}.gdoc-search__entry:hover,.gdoc-search__entry.is-active{background:var(--accent-color-lite);text-decoration:none}.gdoc-search__entry:hover .gdoc-search__entry--title,.gdoc-search__entry.is-active .gdoc-search__entry--title{text-decoration-style:dashed !important;text-decoration:underline}.gdoc-search__entry:visited{color:var(--body-font-color)}.gdoc-search__entry--description{font-size:.875rem;font-style:italic}.gdoc-search:focus-within .gdoc-search__list.has-hits,.gdoc-search__list.has-hits:hover{visibility:visible}.gdoc-language__selector{position:relative;list-style:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:pointer;margin:0;padding:0;width:100%}.gdoc-language__selector:focus .gdoc-language__list,.gdoc-language__selector:focus-within .gdoc-language__list,.gdoc-language__selector:active .gdoc-language__list{display:block}.gdoc-language__list{display:none;right:0;width:auto;white-space:nowrap}.gdoc-paging{padding:1rem 0}.gdoc-paging__item{flex:1 1 0}.gdoc-paging__item a:visited{color:var(--link-color)}.gdoc-paging__item a:hover,.gdoc-paging__item a:visited:hover{background:var(--link-color);color:#f8f9fa}.gdoc-paging__item--next{text-align:right}.gdoc-paging__item--prev{text-align:left}.gdoc-error{padding:6rem 1rem;margin:0 auto;max-width:45em}.gdoc-error svg.gdoc-icon{width:8rem;height:8rem;color:var(--body-font-color)}.gdoc-error__link,.gdoc-error__link:visited{color:var(--link-color)}.gdoc-error__message{padding-left:4rem}.gdoc-error__line{padding:.5rem 0}.gdoc-error__title{font-size:4rem}.gdoc-error__code{font-weight:bolder}.gdoc-toc{margin:1rem 0}.gdoc-toc li{margin:.25rem 0}.gdoc-toc__level--1 ul ul,.gdoc-toc__level--2 ul ul ul,.gdoc-toc__level--3 ul ul ul ul,.gdoc-toc__level--4 ul ul ul ul ul,.gdoc-toc__level--5 ul ul ul ul ul ul,.gdoc-toc__level--6 ul ul ul ul ul ul ul{display:none}.gdoc-toc a,.gdoc-toc a:visited{color:var(--link-color)}.gdoc-nav nav,.gdoc-page,.markdown{transition:.2s ease-in-out;transition-property:transform,margin-left,opacity;will-change:transform,margin-left}.breadcrumb{display:inline;padding:0;margin:0}.breadcrumb li{display:inline}.gdoc-markdown{line-height:1.6rem}.gdoc-markdown h1,.gdoc-markdown h2,.gdoc-markdown h3,.gdoc-markdown h4,.gdoc-markdown h5,.gdoc-markdown h6{font-weight:600}.gdoc-markdown h1>code,.gdoc-markdown h2>code,.gdoc-markdown h3>code,.gdoc-markdown h4>code,.gdoc-markdown h5>code,.gdoc-markdown h6>code{border-top:3px solid var(--accent-color);font-size:.75rem !important}.gdoc-markdown h4>code,.gdoc-markdown h5>code,.gdoc-markdown h6>code{font-size:.875rem !important}.gdoc-markdown b,.gdoc-markdown optgroup,.gdoc-markdown strong{font-weight:bolder}.gdoc-markdown a,.gdoc-markdown__link{text-decoration:none;border-bottom:1px solid rgba(0,0,0,0);line-height:normal}.gdoc-markdown a:hover,.gdoc-markdown__link:hover{text-decoration:underline}.gdoc-markdown__link--raw{text-decoration:none !important;color:#343a40 !important}.gdoc-markdown__link--raw:hover{text-decoration:none !important}.gdoc-markdown__link--raw:visited{color:#343a40 !important}.gdoc-markdown__link--code{text-decoration:none}.gdoc-markdown__link--code code{color:inherit !important}.gdoc-markdown__link--code:hover{background:none;color:var(--link-color) !important;text-decoration:underline}.gdoc-markdown__link--code:visited,.gdoc-markdown__link--code:visited:hover{color:var(--link-color-visited) !important}.gdoc-markdown__figure{padding:.25rem;margin:1rem 0;background-color:var(--accent-color);display:table;border-top-left-radius:.15rem;border-top-right-radius:.15rem}.gdoc-markdown__figure--round,.gdoc-markdown__figure--round img{border-radius:50% !important}.gdoc-markdown__figure figcaption{display:table-caption;caption-side:bottom;background-color:var(--accent-color);padding:0 .25rem .25rem;text-align:center;border-bottom-left-radius:.15rem;border-bottom-right-radius:.15rem}.gdoc-markdown__figure img{max-width:100%;height:auto}.gdoc-markdown img{max-width:100%;border-radius:.15rem}.gdoc-markdown blockquote{margin:1rem 0;padding:.5rem 1rem .5rem .75rem;border-left:3px solid var(--accent-color);border-radius:.15rem}.gdoc-markdown table:not(.lntable):not(.highlight){display:table;border-spacing:0;border-collapse:collapse;margin-top:1rem;margin-bottom:1rem;width:100%;text-align:left}.gdoc-markdown table:not(.lntable):not(.highlight) thead{border-bottom:3px solid var(--accent-color)}.gdoc-markdown table:not(.lntable):not(.highlight) tr th,.gdoc-markdown table:not(.lntable):not(.highlight) tr td{padding:.5rem 1rem}.gdoc-markdown table:not(.lntable):not(.highlight) tr{border-bottom:1.5px solid var(--accent-color)}.gdoc-markdown table:not(.lntable):not(.highlight) tr:nth-child(2n){background:var(--accent-color-lite)}.gdoc-markdown hr{height:1.5px;border:none;background:var(--accent-color)}.gdoc-markdown ul,.gdoc-markdown ol{padding-left:2rem}.gdoc-markdown dl dt{font-weight:bolder;margin-top:1rem}.gdoc-markdown dl dd{margin-left:2rem}.gdoc-markdown code{padding:.25rem .5rem}.gdoc-markdown pre,.gdoc-markdown code{background-color:var(--code-background);border-radius:.15rem;color:var(--code-font-color);font-size:.875rem;line-height:1rem}.gdoc-markdown pre code{display:block;padding:1rem;width:100%}.gdoc-markdown mark{background-color:var(--mark-color)}.gdoc-markdown__align--left{text-align:left}.gdoc-markdown__align--left h1,.gdoc-markdown__align--left h2,.gdoc-markdown__align--left h3,.gdoc-markdown__align--left h4,.gdoc-markdown__align--left h5,.gdoc-markdown__align--left h6{justify-content:flex-start}.gdoc-markdown__align--center{text-align:center}.gdoc-markdown__align--center h1,.gdoc-markdown__align--center h2,.gdoc-markdown__align--center h3,.gdoc-markdown__align--center h4,.gdoc-markdown__align--center h5,.gdoc-markdown__align--center h6{justify-content:center}.gdoc-markdown__align--right{text-align:right}.gdoc-markdown__align--right h1,.gdoc-markdown__align--right h2,.gdoc-markdown__align--right h3,.gdoc-markdown__align--right h4,.gdoc-markdown__align--right h5,.gdoc-markdown__align--right h6{justify-content:flex-end}.admonitionblock{margin:1rem 0;padding:0;border-left:3px solid var(--accent-color);border-radius:.15rem}.admonitionblock.info{border-left-color:#0091ea;background-color:#f3f9fd;color:#343a40}.admonitionblock.note{border-left-color:#0091ea;background-color:#f3f9fd;color:#343a40}.admonitionblock.ok{border-left-color:#00c853;background-color:#f2fdf6;color:#343a40}.admonitionblock.tip{border-left-color:#00c853;background-color:#f2fdf6;color:#343a40}.admonitionblock.important{border-left-color:#ffab00;background-color:#fdfaf4;color:#343a40}.admonitionblock.caution{border-left-color:#7300d3;background-color:#f8f2fd;color:#343a40}.admonitionblock.danger{border-left-color:#d50000;background-color:#fdf2f2;color:#343a40}.admonitionblock.warning{border-left-color:#d50000;background-color:#fdf2f2;color:#343a40}.admonitionblock table{margin:0 !important;padding:0 !important}.admonitionblock table tr{border:0 !important}.admonitionblock table td{display:block;padding:.25rem 1rem !important}.admonitionblock table td:first-child{background-color:rgba(134,142,150,.05);font-weight:bold}.admonitionblock table td:first-child.icon .title{display:flex;align-items:center}.admonitionblock table td:first-child.icon i.fa::after{content:attr(title);font-style:normal;padding-left:1.5rem}.admonitionblock table td:first-child.icon i.fa{color:#000;background-size:auto 90%;background-repeat:no-repeat;filter:invert(30%);margin-left:-5px}.admonitionblock table td:first-child.icon i.fa.icon-info{background-image:url(img/geekdoc-stack.svg#gdoc_info_outline)}.admonitionblock table td:first-child.icon i.fa.icon-note{background-image:url(img/geekdoc-stack.svg#gdoc_info_outline)}.admonitionblock table td:first-child.icon i.fa.icon-ok{background-image:url(img/geekdoc-stack.svg#gdoc_check_circle_outline)}.admonitionblock table td:first-child.icon i.fa.icon-tip{background-image:url(img/geekdoc-stack.svg#gdoc_check_circle_outline)}.admonitionblock table td:first-child.icon i.fa.icon-important{background-image:url(img/geekdoc-stack.svg#gdoc_error_outline)}.admonitionblock table td:first-child.icon i.fa.icon-caution{background-image:url(img/geekdoc-stack.svg#gdoc_dangerous)}.admonitionblock table td:first-child.icon i.fa.icon-danger{background-image:url(img/geekdoc-stack.svg#gdoc_fire)}.admonitionblock table td:first-child.icon i.fa.icon-warning{background-image:url(img/geekdoc-stack.svg#gdoc_fire)}.gdoc-expand{margin:1rem 0;border:1px solid var(--accent-color);border-radius:.15rem;overflow:hidden}.gdoc-expand__head{background:var(--accent-color-lite);padding:.5rem 1rem;cursor:pointer}.gdoc-expand__content{display:none;padding:0 1rem}.gdoc-expand__control:checked+.gdoc-expand__content{display:block}.gdoc-expand .gdoc-page__anchor{display:none}.gdoc-tabs{margin:1rem 0;border:1px solid var(--accent-color);border-radius:.15rem;overflow:hidden;display:flex;flex-wrap:wrap}.gdoc-tabs__label{display:inline-block;padding:.5rem 1rem;border-bottom:1px rgba(0,0,0,0);cursor:pointer}.gdoc-tabs__content{order:999;width:100%;border-top:1px solid var(--accent-color-lite);padding:0 1rem;display:none}.gdoc-tabs__control:checked+.gdoc-tabs__label{border-bottom:1.5px solid var(--link-color)}.gdoc-tabs__control:checked+.gdoc-tabs__label+.gdoc-tabs__content{display:block}.gdoc-tabs .gdoc-page__anchor{display:none}.gdoc-columns{margin:1rem 0}.gdoc-columns--regular>:first-child{flex:1}.gdoc-columns--small>:first-child{flex:.35;min-width:7rem}.gdoc-columns--large>:first-child{flex:1.65;min-width:33rem}.gdoc-columns__content{flex:1 1;min-width:13.2rem;padding:0}.gdoc-columns .gdoc-post__anchor{display:none}.gdoc-button{margin:1rem 0;display:inline-block;background:var(--accent-color-lite);border:1px solid var(--accent-color);border-radius:.15rem;cursor:pointer}.gdoc-button__link{display:inline-block;color:inherit !important;text-decoration:none !important}.gdoc-button:hover{background:var(--button-background);border-color:var(--button-border-color);color:#f8f9fa}.gdoc-button--regular{font-size:16px}.gdoc-button--regular .gdoc-button__link{padding:.25rem .5rem}.gdoc-button--large{font-size:1.25rem}.gdoc-button--large .gdoc-button__link{padding:.5rem 1rem}.gdoc-hint.info{border-left-color:#0091ea;background-color:#f3f9fd;color:#343a40;padding:0}.gdoc-hint.note{border-left-color:#0091ea;background-color:#f3f9fd;color:#343a40;padding:0}.gdoc-hint.ok{border-left-color:#00c853;background-color:#f2fdf6;color:#343a40;padding:0}.gdoc-hint.tip{border-left-color:#00c853;background-color:#f2fdf6;color:#343a40;padding:0}.gdoc-hint.important{border-left-color:#ffab00;background-color:#fdfaf4;color:#343a40;padding:0}.gdoc-hint.caution{border-left-color:#7300d3;background-color:#f8f2fd;color:#343a40;padding:0}.gdoc-hint.danger{border-left-color:#d50000;background-color:#fdf2f2;color:#343a40;padding:0}.gdoc-hint.warning{border-left-color:#d50000;background-color:#fdf2f2;color:#343a40;padding:0}.gdoc-hint__title{padding:.25rem 1rem;background-color:rgba(134,142,150,.05);font-weight:bold;color:rgba(52,58,64,.85)}.gdoc-hint__title i.fa::after{content:attr(title);font-style:normal;padding-left:1.5rem}.gdoc-hint__title i.fa{color:#000;background-size:auto 90%;background-repeat:no-repeat;filter:invert(30%);margin-left:-5px}.gdoc-hint__title i.fa.info{background-image:url(img/geekdoc-stack.svg#gdoc_info_outline)}.gdoc-hint__title i.fa.note{background-image:url(img/geekdoc-stack.svg#gdoc_info_outline)}.gdoc-hint__title i.fa.ok{background-image:url(img/geekdoc-stack.svg#gdoc_check_circle_outline)}.gdoc-hint__title i.fa.tip{background-image:url(img/geekdoc-stack.svg#gdoc_check_circle_outline)}.gdoc-hint__title i.fa.important{background-image:url(img/geekdoc-stack.svg#gdoc_error_outline)}.gdoc-hint__title i.fa.caution{background-image:url(img/geekdoc-stack.svg#gdoc_dangerous)}.gdoc-hint__title i.fa.danger{background-image:url(img/geekdoc-stack.svg#gdoc_fire)}.gdoc-hint__title i.fa.warning{background-image:url(img/geekdoc-stack.svg#gdoc_fire)}.gdoc-hint__title .gdoc-icon{width:1.5rem;height:1.5rem;margin-left:-5px}.gdoc-hint__text{padding:.25rem 1rem}.gdoc-hint .gdoc-page__anchor{display:none}.gdoc-mermaid{font-family:"Liberation Sans",sans-serif}.gdoc-mermaid>svg{height:100%;padding:.5rem}.gdoc-props__title,.gdoc-props__default{padding:0;margin:0;font-family:"Liberation Mono",monospace}.gdoc-props__meta{gap:.5em;line-height:normal;margin-bottom:.25rem}.gdoc-props__meta:hover .gdoc-page__anchor svg.gdoc-icon{color:var(--control-icons)}.gdoc-props__tag.info{border-color:#e8f4fb;background-color:#f3f9fd}.gdoc-props__tag.note{border-color:#e8f4fb;background-color:#f3f9fd}.gdoc-props__tag.ok{border-color:#e5faee;background-color:#f2fdf6}.gdoc-props__tag.tip{border-color:#e5faee;background-color:#f2fdf6}.gdoc-props__tag.important{border-color:#fbf5e9;background-color:#fdfaf4}.gdoc-props__tag.caution{border-color:#f1e6fb;background-color:#f8f2fd}.gdoc-props__tag.danger{border-color:#fbe6e6;background-color:#fdf2f2}.gdoc-props__tag.warning{border-color:#fbe6e6;background-color:#fdf2f2}.gdoc-props__tag{font-size:.875rem;font-weight:normal;background-color:#f8f9fa;border:1px solid #e9ecef;border-radius:.15rem;padding:.125rem .25rem;color:#343a40}.gdoc-props__default{font-size:.875rem}.gdoc-progress{margin-bottom:1rem}.gdoc-progress__label{padding:.25rem 0}.gdoc-progress__label--name{font-weight:bold}.gdoc-progress__wrap{background-color:var(--accent-color-lite);border-radius:1em;box-shadow:inset 0 0 0 1px var(--accent-color)}.gdoc-progress__bar{height:1em;border-radius:1em;background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.125) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.125) 50%, rgba(255, 255, 255, 0.125) 75%, transparent 75%, transparent);background-size:2.5em 2.5em;background-color:#205375 !important} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/mobile-79ddc617.min.css b/docs/themes/hugo-geekdoc/static/mobile-79ddc617.min.css new file mode 100644 index 000000000..abf3504d9 --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/mobile-79ddc617.min.css @@ -0,0 +1 @@ +@media screen and (max-width: 41rem){.gdoc-nav{margin-left:-18rem;font-size:16px}.gdoc-nav__control{display:inline-block}.gdoc-header svg.gdoc-icon{width:1.5rem;height:1.5rem}.gdoc-brand{font-size:1.5rem;line-height:1.5rem}.gdoc-brand__img{display:none}.gdoc-menu-header__items{display:none}.gdoc-menu-header__control,.gdoc-menu-header__home{display:flex}.gdoc-error{padding:6rem 1rem}.gdoc-error svg.gdoc-icon{width:6rem;height:6rem}.gdoc-error__message{padding-left:2rem}.gdoc-error__line{padding:.25rem 0}.gdoc-error__title{font-size:2rem}.gdoc-page__header .breadcrumb,.hidden-mobile{display:none}.flex-mobile-column{flex-direction:column}.flex-mobile-column.gdoc-columns{margin:2rem 0}.flex-mobile-column .gdoc-columns__content{min-width:auto;margin:0}#menu-control:checked~main .gdoc-nav nav,#menu-control:checked~main .gdoc-page{transform:translateX(18rem)}#menu-control:checked~main .gdoc-page{opacity:.25}#menu-control:checked~.gdoc-header .gdoc-nav__control svg.gdoc-icon.gdoc_menu{display:none}#menu-control:checked~.gdoc-header .gdoc-nav__control svg.gdoc-icon.gdoc_arrow_back{display:inline-block}#menu-header-control:checked~.gdoc-header .gdoc-brand{display:none}#menu-header-control:checked~.gdoc-header .gdoc-menu-header__items{display:flex}#menu-header-control:checked~.gdoc-header .gdoc-menu-header__control svg.gdoc-icon.gdoc_keyboard_arrow_left{display:none}} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/static/print-735ccc12.min.css b/docs/themes/hugo-geekdoc/static/print-735ccc12.min.css new file mode 100644 index 000000000..01994899b --- /dev/null +++ b/docs/themes/hugo-geekdoc/static/print-735ccc12.min.css @@ -0,0 +1 @@ +@media print{.gdoc-nav,.gdoc-footer .container span:not(:first-child),.gdoc-paging,.editpage{display:none}.gdoc-footer{border-top:1px solid #dee2e6}.gdoc-markdown pre{white-space:pre-wrap;overflow-wrap:break-word}.chroma code{border:1px solid #dee2e6;padding:.5rem !important;font-weight:normal !important}.gdoc-markdown code{font-weight:bold}a,a:visited{color:inherit !important;text-decoration:none !important}.gdoc-toc{flex:none}.gdoc-toc nav{position:relative;width:auto}.wrapper{display:block}.wrapper main{display:block}} \ No newline at end of file diff --git a/docs/themes/hugo-geekdoc/theme.toml b/docs/themes/hugo-geekdoc/theme.toml new file mode 100644 index 000000000..90b7cf59b --- /dev/null +++ b/docs/themes/hugo-geekdoc/theme.toml @@ -0,0 +1,12 @@ +name = "Geekdoc" +license = "MIT" +licenselink = "https://github.com/thegeeklab/hugo-geekdoc/blob/main/LICENSE" +description = "Hugo theme made for documentation" +homepage = "https://geekdocs.de/" +demosite = "https://geekdocs.de/" +tags = ["docs", "documentation", "responsive", "simple"] +min_version = "0.112.0" + +[author] + name = "Robert Kaussow" + homepage = "https://thegeeklab.de/" diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java index f01874ef8..bdd40cf7d 100644 --- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java +++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java @@ -3,6 +3,7 @@ import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.Unit; import java.io.IOException; @@ -14,6 +15,7 @@ public class Main { public static void main(String[] args) throws IOException, InterruptedException { + HistogramSnapshot.builder().gaugeHistogram(true).build(); JvmMetrics.builder().register(); // Note: uptime_seconds_total is not a great example: diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index fbe8ac4b7..7451e7c10 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -1055,7 +1055,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { "}"; //@formatter:on HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram() + .gaugeHistogram(true) .name("cache_size_bytes") .help("number of bytes in the cache") .unit(Unit.BYTES) @@ -1118,7 +1118,7 @@ public void testClassicGaugeHistogramMinimal() throws IOException { "}"; //@formatter:on HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram() + .gaugeHistogram(true) .name("queue_size_bytes") .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() .classicHistogramBuckets(ClassicHistogramBuckets.builder() @@ -1164,7 +1164,7 @@ public void testClassicGaugeHistogramCountAndSum() throws IOException { "}"; //@formatter:on HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram() + .gaugeHistogram(true) .name("queue_size_bytes") .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() .sum(27000) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index 742105e64..2e66c1a25 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -379,12 +379,13 @@ public Builder dataPoint(HistogramDataPointSnapshot dataPoint) { } /** - * Create a Gauge Histogram. The data model for Gauge Histograms is the same as for regular histograms, + * {@code true} indicates that this histogram is a gauge histogram. + * The data model for gauge histograms is the same as for regular histograms, * except that bucket values are semantically gauges and not counters. - * See
        openmetrics.io for more info on Gauge Histograms. + * See openmetrics.io for more info on gauge histograms. */ - public Builder gaugeHistogram() { - isGaugeHistogram = true; + public Builder gaugeHistogram(boolean isGaugeHistogram) { + this.isGaugeHistogram = isGaugeHistogram; return this; } diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index 725afc8b3..a728ef0e1 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -153,10 +153,8 @@ private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, b HistogramSnapshot.Builder histogram = HistogramSnapshot.builder() .name(samples.name) .help(samples.help) - .unit(convertUnit(samples)); - if (isGaugeHistogram) { - histogram.gaugeHistogram(); - } + .unit(convertUnit(samples)) + .gaugeHistogram(isGaugeHistogram); Map dataPoints = new HashMap<>(); Map> cumulativeBuckets = new HashMap<>(); Map exemplars = new HashMap<>(); From 95b9418f1edc7592f4a49af6776c7d8b83a9debd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 17:08:30 +0200 Subject: [PATCH 212/980] Add Javadoc as static content to Hugo docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/README.md | 28 +++++++++---- docs/content/_index.md | 6 ++- docs/data/menu/extra.yaml | 6 +++ docs/data/menu/more.yaml | 14 +++++++ docs/static/.gitignore | 1 + docs/static/custom.css | 39 +++++++++++++++++++ pom.xml | 20 +++------- prometheus-metrics-exposition-formats/pom.xml | 6 +++ 8 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 docs/data/menu/extra.yaml create mode 100644 docs/data/menu/more.yaml create mode 100644 docs/static/.gitignore create mode 100644 docs/static/custom.css diff --git a/docs/README.md b/docs/README.md index 5820df01f..3d53229c8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -17,8 +17,27 @@ Deploy to Github Pages Changes to the `main` branch will be deployed automatically with Github actions. -Set-up Notes ------------- +Update Javadoc +-------------- + +Javadoc are not checked-in to the Github repository. +They are generated on the fly by Github actions when the docs are updated. +To view locally, run the following: + +``` +# note that the 'compile' in the following command is necessary for Javadoc to detect the module structure +./mvnw clean compile javadoc:javadoc javadoc:aggregate +rm -r ./docs/static/api +mv ./target/site/apidocs ./docs/static/api +``` + +Update Geekdocs +--------------- + +The docs use the [Geekdocs](https://geekdocs.de/) theme. The theme is checked in to Github in the `./docs/themes/hugo-geekdoc/` folder. To update [Geekdocs](https://geekdocs.de/), remove the current folder and create a new one with the latest [release](https://github.com/thegeeklab/hugo-geekdoc/releases). There are no local modifications in `./docs/themes/hugo-geekdoc/`. + +Notes +----- Here's how the initial `docs/` folder was set up: @@ -30,8 +49,3 @@ curl -L https://github.com/thegeeklab/hugo-geekdoc/releases/download/v0.41.1/hug ``` Create the initial `hugo.toml` file as described in [https://geekdocs.de/usage/getting-started/](https://geekdocs.de/usage/getting-started/). - -Update Geekdocs ---------------- - -The docs use the [Geekdocs](https://geekdocs.de/) theme. The theme is checked in to Github in the `./docs/themes/hugo-geekdoc/` folder. To update [Geekdocs](https://geekdocs.de/), remove the current folder and create a new one with the latest [release](https://github.com/thegeeklab/hugo-geekdoc/releases). There are no local modifications in `./docs/themes/hugo-geekdoc/`. diff --git a/docs/content/_index.md b/docs/content/_index.md index cce8d5865..555f28fba 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,6 +2,10 @@ title: "client_java" --- +This is the documentation for the upcoming `client_java` 1.0.0 release. These docs are currently in progress. Target for the release is end of September 2023. + +<- the navigation on the left has the sections that are already available. + Brainstorming of potential topics: * Getting started @@ -22,7 +26,7 @@ Brainstorming of potential topics: * Servlet filter * OpenTelemetry * OpenTelemetry exporter - * Combining Prometheus `client_java` with the OpenTelemetry instrumentation agent. + * Combining Prometheus client java with the OpenTelemetry instrumentation agent. * Trace sampling and Exemplars * API comparision: OpenTelemetry vs Prometheus * Performance comparison: OpenTelemetry vs Prometheus diff --git a/docs/data/menu/extra.yaml b/docs/data/menu/extra.yaml new file mode 100644 index 000000000..ff5756bf8 --- /dev/null +++ b/docs/data/menu/extra.yaml @@ -0,0 +1,6 @@ +--- +header: + - name: GitHub + ref: https://github.com/prometheus/client_java + icon: gdoc_github + external: true diff --git a/docs/data/menu/more.yaml b/docs/data/menu/more.yaml new file mode 100644 index 000000000..5977fb969 --- /dev/null +++ b/docs/data/menu/more.yaml @@ -0,0 +1,14 @@ +--- +more: + - name: JavaDoc + ref: "/api" + external: true + icon: "gdoc_bookmark" + - name: Releases + ref: "https://github.com/prometheus/client_java/releases" + external: true + icon: "gdoc_download" + - name: Github + ref: "https://github.com/prometheus/client_java" + external: true + icon: "gdoc_github" diff --git a/docs/static/.gitignore b/docs/static/.gitignore new file mode 100644 index 000000000..eedd89b45 --- /dev/null +++ b/docs/static/.gitignore @@ -0,0 +1 @@ +api diff --git a/docs/static/custom.css b/docs/static/custom.css new file mode 100644 index 000000000..41ab7c562 --- /dev/null +++ b/docs/static/custom.css @@ -0,0 +1,39 @@ +/* + * Didn't find much time to create a theme yet, + * so there are just a few non-default settings for now. + */ +:root, +:root[color-theme="light"] { + --header-background: #222222; + --footer-background: #e6522c; + --footer-link-color: #ffffff; + --footer-link-color-visited: #ffffff; +} + +@media (prefers-color-scheme: light) { + :root { + --header-background: #222222; + --footer-background: #e6522c; + --footer-link-color: #ffffff; + --footer-link-color-visited: #ffffff; + } +} + +:root[color-theme="dark"] +{ + --header-background: #111c24; + --body-background: #1f1f21; + --footer-background: #e6522c; + --footer-link-color: #ffffff; + --footer-link-color-visited: #ffffff; +} + +@media (prefers-color-scheme: dark) { + :root { + --header-background: #111c24; + --body-background: #1f1f21; + --footer-background: #e6522c; + --footer-link-color: #ffffff; + --footer-link-color-visited: #ffffff; + } +} diff --git a/pom.xml b/pom.xml index 6c33f85fd..f5149e13f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + pom 4.0.0 @@ -224,25 +225,16 @@ maven-surefire-plugin - org.apache.maven.plugins maven-javadoc-plugin UTF-8 UTF-8 true - 8 - ${java.home}/bin/javadoc - src/main/java;src/main/generated + all + public + benchmarks,examples,integration-tests,integration_tests,,simpleclient,simpleclient_bom,simpleclient_caffeine,simpleclient_common,simpleclient_dropwizard,simpleclient_graphite_bridge,simpleclient_guava,simpleclient_hibernate,simpleclient_hotspot,simpleclient_httpserver,simpleclient_jetty,simpleclient_jetty_jdk8,simpleclient_log4j,simpleclient_log4j2,simpleclient_logback,simpleclient_pushgateway,simpleclient_servlet,simpleclient_servlet_common,simpleclient_servlet_jakarta,simpleclient_spring_boot,simpleclient_spring_web,simpleclient_tracer,simpleclient_vertx,simpleclient_vertx4 + io.prometheus.metrics.expositionformats.generated.* - - - generate-javadoc-site-report - site - - aggregate - - - maven-compiler-plugin diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index e580b408e..b187461d2 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -79,6 +79,12 @@ + + maven-javadoc-plugin + + src/main/java;src/main/generated + + From 2f39a224408454fa5f51661ad3dfaa90853c7ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 20:55:33 +0200 Subject: [PATCH 213/980] Add Github action to publish docs to Github pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .github/workflows/github-pages.yaml | 102 ++++++++++++++++++ docs/README.md | 8 ++ docs/content/_index.md | 2 +- docs/data/menu/more.yaml | 2 +- .../core/datapoints/StateSetDataPoint.java | 4 +- .../metrics/core/metrics/StateSet.java | 2 +- 6 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/github-pages.yaml diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml new file mode 100644 index 000000000..b3910f43c --- /dev/null +++ b/.github/workflows/github-pages.yaml @@ -0,0 +1,102 @@ +name: Deploy Documentation to Github Pages + +on: + # Runs on pushes targeting the 1.0.x branch + push: + branches: + - 1.0.x + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +# Default to bash +defaults: + run: + shell: bash + +jobs: + # Build job + build: + runs-on: ubuntu-latest + env: + HUGO_VERSION: 0.115.4 + JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 + steps: + - name: Install OpenJDK 17 + run: sudo apt-get -q install -y openjdk-17-jdk + - name: Make 17 the default java version + run: sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java + - name: Make 17 the default javadoc version + run: sudo update-alternatives --set javadoc /usr/lib/jvm/java-17-openjdk-amd64/bin/javadoc + - name: Print java and javadoc versions + run: | + echo 'java --version' && \ + java --version && \ + echo 'javadoc --version' && \ + javadoc --version && \ + echo 'echo $JAVA_HOME' && \ + echo $JAVA_HOME + - name: Install Hugo CLI + run: | + wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ + && sudo dpkg -i ${{ runner.temp }}/hugo.deb + #- name: Install Dart Sass + # run: sudo snap install dart-sass + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Build client_java + run: ./mvnw -B clean install -DskipTests + - name: Make Javadoc + run: ./mvnw -B compile javadoc:javadoc javadoc:aggregate + - name: Move the Javadoc to docs/static/api/ + run: mv ./target/site/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api + - name: Setup Pages + id: pages + uses: actions/configure-pages@v3 + - name: Install Node.js dependencies + run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" + working-directory: ./docs + - name: Build with Hugo + env: + # For maximum backward compatibility with Hugo modules + HUGO_ENVIRONMENT: production + HUGO_ENV: production + run: | + hugo \ + --gc \ + --minify \ + --baseURL "${{ steps.pages.outputs.base_url }}/" + working-directory: ./docs + - name: ls ./docs/public/api + run: echo 'ls ./docs/public/api' && ls ./docs/public/api + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: ./docs/public + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/docs/README.md b/docs/README.md index 3d53229c8..2868196d5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -31,6 +31,14 @@ rm -r ./docs/static/api mv ./target/site/apidocs ./docs/static/api ``` +Github pages are in the `/client_java/` folder, so we link to `/client_java/api` rather than `/api`. +To make JavaDoc work locally, create a link: + +``` +mkdir ./docs/static/client_java +ln -s ../api ./docs/static/client_java/api +``` + Update Geekdocs --------------- diff --git a/docs/content/_index.md b/docs/content/_index.md index 555f28fba..ae33a616e 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,7 +2,7 @@ title: "client_java" --- -This is the documentation for the upcoming `client_java` 1.0.0 release. These docs are currently in progress. Target for the release is end of September 2023. +This is the documentation for the upcoming Prometheus Java metrics 1.0.0 release. These docs are currently in progress. Target for the release is end of September 2023. <- the navigation on the left has the sections that are already available. diff --git a/docs/data/menu/more.yaml b/docs/data/menu/more.yaml index 5977fb969..ee55dc634 100644 --- a/docs/data/menu/more.yaml +++ b/docs/data/menu/more.yaml @@ -1,7 +1,7 @@ --- more: - name: JavaDoc - ref: "/api" + ref: "/client_java/api" external: true icon: "gdoc_bookmark" - name: Releases diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java index 8ad6ecf37..7dd8f68a4 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java @@ -18,14 +18,14 @@ public interface StateSetDataPoint extends DataPoint { void setFalse(String state); /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class>)}. + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. */ default void setTrue(Enum state) { setTrue(state.toString()); } /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class>)}. + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. */ default void setFalse(Enum state) { setFalse(state.toString()); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java index f45b91152..532cfa506 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -27,7 +27,7 @@ * this.name = name; * } * - * @Override + * // Override * public String toString() { * return name; * } From d3db8b2375d0483e8074b7141ffb4ba2c7867944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 22:49:58 +0200 Subject: [PATCH 214/980] Temporarily add shaded dependencies to prepare for release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f5149e13f..743945723 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - + prometheus-metrics-shaded-dependencies examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 170007cd2..191f0e789 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.0.0-alpha-5 + ${project.version} From 204f21373529bc6cb029118714015b3b2dcecbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 22:52:57 +0200 Subject: [PATCH 215/980] [maven-release-plugin] prepare release v1.0.0-beta-1 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 7 +++---- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 4 ++-- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 69 files changed, 73 insertions(+), 74 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index acd2e797f..03baedb75 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index fc0c0f07c..02716d200 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 54c104aea..432465092 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 6cc15447b..6458fc3f3 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 10d7fe9f2..7bc1ff72a 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 574f38666..a5f6e8661 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 79b21620f..b6b416d78 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-exporter-servlet-tomcat diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 271e7b708..3241f54f8 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 0fd00060b..5a0a6ce9b 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index eef11aa4e..f5dbf79ae 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index b3366d7dc..c45113bb7 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 65710f98d..4d5577c3a 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 60a3560c4..3ca2843a5 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index aeffd089f..3ae8ccb1c 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 71f222964..5f066f4dd 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-beta-1 diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index e42f5c6ea..53314b1ff 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 5d986988d..6822df64b 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 4616c634c..5c4307311 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index 55a934640..f203ce2bb 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index ef1fd59dc..01c756da1 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index 02eecbc64..c26573b7b 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 3492e71ca..98b1885b8 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index d476fb876..d8ef7a621 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index a29bd69ab..f36983ce8 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 integration_tests diff --git a/pom.xml b/pom.xml index 743945723..48ab75486 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + pom 4.0.0 io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -26,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0-beta-1 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 239f8aa35..45adb1d98 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index b417e91c1..df18ecf94 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index d8a2dc15c..c8885405a 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 2c4659f94..1662bfd39 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 191f0e789..16e49ae5e 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 83a717400..d591bc73e 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index ec4e820ef..769e8b539 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 9811b2fc5..3ef353920 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 415914805..a891b4c2a 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 811bd1bb5..6a9ed2124 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 14cf5b2fb..237eb0010 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index c24b0172b..83876e55b 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 6a753d6e2..af3c9877d 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-simpleclient-bridge @@ -72,7 +72,7 @@ io.prometheus prometheus-metrics-config - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 compile diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 1ab787324..5ab4d426e 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index a59c752e6..bffdfed69 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 2777b661c..05ae75f4d 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 15348e957..8aa982a95 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index bf4095386..f33d16b4e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index f50bf759a..779fe77db 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index fda594683..86427494f 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index ddfbf163e..e797add29 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 6e91ceb9f..94a0c18a7 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index 6912f198a..c310dea7b 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 5e84e87b3..4d3ae0933 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index 47a84ad14..f34b44baa 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index 3dd9bd261..c48734317 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index 7e996cc9c..a15eabf69 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index 1240afed4..bd0edf541 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 4d0eca0f2..2addb1533 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 013dd7cec..458d481f1 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 3e66c9c28..9919fd0b7 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index 7058f3de0..b560b7700 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 6b95c4dcc..95b1011ec 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index 13166d868..acc1468ad 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 6dfc9196d..7f8ee608f 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 63093354b..86c0db3a3 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 8a519de26..26b8b8d68 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index 6c073cc76..bb9cef63d 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index fa683d260..7112849b6 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 841adb6b9..664060837 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index 63109ec1b..d5d7ef108 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index 637b46c25..fe6fa8f3e 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index b8d30a0a6..b0ab27847 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 6046d6532..87962b1f4 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-alpha-6-SNAPSHOT + 1.0.0-beta-1 simpleclient_vertx4 From 7e22ff76742b366a653b0993b456887bcd8a8b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 22:53:01 +0200 Subject: [PATCH 216/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- integration_tests/it_common/pom.xml | 2 +- integration_tests/it_exemplars_otel_agent/pom.xml | 2 +- integration_tests/it_exemplars_otel_sdk/pom.xml | 2 +- integration_tests/it_java_versions/pom.xml | 2 +- integration_tests/it_log4j2/pom.xml | 2 +- integration_tests/it_pushgateway/pom.xml | 2 +- integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- integration_tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 4 ++-- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- simpleclient/pom.xml | 2 +- simpleclient_bom/pom.xml | 2 +- simpleclient_caffeine/pom.xml | 2 +- simpleclient_common/pom.xml | 2 +- simpleclient_dropwizard/pom.xml | 2 +- simpleclient_graphite_bridge/pom.xml | 2 +- simpleclient_guava/pom.xml | 2 +- simpleclient_hibernate/pom.xml | 2 +- simpleclient_hotspot/pom.xml | 2 +- simpleclient_httpserver/pom.xml | 2 +- simpleclient_jetty/pom.xml | 2 +- simpleclient_jetty_jdk8/pom.xml | 2 +- simpleclient_log4j/pom.xml | 2 +- simpleclient_log4j2/pom.xml | 2 +- simpleclient_logback/pom.xml | 2 +- simpleclient_pushgateway/pom.xml | 2 +- simpleclient_servlet/pom.xml | 2 +- simpleclient_servlet_common/pom.xml | 2 +- simpleclient_servlet_jakarta/pom.xml | 2 +- simpleclient_spring_web/pom.xml | 2 +- simpleclient_tracer/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_common/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel/pom.xml | 2 +- simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml | 2 +- simpleclient_vertx/pom.xml | 2 +- simpleclient_vertx4/pom.xml | 2 +- 69 files changed, 72 insertions(+), 72 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 03baedb75..79d6a9439 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 02716d200..766239bb9 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 432465092..994abd895 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 6458fc3f3..f2dee4476 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 7bc1ff72a..84ae4dfe8 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index a5f6e8661..05feaa7e8 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index b6b416d78..3dbc14da3 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 3241f54f8..46b76f86b 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 5a0a6ce9b..928f553d4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index f5dbf79ae..af01b17a1 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index c45113bb7..2e15dbd60 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 4d5577c3a..10d6db685 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 3ca2843a5..e7cec4152 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 3ae8ccb1c..44f065e29 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 5f066f4dd..2d8b7b851 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-beta-1 + HEAD diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 53314b1ff..ce770704b 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT integration-tests diff --git a/integration_tests/it_common/pom.xml b/integration_tests/it_common/pom.xml index 6822df64b..ba6842dea 100644 --- a/integration_tests/it_common/pom.xml +++ b/integration_tests/it_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_common diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/integration_tests/it_exemplars_otel_agent/pom.xml index 5c4307311..3453178c4 100644 --- a/integration_tests/it_exemplars_otel_agent/pom.xml +++ b/integration_tests/it_exemplars_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_exemplars_otel_agent diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/integration_tests/it_exemplars_otel_sdk/pom.xml index f203ce2bb..4ef73a73e 100644 --- a/integration_tests/it_exemplars_otel_sdk/pom.xml +++ b/integration_tests/it_exemplars_otel_sdk/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_exemplars_otel_sdk diff --git a/integration_tests/it_java_versions/pom.xml b/integration_tests/it_java_versions/pom.xml index 01c756da1..7ab040bad 100644 --- a/integration_tests/it_java_versions/pom.xml +++ b/integration_tests/it_java_versions/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_java_versions diff --git a/integration_tests/it_log4j2/pom.xml b/integration_tests/it_log4j2/pom.xml index c26573b7b..029786e82 100644 --- a/integration_tests/it_log4j2/pom.xml +++ b/integration_tests/it_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_log4j2 diff --git a/integration_tests/it_pushgateway/pom.xml b/integration_tests/it_pushgateway/pom.xml index 98b1885b8..2eba31efa 100644 --- a/integration_tests/it_pushgateway/pom.xml +++ b/integration_tests/it_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_pushgateway diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index d8ef7a621..71e8c536a 100644 --- a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration_tests - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT it_servlet_jakarta_exporter_webxml diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml index f36983ce8..28bba0221 100644 --- a/integration_tests/pom.xml +++ b/integration_tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT integration_tests diff --git a/pom.xml b/pom.xml index 48ab75486..ebd1ca40d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0-beta-1 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 45adb1d98..7d556ad5f 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index df18ecf94..d24afafe1 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index c8885405a..7846bd500 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 1662bfd39..13edaa55f 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 16e49ae5e..f7cad4ce6 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index d591bc73e..1a9411d8c 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 769e8b539..75e07f6d1 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 3ef353920..0212c043b 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index a891b4c2a..b81fb509d 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 6a9ed2124..508185dfa 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 237eb0010..3484a5435 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 83876e55b..d136434d5 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index af3c9877d..b4480483b 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-simpleclient-bridge @@ -72,7 +72,7 @@ io.prometheus prometheus-metrics-config - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT compile diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 5ab4d426e..90927f4d6 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index bffdfed69..d1571414c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 05ae75f4d..22995a855 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 8aa982a95..af73f9d22 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index f33d16b4e..5f6cee34f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/simpleclient/pom.xml b/simpleclient/pom.xml index 779fe77db..2bc641241 100644 --- a/simpleclient/pom.xml +++ b/simpleclient/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient diff --git a/simpleclient_bom/pom.xml b/simpleclient_bom/pom.xml index 86427494f..417c679bd 100644 --- a/simpleclient_bom/pom.xml +++ b/simpleclient_bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_bom diff --git a/simpleclient_caffeine/pom.xml b/simpleclient_caffeine/pom.xml index e797add29..73529822b 100644 --- a/simpleclient_caffeine/pom.xml +++ b/simpleclient_caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_caffeine diff --git a/simpleclient_common/pom.xml b/simpleclient_common/pom.xml index 94a0c18a7..8d7722bfe 100644 --- a/simpleclient_common/pom.xml +++ b/simpleclient_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_common diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient_dropwizard/pom.xml index c310dea7b..4366d9e15 100644 --- a/simpleclient_dropwizard/pom.xml +++ b/simpleclient_dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_dropwizard diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient_graphite_bridge/pom.xml index 4d3ae0933..e9f432cc1 100644 --- a/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient_graphite_bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_graphite_bridge diff --git a/simpleclient_guava/pom.xml b/simpleclient_guava/pom.xml index f34b44baa..076491963 100644 --- a/simpleclient_guava/pom.xml +++ b/simpleclient_guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_guava diff --git a/simpleclient_hibernate/pom.xml b/simpleclient_hibernate/pom.xml index c48734317..ca99206a4 100644 --- a/simpleclient_hibernate/pom.xml +++ b/simpleclient_hibernate/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_hibernate diff --git a/simpleclient_hotspot/pom.xml b/simpleclient_hotspot/pom.xml index a15eabf69..16305376d 100644 --- a/simpleclient_hotspot/pom.xml +++ b/simpleclient_hotspot/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_hotspot diff --git a/simpleclient_httpserver/pom.xml b/simpleclient_httpserver/pom.xml index bd0edf541..d34088965 100644 --- a/simpleclient_httpserver/pom.xml +++ b/simpleclient_httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_httpserver diff --git a/simpleclient_jetty/pom.xml b/simpleclient_jetty/pom.xml index 2addb1533..24aa35902 100644 --- a/simpleclient_jetty/pom.xml +++ b/simpleclient_jetty/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_jetty diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient_jetty_jdk8/pom.xml index 458d481f1..c696d7236 100644 --- a/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient_jetty_jdk8/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_jetty_jdk8 diff --git a/simpleclient_log4j/pom.xml b/simpleclient_log4j/pom.xml index 9919fd0b7..bfe2be75a 100644 --- a/simpleclient_log4j/pom.xml +++ b/simpleclient_log4j/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_log4j diff --git a/simpleclient_log4j2/pom.xml b/simpleclient_log4j2/pom.xml index b560b7700..c8afc9da1 100644 --- a/simpleclient_log4j2/pom.xml +++ b/simpleclient_log4j2/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_log4j2 diff --git a/simpleclient_logback/pom.xml b/simpleclient_logback/pom.xml index 95b1011ec..96f4fb34d 100644 --- a/simpleclient_logback/pom.xml +++ b/simpleclient_logback/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_logback diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient_pushgateway/pom.xml index acc1468ad..7553c7d29 100644 --- a/simpleclient_pushgateway/pom.xml +++ b/simpleclient_pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_pushgateway diff --git a/simpleclient_servlet/pom.xml b/simpleclient_servlet/pom.xml index 7f8ee608f..7f6b843de 100644 --- a/simpleclient_servlet/pom.xml +++ b/simpleclient_servlet/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_servlet diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient_servlet_common/pom.xml index 86c0db3a3..31d477e71 100644 --- a/simpleclient_servlet_common/pom.xml +++ b/simpleclient_servlet_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_servlet_common diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient_servlet_jakarta/pom.xml index 26b8b8d68..186dd0526 100644 --- a/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient_servlet_jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_servlet_jakarta diff --git a/simpleclient_spring_web/pom.xml b/simpleclient_spring_web/pom.xml index bb9cef63d..7591085fa 100644 --- a/simpleclient_spring_web/pom.xml +++ b/simpleclient_spring_web/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_spring_web diff --git a/simpleclient_tracer/pom.xml b/simpleclient_tracer/pom.xml index 7112849b6..431603c76 100644 --- a/simpleclient_tracer/pom.xml +++ b/simpleclient_tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_tracer diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/simpleclient_tracer/simpleclient_tracer_common/pom.xml index 664060837..26d5328ed 100644 --- a/simpleclient_tracer/simpleclient_tracer_common/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_common/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_tracer_common diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml index d5d7ef108..1a31b99b1 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_tracer_otel diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml index fe6fa8f3e..aa92cde17 100644 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml +++ b/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus simpleclient_tracer - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_tracer_otel_agent diff --git a/simpleclient_vertx/pom.xml b/simpleclient_vertx/pom.xml index b0ab27847..2a91f20c8 100644 --- a/simpleclient_vertx/pom.xml +++ b/simpleclient_vertx/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_vertx diff --git a/simpleclient_vertx4/pom.xml b/simpleclient_vertx4/pom.xml index 87962b1f4..5e365bd2a 100644 --- a/simpleclient_vertx4/pom.xml +++ b/simpleclient_vertx4/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-1 + 1.0.0-beta-2-SNAPSHOT simpleclient_vertx4 From 787a01444a2c79179e4cefd22f6105ab17b73eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 16 Sep 2023 23:32:29 +0200 Subject: [PATCH 217/980] Exclude shaded dependencies from the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ebd1ca40d..0aecb9e0d 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - prometheus-metrics-shaded-dependencies + examples integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index f7cad4ce6..e3b78f14b 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - ${project.version} + 1.0.0-beta-1 From a1c777b8c7aca72379bda4cc2d407fa7c07c5085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 17 Sep 2023 10:46:06 +0200 Subject: [PATCH 218/980] Add doc on performance optimization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/getting-started/performance.md | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/content/getting-started/performance.md diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md new file mode 100644 index 000000000..1f3c49d3c --- /dev/null +++ b/docs/content/getting-started/performance.md @@ -0,0 +1,36 @@ +--- +title: Performance +weight: 6 +--- + +For high performance applications, we recommend to specify label values only once, and then use the data point directly. + +This applies to all metric types. Let's use a counter as an example here: + +```java +Counter requestCount = Counter.builder() + .name("requests_total") + .help("total number of requests") + .labelNames("path", "status") + .register(); +``` + +You could increment the counter above like this: + +```java +requestCount.labelValue("/", "200").inc(); +``` + +However, the line above does not only increment the counter, it also lookus up the label values to find the right data point. + +In high performance applications you can optimize this by looking up the data point only once: + +```java +CounterDataPoint successfulCalls = requestCount.labelValues("/", "200"); +``` + +Now, you can increment the data point directly, which is a highly optimized operation: + +```java +successfulCalls.inc(); +``` From 820c696e6125f9e8df476c7e34bf01f35234213c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 17 Sep 2023 21:11:12 +0200 Subject: [PATCH 219/980] Remove accidentally added line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../java/io/prometheus/metrics/examples/httpserver/Main.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java index bdd40cf7d..f01874ef8 100644 --- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java +++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java @@ -3,7 +3,6 @@ import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; -import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.Unit; import java.io.IOException; @@ -15,7 +14,6 @@ public class Main { public static void main(String[] args) throws IOException, InterruptedException { - HistogramSnapshot.builder().gaugeHistogram(true).build(); JvmMetrics.builder().register(); // Note: uptime_seconds_total is not a great example: From 12adefe003d6a90b761258a75683ca1cced91297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 17 Sep 2023 23:18:45 +0200 Subject: [PATCH 220/980] Add exporters documentation --- docs/content/_index.md | 10 ++- docs/content/exporters/_index.md | 4 + docs/content/exporters/filter.md | 18 +++++ docs/content/exporters/formats.md | 26 ++++++ docs/content/exporters/httpserver.md | 37 +++++++++ docs/content/exporters/servlet.md | 40 ++++++++++ docs/content/exporters/spring.md | 80 +++++++++++++++++++ docs/content/getting-started/metric-types.md | 2 +- .../config/ExporterHttpServerProperties.java | 2 - 9 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 docs/content/exporters/_index.md create mode 100644 docs/content/exporters/filter.md create mode 100644 docs/content/exporters/formats.md create mode 100644 docs/content/exporters/httpserver.md create mode 100644 docs/content/exporters/servlet.md create mode 100644 docs/content/exporters/spring.md diff --git a/docs/content/_index.md b/docs/content/_index.md index ae33a616e..2fda09ae1 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,9 +2,13 @@ title: "client_java" --- -This is the documentation for the upcoming Prometheus Java metrics 1.0.0 release. These docs are currently in progress. Target for the release is end of September 2023. +This is the documentation for the upcoming [Prometheus client_java 1.0.0](https://github.com/prometheus/client_java) release. -<- the navigation on the left has the sections that are already available. +These docs are currently in progress. Source code is on the [1.0.x](https://github.com/prometheus/client_java/tree/1.0.x) feature branch. + +Target for the release is end of September 2023. + + diff --git a/docs/content/exporters/_index.md b/docs/content/exporters/_index.md new file mode 100644 index 000000000..796db3ff3 --- /dev/null +++ b/docs/content/exporters/_index.md @@ -0,0 +1,4 @@ +--- +title: Exporters +weight: 2 +--- diff --git a/docs/content/exporters/filter.md b/docs/content/exporters/filter.md new file mode 100644 index 000000000..32dc0a56d --- /dev/null +++ b/docs/content/exporters/filter.md @@ -0,0 +1,18 @@ +--- +title: Filter +weight: 2 +--- + +All exporters support a `name[]` URL parameter for querying only specific metric names. Examples: + +* `/metrics?name[]=jvm_threads_current` will query the metric named `jvm_threads_current`. +* `/metrics?name[]=jvm_threads_current&name[]=jvm_threads_daemon` will query two metrics, `jvm_threads_current` and `jvm_threads_daemon`. + +Add the following to the scape job configuration in `prometheus.yml` to make the Prometheus server send the `name[]` parameter: + +```yaml +params: + name[]: + - jvm_threads_current + - jvm_threads_daemon +``` diff --git a/docs/content/exporters/formats.md b/docs/content/exporters/formats.md new file mode 100644 index 000000000..fc78ec963 --- /dev/null +++ b/docs/content/exporters/formats.md @@ -0,0 +1,26 @@ +--- +title: Formats +weight: 1 +--- + +All exporters the following exposition formats: + +* OpenMetrics text format +* Prometheus text format +* Prometheus protobuf format + +Moreover, gzip encoding is supported for each of these formats. + +Scraping with a Prometheus server +--------------------------------- + +The Prometheus server sends an `Accept` header to specify which format is requested. By default, the Prometheus server will scrape OpenMetrics text format with gzip encoding. If the Prometheus server is started with `--enable-feature=native-histograms`, it will scrape Prometheus protobuf format instead. + +Viewing with a Web Browser +-------------------------- + +If you view the `/metrics` endpoint with your Web browser you will see Prometheus text format. For quick debugging of the other formats, exporters provide a `debug` URL parameter: + +* `/metrics?debug=openmetrics`: View OpenMetrics text format. +* `/metrics?debug=text`: View Prometheus text format. +* `/metrics?debug=prometheus-protobuf`: View a text representation of the Prometheus protobuf format. diff --git a/docs/content/exporters/httpserver.md b/docs/content/exporters/httpserver.md new file mode 100644 index 000000000..17824775f --- /dev/null +++ b/docs/content/exporters/httpserver.md @@ -0,0 +1,37 @@ +--- +title: HTTPServer +weight: 3 +--- + +The `HTTPServer` is a standalone server for exposing a metric endpoint. A minimal example application for `HTTPServer` can be found in the [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory. + +```java +HTTPServer server = HTTPServer.builder() + .port(9400) + .buildAndStart(); +``` + +By default, `HTTPServer` binds to any IP address, you can change this with [hostname()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#hostname(java.lang.String)) or [inetAddress()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#inetAddress(java.net.InetAddress)). + +`HTTPServer` is configured with three endoints: + +* `/metrics` for Prometheus scraping. +* `/-/healthy` for simple health checks. +* `/` the default handler is a static HTML page. + +The default handler can be changed with [defaultHandler()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#defaultHandler(com.sun.net.httpserver.HttpHandler)). + +Authentication and HTTPS +------------------------ + +* [authenticator()](https://prometheus.github.io/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#authenticator(com.sun.net.httpserver.Authenticator)) is for configuring authentication. +* [httpsConfigurator()](https://prometheus.github.io/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#httpsConfigurator(com.sun.net.httpserver.HttpsConfigurator)) is for configuring HTTPS. + +You can find an example of authentication and SSL in the [jmx_exporter](https://github.com/prometheus/jmx_exporter). + +Properties +---------- + +See _config_ section (_todo_) on runtime configuration options. + +* `io.prometheus.exporter.httpServer.port`: The port to bind to. diff --git a/docs/content/exporters/servlet.md b/docs/content/exporters/servlet.md new file mode 100644 index 000000000..36a5161cf --- /dev/null +++ b/docs/content/exporters/servlet.md @@ -0,0 +1,40 @@ +--- +title: Servlet +weight: 4 +--- + +The [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) is a [Jakarta Servlet](https://jakarta.ee/specifications/servlet/) for exposing a metric endpoint. + +web.xml +------- + +The old-school way of configuring a servlet is in a `web.xml` file: + +```xml + + + + prometheus-metrics + io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet + + + prometheus-metrics + /metrics + + +``` + +Programmatic +------------ + +Today, most Servlet applications use an embedded Servlet container and configure Servlets programmatically rather than via `web.xml`. +The API for that depends on the Servlet container. +The [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory has an example of an embedded [Tomcat](https://tomcat.apache.org/) container with the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) configured. + +Spring +------ + +You can use the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) in Spring applications. See [our Spring doc]({{< relref "spring.md" >}}). diff --git a/docs/content/exporters/spring.md b/docs/content/exporters/spring.md new file mode 100644 index 000000000..e2c0a4f64 --- /dev/null +++ b/docs/content/exporters/spring.md @@ -0,0 +1,80 @@ +--- +title: Spring +weight: 5 +--- + +Alternative: Use Spring's Built-in Metrics Library +-------------------------------------------------- + +[Spring Boot](https://spring.io/projects/spring-boot) has a built-in metric library named [Micrometer](https://micrometer.io/), which supports Prometheus exposition format and can be set up in three simple steps: + +1. Add the `org.springframework.boot:spring-boot-starter-actuator` dependency. +2. Add the `io.micrometer:micrometer-registry-prometheus` as a _runtime_ dependency. +3. Enable the Prometheus endpoint by adding the line `management.endpoints.web.exposure.include=prometheus` to `application.properties`. + +Note that Spring's default Prometheus endpoint is `/actuator/prometheus`, not `/metrics`. + +In most cases the built-in Spring metrics library will work for you and you don't need the Prometheus Java library in Spring applications. + +Use the Prometheus Metrics Library in Spring +-------------------------------------------- + +However, you may have your reasons why you want to use the Prometheus metrics library in Spring anyway. Maybe you want full support for all Prometheus metric types, or you want to use the new Prometheus native histograms. + +The easiest way to use the Prometheus metrics library in Spring is to configure the [PrometheusMetricsServlet](http://localhost:1313/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics. + +Dependencies: + +* `prometheus-metrics-core`: The core metrics library. +* `prometheus-metrics-exporter-servlet-jakarta`: For providing the `/metrics` endpoint. +* `prometheus-metrics-instrumentation-jvm`: Optional - JVM metrics + +The following is the complete source code of a Spring Boot REST service using the Prometheus metrics library: + +```java +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class DemoApplication { + + private static final Counter requestCount = Counter.builder() + .name("requests_total") + .register(); + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + JvmMetrics.builder().register(); + } + + @GetMapping("/") + public String sayHello() throws InterruptedException { + requestCount.inc(); + return "Hello, World!\n"; + } + + @Bean + public ServletRegistrationBean createPrometheusMetricsEndpoint() { + return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); + } +} +``` + +The important part are the last three lines: They configure the [PrometheusMetricsServlet](http://localhost:1313/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics on `/metrics`: + +```java +@Bean +public ServletRegistrationBean createPrometheusMetricsEndpoint() { + return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); +} +``` + +The example provides a _Hello, world!_ endpoint on [http://localhost:8080](http://localhost:8080), and Prometheus metrics on [http://localhost:8080/metrics](http://localhost:8080/metrics). diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index 5ffb02777..c48f8025e 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -13,7 +13,7 @@ Counter Counter is the most common and useful metric type. Counters can only increase, but never decrease. In the Prometheus query language, the [rate()](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) function is often used for counters to calculate the average increase per second. {{< hint type=note >}} -Counter values do not need to be integers. In many cases counters are used to count the number of events (like the number of requests), and in that case the counter value will be an integer. However, counters can also be used for something like "total time spent doing something" in which case the counter value is a floating point number. +Counter values do not need to be integers. In many cases counters represent a number of events (like the number of requests), and in that case the counter value is an integer. However, counters can also be used for something like "total time spent doing something" in which case the counter value is a floating point number. {{< /hint >}} Here's an example of a counter: diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java index fd7d9aa4b..c458d69d1 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java @@ -7,8 +7,6 @@ */ public class ExporterHttpServerProperties { - // TODO: Not used yet, will be used when we port the simpleclient_httpserver module to the new data model. - private static final String PORT = "port"; private final Integer port; From 70c776a2668b17717e950b8c874b3b842dbae867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 18 Sep 2023 14:12:52 +0200 Subject: [PATCH 221/980] Fix HTTPServer example pom.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- examples/example-exporter-httpserver/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 84ae4dfe8..c54b1f720 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -64,7 +64,7 @@ - io.prometheus.metrics.examples.simpleclient.Main + io.prometheus.metrics.examples.httpserver.Main From af7dd680fb1399f5117189608093b2b0c48f4d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 18 Sep 2023 17:53:37 +0200 Subject: [PATCH 222/980] Remove workaround for github.com/prometheus/prometheus/issues/12553 --- .../metrics/core/metrics/HistogramTest.java | 21 ++++++++++++--- .../PrometheusProtobufWriter.java | 26 +++++++++---------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index c937cef9e..987e39395 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -669,13 +669,26 @@ public void testDefaults() throws IOException { Histogram histogram = Histogram.builder().name("test").build(); histogram.observe(0.5); HistogramSnapshot snapshot = histogram.collect(); - String expectedNative = "" + + String expectedProtobuf = "" + "name: \"test\" " + "type: HISTOGRAM " + "metric { " + "histogram { " + "sample_count: 1 " + "sample_sum: 0.5 " + + // default has both, native and classic buckets + "bucket { cumulative_count: 0 upper_bound: 0.005 } " + + "bucket { cumulative_count: 0 upper_bound: 0.01 } " + + "bucket { cumulative_count: 0 upper_bound: 0.025 } " + + "bucket { cumulative_count: 0 upper_bound: 0.05 } " + + "bucket { cumulative_count: 0 upper_bound: 0.1 } " + + "bucket { cumulative_count: 0 upper_bound: 0.25 } " + + "bucket { cumulative_count: 1 upper_bound: 0.5 } " + + "bucket { cumulative_count: 1 upper_bound: 1.0 } " + + "bucket { cumulative_count: 1 upper_bound: 2.5 } " + + "bucket { cumulative_count: 1 upper_bound: 5.0 } " + + "bucket { cumulative_count: 1 upper_bound: 10.0 } " + + "bucket { cumulative_count: 1 upper_bound: Infinity } " + // default native schema is 5 "schema: 5 " + // default zero threshold is 2^-128 @@ -684,7 +697,7 @@ public void testDefaults() throws IOException { "positive_span { offset: -32 length: 1 } " + "positive_delta: 1 " + "} }"; - String expectedClassic = "" + + String expectedTextFormat = "" + // default classic buckets "# TYPE test histogram\n" + "test_bucket{le=\"0.005\"} 0\n" + @@ -705,13 +718,13 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - Assert.assertEquals(expectedNative, TextFormat.printer().shortDebugString(protobufData)); + Assert.assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expectedClassic, out.toString()); + Assert.assertEquals(expectedTextFormat, out.toString()); } @Test diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index da421a980..090ac2a89 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -164,21 +164,19 @@ private Metrics.Metric.Builder convert(HistogramSnapshot.HistogramDataPointSnaps addBuckets(histogramBuilder, data.getNativeBucketsForPositiveValues(), +1); addBuckets(histogramBuilder, data.getNativeBucketsForNegativeValues(), -1); - // Add a single +Inf bucket for the exemplar. - // It is currently not possible to have more than one exemplar in a native histogram, - // see https://cloud-native.slack.com/archives/C02KR205UMU/p1688414381799849 - Exemplar exemplar = data.getExemplars().getLatest(); - if (exemplar != null) { - Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() - .setCumulativeCount(getNativeCount(data)) - .setUpperBound(Double.POSITIVE_INFINITY); - bucketBuilder.setExemplar(convert(exemplar)); - histogramBuilder.addBucket(bucketBuilder); + if (!data.hasClassicHistogramData()) { // native only + // Add a single +Inf bucket for the exemplar. + Exemplar exemplar = data.getExemplars().getLatest(); + if (exemplar != null) { + Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() + .setCumulativeCount(getNativeCount(data)) + .setUpperBound(Double.POSITIVE_INFINITY); + bucketBuilder.setExemplar(convert(exemplar)); + histogramBuilder.addBucket(bucketBuilder); + } } - } else if (data.hasClassicHistogramData()) { - - // Once native histograms support multiple exemplars the above can be changed from "else if" to "if", - // so that we always add the complete classic buckets and exemplars. + } + if (data.hasClassicHistogramData()) { ClassicHistogramBuckets buckets = data.getClassicBuckets(); double lowerBound = Double.NEGATIVE_INFINITY; From dd43c3462b0246c3e4408361cceefaeafd45beb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 18 Sep 2023 22:21:53 +0200 Subject: [PATCH 223/980] Add native histogram example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-native-histogram/README.md | 30 + .../docker-compose.yaml | 27 + .../grafana-dashboard-classic-histogram.json | 572 ++++++++++++++++++ .../grafana-dashboard-native-histogram.json | 500 +++++++++++++++ .../docker-compose/grafana-dashboards.yaml | 13 + .../docker-compose/grafana-datasources.yaml | 8 + .../docker-compose/prometheus.yml | 8 + examples/example-native-histogram/pom.xml | 76 +++ .../examples/nativehistogram/Main.java | 39 ++ examples/pom.xml | 1 + 11 files changed, 1275 insertions(+), 1 deletion(-) create mode 100644 examples/example-native-histogram/README.md create mode 100644 examples/example-native-histogram/docker-compose.yaml create mode 100644 examples/example-native-histogram/docker-compose/grafana-dashboard-classic-histogram.json create mode 100644 examples/example-native-histogram/docker-compose/grafana-dashboard-native-histogram.json create mode 100644 examples/example-native-histogram/docker-compose/grafana-dashboards.yaml create mode 100644 examples/example-native-histogram/docker-compose/grafana-datasources.yaml create mode 100644 examples/example-native-histogram/docker-compose/prometheus.yml create mode 100644 examples/example-native-histogram/pom.xml create mode 100644 examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index c54b1f720..19bece513 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -10,7 +10,7 @@ example-exporter-httpserver - >Example - HTTPServer Exporter + Example - HTTPServer Exporter Prometheus Metrics Example using the HTTPServer for exposing the metrics endpoint diff --git a/examples/example-native-histogram/README.md b/examples/example-native-histogram/README.md new file mode 100644 index 000000000..ff2a81dab --- /dev/null +++ b/examples/example-native-histogram/README.md @@ -0,0 +1,30 @@ +# Native Histogram End-to-End Example + +## Build + +This example is built as part of the `client_java` project. + +``` +./mvnw package +``` + +This should create the file `./examples/example-native-histogram/target/example-native-histogram.jar`. + +## Run + +With `./examples/example-native-histogram/target/example-native-histogram.jar` present, simply run: + +``` +cd ./examples/example-native-histogram/ +docker-compose up +``` + +This will run the following Docker containers: + +* [http://localhost:9400/metrics](http://localhost:9400/metrics) example application +* [http://localhost:9090](http://localhost:9090) Prometheus server +* [http://localhost:3000](http://localhost:3000) Grafana (user _admin_, password _admin_) + +You might need to replace `localhost` with `host.docker.internal` on MacOS or Windows. + +The Grafana server is preconfigured with two dashboards, one based on the classic histogram and the other one based on the native histogram. diff --git a/examples/example-native-histogram/docker-compose.yaml b/examples/example-native-histogram/docker-compose.yaml new file mode 100644 index 000000000..799981453 --- /dev/null +++ b/examples/example-native-histogram/docker-compose.yaml @@ -0,0 +1,27 @@ +version: "3" +services: + example-application: + image: eclipse-temurin:17-jre + network_mode: host + volumes: + - ./target/example-native-histogram.jar:/example-native-histogram.jar + command: + - /opt/java/openjdk/bin/java + - -jar + - /example-native-histogram.jar + prometheus: + image: prom/prometheus:v2.47.0 + network_mode: host + volumes: + - ./docker-compose/prometheus.yml:/prometheus.yml + command: + - --enable-feature=native-histograms + - --config.file=/prometheus.yml + grafana: + image: grafana/grafana:10.0.0 + network_mode: host + volumes: + - ./docker-compose/grafana-datasources.yaml:/etc/grafana/provisioning/datasources/grafana-datasources.yaml + - ./docker-compose/grafana-dashboards.yaml:/etc/grafana/provisioning/dashboards/grafana-dashboards.yaml + - ./docker-compose/grafana-dashboard-classic-histogram.json:/etc/grafana/grafana-dashboard-classic-histogram.json + - ./docker-compose/grafana-dashboard-native-histogram.json:/etc/grafana/grafana-dashboard-native-histogram.json diff --git a/examples/example-native-histogram/docker-compose/grafana-dashboard-classic-histogram.json b/examples/example-native-histogram/docker-compose/grafana-dashboard-classic-histogram.json new file mode 100644 index 000000000..503d543f5 --- /dev/null +++ b/examples/example-native-histogram/docker-compose/grafana-dashboard-classic-histogram.json @@ -0,0 +1,572 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "request rate, error rate, duration", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "", + "gridPos": { + "h": 2, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 6, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Classic Histogram", + "mode": "markdown" + }, + "pluginVersion": "10.0.0", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(request_latency_seconds_count{job=\"$job\", instance=\"$instance\"}[5m]))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(request_latency_seconds_count{job=\"$job\", instance=\"$instance\", status=~\"5..\"}[5m])) / sum(rate(request_latency_seconds_count{job=\"$job\", instance=\"$instance\"}[5m]))\n\n", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Error Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 3, + "options": { + "displayMode": "gradient", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "valueMode": "color" + }, + "pluginVersion": "10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum by (le) (rate(request_latency_seconds_bucket{job=\"$job\", instance=\"$instance\"}[5m]))", + "format": "heatmap", + "instant": false, + "legendFormat": "{{le}}", + "range": true, + "refId": "A" + } + ], + "title": "Duration histogram (s)", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 5, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false, + "unit": "s" + } + }, + "pluginVersion": "10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum by (le) (rate(request_latency_seconds_bucket{job=\"$job\", instance=\"$instance\"}[5m]))", + "format": "heatmap", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Duration Heatmap", + "type": "heatmap" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 34 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum by (le) (rate(request_latency_seconds_bucket{job=\"$job\", instance=\"$instance\"}[5m])))", + "format": "time_series", + "instant": false, + "legendFormat": "95th", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "histogram_quantile(0.5, sum by (le) (rate(request_latency_seconds_bucket{job=\"$job\", instance=\"$instance\"}[5m])))", + "hide": false, + "legendFormat": "50th", + "range": true, + "refId": "B" + } + ], + "title": "Duration percentiles", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "greeting-service-out-of-the-box-classic-histogram", + "value": "greeting-service-out-of-the-box-classic-histogram" + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(job)", + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(job)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "2aa84f09-7278-4972-9dc4-5248bcab0306", + "value": "2aa84f09-7278-4972-9dc4-5248bcab0306" + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values({job=\"$job\"},instance)", + "hide": 0, + "includeAll": false, + "label": "instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values({job=\"$job\"},instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Classic Histogram", + "uid": "f543a537-cb96-470d-a349-660ad1513136", + "version": 1, + "weekStart": "" +} diff --git a/examples/example-native-histogram/docker-compose/grafana-dashboard-native-histogram.json b/examples/example-native-histogram/docker-compose/grafana-dashboard-native-histogram.json new file mode 100644 index 000000000..edee69044 --- /dev/null +++ b/examples/example-native-histogram/docker-compose/grafana-dashboard-native-histogram.json @@ -0,0 +1,500 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "request rate, error rate, duration", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "", + "gridPos": { + "h": 2, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 6, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Native Histogram", + "mode": "markdown" + }, + "pluginVersion": "10.0.0", + "type": "text" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "histogram_count(sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\"}[5m])))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Request Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "histogram_count(sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\", status=~\"5..\"}[5m]))) / histogram_count(sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\"}[5m])))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Error Rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 7, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false, + "unit": "s" + } + }, + "pluginVersion": "10.0.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "expr": "sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\"}[5m]))", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Duration Heatmap", + "type": "heatmap" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "histogram_quantile(0.95, sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\"}[5m])))", + "format": "time_series", + "instant": false, + "legendFormat": "95th", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "editorMode": "code", + "exemplar": false, + "expr": "histogram_quantile(0.5, sum(rate(request_latency_seconds{job=\"$job\", instance=\"$instance\"}[5m])))", + "hide": false, + "legendFormat": "50th", + "range": true, + "refId": "B" + } + ], + "title": "Duration percentiles", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "greeting-service-out-of-the-box-exponential-histogram", + "value": "greeting-service-out-of-the-box-exponential-histogram" + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values(job)", + "hide": 0, + "includeAll": false, + "label": "", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(job)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + }, + { + "current": { + "selected": false, + "text": "f63e7d5e-ee7c-43ea-9576-753bcd833e9b", + "value": "f63e7d5e-ee7c-43ea-9576-753bcd833e9b" + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "definition": "label_values({job=\"$job\"},instance)", + "hide": 0, + "includeAll": false, + "label": "instance", + "multi": false, + "name": "instance", + "options": [], + "query": { + "query": "label_values({job=\"$job\"},instance)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Native Histogram", + "uid": "b5b5f4ce-beab-497a-a425-df71508abe0d", + "version": 1, + "weekStart": "" +} diff --git a/examples/example-native-histogram/docker-compose/grafana-dashboards.yaml b/examples/example-native-histogram/docker-compose/grafana-dashboards.yaml new file mode 100644 index 000000000..8ecb2dd9a --- /dev/null +++ b/examples/example-native-histogram/docker-compose/grafana-dashboards.yaml @@ -0,0 +1,13 @@ +apiVersion: 1 + +providers: + - name: 'Classic Histogram Example' + type: file + options: + path: /etc/grafana/grafana-dashboard-classic-histogram.json + foldersFromFilesStructure: false + - name: 'Native Histogram Example' + type: file + options: + path: /etc/grafana/grafana-dashboard-native-histogram.json + foldersFromFilesStructure: false diff --git a/examples/example-native-histogram/docker-compose/grafana-datasources.yaml b/examples/example-native-histogram/docker-compose/grafana-datasources.yaml new file mode 100644 index 000000000..e16df68e1 --- /dev/null +++ b/examples/example-native-histogram/docker-compose/grafana-datasources.yaml @@ -0,0 +1,8 @@ +apiVersion: 1 + +datasources: + + - name: Prometheus + type: prometheus + uid: prometheus + url: http://localhost:9090 diff --git a/examples/example-native-histogram/docker-compose/prometheus.yml b/examples/example-native-histogram/docker-compose/prometheus.yml new file mode 100644 index 000000000..8bdc055d3 --- /dev/null +++ b/examples/example-native-histogram/docker-compose/prometheus.yml @@ -0,0 +1,8 @@ +global: + scrape_interval: 5s # very short interval for demo purposes + +scrape_configs: + - job_name: "demo" + scrape_classic_histograms: true # this will make Prometheus scrape both, the native and the classic histogram. + static_configs: + - targets: ["localhost:9400"] diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml new file mode 100644 index 000000000..720fb621e --- /dev/null +++ b/examples/example-native-histogram/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.0.0-beta-2-SNAPSHOT + + + example-native-histogram + + Example - Native Histogram + + End-to-End example of a Native histogram: Java app -> Prometheus -> Grafana + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-httpserver + ${project.version} + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.nativehistogram.Main + + + + + + + + + diff --git a/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java new file mode 100644 index 000000000..591216fb7 --- /dev/null +++ b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java @@ -0,0 +1,39 @@ +package io.prometheus.metrics.examples.nativehistogram; + +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.io.IOException; +import java.util.Random; + +public class Main { + + public static void main(String[] args) throws IOException, InterruptedException { + + JvmMetrics.builder().register(); + + Histogram histogram = Histogram.builder() + .name("request_latency_seconds") + .help("request latency in seconds") + .unit(Unit.SECONDS) + .labelNames("path", "status") + .register(); + + HTTPServer server = HTTPServer.builder() + .port(9400) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + Random random = new Random(0); + + while (true) { + double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); + String status = random.nextInt(100) < 20 ? "500" : "200"; + histogram.labelValues("/", status).observe(duration); + Thread.sleep(1000); + } + } +} diff --git a/examples/pom.xml b/examples/pom.xml index 928f553d4..2f3b01a79 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -38,6 +38,7 @@ example-exporter-httpserver example-exporter-opentelemetry example-simpleclient-bridge + example-native-histogram From 15da580ffc38b96eb7f6f1d5991d4d368ae394c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 18 Sep 2023 22:41:17 +0200 Subject: [PATCH 224/980] Update native histogram doc --- docs/content/getting-started/metric-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index c48f8025e..891755425 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -63,7 +63,7 @@ Prometheus supports two flavors of histograms: * Classic histograms: Bucket boundaries are explicitly defined when the histogram is created. * Native histograms (exponential histograms): Infinitly many virtual buckets. -By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. If the Prometheus server has native histograms enabled, it will request metrics in Prometheus protobuf format, and in that case both classic and native representation are exposed. If the Prometheus server does not have native histograms enabled, it will request OpenMetrics text format, and in that case only the classic representation is exposed. +By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. If the Prometheus server has native histograms enabled (`--enable-feature=native-histograms`), it will request metrics in Prometheus protobuf format and ingest the native histogram. If the Prometheus server does not have native histograms enabled, it will request OpenMetrics text format and ingest the classic histogram. Prometheus also has a scrape config option `scrape_classic_histograms: true` which makes it scrape both, the classic and the native representation. This is great for migration from classic to native histograms. See [examples/example-native-histogram](https://github.com/prometheus/client_java/tree/1.0.x/examples/example-native-histogram) for an example. ```java Histogram duration = Histogram.builder() From 817afb695701a3da65b8697e4ff07a4e5ea7c7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 18 Sep 2023 23:11:26 +0200 Subject: [PATCH 225/980] Add prometheus.properties example --- docs/content/getting-started/metric-types.md | 2 +- .../example-prometheus-properties/README.md | 27 +++++++ .../example-prometheus-properties/pom.xml | 76 +++++++++++++++++++ .../examples/prometheus_properties/Main.java | 45 +++++++++++ .../src/main/resources/prometheus.properties | 8 ++ examples/pom.xml | 1 + .../exporter/httpserver/HTTPServer.java | 16 ++-- 7 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 examples/example-prometheus-properties/README.md create mode 100644 examples/example-prometheus-properties/pom.xml create mode 100644 examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java create mode 100644 examples/example-prometheus-properties/src/main/resources/prometheus.properties diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index 891755425..e1db24956 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -78,7 +78,7 @@ long start = System.nanoTime(); duration.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start)); ``` -Histograms implement the `TimerApi` interface, which provides convenience methods for measuring durations. +Histograms implement the [TimerApi](/client_java/api/io/prometheus/metrics/core/datapoints/TimerApi.html) interface, which provides convenience methods for measuring durations. The histogram builder provides a lot of configuration for fine-tuning the histogram behavior. In most cases you don't need them, defaults are good. The following is an incomplete list showing the most important options: diff --git a/examples/example-prometheus-properties/README.md b/examples/example-prometheus-properties/README.md new file mode 100644 index 000000000..2c82e8fd0 --- /dev/null +++ b/examples/example-prometheus-properties/README.md @@ -0,0 +1,27 @@ +# prometheus.properties Example + +## Build + +This example is built as part of the `client_java` project. + +``` +./mvnw package +``` + +This should create the file `./examples/example-prometheus-properties/target/example-prometheus-properties.jar`. + +## Run + +``` +java -jar ./examples/example-prometheus-properties/target/example-prometheus-properties.jar +``` + +View the metrics on [http://localhost:9401/metrics?name[]=request_duration_seconds&name[]=request_size_bytes](http://localhost:9401/metrics?name[]=request_duration_seconds&name[]=request_size_bytes). + +The example has a `prometheus.properties` file in the classpath with a few examples of how to change settings at runtime. + +There are multiple alternative ways to specify the location of the `prometheus.properties` file: + +* Put it in the classpath, like in this example. +* Set the environment variable `PROMETHEUS_CONFIG` to the file location. +* Set the `prometheus.config` System property to the file location. diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml new file mode 100644 index 000000000..13738efc3 --- /dev/null +++ b/examples/example-prometheus-properties/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.0.0-beta-2-SNAPSHOT + + + example-prometheus-properties + + Example - prometheus.properties + + Example of runtime configuration with prometheus.properties + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Fabian Stäber + fabian@fstab.de + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-httpserver + ${project.version} + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.prometheus_properties.Main + + + + + + + + + diff --git a/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java new file mode 100644 index 000000000..97611fe7b --- /dev/null +++ b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java @@ -0,0 +1,45 @@ +package io.prometheus.metrics.examples.prometheus_properties; + +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import io.prometheus.metrics.model.snapshots.Unit; + +import java.io.IOException; +import java.util.Random; + +public class Main { + + public static void main(String[] args) throws IOException, InterruptedException { + + JvmMetrics.builder().register(); + + Histogram requestDuration = Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .register(); + + Histogram requestSize = Histogram.builder() + .name("request_size_bytes") + .help("request size in bytes") + .unit(Unit.BYTES) + .register(); + + HTTPServer server = HTTPServer.builder() + .port(9400) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + Random random = new Random(0); + + while (true) { + double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); + double size = random.nextInt(1000) + 256; + requestDuration.observe(duration); + requestSize.observe(size); + Thread.sleep(1000); + } + } +} diff --git a/examples/example-prometheus-properties/src/main/resources/prometheus.properties b/examples/example-prometheus-properties/src/main/resources/prometheus.properties new file mode 100644 index 000000000..a786fd370 --- /dev/null +++ b/examples/example-prometheus-properties/src/main/resources/prometheus.properties @@ -0,0 +1,8 @@ +io.prometheus.exporter.httpServer.port = 9401 +io.prometheus.exporter.includeCreatedTimestamps = true + +# Set a new default for all histograms +io.prometheus.metrics.histogramClassicUpperBounds = .2, .4, .8, .1 + +# Override the default for one specific histogram +io.prometheus.metrics.request_size_bytes.histogramClassicUpperBounds = 256, 512, 768, 1024 diff --git a/examples/pom.xml b/examples/pom.xml index 2f3b01a79..a52a32f73 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -39,6 +39,7 @@ example-exporter-opentelemetry example-simpleclient-bridge example-native-histogram + example-prometheus-properties diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index d3ef9d68e..81f8871e4 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -103,10 +103,8 @@ public static class Builder { private Integer port = null; private String hostname = null; private InetAddress inetAddress = null; - private InetSocketAddress inetSocketAddress = null; private ExecutorService executorService = null; private PrometheusRegistry registry = null; - private ExporterHttpServerProperties properties = null; private Authenticator authenticator = null; private HttpsConfigurator httpsConfigurator = null; private HttpHandler defaultHandler = null; @@ -204,12 +202,7 @@ public HTTPServer buildAndStart() throws IOException { } private InetSocketAddress makeInetSocketAddress() { - if (inetSocketAddress != null) { - assertNull(port, "cannot configure 'inetSocketAddress' and 'port' at the same time"); - assertNull(hostname, "cannot configure 'inetSocketAddress' and 'hostname' at the same time"); - assertNull(inetAddress, "cannot configure 'inetSocketAddress' and 'inetAddress' at the same time"); - return inetSocketAddress; - } else if (inetAddress != null) { + if (inetAddress != null) { assertNull(hostname, "cannot configure 'inetAddress' and 'hostname' at the same time"); return new InetSocketAddress(inetAddress, findPort()); } else if (hostname != null) { @@ -235,8 +228,11 @@ private ExecutorService makeExecutorService() { } private int findPort() { - if (properties != null && properties.getPort() != null) { - return properties.getPort(); // you can overwrite the hard-coded port with properties. + if (config != null && config.getExporterHttpServerProperties() != null) { + Integer port = config.getExporterHttpServerProperties().getPort(); + if (port != null) { + return port; + } } if (port != null) { return port; From 5c59958af89aa7735b13c84f7e71da586ed22858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 19 Sep 2023 00:23:12 +0200 Subject: [PATCH 226/980] Add initial config properties docs --- docs/content/config/_index.md | 4 + docs/content/config/config.md | 100 ++++++++++++++++++ docs/content/getting-started/metric-types.md | 4 +- .../metrics/core/metrics/StatefulMetric.java | 6 ++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 docs/content/config/_index.md create mode 100644 docs/content/config/config.md diff --git a/docs/content/config/_index.md b/docs/content/config/_index.md new file mode 100644 index 000000000..44a2e4e05 --- /dev/null +++ b/docs/content/config/_index.md @@ -0,0 +1,4 @@ +--- +title: Config +weight: 3 +--- diff --git a/docs/content/config/config.md b/docs/content/config/config.md new file mode 100644 index 000000000..e586e78bc --- /dev/null +++ b/docs/content/config/config.md @@ -0,0 +1,100 @@ +--- +title: Config +weight: 1 +--- + +{{< toc >}} + +The Prometheus metrics library provides multiple options how to override configuration at runtime: + +* Properties file +* System properties +* Environment variables + +Example: + +``` +io.prometheus.exporter.httpServer.port = 9401 +``` + +The property above changes the port for the [HTTPServer exporter]({{< relref "/exporters/httpserver.md" >}}) to _9401_. + +* Properties file: Add the line above to the properties file. +* System properties: Use the command line parameter `-Dio.prometheus.exporter.httpServer.port=9401` when starting your application. +* Environment variable: `export IO_PROMETHEUS_EXPORTER_HTTPSERVER_PORT=9401`. The name of the environment variable is the uppercase property name with dots replaced with underscores. + +Location of the Properties File +------------------------------- + +The properties file is searched in the following locations: + +* `/prometheus.properties` in the classpath. This is for bundling a properties file with your application. +* System property `-Dprometheus.config=/path/to/prometheus.properties`. +* Enironment variable `PROMETHEUS_CONFIG=/path/to/prometheus.properties`. + +Metrics Properties +------------------ + +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()](/client_java/api/io/prometheus/metrics/core/metrics/Counter.Builder.html#withExemplars()) | (1) | +| io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()) | | +| io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) | | +| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicBuckets(double...)) | (2) | +| io.prometheus.metrics.histogramNativeInitialSchema | [Histogram.Builder.nativeInitialSchema()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeInitialSchema(int)) | | +| io.prometheus.metrics.histogramNativeMinZeroThreshold | [Histogram.Builder.nativeMinZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMinZeroThreshold(double)) | | +| io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxZeroThreshold(double)) | | +| io.prometheus.metrics.histogramNativeMaxNumberOfBuckets | [Histogram.Builder.nativeMaxNumberOfBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxNumberOfBuckets(int)) | | +| io.prometheus.metrics.histogramNativeResetDurationSeconds | [Histogram.Builder.nativeResetDuration()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeResetDuration(long,java.util.concurrent.TimeUnit)) | | +| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](https://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (3) | +| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](ihttps://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (4) | +| io.prometheus.metrics.summaryMaxAgeSeconds | [Summary.Builder.maxAgeSeconds()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#maxAgeSeconds(long)) | | +| io.prometheus.metrics.summaryNumberOfAgeBuckets | [Summary.Builder.numberOfAgeBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#numberOfAgeBuckets(int)) | | + +**Notes** + +(1) _withExemplars()_ and _withoutExemplars()_ are available for all metric types, not just for counters
        +(2) Comma-separated list. Example: `.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10`.
        +(3) Comma-separated list. Example: `0.5, 0.95, 0.99`.
        +(4) Comma-separated list. If specified, the list must have the same length as `io.prometheus.metrics.summaryQuantiles`. Example: `0.01, 0.005, 0.005`. + +There's one special feature about metric properties: You can set a property for one specific metric only by specifying the metric name. Example: Let's say you have a histogram named `latency_seconds`. + +``` +io.prometheus.metrics.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0 +``` + +The line above sets histogram buckets for all histograms. However: + +``` +io.prometheus.metrics.latency_seconds.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0 +``` + +The line above sets histogram buckets only for the histogram named `latency_seconds`. + +This works for all Metrics properties. + +Exemplar Properties +------------------- + +TODO + +Exporter Properties +------------------- + +TODO + +Exporter Filter Properties +-------------------------- + +TODO + +Exporter HTTPServer Properties +------------------------------ + +TODO + +Exporter OpenTelemetry Properties +--------------------------------- + +TODO diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index e1db24956..ba34686b9 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -86,7 +86,7 @@ The histogram builder provides a lot of configuration for fine-tuning the histog * `classicBuckets(...)`: Set the classic bucket boundaries. Default buckets are `.005`, `.01`, `.025`, `.05`, `.1`, `.25`, `.5`, `1`, `2.5`, `5`, `and 10`. The default bucket boundaries are designed for measuring request durations in seconds. * `nativeMaxNumberOfBuckets()`: Upper limit for the number of native histogram buckets. Default is 160. When the maximum is reached, the native histogram automatically reduces resolution to stay below the limit. -See Javadoc for a complete list of options. +See Javadoc for [Histogram.Builder](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html) for a complete list of options. Some options can be configured at runtime, see [config](/config/config). Histograms and summaries are both used for observing distributions. Therefore, the both implement the `DistributionDataPoint` interface. Using the `DistributionDataPoint` interface directly gives you the option to switch between histograms and summaries later with minimal code changes. @@ -155,6 +155,8 @@ The 0.0 quantile (min value) and the 1.0 quantile (max value) are special cases Quantile values are calculated based on a 5 minutes moving time window. The default time window can be changed with `maxAgeSeconds()` and `numberOfAgeBuckets()`. +Some options can be configured at runtime, see [config](/config/config). + In general you should prefer histograms over summaries. The Prometheus query language has a function [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for calculating quantiles from histograms. The advantage of query-time quantile calculation is that you can aggregate histograms before calculating the quantile. With summaries you must use the quantile with all its labels as it is. Info diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 96df6299e..426f4efa8 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -161,11 +161,17 @@ protected Builder(List illegalLabelNames, PrometheusProperties config) { super(illegalLabelNames, config); } + /** + * Allow Exemplars for this metric. + */ public B withExemplars() { this.exemplarsEnabled = TRUE; return self(); } + /** + * Turn off Exemplars for this metric. + */ public B withoutExemplars() { this.exemplarsEnabled = FALSE; return self(); From 2199ee6ba133126757686ac6e42bf102fe4ad66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 19 Sep 2023 00:23:12 +0200 Subject: [PATCH 227/980] OpenTelemetry exporter: Use random UUID as default instance ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../config/prometheus.yaml | 7 +------ .../example-exporter-opentelemetry/docker-compose.yaml | 9 ++------- .../prometheus/metrics/examples/opentelemetry/Main.java | 2 +- .../opentelemetry/ResourceAttributesDefaults.java | 4 ++++ 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/examples/example-exporter-opentelemetry/config/prometheus.yaml b/examples/example-exporter-opentelemetry/config/prometheus.yaml index 9f559dae8..18369e9ca 100644 --- a/examples/example-exporter-opentelemetry/config/prometheus.yaml +++ b/examples/example-exporter-opentelemetry/config/prometheus.yaml @@ -1,6 +1 @@ -#global: -# scrape_interval: 10s -#scrape_configs: -# - job_name: "prometheus-direct" -# static_configs: -# - targets: ["localhost:9400"] +# empty, because this Prometheus instance receives all metrics via remote write. diff --git a/examples/example-exporter-opentelemetry/docker-compose.yaml b/examples/example-exporter-opentelemetry/docker-compose.yaml index b66982521..5501c3ec3 100644 --- a/examples/example-exporter-opentelemetry/docker-compose.yaml +++ b/examples/example-exporter-opentelemetry/docker-compose.yaml @@ -13,20 +13,15 @@ services: #- -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 - /example-exporter-opentelemetry.jar collector: - image: otel/opentelemetry-collector-contrib:0.79.0 + image: otel/opentelemetry-collector-contrib:0.85.0 network_mode: host - ports: - - "4317:4317" - - "4318:4318" volumes: - ./config/otelcol-config.yaml:/config.yaml command: - --config=file:/config.yaml prometheus: - image: prom/prometheus:v2.45.0 + image: prom/prometheus:v2.47.0 network_mode: host - ports: - - "9090:9090" volumes: - ./config/prometheus.yaml:/prometheus.yaml command: diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java index 4d9b4a738..966b16d92 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java @@ -30,7 +30,7 @@ public static void main(String[] args) throws Exception { .register(); OpenTelemetryExporter.builder() - .intervalSeconds(5) + .intervalSeconds(5) // ridiculously short interval for demo purposes .buildAndStart(); while (true) { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java index 053c2b53a..0e63f4ccb 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java @@ -1,10 +1,14 @@ package io.prometheus.metrics.exporter.opentelemetry; import java.util.Map; +import java.util.UUID; public class ResourceAttributesDefaults { + private static final String instanceId = UUID.randomUUID().toString(); + public static void addIfAbsent(Map result) { + result.putIfAbsent("service.instance.id", instanceId); result.putIfAbsent("service.name", "unknown_service:java"); } } From 6770d2803a2fa2f6d3b4c9f1925973daf336c10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 19 Sep 2023 16:42:34 +0200 Subject: [PATCH 228/980] Update tail sampling example --- .../docker-compose.yaml | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/docker-compose.yaml b/examples/example-exemplars-tail-sampling/docker-compose.yaml index ed2934446..5db6a2f05 100644 --- a/examples/example-exemplars-tail-sampling/docker-compose.yaml +++ b/examples/example-exemplars-tail-sampling/docker-compose.yaml @@ -7,10 +7,8 @@ services: dockerfile_inline: | FROM openjdk:11-jre WORKDIR / - RUN curl -sOL https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.28.0/opentelemetry-javaagent.jar + RUN curl -sOL https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.30.0/opentelemetry-javaagent.jar network_mode: host - ports: - - "8080:8080" volumes: - ./example-hello-world-app/target/example-hello-world-app.jar:/example-hello-world-app.jar environment: @@ -26,8 +24,6 @@ services: # The opentelemetry-java-agent image is coming from the hello-world-up service above. image: opentelemetry-java-agent network_mode: host - ports: - - "8081:8081" volumes: - ./example-greeting-service/target/example-greeting-service.jar:/example-greeting-service.jar environment: @@ -40,20 +36,15 @@ services: - -jar - /example-greeting-service.jar collector: - image: otel/opentelemetry-collector-contrib:0.79.0 + image: otel/opentelemetry-collector-contrib:0.85.0 network_mode: host - ports: - - "4317:4317" - - "4318:4318" volumes: - ./config/otelcol-config.yaml:/config.yaml command: - --config=file:/config.yaml prometheus: - image: prom/prometheus:v2.45.0 + image: prom/prometheus:v2.47.0 network_mode: host - ports: - - "9090:9090" volumes: - ./config/prometheus.yaml:/prometheus.yaml command: @@ -61,19 +52,14 @@ services: - --enable-feature=native-histograms - --config.file=/prometheus.yaml tempo: - image: grafana/tempo:2.1.1 + image: grafana/tempo:2.2.3 network_mode: host - ports: - - "3200:3200" - - "4417:4417" - - "4418:4418" - - "9096:9096" volumes: - ./config/tempo-config.yaml:/config.yaml command: - --config.file=/config.yaml grafana: - image: grafana/grafana:10.0.0 + image: grafana/grafana:10.1.2 network_mode: host ports: - "3000:3000" From e3f193c539f304e36974c25efec440f9a8915835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 19 Sep 2023 23:14:47 +0200 Subject: [PATCH 229/980] Add benchmarks for Counter and Histogram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- benchmarks/pom.xml | 54 +++-- .../metrics/benchmarks/BenchmarkRunner.java | 7 + .../metrics/benchmarks/CounterBenchmark.java | 194 ++++++++++++++++++ .../benchmarks/HistogramBenchmark.java | 173 ++++++++++++++++ .../metrics/benchmarks/RandomNumbers.java | 19 ++ 5 files changed, 428 insertions(+), 19 deletions(-) create mode 100644 benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java create mode 100644 benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java create mode 100644 benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java create mode 100644 benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 79d6a9439..9a25ea843 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -15,6 +15,13 @@ Benchmarks of client performance, and comparison to other systems. + + 1.37 + 0.16.0 + 3.0.2 + 1.30.1 + + The Apache Software License, Version 2.0 @@ -27,30 +34,53 @@ org.openjdk.jmh jmh-core - 1.35 + ${jmh.version} org.openjdk.jmh jmh-generator-annprocess - 1.35 + ${jmh.version} + io.prometheus - simpleclient + prometheus-metrics-core ${project.version} + + io.prometheus + simpleclient + ${simpleclient.version} + com.codahale.metrics metrics-core - 3.0.2 + ${codahale.version} + + + io.opentelemetry + opentelemetry-api + ${opentelemetry.version} + + + io.opentelemetry + opentelemetry-sdk + ${opentelemetry.version} + + + io.opentelemetry + opentelemetry-sdk-testing + ${opentelemetry.version} + ${project.artifactId} org.apache.maven.plugins @@ -65,23 +95,9 @@ benchmarks - org.openjdk.jmh.Main + io.prometheus.metrics.benchmarks.BenchmarkRunner - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java new file mode 100644 index 000000000..6503c0d60 --- /dev/null +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java @@ -0,0 +1,7 @@ +package io.prometheus.metrics.benchmarks; + +public class BenchmarkRunner { + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java new file mode 100644 index 000000000..7541ab008 --- /dev/null +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -0,0 +1,194 @@ +package io.prometheus.metrics.benchmarks; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.DoubleCounter; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader; +import io.prometheus.metrics.core.datapoints.CounterDataPoint; +import io.prometheus.metrics.core.metrics.Counter; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; + +public class CounterBenchmark { + + @State(Scope.Benchmark) + public static class PrometheusCounter { + + final Counter noLabels; + final CounterDataPoint dataPoint; + + public PrometheusCounter() { + noLabels = Counter.builder() + .name("test") + .help("help") + .build(); + + Counter labels = Counter.builder() + .name("test") + .help("help") + .labelNames("path", "status") + .build(); + this.dataPoint = labels.labelValues("/", "200"); + } + } + + @State(Scope.Benchmark) + public static class SimpleclientCounter { + + final io.prometheus.client.Counter noLabels; + final io.prometheus.client.Counter.Child dataPoint; + + public SimpleclientCounter() { + noLabels = io.prometheus.client.Counter.build() + .name("name") + .help("help") + .create(); + + io.prometheus.client.Counter counter = io.prometheus.client.Counter.build() + .name("name") + .help("help") + .labelNames("path", "status") + .create(); + + this.dataPoint = counter.labels("/", "200"); + } + } + + @State(Scope.Benchmark) + public static class CodahaleCounterNoLabels { + final com.codahale.metrics.Counter counter = new com.codahale.metrics.MetricRegistry().counter("test"); + } + + @State(Scope.Benchmark) + public static class OpenTelemetryCounter { + + final LongCounter longCounter; + final DoubleCounter doubleCounter; + final Attributes attributes; + + public OpenTelemetryCounter() { + + SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .build(); + OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() + .setMeterProvider(sdkMeterProvider) + .build(); + Meter meter = openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + this.longCounter = meter + .counterBuilder("test1") + .setDescription("test") + .build(); + this.doubleCounter = meter + .counterBuilder("test2") + .ofDoubles() + .setDescription("test") + .build(); + this.attributes = Attributes.of( + AttributeKey.stringKey("path"), "/", + AttributeKey.stringKey("status"), "200"); + } + } + + @Benchmark + @Threads(4) + public CounterDataPoint prometheusAdd(RandomNumbers randomNumbers, PrometheusCounter counter) { + for (int i=0; i Date: Tue, 19 Sep 2023 23:44:40 +0200 Subject: [PATCH 230/980] Add docs for HTTPServer config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/config/config.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/content/config/config.md b/docs/content/config/config.md index e586e78bc..c00b9e3e7 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -92,9 +92,28 @@ TODO Exporter HTTPServer Properties ------------------------------ -TODO +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.exporter.httpServer.port | [HTTPServer.Builder.port()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#port(int)) | | Exporter OpenTelemetry Properties --------------------------------- -TODO +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.exporter.opentelemetry.protocol | [OpenTelemetryExporter.Builder.protocol()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#protocol(java.lang.String)) | (1) | +| io.prometheus.exporter.opentelemetry.endpoint | [OpenTelemetryExporter.Builder.endpoint()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#endpoint(java.lang.String)) | | +| io.prometheus.exporter.opentelemetry.headers | [OpenTelemetryExporter.Builder.headers](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#header(java.lang.String,java.lang.String)) | (2) | +| io.prometheus.exporter.opentelemetry.intervalSeconds | [OpenTelemetryExporter.Builder.intervalSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#intervalSeconds(int)) | | +| io.prometheus.exporter.opentelemetry.timeoutSeconds | [OpenTelemetryExporter.Builder.timeoutSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#timeoutSeconds(int)) | | +| io.prometheus.exporter.opentelemetry.serviceName | [OpenTelemetryExporter.Builder.serviceName()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceName(java.lang.String)) | | +| io.prometheus.exporter.opentelemetry.serviceNamespace | [OpenTelemetryExporter.Builder.serviceNamespace()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceNamespace(java.lang.String)) | | +| io.prometheus.exporter.opentelemetry.serviceInstanceId | [OpenTelemetryExporter.Builder.serviceInstanceId()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceInstanceId(java.lang.String)) | | +| io.prometheus.exporter.opentelemetry.serviceVersion | [OpenTelemetryExporter.Builder.serviceVersion()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceVersion(java.lang.String)) | | +| io.prometheus.exporter.opentelemetry.resourceAttributes | [OpenTelemetryExporter.Builder.resourceAttributes()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#resourceAttribute(java.lang.String,java.lang.String)) | (3) | + +(1) Protocol can be `grpc` or `http/protobuf`.
        +(2) Format: `key1=value1,key2=value2`
        +(3) Format: `key1=value1,key2=value2` + +Many of these attributes can alternatively be configured via OpenTelemetry environment variables, like `OTEL_EXPORTER_OTLP_ENDPOINT`. The Prometheus metrics library has support for OpenTelemetry environment variables. See Javadoc for details. From e324c9684178cb114824e1eb7cfa6a80afd76e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Sep 2023 22:02:18 +0200 Subject: [PATCH 231/980] Add benchmark results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- benchmarks/README.md | 6 +++++- .../metrics/benchmarks/CounterBenchmark.java | 16 ++++++++++++++++ .../metrics/benchmarks/HistogramBenchmark.java | 11 +++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/benchmarks/README.md b/benchmarks/README.md index 4afefd30c..b30028036 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,3 +1,7 @@ +_NOTE: Benchmarks for the new 1.0.0 release are in the io.prometheus.metrics.benchmarks package_. +_The old benchmarks will be ported to the new 1.0.0 version and then be removed._ +_This readme is for the old benchmarks, we'll leave it here for reference until we ported all benchmarks over._ + # Client Benchmarks This module contains microbenchmarks for client instrumentation operations. @@ -132,4 +136,4 @@ so I suspect a flaw in the test setup. Benchmark Mode Samples Score Error Units i.p.c.b.ExemplarsBenchmark.testCounter avgt 200 27.318 ± 0.347 ns/op i.p.c.b.ExemplarsBenchmark.testCounterWithExemplars avgt 200 45.785 ± 0.177 ns/op - i.p.c.b.ExemplarsBenchmark.testCounterWithoutExemplars avgt 200 25.404 ± 0.184 ns/op \ No newline at end of file + i.p.c.b.ExemplarsBenchmark.testCounterWithoutExemplars avgt 200 25.404 ± 0.184 ns/op diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index 7541ab008..2befc6bd2 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -17,6 +17,22 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Threads; +/** + * Results on a machine with dedicated 8 vCPU cores: + *
        + * Benchmark                                                                  Mode  Cnt      Score     Error  Units
        + * i.p.metrics.benchmarks.CounterBenchmark.codahaleIncNoLabels               thrpt   25  30978.055 ± 424.088  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryAdd                  thrpt   25  12682.744 ± 162.425  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryInc                  thrpt   25  14434.710 ±  99.809  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryIncNoLabels          thrpt   25  16634.416 ±  13.098  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.prometheusAdd                     thrpt   25  37317.024 ± 283.064  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.prometheusInc                     thrpt   25  39436.278 ± 458.583  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.prometheusNoLabelsInc             thrpt   25  34752.910 ± 293.979  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.simpleclientAdd                   thrpt   25   9520.592 ± 245.787  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.simpleclientInc                   thrpt   25   9057.637 ±  67.761  ops/s
        + * i.p.metrics.benchmarks.CounterBenchmark.simpleclientNoLabelsInc           thrpt   25   8993.471 ±  49.581  ops/s
        + * 
        + */ public class CounterBenchmark { @State(Scope.Benchmark) diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java index d6486d2f0..a0df74be7 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java @@ -17,6 +17,17 @@ import java.util.Arrays; +/** + * Results on a machine with dedicated 8 vCPU cores: + *
        + * Benchmark                                                                  Mode  Cnt      Score     Error  Units
        + * i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryClassic            thrpt   25   1908.715 ± 114.050  ops/s
        + * i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryExponential        thrpt   25   1009.785 ±  12.965  ops/s
        + * i.p.metrics.benchmarks.HistogramBenchmark.prometheusClassic               thrpt   25   6451.533 ± 326.265  ops/s
        + * i.p.metrics.benchmarks.HistogramBenchmark.prometheusNative                thrpt   25   3372.789 ± 339.328  ops/s
        + * i.p.metrics.benchmarks.HistogramBenchmark.simpleclient                    thrpt   25   6488.252 ±  96.737  ops/s
        + * 
        + */ public class HistogramBenchmark { @State(Scope.Benchmark) From 7dff41106e6f81c65294b42260f7f6d3514b8968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Sep 2023 23:57:27 +0200 Subject: [PATCH 232/980] Add more docs --- docs/content/config/config.md | 21 ++++++------- docs/content/getting-started/performance.md | 30 +++++++++++++++++++ .../ResourceAttributesFromOtelAgent.java | 14 +++++++++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/docs/content/config/config.md b/docs/content/config/config.md index c00b9e3e7..5c023975b 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -37,26 +37,27 @@ Metrics Properties | Name | Javadoc | Note | | --------------- | --------|------| -| io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()](/client_java/api/io/prometheus/metrics/core/metrics/Counter.Builder.html#withExemplars()) | (1) | -| io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()) | | -| io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) | | -| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicBuckets(double...)) | (2) | +| io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()](/client_java/api/io/prometheus/metrics/core/metrics/Counter.Builder.html#withExemplars()) | (1) (2) | +| io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()) | (2) | +| io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) | (2) | +| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicBuckets(double...)) | (3) | | io.prometheus.metrics.histogramNativeInitialSchema | [Histogram.Builder.nativeInitialSchema()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeInitialSchema(int)) | | | io.prometheus.metrics.histogramNativeMinZeroThreshold | [Histogram.Builder.nativeMinZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMinZeroThreshold(double)) | | | io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxZeroThreshold(double)) | | | io.prometheus.metrics.histogramNativeMaxNumberOfBuckets | [Histogram.Builder.nativeMaxNumberOfBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxNumberOfBuckets(int)) | | | io.prometheus.metrics.histogramNativeResetDurationSeconds | [Histogram.Builder.nativeResetDuration()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeResetDuration(long,java.util.concurrent.TimeUnit)) | | -| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](https://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (3) | -| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](ihttps://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (4) | +| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](https://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (4) | +| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](ihttps://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (5) | | io.prometheus.metrics.summaryMaxAgeSeconds | [Summary.Builder.maxAgeSeconds()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#maxAgeSeconds(long)) | | | io.prometheus.metrics.summaryNumberOfAgeBuckets | [Summary.Builder.numberOfAgeBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#numberOfAgeBuckets(int)) | | **Notes** (1) _withExemplars()_ and _withoutExemplars()_ are available for all metric types, not just for counters
        -(2) Comma-separated list. Example: `.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10`.
        -(3) Comma-separated list. Example: `0.5, 0.95, 0.99`.
        -(4) Comma-separated list. If specified, the list must have the same length as `io.prometheus.metrics.summaryQuantiles`. Example: `0.01, 0.005, 0.005`. +(2) Boolean value. Format: `property=true` or `property=false`.
        +(3) Comma-separated list. Example: `.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10`.
        +(4) Comma-separated list. Example: `0.5, 0.95, 0.99`.
        +(5) Comma-separated list. If specified, the list must have the same length as `io.prometheus.metrics.summaryQuantiles`. Example: `0.01, 0.005, 0.005`. There's one special feature about metric properties: You can set a property for one specific metric only by specifying the metric name. Example: Let's say you have a histogram named `latency_seconds`. @@ -103,7 +104,7 @@ Exporter OpenTelemetry Properties | --------------- | --------|------| | io.prometheus.exporter.opentelemetry.protocol | [OpenTelemetryExporter.Builder.protocol()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#protocol(java.lang.String)) | (1) | | io.prometheus.exporter.opentelemetry.endpoint | [OpenTelemetryExporter.Builder.endpoint()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#endpoint(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.headers | [OpenTelemetryExporter.Builder.headers](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#header(java.lang.String,java.lang.String)) | (2) | +| io.prometheus.exporter.opentelemetry.headers | [OpenTelemetryExporter.Builder.headers()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#header(java.lang.String,java.lang.String)) | (2) | | io.prometheus.exporter.opentelemetry.intervalSeconds | [OpenTelemetryExporter.Builder.intervalSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#intervalSeconds(int)) | | | io.prometheus.exporter.opentelemetry.timeoutSeconds | [OpenTelemetryExporter.Builder.timeoutSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#timeoutSeconds(int)) | | | io.prometheus.exporter.opentelemetry.serviceName | [OpenTelemetryExporter.Builder.serviceName()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceName(java.lang.String)) | | diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md index 1f3c49d3c..246817519 100644 --- a/docs/content/getting-started/performance.md +++ b/docs/content/getting-started/performance.md @@ -3,6 +3,11 @@ title: Performance weight: 6 --- +This section has tips on how to use the Prometheus Java client in high performance applications. + +Specify Label Values Only Once +------------------------------ + For high performance applications, we recommend to specify label values only once, and then use the data point directly. This applies to all metric types. Let's use a counter as an example here: @@ -34,3 +39,28 @@ Now, you can increment the data point directly, which is a highly optimized oper ```java successfulCalls.inc(); ``` + +Enable Only One Histogram Representation +---------------------------------------- + +By default, histograms maintain two representations under the hood: The classic histogram representation with static buckets, and the native histogram representation with dynamic buckets. + +While this default provides the flexibility to scrape different representations at runtime, it comes at a cost, because maintaining multiple representations causes performance overhead. + +In performance critical applications we recommend to use either the classic representation or the native representation, but not both. + +You can either configure this in code for each histogram by calling [classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) or [nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()), or you use the corresponding [config options](http://localhost:1313/config/config/). + +One way to do this via global config for all histograms is to add a file `prometheus.properties` to your classpath with the following line: + +```properties +io.prometheus.metrics.histogramClassicOnly=true +``` + +or + +```properties +io.prometheus.metrics.histogramNativeOnly=true +``` + +Alternatively, you can use an environment varialbe, system property, or define an external configuration file at runtime as described in the [config section](../../config/config). diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java index fcf6e0ba0..a18897fe5 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java @@ -17,6 +17,20 @@ public class ResourceAttributesFromOtelAgent { private static final String[] OTEL_JARS = new String[]{"opentelemetry-api-1.29.0.jar", "opentelemetry-context-1.29.0.jar"}; + /** + * This grabs resource attributes like {@code service.name} and {@code service.instance.id} from + * the OTel Java agent (if present) and adds them to {@code result}. + *

        + * The way this works is as follows: If the OTel Java agent is attached, it modifies the + * {@code GlobalOpenTelemetry.get()} method to return an agent-specific object. + * From that agent-specific object we can get the resource attributes via reflection. + *

        + * So we load the {@code GlobalOpenTelemetry} class (in a separate class loader from the JAR files + * that are bundled with this module), call {@code .get()}, and inspect the returned object. + *

        + * After that we discard the class loader so that all OTel specific classes are unloaded. + * No runtime dependency on any OTel version remains. + */ public static void addIfAbsent(Map result, String instrumentationScopeName) { try { Path tmpDir = createTempDirectory(instrumentationScopeName + "-"); From c57e49cab206777e09b48e350455225148039433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 23 Sep 2023 00:10:35 +0200 Subject: [PATCH 233/980] Rename buckets to upperBounds in histogram builder --- docs/content/config/config.md | 2 +- .../metrics/core/metrics/Histogram.java | 6 +++--- .../metrics/core/metrics/HistogramTest.java | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/content/config/config.md b/docs/content/config/config.md index 5c023975b..d9ff4f52c 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -40,7 +40,7 @@ Metrics Properties | io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()](/client_java/api/io/prometheus/metrics/core/metrics/Counter.Builder.html#withExemplars()) | (1) (2) | | io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()) | (2) | | io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) | (2) | -| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicBuckets(double...)) | (3) | +| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicUpperBounds()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicUpperBounds(double...)) | (3) | | io.prometheus.metrics.histogramNativeInitialSchema | [Histogram.Builder.nativeInitialSchema()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeInitialSchema(int)) | | | io.prometheus.metrics.histogramNativeMinZeroThreshold | [Histogram.Builder.nativeMinZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMinZeroThreshold(double)) | | | io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxZeroThreshold(double)) | | diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index d88e1412d..0cad6376c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -735,7 +735,7 @@ public Builder classicOnly() { * If the +Inf bucket is missing it will be added. * If upperBounds contains duplicates the duplicates will be removed. */ - public Builder classicBuckets(double... upperBounds) { + public Builder classicUpperBounds(double... upperBounds) { this.classicUpperBounds = upperBounds; for (double bound : upperBounds) { if (Double.isNaN(bound)) { @@ -755,7 +755,7 @@ public Builder classicBuckets(double... upperBounds) { * @param width is the width of each bucket * @param count is the total number of buckets, including start */ - public Builder classicLinearBuckets(double start, double width, int count) { + public Builder classicLinearUpperBounds(double start, double width, int count) { this.classicUpperBounds = new double[count]; // Use BigDecimal to avoid weird bucket boundaries like 0.7000000000000001. BigDecimal s = new BigDecimal(Double.toString(start)); @@ -776,7 +776,7 @@ public Builder classicLinearBuckets(double start, double width, int count) { * @param factor growth factor * @param count total number of buckets, including start */ - public Builder classicExponentialBuckets(double start, double factor, int count) { + public Builder classicExponentialUpperBounds(double start, double factor, int count) { classicUpperBounds = new double[count]; for (int i = 0; i < count; i++) { classicUpperBounds[i] = start * Math.pow(factor, i); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 987e39395..b021bf8ce 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -756,7 +756,7 @@ public void markCurrentSpanAsExemplar() { .name("test") // The default number of Exemplars is 4. // Use 5 buckets to verify that the exemplar sample is configured with the buckets. - .classicBuckets(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY) + .classicUpperBounds(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY) .labelNames("path") .build(); @@ -1076,7 +1076,7 @@ public void testNullName() { public void testDuplicateClassicBuckets() { Histogram histogram = Histogram.builder() .name("test") - .classicBuckets(0, 3, 17, 3, 21) + .classicUpperBounds(0, 3, 17, 3, 21) .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) @@ -1088,7 +1088,7 @@ public void testDuplicateClassicBuckets() { public void testUnsortedBuckets() { Histogram histogram = Histogram.builder() .name("test") - .classicBuckets(0.2, 0.1) + .classicUpperBounds(0.2, 0.1) .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) @@ -1100,7 +1100,7 @@ public void testUnsortedBuckets() { public void testEmptyBuckets() { Histogram histogram = Histogram.builder() .name("test") - .classicBuckets() + .classicUpperBounds() .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) @@ -1112,7 +1112,7 @@ public void testEmptyBuckets() { public void testBucketsIncludePositiveInfinity() { Histogram histogram = Histogram.builder() .name("test") - .classicBuckets(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY) + .classicUpperBounds(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY) .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) @@ -1124,7 +1124,7 @@ public void testBucketsIncludePositiveInfinity() { public void testLinearBuckets() { Histogram histogram = Histogram.builder() .name("test") - .classicLinearBuckets(0.1, 0.1, 10) + .classicLinearUpperBounds(0.1, 0.1, 10) .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) @@ -1135,7 +1135,7 @@ public void testLinearBuckets() { @Test public void testExponentialBuckets() { Histogram histogram = Histogram.builder() - .classicExponentialBuckets(2, 2.5, 3) + .classicExponentialUpperBounds(2, 2.5, 3) .name("test") .build(); List upperBounds = getData(histogram).getClassicBuckets().stream() @@ -1148,7 +1148,7 @@ public void testExponentialBuckets() { public void testBucketsIncludeNaN() { Histogram.builder() .name("test") - .classicBuckets(0.01, 0.1, 1.0, Double.NaN); + .classicUpperBounds(0.01, 0.1, 1.0, Double.NaN); } @Test @@ -1192,7 +1192,7 @@ public void testNegativeAmount() { Histogram histogram = Histogram.builder() .name("histogram") .help("test histogram for negative values") - .classicBuckets(-10, -5, 0, 5, 10) + .classicUpperBounds(-10, -5, 0, 5, 10) .build(); double expectedCount = 0; double expectedSum = 0; From 8076e9cf2bc4c9809ae855441c70cd813b0d816f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 09:53:09 +0200 Subject: [PATCH 234/980] Complete config documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/config/config.md | 31 +++++++++++++++---- docs/content/getting-started/metric-types.md | 7 ++++- docs/content/getting-started/performance.md | 3 +- .../config/ExporterFilterProperties.java | 24 +++++++------- .../src/test/resources/prometheus.properties | 2 +- .../common/PrometheusScrapeHandler.java | 10 +++--- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/docs/content/config/config.md b/docs/content/config/config.md index d9ff4f52c..285637f5d 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -9,7 +9,8 @@ The Prometheus metrics library provides multiple options how to override configu * Properties file * System properties -* Environment variables + +Future releases will add more options, like configuration via environment variables. Example: @@ -21,7 +22,6 @@ The property above changes the port for the [HTTPServer exporter]({{< relref "/e * Properties file: Add the line above to the properties file. * System properties: Use the command line parameter `-Dio.prometheus.exporter.httpServer.port=9401` when starting your application. -* Environment variable: `export IO_PROMETHEUS_EXPORTER_HTTPSERVER_PORT=9401`. The name of the environment variable is the uppercase property name with dots replaced with underscores. Location of the Properties File ------------------------------- @@ -30,7 +30,7 @@ The properties file is searched in the following locations: * `/prometheus.properties` in the classpath. This is for bundling a properties file with your application. * System property `-Dprometheus.config=/path/to/prometheus.properties`. -* Enironment variable `PROMETHEUS_CONFIG=/path/to/prometheus.properties`. +* Environment variable `PROMETHEUS_CONFIG=/path/to/prometheus.properties`. Metrics Properties ------------------ @@ -78,17 +78,36 @@ This works for all Metrics properties. Exemplar Properties ------------------- -TODO +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.exemplars.minRetentionPeriodSeconds | [ExemplarsProperties.getMinRetentionPeriodSeconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getMinRetentionPeriodSeconds()) | | +| io.prometheus.exemplars.maxRetentionPeriodSeconds | [ExemplarsProperties.getMaxRetentionPeriodSeconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getMaxRetentionPeriodSeconds()) | | +| io.prometheus.exemplars.sampleIntervalMilliseconds | [ExemplarsProperties.getSampleIntervalMilliseconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getSampleIntervalMilliseconds()) | | Exporter Properties ------------------- -TODO +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.exporter.includeCreatedTimestamps | [ExporterProperties.getExemplarsOnAllMetricTypes()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getExemplarsOnAllMetricTypes()) | (1) | +| io.prometheus.exporter.exemplarsOnAllMetricTypes | [ExporterProperties.getIncludeCreatedTimestamps()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getIncludeCreatedTimestamps()) | (1) | + +(1) Boolean value, `true` or `false`. Default see Javadoc. Exporter Filter Properties -------------------------- -TODO +| Name | Javadoc | Note | +| --------------- | --------|------| +| io.prometheus.exporter.filter.metricNameMustBeEqualTo | [ExporterFilterProperties.getAllowedMetricNames()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getAllowedMetricNames()) | (1) | +| io.prometheus.exporter.filter.metricNameMustNotBeEqualTo | [ExporterFilterProperties.getExcludedMetricNames()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getExcludedMetricNames()) | (2) | +| io.prometheus.exporter.filter.metricNameMustStartWith | [ExporterFilterProperties.getAllowedMetricNamePrefixes()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getAllowedMetricNamePrefixes()) | (3) | +| io.prometheus.exporter.filter.metricNameMustNotStartWith | [ExporterFilterProperties.getExcludedMetricNamePrefixes()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getExcludedMetricNamePrefixes()) | (4) | + +(1) Comma sparated list of allowed metric names. Only these metrics will be exposed.
        +(2) Comma sparated list of excluded metric names. These metrics will not be exposed.
        +(3) Comma sparated list of prefixes. Only metrics starting with these prefixes will be exposed.
        +(4) Comma sparated list of prefixes. Metrics starting with these prefixes will not be exposed.
        Exporter HTTPServer Properties ------------------------------ diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index ba34686b9..51d07bdbf 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -63,7 +63,12 @@ Prometheus supports two flavors of histograms: * Classic histograms: Bucket boundaries are explicitly defined when the histogram is created. * Native histograms (exponential histograms): Infinitly many virtual buckets. -By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. If the Prometheus server has native histograms enabled (`--enable-feature=native-histograms`), it will request metrics in Prometheus protobuf format and ingest the native histogram. If the Prometheus server does not have native histograms enabled, it will request OpenMetrics text format and ingest the classic histogram. Prometheus also has a scrape config option `scrape_classic_histograms: true` which makes it scrape both, the classic and the native representation. This is great for migration from classic to native histograms. See [examples/example-native-histogram](https://github.com/prometheus/client_java/tree/1.0.x/examples/example-native-histogram) for an example. +By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. +* By default, the Prometheus server will scrape metrics in OpenMetrics format and get the classic histogram flavor. +* If the Prometheus server is started with `--enable-feature=native-histograms`, it will request metrics in Prometheus protobuf format and ingest the native histogram. +* If the Prometheus server is started with `--enable-feature=native-histogram` and the scrape config has the option `scrape_classic_histograms: true`, it will request metrics in Prometheus protobuf format and ingest both, the classic and the native flavor. This is great for migrating from classic histograms to native histograms. + +See [examples/example-native-histogram](https://github.com/prometheus/client_java/tree/1.0.x/examples/example-native-histogram) for an example. ```java Histogram duration = Histogram.builder() diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md index 246817519..de68e3d11 100644 --- a/docs/content/getting-started/performance.md +++ b/docs/content/getting-started/performance.md @@ -63,4 +63,5 @@ or io.prometheus.metrics.histogramNativeOnly=true ``` -Alternatively, you can use an environment varialbe, system property, or define an external configuration file at runtime as described in the [config section](../../config/config). +Alternatively, you pass the parameter `-Dio.prometheus.metrics.histogramNativeOnly=true` on application startup, or define an external configuration file at runtime as described in the [config section](../../config/config). +Future releases will add support for configuration via environment variable`IO_PROMETHEUS_METRICS_HISTOGRAM_NATIVE_ONLY=true`. diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java index 1a4e3056d..e9cc46767 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -11,10 +11,10 @@ */ public class ExporterFilterProperties { - public static final String NAME_MUST_BE_EQUAL_TO = "nameMustBeEqualTo"; - public static final String NAME_MUST_NOT_BE_EQUAL_TO = "nameMustNotBeEqualTo"; - public static final String NAME_MUST_START_WITH = "nameMustStartWith"; - public static final String NAME_MUST_NOT_START_WITH = "nameMustNotStartWith"; + public static final String METRIC_NAME_MUST_BE_EQUAL_TO = "metricNameMustBeEqualTo"; + public static final String METRIC_NAME_MUST_NOT_BE_EQUAL_TO = "metricNameMustNotBeEqualTo"; + public static final String METRIC_NAME_MUST_START_WITH = "metricNameMustStartWith"; + public static final String METRIC_NAME_MUST_NOT_START_WITH = "metricNameMustNotStartWith"; private final List allowedNames; private final List excludedNames; @@ -33,19 +33,19 @@ private ExporterFilterProperties(List allowedNames, List exclude validate(prefix); } - public List getAllowedNames() { + public List getAllowedMetricNames() { return allowedNames; } - public List getExcludedNames() { + public List getExcludedMetricNames() { return excludedNames; } - public List getAllowedPrefixes() { + public List getAllowedMetricNamePrefixes() { return allowedPrefixes; } - public List getExcludedPrefixes() { + public List getExcludedMetricNamePrefixes() { return excludedPrefixes; } @@ -57,10 +57,10 @@ private void validate(String prefix) throws PrometheusPropertiesException { * This is because we want to know if there are unused properties remaining after all properties have been loaded. */ static ExporterFilterProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - List allowedNames = Util.loadStringList(prefix + "." + NAME_MUST_BE_EQUAL_TO, properties); - List excludedNames = Util.loadStringList(prefix + "." + NAME_MUST_NOT_BE_EQUAL_TO, properties); - List allowedPrefixes = Util.loadStringList(prefix + "." + NAME_MUST_START_WITH, properties); - List excludedPrefixes = Util.loadStringList(prefix + "." + NAME_MUST_NOT_START_WITH, properties); + List allowedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties); + List excludedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties); + List allowedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_START_WITH, properties); + List excludedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); } diff --git a/prometheus-metrics-config/src/test/resources/prometheus.properties b/prometheus-metrics-config/src/test/resources/prometheus.properties index ea32a6cca..13a5d9e39 100644 --- a/prometheus-metrics-config/src/test/resources/prometheus.properties +++ b/prometheus-metrics-config/src/test/resources/prometheus.properties @@ -8,7 +8,7 @@ io.prometheus.metrics.http_duration_seconds.exemplarsEnabled = true io.prometheus.exporter.includeCreatedTimestamps = false io.prometheus.exporter.exemplarsOnAllMetricTypes = true -io.prometheus.exporter.filter.nameMustBeEqualTo = a, b, c +io.prometheus.exporter.filter.metricNameMustBeEqualTo = a, b, c io.prometheus.exemplars.minRetentionPeriodSeconds = 30 diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index 61403b8ae..b095007e0 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -91,14 +91,14 @@ public void handleRequest(PrometheusHttpExchange exchange) throws IOException { } private Predicate makeNameFilter(ExporterFilterProperties props) { - if (props.getAllowedNames() == null && props.getExcludedNames() == null && props.getAllowedPrefixes() == null && props.getExcludedPrefixes() == null) { + if (props.getAllowedMetricNames() == null && props.getExcludedMetricNames() == null && props.getAllowedMetricNamePrefixes() == null && props.getExcludedMetricNamePrefixes() == null) { return null; } else { return MetricNameFilter.builder() - .nameMustBeEqualTo(props.getAllowedNames()) - .nameMustNotBeEqualTo(props.getExcludedNames()) - .nameMustStartWith(props.getAllowedPrefixes()) - .nameMustNotStartWith(props.getExcludedPrefixes()) + .nameMustBeEqualTo(props.getAllowedMetricNames()) + .nameMustNotBeEqualTo(props.getExcludedMetricNames()) + .nameMustStartWith(props.getAllowedMetricNamePrefixes()) + .nameMustNotStartWith(props.getExcludedMetricNamePrefixes()) .build(); } } From c547e395abf3784a9fde0bd2f2d89cd1c9ad840f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 11:03:58 +0200 Subject: [PATCH 235/980] Add backwards compatibility docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/migration/_index.md | 4 ++ docs/content/migration/simpleclient.md | 52 ++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 docs/content/migration/_index.md create mode 100644 docs/content/migration/simpleclient.md diff --git a/docs/content/migration/_index.md b/docs/content/migration/_index.md new file mode 100644 index 000000000..b749b91ee --- /dev/null +++ b/docs/content/migration/_index.md @@ -0,0 +1,4 @@ +--- +title: Compatibility +weight: 4 +--- diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md new file mode 100644 index 000000000..661c1aeea --- /dev/null +++ b/docs/content/migration/simpleclient.md @@ -0,0 +1,52 @@ +--- +title: Simpleclient +weight: 1 +--- + +The Prometheus Java client library 1.0.0 is a complete rewrite, and is not backwards compatible with the old `simpleclient` modules for a variety of reasons: + +* We rewrote the underlying data model. The `simpleclient` data model is based on [OpenMetrics](https://openmetrics.io/), which is based on the assumption that each data point has exactly one `double` value (`Collector.Sample.value` in `simpleclient`). With the new Prometheus native histograms this is no longer true. Native histograms have a complex data structure as value. This is the reason why native histograms cannot be exposed in OpenMetrics text format. The new `prometheus-metrics-model` implements the current Prometheus data model and is not based on OpenMetrics. +* We refactored the package names. The simpleclient has package names that are reused by multiple Maven modules, which causes issues with the Java module system. The new `prometheus-metrics` modules each has their own package name, package names are not reused. + +Migrating from Simpleclient +--------------------------- + +For users of previous versions of the Prometheus Java client we provide a migration module for bridging the simpleclient `CollectorRegistry` to the new `PromethesuRegistry`. + +To use the bridge, add the following dependency: + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-simpleclient-bridge:1.0.0' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-simpleclient-bridge + 1.0.0 + +``` +{{< /tab >}} +{{< /tabs >}} + +Then add the following to your code: + +```java +SimpleclientCollector.builder().register(); +``` + +This will make all metrics registered with simpleclient's `CollectorRegistry.defaultRegistry` available in the new `PrometheusRegistry.defaultRegistry`. + +If you are using custom registries, you can specify them like this: + +```java +CollectorRegistry simpleclientRegistry = ...; +PrometheusRegistry prometheusRegistry = ...; + +SimpleclientCollector.builder() + .collectorRegistry(simpleclientRegistry) + .register(prometheusRegistry); +``` From 682fbb47ca8057104e2253f78e408299e31a825f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 11:10:26 +0200 Subject: [PATCH 236/980] Add scaffold for OpenTelemetry docs --- docs/content/otel/_index.md | 4 ++++ docs/content/otel/names.md | 6 ++++++ docs/content/otel/otlp.md | 6 ++++++ docs/content/otel/tracing.md | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 docs/content/otel/_index.md create mode 100644 docs/content/otel/names.md create mode 100644 docs/content/otel/otlp.md create mode 100644 docs/content/otel/tracing.md diff --git a/docs/content/otel/_index.md b/docs/content/otel/_index.md new file mode 100644 index 000000000..1f637f6b9 --- /dev/null +++ b/docs/content/otel/_index.md @@ -0,0 +1,4 @@ +--- +title: OpenTelemetry +weight: 3 +--- diff --git a/docs/content/otel/names.md b/docs/content/otel/names.md new file mode 100644 index 000000000..89f6515c7 --- /dev/null +++ b/docs/content/otel/names.md @@ -0,0 +1,6 @@ +--- +title: Names +weight: 3 +--- + +TODO: How to iplement OpenTelemetry semantic conventions, and how OpenTelemetry metric and label names are converted to Prometheus. diff --git a/docs/content/otel/otlp.md b/docs/content/otel/otlp.md new file mode 100644 index 000000000..9c7938d99 --- /dev/null +++ b/docs/content/otel/otlp.md @@ -0,0 +1,6 @@ +--- +title: OTLP +weight: 1 +--- + +TODO: How to push metrics to an OpenTelemetry endpoint using the OpenTelemetry exporter. diff --git a/docs/content/otel/tracing.md b/docs/content/otel/tracing.md new file mode 100644 index 000000000..47af209cc --- /dev/null +++ b/docs/content/otel/tracing.md @@ -0,0 +1,6 @@ +--- +title: Tracing +weight: 2 +--- + +TODO: How to integrate Prometheus metrics with OTel traces. From 039de468d59b04fb94c9af238f44003dc29e391d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 16:03:05 +0200 Subject: [PATCH 237/980] Update benchmarks docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- benchmarks/README.md | 149 +++--------------- .../client/CKMSQuantileBenchmark.java | 0 .../client/benchmark/CounterBenchmark.java | 0 .../client/benchmark/ExemplarsBenchmark.java | 0 .../client/benchmark/GaugeBenchmark.java | 0 .../SanitizeMetricNameBenchmark.java | 0 .../client/benchmark/SummaryBenchmark.java | 0 .../metrics/benchmarks/CounterBenchmark.java | 3 + .../benchmarks/HistogramBenchmark.java | 6 + docs/content/config/_index.md | 2 +- docs/content/migration/_index.md | 2 +- 11 files changed, 32 insertions(+), 130 deletions(-) rename benchmarks/src/{main => archive}/java/io/prometheus/client/CKMSQuantileBenchmark.java (100%) rename benchmarks/src/{main => archive}/java/io/prometheus/client/benchmark/CounterBenchmark.java (100%) rename benchmarks/src/{main => archive}/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java (100%) rename benchmarks/src/{main => archive}/java/io/prometheus/client/benchmark/GaugeBenchmark.java (100%) rename benchmarks/src/{main => archive}/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java (100%) rename benchmarks/src/{main => archive}/java/io/prometheus/client/benchmark/SummaryBenchmark.java (100%) diff --git a/benchmarks/README.md b/benchmarks/README.md index b30028036..36300e4d1 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,139 +1,32 @@ -_NOTE: Benchmarks for the new 1.0.0 release are in the io.prometheus.metrics.benchmarks package_. -_The old benchmarks will be ported to the new 1.0.0 version and then be removed._ -_This readme is for the old benchmarks, we'll leave it here for reference until we ported all benchmarks over._ +Benchmarks +---------- -# Client Benchmarks +## How to Run -This module contains microbenchmarks for client instrumentation operations. +``` +java -jar ./benchmarks/target/benchmarks.jar +``` -## Result Overview +Run only one specific benchmark: -The main outcomes of the benchmarks: -* Simpleclient Counters/Gauges have similar performance to Codahale Counters. -* Codahale Meters are slower than Codahale/Simpleclient Counters -* Codahale Summaries are 10x slower than other metrics. -* Simpleclient Histograms are 10-100X faster than Codahale Summaries. -* Simpleclient `Gauge.Child.set` is relatively slow, especially when done concurrently. -* Label lookups in simpleclient are relatively slow. -* The `System.currentTimeMillis()` call in the `DefaultExemplarSampler` takes about 17ns on Linux. +``` +java -jar ./benchmarks/target/benchmarks.jar CounterBenchmark +``` -Accordingly, in terms of client instrumentation performance I suggest the following: -* It's cheap to extensively instrument your code with Simpleclient Counters/Gauges/Summaries without labels, or Codahale Counters. -* Avoid Codahale Meters, in favour of Codahale/Simpleclient Counters and calculating the rate in your monitoring system (e.g. the `rate()` function in Prometheus). -* Use Simpleclient Histograms rather than Codahale Histograms/Timers. -* For high update rate (>1000 per second) prometheus metrics using labels, you should cache the Child. Java 8 may make this better due to an improved ConcurrentHashMap implementation. -* If a use case appears for high update rate use of SimpleClient's `Gauge.Child.set`, we should alter `DoubleAdder` to more efficiently handle this use case. +## Results -## Benchmark Results +See Javadoc of the benchmark classes: -These benchmarks were run using JMH on a Linux laptop with a 4 Core Intel i7-8550U CPU with OpenJDK 1.8.0_292-b10. +* [CounterBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java) +* [HistogramBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java) -### Counters - java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 8.587 ± 0.530 ns/op - i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 40.820 ± 5.550 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 10.387 ± 0.698 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 32.357 ± 1.742 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 10.102 ± 0.524 ns/op +## What Prometheus Java client optimizes for - java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 8.236 ± 0.409 ns/op - i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 57.797 ± 4.758 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 11.123 ± 2.041 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 41.512 ± 5.128 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 11.455 ± 0.586 ns/op +concurrent updates of metrics in multi-threaded applications. +If your application is single-threaded and uses only one processor core, your application isn't performance critical anyway. +If your application is designed to use all available processor cores for maximum performance, then you want a metric library that doesn't slow your application down. +Prometheus client Java metrics support concurrent updates and scrapes. This shows in benchmarks with multiple threads recording data in shared metrics. - java -jar target/benchmarks.jar CounterBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.c.b.CounterBenchmark.codahaleCounterIncBenchmark avgt 5 9.613 ± 1.024 ns/op - i.p.c.b.CounterBenchmark.codahaleMeterMarkBenchmark avgt 5 90.632 ± 6.027 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterChildIncBenchmark avgt 5 14.857 ± 0.694 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterIncBenchmark avgt 5 67.335 ± 15.512 ns/op - i.p.c.b.CounterBenchmark.prometheusSimpleCounterNoLabelsIncBenchmark avgt 5 15.808 ± 1.073 ns/op +## Archive -### Gauges - -Codahale lacks a metric with a `set` method, so we'll compare to `Counter` which has `inc` and `dec`. - - java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 8.476 ± 0.379 ns/op - i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 8.566 ± 0.555 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 10.532 ± 0.652 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 10.112 ± 0.740 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 6.833 ± 0.301 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 34.962 ± 2.310 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 28.474 ± 1.965 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 10.183 ± 0.580 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 10.061 ± 0.525 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 6.790 ± 0.505 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 30.993 ± 1.626 ns/op - - java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 9.249 ± 0.651 ns/op - i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 8.266 ± 1.095 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 10.185 ± 0.404 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 10.669 ± 0.384 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 46.205 ± 3.406 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 39.633 ± 1.520 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 40.184 ± 3.697 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 10.955 ± 0.496 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 10.877 ± 0.595 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 45.394 ± 3.192 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 86.524 ± 2.633 ns/op - - java -jar target/benchmarks.jar GaugeBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.c.b.GaugeBenchmark.codahaleCounterDecBenchmark avgt 5 9.347 ± 0.798 ns/op - i.p.c.b.GaugeBenchmark.codahaleCounterIncBenchmark avgt 5 11.991 ± 0.977 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildDecBenchmark avgt 5 14.019 ± 0.592 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildIncBenchmark avgt 5 14.870 ± 0.549 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeChildSetBenchmark avgt 5 120.478 ± 16.162 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeDecBenchmark avgt 5 54.028 ± 7.432 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeIncBenchmark avgt 5 55.782 ± 7.767 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsDecBenchmark avgt 5 14.083 ± 0.820 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsIncBenchmark avgt 5 14.275 ± 0.590 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeNoLabelsSetBenchmark avgt 5 146.348 ± 11.097 ns/op - i.p.c.b.GaugeBenchmark.prometheusSimpleGaugeSetBenchmark avgt 5 154.449 ± 10.655 ns/op - -### Summaries - -The simpleclient `Summary` doesn't have percentiles, simpleclient's `Histogram` -offers a way to calculate percentiles on the server side that works with aggregation. -The closest to the original client's `Summary` is Codahale's -`Timer`, but that includes timing calls so we compare with `Histogram` instead. - - java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 1 - i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 116.902 ± 5.797 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 39.897 ± 1.581 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 17.692 ± 1.435 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 17.844 ± 1.213 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 32.840 ± 1.453 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 10.862 ± 0.874 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 11.290 ± 0.613 ns/op - - java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 2 - i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 326.477 ± 47.550 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 53.194 ± 3.719 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 30.660 ± 2.403 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 30.361 ± 1.727 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 47.051 ± 1.927 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 15.596 ± 0.660 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 16.168 ± 1.059 ns/op - - java -jar target/benchmarks.jar SummaryBenchmark -wi 5 -i 5 -f 1 -t 4 - i.p.c.b.SummaryBenchmark.codahaleHistogramBenchmark avgt 5 820.989 ± 46.036 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramBenchmark avgt 5 86.183 ± 11.741 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramChildBenchmark avgt 5 40.051 ± 1.309 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleHistogramNoLabelsBenchmark avgt 5 41.475 ± 4.742 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryBenchmark avgt 5 63.493 ± 3.490 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryChildBenchmark avgt 5 21.829 ± 2.226 ns/op - i.p.c.b.SummaryBenchmark.prometheusSimpleSummaryNoLabelsBenchmark avgt 5 25.150 ± 2.173 ns/op - -Note the high error bars for the original client, it got slower with each iteration -so I suspect a flaw in the test setup. - -### Exemplars - - java -jar target/benchmarks.jar ExemplarsBenchmark - Benchmark Mode Samples Score Error Units - i.p.c.b.ExemplarsBenchmark.testCounter avgt 200 27.318 ± 0.347 ns/op - i.p.c.b.ExemplarsBenchmark.testCounterWithExemplars avgt 200 45.785 ± 0.177 ns/op - i.p.c.b.ExemplarsBenchmark.testCounterWithoutExemplars avgt 200 25.404 ± 0.184 ns/op +The `src/main/archive/` directory contains the old benchmarks from 0.16.0 and earlier. It will be removed as soon as all benchmarks are ported to the 1.0.0 release. diff --git a/benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/CKMSQuantileBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/benchmark/CounterBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/benchmark/GaugeBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java similarity index 100% rename from benchmarks/src/main/java/io/prometheus/client/benchmark/SummaryBenchmark.java rename to benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index 2befc6bd2..31678ad10 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -32,6 +32,9 @@ * i.p.metrics.benchmarks.CounterBenchmark.simpleclientInc thrpt 25 9057.637 ± 67.761 ops/s * i.p.metrics.benchmarks.CounterBenchmark.simpleclientNoLabelsInc thrpt 25 8993.471 ± 49.581 ops/s *

        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 RDAJQE`lTKRYuD|#000vo4gmlF literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/fonts/LiberationSans-BoldItalic.woff b/docs/themes/hugo-geekdoc/static/fonts/LiberationSans-BoldItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..aa4c0c1f5e6d77e67c9213a283f0c4525bb24397 GIT binary patch literal 192500 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 O{B)xax;R`9w+#O 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 Qyh&K0{xkf1~fwf6y<;4FD2oAsEaM3K0+kc1VIW z$b?)dfD$N$PS6c{LLcZabahTc-6t)3^Jr+-fp46$3pzt_v>80}WPCD99n;;f)pb!1QNneG~!5Mw>;@{sr{pQPO zgdphNd+LTqf0kZ_?Rq7)YhF~F2=F0@}q~Js5?PzWY+O6 z^1*}m?R(&n6HF|}Wcl8`2Od5FiI93s)@nCx+kS%b$bQTzZ}{8RyH7wQ#2+t{*RNkj zE#V2uCfhMtw{*oVx1XT)BkY(Q983-23Fg)u>mW~^F=xRE(1GE2dwI%~ku~EcouE9@ z9Fq+rs%s~nVAjhSE}PBNOkQs+mV5UdFytC3l6&=HX6giVh4N#ve2< z^}C-=Kn3)3CbyM;j*Lx6PS29V@T2ku-Bd$w%g? zZs85hF0|3K6u-C9?01Q#75Sgjx1GL~0!L^P{kGC?hu^#T{lEEpv;3j?c{4h__bVQ{ z7(F(MYiovYZGP^#-}^0{zm_qj>2E4~u|My(_wU-arlj}i|CA}`>Axq<{nZrDj|~T> zLfO>wQ{mC6O)!2~f#*IT9L7)1^MCv`yTX^jREAB4&|l7b@AiGOYo_v>+*=@F4EuM~ zfPF0g53oR|e4QowKbn5ZQ@lSt-`uD@?>%_I-`3nlBrU5e(5!^J`BzEnsO1vZVwJ6+dqwl5W~G}y&K4R(YPi?Di5e3ke8 zVx2)EQfOnW(TYeCQ1;o&XZ_~tv0JTXyIB@rym+!;}K+aSVus0`^?ZCal@D^a?x-4-pSvAHbjK z-`V(?JY0N?UeC)VsC#^=*jfyCawa_H-tFF{&H>m>udfid`0yDqP54?YSGW(l9~QS< zA3%v{hL3R5)tql;kcTt)>m_)+XD)lR^dR4Nuf5Z*l_b4_u}-g%K@j0_J?z!PW<6Bu zp-d0ide3ZRzWavXQU+Q|hZgd+A|5h{l)?*>;ANtaD=d-XTrxMj#%IuE~kgk zelbf-kf3Oh3i!hS{qRos4PkTrv!E!1hq3||%8JeJe`wKLiN!$38M{?4x7HJTexKW9jeEpB628bII68#?%}fOMe;r2oK4R#-br& zwK#xkijl9+OQ9CO2$i88s1glD)o3D`i58-jl${}tgo3vDc`2T6tLNM1`S$*y6vXB226%-XDvLjMdNdFEM6%-WV0qoNq$rA9bzH8lw+ZGoV z@{8dg>^Cx!eg2PKyp`dZT=mmP-;j5)ccb zgs057G>4Gmb%e~kAY7aG{*>c{fKWH>{6e)pr%~N}Ok{DetxQjXun3smZ=(I==Iuy6 zt&`A9H`2sg8^i^#FI;eT!GbgNbG~@%_2szJf-?)~F-=^^Ry_LW;XrMi)}ZKUEQW;8 zoRShv;Z!eK?YVsU4b$Z}0+y6|@@%G`DJ{^@f9%0AW2o}+&ptO2Hx%tJ$gzAKu34*5BsWp@*6eko5 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 rBbpfCb1g-Oh69htxp;Gue(0Bj=HUcCA&~yYK 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�?Rc0&ZOH4}Fk&=-Y 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�y2t#*2gkoSJ@bdi0(2`_lOr9>f1|znU}swE)v; zBSv_Qdb*>^nZMq+R~M0Z|LTe4V>j1m@@6jIvS60B&h0BJ5$2YQv(!U+^&P1zTFz;G z?5=nj{{?teoJMh&p~Jm?xcXS>n7OqS) z`-F8L`qOG=3?18d_=A63<^;JGJREDJI7B&zzy;D{iz;$zQLBt1NjprQ3l7qAi-fcs zJ+3&>?zjS{t&nTLq1b6W+lD3%GaM4rb(5vRblZm({`~Voxn@y)15G~}r+-dKFCd93 z>uGw7e}ndbJwVeBZm3_xd{%AYUxF*dt+*|^QykOn(E0T-%%b)Mt?L6eX1sW88(%W%<6V5MyMonA(_NL3$%f;gCiV|Osie;tnoQ+{9BZ`a{;#dw`_z;t#YTnmxHcuitx(73tpCOndp z*&4^+R#0BYa#mroB(h8~cS2Tr3FYnJifwZ0R`gGK>}#(_$}l=r~tu{FRA++mFd z^M+6Fk|kbF7pR%pod;P|l2(96#Wl3=Nl3q!HH@ESComO!JLH_-fKzPQ8#sji9VQF3kKd6fK&yav8|q#%2HqrWklq8!dv?MM|Q2d%~$)t$E*gZN3gg2Ncjt3X}sHHxnjj*0QC z7E{eCJ#{WBb>sw0y~nJaZ7S;bX=WZ8jmB3_U5rNe>#&~;O+4j5@)br&krLpFc2WYt zA${?FeJXY_j(g&{D5db5{ai`F{*=5GF0Xk4XId_Q^~4iw9UhWzg_C3JG3H6ea>0KNJ_R}=FP?rbp+3U!~@Jv7KXO+UV>uH08uT2-T$|2l~5 z!9i8yCj_&{SK)EV;2XeS#SDz&9AS-0D-cb7Bb^iv(d857piO`O*RdNnjM=bp?8c2_ zHuA5G-n?n#rcI+aZ5+9g;il>QJaDJD4YwKdzMM`=j{Axj@5_ZsnP;`0FhrfLIUUIm zf4S4R(3?~^b*izjr`L=0^Z0o~4P%qb%QEwZ7pjJ+a*LC?bqnb9eTNb}zEsq4W2FK* zmX@=kN`i#WQ~rOFB0pr{KY6K*f6&&vhJ1>;S+ky*HH(eu?U*^klc?6=PgLm;QFIRSK7I+DCHw|F#O6|K zP@7CH;6TWtZsZ*x|3%M7FH-qhi2}i~twj98;3e;1B!f6!%^IGaJl#4$TQIz$=dd1A zdvtcsFi$kk7~O4nkEw#ox^h-+kAiun^K2_`Szb6l1UPvsKMih@5O9Gc-~*k)7Q02z zt3Yy!-h<~~58NqkjIh{MIc88oS`jA>VjFcJQUwz5Y9JEo&YZ!0DpEt;t#dM0kIfy@ zr$1c+`+g}Q`6_B^qQb+|GqD4 zEdGIiuC0x=6DF2GRbrd*3p{T>;2Af^9>=@Iaz^5KwFn8;&JWUQ5+sZ|vqJV@2{iBh z*WSJV`q!z(##6_ZE{)3?W5Ef`yNP&JVYZiAVNneV#<(HODR*0X;>2os?DxBOe~;6< zq7FPbm#I!mP46BNKbm=<1oQy?@a`QBB48@01@&MBSO>O&8^JzsC%6Y32ER2Ota{+y z2Ofj=lab;A44NXYvhHR0OIRIA>JA5*MvWVVpUy;V<9ze#=CL2r>vRXQ7cXB-f5=@P z-nexm`=Rev?f!|k+N9`7d}DE0S@EsK<>ke{g-Xjx(#fM-Tp9|MK3Y~%QijHa zN=rj68$X#3hw@wGQ=iOlQJ3O>=mzq+x1_ABBzmNztTYrL&+v7UQI3#2zme>F$y<5P z{P|ousWJMLd}{tD{Dw>O=g)6h1gmbw>2mR({1z_f3;YG{#b3tbFVO~4dGjSW@b}{R zm(csA!LHGsB_*Ldii^vUPe~n(g+e7?;)L?sWyR&4@z1!-mPPaD!-1EmezhCF296T_ zc-`wx@!~l|)#T)?pJ~TO5$(9JTv3nX^!@ndK&E!ym^*1R?~WVg1no?+kw?#%F}iao z)R|vCXUy1HqeF#-?5^Y;{JZc|aWl?u#uQCs4jVaQkErFCl7(q=iX8SfzM0^#FPCnr zMPn-mHn?lEkLP2QC2rojx}x8J9;>#=!!V+P@=NkiuoBmRMS#;P1UWSkKNv5O$dRl} z;7H^{?Kl!BH_Kyyjh-DCPNM=$o^a>hn1oAkva<$T;!#6~^n3w=NNi0{N6(gcw19DG zDNf%^(_>s7)~Yosy*?pdFdw5)Op=tLXD1{lNEzrQR;f~!d_Oxa={O&v)QBObhIBrd zYlRYKyx)(^#i*GxNAVZR3JXJ{XN?_8d8sFJPGmqaZC5b&wOz83+Yuh9YF3o$*1>3i>v=cTMUuxT^Q$ z9q!HQk*@~_XRPeB_WDjMGKQ4w!hDYWEXLdYVow7rNCi2-A2tM%ll7gPPNN`k=gfLW z-wC}9CLFtDwF=Zu(p(`P?h>yWA@L}tUu{(+7>o>?Q(HB@sA&AKInh^p5Bv%*oah~~$Jl08Ge#v_pQeC|&^NXBG*`=xO0V ztITsjG1`2(`3yfuNG5j0(be*M@a5R(HW~46N-Fp=NhQCxmW{(m{sm!^5W^JDa>gzh z8m$_I86{FGB#ci+dMmkiIC;zj2%GYnHt&NAD;XVh3*< zGkVm-Tkg%y8*{w1{LNx1UXQrHnnnq>_BW7;3+APO#qSd~Z<;Kh{`On>%;Zg%Q31;5 zUs%6%>3XLq`l`#_70QKfYmj^0xzZ{BW%tV6 z!j=^)TBf1qsKCnZN6Y>vF1tZ~PpNMbZbK^n1%9_Yh7{e+cz6lE$N!A^L5wY|I+IEF zEjj%8h6Vtj*G|YbX9ihBQfl?FLIkFH+so&U_;|yP@%OK(+oE0}^yxFEwj1hoDDe4# zZR>tnv-CQ1#jwe*U-uNQdo27A%^`R2g*ozDO5Hu-W%wQLtBc5aj>~|vX}&g+%l6ci zs^X7s)(1H$r{jJ47gq*-*SJN`JLDgCQM~}Uy?mUGN1a@&)PFy&e+U0hOeJvrTFH!z z->R=jUsK;A!Fco!T4g96Y6C7!cMn`_QSPmG8PzQaST8R^15fOqJXlT6HZ$>< z-Y4ufiNdl6$hhyrb&sdxzA6Tkx~=$K4*xk`gO;;UQi)eMV!KsT5u~Rw91K8?I?u4e z&bwrJ3#>ZTxZ(R9^7GH)HkZqp-@B@gasyF7xO3zS&lNt|h`P5vpFkSYkq;XFYq*QJDY z1^_e~-eg8nqk&nFx1C#e6!bp+LqU(82fK)WS-#35B1b%~6ZZ{%&IJ9bwsAk0+tSpQ z&Xk4UxLcY`@${MU@9<~7t4RdRKJFX-dDLB$TJIyE_TxcK7QYd%zbMHu{&_!4&yYW% z@^A}(9BmhSDLi*k*ug`M9_o#1Q8ZxD7-7+v_^8Af7XRllU1+-&R-RxJ$z>>_^4rpm zC#4qoWB=YX*gI`+8h_jm>oVk9QmLSf*T#MT_^*ZaxS#0&m?f?}b~v^Q*iIo6haQvv z-DEZkLI%t!0Tm^*U-!dj;LYd`j34sCN%XPKw3v}S1F;A62dO-3VxO3gU^K%D*+nmz}} zO8O}Y>4)Oud#1Mzp&So35xtIwSkR83Lb~p?53n7 zjiz-RaQQC-AkC)bcZYkG@;_qbYf1T!HtBR6*H%8>c*1w2d~QNAOYLB(JCW4Ao3gS3 zfyDB=U}XHX*vpd1;RR|IxvoV3c!?K$s558c&y5zBpe7kgN&x+6olD|#Af1*`f$KEU z=L|Y`6#(*o5!U0iQP<;CRl$V$`%5IY@pkfRm?0Lq9(YEyDT(&0b+0 z(@%VW>v@yf?-@X8*aLw^ zcJo?yO+;(uEj7e@a|hqR^*J5F#}Rjq&q&e zuG4RQ_y`>T+{M4K{tw3!kVgBL+uGlI=yMl}*AL-2{sPajhTJFB5bH=DsB|i=hF5cv zN(F(1OiDftg9j6D)@1~^%q$Xp2nP8tUUfI;$_#0gH%aHqI>g`+WTYSPgR-bs3 z)>qJ4|Eu)5km9d@;^!J_Lm*+=QXMYjG%8{v3iYB+tHHyq9j0BY<&4@2?J@1gT0G!d ztq$Y5b;&ZY?K4m6)VZ~$$( z=vnfBaJs}Hl~%=(Ah`yh(Q^`y`>0l7=7#5>2H>F} zHO3tonS*ifs0jg%3JU@uHPPVWE|XXWezaYVBy(S-v|NUbuIMRldg?={AN=k119E6l z^rr)4J|4qum`K|cqVw}EetwHScc=T|`q(exbYVMM;(m4ayxs%nA?U)iFNhIHth(^lB|EcUYt6IgyP0pE9t5%gr!tO8!+l6bQ zm&4N1OH9B|z2_D2SODX5pcJTpic@e-ak7mXugKrP0nmI;;HkKdD)3QcfI#A-6B+-{ZGtm1rhMNk%$IWcW@ zanFL|#{Jh?+kz<5rsFTpcoaF_AK=i=k-;zitsVdDc+;JCmfidKy|b3wRg*OS*=Ysx zJF;9m5*~T zo1D&oiRZO}Bt9!!@A0H0CneWJk}NuPO+;q_)|%EpKdt`x%n4z~*j6F|7EM4Pab5hO zQcIirPbXm=ikz8<##~%+8k%mBKa?-uUnHkQPv!jM-ygnw`_Eg}?aqsSl=7#NvxiPT z0fz~DH#Z-Vf0TEQ(;oO_DD3mq%OCHMqsQ<4YUC#ewBupk<8Q!zCl&m~S;Ui=-^e9& zO%4A9fHSN|kQXu$JgyP}qEw9#wbu1Z(|0FSRt;eoC^^(5hfc5Mq_!M%&G(O8;m?T@ zrk&FnWrj2G57w|2bv9?BMV<3pDoSc|l=Nwsr#nE?&sNe~SbCUk&V(;z=V+Ym)00@Q zG<~g-{xc%_emp1%*`TXGfAI5ye8+cr&(3okR!1!<%pV|`;xhz{2r{;33Hd|+#)hnh4 z(s57H({;d;Oq|{ubq?SpKJYun8C4?12d~*TaM!tJqmwfB<=3r3_cu3Rl>hn6FMK{-CnR3&MjD?!6^soR7{v+^S$WQE@amJ) zE?1J*%%}KL{7JfGU3J835XEexrBVdRzz&E{;oSV86s1UcejY z-qU~F^t2TxxFE4@$OJ9PHq>b|v;M<3d{>OKQ9w+58IH%GO|=!T1Vi3)~1*u+?p`0TTZpWI{*}0IVSBo>#jM$h5cp zx7X&^nJmEf!((iq+)qW==dsw6laXD6G=87QIy~a>NI)`HNAL=94sXRNZ40D5-|sWq zG>|D6Jg}52vRM71-2~GR=O^nQeE{dryyugfAAWMq!AnbTe5QN!Ef0Kh&tpANfp@ZS zUM@Q-_m(g1X#VU7JOPup|9(HT!KA%QZv&SL~_TD_ho~MOycQCa_EGb6K%n96f|R6D@;C z03s|Ql;SNDLPI;r07e06nT*yT3)vt@BxDT<6iaaEVkmI~F+LW+gH*`3_&@fS9lKpK zLO4-#{|6WG&5mJniy~|IgS_r#^y9YC%1#b^Yvf6AK zmmD!Tt5$0?PC2wA(QUP|8jae<7zNgeuMLa>moObNVWB-nS0J_|Fcm!^9Tc5ODo!V5 z$QzW7rdrPF)$IubMM^7=gQOEPl&_9{)-mPy9;42&*fObatAII&??qpZOm9|n{rE0& zMD5|nW@5S`%Lm>=u(L$dpqoV~MLrhNDNw6(>4LhDZnlmhG%B?L0nSJ?LbO$|=0U%D z3&vCMSa^K>5UVp@=m$HG?&zpKqMLH}=W zz|Rm(^AO&$h!ismSvQnQlaf+0VRnADKPN3SE3+c3w0R%}sfw`FW`+>zvj{yFY$d{0 zO<_TE-7;bUqk9_W&3!>azno^neeJ#U6>e&P;zqEa}2 zp9eqE(-1N|SjQ_}h?OlanB+}LcBzaGV@24Z(drBgDKJZvQyQEUV?GwY#5dS2!RRm2 zl>(122*mHklgHtYW!|QmuI*~%^Z3zO;Q{`$;f<-9iVb#~?XdurV*P$T^LnLbq4DMP z5_13d{8|3{30J|pH$o=$GNpE2q^mb-bM>IQAU;XLnn$m(Lk(2Bm{1+S-!hy4GAC40bKr>ua9( zY^QP0_FF`Cxp(Urf9b_mou=_U;m@RO!KJJG<G3UTsv`krY=$sZ;7w$W07VG{_{^C9ct^&kA+xF_JOaQyGk6D%GVeNX5Isu>tb^ ztDkNK*&mZ>*41l3r$zjOJz!#L*C$WUX);s)#m%drXxBUmwPWWc{{5W`$l|5*J3amO z&}CZ%UhRnNsA0k`#zsMd%4n2Yr8YfMfqEmNJR!hVnz%6_IwK**h3WX!0bOO*Y{ z)>i(_1x$=V=fjh6uCog~S(rucN1q?v`AL`vZ%_;MQk7n1wrG*TphW-(TRsz;ih=lX zI;|*^qE;pP*d0%*ZyvwsIqQCkj~sgb5<3B@nYHbU-vxs}i)HI(ZTX#_cje3rt-F!s zh$ih2&;LnP3j2R6gN?-HYd?#fNw2*refQ-&z2u3KXV%xezs5E zTK>eOu^ER~weMpcH)hkY5-N1%*b4r`n?q@S1lTD3`4(WosN@Cqb@!()-OiA$KYVGy z++~r|u*Zu)GwfZV4!RfhBo#u8)Fzm$`9^^rAGq%Tv*`X<3oCI~eye zF9opXm&gd@5BFRaQcibd4xPf^A#IU%weJhOHi_>^@1&a|ymtsD6H293rP9-Sj+Sr| zN0Qwpq0tu_!m750!V0xfrL++-JPW(b{5cN?mjn$ZOq3=ux|6l>K#Ym=li$u=*TXXN z#0<}}pU)yZ^Ih3V$EUJOR{nHgGH5z)2DvaY{rO9M0sk0SPk|o65IH!qB9uL@ilkl< zQphl5LF2rpn3HXJnY=Fx8xjc*AUT$>g$7*ePe@oAK&g z(S}SCoxdc=M6u2`Dl+4%Spp_1Hgp~5t|YKe&rU;^RGiG;^xUjZHcwuxqZ%KY{`BER zzwA`-zn5`+dJbEWl(#oe0eTFdya;&5{=4}y+r10B`IFDhS+Zo#2j?$2xK><%Gf1$0TuYev zfJQHp+sIpp6`#P^hGk)TB8aaFF@jND+$A*wo|!(}?=Z1fn=7DM{E~7G0Aa*I}{63?vagQV9O~}P@V06;^xPIN|8M^H>(3uNs~Etm z##dL3>AsEpFTazooHDeqx?5RNdftknu5I%B_3W1B4{QOAkI}~u?tbmdo2|Qnva%Hi zCXMafFHew9?-GP$D!l^vBKbj!S|wK~6)MP)q+X^$FBCe0u8XUd#%8UU8mwPt0NzQ6 z@uyu=^Vh2x-J3oP+eFfx$lWk_xD+VrTo#BZ*A2~&q!IDUSQrEp5;$?I* zm|OHsHWkhT-NZ=Y#;XK#6d0kHeih@PlBqZz3g;!nLoFvrV8!9kQx8tnm<+1=G1Qhw z-{sLabP}?$K>ubBew6eSbS~b{*T@b5ot~MgG#Nb}j#JVwH^-dJCWpc*LdF`?(wt6c z5@KvoQve;;oP&LZdYh->s}Y5rx?bZ$LM`A0qQrAYqlYm`eTLp@o6u;%-PO~V$*5+B zr*AnhcHmgpzwfG^jcQK}o_u)7(@Aaiv{E66mrdDl8OgLIbC=CNe{>CKJ)`#8QefJ$ zwf_wMgjGpIM>Zs%~8|*mC&^FnkQ6 z?HIl%&Uqnw(}nF#6NO!BKmm7>Qt4r>Rbjw#Qe9P8N(n)jXv`EO3=9>A%ZkB&e?Fzd zW)=fEB%TtIn&3gj*R^khsXw0tny1e3dp|D!a{bpk!qIFd-xF+gg8aX54s#X%*THZ3 zC%@6~!zFtLUgSSp^wvj*K%WajLX#AElj>o;rM1brS^Y z4(DetoB{2g`{>o@_?lA)PO2M7TE>4ff88@>&-{ht!c~HxZzG(V@irZfG7$(oi$Y;F zf~v65NJyocs<2Wi6;gTT9Hn&yOh$hIk^=)D{QVMW|IWuCEw?7+jrHq) zSn<`(X5E2952)*>K=Hm4y8`3qPWxry?xT=zkKkdEfAk&lgBlT~L1(H}?tyZc!Rd6F z(5gvINg+bv6dPVej#r|^LY<0(V zSHF|>%ow!)NXf1YM?4qXik?F#h@zmKq-h|9O1WGGBvoN52!K>3BdWqOD2>if!U(nA zs9RbltboNei8w*afZuwM=gN+!NB)|50chd9B$S`6 zrmC==kR!b!=jsI;5sBhDG#>RAbt4Sn9EF=97hDCS zA_f`Qc7@+dej_87=aE+;2lMb8O+HK?Mz)B97##GgXsJ}mAaSR+>77ZmgppK-r3}`? z)nS#AL4OF7uw1)3Y(jum#W#}0H>3YUGFm{VfWy>GphJiQ1*zx(vpR*aC(1dN0MFZi z4|IRo6`7Szo^eGwq>%@MAFo@^e=)jxH)wg`5=eeFa*q!`UGWhpy3Kz%9~3`5h`%u( zpC5&9A zL~esZIGb8S2$6B22=AeDM71nF19pGu)D$0nAX5Sqa`8xpTz`h*r!)e)j5&P246tr1 z|Jq5A0$TR&#P1r`obf+GSKg8YvH&BOD0%TwRJ;NI=AjC*lG9XzZeH zZJs}2l~nYlP1v^LbqCy7M#0 zk-GGo7i&`;@b;dQUKQ13hkk$m4*Peu8x1$s4(k^j)^GDh_*!kdF2z-SK`VIj{zq5u z3|af^@fPj7#A3R=B(snlD8Mvf_4;h3-Q|*`BD+?iqza3&k%^yeBP6m^n?~a`$&lFt zWp&%mW5-Nf^(K0uVi-5!piII^6JOVzmCoq6b?}ob)m?WEU$ojV>*#c?v{R4q2V9fH zSK|)2CmlPNw(yhZYunr4!L3Jp&eNm&PaZdSC{AdQDX<~qeU?{iK=>e3L3WcqB zX}3yO8P=$PxLP>6mb+g55i8g@_7m1sCaf+aUw*93p2s(CR&{YayQ+ByXOrS59354a zgJ+$!Pp{!WBh&kYHm}I;2-d7$YuIgC$4_sQRZ;okdUEFd0+DxqaYWo)GpA#P`QjUbhTnpLlWA z*dE2J*N1QPTW}ue&X4Z6>FK*al`X!)e|3-F$N%JRKjY+odamA)+b9yE=SE(4H2&d> z$^4tYY%a(3d0UZxS43?fvWOC5axg^94k~nYtUrSAoosVl+Xl`9S{1lSM!CNZoOHTGp*a2S#Mc&tbm{>U}7Xp z)Dx)d?KZ_iA2Ig9QL!kQvH{t+-Lz1vW+NRPaxxbFzPWW(+ag;t^+w&e?p?Z8b{V|6 zAKmTdxQTPdy*zcs#-jYeySq5URF|~k&VBm&hWIotV}30T^Puk#ZjZ1p0R)npLu&H2Zpqknz=%L#5969WX{M{Q~*xqAi zpI}~7TX00jp;KPi-K?#rbBCY!|MuQDX55hxsU^vc0v!_1mx*nUMryUqkdi{#sO&6t zikZ;s&1P*VY^E{@0=Yjzm9Bx09^-p;Xjk=ei&Di4f;J z@^l?{mI^+?U?j&X&{^C>GSMTLG)B5 z?NK|p&_dD3TRyd_=k8v;2AMpAOBY6Zf%oUq8zv6z7Ap4U^KVDIt5=g>0(Wl4>Y;4 zoLtbV`CNYEmJg{GgM0N1BGZ$<%&%Iu49o)=MFn#Poei$PIbz(1sz_JdT0#;N5$|n5 z_5|Lw-Z+?KlN(u&2O42UBQB{r%yO(uiEVo#rMkWik&t1>pwliw@Jevn!;KUV4x+gz zgPtJ?uApw)NOO{Wk^h;0ultHCfO!)vbMP}?d~03S;7=CgK%vrT6cQ+-by_W_ z)Kr9(05EbU6lUcblBx)k#(G<;>uXPR6H@|y&dYc?H%BvG#LhiY35w!>!YfD3FJY~w!{_4r;yTO1ooA=(C0G;)c>0ZIB? zw#u-}$PuJolNb&n#9&ZHeEys+PUZ$dplA$8A_sAQtuFL4^egDYQqK!0!6xLpc-e^ zQlraKg+|pJWc`77g(z0w*38Tyt6pF7=6fsnzpuSMR8h8e-T7tvV3T&!zW5X_nJ{zN zbN#1}S$w3*_2kDt0_vGA*RCGppFO;@c}dmSyzo@Jo`m$vaPsWgPx0?8n7(KYNU7I% zBf)()4<0N7JeSD>873*_`W6L``tn;vt7`q(d%`TiKU=fF1KjV-PCA+ z0-^_*Oc@HxG{6`N14F|C^Lne$@#x@anIq1&BC&~t4^BF|$=m$Bv#)mB`q?rdvHiN~ zdJ>py<(DXb0;*RpEe7(J1}{Ijb$;W(S0ayniQsA@z|}gKqSLS@O0K6Ui`=Yb5m;IT zmR5_1r3i)PhInxGVX*wsiQ&j%6zxMVF3l|pAQuAHNV$&#)w!$Pp8jMFf8X}&)=SC! z5-XT2`-#6tHGb{l0{;6`{g)rwH$SuFt5~hRO{j<7A>j6AEG|r36mUBZ$?e-hy}VDr zZF7Qubf(~Q~fc!7i2a$E;jQ>yt~OWfT5qJ0zA(tm?LV(Vjhv$V<_}i58V&;RK><2BPb7Ojl4=kIp_! zXO(9-f63D2Y_?o<#7AX;3L`i+UWs8UtK;4o2%KBhi0f#)86vd$g;qY^bj7rFZ z;(cX^7DtiI>m(ivwy--KMjgdb3YWsIGgO5&x>DU?9ps=+Cq|z&N~e-kK_LijsS4-X zgZ7Ypw*8|0O}oTy$3|9u6f+4GuW`{Qcrp2+nV(!gNKFasDf(t62}SNZ%HLo51{m|@ z`@ok|lYD*MNBo;b7i!1uT>%OTAWGRal1{gI{$(qno88jR=LTRi|ZHP!(pOLMD+_g(X})e<;dK z{W3BdR67f%h)@D5rg(HV92~}7EmS%PxLsPrO>Sxy@1L@8*TI>Mtw~&R`-w}#dtu%L z&<06l{th3B?79mkfpHtx^82XI`KS27{Qed4P0VW073cvUIe4Y!jc+yr{kSKQ&PVr( z!M#;Fbh=@|00SYVK-L^#)My9_+U#8}jXFtZqRLWUtEG>%*Y=&;C^8Oshn_O0x(3+#2*1|g(JOB zu82%P!u=rGE%7A6eMh>*ht6Wg_1jYP9Zso~07zM^8dhgE$Pt%I33*T+l0z2C}(aDpnKPPQ%ETbWjNvygbV4%HK7c^!M1=5 zAhQ5kK&8Le#FPTScJQ)A)S>&c;C}w^-t_%D zjxY51jzrL%dzC3bu)ia~eji)|9R%5ff!}6wLQOr{Q_2sguM4@E(x8(j6@)}4BS@%J zNg0Mhnx7_d!a@c}odP!^V@+IFq*Gtea&D1#(8U0^L%ahq%kL2Ueg?T*ju1Z_Y@+A< z?W8`xKT8;%+^~lg;St#&)X#zqqDK~9I;BFsjg*usp~0wBA$CBn|F5`fVitus9eK#g zdR>HdH@6;Cm?;|GQxJmNk|OTzpmpqK?)f-&GwC^7__754ZP;5IlkfCgR)Xa_l0&T! z4u>PS)yR_R6U;Hlv?>h&Nmi{U36+dCNf^e+YE{~*uv!HT8bC;CDLM|VLq8Da5(@RW zV()Ccn5bTKJzAsX$I1#ff_e5Xsg4z9ITlsxeR)|UJ9u(n$n52#@cAT zadaI}JeO-0f7H;)5)(Mlf!}zO8Zs??snE|Qk$xnZaK9byhQaNtNTowB9O&ugioE#) zxizQXTbI_9ck148%7rOqRU?;jW8Ivk{l`q6-R!x8y*3Y6d){o=H~!Xd z(Om6I!W|3+bCt*_S1Ayes@o{KD@a;lP^2iJf{{o_0Hw&$>Ol9VNjYt$8_|#!WOcuB z(T-!p)#zl2YkU&r8+b^vHIQgA{(MQ0Wv@kL*`HBarb4pp2x}&o`mzkmZ3H_OM-R+u&h=p)oTqpPKUlgc8QjS5=GQ3sSAqu z>$1}MkFrF7m)grK8=4*!{4Zx7VQ9qqnIG!yj`z|x?5B?Y{1*N>>>B?%-Vfc-pKREh zjLt3SCE?s{gUNE%WG`doDy2fD(5p2Xg9^FFzzA76p;jP2vo7C=X@HmI)t@OqWaQ?@g_(o&F|O#HFC*neIxIZCXI%jg9mGWh3wzw zR?llL)CW#|@NbEdUWPYgpnE4s|L%`Q26!~kM&U@zqZ_1qe#l3j0hXhKlh1mSzXEVG z|F2^sGtXwe+xeBxcP$N^Zub7iI~SFF@Yj2LhzH9~oVa&q&jVulmtU@Y=iHWKw_e^_ z^N9XvtoJv>^ghz`gbW*Ac)6xbhAc>hln|QOktHeYG>WOGN9g?&tdycwBi$9NB5Wr9 zPTu_e%c=ucB#_UT-Ey4KihQ8jaLw(CN8o&v{I7 z)N9C&Dt0QKepQ25jTyR&Ffa10nlSbqDHlbh|Ln+XaRcbXMr6?_A)hZP&(n6z*Q6ol-sHu<$hQGez zNF)mWEBP7`=6;p{(%TrM+YPBBP>2-n?H>(oFsTy!gAE3iI!GWk`Cn|Xz{55eIgc+) zB9~48$uS%3>PMi5V1vDiO!N9a1Qg;^yfAA5cl1>TvnY)Q32>#dS7j^Bpj0R<8xStKjuA)F<%!y#q*$8L+FMl6SuoZ#s z!oTaxMWnE@FsulX#wfT^TlN%!SB|)*WiXjgD5PpiN^yEZhcHM04Ka&A7$gWOk{(hd z@uj-B#1nCt5VFN6di&W$O+i2YBL8zOKl$zRCmJtU4iw*S?sV>sfbY@=KQcd} zGwKNs(LR`}RjJe#xeG$M8hVqpN~Bn|YE}bPY8_**3NsvGs6RJBlrtF(?5~7bFM+6U ztRv`pBVXvFKnn8d*ZF5YblChNzx~vE@8MF(H$M^Q?(9MLa1!Dl72@`AFjEPDN}*7zr8;CpN~LBM zL6{UkX+Q@v8Vu+=YQ#Yh3$FOkmnbz78i%!Y@-tfC<`p`flM!1Xae>%h%+0&|kc}2D z1L>fU?9KmjVI2QNq?Xe0gU?=iW*t~a4#|CG&bx2jpGCHhoTR>;v3&YGJi`dt%UMD! zzqLS*5$Nl)^j&mYQxX5Wl{z13(OH~n&U7ELmT|P+aNpX0tH}$ z^HqM&#=&K-m2einD?ha1>9#BHbX&Y&{%hx-;Qu<+2Siqa!CySpJFwHzwB_g*R|1(J zcTykx2!EwoBdpqyWfKnO_?(=RFf*J|NihVKmI{4#pS>ci@c{+&`Q$9?358jfGsq30 zuu@)EPE_x5)Hn2n_Eo$SCsuS)!sN#Yi(J^}*W$W~*fIyZCy{g1v}w&g(0V+CJMUF=-jgh*NFo&n=wtQ8;Kx_L znDfoX!AEl7p`9JtHR?Iw-vGEu`2W5?eS4<|Q#N*;ssHKPc962AqE-7VZ`-H2`P=+k zt6$>p^4~951d^(Nd>S8_ym+-3XKI7akt*C7p*HHl33TUQ7kWvT2FtVr38B$wa=6q` zX1Cj9QYmehL4*xx3Oj`76&Z&S?wCIuIW!|4~~0+9oXGx*upzz076#=}GM3JWs(*7SAc z7Iy;bi~R573V%3rh7DP&YQWceo*{es#)FQ(jPKzEAM!p;W_Qqme`!&21 zPrHZsb2ill@n`>FK5LgHBP(3#O19H!6ojcRl~Sb)g;gpGp)mjs8Vn-0vVOeI{bnYe4UHF>*UgyJK3x2I6njf%hePFaR)hw^)*W$i?8R82a(KDFIA`eMLYPHC@ z)hRg!dyhJu5;?al$ySKYtx9PSJX=l7v#oP$1%lVJe8iNaKvphFRtci&A2oe_&Dw?U zM@e|Dq<`NUsxj}=7gPa%lw`jfcrT{cHpIta0lwm(9cW2b%j#t^4j_;aPqG?DiBo1e zVWvRBWE?xd!1)Ez=0s#V=k8WP{-^@H6_Ne!U9LKsJZ56eL$K1xc&a8VSxq!lc!Q zZZ}9m8k+{28F3!cax!9}8Yko-MLL%Xb?fc%Ofg6SnM_V0H(4fU&@n2)WDY?8$tAP_ zT?9oPef_a}ZBA^PjHbV^`7eeI!TvD#GF)@Jriyn|)!atpECSd6z6yTgIjZp^dfPEP zK?Dy&>vxggew%?Cs-wN=DN+kc=oKTH)Tl7Di2D2Xw35 zYHy}OiToCiA3~22wrTBg+tezeD2K@jg}n~Bh9WqIZI();hQd}H(~gE%qD57LDHzuc z=$rZRRBnQnz-DX2ZcxEsE#KB``b?gQYP1;!b#DLMWJ9IOg-Fp+vJU+bt zvtU=`W_9;-dv5UyPYv&{7{%Mk_5-^vtK7$Tov~~^e`@Bm>9F&9{+%Ur7j6U{pPV*b zz~3Q6%ccVU`UtcQ^TVmmh!zecQ?j5{t&(ywmQ^UQ328-+0Vgw=Xl$4%6&eLHZwxB6 z4Y{L^I;Ja4uxskf{e<}d2?H)L2YL%)6EK7>?q_F42fLhJJ7QO8y@82NcA14P#WZ2E z3)#Q6edKGfNwFYZ9PC1_5bydD!~hYY-l8~YgL<`GuFxyY7PVF@!M)o`l|dnwn-axe z{a{QCxLBFCx2~EPtZJp~+@*M8zai+Fge%uq&RwovFSE=7J}S zo8cuO0LyZr#ypGY7tHlJEg(~-lWR0;wOpadbi(W$3$h&T>7lUQXhhH%jcSd->+v7} zvtj^7u^Df#Y>3Q<0hTaz$b4kMJ*Ap%>C|K53${te_UgF<2)XUo4t;W^I`r&FvHTqW z^q_qb!u7(*fsW-@caVK+U#MD)P(8l)6M{`m ztW$2!&Ps)81d)-EmY$wvXQ|x0tZZ9)S{j$+aLA!b&uLT^q^gZVQIat;gUCQCO3(vQ z=81VKXpj?En1s#myRikCoJfPu=+>l8>$Z8S`HS$+9vTMM9gE)iFBclUORkN+pmn zM#P~c&_Gcw$3txy^?FcZ+Sw1IAo?2sSa7@MHvcY$@>Wef2(i2uprld~fE0W~1SdQv z=s5#X6trmxB~8#Kqts9lmP#Qb(J0kW-2ib7HqJj98hGvzfIJEaK*$gbM}--B(}U%5 znZ?R-9C9M8GRl#}Awx>TA%BkJ7=lqD_d(9etL04TO!A zY7`2kQc6ItM~7h4u`;Bi$9N2Peh-$Wu$nMD?h6kHCEn2Nnr|{`~nOSzu z$W0vFvR!d|Q-QNd6Wvlly^lWj{XEM&M~wqyS@^dz z>~vJiuW=%SPQ6&#tuJ{^9OHJKIx%nU+Ib&8t{0Vk#IS7v;$=6|^|PY;c?SoT7ZhNu z0=%jCRY4-7{$fy>kzICJ0jd?Vqu+2^9c99}YbaC7R2nJ3(N#J~BTt0Zi0&{txz)_x z#l0=@A|E1S+_;Q!Cc+d$(p_h!M!NyTvQ{H_t9nWP z<_Y}imu@Zj`N+P@@*|SRdM(?Y3f5Zr36h~x$4)BbU;g0L3!wLb=hj=QM?QCKUO~?6 z1p=?q=$!9S9g+RmL--oe1^hwZV12~BYlK!pK68yAK0J-Y>cwNl#bq*ljzB#-<$ygLZgM=|4 z8^mbPD78rC8*L8gsIO2P4p4ol+AV64H1x{r>08O0qInXk@1{e^qimJ>etSck0O>4A zDmoV@bO#q$XrR~Y!Fg+xCaoM%aSVA)F4M0*4Z^Wd<1;DK70p3dx7I&DsI{!=vSdbfe)gZ>w0a+_*q21 z8OvxlF*;akSJ{#X9i_KgEf%wx)2k$UiN^~yp>UGHj4U3TnZQ@y1);_aelb5Vlh6#! zG7G`!^>SHEj|pPB-?&H4oe?8-LJ;|pJ4_N~HJB{Q-^s@({eyfCN5$_mWWR=jIqH{F zGOXj^4}#8`1lmPoSDe-dZgNIl{dvn`tm~^-tPAPHmeKbk6$i2%uEbbZ%+D8MV|~Tg z81ZSsOrWhcFUcju#z^FoOvJG@Wb-`1bz?P{0XKv`x1Kmeo) z0AUGQWH_{q6rozBa#HbehzVK&2Mps4f4Y*ov3Gg7G&U0IO>V63){@G0yL$R!u5Hx! ziaNHf`BR{bnpx-FiVjzO-*(J{ALV)U2BI<1H<(+HoT()tBornSkqnzOO#;A`o}N<` z&Pu0TfvT{JvrDSNc8=BS)m33V6)$B?=&~ZBL#gUFYU9b}*x+mqbag>bAw4IdyslJ< zTPzM1+Wv&@+So*pq5!q8^Mx)=Z_HZy>!Ci^Paj>~x9`=ZKnXIZe8k^4!yh^FBmdF~ z{*RRt-v+5C=bY#=Zg|atk9YLA`|7;!`-6P2gdf+X+k`iPapA?cMl5Sl!oSPc9_07_ zG3VH^l|cH!Hqhs{8O7}u3?K0-|J$r<-}me)_I*&d5smeDYN1xA({m7zYK=@oa+HBl zDvd1A$w*G4p$MHAz!RId6T`jn=4}r8IiVxfZ#1yLs{nY?W$5eF15KY@quQ(Gi?@3} z-MR44b#M?|saCk5v5YVF3Ip-1FL?#5xATu> zCFFiz=V#f$+(vZ?VCuly?{Ny4GOc|-F(-}vg1?ZhA|reV?kqjwv&(6>TkbQkbZQzw zCX=DCFWG3fSmc#q3+s?ogbkd-!EzclI{ZOb5)Z7G`WrZk7`b(xm`9w6hbNke_Mxdx z-oi#vLE3lBxh3||HP2df2fUKU-dbcG<>`mS?w`MZadUwnPr>!!$A?F5z~)QGf3jed zjOKF%xr=Kj9{k9(ME4|x7!oY9I2@E+sZ_`*ua%NgKAkRAW30k6Q7DVODr~VR6zHBP z6jD57#DhebD_UVBCbeP>=H}?2=!7Prgi1UgDR?>ndpd+WRy0qEv~I zra#h+eNGheZ|}M&KP(&8ec>}HV6K&)FBvp-{6xW=?8zq~9hvd#fA?>&3>tReXw;^} zz3b>+e=pSD=!v#Lk6fW3v@#h>FcLyyL~_p{6H4M(7Ah&IV1&Iju{=FdzalJdws`SU z6QL^93)CcZLtiS{=QMxqCJfyH$uEsKJM1thhfNFL14mk_6{J4$Bd*}U&(v?s_yPPH z5N_K;gbl6{ViamzsiZ`HCoKVlgpjc^4P?|zD6Ce?RB{asL?vAht{7O++H?#JC-9Df zglnE{GqK(7c4OZ>K|Z+&S>$rFP?N1f z3ISork))REpsqS>hEPvK09oYR3z`4?QXKGXVDeO~}Kf33i;3=on1n2)$fx6d*T{u?+U?@C8OE z*%G+np73GLJeaOnJ`vdkthV?mD-pOapF(|yyARWA;OFY6zhl-fa@%%wjbUxxN0(F zXD?4ZKlRs0j<+VQ5Ls^;{xVft%Y&VfDUi0@In{Z@o=-Y?)-RVtR+8hH*MF?JiT)X# ziJTsp0sbYNLxpS8g_*8)+%IpFauS)*ZUq1#*KD@SIK5ipNRr4n84f{noLY}%h8{V_ zYQz7265%XvZ&CCRxB|f&Xif$YDJZQTSBVx?M|r*yP*RbG>ly*s{HyV@h3KVCYt?^ zCQNe>tM3u$L*IXxKK98&`BhV~WS>sn{a@*{=4QLd3UpoOC(z1^cy0xvl@pz|U(oMn z%(T?zaapaT!{L#dEn1_>q?db>rL@k3?uW-_GU+WAH!@c>28~n2=naoP>BH>ju17IM zu&9S4(v3lcqlYEX&7IdOpZ~BM66J%*mQngSPc|Un?nPB8dRRoG#plZ7!vF|(Gvfehi(}r>9jEt9S_2M@+%mF_o>31XUV);bHYIwF z>r~Q+DoZ7Z((JM_XNA9@Kq_@QLoG|2l>|FwG|Ffc3TI^4+XPC2MJ0Z`6fzVpVfCh< ziLDG1Ce}nMpvi7mAOT{dya~fVA597?d$S%jVw8xNLHpz5-D9*63x=Y!Fg}tP3FR3@ zfk#k6EY^U5A(yT%t!&h|u(-N+&z!!!x0=%&ZF`MwJ!WyIwTD*BZ@ywztbn8G`;+RC zVa~`&U6ytqH3fu5t?cbJy9?7ApFT%Ddf8w?&FGt>3`eHvr?%7&qHF9ud`Ki?scv+m^8|^_LG=!VT!?iEgoE$1eucVaze5*YZS@zkP zsX-l^%2tI_Qd4Dw%v2SYafBzKv@@Xy5;5bA{KSE^u@sCj_fitu=m!x;iRGOEA+Mhe zfQMp)a4PyHUV{V=;7OPh?((l6kFNI{ymkY4_w^q@X46@NODFXx8Ua+l@NYFpKo*II6~pPob;epldcJcQ`6IFr7{^0`lgL_DV+c5@WN$G z%;Ja#_dTL*0S@Z0+IlfMfy0jsmpUeO2@__Ge3R5@vW9g0Z*FBT}*y=WoN{se}AZh!v zK9kju?8A5F2)Z+$2{pXgK@%Z?q=Zx%R7M4EoKq_(5=wwDfgtXp#jA&q=H`s1QhGSA!eB$qbm!mU*leEI`_-phIQjw4~f_P4>tPR4eNvM|T8qCVX^#?YaUoVr9eh*c| zaRFyeRoKayQ>(&eN+Z+jbaD+rSBFVqNMSS|7%Nh!A1l@-q=-s^c=MYBp&=gaw0uh0y;63;&1%sAm!~GWGJKaKt|%poy_BzkJt)32$#cbmqeGp_7~U?LBlt zi+?&j)otJ;-tyh8v!LyMoI_p5e?4{0*0nvE)JP8ii3g$@hDEZ4HN;q1xzf?APp>C zC`gRvKu1}!I&*LRa*p5sMfQ^=o!R$)ya4)t76gBlzt00~>oFx=)X)9C zkiJ)(o6Fz+@H76&Z_Sxt z#HZsQ{3!d3d4~uP9f|J5@?iU}ohm9ib?er$V@t2DW1d7pSXDZ@N6(JM#VxybuV{(> zv@vz>-dxiLS=Mb-=^9f2LS#)tlL>jPHWQWU)A*{w3Jq7k5G9)ai55irV>4A_5%0PV z4qZun%aRZ##v6jfFfmq{R*;;qsXf{n5lDV~_M9Lfcek7|X3*YVk&RY;QefmTRTn$m(`)B{{O=3=<_E;m z#~%kK;=v1G0P$dv-Mh|X81Wka)x0a8cW>La`}o_yyzJr|UOjlJD9|kT@v*y)XOx!Y z!TC+|TMulvLa;}MB75Y%WF66nC?Lv+5y8UJBrZQU!(T=~zuL^v4AZ_teojV4la^(L zg{3*AIp&sXFKdPrWihipffx=9?p+U3A@Y#LNS-kNwf$M|9X=AlCBWNtMKQ zGx`}%tk6D+Z4g5#{Rn(Z++!y>&fVzy%qOcaO?u}1rOVxRe!0*wU}<&9553PfP2JtE z`l+EU_%RMsa)y9AvbGMn%>cDWL@s%K+Jp_Sotn?T`|4v|yIwl803_djY(uAQkucvl zE3--E4nV-lmCcI%2y3%NRPH#9QAx!5O67Ty?~wk|3iD!Kq07N=A-~gx_JL>HHc76( ze^ZG4({s@Kb>jO;do&+}7jPE344krFt@Jp)yD-1oLKFsV9A(DyyR8a^EjG6s7^}j7 zs~a!gaCA4|d_?`JC?Z1#AjyUP#sB*@c;cHoAS1UX<<`bi{I?rEdAVuhvB;L*Vg^O` z{{$=XAe6E5kMI|6U;mnooEK{ZqBFb&8yj(h$s{FdDQ(qgY)TGyiy*U&z-AluD6s01 z`vGyuOugK`P-6O1e&Lv!(B|E%e>wErEAk_fQGI4^=`mrpF7gU^M)%IKYoOPz1M4gU zMl9k#T(wZ_du;sRGiogTA;A%og3VQ#Ypw_6X!Yro|$1iIn zGFpz;I#VWiBO3&bbk-z=tH2e;^#2_wOsq~wH3C(OOuHdQ|*cW2)j8|HImtQ30-Nv z^+sMU$9NfWmtQIPPfD0h8}4I`^o=ulWuZ>xjmpOeJA$e9z=M8QhR;gl9V?~Q8^RuU zH4v{q@Hn&u8IuNS!zuKQH5KD>MpT~>@WhXzn~fGid7UV7}eP?Tj_2Wjp(3fsrSll9WA$6 z=`BVZk#qA#KK_dYU=Gfau{ZN?;8@N>FR)bfdJJCHpKsveufYHK3O?d{De+fi?fCJ- z?%dG|kF_g=Co)TTy1zhp`c(YhYT+qj5uV_c_3M$G;w8cp`LpnJ{~O_n@+JPP_A}w> z58+Y3*-(BC+)V%LA)Iv%rnCySX_J$cmf}mY=^c)w&gC6S@&kbmX-OSAB&9)_mQyp7 zjL5lBg8tV!yhVlHLM+z$l9B@2;*s=I)uE`$#gA$$dfsIXIFL5D+;Mt}s9#a)W>% zAZIw_zLiTvM3zfLM1cSSRKyzv5nW{!U0e^;6|ePJS2CTis=9kJlYsjDmlcLE-Sz6# zd#~QBdhhqD&=Wm?ywjMY_`mj;-ITpG_4ny)3{u3!*ft&(xUTyc%bZi(0 zUjZ?I1;(G#VuexCHl3yzM2jC@klsD~;qqh2j)oF?`l_c3HfBv9G;CeU*qqBM%EgVG z$Vspb?ti=rgZIpw*KuV3F+)=B-=yR;oWu1&NG7uJ9g0D#GwIEc@^}K~OdXq>BPZq? z%^|a)Z`f?lNM4wlC^t}xn?`&QZu5+M&^#kQHEuTGF*S*y?vV89;d6I4iofZ~{(hWlb>)>IRX@6CIMG93(n&}@X7|NE`Eyg=9(6e7DBy)h>lFVQ;bFHZPQ z#NL;m-{af!C%5HFjxw^bSThHQ^4%0~vzfIbd#HbG-d+l_b{mD4f14QV~{I`IXG zHBf+zfs-7?24Md$foV;@Io0!@lm<;W11v>g@%(=MXAdmcu}#{|E_(aeyYud?Swge;TTz`uso921w=d7(@MUBQK~7VkX>Coc2wTmJKk4tT2ObNgo;e8a3drPq#rvWsr#dTB2i{c^2iu7;*0F_@|sP?>5 z?y}X)9OM-Nc&MUoa^$I>5L?+r;E~Ad;D(Rv^(4Ox&O)+D>ar*RGz`mXS%%_x8c8Fh z1)${g$AZVmZ!g5PYDhKSuX_h<>a}~URLisj8zSG3_ogBJ{2Gm6M1E=lr_%wwo;N`# zXpNMyCd{E_(~B4mjBY}EC~R4(Z7sAC%q@~f8|?hV47egOQd|Z0BuGOSo>}+=Or?ix zmu}k_nM`kx`DH}&NhCED<)I{lM#GpWN`O3X;*h^t5oYwrnj7hguu;(1n`E_#aZTx2 zIC&Rq5lMQp!bG>UvfZ2R^CRm<&UVk~$Fy54U0f28XnF~#BlsItB>x~8S=n?a??#TU zkB7k&yXY5(hkbs()8#@c;(~}Ir^q0!VZ70q$CDAYw1@^XX;rD%Qn3m8A9I9Ua4@Hz zlAgbG?4#_bybEV-_7aX1-HCz>;ES|I49Eg){8^B5W6U zp0U{(%*{WYg4~g|sVG6o5W^LH1Yobg0Z%Oc&o1d;){~a;BOZHk)!a#AD(c>$@A69h zdd;}I?(*S-(l-wSud!cGK%c*VtzR0+v|BAr4_?L?W70T+F_unE4RwH&2%U`6C8Q=p zzs{e4@lL!6jEi+;B9YEWP4;q7#uh_%Hz^SC4G#xIr&$ZrSp|w#?pB}*Vqsz7AD1%U z8cU2+sQo28v5mce_ihw!1*CU9Q*-_pQ|!q$kw-De3Vlp(C%9sb`=xO#u6;?v^QS2b zL|cZ_loEhR+9V&T@%G^w?+g?srl$lvEG-vyn@pNSzu#LK_S+qTMo44q|EKxis+60| zUMc79SDMvS&YfLUlrNWa_X0*z3w*q4{O$^W%aZQ#L(}3)x}{QFF{PAs1FAjJwXfLC zR0%aL)KQm~=Es<7rjpE}qLNk~$d+3D{&snVHQ`oy-k=JuM)}-spU;7tmy~2;Jj}3) zpr#z)MbQZI)h@-^EphYy1V>E_#K5SL4i-^lt+s8_=}H2tR`m3P$6kzsReKEVTJRP@ zRXcyg{I?AgdVBix?>B(M0Bh^#Y+c<1um%QHZLh)ivwNrQ|7U8)9;>#dE(uN?m71W` zx+5LNweH2#oKQ%clH#*F9C`jgAU(ZJn<7IV1I<2PDJ;opT@lX9@y67?N6X%e(kY6o zY^r?!W7f1_&i_Xpd~@dfNn!l#X=0Qyd@`w$A769RD*1c1r*>5tlN?}Fd@79P=A`N~>(5 z%43yODb6ph9M$`!7=?@$=x5d3^?i)~DK+|0Y&;h=G?eeKS)kd;@U)J0I$dVLCAf8Z zy~k!TIcP^sm}h7!&9bx=nq8t!=4+u6WGZ&1B|e^FVi3VNydak!1SSs=%_-b1&+k30 zgSQ-vk{LYuUFoOp(<(YC>=nQU>Ad%LumiKWAwrLr)`3R_%;8uJ1P7+yCJNAG=NS!+ zS#83s)@ZdZQ7{lrBl<0vehV}?>>8QZf02HxOh2z6Tq zPc2p;5kT2TV3dN1u(Oc@UHEvOd-0u{#>w&)n}~dA;PJXOK9ecIW^rnqh}~YwTN7p| z4f;h}-68>rjfa!FS)XvL8Zxv1CA0>Y?8-Wmb<%gTAXcC;HX#w_H+L}yE??d#HAW>G z0~BIuW}H!8lfJoCp?n@_92UkVvNi{Bdt4f?$>g(H92y5M)-+mOcHTpIkoiI0p;4fz zxK2oFN@TNSEQNOLO*BcjEZNrJzD2&e1klPYU7X$|;|c)9Hw)R)jT;w74yZz|fKV{U ziHtmn3}FT0w;e?kDZr*T8B7+N)y_FI8mCE5z#owk8m%G^3H+1d#@>WXxpC7?I2$-e zFPwE#rv4#rqhknPyK{J zYnvdWZzN%ps@PJDfg#`wbxIISv>q5x+-fvwIUU56eI{tO0Axl1&@t%W?HZkqt;C%b z;;D+QjEm_f5~U{&5`$n6?1_cNkf8@;Xbcr6a3#UxY8y%bDAZzDlTIhd>|wNWmm3xu z8975Ct}kdjJFwWtGlQO!D3$-z#Ek7XyirV(9V9Ml8$!Mz1q`f-VFaT9ba?uZH`pOp z5r#q&avc6MIwnv?i%ylchrz$R(z_?>hDW}MPIYxdWz0OKD$Q&(&lHSj02v2m=Q$1} zm`uRVFsW${2P2B^;bGAm^y~d-?s`4))DaU{NXb)=jVYojC@q`l$^1|PBKyrlCK&lC z0#E=fGPM&%RgY=&_iN4Lrmm09Sj~KL!;kp(d2WKG;p>~lOlsXM*O}yAR)(@X20(eO z9Oq4h{(y@d+5iX>lahRu;UvLm)Oix^Iut+YyiJ_FS+GPB=P{qvRnFt8VI2;zW zjG0tql*re?%g?t6niRAYe1CtP-A4L*l~8wu+BkKs6En<(MO12Pp)XO#mbOdI9Ue|j z=1nH+@UYp$_&mG^tqAfMGP39_q_MPm@muJMxd4u9Vbqi%n@TRa(QnEbuL6TQTx4@{tO=ZPx6{`5o8q`$cLv3Q~?Q?RIC!?(<$>xPNc^;Zx_FU$SiD(;HiN z7}lq;$Gq;NmhS12(ZLt!2uwGA0Wbc$?b?jjrNz&mIAh)X%Q+B!`nhK=Nh9Wq`EchB z>DP6aC(Qu!j*h)Y#$SNXGd-znstD%`JGBLg=8TLsIfxl;e2H4NxFk8R0x^R_%&0)j zF#9|l-kvx|n~Y34vjQ>0@mH8(iQz`fjq9zs;Y7@6BR8r-?120F)(q(}Xw1GRdapV; zwQuP5l-$9ORF4>x618^ux2805t+sZaLt-y`AdfCp-uY&%|ApzW(LL2jcEZGpJsn%ygrR zvocn@i^=pSC1v@76=A>MXXfk>+U+PTwmbAlOO1MUVrmL%d~u6hnnX%lnoq8Ir8I3f zgZDYe_1+y+d?5AH5WJ#VY-x^f^KM>rhhPQWo+vfTLN8 z=UGm};3k}uMytVl27}D&@GuwMRBzhYP2I6bqmuX5Og`M_;h)uhBsWgut&{W~k@ruG zn?x00XSDuQrdMgQg1$#@!k829!HX%Xp}M}WoF3K-} z-x{f>yW{hTkCl0gRPRulNw4QD0B{^cZX%>!9 zzmzUTetwr;CmnnZ*~csIM)rfGmDqb77THDrn|>(r0i7Nh8hMF$u$Znx$cODfeAqvu zOMrGvS7n&8|2bWd(1it+90kxXUXqr)2ChrLJ$DuidrQi`JQ8UUcvk8{=g=l;2-q9> zSsFlKi)35G{X}@xJ(Pz0X_H<9SOc%svL>Uznk^c}$P5qbjUv(&ffAJHh^%7ytMTW< z(IAc-^DFK&^5@=1=1B7WoqpjbvQA$Pf`NAX#0)R7+YF4Qbd;qA^v=Z_!FQ8 zh4K@jhf469O?s=KGZ?Jq1P_}Wq!N=7E5bHsl3-F`$Z&n583jjFd6RKMa^H-y7>oHw z;A7a1(!LSO1?QRvCNVDjVAqv?g*u7jYigG_qc5i zhlhn;UlX9Y%i}@Orbo0ANb~p;+ZNu}O<~RDDcl6w{6A|DpSRou-8>pkt(3+QtTZp$ zPtz#~U4p?Pn$3En(c*%>1kujfab6^6(Rl^+cuEz;!j@FVz$e7uZOPXDW*}-Ov1MO+ zGaxl3z-j_hYr=;2A|E}Q6=^%=lI9UgYtQM_!miVW0yMVDSS zfpOE2IIf9Ue42*q)nYikxWkloohK5!y3rMxQ&P=MoSv=)t)%xf$uewR zf$h@SD6dgG%e+r;_|cweWHAyyYjZh8fyTN|(>6QQ+C+78X^Eeg5(Szl11i!4vP=g7 z-AqJ*<$1W2$YL>%}Yc7Y=&-5s(9{-KLBh)Tdi$Ao@I5`n&Y~%qjE+>9^~> zU%N`~zJF=F&b&_g&F0{KL9~VPY17h@laZJ(c^;SDo=aJLmWptW(-+eCG(JO85(-?B z%mx-?xwM$;`Ix?g@fqo=iaJ%*Y?^SP($SeuFIF;i|E68KY}oeJtNMKM$hoVmX3Bg# z*&^USbK!H>W6Yx2%TA<%{}z-lT{k#fzGB+dH_|)Q3@5X^{OiTj<43LPK5xmBkIL&P zy-C(Fjmo3Ohl;&!2jXs`QE$@Zuyq2mYON?+60!>Uo}`c_Nt0wqPR>E0t64A^ zLI$={S?U%nxao37B|K)yqXzG6-LOvF(Q|A4$iKu33@s_!eN;_4wh)EKGX>@~^eT7wQ?x;5pHnWHkCH%I>go$PY?# zI4qT6hr{Z%;TwEwiyQnX=s?`TMa%np(%L!ZGAR+jBa43ADecX8(l++4M_)Sg^vG(o zgG7&x$8^|t^weSL>qmgsIH(%{@2`1O@;6;C&CW}FPxiq#N@GYrBPZ1(BsxUV?sRIb zl*QuKxX?!tr`nmrPEl^Th&vl;II9}1tA3o~>lTX96pEIu7D>LE(&XsL1*FMQw<(Lp z?Sqwaw%tRqjgD4;wxB(bG_HI)#$$6b&GB*l3&Ht#?_O%CJ??no#sY zX&tn^ZUw(m7BZ zgI(QjQ3EaFbUEeBmAydr;;x|-%Hh!Jc!N>LIL&4kMcH&VI6Q3g8a2biMx##9L!BJT zmgdLQ_{Fz1CY5@GZR!a;jjSL1PtqgH{{Ek$-Z4kd&wo}fJtke1#`PQ*uA~})2-Zc9 z^CP-ZQ$#a^9-ZF zTZlj`t}k2051IF1N?*w>LvDQ;u6woMyEmj~vKIBf^WbT)FABHCN{wFvFX7!7be7)~ zpL7l->ji?nhTf#}5@`S#8=Kr7N)~W%Vh~-TPp8*6#U(}*ml!b~s}XVPf_fNV*cxWI%CngIk0nW#qRMFLpKF?md4Ru&?6=$LGp$Bq)`dTJ_k&K#+u-EBl~RC3rwO1 zx?D+6uXmcE&#Dnb${ikk0S_2>M?j)`<8pk#vwcRoKcWpA&Bp0Mt6dD?#)`mu`|@-HMTEP>}@ z>>id$f{X9QwuRMdDZ$JDj&m5yjEANuuiK!t2xhy3(c3xDH_SyXU$ds$F@W-F{&P$4 zdm@wPrbnA_uZe@dm&H@$~yj`q-Iz+T1QF(CiwF~QNS=QhTT%_j5guFTV{%rk)JnUdWMXLe5Gb@pR+i)y{+;_mOvC?<=R}*q1bI%Gm=T-PQj%QpbCTbI`GDU+uxnpe`H+G6 z&@DCS5SsCU_<@+;vLC1gbd}mGJR280znGE6HXBFr1?Q^1AmaBv^_eVO@Vq5GRrUsB zXd}Hl$vCeo>&mOow8rB+o0kIv&Bh@;N60u|Df8K(K9h&X*_@pTea*0V(Ku`tvJF0* z&CWoFpm)0k5i$uDn=KKybQ~Ubn9V{>*leb(FfM;hcHg2!m@WE}DCuhC06iPobbMkZ zBaSe%=N0M4!u@TYUNG};b=^~?KG4wcc_O1pihO(Mg*DQzwquWXUAb_;W5cG;*#OpU z-z`lRUwCBQSGDpyx1xQV#eD$i{!!UG&FxluY|^X2&&cj!*+WVO_L|JGJvO6wj{Q_T zNA!K2BC83=Hy@Xf6p!bqy#I*$ezX?rRleHrS{$|r6yI$95SF_X+r!KwCd2HgYSVI-%9Uwfd8Ry1}*XXk2ikncIgT;GfTj}jV zaI_O~oFpV9niDCrhSKXUm4HSB zn1UFrh_@pF>5-m0L2rvX6w3|sFx9l4Xl)pn z&ZaSNMM|=PX(j{F^<=gw>)EJ2lV(BB%m@bJ*AqQMdgBrK{HHPwr^;F?md_cGuISAvMbFS)1D4sHv3(p98`KW zbxF}PH`24EZf`6OYV`d_)c2!#^iXN?;(080Ibd^pERQi)9Rtnd1NE6CJdX!_9(j}& z^Y}434g}|-&){)Bwk6zjoW%qKR-VgaxNJX0pMP-$nvWx&1(W&wLz&M|^_fIG&Rt$N zYisrlIfo_d@|!ZBYjN}G@AKI7&1`tNG>-WPvf)}>tHD7H!)thC(ezpxU(RwG4UD#C zB$u->$xceS0m&d`{*f3ddUw@5hby+?dX4S!r7U_c9wUhSTnF;Ov{ajr2aTbjaF2Ul zuhY_%VXc4%sSIoEO@rVHaC~rG8b68^Iy}sE|0(&9Ta77 zTbvey$;f)GR-aqIJ09BijG|~C9u}d|g92BP(c+eo-q_H;Ss6#n(IvUChtcr59LV(? zYFP<5UYz*ox*naA+LX;sa6Gi|iG;W!lM#V`DhZZFAUJ9ct4E&*B` zR%j8S2B%`F#6~Z?(XVK4b>d*eW(f55sAF0GWV`f5^PA5h>G!SP zFYd4p2&GkI(?xMNpuKui%Kc{*x&L%ydaa_#=5$&xy%v$NI~-oK$L2Iavt2}S2h{Za z|E4#+=_1qv;L-ydD%&L$m2{|RdpQ0+bp3-f*6nj_v-i5aVhWfQcP;vvbQSYe?ukrU za2G){FzQSe9pD)atAPfC6^drSax4;F9mhf3oEM5pUT!SLU`&LJZ;r92CikO8k_yzj z_kq}CjTm}7}vu9wGUg`(kco9mQJU@Zi=CX=++==`PhAJ7_T!2Stmr0oj%#67nzLAw1k>) zn$@lw9<~SU0l^9Ng1`+A3o6jBT#TtGa7?{cvT|xr4xj=$M~IENLB^d%={5DQE?;@@ zY#`Y@V%nM!uYUpB01F6DKXc4_ZvOhD-p49(ez++8LT}u;aop5ro;)n2jp&;C>Y)#Q zru#Pxt}c4>k;lM;(&$gGqB)>BafR%8%1`B^$RR5ic_&Fum&=p{nO3cRRt!F5M9!t2 zcRDGa&#VaZW-8F4iKSR7mX^n~WhuN_i!yl*7=>BxoW!L!fwBSeS>9J`syq56k%{DB-xnuphDJQjO^&CSbn z*d2DXLGTXV5cKw z@x$(20XBlSQrYc|PxkC#lE<4(8-&XLzb6*_YJ9jbYK6aG6LZ5$p;K}Y? zMpbWGx~zK2jQcx+0mrv)I^(jh7%!h$p*?dC)0@h~HFvIbGn3@^GwGC$&C0d`^zRj6 zkOY#9DJkBHaEe2#H5z%Osj&@Im5ZF_Geh&bMdgirSQ=eJ+(oW?^J<$((`mX#Rn6o8 zTD-h-b^8xK0Dfs+Xrr&a`>xR&54?Ke+rK}xx28(=e_lrZ&kJa+(r^yAkD`+OL9N3P zbh8)|+|40FQ-c&-OioEj8Xis&1wj;%%8N|XgrY?(vGY+>t4$sO#~_8+Hz~G~y_zDp zs{OqCNBX*f1F^MLFV`=A?Yg(3l%ZE?n{4;TCTY=&JC()9@j_QI;-DHB=yGPnvZ^ka%kL~jM zcV9Mw+@~PjnU3sRD%BnB^+5~e_4%kE)TC?Dyco~QSrhhKZ+V;2>@vV|tJ{>Ab5iw$ zlo=saG{0Lh9ulK z>dgZs)lp2!_sU*qSJ)ardX;n%!;f?YoI_Ymom*ZLA70{eBlw# zQKYy<#h|Tx8}oVi=>6vYy`zkj4(VL-Wdpu^h>Yr+sWK4cCxm9mF~(?QFaO1ELHl=> zjOT=6bR$0dq*LS^S@iEuAwIjQ;!px|uFXeC|Mk6Mp$T)_>@%Np#WUrDc zyVZJkENcxr)TG&lUq`9330_U28@XX_ zDAng);L9kUIIvvfh9{-Temd3~g=;^)MII}X^ zcMvZ~tD9S)^WP-mo@eW{eTFj0@y6#yX!~-kD^e}{E76rU@;N`Ec{J&PE1%UKrYKDw zxkn&9bg3~Y=5I@Sx(+7TP7g{8sD#EhDJK;OSw&6|^jC4;n-Hh~HGlyYD*t?SbpehN zTDP(Wi`1U-82uc}Bi_$=!x)1E+zBlpc*3q%uMdyH+a*5IhaPhm8=zkk;58dIR;K4B7Vc+0|1qeiO0e zYAcYm;+W5T%xA#l`IGbVlKpvKs2?6yKXCW>b93d-@}E!p^T@wpdtzdHgOywZqDg<4 z;>ghFaZv6=zkvDAOGvU4|!8FA0Ty_u`%I!z=>kmU96N&ka_&l_JW<5vk-@hN*i3iyV z@Ey09N=95YS`sKj0{Z1}E@b63Dnz5n<*p>N7>8uIB!i%}IhDeFd?g~!EXU zjundr3|1?wQ0c{m{DbS)zqkH9X+d3G9l^PgwxjPSHU2>Hl$8=s@O%gYXwg&oh3BhF z^INyVnR&=qu<64p&02L+n)ZI&m_{EO%+qYD>hM_uTeFYv&IM&!62cCA~wt%(N1&Z+L#~;P8Ccp#FpMJ7koUrl*&dWOT?!e|6!X z&ktvmlw_cvk#hz-k2+-@)_B5S{xg~Zb5pu*N&uEe39033ZX0ExTu9d$Mk}BN*2uPt z*lQWu508Z0G+y=}z-pa!d{xk9A5}iut4nItO0VO#6$~1q8v}Z-GUOH)$asG*A^Gc# z_5?eX5E3lB-AL0E*$*J#vEbs}0IxF)7Lz1F6KHY(Ilgv`I8hwM^MTA(`Fh=GP2vV= z!BF!g@1W!~F)5){+t#fgcgf@IkoHi)#*dL+7>+_ZYCoJXP+V9XER#;!u4D$K*Ct#< z-@SxrD!!QxL83#Z2Ohk<{&G}@fK-pZ-yYc}9=#jOI(j!2bX9lS`_ApaBH4G{-;kCd zokJTIb%}gmplpg<3%Jv}D%8C4WI*|ICek?k25_9H-U?AxIP}}NYBc@@^gegvZ+QH= z5CDKxsAbDRda3{n(g)@Z3qYo@Svpc!;rOJmr(2G#Q_;Hi{!=@18QB@z(g##KGjlSs zGqm&t+n%}F`YO3|cSjH<*vZd;thrJ2CSG z%F%(cIH|F_blY|*cyZE7q;s`Hhs?+Saed{bDM^$6UMu6Jnb7`xx$!&lerL!aP<9Zq z@3hl)EhM90XN13nGw@mqKcGh0N@83Qij@YVbvUk!5v1~|_EdVvR_OJXQUMSO> zT;$=U3wT75oOWJy>Da&E(xu+w=hEO?yLw=n>gZ*wA5_wln@!=T=2L>wBs8C`Xg;!U zh3ub|LjJHDgxovbwA;wbj6)U>@s36D;;kr`CfPuDd)F3R+%;)ZrRNmORY z!O`^FNUs(`=%f-rC}C#;ouD`YQ;~hg>LDKh1`!p(ThsB1V=|^>g0tm{O4sk5H0j>D zo2)BnbV_>~>l!N(c=Vq%#`16WXOLcF&uE-f$7jIO+Vg{0B`macq^olxzs03|OKa9AAxZr)|T%(&x zZCs4x!%zn~1(FX98Q=rb$B56;$=V6zdx#hKdpyNGgT8~fr!3S}bv>j#GbT)!L2y3U zeL&>8koW^4hoKzVA!My%sGWhv&&|co_^&Z>%m3{;C~YIQ`-f-@CfEhR>&49cB=AFk z3Dh^faLk+7Js_Kj?CJuM_!F^gb>8B$v`uB}YL$i255p7^?oj^h8snQbzDrM~ra}{@ zDTG#2+e%xbeL%ZY`?i+T$}El*zg+d5^jRF11aouoJCcyh)|0i-9EP+kvuNY_SN7y= zY0uTGWS^3l*>D8glY9rra!qdC(&_e@kyqHB@1pP6*t1|Nmrd3fH-LpQ0r)OC6EAT+ zmyOpLbd+k~A^vi7ynNgmz7YK!T;3*SN;TS*{%oj7IP3Si`;o`-HEf+81 zvvJN1($SudZ2;5~Ud0Z+G8(0hBZH$w0F63nLgW5M&8_UluTd>O6^$dQLL`)K=1s~> zB_GynZqtDfqEe5j#KATGOo3A6nny-$C5=Myon#rLw=N1SzjJW=#Iay@AaZeoyXS~? z%$o-~u6{J~-2wWC<)_CIERV+h(gHB4aR;SE`p9E_WP<_-mLp#-00z|=*ojR35gRys zVW-Wu^KSJ0D`;~|M>M&pq!W7DuE$1D-(mlkZAvhLQsUcXrg7vA5z~&7X$MJ z(6g?`ZD&GBHH&5e!@JVlo;4jFeQ8&ydU_S}W@O`fs`2WTiBE4HDFx{ZfrSrClfe4z zTZZ{%`+J?DnD%IVE0um!YtS2FxB}3>}Hl zM;WoqC?!QQ#4GOA6oe+4oCU$+Jcv^cXD^@9miL}84I0utuk&+V^Y0u|yOy8h;$AxCjT}xp94tdyQ1g!q30puSnwE41A{>?Pr!iQVU^z!MVcX?riDOe zQb1*#RR73HaD268!5S$c0N(rJf^{`aX!wl2G_uXmYQ(hx)sfbiR$S!%9U04Xnu1tP z@k*4F5}+Vxd-A(_=FJ;wZvn*DtIWr^CsRmA8-UShLbRApff7nXCRP}e8ONu~-LT3) zacVJrHGR}=#VLlx^^2`{kCo1*Fzz#{{=z#tMh4S6CM@w!dtRZ1xr}JBQ0~JzUY@ZI zkz=8>%8aAf3#49No+(^JW_kKT{kPx;Bp_?#Io`O+yh((kwY(;c*I9G3zf>S4Wv&dlD(vT=M<3(gOGa`o2Ip4r_Q>qBNLv(2*kKHWvW8_%de8Y*}ki zILY)K(1|R4bRb)0RJGEG#Z<9XK(Vg){h0v0xrm(BlaJ&$9z{l( z(hC95<=J;L?KbI6=~?8+eD}HNZ7n^2;Hi_t@9y>cfj2J<9DOb+*T z4IDNLw`oBKq$Ug*jYlK1ph#^2A%_hFt(PFoP;7BgiU=o+94nb-)b|JZFFo^>)JeLS z`6cLI2WR&lOxH*~9^QRM+9JI>=3?b_AmaT4$rMYWIcks;B_F1>$}DLzOWjRosfZP> zIw1^YM%=jeE$v1;Y`A)mJ}?0>6$#dp6{A4khLv=BP4Uob%*)TvI65R>UaGjx;db-R z+XSqu=+!)0CwY2!6EG=)Rub(Yhyml2#zJ`A6nlq64TJCDUVqLq0Jj`H>zNzb=Lb6n zCR|?r@v_fe`_Is_!>oRlo=*jz*MOGdF#~-Tt;%Dj2$gi~f;s~(ly}6SST@7fj zh|%wkG5QU#h)J&^1^=I%XZ0_{uxHVCMZ9lmbuG7jO?T?Cp2B)Koqjqv9eJ03~ z=oDxG4=7gfhm=eX(7Vo0Z~gr3flo`n9=`fjtI6+m8@+V(;$t()=Wj+9^|7Z%NfV@> zR=xYi0AK`sezi1d?egX0u7DA#6ROC(pKV080?}loyvHbL;0*fHNGv&dQz|T1ELtjQ zoNg_oDTXcfgB=G?ZQOUc_t|Rcl4O&{rvm4D@YjZ(IrN+K_4^+Zzxg{f|8YdV(vO)r4(J$URgYR| zK%b5gVHKSb4~+#GDT90mg!U{e+|f|sr$33*UjnYGVJV%S@0i_x_K0r|FoDSL$;%d8 zy|Q-0@D!;+K9@lH#XLy#%TA@&LC7FOszuufgAXW_U7wa0SgGA2x6NLl7&RUnHL}`Z z+qL>H0yKBw*>lo{Z!(VndimISkso2gjSM$SJ_>Ghpho!}2kcTSO?_Aoi&|;OO;qPCjjgjA_Uv8`{qnY<2E6t9% z58(B^jO?tJ(3o+Qx7ls7mtaR!8L@3Wf>f%WI15eAWYlFa(MqQpYf$9~d}TFOtBX^E zcklU|E?^#ew{P~@0R8ai7p<%5OIW)ir;eWwADH$qefNRw2fI&=Hc zLkILd<}>m=a^nFw`MYwDA6z~cePZZJztIDVUk7wLR?7*1jV4i6$DlR_VL)lyUc0|gn)u8ix@Lc7j~_u>=}o3xWHGoP70P<> z1X`DGNbRSU8XhV#0V8eEih4n`05iw(yq&datQ>}^U=6Ybkvl`u+E32XpTH4b$yElqzg?%Ht8JE*h=2 zEGMUn19rW=m8UYC-x2p2Z6)LzTIILO&opG-RuRs0Pyus**1W)zd(NB*WJ!{JnSku;Br0h&>o7RZ5Fkpftd-joo5_gseMl{8If zOmDQJVpi!IjH63d0fvAD9GpA5YHiM{ZhznW(DT8&epokreJ|-p>HY7lZ_itha3ufB zm;O0+-p4QfL(ssrZ*BZruj<~TpPXin(9C`J%-x?%cMkSmx^Bpz@+C9ZEL^>)=gI*m zpJU;Ogd_b2C2U-}W5?U4TFp&PVwj@4`}7(bet6)^-RCViu!DjG?<0xng8WQBl}(Kc zAzBT7GZG3Post46%4aqj*qmHHYZ8zcWYf5c847~VW=pRK+ssb4&W-q}Yw9Y}RFHFv z7T`*z35Ew&?x;wM5yHEs_9AM&A(DRhd2PMt!H$hz|La2kIi5LO&exZoIn&UHTa7GQ zeD0Gq8;1_9UE$Ni?prEW6%W~eBopac!WW+`X?VppYGP&ARg*^C)^pPXCDA$@jNvD8 zIFgh5o-;T{3HzWKA)A&pA)nML0;B~%pwN^R^sDmhm{yF1WCu1=0g~MbQ2-Kr2aLP= zlXOse1HAqC*8SU0zx^B2?$WE$S!p}HbJdcDk3q7mi@z)587Mc#k+B*@qgHe{7#i*T zUXPuIG!jx2ap)n06w6vF!YtZC;>b|h8`~~ejqWgQq#PlRKGM5I3=Uu6T^^33v+PIj zkDU>%;MywiMiaTxi&zzt$$bk_#-9K(e#8#z`+r+6bDb*4wDc0k6T$90d$2Bc8~LOFJaHYLUE z^Z5-924=wYDBL{dj>64TTtySsJkn{|G#O+flsc??{uuKEy-3 zKV*k&EXSh_Lrc-Lh8G~+FAQ;I^Q$U6Zeg^2FU|_V*>C%k>yp8dck14~cJLtUzws)r zpvV0A5%H%L`iq&$2|08|y%CDgV$dUf6ezwqCz^8Jaqvv8gvnluTsa`DeQ-~lmO%_c;>Q6P$hyd$N3_~NYw-MKOTr+C{>yjLda!Bm zV?$_8TJ*r4b<(^j_Ass+x8r&14H#}vG%yaQUBem$kv7I_H32#;z{?1dk zCa7aGiC!?v$@~K$3#;RCY+@30j8WjB!A{Aelfg+App52^N4J9A(`-5P>lfcS zxX|Z{w0Z+$>^?K>1RRZq+qATz;UT7-S}#cQtK{4^7r~arxrq*9w^FFqOdt3g8sCGs zptI;)PzSv}-c}EsN5ed2LVq4c!7N_={8-yXLRnf4*TfX3a`i`wdFkm_8Y(N1F-nHlaEYaTDf!Nj3x4!K?*ei{tJGLV(U=I z;O1-=h-gXhnJ7Ys$!14?9t+!SJkJq|cq(7k%2>LPNEE2W4)QfJwYN{a7irpn#`l?p z%rGP)iBvjuXUN030v1N(`BW(SOwg2>p-pz%7)q~qAiCK5znwLqTi6s zaK`k9R58zF!kTWlN#7=GK`|it3D#sD$lTm}wV`AC5rG3M|M_`i_pU<%Ppr6SURY{V z(*Eo><9mXabMpyn$G_fv^xmiY|Kp_@?{*uu_vt$teoX)$=Pd6%eJS0`F6HDbxE-+? z;<|eNHe?F}R4&z)nieY4=I7@nCA&>@+YGC5Wv+P7F-MO%A>AGP9%9q}E z_SvuAsFzMW@j~^ex1Jq8s!sZJE%4kAvX)9e&Qvj-kS-)4-8e#7)9!6G>Gw_)>#w$q$ubZvnBlXw29f7VDp2@*Tj9w|@D_~zFu zuXU*GE9)@MdrqShDG_-9$*dsLFD^uGRB~D;&1v1j zIrpp@;dwS&`sBx#KL@)zmvk-J^ho%*hotYNtN$izh4&FRS}VC$%Vp*`1AtbW0l5wa z19Bwv#F4Paw|#R)`-9=hF~NWp2Jm(r#I3^Kdi0bey)RuG+Y^}Ptb37Z_sFsX=V_BP z=l%)XWS{FI8qD(!9wi2zp-caznI9Vi+r0r!!ZEb%K$$#~k3tfeWgd zfJ^D}XwtG3pB5%>v_Zp6Av9uqkw2K8X2G$7+YnSu{Q~BVY5C0 zO4emSwn-RPmk`z-Kp|ZBjx_Yxx!qeMuU-2*vTVf{|D>mYH*UPT`Tphm6ToGusP>)- zkI1sH2hkHC@n~kqhI~7ghZ+F1texg5zA}s(mdJj7)R|JiR?*@-2S>T3{U_^AO8apI z@E!0(6#sy6VBZ1GB)-EZ)F5UNe4cVqy+Q)+?8_Kz8k@`Ga=XyB;R>06%1|_eep&o}Ox>}t-)^>;(Wk>!|$dYIOlDg$m|ER7*e<^AJt3X+>n5 zZFOb>AfC1I2l=t`h2HeUr3*`+K$A>{mNQw&ESe;EsN~*}VDq5Uha&d|=!we~w%fNM z@)sl$Y*XB7Gb5fV(5tz4Q+rX~f#c{%w%<|Ffuqae#Q8~cVq1|`g?b*^DblG)GI_79!yJpZb>4rH0@={VRHQ?mn>OzS<2dW^dC>7&2hF9K*bgY{M9| z*JV)cLVlyxotk7z)iN*(W(Ir};eZ4E1X30f*{LJ*KbHS*-qlP7~>|eR8mMl-Uh`{JWE%i zXq}NaF9qdSF1p9?2ySWP$vOg!fIDYk8AP@gZXtL#y~#WAUQkGEZ+gf|atZqJe|BY9b<{Z(u&5g%kOUM|zQS7vf)W4ULnkGj__fFkX&-QHqQDV=Yf`z^g7vIz79h0>1aK84a7YHc3DLbOu( zAr}RJDB87Jn+0*!BJe2Q*YXaTu9&D+rKd&J3;oW`AP?VZj&+F9?eSi02mgkrNbgc3 z6-1twUdJ#d0XYVYhP_5HUqvg~qj4QMfVBb+eMp0OZKXkvZ>GC%KP!C{_#6!EXaxTT z0qH9Iv>_3WzD=44Zo6F_hrNcz!RN8PLs^h9Sgl4%W7e6>l*n*4j~;BC%GqyzZSA*FSq z6CDy5EWHYfR3fKKZ`>;#nhs}3UbOSoAYMFpe$@^}oHn^p@0S(&#nPE=21PMC*S^ zKV&b8N4tdlDPFG?SS(zs(`Zc6a$K56Z?&dq5bwQ~uY&ZoCP)H8CQyOn#pt1gwNSa- zQ%@-a)*w(Q1uE(H4y(lEjydk!Sb~WU4+9U^E<5{u7mz+}7ABs_1&>W0v!vUsk^!3z zfH$SbCyib%Jq|7n?uRDuE|G=)i1r(Zb}jPu{UMV8fL+IN4ikM%05VHs`|m0Yq#5<# zv5W?%q-|$Ghl^J>N&f}rom&oWK3BbSMhEoTPhUKFLi+k)x@O6m2z}@JXNmsf@xDjn z>8XN{2V?GWItm(S+NddK`>?n_1-Pb_C9M#zWt^S$#z&wkmnkozMpd9g`%V_$UhYn}mpFV5EyywTSUpZuVS+ex06YT7ArjdH- zqyAgoXRq8lFR!Nig6~$XdZ@VY>6y~@$KE@6@Ba=Cmif$Nkoo6@+;UGYJbk*H@59ps z^)uF@L>ZuHunIi-kFcZ-uRXiA68yJvJ(@d?B;cpgFtCeEUmgeSM&m%r7cwAw$)J6M zrLSSxDUXpHD|+Rp>&~vji$tDl2R?#&^qd*Tm<)sli{4~H!QV9=G3;y1u!8a!XGU&N ztF&Mz$A&a0nYDmlN_Q{ne3y0V2`A{Xq67G7!7A&}UL$JgZqp;(rPmccXbB&3LrxtB z^Z*TD&}xl3nLCFq~Z36F&lGY_nY}71`-n(eQ z*+a86TqjU_0xcr_P(|(iWs#xup8OFzBIDtwk-m8Y7SYe3B?VLkq9Fy*U_i0B75Np2 z4MrXA;{w=gyv!?dvKRwctFQ``;qZ@sS=#4axZvzoFx;qHvIq?ai*`jOqA9*Iq&>Yi zZVV%pg5rHG%~Gt1=LG|YRG%fxDkv{(l1Q?xM-MP7&MsV_PolT&I=gV8Xpc<7?2F7O zo(76Cdf81~LTOf7w{k5mYZdkJ5PXPZ6?yHyPs zG_&(y=7j}QYaYo>ol{Y=&42C+m>bI=A`wm7&+#dQA7Gvo#``VRCG^xo9K)U zt&ka-?FNm;0nBD7FxTK$3Vd-?I|+({ayDWDR=h=_V5^8Om%hDo?OCv4^^Q>|R-e3a zCjjpUS$Ma!0DijczES(bpn8L}=s6!19rGI^6As+D-Dt7kdlsiw>q47@!@<~_c|dU% zn>a%1-fjg-FbnCQ4olxxAQGNf^S3Q)pOZeBvTXDa>Bp`}eYZ(t;HQhGFWi?P4WxDV z+;!)j(l*&YMRdGRe6W;|g@TY~poZhL6vMFB=&zJK#-^hO;sE20DKihOIUvwmW#%8tJ8Dv1T z*DQLVQEfv)7qvLp~x_c zF&cTR=Xy%3Ry;-VSp3QHgnSfA5F+A0!(^_sjrON0Dvvt`mJ>C|nP@T3K|ZPy#q`d3 zkSUupaMY}0Z|ySm=u}x{otO0J{r9agw&6=`4qeWI)ep?Lt+eyR9y;*(#M~jb&m6LF z1*Gq=l$W(HvyZEuQj>Ov^lPfS4ckW#7C|_uZ<{V9quP*p4nXrvLi0?g3aLS%96Av2 zWe7s5&!=l+cQ|r%y0!*}&kX5|-7_=YyxlIkzYgZ-HlS&Djf&Qh&9=foX1oip>TJZI?_b;@Ih;VA>1JY}S$ zF;m991;G{QWB!9ILI8I~ahn7`6kxL6UzC%g{$XB zc0HQhr&HO8iI-}I4jXrE$RQbfv>o`E`4X*37FA4@Q}=~BCL|hz#pOtzT}Zb1;zXFy zN)$t-85y^ANWIP>ud^I4P)Ks(rL4NFuDeQZzL~lAzIWeCl<)U_C=Yl!bI#0}GpEhWnUviSL_WNa zB1s*$2=m)BSYnd`Yr%H}#FCIi%^y@O4{_%=$n)YO{b#s3Vt3A(cZ0R-otdkifBzBH zZQ~}I*ZU9MxPRz`d$#|MQgv^;b?)ry+KOQ-8x^F5no!rW+)9mZcx7O9-jt?klU`&6 zd9ZmyW!yBkt+VsCZ7r21k_^@LFB@31sQTtud&}xhoR?<6$K;1%0&3g~KvEf{|!AeIEM;zBZ;W}3i17q4!)cg>@P zq(!pE|HOtWrIIRM8f{x$J84w&^nUcewlBMb`DydcxyJp}8s>a$5YFxVcc-Q1mLzV3 zvUfM^C)A-RD)&)#y_TW_u$KmzMEi~Ml1p;MoGE&|f=-DYN)_}ecZ+zr6A#5}VCr@~S-msMS8JMQjl(ocfED;!3J>$!FG* z)~TEmW6n{+9fUpQcG}2?BrgnDFSKzJQ&Z zSeEP@AOcVhZ-u%gg5LFW>r`GkB-hEaXp1FV<@0&HaGiR+5{D7;_6kL@RwEY0niQ!} zKHk@JTe-aNluQ?vmvT2-`KK(Qy^ydn3IZb*7u5{jGkL|OX|6t|%NaxN7Ot=H+ryGrnr({IY@7`H^_}lIgAim9YW1|329NoshRdVq`ol z_4_GO;dU5Jq$#9vIKpm)LWxw3QfW0B_0}sQI0QbxfkWtX0BkJ~|8JZQ;cIMxf^R}g zojXR4T{z9KY3ZPf4erIRUGo=iSj2ZG*dmJX;x$7d?_XE z7_wj!D;HJ7X=(`My^knBFM~_1R*EG3TCFqcEOcB}S&W)sG*}xP6QqN|TqEo}@h$70 z!=Mpr##&x{V_c_0T&HV6Kv@0Q5<~lRVhK9?V2q_!9~k+M&{EsYGv}MFpn7rr!mgHm zs~T4tNXkL2Qdk!IkN$M)$n^s!jA@=xdHRIAbKdfGE&Xp>dIOMes2^gSC-QFWe(s68 z$k?&PFVAW1nDr$)CW?3m45PmQl|X90!uu!C>k^YRciQDLNr|BY^jdLkO19C8V~@Gq zVOe7V`Fq#w1$ArIQ2V<@4#+jA7zLF*N<;fhJ4P+fKt3N{Wyg_QUVjZSc|2ndTMmB&~=0-pNiR7qY!%*02W+Rm+Axr<}B&{|W5rOXDIX6*nz|uJVM#TN`T+ zw+%bv7|mpJ-!Eatv3#P5)8uQg|9*5XhBTQeh07Jx2UPYeX1(#U{u>dN9mFQS&oShG zhLUB2%J|pPlAXr>9Tbxr^7FM0PfnI(E!l_kUvCtR!G*_{Xoi?LT z_ex5HJM9HiPTY9&{T(MZ-g(cKC#Ni}nb0zQQ8jgL%l8`}-m~qS<@erlcE;3Y$SArlt#r}rH4U)Xok4c~8CzCd3)X7ahYzlZdfQ*-c`b%ZCb zf=-a0P^k=B2`NWpUo92}z<7|70MGJ38TrJM4KoJmwmQx}dgndTtupG|*?~9CJbmuo zTMA1`Aa2CZFg1tJBitf_Fep_jqmqS#M=@f01OlWDC3h}$nK6dl{l&&b8 z6P?vL;Ktc6z4b76PVqFQz`P5gnyL!5i;@IQridhL(_f*~^2?HMy{yScj!Ci#m4z)s z6~JN+*Ilwq81hr7G{58^H2Bh?8;tWtKCLnw z7h+0;FMyUAz<>$dB3tHMsTPs_R*acFM>LK8im4p#Td{2=c)a`3!_vvlrv9@#^f@Gr z`!N-|qR-Q_V0@4j*DGkP)TlL@O@vV?m3m|VUv1Xm({~^l5eRmj%Qb-8a$XJ2FI&(# zotbJShaIqVP2azd(UZ3~PaQFS9lcyc#@FAm4b!U!pVD{JUlX}#AITRCy71UF78jkT zP~__@nq0Z}a>Ra7Y`m!9I8Yml34KFdU$1rI_aoUQm*j^a94G(QqART)vkK`;og8YQ z(pf{sPnTCN9zJ=NY|47{!^V}SCi-h;z?j^!@|%}}Bi)bAsNFiY|G0)p!)JF`tH8JH zk9Kx~C(tSaX74=i!xJy(p(Xz60Md>HXdbn z*zh7Uq_#Ao?5n zoK)Tqd=e;b8c@)(Zc^Kd8zwbw*|M?!kf5unI8az!JT=FNbh8w$^-5@8jnD&($Ne(5 z+h^6&Ss{wb)_*JZ`D*=R{G{Knv^pFbvp|i zb<2Iv4&417d5}Cf{Yv*6uHd@GP19$nXU?b|$?kC;CH_RU(HFE5(RN}RxfI)*MNmIB zVV}WE6vr(Zu}f}q*?eBgVDO8bW|zu+i7>O4r&sEa^o zaO1%*s=gc7j{3F`@_Rr1Z^8*BWMJHDR{Lx=gte${ z%y~VVa2?I3(A(2ZQAqvgT}`BWep7@ zU8|-=P*>2Qv{(xZvx)+a%3p3^9y`94yq(D>hhCjoDw|+*#;3ds)-%TL z*U|nnmd_Akl zFY$Nl*zcgtdx{xNzD3=R*TL|(-z}4cD6x<7W$UdvonD^>mx3Rz0kzT(|I<56sBBX$ zTg8V9$y07^>PAfFf`IeX=Yjz5FS%)PThpYMA6h?^mY1yExCvN~=g-et8tdFRyUj3d z{xE9K#@VxOHJH~m?K?HFj=2a|#Nk<&yU#kp>lQc6z-+1k_yxv5SvmFCXpKA@*l%Du$CPi$9<`HP$^>?b{YaSf;nN23AQz9X9{Ax8pWZU!#RVWmftLyY3 zeTX)@X>^2(tDapM(`CfCxc(Izu&|C-#A0+~?;(IhCJcnWVE(9A@4xdN$rqzb1=n3pp<3AtKrM2UAbE$gNNgx_Y|0 zcj52mGo#3l$Sv@@%{{lWvOzTWT#*2JG_-dyVs^Y7ih(f}^pUds{OoK}ZKO*|!-Wm4 zVQq|PXjSW^!I(uFlg4y@i$>>eXw{k1-p6H6@Kq-77G>08jrI9PZp6gyOQz?iC1vT4 zrcxivw(?Kq{}c03yZKUGw6Pv$-X z9^QFJ^)T|u?vA0QElpc*CyzGId-r+tcIt+$Pwr#mI`no`iRc_rh%ADjQlQP-`@_6513iP!v@e zeHB0N_sOezd?1%dJC-E4H^gVW!Z_sxIeqpOj|5X4OYRvMt87?KX=k;kQ`>A3Da|_@5C7P)VdrgNI4U-e zYw3%2Lw-ex8e(<4u$n3js~lFVDlf-CiEDknc)nbcV{&O+8bc780kgzLNGc$2Brry> zQj$|WFQ3%t>(HNZg-lfk7jdDW(ta*Ff5+Xcu)l??iPfh2SG}t4*MeW=79~!l=14&e z{@YlF?emJ90SC`4ixV=-ZseHdazE#iJz)|JKQxeK*ZNzVCYvC)zy`>zLr=*NrzG>A zkRnb=uMOVS6kC{N*4@mr>riEWboS=}6tYW@U-`u1c(qfl)BwBNVb{>6poGZFi<%1j z5hzW5f^fQ=jjbA`PHxpTwAul>`q0p7l8dcYb*_tlyBvztC$F-i#DC(O#kqVIHJL!h zPNL!#?0vMD1e_RcH*uqPdK(k%Rs+WwRdC?%?7y?P?z&|}vAxbPaFEXM zzMXoOS;P*WnF>B<1qU>2U3@Ri4GYABog^3`ABzFL#tbBt!rqtYC$ob7cGf4wgyWibUoeBs;U`O zQtvQEwDOYrNTj|*PK&jg0z%AQOktmOkFqy$Dl6IJUHB9Ji@ytyc2`RHkTX7N6^x)a zEHR5}LEq(|%h}yi1Q!lQC{P0;+=V_19Wsmf90<909P`l*dfLg3A==Hl&69I`m54S4 zM1$>H^qc312Aqg5WInKsBCYv464#d2ih<|a4O>A@WMuP#heF_JKP968-`g8zt}=d- zRy8_4<7wdU+IWwdIRWZqrDA3|c;m~(N>pol45&OT@At=|`Z34uMKWZB+3O##qq-D23e7!2rsyKVoz!FjTi>wgbM$#bH4O2!JVnp&oJ=|04aTGon~ zbTYJl#Q_WR6uH<~TciA}-u=iaTr2h}(?SH-&*0h>UNrw16wTXHouj5UY{x|JqMCWEa{=aoj5!UqvRnYAH!uBU z+X6K=-XGw2LqvPLkS0YgZ9prc6lQZo5f+gWLM>@%)wyy^qYV}4gy*4Q7^;d7);q^Oh?2tjFoOuy! zW;OD|Z=9DuB;WP$Q9MdChZmr~1NA9UPPE1Iv#nxRSQNUTd+n znDTnVjje%zS4+toTO|?--G;^o!(&n5HS$VbWhHz2k-f9a+a9*YXE_%S6wncNaOF7g z_a^sD%pQP1uo5s+JO6X(=v&!$_;#+?v)2?I_5Hw#!hy0airM2_-@Ff|=NZc|7BBrpgBL^ZntLZsj%3g)oH~Pt@K%~Man|E-k@)6)jBk; zpsS%(9F{7Bnz%*^Wm}^mEG7fAJ47zG=&|N|4cq2ScTaGKK%e3FaZXHGYT7M=%$-2k z*_WToC1PM0-yts2Yq;r;RBy0vn!7rB#(rja(9DT@An1`y%&9U=H_jSos|1t?NdXPY zwqCuumAP4ogg|jPrk|kRW`(@?0NMmGT}Aka&Uk;DS8X6Y8mW}f=>mjbuhD9t%{3@Y zP7^fBBrTOX6>$Z$!&a+C0n}oJg3xLJmVJC1mV5CD-{Ow4&srBpb-g)(GeLoJq1VP< zAP|fh_#}A_u&TfpiO9BS*R>B`2&%ddIj9N;b4O*iuUNW8y`rOT3v-Hm!f_K=tt^Z# zUhVW)Eveh%$rK9mO_CZxqn3Gek5T7s4FKXpIvph9-$4V%AU zaKqq&QTP4t#@GMZu z{cX-)dX1|;V&V5{;opjjQ*J4L+XlM@k+j@CFvLg+Dxb*hX9WZsU1%vGg+bL8RUbJ- zYBnY{#ZoZ**2Fjkc;Rv8*4z^4OKp03qyFT^m%S@bPGLSZR$|rR9r8l3yq?^Hlt%Y6 zU@iF-(-;NaOsfnzQ{BtRZ4+u9dHKQaL*O!V!jDu*PY)$&kH8^!hi91>S

      6ckEg`nsUK*8#+&Sf^KO?_M>FMMAdrt0Y@zZ2H%gO$59d!RA^@mu^3{oNxs{aC7~O#6t}TmA@CQti#sm! zSGWF3aDyva)Vz`W_&-)I7z=Fyt!@&31=8+vTq7Y4F-x>8DAj_h>A)?bH`7gpp`@3C zO{s>of`tkux#2jh?C;8M++d|Z4G(Tz*(yW{9<*}JnoA=)wZ2=tChktUXqV*`aQ2xfs1-R^~HZk(knXGjq4#qNkt!1;1N4;W_`}1bT9r z(!NLeGDu(|!+HxZ4tmtdz}ZC@55-MEw)ALO9iVecBc1sR=0JdZ$)SvU$!pbCL0&%y zZ#kkU-TjW&FI)k%4=DX7}N+Mg|8a91v~j?j{oF*Xq+ ziczG^ID2mtz=6U-T#Kj(8(Y9%1S=VthE-KtqRQ$v8B*Q-)M8_|xBrO*nS2|7(47a| z9?!vS{Z>Hn&>BE5(+O^J$}m>`LsIRz>ht*`F{XT)QkMX7M&TW~o$DdESqX=mWCVxF zC2XnkDBvl1An{As=PQeiaD92Wz(5e@vuD(36Gi$4>1mjN%7pU7zxdbYsKLhMP(~GS zj$Y?;y(~S}0m7UB5jKk7_wpFNKFcp`{(|5H3p|W;P{_EWX#G~qSIqigK3ihfCU)}Po>!^a->_B5do8G@Z@DdgkPCZUt@uj>ZQ*aT9`F)SJ!#3WVhGjag zvtg*B$Kg7bAgW%u^H-L&#|}l10T{YSs`1YY_b#00uoG32(n`GfHsW?g^i+;b1EGbm zz?z^pKwDxfRMpjYTQ1It9I?83Ied$^FDOsFqGsgsiCTsSJT;VL{MDz{(`)vXDt5xY zGAES^-`4DFt0U102fOg!hMdM8uSNvj@TeRVzo!kkkFFV$9DfvIB`OklHt;NKUJNnB zUQw=x=#H#|XkE^}!DaE@+X{j~kk@{?=rqh+VBseV=mb~MNa*IO*Yo=%!p6lmykSJ% z*wP_y$`9N*8uS%KI`O?LH?W8kl$7YAu8 zat#SovwK=7hb!H+V#23bITz`z&XVPVbDP7PxuHD0$+E0uY1e4b8B^W?z5#?S#ja@f zw{4Fn0?M~hvc8Nc`_`vyWSys}Cd#p?_Fdh?j+~7n1u80grF5h=+n`<1ND=1^ z@Gz1CMer(VngIbr=Pg1=aXwR`l%Sn6k@nv=PCf(I7qk5fkhVq?JzZr%;z^BZ(Q=v4)HLUn$v7;J0z3ub=`5yDAIZ$uu)@#b~B*NZKvYpTiH z2}t{m?S$-v*iwj~DnO%UQ9YBjMEck8u3GuxuAO6F-1S$9|KxpoE2Dh8!9B0>H$qhh zEoKi8kH#ZCM#&A!nb&^7<<$_Z`Gr5^y)U5EoLqHa#j1O`KX`DUVWwB)eq9n!mvC03@xJUj@g zOdtjGPit7Go$vcoE>@Db`HD%kd$l`TZV^+*3363hb{QL{4h$Em?9!I1+o_hs=yC`X zb?h6;AyV__qY&5Q)mFNP2{C*lQYk-U*#s@TPA{=pj-eBkbu*2&Zd>;d*$&K}%n+h2zH(|Z99oywEmv#*@5mus&7S;7ylMoo%SvrB5kZ1Exe zRhwl*V5p!R{*pG2?(!YPIN?8}n+P%jJn7 z-EJFx6uQ)Q0Q&+KCqo~QeS{se@~Qd?5JEj23^ShFgBOZGQ_tLD5*2@_lkIIy0R+W!0x(_kgD`TK|fMnzg?*Dmcd zyxXNV-}5^MkAT3YtJ?y5tLANAoZZdmCnu$Qi zNtAOCGs-Ead~0IIv1_HcFQRjVo=kOEhI%}UPwmEl1$X^Mc@MSe{Wp%g-kkY9>Md>cYj&8b64Y5>-p)eXlaRv|>EVU07?dGqT2IZ&(4EM_ zJB4;K8HE?zT<85onXy5sc_WFXYxZ@0Jg>j%bI9gt-GyT{_kId)Zh||K5976l9~OB1 z1~)#uHlA#{uqCJ$o>o4NHip?ZR8;kZn!4hTOUM8da3+VmjTph7 zaRYwV;h{`d@1YR66`(<|H2ebNNhDztI-x~>RhvI)_N&F~)?~HjYD}zLNoUnEMPk$1|C1Rew9!zV!XgDG^)~ z&4ftxx(j4fkk-6)2t@Uv5_LD3H1LX+37QmY!X_QzV)^2`fOSk-&c-wa8Px06@OA@U z1trOF{s*g16?R=3ow{rIBcF~qo`9dwE=QzCAmos;>UWwWrJW zJ0QebX;h_1zDMKBIr6uJkG1)G3I_M8mpc*suCe?hSp(2>3Vs6IAYU@xld)rK*xCVp z&8{U4Zu_qG6ezI~9Oz%AL^<*6fi3o(VGjT&LVq_Y8tE~>GDrl%GqL7Alnf7W6|TRv z_u?672sA|wkwD-f6{zUsrT4Uw`NB1U_mh@}eBK?#nZ`b~4NRe5hU&@wAOOHyX(l_r z_(PhNoCqE_^$$UG1zWDcivEQvt&QIAMy`ILq^T|CLhW&#@oYi(rMi)M$S4DJmUbsh zX8=-rz~Mu5&=~k$yfBqYpn7Fe&qJph0U%KUh2?mtAv_bpkp8B^>1#dIsuW&>cj}f7 zNn$~fr;H^cB_fe-4QTu91++=>LT6ML{-JeX^?~XG%*TNX+m%0%x7D8~V%nbW_vmp&`1_g-V}Q=_VJ#iDI8cxvRt z2m#?ZqYdQ2Lk2*Ziz2b0L+o(_$W|FA)iWl zF?wi4do0|8L`3Z9F}{0+o%o){)?%GP+rB+pw_}E*NR?|bD;!Ldk$^z>N4&gvTfPox zD0Z%Wv&qWT`=R$kVW9ov8#3EipCnkdTPJ7ljl&9<_6-X=e4^8esxlKbKN)nQSKtKSD}PIviGwWFQE%JyJ@0-1*D;M8 zu!YbWOZ>u)ynec@TCa)f5&2|M*rDMj7ukL(OXKuz+~iY64?>2~gnr=!zeaSP2MLJ+ zNB@qy^iRHuLgokQ2zFyx-xc5r>C$)qFb5N}q2$ABp(+P2xkx@wdp38_-2C%ybR428 zggMm^v#h*rk9(K;75g!|%QM_-*;kC7l5Eb3da7Vmf1ib>sHwQ9x$-@7DWatsuM;|R zWomc)rs*_2K=(ar=;!j7tc1X`pZIC2FJ0B=X7Rv+1&^?9uUM05{ zKmoeFR$fA~SpDP>!M*5(z03EWda@w5O+PfceDTm|`903}eZH zUdu?o*1`6@BM6uWh9xJ~B$sr^ttnze2V&UECo6o7_)f}&e=L0kpqb(MLxkxL{;|$# zy42N`aZ13Cjylq7|Jtk0-RsFMMR`9nri3ttm)~)yz}l9V<`pie4$@P;Z-qgN(eJ(L z?6I3!FF1mjylTogI!-3K=}MM_Rr92kY`Vgmggk_3aY1Ja9oS;m84qZTgU|I`(COFs z2kA8Z^kC2RTlXtKwywErR=@P^kdc>?M4dN@-|?=%4LBl!GjBWIq;W>aSjvHkD2gJ;0tk zFF42fMy=~t+GS3i2Gs=Xq-Q9b#@Y^gZ=Usq7r|hiZi7`?7PW%eUUA!6tBS#D9>rmP zR}D+R7o)%WsdNG&E<|TsHHo~@TlVTGndS$4(3Or&A{r?xQ@t^UvoyHdD3S$vw<>Dl z^M?L7LAL;9Fx}@E;CFtCJnSW(T@|-AyDD2ERPm^v8xy6#9CXhI%1>(;y7?JNn^$-} zl?2_f69Lh6A0G`d5LrhX0^Tfz4X@S%`1YzG> zB}P1=ZvCW5&`}l6Zt_Hr zY?UZBx;p)dOeSJHNn(48ZHjjQ7LJzR9+VaqI zAw<}q+jt%D1hM&6fo6)T81XxkAQEQsSDE2q!rHnkis9=9;>6?q1Q$3T=G)$Um_09D ztq8b5+XVP^=rzvyWLbSKAAMCh_E^e6h=A}rl}4?&dgQmTc~9nanq?Hgg#vhN;xOSFMZP{C4dP-g!T< zBX<4$ycd)xi=3za=>ETFYdS^_jOLYo>>96}a&Xzic2B|b++Tt6ceC{vul(ozsyl(k zrnJ$QKZZXwP2Q-QF&FQC(CiQQ=hm6Zj^1Q0YVXwF3Wh_?pKEibu8*x!;CU7q?z%2K z&SMvR3YW0-*PWHm^Hiwnn6uMUO>%yndD+9*V1bkMh^fj}+IK7$Sy@TnG(UfA&RO)h z9jOsdax6=k>h9={xKh=UH?n1HGg))m$1bb2P#VjFX#3L&>wY~WIC!6>nBIr z`WhmZH{ChF#m2SUyHG14mm4TChlr)W!d7%;W2luQ*)CnZp5KEFrDZ;8VJg0t9I;Uw zn8h)1jj^))WiRB5jb%mouFF4eT5+Liqhn)=qlTxpM!{9Lf$M`7WL>tSF1B)o$Vxxf zY&JC!x{q{VeBJdm2FWz zeQ$gx0KEaR_1>?!W{N5k-l({Gk9U1rZ(VUcqa~^!J1aj8L!WA~8CNeYXYMs)Ui-kQ zB5|Jk7M);z`zhszvsZg-z>lUn86EMx7q_KrgxLD6uNvLGAHL?G-SueGa=t_IZ5K-G zcn!^>3!liB3#{H=reN`@(KRP6pE}@D3O4Er{7cH*JI^gMxV)LAI)twQ$@T5|l$PEY z7iYO7brPXMz75}xm)neATlJjqPkAS|Y5jd6h{aemmH@xOe)Mtj&*Om68PbeT4>a3A7k$8 z3XkQs&UWmBNfmFyZYA}%Zlf2Byh%q-_tTxercYKSCb^in((seBG6hOqEsr%;e8_t4 z_$Mql5?d*U)9sL8jpE!^6opJD-;mo_=vJmRd}Bf}Zfx75k%N^ZA(aK?Dhg>g3f8lM z1gvVegxI|n?w*Jda+k?1&x~_s8ZJGbhjSH)DqVl+wf(r#dEN0(@+P=QrV3srsLfNt zgLFyk`fo1V4CBf_%+f|&bsB1E)$y5+!?kR^w^gNQqbodO3cWA-O`MFjoy6Qi!=&__ zH!pA1w&G*HUVKWa@+k^?ef-uMknI!W&i{$;pL7MSc&OtygiN-iDzYGnAxN?T*LmBy z1$CMFsCxwE8lX7)vCgk>_VY}kOIfmJAHg^(G&0L4l$-P>-f!*s??l8S?&G;;mQkK( zrhDhc>-}wOI>X+m{lU|oakqPL&m8gMOB7$z7zW7!gp<810yc4lbb+lK=EZ3*M z$E2m^RN*IW&k_5phL-$sZ-!iKWOncNUVZ+!m3VyhosM2SLO@6aU3zZ4rJL>hgU+;u z1YCQ3i3)WHQzTdG+~nW?YPcfNv-Zu2Zz)oF+Z-lSyWpelTv>y}XW2mP$bs+OFBIBp z`laa8hw%fsgRLR2nyU9i^w^6kI!=h(bn&S3bN?v7N9|yr&RoK3a&6IhMJ|+%!!`Rq zlgU$e7$u6tPM#Y6r>d|%TWj=O>ub`Fu?u=$H#>IgWnl8{V0$LGLd6Ju5VxF#{^h4_ z`g?EAQd+aQU%!@5p}kVQFcUpnA%9mcL%~#~O(*BGR?X+S(Tdv71!iz_WAuse+^^k# z*qrBL!=3kkUoWm3p$NzO^lF+ouY*yH3p9na0xb?+?mDfc&~WCs~VJ6mI9&NYbYG{$4+15iAZ1Ky(@tDczdhgcxyGZO?rii~9}6dOnKL61 z`!i_8{Olp1`PYjDyo*z~?v=Q~Q!eRy{A)Qww0ME^w}$gO&c^548B+k|yld)E!0`6? zelp4AboB7xcJ|jVVQ*oPutTcVCI4op=DH)pLoMG+n-VygOrhr_pDN7Rt}}6Yl1DB@ zvhak1$0q;pm5)YxXTJ5=|M40d%^ zb{jvLt(md~|35yEn0@$&%$r{e9ge%ZT@IDmI{j$lyjm(L>GLT(^ii*zT3&3a{8TaV z@P+u`L`v%8rgLGmS}Z;GE%A)^fNOSydmn?F;2X!U8{X+E_cuz`Bik zT&opUMX~`)|5$X7k>PpILJUn`F}sY`^}@61wanQjmz+ob0|F@yp@upc{-aaE!{4k8 z1FBX5d^ePHom3QyI`xe5j{!MLKG#EyjJF`GQAG_UV1iWr0PEA08hH0ut_js6-i%V0 zY`}%dM(^QP%;hz-5D(ZgLZfj<#u9mr-@6Li0{*^ufim4?@?HN~o%f-v!bdvl`L?5j;&OPFO$FX# z^&M=*M=t$BnRS`L7*)4rRg|c>#xS#jmpW-UU*Wz19z|!-Gqfv{(}O9lYF{qu<4KS7 zTL56E=F{Fu1XE9I&3s8t>RjKndk1qTfn%zyzY~cy&#lnkmw(gnU;SOqmps`M8Cyq7 z(4w^^wodBHxRSM}6lWbnQs^y>+5J~jU*BvZexY@STKsL|LXDaH?5O&~@UeMI-2u4X zm?9IzHsW!*ADu-P!J73)}v?RwYS?L@5* zS>i9mu6u#G?+E9KA({`6+WsF;2Jc8d%XJii*#G%xv1>(O>~IBT`7(>X=C`j4P!Q%P zEb^j%&Mi=?MIXv~<)3?yel|M}TkJ3F)`wVxv$x1nvlpG9yRH^#Pk&x$_+(^P+apa5 z>`{xnNbt%6;ay}kV2|f4JKUv(trch4VNwEHmrERJhpz@44>%wLUk#Y}a6pCwG8~h- zh_QxD`EgZ_d0z}SICh3(XE@I6zr-n=7=jh6Em$Fro%t6#^Z!Z2{OEks_>v`}RR@35 zJO1B+Gvi-5VI0g4hZ_`*d4;bA+yUW)aq!iEi4P}?5dK{0Z$1$$^y3XZue$M5(yA9VpCa_Fw z*@6WN1Wp`3tiNCZA9BG09v@yF@F#0amYxFt!{>P1_{xF>koKv67iPNa+bviiwcy0z zgUIWTyXz-I9-qT)`!TV4;?cqy6_uZN+LEsTIc45{2a|gR7jL}0P87Cy$&&rNy#EyV zLkgutmKB;Do*$oD_LeG-7(f-Jiq7i+ z(;Jc6gFGm;QodjTgnwS&V7B+Ld??uQW%K*^)UqqY0I49}f3c-7_!8{ldGBZeFMN(y0QK*L zB>gWP&WN(~UwK1?G|$$3Kj!ZW3wi!61niDkw&?bJVGR6SVX4Ny@}1*7mhe>@G*~^E^V_ z{||!mUrhb4smWhg`0EODC9ghz>BWBv{L{Jl-<0jY!i)T0rv2Z{r~vktY5%8O?KhqK zAIP--5~TmCwiSPq&i`Hx`&-ES?-2R_ej)E~uJB)j`QKdOZ?5n+SD2Q-Usw3+3jd2; zL9UK)j5!OyNdo`6#b3AhU+fltUEzP<0Knh8;cwnBTLS+pXJP)j!fZp}iiUp)(qDqa zWfIf>`?uZ3$(`nsko=0j?Y934FaIC3+sx_fL&L+hf`hv%Cq}v&M~I$3?F;;u6u6jJ394UXG)wnJNwsRl2~ZZPry+>~U%j`Jy}Nu~$G&U5Yj&GpbwH zm%eWVmqbWYeT1hsJ*z^e#?!m;&xw8kr2Hn^pM6xK(>vxvvdyC@y1TE)5!NzHQ{%Bs z&xQjJ$eoa^{~7(FJz6gQZT@99l}Y!IICP`qS+`#U316}e(RJ;;!}cz+vxnbrxr#sp zP-^{K_gS(Bp8CBa5;Hy^zHPbbGC?Gc56X75qLL~DG4!OXrLP-LOiDWIi+!UN86omZX&{M%9u@ZmRz8Cp@ca~AQaU7jKnmkSW!@IrsbhFg^bd@{`ov1s zCl0m_)QZPn3;Ym~X6u4a?f|^{Y@+gCM`vui+v@~Z8GSMICCy>{ird8Nw$r_5jL(u= zlM&ZgXJ(E;VneSel*7po^gk@)1f?I5Q`#5lf9+dmei>#U;%YbMad28HrQlwGb-diK zBX6JFx0S;0Ldl7}+zsLF-krN#w4qtHvgm zzdChDuIAq#M>_aFB~dphu)=Y;j0xFbQ_cG1!O5!Y4G$Ya z%}}ZF4E1LYDlOdsUwT~XD=+IQJ}b>@crHE@s$m}k=GclrMB?7Zm(#D+H&*sJn^UJ++t_@q_k#~9G+-WU3W37nZ!PTc|g385~ez$Isl{msF66T*6efjQy=58 za-OoX!MWh1??d%N>sTB9t&&^&*UfeVxI=7hdjGY$NV_kDHZNt*tATnX?HEAmgaB%7 z%aXi_#W$Ou?=?OcgJfMP!KS>DNWVq|(h#53{h&wAqG*j6O9m+cZ|bb$_VbhSX|bg5 zBlRP*pFZ0OFXr%M@BjkKFS#@_;3{p+_}IuXnyJ{w<<3VIIyhe4BydMN7F#j!B-9Yy z^y*Ev2HUl<-xT563nIf7o8Z@&IONt^e0bB5k(7GEA%EoBPp?-^!>8DvWjfKVsC!sn zKw^9qhbmvHL5xqOyuJ@Ty)rn(e}8*>aAkS>yN?eEmtUHkZx%QF%mEo!NicNTJHX^D z`M8rq+2>u8;!&yjqrQ(O@k-wHM85+Z;4%#}Df`}Zm-*ZafPL;m{1xkFfttJ%7 z`LIczaB2VZUE$9W4*nV=-}_>T#EIGi4Fck9v;X7RQf|;$PYNaSWLO#xX*6coI;&9M zr6s&6y{=Fsb-KflkTxvq@90|b$%NP|a+tLmcFf%Tyv~)BXV9FnmQRD^7mlPGmCmyE z_TL3`k~-<0^=woB9TKqD{Xo}QqUcfjBbgH>#N6`pap;+`%~K=9pxzVxQ_yCK`B>i|>w`>`I=mBwCI-8e_TffJ9asw`aZED+yT*NPTU^aNHW| zbAgg29bT*56?Z(GvTg4pz4fAB%@-Z4S?Z^FqM@cpZ&z++0&mH%^Iz|(+ z0S50h@5iyuGi^3f+3P{?_44uZVY}~XbE$~qIGy-Xx>s|Db>*pqDAXQ(rRtYe@u!sH z1+V59aS*8TBp&~G;Mq|G>Kf*wbX0@m(4}xdHNjPvO{AtxnR_(miY=5JXShp`@nYz~ zdo3ci;&#|=WH=$)?D17rh;8-9wi4ovZ+JaZaoa>2bdlYI8Yxip=8Uu8rePO@735=p zrTL3l3iZamR>XBaONctL)U)GZmGWcZe86U#tQ)B05gTN@zH{ET4i*A^+zavn&)yQ_Ql$|kfdNl7k1 z;k9rguLqmKpQnmQvi68|wT#X}S4RLDq-R%qBptpWTV8*0gto@!=7x5m;P(u^ARz0@(K5eS_17Sac{iA?{A>joUm z(2yEQ%ad%=L414Y9aB+@1O`7=E#O@C{3U%(=i_cRJ+kX{P|hq9V!{pf zE1!R~O4P|IpP1keHcw#LVqd#>+k%lCtIH49JF5GQ-|uhBS6U zTEc|AA#aORI+MJHChzvXU|A$f)GJPJ<&j2G6etQTxU7rCx;1r7B|2WmqC%B*1@7p^ z(whd3K7*punmINF6A~>6PYhoVsE?<)$NNcQb`vYZkz`uiaxQ^jLk(wfW0*@gq1Us& zX(|*BDbttA79pWsv~2Vaw%?0>y?T~heqmr$K@?sszCv3`O|9p3;q$F5-TgTPmsEbJ zDI@B^$UIRT84^oRmO>dL_aFpL4<%eDcz>JI749HVxt< zF9^GwcWn38z-T?RE`#rnU!Kl7-6U8wywj z6Z}IU8I#>cwX~q8Dby}(n;_Tbv7ySdBwo-hmZ*$4bM+hUE)Rgc|784O3RPB}g&^R0 zLr?Q$meJiw{cJaaZ#zi};qrGbd7C5dB1g^xLzwYOst(;vk$fQKBs;Yg zH8)Qc{n{VrE!3A`=td=259XwiF;VwbWmqotdwK3cS46nBb5opQEL~ukE(p~`-gdU> z^?M2INuwvlpVd2{r-`%POe*HuA{QhTZ+W;GJLl!?;3sgFC<0 zf`#k{$)ov`(L{9ym6C?3*|zP|ny@_x=bUnmXf1yl0r=6$NosX`NkxdoiW2!;wS(Os&_aMTw$vw?c>=+MA2nPTgFiRQ{ zGOTRVn{e|wwl@x#B*}6*-js|L+AO2FX~0;c_DIQ3y|}E=x;hWU z;f&U_t|C>o9<~FYNQ|R zluV6(qjhOFsxo{vd%x35Q#!jYD+!Q$iw(`LczQYPjVry9(5A~pSY}=+{D_8(Si%i9 zK*JLNf*g9lFnM3cwUuQYxeeBSeWD(rwy$J$ju*y-1J!~pT@ zn81yZvZ8m}?jnyMaBQns0I7S4&5zF+7(K8<7vtW2n<{vz2XC!Miu#X=3q|vEE{P7Q zNjbSZWW(c$va>ekFRHb1B7xcoo!16Fvv(Zr5)SYjlNrnzycuG4zwxPzOhCwLj)eM; zSxfC*2U2wEaq4lVon!Y~|L9+>M_R6_i92!^hpFFX#0eDT2%ZdIK&t|Nt_MAax8PpU zQnzSURu)0*>}xK=L{0bxyy_W3N!RZ}&RFpVPlo&Dfx&|>M;*rA*AfYY?Ig*lgX`FA zZw~$q^3wS1p3h1)=2p3xaHQ-i&J_z_T|Pkmppn=HaZ=w$jWb>;U^(IXOHOE?QroTl zE5WnROvNuaOmQlP=~$^-@Y*rMzQ6$4di_q8gJ73^Au`Evm)xh?!C|LrJ^?8~lR#ZixU zn3+0qI|lblDL#rrMqafBf<Kc9P&R`2pBKF&9xe5(=HqmC~ zubV@NpBf*hiFizu`TP3&a==_Jkq=c=w(MJ5Ofg0Wtm&vS_Hj^?si=NfueiX6t0cG# zGNq!s-CjSA7D<9{;yKLWe+_}yFke7T!~IU15Gk7DQPW(;XNDBb?`bEf^i48wdU0aF zno2^(3Dh!c&gU0QDhAc3EIsP)Tr0_V_4Z3rT3%EmF(Dx#hrWZ;Zl>cQY}lMT6nuRI zs%f8|+N8%sTc?>$Fky|Lupp=3*YcF+(A>So?DGS-ODJGEUI!mfhkw;l-VhpA;WJs3&)eT7St|inxcZEzm`R%uwRAOoiTa$rO8u49oMr zLb@T8(BoqC-RRf@VYfA(*XVKXb%KX((UfX4k|*@?d+~qQyhU`r<*$-p(nalrj9$Ga zWD^I3bb%q&`;)pu-p}4gHqU15kLyK2*xvPtL;>PN{!+UmQMR43r$-X5Cwj9pZ~65+ z8ApLP6}PEF@9TP}8XBa-+-p`m=Qeip(|h2U_4GspNsDIel(5@^jBk!vw42GT3JP|t zYX|+{&HdZdD@AC7%Y8UoT-&Q2By_ z6miXj=I!j0 zcdsky{eI)=5lu4QK65awj&x*}I4im9R_3R7r+d*Rs6!8*%W2VCp6xMOCl`;vB`v$) zpUAPFkCvL`g5xg-)57gdT#uF2e`oU+rkG|1r1JU>Bq^`oazb)7V=v?e~!Ju z=;b{0j-PlfA@#v5Unr?4DuCl5Q;?}Wqr8=U$(%MZLTLl*?7QOi1q_Es>Xn2wtAvBu zzol~C{QAJcj<7bf3&tPjNP%Xik>zR-KM6)=yfemtwp{`$#ZF+a7J@Ve%%#fcehDDs z06AZqC8>x*Ra2%@q0X}vw!ngQp3qB>5#>fnFY1RE(HVAURdCHQ%*N!DwB;wkWPA+l zpLz+Q2Vei(gK*^;CPJo>m;LQs{Ml$QYj_vv!wgsLU$co0UW`ExD9YgD2X!UX_GoA{ zJD6WBgeeK2G7gLzsdT@q9L%BovT`~$E1q)`j;m<|+vbAJh{k>+vE-EXGbkWdS35D> zmC$s@fsx)4w{#ZM5}jG{g|)3GWRRx17;-S zx{^}Mw~`?RrpZlPBKU3QJE+Q+{C32tUWc+ic)&xSjnoNR3w1d1CDC?M1ZwnkXRrI| z-i|peaORtTB9*6Gl*itW+HC(dBap(ZBM4JTYDZjV8aOO42kPtlc68e=dM9Q^cq-Tdb^|8M=nW%3o=)`~q86$_*!udt$jq0$VRtDb#q)-{K|_>A z&g9cqzZCqqPyu(Qu4{|XZJ~VSmK!YBeX7K)IiSh1!}CQ2!^2nUl;$!!L<`86^OJ*u ziR;q9WRsInMk9D8e3NW0T-}6u)QY+5R)oz6M5Gvjr4*w3H@Fz;XaAJSEi z)Ea=#(DK)-z@QP`QWNt!{F>2V*l=~7gS+$~H<%T`X5JjUT2ZjxArGgXU7RqqNEcHL z$9Y1dZ*vZai0_8$KsK+Yw1JI~b1JyDv$LvB&s-I@y;-!JWvT@ibrP~|TEs!Io%-2x z{iY&kcQG0Pk|gK4vtUg_m61D9yB@^c(IF~VKc8Fk>p~x!;xT6ZPtOsEs#C!)d}Wd1 z5+qBS3wcx=erO)(3zNWfhEeaSgC*1bAD*)#@txnn-zR$^fy#Rs&WK{ z=%=dz9y__c9uuJmCB$4oAwm)&%b=Q5&8PD!@EbP8Hk$r^a=BcJj^xC66v(3Tn=aPh z;zKRFQ#LmuAkv&-P3&#;%hq^r;(L=l1|Q|vu4 z(Gs(Zq7oL4Va=uZRbFB`SR@$7JZ>tW2NM9r)s|&vJJMI{ zmi4uQZBEAHUtERP6<2n1&l|Mfz`8wa^^LGEOVDpgqVGX+h4c&cXxcenpaZGa?=gEh zl{uCh>8feNhfs$*b3=nu)+umdz4@c{1luG!2rgFvIggP$kN7gUnZ>?-yiid>Yh^azGrKY-bdYKe`4B^n$@NmyOf3$ zQ`P24VqY1F!Go5cf3#;chb@9KJq#oP&s8G<;$HE+r$=55=k~qS4xFRoH?wwdwHW3Z zS#r`2eL}LXD=0ThQGR#BbwtAq=6wEXnC%X*Ftht%vA*jojGkP6?#mXhUM@v}kLSXt zd)Nt;`+gFhn=TO@UsZ(&yMnF58P%?jQP|5BNTq$d@2Alxzon%rN0ur+v*zvse^mj~ zD^lQxz}rl}{c0;1Qbmk7JUe*%zn-p$t-nB3o1HR;!vKRq>tlE{%zR z;-VAJ>hWbb2{w27{ih&450B!OOutv20&Uw_OeF zz2gvw06tHSG49}t+FDzwroXJua*Jj+*y3|!zo}PvIWn(1`BenG<)kK>qfVJz3lLKV zgmxuMHm*Io*IwX&nTN?Be#t}bjamtGV{sVa>%3Y*f5Kt(b}V2`ue7nSssu;;^AC?~ zWgBpTtq&nv-Hw4@9kt4yQk0^GFaEDb2Q19Tdg}*9D)c;cslkI!&lZKKvK}_2@b(+n z&ni9CE2D=^DPuQf^Tjl7oE{0Gw{48$kT@uNSap^}C>(|Liymg$Nx1ossBhoWTLwsX z(4%+mT^cJ2ljAH~v=>_e*DgKgUH|@7@d=be{*Nc)>r6wTG}6HtI{+y_@_n@xi9mrS z+>OcCbwYKWyLyPrF!a!bcYLVL5uUEC%Q<<=J+Dt_g)l%ozLe2l$Z+pi_W{Gh{`Eh` z5~P&7bP;NXeEG0|Wc_$$zjdJcetw5=-ltB&x8=%NXPP1;PtS~qyhXNX^%T>40t)-Q zTwF+Pj$GmZVcKdDYDE_7mC9J#b)k5CU|M7L=wuUC2$L));Az8AEPzQ?Q-#x3ThP9~ z99J35vi3RcDF&nyq`keQSRHinX`j zz3^G)#)~{Nd|$8V19JUhz{9nDIY+|rcJGQB>fIJQx^y94wRxbaG>KS0Bf%kK!eOhf{kQ8%wa8A8Vt02rqr_Vn&pk4&>xZYMhPG#?jlv zXKge{4V+P0By^DVuss{$&UB2&7Ji5CV)w)wC44>aw+C<*VSC>e92Widb$xv8#EUjx z{CDb56zLn6zfFmC@eCjv*Qe@mDg2a^!}DyNOpbNXa=dS!fVmXhlDDLr2NL~~0a(o1^i%6{e&zkvs4 zkOD5vWo;`G2hYXG-Cy9s7p0)q$5} z6Z9_$=uP;2=x=fGNE$M(Lqav&C%y$U^;NrJ?;RSXc^+6bOam=w+&GXDtxB znYj0wPAt@rT1578I)oY+V@&j!ZBVDh$+}7FXByJBGr^0sx>VAU*$eX`DT``EvY7IN zRSNKr`2f;|z5_iidjRT~bYV&BrKS(0$YppU75LotOZD)%JTQP5vUbNzAFPg*L$FXs zQwio;-Z0dX{8$8AbV$cI^!}TGQQxcFFLJ4rI?y$KG|BjiM0pvEmn!Gi4~5mbX=qqa z?4KnO=h+*dmWVoAA~5_RWDm;A)f}2SRHlin3z0d6s{|y5KDPN`>M2;qN|Jqt$F9Bi zK{6oCg&qreGSo+4(aWSomNAV_3glNt=t34C-B=gppLY7~aY|Rkr@FTn4jjfYyg)0* z^o`3r7BicCIrJ81h{>^Dgp!EeeZQ21^Gf9?QA{~vi5MAz1(vBUX6+bm4UtC1F?Oe) zQ2IUsuwsy49nAd*+PxHM=q#=0T!^SE^nKQ2@pgRlvvttEn*g<@o-w}q?dqtZ2ac@= z8ds-|PbeS2yVv3T5(ni`our?$&L&zi(EuuDY1tb~CL)05wPK6@IiY5^$P_2&yNORl zS9w|ca%|^$d2=M9tmavd!XBKV%noPo6DUgCJq-=e85ItgtuXVdCi?1m4h;7H#5d$N z{vuE)u9b;Y>M!dHOyBzbAZ#*)JL);_1q<}@$VRYPU;&5%P|O+a``Z$9SkQpgRB-g> zLs9x#4kl?#mdW_0=(*cpul|)(xXytnmCJaF7c}(f3GW|5H(Vpp?Bg^mi4u3MWg~(N8n5~g<@Pm z@@E?UACLG}Fba#F5lXARfoJQuaa@ORwpi~L7QlFr*FVTH_~Ri3=AtDxz+S~Sk4*dm z)I?hh%O?IXb*ZG|v;BY<87H(!X(xQ-dkAq??F3D2?46u4i=-D+h_*-V+qwq~^-E`o z$ymT`7CD1OLp@gzY_LEZ4hvA1msjPp)?zw33-b8og9J?fZ##-x41B>`&w3_XMqyys z<4lk$sqdvHE2t!Q_C37o^>1U$mQk9?`axhd76Fa5uuS&cu zsX)WP+ja*yCq&@?~mC4LxmQv5aX#ZvD{c!z7sNUyQV_~cO%jvDv$g6WGnF4y?*bm`GJL}tCQAHBY^8x z##@Hk(EAU;iHu7nz0`9h_KXuH_IVqvh}456UUXVeeXi^dYIn{N+VBC3rdB)6Yh@!v zjl_{-8*^y!LG_e?pn6a1fkw})H?mmS(RvJ9o%~khPAnLkIC3439bo6wXX1S<&0t7; zOUa(e$sk&9jlzaZM_QZ($*@s!)NIfFz zQuZrS*4X``!O8N%nf_nt;|;{+?s8tIzD{;v_}udcqte@IPg+XJ=5)Ob`qbe0gOO6r z8~-Yf!}_?*t>DzU6^UAshi$d^kgo&lIfhXERy?uQyJFJON2*_)fu=_D>YQ-~A9UOB zW|51A+KbO#Mi=s$u@>8f4(kXOWxw(`6As0wIcsMrSHmf8+BJRRs~<_bqsJyETZnRW zGYYq#o_02FXD;Xn726AQDRxj?roWa zjdFC_fJOq9beHjsf*}oOkEitro^`g}&7j4UtMmjO>Pj9+A9n~`?yliwVl-Y|tT|dH z>D%4gxIxOuK)1E|D6@Vt?Y2@~7!U|I>{uGWq+2TzS6u)ON0<3P$DU2HyZ+I3%TV;} zwA*#|{O+lAb5ruG@idIEi5%m`m|D`xd>r zB#>fAwXi;ec2{cD=a$Ha%cMWm=&3EwzDA2M*dY@q%LinmqzZhSDS ziqGh-Z*>=4wcE4t`P-;8+OZP**S+QL1P;>$#h9Vl2mU2ff_EUSq1(AE0lQGK-0bwL zKC3v7Wn`R)@3g&wH$MBi7T@>vclK0#T4b9qdbl%671gtX{Kl3*WxU$(!dCCOSa0&y zZtZ8bX;L0Vl0F9coBAuQeQvH#+a-+}@ktVt?>Nb3?^A(?tJ;FvGeuoM1nw2>Q)Huw zpM{hV<<~(VwefUTM}!6GT$^vv@~90aa&_?3e%TwEkz~)7@Z8JJW(QPpD!iGs8sWPT>ZfF^tL1s(4E!y?#R3P_VPZc5T8!lL16b`ly0IeQP8dE zwrPu96940(5$_&?DaB6xS=Ze_UUv=m^F~>e+DWgqEL!y2#8)T&Q*eY8k%ue(aGC8` zs7vse3=`C&!|Z6;(px{(uU?y)x22mF*e23NEmd-HT7<~2-UVjOnT2V*`f)-EsAtU& zQ+q$4&J{q>0!Gxl%lg1-5SmQ~XmYM&V(t z=+ZO4Xt$W2cOeMtc|+w@z38Y1T_?u5`nvUzGb@*sLXdAGZ=W0!ED$4-0ZU;^_a){H z#U6z<*@I)HKgdav8%DjXRCZ9u*H3DsshZ_`V&!k;WZ zaG@#QuCPHUf8Prb{m*O!EOpM98rDRmBXv!+#I?bM^0nBhXx^zPU#%qc_#v_)+g zH66lljL37Rgz*`~X&mE}eTMDuY$6H6fnTVJD~W6$I({+QI;HWVQC6$Q+ve9YJJTY& z1W(~)JDZWfZmT$hE4JjpWkp{Zs-|SY^cJE^^`rE*FD^dasdeu7gxjcIT-BIA`^-|Y z-B_5g_pXgh#ZE_SJ|q}Oj@3V9Dxjc1tX)w56J5QVGO@I<`Lsly>RsCm*@Df7Q3OZw zm*L|Vbkbz2ceD~+-sAn$LLQ5QdTp5WSd#PwugDhK0?4=8F_5;rxzf+Xd+gKQQt++d zSBr#mAS(^~7QK{^>VY=$7D@XNJYVLxh3DsBTi$s5F<-SBkJz#z4{H-PC!7lF8Sg1UIc;=qWRDJ_t;;ZYQ zPbe6@>V78%8w(s`wcx;dK6ZAh`P+bS^bJsUEo36E!D0WF=WS(ud?|)BWB#gl>7PCx zmvKaB$FGXFwG2&Cb50gcFlbqw!eT`0F)WBl@kNLv4A zF=F*c#|t{G*l`#4EK~r!EsA_;{5_}-f7oiUx!*;Twd=^Db4$p$7&s# zOC>qYl|xP;O`L`wTNv2Qd&&j#K7R7e!>c@99b1|pRCEH_^Fy05sU`Fz@Un?<-OFFzhlEMTZ`bUF!FOCp~X%26(jbb<4nP08D-ub+qp@%6n2t9`h5S<{o+F)42`K z?nb%&#*xAp*U-)eRitoD7T-#~2ja$w(A0%@5J|pozYIH4X+_Gasyn`4cW(N;4CaCx zlVt`1Z!A1yesJRVthvuO?PhhCa&h`e2{#*O1DddfsKq91#%85*s7%C8=Xg|0*XBUJ zln{H~<%W3<-_A-TUv`+Ow91se`BZ|%i}=J}Tz*pF%<&+tpk&O!jM0bB z_odiMc7BgCNcX;Xu$`AE2*&rQiQsPPwc z60Jq;4wDX6u`Q6@@i zVwwgiVIvkKvZTr09QRjOx_4Pm)5G5!F-doRhPVsT@(zEq&ujM!vw?z5xx3X?z1^Yk zT|XbHW^@vwpiMSY+^_bXk_R$|yo-j3rDs}coac#~*Lh&;j&6r+ci*KU$75*eZF@fJ zxtmU?)-C9{AbZz(D|(mnfRYfZCvW^nne|uD6vD>#uuTDeb3PVcP_Vu|y!(0E6$k#Y zmkFnwZyF35A_&7$nb=-)G(CGy<}SM1RD!x!x$b#}{!A0d03Wd5TTqH!ao)NHbz9{c z)ki+pX_IPSOIm<*TdT+IA6|nJtcukJvryYU8FVF|UQ4C7f4SC5%M;?Ur`*aFQ-A}Y zX~&wXG9Cue=(}Q|F2o!>+X7BD&JH4A@fj=}a+T@e2Owv zZfzwEu!J%^R%QW2IoozYh6mlHc*N{TeJov+02pFu{= z=i)A?2`PQVl!v-93$_a&Bg+tFrn50@VFGdB2dcEQ{Y7n@}(x~ zuRx^;;xt(RI7dOqJX#=Bd+Uy^JDjg~F-qa6q}6~JS`hV#6sJ+ilEhR-;s&Oe+!+ZU zst^tWAqUTluIBL}OnrfkIElp48_1$qpkmxz?YAB{XE0y}jdSUNJDY=D65vJffnVbF z6GRW;^ZN<5L^y6r3HvydkZ3oT61Yil^r!^@qK$XS$Kxwk*epHbb7|Ncs~L(!B{NQk zOY8+bEiazK({$!?k6Bc{>NDtO|LFgtPm4r?x-dBeZcUkEYZng9YikC7B5olH>tsJq>gz-|JR7Rgbm;YH0W$wJotb~w~3 zND9GHA0_Jx`1%0)jqHXc$i)-pWrXJhjD}>iw`$`&^vQW@!2sxMArodCT+>HouE;T~ z$ON@1u!34ZK?LM!?j+I8|YDW(F=1WWVIc-~oy(n1oC0{KvrhUIY?1A%WtE zklOo2iMS zfd1Psg1Pd%0h7yMVLHE0{2VhHv&)p#TeOwF9SF1CE@Z-+(++M>2vu|fr5OX3@W8c| z*N*vs`Y`W%!z_!#sz1)hYzo4YDG@JQ<(#vQbR1j;agDYmm_kAuAqrMxHG-|z=gFWk zR{0&g@%Un1YXWJM)$yy&uR1Sw9Rjk)Q(cVQzVU9BC;P1l2Uu-WcA$9!x0Jc zWGx9exRf%)si(0D{%nz>+rAw-0wcOWIDV*MM!mA?^?Xd)@!d2+BOXdreJcQ?M#Z=t zs0m4mb|Di}tpw&p&ywGV6Gx|HC%Uga7NDkh+q|Qw0J`qhRJ4%1piibg9+T}eWG)5r zi(T_Vy0?Oep6|~Zt$;tGYlfqYrke+`fm%xW zCaQEXj+UK3odGi{mD6d!X>DLoqV)#b}|;b2bkCG*&s zxwpVozp0|dKg&Rlyhz)9)tzX+bRh^ovZ6p=onU)8@%r6h0NiRA5=U2KkEUDQsGEln zd8($jx^Zf&6L1t*^~tA`Vu5A3uUI3ZpqWg~v#u~@zGA;%ddg{vl3fnWKK5tI9W3`G z9!>{m0`5VLwt_*Ss%<;lD-7lVN22nOYARnJZ=Za*Jme&JM|f1MprZ+-UTeD;`ou=o zcCZ&6=PLGa74r)gtV?f|bM4mz*-g?Kpi~oy&}^9?f`x??#o`c6)RpHQedZiFx9G!p z#Cmxtp5D#iO@nJIhgXbRcw=k*0O`QnF@T3Y4vt#V;LggCVS7X8quB-gq1rgrc5v<# zn|X#&vmOvr1S<-YL9AS-gl9g<7(YDJw(TBG8j*>fvPxJm{|m4zlTUZBvEBCK^Y=|) zfNHa<=vgQ z2u0cnLG`3Zu{0*y{sH7lYq0;QzT3SYxtOoiFm5T0@04(S?Lk2FVfY74*}TsxF@*1E z3HuIeUQBtogy6|a*AigdoswiOjHl&3tvw1>4XHKN4Ac*r7OM(r^=VcCCjblH$nc|3 zC`OdD97e-y5zl=*K(8`gbTv3qaSsX~2~2a-419g#HTy=uUGz|h-%_yHR&3xjs5hyk z8y+sPi*6=i=K75W&fo2{=yPZ6>ZVn#v*-iIs?^Y4hF`A~Q7lMXt^M*OuOFNm13A?7 zLIX-4Ik!)iK{6_ZpeSiK8DGx`Ja?j@4&+QGUy+KQj z2FZ4=q37a=n729_%h9w}m$!{N`6_oVhVyn6zg!Nsqs31}+tONl6dsO!MWEND=1$Z# zy$2`YpS=EVX|JCJrO}ud6|pEm@b!>e?__8l1Pt~cf$|_q3CN!9$N+~(Ua-$Qn%-a8 zw;{alv;(hus)vJ7?vD=&$8mm1CY4=}43~xj@15{H*U}hepM-+}FtN%#QQQ#Wsm=94rEWw$l1C=yxPRC{t^UTJ+~iceRIsC|7=rupP7h2Z`YtX zR)Ymg@Gd1xWi>U$Ao@a(EKg)@5 z@w$pK@~A-^2qp}6*hZqqlKGHsj#qu_umy1)6`L+NS8Hlss|#En0G4VndTgsOrg6I* zU>==kaH)}?p+WyZDx9Pb1vl+iwD$3feDM@~zvUV%A*#IU@JaxDPkjtHrm&eGRfK+( zg4>u!?GtDCAl^2Ta;0;-Ad&(axdSqORz@r)Zpm8XHdLP^}tJ;P2U~L_?nzZ6UC07C)L;F zU#Vw&Pq1U_DMASYM)_3di_+hCV~4kTKhPVx4YrSVlO3~^(YR|9Hwp_!Law>0mO9(i z2Pc6;)h`-UPWhOf_g!Ar!r+My>qW!ThwBAVk>_aW!7(M)!a+(;xpW8J8(Dm8G0!*2 zGbV+?uIq=o(&`Fph$DG7Y7JTCHnQ>1tF!yHQM$3a!?eb&l%x^Pg~&9|<3?F6+2k{K ztD~+dO-`m?ZwS^#pLHWII+t=Gci2qKA@cRP{Yd8*!8NRq4Zc5U1-Bbi7Z&7OJRqI% zLR~K%I`1#9wGMvUjy$*m#h<<-ZD6(3s!d5xz|J$O=~d_x1D~XqN6Ylwo5~7BQpY_@VX5-C4@hasu+wFdzXcHCl42if8wV#-WPJc5Yfq(WhECvGqD%Y*3GM^f%@f%w-h6!6g&H6}{I7Y?^8rlqP>`He=ob zw#T%$!oR#CTMLJ2J7;w<9xt?x4zwtJndCu3d+~r-N<;4u>#wv45*y{G`|Xj4WFlypch z5fJZZLpXRdi1U32*rV&)qtdT@z@XPjT>EnGvKXm4-D`)C{?4?K08q+2pI`@ISx%e4 zcNdt^-R!Qnqx*P6Os}>0Tc2R*9BiTeQ|11t(WyfQA-)Ic?0*6!oL*T~nh@1Pq^HRu zQ8-18`%+VhDc_7+_&+WPynsl#&|6dGL73Stqo?zZ>{Zr98r-fX%$vDQ?YJ0VVs<4A zA3XB2uG#oQ*VZ&o#N+O2&v=$c!WyNgv*csRl#>z}7c6%c{W!j)hAQ5F5p1Q@el%Yq z5CGnj`&NQUb8cN515~+qvshROz&(HA7|T=JMH|d+wyW_u_L!Os&d+82AIiQvs;R7d zTSUP^u^~+XD;N}_G?glh4M7-50Hp+!CROP@W*8DJPNdS?!SdTB@aP?So~z)r1Vhol%o4c;6&3_<GOn{Psw zk6!onp-zwM9F_B(&8KgMppp)zbBT9{$!m$?k~qP^HR@|L8aNS=sH|A6EOHCbK4iT* z0j@}-NC=T%1D&&!8*9Bnl(ag%FNdSx8by-SZqQn-;Jp3_n9*-=ZIVCOc%M9^{u#oAVTNl-#vGIKyIV^_I~}O zF*{m_EXwi%+Sx~&K&}3k3R3O8&!FqSAJE^cQ?E&wLo;a}{@=g$ZiAG*e=;3c_%jFs z$Ku)>jtQC2xK~uSCBwr@hv?Hjs#6%r*t5%fE2b5yB6e7UuPHQT8$Q1`-#eI~&xMWw zd@ll9&%ImP@MHMKW1KHT{@3JuR#xX2~j$dX@G_2mNoJZ<+HhWGR)pkf9wIs!fg^H07IuIfNHJ(<5i5s8U zsIT;bbp{3007i1s_pm;c z%av2kbRO?=N4KKy@{*y?r4ZyjH9qzvd$YI$*Fa@{xfw~4Jmn-Ai)QUG*8@0nb>h|u zC=@)=)+!uwc@LgiApEA}@@txtCw&^Lt$c;`iXcCEEgd|St>+P|o5cp;mTaPD-g^Xf zYnQja?gb(U)L(y;TG-jfOO_nXKfo)0K2WC9o#x-a+zNpGvRXL8YZchqxadr5_)uSP>4pOSP*~=M}qJfZ8GJcxC@~=DTw_BeltXH&r`u}`k;R7W(mYd zpSub?ITA6XX04lu$g05|4*&@yXNfmGFQI3hu);*eX}*x9oH5_@JGGi0AV8*ex^=Tv z#2JFV+HE3bLdr?+!421CWA{o##EIo7(-wH?J=eR93W~`tVXRYJ{|-qil*96^Q{?Ki zfb2M3j*!?i&>pjZfKF?V&Ty8=>c*q|IgDa5k6xG?0_lYT>py>~q$9GVlSI?R!Fddx&$W!(Zj7emuu6(G763ms!7se30S?+ZiR!`z$+S(M6E< zyvk)e1$YQ(P2`$L1Q>ZJ(!_&yxJ#U^#vVU3ul$^;T*0A@C!caEfPX0W<)D_EF^uX< zpI<%72|^{031_fry6E%Uw>Z1%FM7z|)kWKR=K^&}8ol6k)AMCdXeK5L7b34{5hP&G zK00k?9p_>m?U`wAZzQf|sg52h0cmrMhzsawl0aa)?B-5a+M;)DHtWv_Z2_%pvceA> zT`gIPB3-0=&<<2tqY^7yMtr)iC$2m8zN^!QOEnwRaenakJNJw0v$^mq20#KwjJta- zje6?XZCkG%?LSv5dzYw@xZibsec!vv!aqowJ|w4XZOrV|@K0_uAwUZ}%3ndUR_HBNABZaPNU+JyDTf2DLu)dFYaF|5tVQI*NCvDmYcF0=A2Le!UR5x3WkK zEg&0oqj2ZaEq5~)7C$ce4!#c3?4yIu!xeYTzTL%4zK_jJWt|3)hDe^@T5m{#b&q~g zDD?TwcdXqnY;w-R%X8ZT@+PRXq1uKz-LqEbB9Gquy!4V!9_#yot_*N#c<@JaRw%WG zqt&iNWqiKs@-0v|`8oC)(2L@{g$GnV!@XmatxZ`g=aUC6R_P_O-W-yl<;Y=^_@GFH z272|wkE03+&U)uYZ=+@4ba(o!U!7^Tjpp@*S=XQEe<$Po@8x6_V0>u?8Cip39{Z8& zb?f$c%{`B{xdJ*wA;IZ;AyZ$lKrt5|UFXs1W>D9{3Uk%U83|b85v@&oyly-jx1%}c zrKa1|VB*x#9{kTBf}c8C-+jL-yEfqqC}CZP?zQ%&ROk$Q>8$9ZVv#lWYwn1nO3mj& zO;V@td4ZN(IS>noXrT3%)=#W+ktTU9oQp{;uQ8O>rnDyHk+`&HC`&5oRSDOX*%G!N~1f;R^ zPnFian2L`BV`y%>Z0&9yuLyLaEcn;$T;}*d?p~$_zxvtDAe|pa&jJE!FMxA&8(Pl$ z?-x=aKz?7u@2}t3WZE#iqHt!@&~Mo!t`OWzWg5||8+>`&GDDTO_;nZnP~wkq0L`!G zdj$v3%*{C2KYd1eNtxMdper7PsAVV^dmv;JdZr@z%1}+)x8EduvATdB!Fs))oW|CA zPGo+1Vw(kkNUt6gvOeXrh(N~7{B~%frOH~GnG9L?yAY3~OwFgG=@oIR_vk%a*G$k- zr2cM009r2nHHdQJrm59f+C);%PBTsP!XlGMEAa;eU;IrF59pS51rkCwZp<+@Xg^ts zvg3!2Q@-`;l2C%M0&ZULs%E)NY~1wV!(5(pw=V#cyBQ7Ezq}k*SxYwS4n=xZxKk&F-GE$gz@$seuNZ!f&dO z0GXJfJ#q7wqc3Huq%Ks6Hyh4AJw64bx^Ayf+OBw1Z<;8*Jwe%HnPfq1#~(@A?2Z_RtL z4&@3Ewe49kj=>vwN1!Q;C}X{I3w%49TT5 zNY{Q(K+Wf?CehYJtcl>TA0^`%5!&3slm42$#QRLU&gB}8pg%VPNVUuCS}CgH=1rqi z$%B_B4c?wbi%Y}eq;vj3LRkxGexh3U-!+xH#6IXOUbe_)VmsjKl^fTuGMz*TB5l43 zL!7whw0##e;|evh@q!mk_De*ZPpB$GZ|#Qcia)!YW(5;wSs)&*f)Ac=1TfH^^;9`5 z<5EI`P=3D$P#?^6h@nEM2jwPAB{a}JQpXCK;#NEz^_#B5CKWfMnbu!Sbvvx}Q0LX1 zVIo*2QkUZn5`CTXTbi_gjqukFF(9jq{gM0P`d|U^m7?aKwh@T-1~mgG94jM<9Le;p zkfwiF1nBIe31?QxM1mg((ttS@lJ!3lDu*hDwZl9-weu}3$FEBznxl1k?=5>#pU{T96I*ATkT2FJ16b{$}DAZ>%itA zp=<2(Ch7k6K3s;eKA(bnb{GduA^h*e$_M%` zli)529H2eZD0yq#!4v*>5^ewMniw2A+PCK25<7wY@wq@8)tki2wYO#|0cOu>{=hTIB~s|Jeo6 zsdhouRU7zf0Vxga29G|2)U~7e`}>)HvVbCkp)np%QEsec_ZWHW%#Y^^J;a@f`@;z{@)Leuj6QaY~_!wQ|>-o=j+d<3t)iN@lf4+W_;{G;RQ~h9UU|`y$>9m z&loq$YOK>spfzB2Ds6fVN2cl5s@%$3A`3cd#OeQ;qkFyCS(E@J=-WC{W=QJtuEE&IlFX==91B@!Is6y2Xcedl|nL zEbIxZcK3`&sy-%gNTTFg_<*U+4($eXcd*|pE$*B8V^?iW3Uy|DrYExaLFM7g<*&ah}lnaot*OSd}l|>Ry6x#uP zP=8DzeL)ozoqgKeabSK}*Cva;kj1;cB@Jt8n8~BEl*dAjpp)Py81=q2XK@i|vjSypu6?L_d5*%wt@mJnooK`8C^tvW11PsTN@I*J9bdqV9Q67%6sq6BJ{oHB)OaQoyv%dMNrRyM@TRHh02!&VW8|$g(0nXPSyF@L zEU(>qOvpF57Mj!oV!|B@V3zMHbA%m@W72;p0+po>7%#V(sjgek3(?;4k3mes;jZ6$^#O9HQ+Sj;h6CqE#}@eSNGqFbdxWxKY}H(^txOj(_neB8op@ zwN1fktkdhosMopPB&-n%6kOP5^HDoOt5-zDCUMC38Gy_BSH+G9w+FG_neeYj?fRS2{a7wyz#fQ!(dVf)k6QS^c`n}m7 z4OruWoqbFQ6kgblzjXBo>H2=XgkpAtAauO^B|6cl-5zr&5?y{rlT+p*+82(Hh$|wqVi=hTW^#8AO7fr1_f1U;hpI_re7l1blB?3Or#@q%A-VX&*~IkXy_N4 z-LxEiqM!eY{J~8Zc3ikxw?^m$_~8&R^in5Hq|xU#-{&RMKiwPWiI67BvVg`|omgvWVagIoTnZa-tGqa}aI zVOOJXm!Wcu#kG3RtGv-Ac`fQdmDsPaD1VS z*Tjl8?nb%gOk>BO7qJ&ecV>0Rhi{t1QM^=HG%QHnTG%l<4%WS8Y8G%R!gKvi#d(st zmg=FK9&Xyq&ME(Zy!l1cT{Y5GCtvGA4R=cCsOd~6!;d4IIY9ai2oiliDamZP^tk-Z zQ&`0Ln1HxuN&?C{7wfz<-UICs#2oIMUr@y}P7()WJ)FBM>w?DwXAd$zb|4BExWDSw zvYJZy$$x)|4d>e9b>_0Yk1yZ;%@UVy-~t3~IHB0_`)LxzN;ACGMbh*3usWA3gUyb% zhWCqY4Y?5ql0FRVPE)a|XV|#5XDKwv2sE-cAumKhbl(3-e`0#gdYXQM) zU3`^fS`!uwNgYj4K=G9w!4F3q^aS~yX9Hli$#(M6o2gWm9V$_i&;8AyyKqq_vN1Pb zS17;O3g$a#hM$VRgIhd;%s+-%%8{ea&%6rsv9f+lW)Z~=L9n1-=A$KAgFnT0H>mR~ z@F$IBI6taaCT@fq)V$II(Tc?}f@Y#-;*bh^Tn8LfZd5Ssm{egIByhw(d`Sj(j3=7C zf|3wOdt%5u;w z(ASO6UTO!^%niK2B@r_vsc$uO{_eiDd+#p87r<>_6XgI9qAY5Esi+F|dUrt+J$_F8 zVmwQ+ToNw;d}_K`4ImTEj*t#D@o(?f+Mw+(DtiRw=3%I$lc*^%b4`4(*N#4+I2>Mo zd`U;$eNkJP60zbO*lWX7clt4VmUlnR{uDbJ2}^MF97YRaG8#U7WWL!pXZ75nNXokc zi%wOE+0Jj1>%jp=CW3n3q}QN!Q*FRH+}1V$NxBYt+?m`wX%4LLiLU_8W+(xAp#tb$ zV--Kd@M(biKR(tvc{67w@|O((g>if~Qo=tsmBZwCL%ibtwwi7`KrL#C=LXJYG3O-8>xDN{X_sM7Oozni3q%##&)~~RR!%XvvLGz z$s1Pj)KMCISauRL^ZC7gy5{ir+jVpgt_uzVWGUT!T6=WMOLhqk#M(Y3@0vF`0#tJ% zuZrt_9A-NuIDSNfP5?(2kfi#`#{>qsbR@LEF+~GL8atrMfEViMv4wz?rMvof3he6? zR9h!Ses)k5_@G||pTWogmQEI&!B2Jmf5vOxI`!ZVZVwO2Zz>aW$K$qI=q`{mm|;n3q1u%s5BW6Y42Al0C(+;)v2E0*s9u5FP&c&4(k08!PUD~Ec}CY zGIeYG=I58YJ{Zt?J@e+eYQs*}}gl8OLoMJy@D>+_&f-q3UsD`T3K zucz5*l6s724HuoCF0-^Pt)P0X66eyzTHSpP+OP|Kr^aUCoF3>SF8CEBE zIlpD@fto0{@eIihr5nId#5H|%PeB9FpRWy`F|CihWRSe%^BEHeniy{Lcc-`qb(k~lQ;Ax(H}D_M zB|DHmO+^}ZvGp1;Smo4>KW+gbHBXt^<`UnoG94~*-q_-})aJwqrn%C!gQe2zUdC#< zO{V@hx9o17urR^mLTLKnovqNN`6YRiWCfGl?j&VO&PqcGw^i%CcFg#vp=_dmujoE; zU+HZ4sc`uGc9it_c96e(k3Su=&5_ztGcMIKsw3pXJW`2%;kLzwlR0&aN{@gSJbKz9 z5+LQhObQ_&&&?h9=_X`TMzYjGT>6#DJx*+KNorH|bn9^}#UGsO(dQvWwV zhp5$TNyj2=oo#xNz;EyYI<|q#31I>2h-*B6Ydpbosh1}V-&F47G+uMx^?m!{pS!;R z?|%IbmgExv`UnlRQVpmzv*3PcTY6TL1Mg|Z3tFoL`jN~VOtsxU*yaswd z0lF{0L_8B>xG3$!RuOizj#sBvp+@rJWbwC5*gfekB1smMNTTl}-684cXc_PNOV@!i zhY<%f4h2EaXCGcxC%rt24!AT5-a>f`-5YeI{4#uUnRGyIT7aceiN*(6-`$#BT4`w{ zw>Swj3=`sKV2%ys)iilSRJ77Bgb(e4 z8^CV7`-KXOS0e&kv@sKa7Ub$F;`5VE+9`L5ra)p_8?DH~;J`yL8Vf{dEPDv~??3`` z2c8Guz*`ojmAD1JIq`B=R}yWaU^iBI_Bn5bqD3+F@}(b3P&?EF^IY`OqT75LC`r)7 zf%&y<`Nj-k$&E5PN#8&>4@{B`0{!)(l|4X##E%R8AjK5i?;S`^Rzn*Q5In}@9{l@T z5>4J|abz zEjvycmIfklyK%cYc(&my1D+aP`949bh!aR%e9Jw~bNE>$GbB+PWuzX!>RW)iL?!|; zy)%AG5Olr;yA-GB5s$!j&ijlteA8`S9RIvQ_^*VqeY33jZh<5ikr+zxv&>8;u8lJ1 z);!hxitjT)ek1zF;?3BH6`VGf0k-k9(%{8z0}pEcoU`|=<7~#P75tkx??52AfyXRh z-$pG|S&{x0c>`ow*iN*Yx7h{sgdzdK7m#3C;tKjE$;BY1mo*~)Xm$Z2UmfhHsypfL zn&r*6fTar@?Fxhd<@j~@GiGYS(p)<^hsramt^Yv z;{5c@lb;RS(E&SPve$gPonF@&Q~c2_%wsieW9!h#+Px8*j^ynX|2(9BL}JYu>HXO) ztHakkPd}FYcvVW+#cHc{rw-x_N5mdC2fe+%`u#>T{mgJVGmDlrtKaG0Ew?`sRzP}{ zAT>Cw*aYSlp-G5~=L|?bL(z+6E}nV0p@`}(gqwB=uOZBt7u z8u3uipwxzWykXG}z{d<4!e>x|^A0m8J#J&>uR`aIPAj4oT|Cn>Qq!M5qr-?8wsJtH z-cPELhTV(PEQ6RvQ^GeK!JVJmC%q6neMEozb6b9VtB;Q(Fu61(-L-i%%6LUE)IeSx zeT7sc(x`8;m@_phY~--QAp>%D5MW6#NbP)f>*=uxvIK^-d--5GRBysSQa(`_+OXP$iI0mq?X z9K^Zwacy^n>QcnT5kH2V*VSTAoxe-_RH$hwgJ!EO9J(*kj6x4WmTeyz?C7-{swlp` zj?Zc27b|S-*$UXlsU6d0**c)JeGxn3anbN{a~Q&02#4U%$IRwj-OY7h+Y(#+J+H0C zoWhv7g)8RLOEBOrrzIv=eqwK;@^uv^(S~ul=&XLL7p6tK_Rf-p$uE|_>zT?XP-3}ETComcEG}r=yiP2Z+J1)Htz^iTB5d# zt67V0>53P~W(b!xw8yqTx1;scv6IA~LE_)6ZQUgrv$+Fb3~t}^wrNXUEzZ}}v{2=s zA6@bgWkn-?wT6eV&_#=9E7R_|9?+dGPxF)E3h6VlX}~b~mKI%f-1^~)SD62)pWKm%^YM<6#P!*vU zZfoHS_Tt@5{`D95%p8A|07Y`;_SK!HCz?at@_G>;t(+B7>6rxRB@XJg4-ugaNKW=k z2ip332D8B0fCac%H;$lKaCIX`U;iXMJa0*~^O4D*T!vR=D0cP9)hD@+523yVdb6in;VH3@7=1W=%DCMN(FX$wmNla|z5ORsX&Nq-k&P}njVqU~sR%ZLO z+>pdR>7`A;oezjsNoGaZQpVb!b4zxv?OYp^2cS9B7|QX@w(W~0*3|!VnTE3&vBlh- zx!hIkXRQIn)T?_8#X8%)+Gy+qzs_Be9?-=@?K;;>5V3j;eXQe|-I+`5g>;$3`Smi? z#!}SUxihAH&NXp@{mM;Wwb2y&Ruq~zBh4-QK6Wi6qimz}x%HgC%wARUuy4d`<`YWP zc7x$ICs;BLKlAw4*R3iPJ4M0$EnTST|Du5E6;1-XqpQq5$o1oZgQ5%KmcqZ4nW-K= z`L0ONeC$dv!FZA%%ab?+Iu~$UGo~9rhtQ|9Q>v_n8+ePilVes~EE2mgwBhGS7Tqy5 zQVxacI5!#`Ey@9?yl!p1i@6B*L|E%`y%crNP8B=6tN$j2+QgeFXs(E+dZoas5rmzY z8_RTZP7DPSWe`y`L*fOa!)hqcm>Zh=JpA4AT zaASEQ8g3#Oik-k>ws4#lFZ(cu64=(axz9Y_nS;Z?WOnvVgn>oo31F0?8FnyKu6`_% zh?jgOMAYOxKJke-Y6W%V0ZL(RQVlJJa>ES6BAx_KVghBzKDCxBuuP#ys`zIopa)Oj z>c5qD2^&B3UdKaBzTCkKB$+rfxfGb)hdK+d?f$>)5M1iVn2YGaY zwcJd#uJsY?`wodv(bwzaF)aDO4ctp(fR7PB$HS@RaUVSRjov*Gm$qc%r=h*nN_5pj zPsPKDaBp)l?hBS}1bOYCBvoI%Dtl)C8r^VYs2$C>o?;trd&LlTke|S^i7ldDdZeu( zSk86m>0ZUI57}-lf2R};cK6-MV|hcay)nOGwEJ8m#M!3q`=Ui|BssIvgR8ZTWAmyjaYADSlpA@&9gM=6O$u6Bc1cJyo628Lv+VIl;Mt_DsL-1t!5Q4A2jlG4 zhVL4Z?Q_^3X!LX`Z>IIr1L{P@_`Ma2SNd)7^W3uXp9=fg>0u6dp%$eWhonk*H2C-N zTbh;(g&PG6rq84KwfX&hI|i6%Es5A+M?tExw0q6MkX}RX^dY2oHRrK zwzboCUxS9Mn@HHD?E|)fUA9lD=g;&F8Le8uZ9LlwUS#!0BugDFB4B82TBr34oi!4&Mo_nRY{s3+-j zCSNMm1xHhXGUCW^%|cHQG*%?uD7E-CRQvRNnl2i{0cGD0OrS3~`x-3=s$vIpfL&i{ z0Jz!j-IJvd`|?L1V)r;f$#WNKU;W;CRL>~t@kP)iaFQfi{MvFm%hEd6kVkYANeT~S z{X<2Pm9^aTK@0`^)*6&maRf$*ecB}==$dU?utDju!DBO~192iRDHHa6;1(t*$Nf$D zS$Vm)7w!$f_H%dzWZBjAHlX{VQC!qosi4n?(4RCIyHV>7eMDv)BcFGB`CXz?wwd(JE9Ic&n;Q3n0AqE96b)oVZPwN_9pW0y3#j~e&UwKINw z+(qATq3?9A!XneBfy?0nK8thw4ha^Be};Q+6&dA}C%5q;mt*9IY_yzw%eooRCuPY= zjQ8yMWaGgIn*YLGj6(!V3hOO|uT;sFcfdQx=uPoTgp6(J+#Nc9Iw6EU3e3&9`(7w#YbfNX2{p;f5xBI!x-tqhe zK0`b^$EnF17XI1drIXTm$-N`YBHw{|E1-=T5G|D4iqD^lPJctGg%MA+&t$PG*N$rX zY0+SnA{o`snE~@(_B?}ViLS%nMs#QTHR4(X$xH+)6;=hc26D>w8_`HaFHk`-sB zs%UYyTziz?vcGJ|gQ1u%539q+AISRLnc)rtOw?M!srRoYhu<16@~duoF=fWhF=3}9 zUiy8`b;hS$t|=?pi|MYF$y#VK^77|fyptv^TBI%bjEKs=6}~R|og+>7#6@%N&pd=y z&t2LwaA`ftZ_aZ3(7zayEN-PiFMjJ?e@|acwEg@?mAf!_$kct@$OxY8V~t)5MUOU? zaL8zo32>%lwMYO4W@&#?b$_a;mG#yNFNk7-Jm4;<=`ve7U+lDk|LIhf|d9C z(uowuW5dj|mM@Gy9*&t*&;wh+tJk8{8{lhD%CK!U9kE8PHF3wBYG;=UECx9-NluBE ztToW0MXEwWJ zxnEkld)gxuiA~1z+hH;BGA?2=xV!*B+=10 zJ?l0eyUado@>+=2yW9Hh&$;c7Y8kxl@|YsA4BV-K%k&~54|e7ykz3=%WAmjx0`h1i zhrB&ui_I1r1cZA#<%<{Y1t<>yof!%~jvD=ac#-E#v;%WDSr?V3#y~GZ}P&#Y{l#cxsO5eb}&ocAy zr*L+Ah|Uby%aG124W&0f+YFuwE9!N zG5~=*$2LkWS;6OH)XFE19Zg&~n^@#{a7T>bx~z*hsJLK)Qc1k`Z?{FjM!;sx;Z8Ra z(Q4PdZr5{YWvzWEKGi>fK-NnJ?Y&>vda6j2IvXa#l&8iIn?tf)y8+hQ;|}Uyg-aWX z6`k*b2x{EQ*NYuJOGP%C`nroWY;G7Os*yNj`N_+R{-+^D*4vxCrimWGjQ8bOpSU+2 z^(snUzXi3gac|=`HyQLyR1jf*+4nh=yA)>fi-)!KjMqFXObUEdOgFA9jnd-z}k@K^0?xP8~Y-QDo z$*jrp^*gFPTdO5AbV)5yb#6;>Vh@oQca@^9mRvugbfqn+HTELwZWQ%7x!YLU-5L(> z!M>9^2TaCS#)pA12r{(AG25WWFOxb`@g;3hO953Lr#&Rgju!R5xWZ<{{{iM>tiV7e zYKrXlhRe2Z-(ISRnVUFR^4i}QP7Z4(Lj6tDtRO=Fr2})S;SJb%htg zE8Azr;GDZRC@9qek^g?Wr_dsMD#9zg(hA|y8J!k_3)l!aBw^FXb%6_68K*ZOUo;+= z67$o~ENeNaI+f?~e)iu!Otfv{&@pL02ayqhILGzA-$1+t1Z4UUK2uI!FsNbzJ4<~k zx`?5+YFWDbVBrQ*f5Lcl0#~H5D?ka^9jThxelYC~?mekjwLr2_%1igNJ<@J*Uv;SC zRwLkHrvt{d|F?%-#V#&WzoR|(+dZd^8q;E=Gwy56{O*S6GI~DtbN$^1Lh`>Yt?gWQ z7xrj7Ir;2oB5v11TA>cyTkv<5Ug!Va8>#A2Rd5#!hO`4u*uAliVuCRdZc%na~g@K((mA8*6ERQ3KOhtminldYUp{r)N4!P zsvhn0%s9M03rR{Ps(@fxmfG_*gLh=-dObPJWYapmBJUT-(1^Yw{ZBQhkHw1WqrJqo zZP`<`gE_MfFd-}3fp8yhF&|vS+;jRlZR#KBMBu0i`^Js)SZd*D2%YPG?)T>-l_1Jc zT9uKJpqZ|jcqVdd0^zC~bfVq{``rCSjH8 zKnqQfU#Ayg*Xe-f)>|4G)Ai}-Q~Ep8p`$YF#h$g{21Bl^(bMFobjLF@9fIVa^TPgt zYmwLXGdQhv`SeaqaDUN=n`9K>lzhMWCcrI%pYwoH8cF_UK-IQjOPbPJvZWUtvess% zO@Ix)T3;@QRe3pk1aMn345aNTQ+(MRDo`Jt=KW}0I`d5FOfN(%_Mz{%*rMyEpSV5;>w0YGWeVg4=HXDI`nUW|m>QyMxXqWL3S91%qO1x9 zF?mSRM986OB&n-XA3=%nPsZs+?c_Rb%~3j`O1tRG64C&A{eZ!*(PBx-B`%n34yDbj z66s~%bMKlqzDcpQ1%is8lWS~2KtMfSJ)&e`M40$)?rqhOnb}`JRvj~D-tmDUD@Yy& zc;z%TlT-k`xh6%fbiIor3>k$CQA9}?<-`Q@7FmfX4ybc!jdjPx<%tYiK#?=o@_g{F zy=_qExU}d7Uhjby8Qe-h15@_B8MR&HW2#IN=h-!Ofk_CTA~OCq@`yZNP$rV}hi849 z@utq1I#F967D{qmid2Q;rI%Hg-RZId4+PN@#L}{ASw7S^k^CDsJc6WS9;8~SfrtiuQ4 zuwWbhNPo?I-KK-u^fxO+QuHD9*$~pGb3RMBjK_rV8opg1mK+az$HqM_&Td_G0KyzIXD{ ze2!kDFSWFssk@bevPz#t0(!aL4baPzp9&4kp{*v9*1-2VeKDxIQG+7owYtg2Eq%md zWr`J7#4Ep%erEAe9FYnX>IgrPi#``CSthEykY(#F!BcE@$j;=bR-j5_(qGvT&t4QL@S#aoMpvdy8QAK);7OUVrQVCV>`GOX&H zzxZBaGe7xfH>)$1aGCmwARAe~k-et-A!dvm=aB6E;R+pJ{87AU!RZLseVvCMKW z$B)R=)4)+@;DIpQV@LcQ)iji~w{8`pXpEAaP7V9`pdIVvi~Z$%{RWT#l^uL`EG~|> zsngTNvozCcV)#>r8R>NjdY)JnaA1(gZ@=@fxsPtbgsW1&+JyXo;QjTClGMpe35EiHaVM0fbGWgJ`us zFJ`{Fy`<-|@6Q=Z|Ddr-)Y9NASWv+9ecyWv?{g^Y(tIZsOGTB34$QxY-cMfz7UIL4 zt06J(x?k&SJJOouHOYYP1uU^PVA@WG>$aS>+tZ?%Zy~IYO+6zp=~>p zi=J-xqZJr3wc~P8<5QR9{~e))jF)t6-2IoE-Fdm?UKW^!@%M*Sn#T ztJl_i*%WPS|IAiiK{hOC0iPj;F2)Uo7pR68BdZJhYPuJ6I=A>|5vT943lpl(QZ!*q z3hD+gMiDM!JyX9}LEgFT!EO{b3eHv_Jp#(7+-PxY2~9hPnO93%yL>B3)CT_GwO>I^ zvT+`k(#!!VsgZIkDLFaOqHsuyTx`X1Dfsnm?6y{=_g)V%aKf-$I$#Xnf*PBJnRUPu z(7zkU)SwD(5~`IbMR$T=1M|^Z-OujNbgMina6$N!fpv#|gtXBYpx{3%vwZJQ(02 zD9Nk&W}{w5Y@9|Ep?VMHrLDlxL6|qtbW7vRYRSy#avv2v<$%BAx1GfVZ>ogH%KUQe zouZP2rXTzGZ&#U2NMq3Mp6w^4D^sb$f_AM3Uru$&a&a}~L@STnuH!PGEpo$OM438e zt?FdwKVU5WHwHMi{@TU znEw6tukK)_STA*s_Zya_1=v&x#*P2>g540QEvdm9SQsm#oBm(#iyZi4?-}<~9JQUk zj#dL})4a>B7Yi9B8uxp4w}WTE6yg03Ga7Ko)l7X`#G~ z8=dOg_MK^2ais#+YU1wqDR1Cuw8!7Uc7}>Z|+Z}meS`*F*#t~9el*IPFcPQOc%+C*e&sn;#6#18uPXCA_;t|+D6yYts< z(JFR3=I~6*kjNK+2Ugn$a{9e5ywXZhGVDOS1HU}GCa?EG=j#YfLpyXh!bjmHXFkmf5P^23T(V@V|E0B28NgE?qe7404|BB8I)qh0VAD} zx+()DxnjL#>-peG!LJ;sS$rJ#k4-6OPGZ4{m`)nd6GtP7t9=cnE|OXu@vQ=3ea4g4 z@4f2Ka#~r1SE?W+34E24l0Gwo6b2)oQ&>Q{yBsB$iMi&3$LI>OG-m(Y`b+Hcz}eq0 z9)%Ni&+Aqta4KUdK-My&BxP$E^-+lO_fwjcVg6#?6FNKev6Fvrf7z7s z;Y~b#J=%w`n3XSY0`f%RK8!jmXDN}okZ*-fvU#MJ@U41iw3;3_h#Y5IQl9}SfI z5|32^7WaubLn4t@yz8ADc3gG$)0B+ws5anw;jnPLAJ-5d;)K7{`8uHn{O|ry#3|ko z2LvGV?$+^q>>xYN7py#ygYYb^71}=m!^do3vL^U(Y20B67%9!n2n4rYf~fROV9L~_ zMuRp3U#~i;$$Oc>WGaol(kw$sHZ2t`9nO1JezO1Q%rTb6Ni7kc)AI{Irz-qoRK*=E z&kwg{Z3C>~C)I5RfQ}y3jw1BUe1rMuioz<$yo;?2<@Nmth~mlz-&W$QTiyb{@ysaA zetz+nCD_7CI1x5cDcD=Wn$901o();AggVu>Ecll?ng_ER3XDxzsTXBAL~I>rfM z#0qAf7p`i2lnNKro^YxE)uF7gmrkI7az3%+#qgU32N?&ZD1mi*kt9J5=gd*d;S5!2 zq9tPQ-Mh7^^EJ$38m_%X3{&4<|37apIfxLMHs98lzfZKNATMIYtJ~uzOfPE`xBuKO4RtFNQjVSG$tMq{8RENFuC|VW?CFPv~?i0&5p`sjXn|VhkW(a<~J_ zME%f7lFQBoKy$dt&`jpq|J?s{hQAu?{sL6Id|ki--EsieqEpe%FRohlCM0Dl8s0oLvQ`}KNttp+3H8KDeZAvdu(zPrrh^k1kJlGdm^z`I6oK+bd` z76N4gUKL^JCMtLHt$`SqiBZ%=ZVN2tY|W11g}l52V4?lXQ^uabz2aBMP*$-o*)s=) z!oC(ZSkV?T=&SCApz5tR5zx#+aB{0wXzd0UgZNog_Rj2L9Ul6m%q5!X z3e$SV``0SK|HqM9&p1jz4?%L2A)Nv-80>>@ZqUo?t6Q9zQqR9Q;IqHuycG)eIshjp#?|fhe{tIImwcHv!t*#c)>#ci088;pMrSJXhdTggfYC7q3;+WP zqBkKz_|~pSVzUgeaCKzH4H)`fu#a1>2809QWdEqzNYIr}cS&7;`gACu9jgjL*wB#-(*%&b9F3VpuZI@n@t zCXD!XrLnVtvC68QtjgklV3k|N5zuD5ZE>HI5iM!TEQKS(E<6KJn1u=yNrw_E1f`LO zsFz91tOm&ZqJ)#!4%+vsODW6A4bXrco}|NOv+jQyyhbExG1l2P9D@IT4G1qrQS9?h zRaVdf$L1(PA$uYF58u|Q*qLLu4lU=88DHErUv4~B?S>uytr**E)6bAb_6NYQ4Dn=? zBNZ(r9@6S9a~rXv0W0U{LcG9nK0iX!ljJj44K6vyy9IX$4$P8%3g$}GZgqg~@Qa~>lKNY{p93i~-;WQob5VmnUe#`TrIV&g`1W9o~*YTP=w@=3qG7{b-{I;WoT6eBM z^^5KKA3QzmZ8qHjEi!+NY3o491^@KKF`DJ-dc#cOp9Ka@R7-=U^?D~+IHl6()j3MU z!839)n{20(Xgrwdkuc)$%2QMNdn)tygZ~7ce0RUK2*g`<;OxAxqx~=q`F(ZM8AXvF zEt6dr&HYK_eCq5Y&YRz2Mf*Cp^T)VN#7DU-1ENM{D?gZsh(8 zXovELfGr>-fETiX2vBd~g{78&DT)-g#_4QcD?E?i%+8dtl}_`_f7#~*Su+{*)O{kF z;46uaLXwIVUG8q29Ip!iamofTfS~7|a@t~^ey2vGk*I7lN06h<_e`4)rnX(8)vmOm8-CM^ zBkOQEA`&=RrK6SF4$L=N3 zR5CM3KN(vyv2DKzu>TS3#mjQQfk2rPdguc*{8Yab1;^J+Y^`q3+@d1DE@# ziLaDwYSD`3tPi%qQ)E`?UH|#&uIA9f>CsT$hw_1c&?StAkfelupq^(?55_PkZJx|0 z51;u=HlLWSQ9C+SE_rEbrEPl%7wE4{NG!Dc0J>L5r$@m-aS>j8i8rzkfedsPEh^=$O#Zj-DKVjFTf(`m_fl!R0r_AYBvO{ zPL+lc7gw6VVi0%!E5;ZYwxe0ygq`yQ=&SSNo3H_Nln-iWNs5U9lo(mv(1liaa3k7Y z++XX#&mZHHxjggx%tG3K9bPU#%2In?r1CEA%yS<61FmRe&_WxsA}Xt=J4fFszM>UJ z0FhA3TPoRP=Jc+4lFlU>ZKVNONd2#eP*Ug5u}c9zv8$jhijb{vlQ1(@dng~|%9M1y z>%THmstzDz8{eSk))(`6-T0U6UUO)V^n6XaYg5jpoxdCdxGURA0nG1SW2ysaIT4~6 z1u!dzpm_n#Vhx~pyeg(_zFxUf(D%?`xb)M(YQ;@qjs+?n5+%Y|mOvN8Hx>>sl)1G7 zlz{zcPQ#!WSI{m;dy!~AjWbtdZgKBY@%E6?lB>6pA-xBRQ6ACk8VL#kA$asEtRRUZ z9QPz)zIwQu%!nL!t@8P875@eLrfRI9i;QLX){yOiJOx(Pg*{*>>!y%sf4L~ZWX_lk zdOJ6wdnqv*3WfMyiYg1cf`z=K{FhbP0Q$paP3I!f`Q>jh)X^ve+Vg8OBA5Irn4Pm8Vl2cBsL%_M|Am*-0rg1Uv|Fq9iiZIp zTL2pmiZt4Ox^3_L2u1`KMc@eZEW#f5tig!jj~@qMr!5$OxiIof;)7~()5Ncjh5qxg zj`&DE{KVmcb4KbyAR`6D>Z*&Hyw8gmoWtj+5@#ViBo|Du0(yhq{@`yVMTfAQD_D)a z32?{2e~VfqoWl`CyDLs(jG*JiaELvku$W{A^FH8?^t;>1kgkE#hD}=8Ctc#oe|c9x zxzqqV2jolU1yPJ_1qj!hs9yY@{HQX3;$}7Pt5=@Z2cv#Knd}C=lW{B!I9!Kl0{;4r zqnsfu*!C+EgS#VS1LpX(di%oH3h)^q4iaO!S8#UvQa3qSm!SsJfRrv~mNf`rZzzat z|9u}?VKwA@qBKadcqtsNZ zk)BrngR5K1rMDBviVvYoIyX80g@ln;`OW#cemGOD-0{PqfmT!h$JmvC#kjVAM1_(q zQmJrkg@&|gm!(69W=fLkP|;4>mocY}EMpS0doy(bd=XvkvUViuQ{@nmbX?+EOkhmgzi@!B5J#mDt1H+UQv>Z4ElwSaX zyt!u!Ggn&_;Fn3?l$*C$_2fdj=l5{0z zt0RC&Pq?yPuTs(D^UsGShR#eWV8EXUz-5p%EY-bQr0rDnvdsCUYh;-=D!+&6oin(D z0l!}coLmsqy*oL5gp5nMvN=G;$#hWXUPlT1#k`q~_QBDx6OaEVbUcp^+$UY&Mkl?! zMV}mq?!vShoj?ZXO;XAG{qqG>IOT5QAFqz^nAt*~eH9(ub1RPIpw~c-gzC33Cw+t7 zk-aMMSWpsEt&*oua0C-epN?xlc!AoRPH+1w?~f@$pRaQ;MfZ3M^` zb$z5q;FXRd6b&)eH^Z^HJ%Qtv#Jfd!DPh)+BzsLp#dJ)l?EkHe<^M(vgBE`NWDeJF zh4RC#Fum)X$gLFHeLz+@5$4Z^*`SS;f}T9x0zf4(f0~3Bc;nTfEMj;`hZX$vpFav#M`qx1HdM4V2g;v4hHw4RLCXr!1^$9D6v>fmA%V$6l{O1CUTY<>0ko7)1-3!g|C0Q?n^_{|%HKDDkeQ zzqonX!FUaZ)O2h3bS(Cd9Ikt+dEUp9$Op9|Vr>9#EN0B&u5m@3RN`Y4tr)H<&MN>Z ze(-X;|37#%NmdLF0Y`xD9dt}lcXkjcbSzQ(I?@&&xZ<#4Z2`Dh;0!9Ii`l-l+KvB z863yT2oL^4g2$mfo!_#TiS0T}+`xn9T3Vwd!S`aF9$P>eO0s*N7pGgFIi5IJ0-tH0 zPMrOSL&3`yIYZGl^DlPzECi3J@Z!}YdBWrXj0ccbb0e-ndAztPazlVA)A~Zk#Ieg4 zXxCE-9DN3WtBk@|snYBvd5QiWu%2Qb$7b(Ph-ViEU=K35$V=TN!6cmbn2D2!xuGtk z;Qy3#UUQ3ddsW~3dw^KTJeQFu@L={Sy(L?;07VU~S=k7HE5E&`+LRx#(k;;Rf=Qj3 z_i}`JltEJhC>h?*S+3xO?JJ;TJk20+`S%-p;I99ch|PI#6!>r0v))Z}kqZV-S3`RV zfJo;`X0T~l&!}}_1>&mgt>D&@VR`|aC)SvRfBY@^2aAA%6*!}D4Ccpdp%o|(jMW%T z59;2OU0_m+0w5H-a;Vz&yn9M%W>=*kL1+&-nD(2659|IjRF<~F0Y4-Dj6SyUN}4Z> zviem&gn=g@GX@U|*!dXB-%MUGkb1r+@I4Fz(c;Hc^elS^J^WvRbHx{CI_9*1yw9`f zBIG2nH5BF~nx3OMi3LyM;W9@R8NxR=mNW{2$JDkw+%Ixx>FJI)K5TV_T* zdo^1MlAL*yeGQ$#<36!IOJNI`A=7vZDSMkiwx>Oq5KHSZLpfszOprPCSyyNIkgFg>?(* zCi|zJ6h_VL@vj>a&R;~h`~42idnIMV`LPk;=Ok@?Iit`l0iwFl0LZ=HR2zsVxY@OST=a((;xBW~)4 zfjf_!TP^$CqU0Lx3)Eq)hMZPY4x&xBYeRBUz!MYBV@5W+*xxB5 z-L#H7iwNve?5DDZyasZp(*s#-r|jzT8ivfWHaqkWXs?hSgkU-MZw@cB0d}bY8H8!-}1{{g&ra_vCpW1n?VOBq$1!*TLUu8}a& zY&1um`aJJy+KpgD+i5cbux1RAeo*^M!F$Ho5=Ks1_yG9WaSg^D(Ie9?l^0SHVwgE8 zmFE`Ia15;`$&3zt`=seHhEH|v(%z9Z*_pcPI>OGp_K$j zdzG|K(DE1*1oE3AVO<=zTynEVcKxJWtE+*Q!<8|&?t_We)?CpF;^u&fN3BWc zKZ^tP|H%6=t%mIa6#h+bT8y?G-To?Sp?iL(`swmql4s3$x_J@1xckHk-plsuFcYf> zG&fO{Bg2^g+?Y@8D8a7uzC0mqX1pC(b66(}@FYn7r66ZtiVdO6I>s|U=f@vY?#r3q zfTXzzjdS!HO{s~UJmGd9M(ht!Qp$v_RF1&>^OC50T2mD%+~$tlFUi!2!Fp^0hWKW9 ze3x=%w=w3ua!>=@vs`AGN2t0ra?^-v1PcOcq3U0*YB}te^&D^uEvHOcZ)x_C&LU~D z9c;|>6eg0CmzVcA`$M959q%@3N0m^u1B^{4+?CZ>5W4Efs!OXcbyzU5=ia@cV<^qe zCiX7@8`#;kzxc4-k+Ou<6DVrjAg#lyjS-l5a{{Vd0h^e!klFVaC{uBXOkEX5hRRIU zhukmn!5*~sW|Ai*kE;1CxGPLW>VA%6Jjt&4Q(d<^7CyA|GL+6L7v>1&P3u3^uHXy8 zGO^k$J}goF!IXjU`5P`C^^_)6nuOIoiqR8VQ3{-{?qe$wc-sTxzbO-LFvJut*6pZJ{fl`C%~?JAAfI|AJl@2h`>5PfVY?y!exb=DUyP>0a+Q+q z3$puuRm2Zv-zsz7$D=eQ9>b*UOt>P7PGorMM|gf9Kf1;%^RQxJM3BZ{HxRIgnMw)Rv!hj&dtb1=$|v3*Zi9Gcc32ZvG}x9nr{QhrgOc z2yNXW!vn`U=%a58(8;?4-FHiXX6$bgaxIZy% zX%{1VV=I-^7P(c0C5=~oC@yTfBw;X~g9h6whVP)B6sgm05u)^Yecq?-l%1leH<3N%|NND|3DF?`bn1W-bwbT;!h4}3n=&UA}hZ}_Ry|NpFzX6JwK_gjy_hfn= z@jWU>mSH&3_S|aSQ@Wrh>iH7U5xwvU} zxinvwOdan@%f0w?EJu33XnCq_zM9~s%?htn_j_rLJ)y4fJmKDOJ*_(IV{cnH)p4|; z)?&8-)&#$XiIA#bp%zextOEGMy9*b zlG>vM;yG@&@(td44mGJ(xsl%|ZBzhh#qVrvmkbOxOC9h0BD6sK#HEVMP7OxX&)0@A zhuWHhX8{00iPHeB@0oB)+K_W4W9i&?jqYnuM*6=xB6X2@_UdTJ|$-hf#llulkEU(r>4xAbMGg zmo+G+&D*Tc0uyVK|)KiwFFc6Fe(D$<%ZQlffAVSj?HQk z>eLA$h&^C?p5D2pPqhNK8I5I`Z@|&tF^ev_Rr{L8x`1<8Z`wWN6a?W9xsFRokUH#)yXi#Nb6?Lc9jlphaz{$qYye2v_!1;K?PMcX+wBC zXTH8*h+qi0GK4&7Ex}H>d(!QA-Dpyq#X)$BO8{X3-8wU*Tc<^%|I>T$0lMT6JD-k8 zFW!`73d1TsXqNp3viPy{z9imoY)YGc)9ev1{b7^JUn=k9jhUS9s!+~Ow<3i4XW^b* zqvqcoTO8lZ`val{BcrmWDEsMpZZ+xoR&OWVm9&;UOxrnBLwf>ekb?Gl-B;G0aHh}* znGNs-XfN=b!4_O8>!tHk4gMVsccqoQ2{QOlz)U`n$SnyHe$)X-)L@^^t`S*-@1uzJ z^uQgqB|alA*wcgEPnkM7Z}Az6NyHIAWa~*dV3Enp6SMU`s>Pe<-x=t!IChuEx;Ml} zu3?dYzpHX*H{k?TdY>$(ER{lCN#0kI@g>R><5$;_9~I$2a}Q?xz$s$p(vQh{A!^{S zcbJU&4^I}-DV|GGTY5m|#?>M$$j2n?SnRk_l?wV{|7_q2`~Z6s@&^|D;D0*tBF?(r zQ?nQ;RSI6hn99RyMv6-Q|8F-RG_G1KB{68qtnMo9Ey+WT6t;UmH5xXm|@K)cpxSvB!&meial}B!B3{#UK!QfaDn%6An z4KoC22e6lT8qXOhX(zi(e8>PI{RuyN&_54ipzJTLykId>REvW$Z zRe^oJRI-IG`5Sam5J1Kl;oi-~e-7=7LnE@XFi%{i=KtPOw>`0olBPx z-pqCRJd@RsyIJAC>$fzu6Nt6~xddX4a*nd2v4Bke^EJAE)ryH9SS367*)ti_QF@e( z3d(XIHUWneQdHEbKKTeJ1?U=KbemcGy$K;jaFmUXGq=T)-Y5C-PYpgbFCJWzu=4$f zO1x81P#3BZ#Ysi@u?Sv;>xd~UYm;BOubkjTnytxjBJ?eBB&vO z#zw^YWjmmeT9pRS9jK8Y)tZ?=zLFc6)?0Zx7R|>aahA#@Wzp`Ruz=tsQ|Yquw!j)D zy}e!+YTsPh_wtl@iHRTE`mFBgD&OSLf{FL_lE+^A0-h&5_{wp|!~$OyoqiZs4aAE3 zHdtk;V2pSf;lmPG>MuNALmP5LAZPsC#Fo?n;xmG#V+G=`jNZPwEA~8p5!YvD0Z2U0 zCcwG8dB5RQXSrET`RWMh{>TSmRo}O{@N!!pv>rP7%k&ZZcY%dCp!-JCf9x6I=dorY zo|5vV2V6BOH&>s8G22bsHieaK_^{{!=o4KUzzd2Ukz82i;E1U1!3D*@=pUPX2 zxkIMy0<6B0YPy>+-QY<);J+{l^jY#j!qKuQ2$(1xz(nz81~PIIOmc)5wZodUqM$gu zXI(Un3i!(_f1V2;llpluJ-r?&a{=keTP1}#>vAuuYQ#a~ki-`f^ME_TEQp8Czqok( zowkh8*0V4^N|FWfuxBFdsu?{y8$by0CYW@sR<$yPH_Wa`5)&x{i~<{tv+J(|R(g@@ zUTD#YnuMj!54_*N!WgLS@*pyJaIN~(1bbDv-~IUZ@nOG3F0v4eN;7s7o_Ob*bT}m!?~G+u;}IF4k_IIT=D%{Z2A-H5!P}Kq6(Mc{Kn_#-a&*(q zmVZTt+)0Itjb`hmTbNk7v*ae*n}XsE?e7XvU2GSp7MKdKpAk*M%QV8c|ClW_JTCOq z9ps5H^H%Qc^)6X<^b1E7fRT;X79s=-pN=y$Y$^k_>a3ML|NZCaxg0!9*mSQC+c#0< zM9-oi;WzBo#<7&Oe>YB@P6t@vq{ zi17$#i?mXNnz1o2qMgQIcJ^CmmfR($Cepm+3EVL&FRjx5CzzX=yH$oAAF4^_8z@}w zmsXd-ww5A4b+IwzR7T=-!(R4Owjb)#p;`L2l6f0T5%>cOPn}e9>y-Z23S6wHfw<4RTj|W)>UNmo zM0Mn1+r_qAaJAoa2HoAzTk|AS%%6P`p|ACInRB81mYUJ$Juct2W~qXnSc31dn=f9UaR{&hii?oPxYAXIYd@AGg&(d z)zmyyvF|f;c`nk&rF0z`jLm_1Xz~UyJsEJ^_j=>O(Q14Ii$4VNT zNZy@&e@ypyfw;8+=y4ctIWeUU$IP~W!{}W(r%R*#M29pzE6fFw$hp*OrzQMMS$(0v z3JVeBzcCd2940)ViSB|ZdG^Z(ic=&@CQ`tJXcn}XSu*XRxyl`Cr_EeN}K61_0uwsjpi>t#j4`{ zf3OP?WEaxRNOv5a)Ada-(3dZ_G;5?cA9%($m2Tc74Kp9v{wllqd)p<1!8pl^V3-(BL)A2;eRn&%2AZ zY=tGQByvTTqdFIFAS-~l;uD-jqrbs?l226={;tNLoyY13~#R1?;a^D?kUN_CmU9XbYd&98$-P$;AVf5UQD zo$v2pq}}SS5!G~hGP;UQ<7{shZp3uhwA&$AP)^;QI<}$8{lm}a$z6C^s~~8G`%<9U z3*=1S<_v-;qCQTyo#uK|K8#6Y%|WEeWpfdpN1w7a>+A_!HLwc|6w9?|c8&mQ3Ek0G zy9qs+9p8-IfNMa!7xiE$`0Cx3lAaZb6#;87>57CT)hga=sXPb$W{eJCHOEYN@!jyf zTY8>=0H!sdCLl3hGF!-b4MxCCi`yVUPj+>gh}43ORY|`0`y4v&%xs?wD9vsI>Di!V zpu5_z^~sc~nBqE~2DI$@`e4&Yh}nhYR}CTYdLNEz%Sa5dZ!!Tz1MAlJ>spG020Ta} zbakux8zUYg9smgi{gQe>^;|3DevIocbeTLe+FbL+kP60{rEB(@uV#X>qpC++mYP?^ z25Y4*^jkk%!4u)WmP1=)&Al-G^yFp|7r*1s_ea?HOOm)2C}`fRc>+>Tww?O<4OoQWDD>hxyw$se>U(z{i=wJ zY3kS9y|!b$Q7njX2a+#?M67T4)GizdOH%<1LkV0;2LQtpWcl=#)(jx6;2!;as%PoN z_0p1QnL-)wja0l2`9M$aq@e)2_DL6{L{ww_-ASa%-j}q;IQ-nVi7p7NRYDcXW4)bC z)SV__eh}h2$}Dow@{Py9eDNM3h$3OL=D^0lZy!7LI(f(-i&zIV^Z6}kaB%9Va4*WH zXMHQUA=#|w$QrqsuTLU}?48*^DPhUP;WTPYEq{8EO2YdZ5F>+xww^NU|2JvsgLrr4a}zO zxOh+G;vWhD%mo*n#KsoJ(U{Kk{6i}R-t>yOe21*KnZh+hK zYU7C2-K{huN<=FRM$l>WoaM3Tk0u%q(sKF}% zP<8&Yh>){?5rHk>0jVY0s=~2Rq-q!Pbw@^=hMl_426t?yavCNm+6EV>ts;?=z>5n| zI*Mp(V7%bE8E;e1MG1=;RgV9~v!MluBWVZ#AjAE#V)_F+S54-^{gRO2eB#|Mmrc6(SbjsZ?0{UOi zHlken`QVOH@tA1XzO$#EIb=|$8JI=h8cmM5(CDkX9gpEeRu@(xzN)h$<0*5o9-fDy z7hD83D3&mN5e2R}(JJZz3t4s`$(x-JGr0zXR{=l*m>@_qlx3ATmaxM3(2eZ-)<=)# z;`6nU7GIUwFhk5w(tGx_XE-cyf28ei{ zTW=tC5gp3>@dKHQ3h&xq=2GG~*15Y{fAKLF4{#B9aeQFLSPf!M2+dy3xAGJ@ImO^( z!Gg<`cwrlnfU;hlUoz^?dB@?QB?6w%>DPn$V9X0+C^(bIljLN}5VaegFUb{1>|o!iB30Cm)swZC z!)VJ${=2B2G!^|;_E)V1zux89yeYTly}i$a>ejq3CSF_j09GFrBo(thh7A#H(q5#7 z@gDw@+FadI=EOls2mvp7$Yn)`l05N3IP)ABe5tnB0wdFbhmH(=cXP&Q7B$;Ta&cO#p^o{5yNuhp8!Z<6o)zK1MR zt9{0*7Jbh0!4AHtP{U{IPW0k;;X~A3ob$NZxbU<`t75dl>6Ow;zAjbX=ewkkEvv4+ z;#{Zgwvsh`54lni#CRyf|mX@3?B@*E& zIY#E!kIgI)y;q$bc}iMnoK4kErCOfA_hKhtPjX4*p-zPo93{G5&=G)Qx#xiFH)~;( zhoR-Foc=f%d=cvr|7FK2PvHJ;W!On1%;YK8nioR+V#CGlyKE}AX_4q6QP_7p$WGYu zFt0w#VfvHDhQ`#aQH%4G7myU*ow^AU#*2%C%A9|o7Fym@%22H`1u@6SjPnG*Y)g8D ze8r&^^hW>7SEMZ4qL|G}qWc9^wkmB=&dc7*wzm4`w%qLALlPtGWD#7^DZUyfF!#YhJWVtK-cc zKx}|G`R^gvP0#y;G<{-?Zd2Q(zLDA|=Pwj`DMqhE9ztz=uU0VGmOl}OOiXR8apuwp zidH9I06+j{#9Cs91XBUq6BS8>`yPySH-L@fp+PHBqFLR^t0c{5nl{ z=zpj=-?;_x6xH;BCajAloeJ4{*a7@lZ@;d-8Y?zM+|zH<9Sx)bfspxnGb|CxV4M7Y zRD3<`qK1u0duFQpk+eYaR8PI*Xi{%rPyN}#l|1CelBl`_fL>Q zC`+g82ndPE-1a{M(s?5F=}in@wdS|4s+o?`c9)awqHbJqf|amz?b5Y-&E={inU8L} zO_Xc=yJT51bzD4;%{M5>Q#St*-`AWQ@`MC&)!P1|vbQyFM-hKJE=HH^s^#yQ(h^%D zN?cmlY3CNn3|?T)SHBvER-hp1*G{VO4L0MqFPwJy%k9XgI2Yu4+Y&IB5etb;)xv^es)5o;d2WIV+`59ycG_d&(tK`5!Vglz`r;-6q3?UqG-gNvNufmb zlBQJptQ($*eDVyI8aLSyNjYi)INF*zPBvcnh0s1|wXDs-kHNqiW1n6}z~~U5N2`CW zk&EyoS#dQMoI0<5zSZ08=|}3aN35KCv$GwU2<}v;j&b32Smh2k4V7P_(^wAcuv10} z=_-D1z4}~SwX2rh-@{*6CC(c{4Rcn^_i}MlHHB^B? zFh*b)=M{~}Lc9mu>7HAyN`9gsW}x2U%Bl!%?!Z@(GyA%8)u$50@Fu*~XC^bgHxj#2 zu~mgpLvJ%2_=V43*B?85{b-iwPj7U{dSW(mI3$&mkn%UATOt*ONL6j-o_yd&5t)^n zNSBw@iC#p|9{nbMJMNH_bi=q@$mWpE%=h;92FuxA-z#*$04?`gO#X*>=;Xlj;rkVn zQ%)(+Y4mPI(^qcRM-$LmtH^wP@H9i%VFdAZsMsRjtN|;Dv9G`L)6BHZpB>YL^)iWYtCl#E=;g<$%31#_chRH796<6g%eY`n^ zJ;VtKl**0r%F-U-tRj=GQez41hx=zu(f4Z+f>yz3AzwV(4-p;nORp-=4EcxzWu+G( zhM!U2s%e@p;0To(ceIHGR_L&M*A{@#o3lO{NLiQq?iJr~`K*tjZiPO0BwSGEx!YQZ zu=|V=SYE)SfqLbPVgD)fH+7pp2v~=MJAQoLslcbe$INZ|y_Yk%sUf=O&1;`k2cg-N zNWKE*FG$t3zcS&Lt4r3*BFKU$_o%_~c7@d_a1qEC{3AU&k=&4Yj|9URzsf~FTY#69 z{vIN8O)w(ZH+wN{}42@<)I-&>WuPsQ6k z(n;H=z+peXzy5chipinFL8r-lGO#X%1cMc`cSc9xINFrV7$=FxDH>m5cOG2p{QTj+ zyKeD6W6-C;@LE#XAU91l$QE(Nq+Z`eMS!=m$XKx5F3BJ>u2T7-S;W<@AlyTo zss-DlR!3>JyC*nBzV{hqNsKF>u`6X|T14<(fo~?Rw~~{-#B$F6pbID`?F7;80||(q zHY_HhO!)@LmEOE7T#N0dc5|jTOFOT3)n{F}YPpKc#S72eqG|XKiwt1eaZVxRVYgJ` zMBDZ>eWWLZeAW4rR*IBvRYj}sD?n7TEWj8T@37!=`uv%pW#FGc#?2HYCecJL-9>=Y z2t_>e#lKd{`RVEmXOnuvPdSt~cpZix3A;l)Rn%+Qe{3RKdG((@CA*zhdWRCHJztdD zV741<1Bh8dUM&H7xPog@ba?|ql#ZVb9)O3s1~Z4p5%qr7LvVc{qxn>Zuj?=i&bZa` zfWz@crLyS$eT2y_c#-fgVRmdnNX1T$tL9 z=adsAXo1#ty8iXBUG$y@ECs2t;?s&$J}uxIK$QS z^7U7h_@N$t>h--$D-sVPQ-%@Dsr!RL}_p{?}p>ncBTv`-(}pp%&y~7npH~Qg|D7zT6~dkoHjRbDv~g2ym>1)~zlj81mf1 zRG;0DCrhf>c|8D#?^#Jj7~%jw$z~X;1S=)X^F;eU$xEs1ok~q!8*=-ftRtVAIdg+7%DM=5&|r&!W> z#V_0i=M`v<5)%Oy`XokqRrchhL*Ix&R?T`oF-yBuDO}uFT*>_=goC?*bEL=qI{6Iy zJ>_*ocj}~YuJCYexh28^;2S3{T6847c2wLDSLtZ@VMWd9ryE4R{_LHOaPl#%KOvKY zcZ5J!SeyFwOob@XxfzIB$>0XVsu?+|kiUFjRK*wgo2l!B=o6<=a-&^b$mht-H&45f zjmaJxJx<%jm8lS%!Um!(o@kBr#lX1y4bsr$4Q*4G^PmXTzoqlubezOS>cv>l7hp+W z&aDS1QOop!j0xkgV@NfO;gWWsmA4ET@8vMkaFSm_n6@f}e{O%l*kuV2%l{6Je84=e zsY`C;E@`;c`}0X=Oy^7Z9GyTAbS4aM$z&(AgxXd;LJT(^LM)Cjqe#j~=DR_9$v4l* z`ZBLblpUP@Q6A*#eo{KVQeQ-3A7z<-*ECt)`;9@jXl3?Z#4r{m-}8?I-mwYXRitgh5ZI!e=BD(QV@SiII@GI0iFx|| z(s%AtyVx!xhQw8-=*|Px2IABaLeRKz#Rf!MTnxVbv)r}icwa|-ZAJF$E|Kf3OuFNJ z$-?6Sr-#}|M$@YiMfO)(^jndn&vV%<);6y@BTrPf*-}?eUNJ(D6bHupTx*~r^O=Q> z!`QdtiuC3{EsPj?9~3+eQ%iTN=uP_)*)dJI4c{J}JAib29d&g*p{M}j=C4GI^ip=- znN~s5qxE(c3rDeQe&EzI98P+b+Y!*Ee9z%73is11fMnISS1w%f`51w?reSGoy3Lq! zGO#jru;J)7{jr6fo4>!= zl!i^^*Y?9cH2cUcX( z=e3XWlPK}_ad3%jcUNMO?Owm_vPi$}bvv){TxK~tT>EtkVi6_~hjQ`91F>Bq^YMgn zAmK2$sD;eem@F)skKQb)>21bI?6ZBB_|LzDgEIeW?cC62W)@*c$PDR7&>l6c&_E;A zmrx|1x*@Eh=j0c}iBa<3R270Qk~<8s7hl(8RGmO!rvRORfTR)|N8hfUbS}UQDDLG& zvRc_x#zB0|`L&Jp%u>Q(j?X(}Qch)GO_?m2xwB|UelfgmLK0M*5+LlPhT+Ellzcfr zDVxHCDK6L=Fy{Qxh*HM8$Ne^~(pfE1nko1bl>b{x}N0U++!yp1Ry!AU9Ab9R=vjwDf5#VL$~9TBtZTVW1!Z zcZQ@8XHH};c5JHlD8ko<2v$%5ZSXz}djJC7!btBwQWT;3>m+E8i+GVC9c$yyrezD| zKsSgp8d#-E&TKSHs!TXU>BGo7mKK5Zq7CMfjBBB$Y0j23r(0AoX>4q)nV8i}N%Pn( z!IQu3i8y{KLO8thSXJ+?C%X6JC}FpHpJmn74iq8_UWHxPf0yI8ny+}o_wu6y@&=Ms zFK`r)%bgkcr+s#|{5mv3v?3^%UJc*kZezPFO(mG^NNRW#BIr+cxwW{UoFdP6iI=Y@ z_1^*4*ec4vOY|+9uy1jpe~XciU_GcCxJB4$4OpACf@@C#Xzjds1zqSJej;lpV)|CH z@zOGRrAm1Nm8QH{N7YqrknBmPi-xn>rz}#*K9+6RC8pX;91s!Pz^rLtI^I+F%3%*j z;vydKGDMW)g# z=|KB;Dyx`mZ#>`FnDRrBe<{z=Pf^s97giAN3cI5P@#Zkee-FA_`C%RwiC2yHr9+?y;3kUeNQ*j{WP_JpS~JT3U=>?SzwJiO~$WnpPK?LWab0jjOfLni5&GD#r&YN zi{<;x32z7n(rj$Yv6lBiW{-r2ENcct2yT(nIvsa<-v~P!W;ve3Yep4lftY43bd1`^uy!#$$ ztBTdcM;5#n4B7nl)${Xx>QB9M)hE3}-l=D_cYWfCT*0?Ctp6#9W52)-{v-Y1q31ek zagYMaWM^9Sp+W=fF|Ejy!Lkl6n;YhCkk*Kn+AgUgp0_Z$Dx<;2yrD2w=u`5~O0}&} zX<5o?Mi!hfJv?gu<&dqu+xDE?uwqtqr$!N(60}`T5P)4sfv?e0U>0d91h+EzI~E1u zyx*9ZGNy=I=hZM=XK#@l6bVv;S3jL1@)i3zS-y!jwAmaWoz&b*A;v6N8?!pb(Bzs_ zx;MF|P0f^iz-U~wp*(2nnZ)ri--43IW5%)~D!Q1ZKc-oFfDVElTKN1U$Dft35Ip(T z@I4)`>2zdS6a8mI$GE!R`nj@;to8wLXDHh&N$kGulICknztZT z3TiI=#Q7fvKf<#{n;nZi;p7c<(8(XQpq+e^-xKJk$&C1+RHNXI*mDM#`QZVQ#GUia zNu*+SsURwhTCRCI^`Jb7+_(9xsKkLp2TmP(BhNDD)D36Fo|?Vj_GMGdQzKt9s&0BZ z^sF~Xd)lr9?QkRcp^|I5f#%b``y{*?;<*gjIXGN|!z@J&gwSFbLi%%VUWPisa~{Z* zHjHmJpsE6-9g7savpy<71XuJ-Ah+2OjQj2?&+_+4`!B9v6D zLV4?K(a`uQhSk%qU$R-B+$i{Z@<4XKVD{!aWgwRwEXaKBUUkKI^JDRr>WFg{nl02? z=vGOkkMs-Wf?|mMQ?&HwD;8cj+GtO)eJzrw0la7l;6*#c&NNf4ih^u^1kMg+0*MejxZ2Xoc5!&0w`$JMeH<=hHg@jy=CcIjft|5TKhyW@w$nKR+U5cT_s`{tPR@CW zPR(KDbiS#cTES8i7up>=#zARMiV7}o(nT@ojt{L z)a`Fs%c=Fbl2Y31ojOlVr*j_MsVKPJ(?lb4TXfAiO5NqHI$OVUZvRf%&~M}((N9gk zdi{7s5}DdZ9N2thIGos%%d z8re*(8OvI_zKSoAPk}s4a5{X$@a3S*s9`}L=;b|&OY7`f@7hy4+BC5^^4frYw8kg- zT+EC6(2lD22I4YJ6J+eXSOy+{tC)g0Nqb0?l;=TifCg31JGYxxzJG}Odpam~V)99D zXWe*r+}P5R^K~keI%UcV_2!BwOVj1o4hQQ{3UXDO*S)^Rb57``_`cI;t0fM+;qBkZDK8&&{b3!qjX5lo;=BsO57PK6fgB)XA=mxs)RA?9!ymMFoo$*X0| zGb#CH%yvsu^f`E0wW;OSxpI?D6FCo`Cdf=q|9F_1LkRSCzp%nA#*i>kpL4{ncR|u= zc2mJzyFe$8&K>Ugxw&B{g?D8-_1NdE&l)buxg4$mgZm{QNB0qP2B+z7HDv~4vL6B! za+pKZkJl(VaZWu*$iW}PZ#PfWZe=Fd%Qo+A@SFzh;30K9wBfE<)((fpgdh&N@sGPluKH>w z-W8m#0dyn)i;m^A=y(9jy{eVHv+qRN`;gNy#ShS8XRL7@=9yXWGXJOpv8qPunH$@p z>L;y6+rnknKkc7-zHQ^+ z`)P6p5$1Mbrhio{xWIP*!!10p_F~YsybX&JOczV!8L0qO1t=w3DS3!)``K5a^j%ay z<=dcdTd|dYSJE<>Hc$TDDqB@750c0a^OM%PO}B`qb*~BTc->m)R}CF(2ZevHUD$iR#VrpCS`#V?Y`DAbkPgCdhleM>uEi z+ybVdy>r^J3z!IErF8;>E!G+0gJ#?u+dWOMHV4U5JQfj3BuCP7@R_cHNoMd{@Ri_( z^>P;>2gpz8;zKlxd!jIJlu>=~cgPqZxcRXWUnMU!cnvBp-W7QEQ;!lOn?OIRi48B4 z%o$N2ekN}?8r;b;I8$;riyicTgZPn0bNpPAg7tWwWZNr-0SIhabHOy{MdDAVycNq)G2Q+$jHTN1m0XQj%__X`O`TJ zPe@m1CjEtlh29xoH`D`s^UnrqB4|QaczjON5e}~t4o^Y9boTIs7?-8}1^r7{BV~gBJ>vr?&;N$xow?=%;Y(1 zZR9zyMEC>XYbW%-aJxhf*REYxZ*%OdpX|qJ*DE$cVDv;#DJ z7+VZn5wGTKR*}JC;|_py#C%V50vs@D5!JyJW(aFs5=1X0i2N3?)u{i|G1|@?;}Yx` zANs9>u}3(7-#~`)n*Zg~@@b#eiP6hsVmpX1Pl<2wvEIP=RxW}8{`XsHn|Uji^m@Hx zP1rFVHA*PDa8T5NQYS-E2aqhnCFY403*I_lYka(opO2$N2HfKh;KL|lIJHCwE+?e1 z2Vr*A;xx=IhKAX_aWoi-+$3dwbWFOnHIOMGP7(++25K>1CUSsLg5(M5aRFS13;y@t z0*yq_H`F>dqi?7p1eW2={uk6c=1%w=NYCY-lkZ`=65YPDYOTl%d2K`v@+d}Z^lN>*H0_#wtv~mP_jMh^kP+sL(5|{r!nZDor%m`T(lDABy$y)}i zF&l#ucXv{s&Xbc9e2Y2pFz{<0D=GI;ixD_OGQULn5#0W&8%#lR?FzcC5-x5t{6r9o zv;?X!T0aTbbJ~4)?Xlp3U6*SnzQb%qW6*H|@R@9H!d(2)0EQtabcBz7KSIF8LHhU! zP5St2!3}l*uWPU>6F-i5a^EkH&izDdmwxk>N{B%Cn;V*WJWT3XAsV|%Ho_QK;Js9J z_s?%NKp7uxJq>j`!M3PA7}1yJJ*D7$zyvt}L8q0Gd$!JrH@%qW6s*N!Zu$NJzbshM z`^Qc##GM1k6}yDY=Gn*<(~PG;TFevHdU{YBWL&YvS~0D$c73m$*%6;r>`PU>)f4h$ z-O2A~_8>6KX(ODDFu%sb!=jFPhA9TMv)9Zqv_qd2!P1mgAlT`vL_>=(4OIQ-h!w$O zh6v6_F9cCy#eawl0<4(qwV@ssjvTOXbPStEkk$4(gLF|dfeIL1pJS?q@xa7Q76CYZjv_G%wb&{% z2A0GP(w~2;yW`An-42szVR57HRddP)|JJ?IDnFLYdE=I23m$PnbjiP!R126IY#=@@ z@zACB&9P8C|NSe-V(*{L@29NjC6?|TT7@P4tMm`CL$gTE3>EqSvgvG~MFGSIW9+H` zrH}AGUa#Jn>y?A}BL9^5okJQa(7T~BcsodxV6U;@O}1Z}(kQ2y@1h2FK4K^6D`dcS z#s%A^B~>l6ekXI&CNKWuc(G3X_{@zm#Aq%4k*j@nTJ8oo;i|qgLr`J6WP~2gy>Qd4 zxQQC91EgJ0O!NJvX+#5^KT`r+I@ic!N;(s6*KU{4do;x}CyU~X@UTPVaZaAdeq!2O ztz0+``3R%`&Dh?~7~ATlszXb!Z^LPJfN#-(|2>Tcc&ew+fg!=*`k;o9D7+OxdU@u^ z|KtopWL;l{6zqxsA`Dzki_oXKWYRvExA31?gz>A80~ZdYH)Bb3qFyP|RJ)Da`9y`4q2531z>6O#o?W>&##2L^P=g{|YEBz|}kV5_z>^=Bc5&4TZf)KD1fphG40VwDZLvyGi3{5PA(PPsw z44XSq-9Zb?m;^G|5%I&R5Ll?Y{0ywtf-nlpd?9w0+)Xt>9i2s>u>iIAY~2#l{@>99 zUHP{QFpql99XbgmcTm!d0qOaL*XF$EMhM9T4Hlzx2#v&vT>MNd!oJ2GT|9eMad${iNB@v zIyzcVw=6VhoBjQNI={+OAs`C=Z(9!&;*pT_XU3Embu3ZNwGU{ZY>Vi>UdNlkpttsH zLq3>TGxI^$bMbl$wheDMJ@ieP0$la~&+zuz=_qpAxN*>552WPsK1!gXj$qoCRy!K$ zuChXETCy~Ql92^$@qGob?~d1(=0CD&s5E6*0>qV07^csJoP zQ}c4bvqM+&>rz)lL6F_7Ofe84EJ_I31FV*+OJWQy3xLpW0lD%&ON9_9loBHMC45Ap zOOAic51_|Ag{V~vugcG{meuqnw+|3yN=5<|CXy;b2$=%QD+c8bm~2nYrl7=A=&t!9#4Me@xZloyg;m& zT@eS65a_-qh5B^Uz#O0;8sTN2tNpQ-@oO*?c7x=gA{X60O9(r@Mowlghog@2&y^WLU5RO)OG0nCc{s6eVU4(f&V9Jq1Y721``Kz_{IWw)( z6~hes_b}r<$oap(8V!r!R_qKdLhWt@xsJscac&|{)&t)JRdtw_HvOKWl*22~24XS; zhm7m&{TT!TTgn0)E?^KbF(VJ?ysZKxMLU<@{?ZqXfF?m~#&KRag0B4maQD}Ic(>7w z^A89Z#|F$B_?^pVgAR>#Ovh*Eycle`{k#GU$oFWSG4Bo*4?5H056|aJdp`G>YQ~#I zr;$e;JYnMXARJ|S-sl3{Vr=iuf8OFsbc@f8RKeon!GY>Rqv>=15BU~KIx?i8|9$s( z(cNozi7be!`lnhA*oyJ@K{U>cL*$nR4A{=W+CSy)TLE~USt37!UxmPxOt@03{{`{K ztfSH70&>p&k(2B84lwi~bp)a`{*-kgNOERD>L4Nj%Gd}1#uRNm)5^uFfuQzO;KLQ} z&q}5{PxJ}|jPU=<$2p*n%L7JlrU9bUfngVupk#RpVqd-%PRyZ{u(2qiuxA(D$gn%dJ&zy!XAiguy#*saScLp#3TfkbINmeLfV~AM84}OR znDb+!i2uuvy@~x;$olHz5CH;|#eAatv6b@L{EG7rE z4^^QZKNE%Jp@7QikL@l%z6-?^>>rml!UrwNQNcbH{R65D)-`}jC488;NkZr^r%V96 zqnKzDjOfYxV3R z9c%er(&UJLr%Zg}XR{`@Gc|MzYlU%_JHwcV6V%)i{zG-jqLskFA$H0%`pIPpPrko| zZW`^NNiX02DYZxG6}ATqSDFi{fu-V#>WRm>B8R^#h^DY?cMaXh^VnG!b$Mlt9E-H$ z(fTp7Wm!UuP79D-K(f4ZzvE`#@*={)(|>>ccv15pwb#a``%Nq7w$>KoCAgsU=Uive z_{1`njRzD7lJj$zEOp&GFA zLfNol-Qk&$3=kLy@GXv=?i8Ai_N#T)TeGwhZ&`G+#|;b}=Ev5A^92YLRLf&)9tR0}yhP;RS1 zFV_E~*=%lt8M6Q{8t~KEi~IGn1w$hKO7ehl&8>qRp6;zr?JwwFGcD%ag$+*#VF9xg zV`(>{^*llKtDR2mn{`L%A*+@Ga8S^2)#le{GQ3L|6o%eb0&4=8O%u|1?b(?XKKnP( zOC=e5Bb4wVi7qb<_0!V*TUWKgiP11({v+6M%n($q z&v_|grw6BE6&WbnooE(k?36?PS~X{XT@h)47(qCIfIf<#AjN_Zx=1gfh%{*`y+lBY zw9peEm1GAd#zbBvu5tOZ{39$*CrVq(L)|`0J)+%I1CDi zF;Q#wcITJ95mxOj^+c4NL{CwP>^@_c7Y%y8D)`A7YMh~19|&)>mvR#hkt28Zd~Rr1 zU@s_M`BEPu_t}qxZ)x#6jOs$7_=%HKEBLyGp~c&NjU^D@5$KHWUB4IDqyy8WT?!baJ`O45+5Zz#ofMMPiSO$5Lf5nL{j?^R@a88rZGVKpWT^%6MT(H>ZORW>- z-$(TX1jM+)4-qG(OSyb@8G{j)N?GTkl6NJ3EDusXYhtxP-zQkqmSQ+(94Mx{!Iz)@ z!JT8c?_?&nwbTl^lViT?n462!0YbZbsW>13wXbMIYijDKFBJ4|5BG2o5Q+xyh#@7p z%Ousia;IR~ECnyipCuH7>E;S;v6=kLA+ow`@dSr6N2HnCdHk?@DI)HknYVYuRqJO5 z%d{fb8IU#=u@(Wtn*<#9p6x3oR8;e?_&)v(IO;X{vH5pjl}o*(ag6^(-zm2K9+l!W zR$b!a-teoOItzKyWL)#86}N9~9$OXXP?DEFYV*ZOvTr`oU5(H)@^ z)~=w?Uw08MS^Oi%nUgE}NC|7!Q(?b4-TF^i$vdXyqs&^`HkWPNob1Uyxi{qHO4}<&t~WlRqU(S z2lQNnNa&Gg$d?PSc)o%8p z?df3Z{d3vvd{pI4G3I^bJb9NK03Tz;md?*+Vi(O8)YyP4O3DH;dGshWvMHAdxZ?&M zLsz8%v>5|#t_@;VqD}Y9t^s_0c+Vo>IzZs7al8hvbC|A7I_g!q*-h>T2&?#RIN;hty5UwoL!yp_rx{d66w(ja-$EUN;nQ|o6D zp_}C1?Io5f)Vch@rGG_J&)EHWTqxn;51T3xs% zkfTjUYF>cW0o|S0(2?n7w0rvUH=D}W7c`4_pVj&4Ee*#er++^)u?372z*(e$1@+`lufIDG`t1=2bXg}~LAc?0kgQD#KhIvwomN4KLpU;P(bU?(`* z^I@(;7$E|1&*w*-P5M=ynvLg)#7k>SRso7vG4-TuWPi}@m9FP?RzYY z-rNTjy@D=TjaM2K&poFnkB_BV6-p=OBa21l1S|J_|l( zfux7X>pOwID#867{Yslld;sQ7GfmH{0+BK3dCRo&GMwOJwc(tLn+hOM^$7@?#C4i-!dXh6+ckq;3nq^K8dAu{;@p;(^;%! ze5aGQex#1~-pokM7e5{dn)7+bXOQNAo;MkdkQd`WkE@(*bWn0?+yL?88y;he% zQbap9aS2Lk#QCikG2EnO-VAKVStU2TU3MGrYV0C|LS@&DTCF_y4^JPzl?c2kdOQ`H zT)0lTSMG)~ow648eT$oaaRju9;Dq-r7eQ>gYpw*iR*2q;7B?L;YK?M+uXy)gvWdCk zuf=R+5IH1_DkOm+knc&%!5mIY%6S0YO%N(mGhe7tXyn8Yrnm|lV;}>93a3#gqCf_P z0<`G=)n>|5Hj{*v(Y$2>W(5i&?7rwrCu}dz;uW$r3+=?*ava7w^$DdDKH5yV0*y9E z5dtdO@j!d`y~6_4NWrU;rWoeG*!>}~Ds#Clzswg*bR6*$@s{;PaFc562Rp3ni^9_M zj=_$>WH@0%MyPAus5+Uy>hHCx_TkE7ZJ+`4O#lY4)tcKHu#j3+>VdIP(EmdifOVkS z2j!ujm8l=1R5ZX$JXEvBL^4`uGXzF67vTK0eUI{yjo&}Hn)#Y$ z?YFW0P#l&jnrLSRO9Uv!)`PkZaQnEl$3b$3E|c7w5Us*qvFCx+?6Up6Lt7!fMqZ*Q zn9HSJs3;%CS`EoMtVxXRa)=l0sL2rU9-dDL(K;oTSf>q}+<#=f;xRq;)KKKmq;r}* zIpAbsaLQjzFMJzja}dV>ufm%zek+u3TCLJd;ix#x7wxWnBYh(@CJ5R7c8DF4E~2!6 z879m-^k~Eh54%A_-zrT1y+DajIbJ4vX9=!LIZZtv@fg^rF}OQ}4<%nzg1(~i`>3@5 zg*90uj-sAKvsV%^r|Is05=WUPCsjOwaP{o|!@||MKz|5|((=uMR-d(DOS$rq5tk)G5B{3KRhgn7t^pv6y|n;PynDnO}8dtk{&Shh_NI zcXK&c*7}K5dL~r@m!_?R>Qt{$xiU18iSXFL9`-B&h4vmVDoXzer8$(LCKhRMh?;en zLQJ4bBPG7`(+63Gv3Y4bb0?>C{7U*c4Z{s8fVl|p`fL3S1_dIK{c4600IU<)H2MHb z)@>Jr<}}ws{wI*~kX7nm(t$sYCeI|e-A)TgP%ZgyXdZKCTw%K9P8bem36}MArIxSc zoNlYRy*&(I-b)v~5&&0DGSmdZBR2y}R`gbYfoW|ZRp~g8w~5xJff@B|hEiTL(AF7Q zQ3)U~{9VnrE;Io?cYb|2B*-G-bEUPpMsFrgeD?3^04(YIsbetfLY$X0bdwNEhc}rm<;{Lj`Vk&1Sn)_-(F% zZVw#Bfdw0IO!1f^cuFHh{fXGSDt5beU|3TibVL+8m7?$TcN7|DcFWCPxYep)CXu&! z%P{w_Mf?%wSq0UOLKGlADM%cD2!#bj#d1C5rk63CPFE%;(-tHq!?m_~2QT7dD& z2m47p5F$>gR=OUT*9RR2A?7f4EsY=C;cS|OnFbRZ6L1p89iV2q1sh}m4y%)Ry_gr} z$AuIryJ$c>7x%|P(efQ@O@eCk0#Su^BFSW(-+Vr&o_Vf%p zLtr;sW4L2LKy#zus7JACkfG5y8ZE;~;E9jk$o%ym%Z>=!21>`S%+3XuRej2;1)OOT zI=gFj)#!0CRSs4?KhU)3;X#tYH2>mS*!^SsC_rJu6f!@QP(a7U^~BiU@FhyXeBVV6 zOh66`*qW`lHMpsW^qmGp--rZh@KSocTI9sV=Lhm&LkP{K0@*takmzhGHUM=!r4Axc z=;c>`x>}F11~4DrJbW*8`By*4ii2Sot3m#ebF%0B*EoX>`+*lT>W7TzTdkI=#9?p> z{U!4>1~=BX`#{64$Kp{P>F*PI(qB=6Q3wyGNB zML_!I`-evj!0NrbomcrA2Q^$c8L$9<_WzRd0CB>L5ZR(v9cLq)QMD>lYm;oKx?(Sqv|Qt9adY`i<_Ak{!x+9dTM{8)K^XQ08g$N(7FM8-Nl4H*1i)Bc;rEeqK%7e=v*UIbeu6YH#-N!NygQ(e-iwNIC-!^-J2y-g# zB4B#6k9TXFBF%3E^tKY*JFeeDS^{2f;@^NVd8Gn$+W}m`H}a2WJJhZ#xB2Urk0}!Z zd`^h&~nCrxJhA?f>N^< z_ZtVtqvC(A0|YpW(N~%}IxY%t4>hxOH2o>7oX+};^%=CIrwWFhJr!DY?4K3B zI<&l^0~Vh4sf;pVZHIIg%rHy7_?K65`3!tGoL=m^56h|)1$oBbTTph6$#rC6_d7L7 zI4)50fVIDF1nv=LhrLz2&)Z>H-;T|jMEWXr=p;anQma~L0;GTKfM5Rxy5ZN=f|@_m z(!-dGu7?%%0hRX%yTOiU`cbdg^`MaE$vi6viW0?(&Nx-s1J)nQ{ggF5#J$BcZpPb@ zOEd8SntPdGY5Vux-v%vi^BtyhI7(00Hxh3`e@H-;ek1ZI)pOfBNN}B1Bgn=Is(*xn z)*TRmh|%yd*NT_fEDp)D2Nn;QvM{k>HA>j^CP%r>eVy@RhmuzbfIwa01{p9=;yMIT z=G7Mfs@v}1LI%yjVqKC+TEyz6O=<)RzyG1=DDEg?FMivn_0D~Vm)oP z3NVuU2qsRP84Qa9Ex#F+yHOCM+)c-1uPVUZk{T85IvIz{!p*!8uywpzure3<;n)V@ zih;Wzl|pg?FAol(&^|zx2QH-;312^Y|IKct4ub2(fPU&?rZ|}U`j+BX#xbA$PrdZL zJBm@{4!G8Bdp!`6W!!?%(qIF%-(Yk&{7bffa&cfuVEY%X@s}}xv@;X`o`n~AAFkc{ z%AUO8nm>4={Q4(@% zoQq7bA`IZ8iV+anpRss*$ZY*~zPBtv0yWytz!>gcQY<<4+y+$f6T*S3f%{=NxJx1H zwtZ8;a6qMYj&)A1c?;9IZdH{l9C!TzSZj8r63a!GqXGt+J?bt);t~NHex1zJmI%Z< z^|=RNu){BH`uN0O5U=AG5RxH-`jL-2LO3xslDtLRNI$)pzq>G5pGUp359USd{x=+SQgvjwQacsWA5#XIS0?q~m z-60H5NBhy;lg%Y~XnKIi1tmEZ1E+HQbZgvZq9=%M7b3JgAS?YTXuAUWlvcKh-ws}JurNeJpFhlb$a+yo4gl*Hnl#!MUxex`(f$I@c73 z??vFYar^JHQPRHVCw?A9F$XWn$#X-lhkOVO2peHmEDmY|mufoOZ55h9EEBS->>6W?cB=(RepV?uL6)Nd&VuFr-McS2bTsByRJz?XVx*Nvbs=_Vv3z6|_^QdQ=hDkXCmG}JSTj9cSyCi& z1U(j7mHRxQ<@UJFL}mbV=#`q$H$iOzFtxdph)Zka$BN};6%Q`%^$=9x_HFn_i(^lfgZhXJh z{d7UX*u#;jeSi}iMmU@<^#1MGN*r5=iIM5Gc0lq9IzM%*IA!;T;3a9#pTsvv%A02V z>RWXg;AN=X8FvSY4PpVokB$>4pN6t9pW}(;_6gXlZhI|hEEcC;#4a^4%7wcS_dz5R z)S*EgxKk$wv|lH{wBtN3_>U(+icIuRO4B6Y=$Masw~u8P=s|0~c{MNL#^kqiC>8IQ z{Iycly-(053_R}JGgO?f)V>lzUY%TPn7*#X5npr4wNeCUjbgh1(M_tJ_+!5q(Dh@M z-@7qn3y+$eV*Kjy&@q=5jM|q@@CN@u+^Kl!+4X1ni?Sp&1CG)1gn|KVuXwkKKhLwf zoKLrJJjw~^6afoT*%vTl2M5Oul=6fA_`aM!zK_3j(X9U{8P{TA4k}g;KXTrL5~a<| z%YoG)XtYnAWkoxArKoD(;cs2B5Kl;siX7s5Smt!1rlVtWmoDk$REStCNK8Ri=mf@| zd>Sx!fV}`twDqr`xIs1b!4sWJJPj$*YpwJW0@eC4Pb*Ev-9L zGEq_-%Y1FSe^Dv9a|o!-S)g_lQ!brbJAsZDg-$BK;qFNQ@nJ>_GCb^k4uubB_#QRQ zmKMq%yArp*f*YJX0Nzl%ug9(y&jE6#l#G(nsNJrv%I7^ay)`r3f#t}Ub-OK?nP&NI zgR-k!Bw%F#Rfq!~4mH+}iL(hzJzmbDx(D6ae&v;?kGAnva9v4xXYhA5GsGHkSwi z1|$6!$98I@J;4-dwy+5)eRRjs9n2RF=|(hd0iqte(dT!7u3QpfWeyuyWuTtV4s*n0 ziU7*FRH&l%MCD2jkV=cDh;6vP!JJ|6$#e;kUQ^i(179`hvhXB?19o5OKE$REM)APa zXaLJX8ngrl=JV~=i4^kG@^E$V^f57O!+p6QW47@<0Qfqcr(%j#WwX}Bi%N*@ZVS}& z^s7Mfnm&+&#XIk9t{tI0{D`_$C>GSGN`S_Cme&ZZ@gDLuGfFu$5Qu_RVc-EjvaOsN zt1n}1up?0kC~pnoqWrf^OKqV3$Ith!-UT+1`2g6xQ10`w`(HtFbYZ@TaT$%EIp)J2 zoMP1E=oJ#Nk_0qQ1N{R94$a7rNt3UEWXr7SqUnVn%V_U(4>v)lj>DP733Z8}{>k%} zrGa&oE*EM^NI|bi`$@;H09&9LG0^g1H=dcf$e-|cXjKFPq;PGl1_!6h*29+AYi)u6 z5M`vm&V_4uB$DjY^cErdY_>t~Wddq4Z9E_3yJcn4f`$`00LLaxTA>m8p`@>W-d-)g zkJ)F)9^(dtUCi_C4_>B!DGe}8@Q?%wL^<`hf{QI(Z)-sBS0_#gkBe)A~v3dHa4sv0k9j1 ziOpAsbCQ>aGT8JyWxZwJ@u6PCae;Ej#O*7spnBAib?Icy@n*0u7YM=VCl!}VXVQ5S zuXP>NCE(bw_>f1U9kKx6C`vi&H0PT2JeIy)wr~(Al#t!=X_`x}>$Yy+!7OmdmnrQp zsAt7jIx~so&9*AFRE0ixhtOyTpL-LF>18KWS5|_IUe2NYtBP-2azO9l$Om@2;hcmh zSvKNS0*Q9ne-=Riu@@OP+`DmQTkfhtg!RA2i_Xf zuVP)HF6#eyAbZOIw<_PKT=ldLWd%ifUgiLk6)D4=##Lo49PD9F+ev^+vWb<2GdK4# zFieU4Orl1EQzXJ$i(4b+`FS1t6m(5nTe}o@8t&HJsR#ZM`v;rjS-nm+i19IWsSEC% zED%&vA7N}suv_&4cvfA4%bs7`Va`jzCaI0pj`$sMf~S?mvW`11j}g8 z$ysyP!CSQ}dNIYzE-qgq&@&^&3{mVJQiqmSxb0(^nVNSY>nZlIF5TTayL3L5WpS_% z1F0jP{+qIJPmsa+=qvzjrwiR>2?euQl23nZNRyq(O1t~VT$H@xcH`Hew4m$owoavk z7ihMBNGFc7v0=Tg*Z6u`;*9@*m6d6oe#-(fH#*S~SGAJCvcCyoxh!c?K9+} zGHNPKk2r)jD?Hdktj$}9k@|;F`X3;hN!vMIke|*)EJt3~hKVH!3GnUWmIT$P*TUe2 z$ppiCk^`S*aE7V_jSD#!5#}QqBg;dffuOj%F8C#r#Vv0{zCn_-SLTVIM$30Gc!YvYBT={Da;|YQ^j*7&V*rlXD7g#%up`$62y1dkQ5*wCXm?;L09Zr ze*(me4;-*b$GdT*q!5sDMrSAQSQIhvn!d+=$04#{JVksnTamcwhUBRRm6nMKS(UFJ za`htGnKtLM9zLksv;}6bV6x(ce(9O?-fiRPxESA5DJjmo5xSHx-bT;-@jCf4iE;kr z@WIb6g3q?B%34|qdQ8V@D6dwW{)Sv|K9~V@kif`)?bCPr9_G>{)yNf+vEnDM^Ehz- z-5=#BKpFPrno-Jzlc&Z83qM>doUIr6 z6|71{>!A3(z<$T+PTT`~d@rPH`oXh)Ahs&zE8)A7E{v4@FcJ9Zs>>WsQQ z8Anm2!daSI`u1WHXI$Fm?Snh}fsW3c(a&;}z$p8L3H1IRpGnn<3L`O?DY3nf)8(c& z!m#UbbC=T-7KK@InvbI)p&7cwTw8|<8$UAV`XW#w#I?xM+*25~GI5}E=BW#=`flLF zV%(i3CX1U`1FQl4ORkC-(jGi<3PM8{Ge3pn>$Xu28?xB6swFvEl3=%oOOGQw5MYAe zM1g7`Wrtx3k688`$yhw%VUs_u8n+o&jP10TaTdSklxpXgF0I`6BRb{oaCgczgTHf_ zgeqY7)hkTKo#H#RS~)N0L z5K9e0?#x(TUTCW5HN!_{PM5k?45X0V3$jo^OXl$BOa3X#At@hcW!8tp!)DMC?HivN zxn2`?h0geT=B|-D>V1T8JYGJ#NGk+gFxwQ{H`!Z)P=! zi! zw&uc{IEx-sWt5mM=Yw1l$(d%DW1Vl;IWXN;sp3y2%|uqlHFc^JhV03TS<)B8KG+4M zzL2?k-h@{Qb3~4u-5Qc=UR5?MghzDwM$24Q$^&@wk^$otM5S5ja(I6erc;T4Q>qTg z<0I~}I%j%QGd!d!1giV`I>F`Ka>uwY6o>PB(2c=a<`yKHe z@5d+3Ap{JP#)Jjg)R{OEq>(}i(#&1CE76D5#Ht^-%A!$@^^hL%w`MJ0Z07B%0E4_* z^2>J8mOihaEz@n-sZGx6p7tK&GtresTx9v;g=Se`n3;Q-#Yz)ANou#wd5m{@A6xvg zbNkBIka4afd=YW)*6R(0KmQ}vy-$P2lB8bng#J2MxtHU|Vp+sCm1qy%+Wq3Xy(|<4 zZWzX&;6#(e;smqWth90aD;H?2p=T(?40jR!G3szpo!YRM?U^=o^?53e`8vzdLG+ zIUa?yVs%2013mK0eOPXU@;imm*;9i?W~siMfI z4ku283>aDzX|`LnTm5o`Nu@}&U2z7bv!lx>yn7u91Id}tI>{R44kj7B!)Ic4{fdj3 z5vFfO(C)HchvwPCa&n2nyr`{7+$f+yP`h7i4s#-0txwsS<^uCYF*7~>+p~bz!DPY< za_Q?nOySADzf9cl-d0>uM50uiV4)=I>btS%h3x=Rp)Tovcv>OfYHy| z1LUT(N~K|#X^&AsTYuLBM2l`d8dxQAHm<*oKla-DJ6AnspO0ME9rJD{DaH^c*(xlm zV@2*ReSB=On9f%5z1XKhb0YH;z6fC72@NamoZXEt_^rb}b139R3+Hw^RZoX?&JAG5 zD_m1TeX5102sq9Bk)!>PGZ66^_}Tw(PL@q`x$1m>DT_D<+PnX)!0@#>gtk~}9T}H4 z9>>@ud`}S)eNuOZS}HNB)tdRwO0rEH7lNG7d;Q)k8{2(OM1xh8o8A7&%)$vOq_6;Y zgsrc~3{Li<&cgz}0>0m6<(DeD4taU$TUz5x5$Zj6x=s3{M@)oBH~NDt?!;+VV0@={ zCcN{Ajh;1bhkvry=^QJ;j}Kt%i3M)5`NMH@7<`=l#%VHorljJO#w{!SXMhY4}a+=_)Is=Z9!9JD>_XA5uJ4VdV0(~V!ry0Qm8Oi<0 zef?P;7bD5T-GvvOCS%FNh?mZ|zRjnH$V>V)b_1H49i$P0CML3d+HlmF=+3t;b(l;X zMk~zs`&9Nz#cVaGuFK;!o+G~_AkZ!mw>}=C7NRM~hf)clQY0kZNAB2ntNtZU(X4`B zM(^rdaP~sJ_=O4WksO@elv92ZKiP`|gg0_0sS|VY8qBkqmq>7Br8^%SI)(eESj0HZ z)aQDp6T*Gv=SRfLQfE@1A+~*0k>7o&_1YP`hKP5GJK<)jx)Chd*URjz)B>_4$-Tqs zLl}gMZ*4WL)DS_0rClmLMKOiK7aLHpSJR_Y~ zLZ%2uJ&>#S1&I_}`g598UB6ZtwB7@J*HioWg8N4;uV0^% zLKhY|I#6nit6t54=t!K^G(&t%v%nzKC5z{L=0Hw4tbPsK>@i*$c|9j-(Q)~5Qu6kc z9mcIHPo4LgZNLlni=V==vt86s=*byPaMO6gSmJme3J3%ucs^~SmheR7A0b55aw7 z(IZQj>a|=Kn$=F{3~z=dZ%l66te>N=+K32|gJDjKvD&8@w|4POTgH)&;j1zbMQsYn zb4^PO11b>z1vPL; zGPx15`blF=d2$ZDfy0QB@$yp-gq=&W_rvwo-u6w2>udP_PUmsi-giPz9@3R>ALT5RZH8Ug zEJbC~dpiAv+_)kh!+K38^>XWj?hAX=line(51^Jtp6^r*SP}EOlNO{&-5*fAd6se3 zt?`CIfID&S)WF!4Cn*Qrux-B4*A&|FH7CVu4K6y8h==F6{+8L3k&;0*GU^fcWH{oH z$bsDpkry;oOKT43C%<1XTYAEAmMihb7ip)xUt?115Elt;o{l4>zrB#T`5e2B$%&r{ z)v@fr7(aewk#6wL(055nl(}5et8OQj8Z2{{Ls8NX#uN&+<04mxnRl;xN>**h?<@l{ z1UkpP$7iegOq?lOr7D)cQm>?PseS^!qb!8{UP=h;%5&uKVPl7b3f}D-`*U`mYkTn* z4P4ftFL1A?iAR-Ef5!0V5S)>xT#|d;SiI-y8g(M`eOQ`zTd~=atF7yajA5Vg4Cf;6 zSJnFZN+$(h(_F4=?D{}Tw%cV3RLq5-7P^?)d*Z}_MEr^AkGb1SNzsHYwy0uc^2od! zn&8%b7|?1{bGi<~$U8XiTR;BTLs?yy%}PVP?A@Ao?9y8-G3P~%n$3)m;H^LO_e_G^ z!YGAKYX?eR6)+%zrx@--u3a>FM5^S)cQkkt+eaUL4;pO!NE z>j)Scpee~%El^ll)~*%{inhqT{bl!PZ(H4UsYAE)LRPNqyMH$TAcX@qS1g@hah`~`&DR%Yx1r* zzm>L(%%Y0GfNemg22ctc64cWcU&QuTbkBP^xMtkQP!&112TfO+3U>8556MU^R5?aONEG@E5XS|vQfLX zj9EySFg5&THD|m(cT#P#2jQ%mN0Sgm^CvF%oUzeSAe{Lnh(C^dCUI00c* zT<~(>yDh#?N%QJ>2lZ=LO$nJ=PiaXUT??WQkR_VL2l$F32v2qH#H}c4b;Z~7=Dp0< zWa_~A%00P+e_Sp2HS{NSGs~=n_N@O|Z;;B$B1Rm->wHsD>&un5<+e328uvpE+nIZ2 zgiNN+nYV&0t^A|@!`u&d!-Pj@2I6b%nxW#?+AUvTPwBi5$QA-7?=E@RzeVk(08e+> z#2ao;i24z&fFMtg4YUswOpN;s7TT-+s){?jKn{>7@xwH5|3hSKkj<;T+vDD2*NtDk z5_clHdz~_rztkR23U;;>p{=A_nJ`ot1frIe7S*}bMEVZfn9hZKhqGnjd2@sO-b-zJ zD)vFx_QJ#h=a2>JBz_!+6`ArL&B}G9857UEX@R;?-^W@cO6VMBk*vIudn~WP>`Vfx z%?JD4);LXCQ|ujlq#{T+!aU+&qX11v*J`Vxx5#_Qin3td28mB@=wi=-@$tTa2cXuZ z`$YGO5c7carq>BJNr!8nUff5VKsy1g_h&`1zZk8``23S+T^g%Fs3~q56Tb;a_OJ%C zCC)2+At#c?fKzZ*y}M?`kW-NuuYi!GYtE>w43NE!DUX=?!U$Vc5jWLm9=LQK1r+e0 z&ntLmUoN2tUnjolieR-#{ja?=R{$Qmf3)m1dRyg@D|s4u@-U$$ar^YBn84J=f{C-Z zvQO%R)Xo~@@e-mLZErl<5VHHcT;6DQ*wthdVbexflh}vzyQ(tgPE`tynDI5i%tnN1 zo;k+>AFhA*X(T3BE`rzVYXO((#iTJ7O;UkwL{?J=?c$EMF@E6kdYGpuE;M_9ZKAZl zw)O!W7W3W=1+jS}_wt->xM#UD#$&j^{v}N`L!LK!j+=Lt4Q)~_sZ4VO>ZAWbOHGLi zh2tuTJ6$Uq+v*WWFa#CYiV|)E6uF!^dhrC%+dKy~E5)nlz8D|X6U_?C zA;Aao8hH}sor>=MHl=hOwd(@$Bw$$b4eN`*5!3SL^#KD=e@bw zUO+SWDnuVB_EzXMr0IaG!)zsa zTcW&aku~-671i3|vvX!aO>zz2y~eM8+6)7YIo5RiU)#A1P2fY}UHaRBC=e}D^6CRd zvldoe(uKG9^vWVcNn<|ZPAfY)_Eh8!P{f{)cmhFr0vsz)n1!Be5d=W>H|=vnJVqX+rnx1Q6%nYGp@X=q0VoombIpCf$XNI;bmp5HN7oWRdiR?PCs49w)7$j$mh~m`3UPk&nW#E}$s-NFe(&ox z)N+kf*u#YA{IuKlAvbU+7{YX~zF@t9hoch_w~#G+o6E6B(TRpqU<-=Tt9OVnT`{OX zOzb%~$Tp$2P2SbRX}l?Pc-I5jQl2O)-Jgr`Eu~dvzEkXq1BY|cUC*zT>M}i>_S=|x zEPWg+Tykdrkdh8Kv~E~(KdNVPb??D_KmMrkuw@U;7J%I1KBFgZP?B31ns3O%h-zf6 zAbDi7yx*nj57lF5r3Ce^tM8GVVZJtUc3kaw_V|5|1H2;rMLVt>CB-fnQ*n4 zJ02r3*Hh5&qS@hU@wXTr)K4}ThqC5aP>LRhV#R^DLthFk33TtFJH)sNcYGFzUE}8} zTFh3gWwcu1&(#-FEX;HAmu`XnP|LjWo^%FZ=Z>ZZk4hn?NY3($2sZyFs3r+Z>OTG6({i9VPC%@qKV;kg@51*lH(Go(WTcH>qXz+?j1}$_h^ev4~u;QgCPtf=T zok%2Mw_8@)$hMgWwWilwF$7@%;ziJxRs7xI4O{QQvN+osBTaDlrp7 zby>HC^}lhB6E`(`uNbSaRABk4+GFAcRrlnpjd@jYghgNpS6IsBA)Lkd=H8^Kv7>}X zHs*@+;fitU;hK}GJh-mL{ev=eNeC~a!_vt^Cd*8y&3^pa4??P9)-jmIk6qJkklIqy|TN|#=EW}sC5gokVU&+_+}`L?zV~x61B`6r_wR%U|mm>itraR z9`tizg|W4>5x3`H+H)(4xWZm?@fDD=NSKfwdUj+yA*k7tHMumc!KPxqD;=4QqSN;ylCm%!W;Ex_EmjFC=i)6+_RQ{2e>g7qDpskWgpiwk zmmTs*^A`1vmKj+zgqFzE^^Cr6Tkd-J&mn_~8wO_l8n>Gt_lstamzL5#$B-jb<@g0{y`t_+?0+?=?XR;6dZO#6ua zcc@$xsIgpI>z%VtWIL~}7cye7d`Ye|+qGGpiRczq9 z>$Z0L<~c)E@?P)DoeME5P^nPvZs34wWrtQU2!SaCJ}b`+8Xf)R4m-SyjJ9Eo)kU7@X%^nuN6d@%KKehTgQA^PB-;O_HfAL zI|L4%KaU!(C}%?pSz`<1c|o(9qk}Kj?m==QK(m0+U?=rVyqn<{Cd36p(EO&i&fggr zWEp&a>pArwfIIZQ8OGJL0}i8myeptT!hk=ph);bRr5Vt1ODYi2Hy1xWHRYFaD`zybqpvrzV)W7OaelzlhDk{Ha}|BOKv*X?1l55 z%-L_*O@ZB0SGQ^0nvaZ@tqZJ9)4lPcKEg1$HNTE-hPQibEQ+5@;O)~=w zO<-p%l6o~;y3!AG>0Nz(hO5iqbweI<0(7x>E~t7}=yW>KR0bfU&y5A!RBmzaH$o@3 zrVL8kuqsVO`U34%Osx`?IPo&*m&(tl7){wak$bNN zB?+e9HcMr(7Z&LGY1zN9``o#_lr=Mgp7EXoTJ|k|)FBhO%oEJP&Gpaujr-X3IGS>f zMFhRxzgbVTYqMVG`j2=A_%FI+PiG0T+b``);b zgavgjr95JNoUkV1i(pGw_?|k=aJrSFAoSPh_KUTlb;p?A4a}8y#s?kv!7DSlTlRzMZLn|ZCVx{TLqtuoXNUDUY)WHTZV8q_A#J!Hcsy~&y6*OrEf&K~gVZ^3l$xN)g2Fl-g=GHVe|v?dUWoH*|HD*U4i$5SolyvLQC^bfWXTw zhoL0%h%2CglmjVh(#6zcj6nkuz>v4t0anIyP0;m-V|+*Aqyf61q(B-b_Mh6kJFbX* zx(mw8UM$tGo+E@XGW)y-IR+zVXbOEG1r7eMe!On8-b)YwZn>dIkKsj{xKFu9;NSw9 z`>6Z#3*o7J9CEZK7x781old;>BV#TA5r5wJaylMGnA82efKP9He-cMN>)M)-kR@lC zDfsk~*EE=dEA3ai*UrihC%?!YIZG}7trmkH?WPcG(^SPMB27CJT*D-IwTf-j6cPyZ}u=3rN>`24t_rJnzSMz&*>!vF54pD^oZn2I9epl&>f*qbhU zN_M=lxi9GVI>FgvA8846uzf3@{5IF$<_*w?G)eYvwrx5id4q(d=vQHceOaZnBt9SgZ)%rBz^U1rNvc-gIgV$2!(t}aR~~V8o)82TQa8 z5qGEI_{?O*$;6+s#W)uKt zIIfHon12Q630wct{={gbslp7$p+A&_9zuRI+ zdG?9B(=7?mJtXvDl^GH&cMLD;f+p_E|Nb{G2pX1nxef-2ZAXAsSa{vf5e+&> zlg7$hTR>3yUo8a0KwGED_1mv&y<^{&5cw|FN2Az#rFR2LjmyClEb{Go^b(6W@A)+2 zf-i>F`)KR}&`+KHrxpJ5hnZkpnk2oByKNVM#jz-V)!I4F5n65D+MyBnp_9?!{gEX@ z4)4#em)G?-1vTcD{6byVmE2(dG2cQZ&F6Bf%m7GZP0!Ao*fR1Cn;URx{@Hd=r{|LNc$9W|`~(|_{Q5WP8l zd=X13biWjJu!Ge{dvL}esm8VZ*#^`zRz1P$&_UX){N_K#!jFux@aZ}ky#jJv`U*lu zPcYB8h~~>{wlZ|U*eRZJ6E6})=N9TV!>XPk^poBni`0s^)p3aSGSg=AkAcmTF=_&x ztU4l^7xhpj{V?rUC{cvF7@alaD>UzAS`V8dZ~XV4uX<`qGW74#{cAQ9bNI(o`|pwY z*IoSUX;(vy)xWOtUsw6BtAs?S{!e69-^zjf#vc`c{}Z47udDla-&cd)zgZ!}J@(&> z`2Vqt_+K~wZ&vqjR`-7azfTkW?P;eFw$SnPGjhOLPWD$e%FXW1LLAZ zk{b&u4F4th(;mxhRJ}Q{zYl$Cn0|S_fqUsm=P76upZWT(c=_#N*OG# z)-yO47{o23LI1&&%^yhf9Fz2?Sz7RTK;1)zr_%yskPcnYP@@0sW54GE09Zv+hss3v z3lNb@nDZ@D1(a2*-v9x$DB53Zrlp@Gf79v?2J5n0xAk^AT1 zQ=)*<`?ozp3kTMTcF+d2+Kfog;Rn~z3`&5P0G;Fi-J9zt&HgXmJaZ@x$JEFDdrhEK z&OFAuftfmCZC>^aAsMP8MEf`XVtOmc(DUoN;&G8~%6$7!$!XKtW)OnvD(JM`o;~FG`>!IUc|;{?8+w#2_tg9@ z%1yiI6p?!BkS=5t&lTlw(#<5Ycg!}eti%5O`fGMB?rB)zF-UazXddk;T|42(sd92I{q zY|XB$^EoPt20{cGoFO9K&UPQE@i`h{xcDjht!DRcBmo8fN1@tUdqKHgBnoRh>xY*w zMtJnR2|B|=YrWuAID|%ph1e7T`2)*cO}SL#PI&rSi=SenS9hpq9;2%p-O-L8>%p4v zT0>|S_yZKQcxnfcbnR|-2ipfIf@RD}{P)di%V5a$lfzOTnE0)>scTI!@HXrB`3)STcpg2*12h_-)%w=Jgden` z#RWktI*8|q4gD{AaeNktV%H0uay<=CG|sVu{cOtnjoyJ)dX=wOi|TOLb!_4(OcQ|o zW0n`?uw*k^^MlT!~=wPx2d@$8ko{zw|J z_kiw=fsa3EAvHj0q>mTHET#FWbBO2EX24(OKr?6xwhkgyquFU95*62nk8W0IW>uKw z{{dW)r`0UIE9%e%#-m1>^8N^*1$|#VE>dxLU}>~Yr?CK$uJ6CcE&-RRupw9%0m}X0R4f2Q%-a1M)%H&-iijU0 z1&XmDh$NF^P3AiR;mPwua-Q^uP%d){tb$}7L6!6Y%c|#jaZsJsc>*CMx*2zhD_Iz8 zoxwrG8-OfIg-23Shwgx`V^%(*>$Y4F`CqMRBpGjqec9H&OLnejRD# z!Uh!cDQ!%%A)#b6uzmA?@rs4z5X!USZqWq4H3+Ds7QopbI_OD%fQpHmVbBCEw2WW> zr)6|_2}9lOSTP%@pXu8Uyq}b06W#YB7X$7&&AMVC-C(Xuw@&?3*zkSj% zJH{if*IR~yr3_%J!_^MVvnwCNHs=R1J)u98e=&`B&Sr3f0U@mAMU9;x_PUm=r6a&H z=mDT*ZJYFbW}Z4cNaN8+hnO>%qyj-w1TdJ~~4gSx$Q-q?l#=Kb@gWxAm}gQ-md< zEq;Yc+tIYKI(9UG9d$z!sN zLbXf7B*S&Y=;OOR049%AC1l~ff3~()+0;hJY(y2mn~9}eihaq9$Fi`ttPhZ8z|Zul zs96t`F}O}3lYvAL^0*;d9+zqjX^qyj{;!M$R!9 zX~d7;S4l%V-L#}@WiwW0?QDWL^k?)?5!hpTUvsV}1j2tRnLX>CZTk2)XeZs7ikI7B zpy0%ex}ZMtpWJYWWA1k-1CRX^oY;LI=6Y8(zTimfBi)GFoeYP)?8jypacObdFLe5= zFyd>j4+F_31fQnwF5QVnYKN=uE#23Yce}Wm-_zYFYA%+yVlb7T&d4QX2GgWZw=3?v0Jc@z8$%r*Cr?>Q6)PN^)# zozh%Pp8h24oa-n~XGs7F@6U)k>*Y%-Tv{xue25&bpCz<^JkiO+PoEIP6L=wP>7c>@ z8s2a3*aYB*bo+EJ6}&4AUw~XQFi+VK1g_#-KLU%-!f(9Y6t5c*B>cpk)}D0TnLOiB z_|f4B1la<9cN+i%9yX=(J)K9uY zsyVz{J)|pE{5Qaoa*NS=X2^({jAq|vCLr!Tc6H{4C&tC~T;O}N9=c5cmR%>`{I`tW z5E{%Q3G$&Az2HvJYYP7Vz2;Xt^HvmW1{VZhq9+#bi(}#>QtxbUS8syS9 z(@hDz^%)LEy);*G=rCAqqEL_0%8}0o_(PGj%t1?d|bx zdX?K6%DA%Tj4RvCo@&@a_=5k;CL3-h(IoO*7*X%*$zX{BqnSt$9>A=+cz3aL9#iG) zkjzw2d@x*CmhzUTga?$5n^&wbwrs;;h` zsoeMzHRtzAbpvd9S*K6+lqv6*OFy_Ka`)wP&2yps3>|e6H_)fktUdOTkLCs~p`xN! z;_Zj+`m4+A$t}u(aH-Zt&PY}NIT*zRJLh<(wGUPFUL<{ z8F36)PJ1f1iBztvor*C?C{$e9yI~eWGjiI14Mw817-+zKvRkdu<#SYl@YgE14*vCU zhzIdU>$-LN#U&^SBEsZ_#gGaD`S^f)-7f0wYb~xf1YfS5ewr#xfhAy!%m`}VRi8Cf z6n@MY8@B$sCzuvhNZy6WNPM1AfDiJ;(xBK0yyd;G_bZ^{K=vCz#=;007tF}GS^n~@fGFOARZXVM zhnaUs2qTbbyEgyirT}TFb&LVpEl#y;9yz+GR*Ty;hZC~^1(x7C6=?}NO@hXDkAD!4 zy)9WaXvu88GwPZn#=jO`9mS2Uz)YX61Rd+T(d%+Ym9|LW<2Rw1F=x`=4-vKDE4goJ z0%##f`qG?ug!X8qs*`65a6xksv$~NuqS@XdkmEy-Be+49j-o1w9zk*sn5GrCVwqt0Plh$7`ZCy{KXFO_&eJhNA73D!Ub}Bg5Pe8ek?Kb_B#1 zrtE^y6bmlkDJ{8w;QB0EZ9nHjJsjvNnrc&$dOK!gvpMdZ=3+Sif)Kj^!>!v=JLR=E z$yT|ewk^qW9A+ng2exd1$j=8k#*>CB)7Q?VZDuM6jtKI@U8O^)an9YU<9cMTz5pS6 zu2MA9q}B#8y(?er$CMUmg_b|1Ifnr{!L3bvk)S)_TMXAdcgj(LTZTz|AQFGj|84*j zG&-HA)mzY=3(*dd5abQ|QgwNVkdIz;xz%6x#d$4$B-9-i0fWfaR4>BZvI#A}Zn||! z(IXk?1lo|gZBlS{@P0C0? zTVe)@S<=)W5x5FujGvZps_3CS%(9c_WDgVRfyrnk2%dG?bYFK zX(op%4&+eCXCOf!|%)>hwq`JzQq>S$m`Cf~Dh!};S?~B|y0Y6uE<`i>Me{jjvC7X$* zk5-GuLKo^zSDO+uVsw5w?9y)bHH`{lW&@iwIxGonnu25lWOIb=L)YP(h}Y z<4?c+^Ign-h*w5d%CztaIW60?DfSRwPFoVFIdlpiJ_8#Vr;>y$@x*T z0^ z`Tf|Fo7E!v%eRSx4&w&+L;k5!6v)99us*g|&QT{-eJ7I~-huF&k32b;c+VKFJeZ0b z2n@4x)Bvxtl{`>{&+~~Iz~H78vn$A=r5XXybPXnt`xD5-d&W$UC^nxejcYKTGe2PQ zm`G$#A}}wC=cPe{*feP*Is#mm;TglcPSpr{ih;#z-Y-wcBp^i0o`rLME2xNoL+_-@5E+^bF& zq%?t38KB!}d!?@gPcMBc6BHeF*n@LO%gmK+Lq-Hnd3rlhMwvd9Tz&FMOck zgUjqR$QgOPezrjOs>ZZv4wB4!KpfVNfEmr-CWa!^n%iPpk324x=~V{Wc6v#@@7>ts zCFh$IvmRk(UO!vFLsjyi2l%9__r4uBqt1JOGi1tS{3Uxi6lNwfGh1&))i4=x4M{eR zji0wQ5Bk!gQs4BIK=OGDnn!|%k=>~^4B91K2VFMqNitkKa-T(GTMTuV>OIBmzMcOg zEAsbW{;R{q^rnSCzxb^9cRI9D<{+`Z`eKe}>(MM27l2ls`U`09IGxe!?IN61`;tL4TzVP^KK4V(GKg_~y>0Rk6jyh{=7_8RJ@_JQjI-11??#-i|>a-yG=|f#$8MxNU9| zS1T50jy?W^J$S*D3D-a)4UsTV)0+Oyi(w{E-SV|*G;UHFP1Ju;=(4PL2V@yDeN*8r z?FfV-?)8pCzRhPdLDl;sW3gY{z!HUu(ZY#q_%N*$FGgId{L7;TeFkZ`W@fd)j`q1N z0w~SV9b1q2-sm1xkiQw_sf9!DAPgLY1yz8|z>#9KLm?hN{6!Fqp7rmuf`A2?u*LX- z4wnI>&g!=88Haqb26SJmTZR)Y(RdD})J%hD-Q!k|8vH?deA!ZZdiyeC>f!)PxL2^1 zhB&TZLw(_=zGnvKeMmvSI`(`6I1ljm+b;Fs>?W9Yc3Kfkw$k@&$n2kHCOJeD+w0*L zxzhvLMjN)<`zYNqI#(aH)bfCw!_qCDnD^R?f-SJi|77pJ$#!-3V`Fpv#n)8NwjVsN zb@t(b#ay>6S67fg+_|7xI(o8YsO zkcPywLB%;(H`5nUh2H6IsvV(k(ktsUcSM>q11kQ6rh)$oF$q$|ak?&jA~0u{6q6!5 z!xejuy9`^AZUyQ3s7i1?h1dWMHI!@v9jGsbmDh-Yk1Jvg z@jd>sR&`Y)O3$})Kvp5OTu1;VL{(^1ef4oJk5iS*vCdx*ww4 z0)As0xx0M0!+OA-tmTDzGmKmbPDFnyzH{I!1YaM}l0%_V7;kDJtyZ2lMhU9#r13 z<&f>Nx74P6$T{Zk@rP+r!YW+C#C?QlC=^cz)b z8=FAre|Vlqjio$buwO$-aGrvSO)6eNw?zdscH-6$$FI_@7MyUK3oK`zSH%OmY3>y2 z3EaukHf}aUhfXrpyWO1H%cigK9pi@34uRnDUPmTHmnW>p^>(PW{BdP_?-J}tK55%r zDg%6*q6Nl(ADkE1E8116nl_CmiT-G$r__T>HHvuYCCIjQvlX$gh6Vv$PdRdPC+&tS zb0>vlh-VCvNN&k|&djONZl7)+NFOwC3#kFVMYrd`Kp=3T1m&zG@V(>Rn>)Tv9G6to z9p?6~$Tj)43s>AM27id4L7s1mr~@*+M23g%Nql#Cer0KDP%@tmm=VvO!8fNIK$aK* zFj^e)D18S2>i)R5i@eFLGbsDw3o1vrPYyQWGdaP(z8ftNKabBD0i$1v<90=w3mFI8 zi7H9{=DBm1&nY;NxIZ5DJg||F4hE{v%Ii@=WM>rdWOx+b&q(;7EuXiyB=w5pW|%^h zeFit(l~R9gbHZhEn(BonyMr1Yv+n|wJ`n>@REmH>@uRQ^Y6(uLZzE&@Z{s36hh?n8 zH)|@y?AsJFeBQwcV|*JHmf3#u%V6Z(Pj4E!O@0<&l{P`Sa_`NBFX30JiHw-pA?QB= zg2ZR7A(&B?I?m-EGX0+MT`tv&d2zz{0c=rsGsZqUzIb@pca$eAt5oF0lQ>87J4)WL z?|?mkE2uz~@XTIYq%%K1^!Mjn>13g1If>u(^2)82<*<%7HD-i2Tq5ItsyC#pAED`f z5s$`;kM0qa-5x%W;!a=kbJaifeuKRZ_ua{BM^xruESg5Ccpxx}o-|{8db_#knrFc4 zNU9zo!9ke)lyWMBhh{EdU+S2_I1_qC!$*?zEfzaYFZCnq+lYkh@o|fx%ffGD&b<;l zt~0JPZ{;jx7hR%7M}P5c{S+-^@U51P`pOl(K42g0-49B=jux%`S*_yZ_ne1|{-SCM zUov~&G~$w2V^;~IR*=12i9N7k#T=fvyDU&Kaw(GFsCl4q6MZ^hw|tB~HcZzidk<&i zJnXo;YE-C#Nh+wa&pYA+=lqaf74a2C2QIz6V1cO;1}+ zdBsvb$E$iZ#Aoxs6^{@BD4#bhAXhllLH-4rZ0tOmHd^Rbc$3F;%>f8U{*ahSL|$gT zGF}2NF~@=wO96Jr$&NM|KG}g_wd!Q*K2mnm1JuE}F96@WDocerkWjHvj#+O+clgF7 zoK$C*v4T9(GtvWjSgGYHk{rvZu1&5@^V^end2wU8VXp?WPtwEpMbto(+CKXbiSWW3 zdhc=jFgCXe=l$1Adx1!NU4C4$AC*W5tyq!duw6*G_v%n#XXV|oH`Ynk#CdLVr&Og$ zYiYF{Ydbcd;eN%lnN7~J2Ahr_Z!YTadsHgM6*bVg)}mW4EV7XOnJO0YOlW6mT!Zf3 zU6$W6MuikM88M4elAJ$h|7P25Jt-BcccZN*&&3$x()_5=Y$)>?=ltApm$c zE0j4qMhOVM%PfiN@nolF$eZ+ruA@GAZ1ysIM{T38IJWoQpAWexYA2~R7f+HcQ}GRZ zy7t&PKO^Tf4~^8=6$7>08=iS-CO;bsu~Rr<(r@s`tL}mqQjBGME*i)N85J9P##{ z>(+{gb_$9q)>)w&;-n4gklSA)ynx^}Qa@0Ym8U9go1fCf`83TpE8Q$oeeCM^Fpo_( zk6qytKh!-GeM}j6nvtp{jrCsCE4==KePj*umFbuA+8zu0_W&PL6Y_9v-jE26NO1&p z-g&)J{ER^_zp(QqW9qABct~47^%cc5+2)Yp`&-u-B}|kdJe^nfsc43xa+{ojPB)G@ zI=%LA#G%Rtzlu0AF?!8zBp=MUuR);g(c<}4P;P@$S9$9?g;FpEg}JR5-STpP5Z0wZ zGt7u;P_FCJqY11qgOQhuHzn7`mDJrMa>NKV?2UC(y+Fu)X*-Uqobe8;>jbxlnlnko zaM|ACyA431zGXgmq!^t(MPrPL1dJV1AT^9fxmG`Fyb0nH?Sfk}rfBt)1n(8?@YVIDl=?V9zd0~O|mkga0yLq!7^ zU1aWRSE049Hk1tS6gKNn!!gMNr!wxWHhQ6#-dFyP=q40ZlRW=)L*{W^*?{KWE~HAM@=DbvE#Wb%Xj4&r_%6A=$;Bxm29F8 zl&f?PsF0?6!~!!8>sDr}>tku#U)78TZ7x5lsVG@L>`xD~`(8>f zykc=q3C^cR@>X@E&@*t}=(=R{!4+F#>SJKq(RfX5oOWi=W~9Mw za}@Da#clJr+?*Q?O+)cfoDupqrRtS+wk`%!48gAfm3ASoecuGa%#+{!1>3-e645&~ zTv3zIk?tXKoUYJYZrhka+UjPJ5g+e99<*(ZUdv~9;C>Eg2M4#_!f=}LYD4_<$TcU1 zy_B}K5!)vxpQmW~Fe}P~J4HN*z|-8nb7%T=;!u~3}H zL?st<01>KkW7p<$%J|>oEnp^gX^NM(oW%Q1cVB0!PiVZ5t_Y^0y+dczFpawJL+A+I z@bFW4EQH@Ex6OiFdn`}y-cIKWOPla0^2r+;{w7WGBDTC%#C0>fnRPD*7G=jcDBlkt zU!binZ55Oi=pgo*_d={b8%p}f0ulml{wK`W)sw9`I47mia_ZZm3dJvSrD=PM#|G+# z3Q)ZD<^a0{nXL}-g`Da;L)Zm5PbAci4XZ}-$}fEbfo0HZGph9KICNs%<>VlVfWkH0 zg}kv}3U|et9?~7wt{ygtrj!c3I3LL9e%lyvtlYFHQ2jgI$>Gi&ZUyb?=<2w?yY>G> zmPVn#_Q+0mzAOkQQ0@T=(zA?tCq{opW{?9llj;XC&*aF)>z>-FFoya*4fRj)Ug*$D zI2VjVU+NSV*ojYJ07Spbrm8ta$1jrb@aL7A-)8#@zEP(IXeljk%)aljNapA)jYox? zGg>Ic3fQS)BJr_Mr1wOHL%Al2bj$!C`T}rtlbj!HR3-|x5$~N3gc(ZdD4>*Z zh6ld&N6go<2=m1SwHGVH=*rV)-;cE7!`?`a8!MQXr0yLX4@nZZUB2F{{9OY5R9bcm zJMFP+cE)s#QLn8JGd9Lxqn^GWF5Ljab$!Mh=B3`rQew)QBYQnVI1Yb#Jb8DY{LbTR zBki7=3lWv9e2l2Mx%jr`s0?OXcKKb?w$NlE-fy+UnTMqQ@AS|allr>$Kdq&OUb|i` zi|i`snjQb~)9FLTzfzZZ-g=8hDF`^578_n@xg!~Ij_ka<-Zn3-qg({<-x}bi&G>LR zA{2FA*q0F@;)Av;YwF;i(4;$iP;)0yNXY6@RJh=d+ux|zNoq<9p4h&rj4@ub0Nw7#%tsoHn~ zxzuFdtjq+T2R#;MD+H=&90S4HJ%oe=X^MZGLxWS&{_D=?TLv$Tdq$LByEnCQsx#fA z95@LYcVg3|cb-b!3kE{SbW9eJ9+o8AYCn@>zP9a5_IVKA^;?@2hPSU))hH()%q&my3rxsDh*iR>|MfZF^Pkh37p{)?TfV z);A!2q1e!x97-ezMRp~3rObm8c=Jf{&j!{|(+c}puUYn)Tx}W_xBmB=0Ne-c#~^nU@Be%g7DUFsy+b=Zkp)A|uO7$v zo5;UH(!oRA%j6q><{*B%Wk0rvwF#_ESO8m=CM*!iLe^%{(L$LZ#Kxkdxybh)Wrbnc z1O#dpd}Ptl0+B3)6N`=($^;=c79FwZ=ocVi#R;rn?H7u{GR%KRq%8$L+-z*?t&bc$ zfc@uSiDje_*5+3qSw{L7{0qkv%Siu%ix5&{QPZ!IWw4*I=;&AcgZLSXju48q@FR zdU*1`e)4zy0U7oVHq3tM Loj4e)Lb&>0Q&;O* literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2436x1125.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2436x1125.png new file mode 100644 index 0000000000000000000000000000000000000000..4e43260f104bcbf3fb518f4e28c7d33f40843181 GIT binary patch literal 88281 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2688x1242.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2688x1242.png new file mode 100644 index 0000000000000000000000000000000000000000..a4360a4123bcce624349daf334741f2bf343228a GIT binary patch literal 102979 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 X8za^y>csxfM_< literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2732x2048.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-2732x2048.png new file mode 100644 index 0000000000000000000000000000000000000000..8f31a8595b266beefcc900163387a36e70dc08c7 GIT binary patch literal 205972 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

  • BDQ_i&!4?{l8#_j;Yb&N*i0 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 literal 0 HcmV?d00001 diff --git a/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1620x2160.png b/docs/themes/hugo-geekdoc/static/favicon/apple-touch-startup-image-1620x2160.png new file mode 100644 index 0000000000000000000000000000000000000000..c8647135f89dfa4351dc1b5fd2e066d8b7d81140 GIT binary patch literal 139509 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

    + * Prometheus counters are faster than counters of other libraries. For example, incrementing a single counter + * without labels is more than 2 times faster (34752 ops / second) than doing the same with an OpenTelemetry + * counter (16634 ops / sec). */ public class CounterBenchmark { diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java index a0df74be7..dbcb9915a 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java @@ -27,7 +27,13 @@ * i.p.metrics.benchmarks.HistogramBenchmark.prometheusNative thrpt 25 3372.789 ± 339.328 ops/s * i.p.metrics.benchmarks.HistogramBenchmark.simpleclient thrpt 25 6488.252 ± 96.737 ops/s *
    + * The simpleclient (i.e. client_java version 0.16.0 and older) histograms perform about the same as + * the classic histogram of the current 1.0.0 version. + *

    + * Compared to OpenTelemetry histograms the Prometheus Java client histograms perform more than 3 times better + * (OpenTelemetry has 1908 ops / sec for classic histograms, while Prometheus has 6451 ops / sec). */ + public class HistogramBenchmark { @State(Scope.Benchmark) diff --git a/docs/content/config/_index.md b/docs/content/config/_index.md index 44a2e4e05..15545d2a8 100644 --- a/docs/content/config/_index.md +++ b/docs/content/config/_index.md @@ -1,4 +1,4 @@ --- title: Config -weight: 3 +weight: 4 --- diff --git a/docs/content/migration/_index.md b/docs/content/migration/_index.md index b749b91ee..cae50cc47 100644 --- a/docs/content/migration/_index.md +++ b/docs/content/migration/_index.md @@ -1,4 +1,4 @@ --- title: Compatibility -weight: 4 +weight: 5 --- From 3eca096f0b2930887221ef774b7439da4bac1547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 22:37:03 +0200 Subject: [PATCH 238/980] Move simpleclient to prometheus-metrics modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../pom.xml | 0 .../metrics/core/datapoints/TimerApi.java | 0 .../core/exemplars/ExemplarSampler.java | 0 .../core/exemplars/ExemplarSamplerConfig.java | 0 .../metrics/core/metrics}/CKMSQuantiles.java | 0 .../metrics/core/metrics}/Counter.java | 0 .../core/metrics/CounterWithCallback.java | 0 .../metrics/core/metrics}/Gauge.java | 0 .../core/metrics/GaugeWithCallback.java | 0 .../metrics/core/metrics}/Histogram.java | 0 .../metrics/core/metrics}/Info.java | 0 .../metrics/core/metrics/SlidingWindow.java | 0 .../metrics/core/metrics/StateSet.java | 0 .../metrics/core/metrics/StatefulMetric.java | 0 .../metrics/core/metrics}/Summary.java | 0 .../core/metrics/SummaryWithCallback.java | 0 .../metrics/core/datapoints/TimerApiTest.java | 0 .../core/exemplars/ExemplarSamplerTest.java | 0 .../core/metrics}/CKMSQuantilesTest.java | 0 .../metrics/core/metrics}/CounterTest.java | 0 .../core/metrics/CounterWithCallbackTest.java | 0 .../metrics/core/metrics}/GaugeTest.java | 0 .../core/metrics/GaugeWithCallbackTest.java | 0 .../metrics/core/metrics}/HistogramTest.java | 0 .../metrics/core/metrics}/InfoTest.java | 0 .../metrics/core/metrics/StateSetTest.java | 0 .../metrics/core/metrics}/SummaryTest.java | 0 .../core/metrics/SummaryWithCallbackTest.java | 0 .../metrics/model/registry}/Collector.java | 0 .../model/registry/MetricNameFilter.java | 0 .../model/registry/PrometheusRegistry.java | 0 .../metrics/model/snapshots}/Exemplar.java | 0 .../model/registry/MetricNameFilterTest.java | 0 .../registry/PrometheusRegistryTest.java | 0 .../model/snapshots/PrometheusNamingTest.java | 0 .../initializer/SpanContextSupplier.java | 0 .../io/prometheus/client/DoubleAdder.java | 267 ----------------- .../io/prometheus/client/Environment.java | 23 -- .../java/io/prometheus/client/Predicate.java | 8 - .../java/io/prometheus/client/Striped64.java | 283 ------------------ .../java/io/prometheus/client/Supplier.java | 8 - .../exemplars/CounterExemplarSampler.java | 15 - .../client/exemplars/ExemplarSampler.java | 8 - .../exemplars/HistogramExemplarSampler.java | 18 -- .../client/EmptyDescribableTest.java | 47 --- .../client/SimpleCollectorTest.java | 180 ----------- .../client/exemplars/ExemplarConfigTest.java | 178 ----------- .../client/exemplars/ExemplarTest.java | 186 ------------ simpleclient/version-rules.xml | 6 - 49 files changed, 1227 deletions(-) rename {simpleclient => prometheus-metrics-core}/pom.xml (100%) rename simpleclient/src/main/java/io/prometheus/client/SimpleTimer.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java (100%) rename simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java (100%) rename simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/CKMSQuantiles.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/Counter.java (100%) rename simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/Gauge.java (100%) rename simpleclient/src/main/java/io/prometheus/client/GaugeMetricFamily.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/Histogram.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/Info.java (100%) rename simpleclient/src/main/java/io/prometheus/client/TimeWindowQuantiles.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java (100%) rename simpleclient/src/main/java/io/prometheus/client/Enumeration.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java (100%) rename simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics}/Summary.java (100%) rename simpleclient/src/main/java/io/prometheus/client/SummaryMetricFamily.java => prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java (100%) rename simpleclient/src/test/java/io/prometheus/client/SimpleTimerTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/CKMSQuantilesTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/CounterTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/GaugeTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/GaugeMetricFamilyTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/HistogramTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/InfoTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java (100%) rename {simpleclient/src/test/java/io/prometheus/client => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics}/SummaryTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/SummaryMetricFamilyTest.java => prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java (100%) rename {simpleclient/src/main/java/io/prometheus/client => prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry}/Collector.java (100%) rename simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java => prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java (100%) rename simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java => prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java (100%) rename {simpleclient/src/main/java/io/prometheus/client/exemplars => prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots}/Exemplar.java (100%) rename simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java => prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java => prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java (100%) rename simpleclient/src/test/java/io/prometheus/client/CollectorTest.java => prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java (100%) rename simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java => prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java (100%) delete mode 100644 simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/Environment.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/Predicate.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/Striped64.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/Supplier.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java delete mode 100644 simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java delete mode 100644 simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java delete mode 100644 simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java delete mode 100644 simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java delete mode 100644 simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java delete mode 100644 simpleclient/version-rules.xml diff --git a/simpleclient/pom.xml b/prometheus-metrics-core/pom.xml similarity index 100% rename from simpleclient/pom.xml rename to prometheus-metrics-core/pom.xml diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleTimer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/SimpleTimer.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/exemplars/DefaultExemplarSampler.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarConfig.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/CKMSQuantiles.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Counter.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/CounterMetricFamily.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Gauge.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java diff --git a/simpleclient/src/main/java/io/prometheus/client/GaugeMetricFamily.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/GaugeMetricFamily.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Histogram.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Info.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java diff --git a/simpleclient/src/main/java/io/prometheus/client/TimeWindowQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/TimeWindowQuantiles.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Enumeration.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Enumeration.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java diff --git a/simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/SimpleCollector.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Summary.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Summary.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java diff --git a/simpleclient/src/main/java/io/prometheus/client/SummaryMetricFamily.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/SummaryMetricFamily.java rename to prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java diff --git a/simpleclient/src/test/java/io/prometheus/client/SimpleTimerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/SimpleTimerTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/exemplars/DefaultExemplarSamplerTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/CKMSQuantilesTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/CounterTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/CounterMetricFamilyTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/GaugeTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/GaugeMetricFamilyTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/GaugeMetricFamilyTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/HistogramTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/InfoTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/EnumerationTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/SummaryTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/SummaryMetricFamilyTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/SummaryMetricFamilyTest.java rename to prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java diff --git a/simpleclient/src/main/java/io/prometheus/client/Collector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/Collector.java rename to prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java diff --git a/simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/SampleNameFilter.java rename to prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java diff --git a/simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/CollectorRegistry.java rename to prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/exemplars/Exemplar.java rename to prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java diff --git a/simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/SampleNameFilterTest.java rename to prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/CollectorRegistryTest.java rename to prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java diff --git a/simpleclient/src/test/java/io/prometheus/client/CollectorTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java similarity index 100% rename from simpleclient/src/test/java/io/prometheus/client/CollectorTest.java rename to prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java similarity index 100% rename from simpleclient/src/main/java/io/prometheus/client/exemplars/Tracer.java rename to prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java diff --git a/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java b/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java deleted file mode 100644 index 8be7a6e26..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/DoubleAdder.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - * - * Source: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/DoubleAdder.java?revision=1.12 - */ - -package io.prometheus.client; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * One or more variables that together maintain an initially zero - * {@code double} sum. When updates (method {@link #add}) are - * contended across threads, the set of variables may grow dynamically - * to reduce contention. Method {@link #sum} (or, equivalently {@link - * #doubleValue}) returns the current total combined across the - * variables maintaining the sum. - * - *

    This class extends {@link Number}, but does not define - * methods such as {@code equals}, {@code hashCode} and {@code - * compareTo} because instances are expected to be mutated, and so are - * not useful as collection keys. - * - *

    jsr166e note: This class is targeted to be placed in - * java.util.concurrent.atomic. - * - * @since 1.8 - * @author Doug Lea - */ -public class DoubleAdder extends Striped64 implements Serializable { - private static final long serialVersionUID = 7249069246863182397L; - - /** - * Update function. Note that we must use "long" for underlying - * representations, because there is no compareAndSet for double, - * due to the fact that the bitwise equals used in any CAS - * implementation is not the same as double-precision equals. - * However, we use CAS only to detect and alleviate contention, - * for which bitwise equals works best anyway. In principle, the - * long/double conversions used here should be essentially free on - * most platforms since they just re-interpret bits. - * - * Similar conversions are used in other methods. - */ - final long fn(long v, long x) { - return Double.doubleToRawLongBits - (Double.longBitsToDouble(v) + - Double.longBitsToDouble(x)); - } - - /** - * Creates a new adder with initial sum of zero. - */ - public DoubleAdder() { - } - - /** - * Adds the given value. - * - * @param x the value to add - */ - public void add(double x) { - Cell[] as; long b, v; int[] hc; Cell a; int n; - if ((as = cells) != null || - !casBase(b = base, - Double.doubleToRawLongBits - (Double.longBitsToDouble(b) + x))) { - boolean uncontended = true; - if ((hc = threadHashCode.get()) == null || - as == null || (n = as.length) < 1 || - (a = as[(n - 1) & hc[0]]) == null || - !(uncontended = a.cas(v = a.value, - Double.doubleToRawLongBits - (Double.longBitsToDouble(v) + x)))) - retryUpdate(Double.doubleToRawLongBits(x), hc, uncontended); - } - } - - /** - * Returns the current sum. The returned value is NOT an - * atomic snapshot; invocation in the absence of concurrent - * updates returns an accurate result, but concurrent updates that - * occur while the sum is being calculated might not be - * incorporated. Also, because floating-point arithmetic is not - * strictly associative, the returned result need not be identical - * to the value that would be obtained in a sequential series of - * updates to a single variable. - * - * @return the sum - */ - public double sum() { - // On concurrent `sum` and `set`, it is acceptable to `get` an outdated `value`. - // On concurrent `sum` and `add`, it is acceptable to `get` an outdated `value`. - // On concurrent `sum` and `set` and `add`, it is possible to `get` an outdated `value`. - - // Correctness is guaranteed by `volatile` memory access ordering and visibility semantics. - // Program order: - // - writes in `set` - `busy` (CAS), `cells` (Wc), `base` (Wb), `busy` - // - reads in `sum` - `cells` (Rc), `base` (Rb), `busy`, `cells` (Cc), `base` (Cb) - // Note that: - // - `busy` is written after `cells` and `base` - // - `busy` is read after `cells` and `base`, then `cells` and `base` is re-read after `busy` - // In other words: - // - if we see the write to `busy`, then we must see the write to `cells` and `busy` on re-read - // - if we don't see the write to `busy`, then we must retry as we have no guarantees - // Execution order (in the former case): - // - serial - // - old result - Rc, Rb, Cc, Cb, Wc, Wb - // - new result - Wc, Wb, Rc, Rb, Cc, Cb - // - concurrent - // - old result - Rc, Wc, Rb, Wb, Cc, Cb - retry (superfluous) - // - new result - Wc, Rc, Wb, Rb, Cc, Cb - // - invalid result - Rc, Wc, Wb, Rb, Cc, Cb - retry - // - invalid result - Wc, Rc, Rb, Wb, Cc, Cb - retry - Cell[] as = cells; long b = base; - while (as != null && !(busy == 0 && cells == as && base == b)) { - // busy waiting, retry loop - Thread.yield(); - as = cells; b = base; - } - - double sum = Double.longBitsToDouble(b); - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - sum += Double.longBitsToDouble(a.value); - } - } - return sum; - } - - /** - * Resets variables maintaining the sum to zero. This method may - * be a useful alternative to creating a new adder, but is only - * effective if there are no concurrent updates. Because this - * method is intrinsically racy, it should only be used when it is - * known that no threads are concurrently updating. - */ - public void reset() { - internalReset(0L); - } - - public void set(double x) { - // On concurrent `set` and `set`, it should be acceptable to lose one `set` measurement. - // On concurrent `set` and `add`, it should be acceptable to lose the `add` measurement. - - // Correctness is ensured by different techniques: - // - `set` waits on contention (blocking) - // - `add` avoids contention (non-blocking) - // - `sum` retries on conflicts (non-blocking) - // Performance characteristics by use cases: - // - only `set` - `cells` is always `null` - no allocations - // - only `add` - `cells` allocated on contention - // - mixed `set` and `add` - `cells` allocated on contention, `cells` deallocated on `set` - for (;;) { - Cell[] as; - if ((as = cells) != null) { // have cells - if (busy == 0 && casBusy()) { - try { - if (cells == as) { // recheck under lock - // update cells and base (not atomic) - cells = null; - base = Double.doubleToLongBits(x); - break; - } - } finally { - busy = 0; - } - } - } else { // no cells - // update base (atomic) - base = Double.doubleToLongBits(x); - break; - } - } - } - - /** - * Equivalent in effect to {@link #sum} followed by {@link - * #reset}. This method may apply for example during quiescent - * points between multithreaded computations. If there are - * updates concurrent with this method, the returned value is - * not guaranteed to be the final value occurring before - * the reset. - * - * @return the sum - */ - public double sumThenReset() { - Cell[] as = cells; - double sum = Double.longBitsToDouble(base); - base = 0L; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) { - long v = a.value; - a.value = 0L; - sum += Double.longBitsToDouble(v); - } - } - } - return sum; - } - - /** - * Returns the String representation of the {@link #sum}. - * @return the String representation of the {@link #sum} - */ - public String toString() { - return Double.toString(sum()); - } - - /** - * Equivalent to {@link #sum}. - * - * @return the sum - */ - public double doubleValue() { - return sum(); - } - - /** - * Returns the {@link #sum} as a {@code long} after a - * narrowing primitive conversion. - */ - public long longValue() { - return (long)sum(); - } - - /** - * Returns the {@link #sum} as an {@code int} after a - * narrowing primitive conversion. - */ - public int intValue() { - return (int)sum(); - } - - /** - * Returns the {@link #sum} as a {@code float} - * after a narrowing primitive conversion. - */ - public float floatValue() { - return (float)sum(); - } - - private void writeObject(ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - s.writeDouble(sum()); - } - - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - s.defaultReadObject(); - busy = 0; - cells = null; - base = Double.doubleToRawLongBits(s.readDouble()); - } - -} diff --git a/simpleclient/src/main/java/io/prometheus/client/Environment.java b/simpleclient/src/main/java/io/prometheus/client/Environment.java deleted file mode 100644 index bc6393bcf..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/Environment.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.prometheus.client; - -import java.util.Arrays; -import java.util.List; - -class Environment { - - private static final String DISABLE_CREATED_SERIES = "PROMETHEUS_DISABLE_CREATED_SERIES"; - private static final List DISABLE_CREATED_SERIES_TRUE = Arrays.asList("true", "1", "t"); - private static final boolean includeCreatedSeries = !isTrue(DISABLE_CREATED_SERIES); - - static boolean includeCreatedSeries() { - return includeCreatedSeries; - } - - private static boolean isTrue(String envVarName) { - String stringValue = System.getenv(envVarName); - if (stringValue != null) { - return DISABLE_CREATED_SERIES_TRUE.contains(stringValue.toLowerCase()); - } - return false; - } -} diff --git a/simpleclient/src/main/java/io/prometheus/client/Predicate.java b/simpleclient/src/main/java/io/prometheus/client/Predicate.java deleted file mode 100644 index 6cbd83038..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/Predicate.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.prometheus.client; - -/** - * Replacement for Java 8's {@code java.util.function.Predicate} for compatibility with Java versions < 8. - */ -public interface Predicate { - boolean test(T t); -} \ No newline at end of file diff --git a/simpleclient/src/main/java/io/prometheus/client/Striped64.java b/simpleclient/src/main/java/io/prometheus/client/Striped64.java deleted file mode 100644 index 954210b1e..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/Striped64.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Written by Doug Lea with assistance from members of JCP JSR-166 - * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/publicdomain/zero/1.0/ - * - * Source: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.10 - */ - -package io.prometheus.client; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicLongFieldUpdater; - -/** - * A package-local class holding common representation and mechanics - * for classes supporting dynamic striping on 64bit values. The class - * extends Number so that concrete subclasses must publicly do so. - */ -abstract class Striped64 extends Number { - /* - * This class maintains a lazily-initialized table of atomically - * updated variables, plus an extra "base" field. The table size - * is a power of two. Indexing uses masked per-thread hash codes. - * Nearly all declarations in this class are package-private, - * accessed directly by subclasses. - * - * Table entries are of class Cell; a variant of AtomicLong padded - * to reduce cache contention on most processors. Padding is - * overkill for most Atomics because they are usually irregularly - * scattered in memory and thus don't interfere much with each - * other. But Atomic objects residing in arrays will tend to be - * placed adjacent to each other, and so will most often share - * cache lines (with a huge negative performance impact) without - * this precaution. - * - * In part because Cells are relatively large, we avoid creating - * them until they are needed. When there is no contention, all - * updates are made to the base field. Upon first contention (a - * failed CAS on base update), the table is initialized to size 2. - * The table size is doubled upon further contention until - * reaching the nearest power of two greater than or equal to the - * number of CPUS. Table slots remain empty (null) until they are - * needed. - * - * A single spinlock ("busy") is used for initializing and - * resizing the table, as well as populating slots with new Cells. - * There is no need for a blocking lock; when the lock is not - * available, threads try other slots (or the base). During these - * retries, there is increased contention and reduced locality, - * which is still better than alternatives. - * - * Per-thread hash codes are initialized to random values. - * Contention and/or table collisions are indicated by failed - * CASes when performing an update operation (see method - * retryUpdate). Upon a collision, if the table size is less than - * the capacity, it is doubled in size unless some other thread - * holds the lock. If a hashed slot is empty, and lock is - * available, a new Cell is created. Otherwise, if the slot - * exists, a CAS is tried. Retries proceed by "double hashing", - * using a secondary hash (Marsaglia XorShift) to try to find a - * free slot. - * - * The table size is capped because, when there are more threads - * than CPUs, supposing that each thread were bound to a CPU, - * there would exist a perfect hash function mapping threads to - * slots that eliminates collisions. When we reach capacity, we - * search for this mapping by randomly varying the hash codes of - * colliding threads. Because search is random, and collisions - * only become known via CAS failures, convergence can be slow, - * and because threads are typically not bound to CPUS forever, - * may not occur at all. However, despite these limitations, - * observed contention rates are typically low in these cases. - * - * It is possible for a Cell to become unused when threads that - * once hashed to it terminate, as well as in the case where - * doubling the table causes no thread to hash to it under - * expanded mask. We do not try to detect or remove such cells, - * under the assumption that for long-running instances, observed - * contention levels will recur, so the cells will eventually be - * needed again; and for short-lived ones, it does not matter. - */ - - /** - * Padded variant of AtomicLong supporting only raw accesses plus CAS. - * The value field is placed between pads, hoping that the JVM doesn't - * reorder them. - * - * JVM intrinsics note: It would be possible to use a release-only - * form of CAS here, if it were provided. - */ - static final class Cell { - volatile long p0, p1, p2, p3, p4, p5, p6; - volatile long value; - volatile long q0, q1, q2, q3, q4, q5, q6; - Cell(long x) { value = x; } - - final boolean cas(long cmp, long val) { - return CAS_VALUE.compareAndSet(this, cmp, val); - } - - private static final AtomicLongFieldUpdater CAS_VALUE = AtomicLongFieldUpdater.newUpdater(Cell.class, "value"); - - } - - /** - * ThreadLocal holding a single-slot int array holding hash code. - * Unlike the JDK8 version of this class, we use a suboptimal - * int[] representation to avoid introducing a new type that can - * impede class-unloading when ThreadLocals are not removed. - */ - static final ThreadLocal threadHashCode = new ThreadLocal(); - - /** - * Generator of new random hash codes - */ - static final Random rng = new Random(); - - /** Number of CPUS, to place bound on table size */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); - - /** - * Table of cells. When non-null, size is a power of 2. - */ - transient volatile Cell[] cells; - - /** - * Base value, used mainly when there is no contention, but also as - * a fallback during table initialization races. Updated via CAS. - */ - transient volatile long base; - - /** - * Spinlock (locked via CAS) used when resizing and/or creating Cells. - */ - transient volatile int busy; - - /** - * Package-private default constructor - */ - Striped64() { - } - - /** - * CASes the base field. - */ - final boolean casBase(long cmp, long val) { - return CAS_BASE.compareAndSet(this, cmp, val); - } - - /** - * CASes the busy field from 0 to 1 to acquire lock. - */ - final boolean casBusy() { - return CAS_BUSY.compareAndSet(this, 0, 1); - } - - /** - * Computes the function of current and new value. Subclasses - * should open-code this update function for most uses, but the - * virtualized form is needed within retryUpdate. - * - * @param currentValue the current value (of either base or a cell) - * @param newValue the argument from a user update call - * @return result of the update function - */ - abstract long fn(long currentValue, long newValue); - - /** - * Handles cases of updates involving initialization, resizing, - * creating new Cells, and/or contention. See above for - * explanation. This method suffers the usual non-modularity - * problems of optimistic retry code, relying on rechecked sets of - * reads. - * - * @param x the value - * @param hc the hash code holder - * @param wasUncontended false if CAS failed before call - */ - final void retryUpdate(long x, int[] hc, boolean wasUncontended) { - int h; - if (hc == null) { - threadHashCode.set(hc = new int[1]); // Initialize randomly - int r = rng.nextInt(); // Avoid zero to allow xorShift rehash - h = hc[0] = (r == 0) ? 1 : r; - } - else - h = hc[0]; - boolean collide = false; // True if last slot nonempty - for (;;) { - Cell[] as; Cell a; int n; long v; - if ((as = cells) != null && (n = as.length) > 0) { - if ((a = as[(n - 1) & h]) == null) { - if (busy == 0) { // Try to attach new Cell - Cell r = new Cell(x); // Optimistically create - if (busy == 0 && casBusy()) { - boolean created = false; - try { // Recheck under lock - Cell[] rs; int m, j; - if ((rs = cells) != null && - (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { - rs[j] = r; - created = true; - } - } finally { - busy = 0; - } - if (created) - break; - continue; // Slot is now non-empty - } - } - collide = false; - } - else if (!wasUncontended) // CAS already known to fail - wasUncontended = true; // Continue after rehash - else if (a.cas(v = a.value, fn(v, x))) - break; - else if (n >= NCPU || cells != as) - collide = false; // At max size or stale - else if (!collide) - collide = true; - else if (busy == 0 && casBusy()) { - try { - if (cells == as) { // Expand table unless stale - Cell[] rs = new Cell[n << 1]; - for (int i = 0; i < n; ++i) - rs[i] = as[i]; - cells = rs; - } - } finally { - busy = 0; - } - collide = false; - continue; // Retry with expanded table - } - h ^= h << 13; // Rehash - h ^= h >>> 17; - h ^= h << 5; - hc[0] = h; // Record index for next time - } - else if (busy == 0 && cells == as && casBusy()) { - boolean init = false; - try { // Initialize table - if (cells == as) { - Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); - cells = rs; - init = true; - } - } finally { - busy = 0; - } - if (init) - break; - } - else if (casBase(v = base, fn(v, x))) - break; // Fall back on using base - } - } - - - /** - * Sets base and all cells to the given value. - */ - final void internalReset(long initialValue) { - Cell[] as = cells; - base = initialValue; - if (as != null) { - int n = as.length; - for (int i = 0; i < n; ++i) { - Cell a = as[i]; - if (a != null) - a.value = initialValue; - } - } - } - - private static final AtomicLongFieldUpdater CAS_BASE = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base"); - private static final AtomicIntegerFieldUpdater CAS_BUSY = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy"); - -} diff --git a/simpleclient/src/main/java/io/prometheus/client/Supplier.java b/simpleclient/src/main/java/io/prometheus/client/Supplier.java deleted file mode 100644 index 3eb766ea0..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/Supplier.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.prometheus.client; - -/** - * Replacement for Java 8's {@code java.util.function.Supplier} for compatibility with Java versions < 8. - */ -public interface Supplier { - T get(); -} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java deleted file mode 100644 index 81ab4e9d4..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/CounterExemplarSampler.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.prometheus.client.exemplars; - -/** - * Exemplar sampler for counter metrics. - */ -public interface CounterExemplarSampler { - - /** - * @param increment the value added to the counter on this event - * @param previous the previously sampled exemplar, or {@code null} if there is none. - * @return an Exemplar to be sampled, or {@code null} if the previous exemplar does not need to be updated. - * Returning {@code null} and returning {@code previous} is equivalent. - */ - Exemplar sample(double increment, Exemplar previous); -} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java deleted file mode 100644 index 39ff34c26..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/ExemplarSampler.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.prometheus.client.exemplars; - -/** - * For convenience, an interface for implementing both, - * the {@link CounterExemplarSampler} and the {@link HistogramExemplarSampler}. - */ -public interface ExemplarSampler extends CounterExemplarSampler, HistogramExemplarSampler { -} diff --git a/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java b/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java deleted file mode 100644 index 03d300112..000000000 --- a/simpleclient/src/main/java/io/prometheus/client/exemplars/HistogramExemplarSampler.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.prometheus.client.exemplars; - -/** - * Exemplar sampler for histogram metrics. - */ -public interface HistogramExemplarSampler { - /** - * @param value the value to be observed. - * @param bucketFrom upper boundary of the previous bucket in the histogram. - * Will be {@link Double#NEGATIVE_INFINITY} if there is no previous bucket. - * @param bucketTo upper boundary of this histogram bucket. - * Will be {@link Double#POSITIVE_INFINITY} if this is the last bucket. - * @param previous the previously sampled exemplar, or {@code null} if there is none. - * @return an Exemplar to be sampled, or {@code null} if the previous exemplar does not need to be updated. - * Returning {@code null} and returning {@code previous} is equivalent. - */ - Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous); -} diff --git a/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java b/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java deleted file mode 100644 index bdff0dac1..000000000 --- a/simpleclient/src/test/java/io/prometheus/client/EmptyDescribableTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.prometheus.client; - -import org.junit.Test; - -import java.util.*; - -import static org.junit.Assert.assertEquals; - -public class EmptyDescribableTest { - - static class TestCollector extends Collector implements Collector.Describable { - - private final List describeResult; - - TestCollector(List describeResult) { - this.describeResult = describeResult; - } - - @Override - public List collect() { - List labelNames = Arrays.asList("label1", "label2"); - List labelValues1 = Arrays.asList("a", "b"); - List labelValues2 = Arrays.asList("c", "d"); - List samples = new ArrayList(2); - samples.add(new MetricFamilySamples.Sample("my_metric", labelNames, labelValues1, 1.0)); - samples.add(new MetricFamilySamples.Sample("my_metric", labelNames, labelValues2, 2.0)); - MetricFamilySamples mfs = new MetricFamilySamples("my_metric", "", Type.UNKNOWN, "help text", samples); - return Collections.singletonList(mfs); - } - - @Override - public List describe() { - return describeResult; - } - } - - @Test - public void testEmptyDescribe() { - CollectorRegistry registry = new CollectorRegistry(); - TestCollector collector = new TestCollector(new ArrayList()); - collector.register(registry); - Set includedNames = new HashSet(Collections.singletonList("my_metric")); - List mfs = Collections.list(registry.filteredMetricFamilySamples(includedNames)); - assertEquals(1, mfs.size()); - assertEquals(2, mfs.get(0).samples.size()); - } -} diff --git a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java b/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java deleted file mode 100644 index 74b01db52..000000000 --- a/simpleclient/src/test/java/io/prometheus/client/SimpleCollectorTest.java +++ /dev/null @@ -1,180 +0,0 @@ -package io.prometheus.client; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.junit.rules.ExpectedException.none; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.Before; -import org.junit.rules.ExpectedException; - - -public class SimpleCollectorTest { - - CollectorRegistry registry; - Gauge metric; - Gauge noLabels; - - @Rule - public final ExpectedException thrown = none(); - - @Before - public void setUp() { - registry = new CollectorRegistry(); - metric = Gauge.build().name("labels").help("help").labelNames("l").register(registry); - noLabels = Gauge.build().name("nolabels").help("help").register(registry); - } - - private Double getValue(String labelValue) { - return registry.getSampleValue("labels", new String[]{"l"}, new String[]{labelValue}); - } - - private Double getValueNoLabels() { - return registry.getSampleValue("nolabels"); - } - - @Test - public void testTooFewLabelsThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Incorrect number of labels."); - metric.labels(); - } - - @Test - public void testNullLabelThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Label cannot be null."); - metric.labels(new String[]{null}); - } - - @Test - public void testTooManyLabelsThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Incorrect number of labels."); - metric.labels("a", "b"); - } - - @Test - public void testRemove() { - metric.labels("a"); - assertNotNull(getValue("a")); - assertNull(getValue("b")); - metric.labels("b").set(7); - assertNotNull(getValue("a")); - assertNotNull(getValue("b")); - metric.remove("b"); - assertNotNull(getValue("a")); - assertNull(getValue("b")); - - // Brand new Child. - metric.labels("b").inc(); - assertEquals(1.0, getValue("b").doubleValue(), .001); - } - - @Test - public void testNoLabelsWorkAfterRemove() { - noLabels.inc(1); - assertEquals(getValueNoLabels(), 1.0, .001); - noLabels.remove(); - noLabels.inc(2); - assertEquals(getValueNoLabels(), 2.0, .001); - } - - @Test - public void testClear() { - assertNull(getValue("a")); - metric.labels("a").set(7); - assertNotNull(getValue("a")); - metric.clear(); - assertNull(getValue("a")); - - // Brand new Child. - metric.labels("a").inc(); - assertEquals(1.0, getValue("a").doubleValue(), .001); - } - - @Test - public void testNoLabelsWorkAfterClear() { - noLabels.inc(1); - assertEquals(getValueNoLabels(), 1.0, .001); - noLabels.clear(); - noLabels.inc(2); - assertEquals(getValueNoLabels(), 2.0, .001); - } - - @Test - public void testNameIsConcatenated() { - assertEquals("a_b_c", Gauge.build().name("c").subsystem("b").namespace("a").help("h").create().fullname); - } - - @Test - public void testNameIsRequired() { - thrown.expect(IllegalStateException.class); - thrown.expectMessage("Name hasn't been set."); - Gauge.build().help("h").create(); - } - - @Test - public void testHelpIsRequired() { - thrown.expect(IllegalStateException.class); - thrown.expectMessage("Help hasn't been set."); - Gauge.build().name("c").create(); - } - - @Test - public void testInvalidNameThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Invalid metric name: c'a"); - Gauge.build().name("c'a").create(); - } - - @Test - public void testInvalidLabelNameThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Invalid metric label name: c:d"); - Gauge.build().name("a").labelNames("c:d").help("h").create(); - } - - @Test - public void testReservedLabelNameThrows() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage( - "Invalid metric label name, reserved for internal use: __name__"); - Gauge.build().name("a").labelNames("__name__").help("h").create(); - } - - @Test - public void testUnitsAdded() { - Gauge g = Gauge.build().name("a").unit("seconds").help("h").create(); - assertEquals("a_seconds", g.fullname); - - Gauge g2 = Gauge.build().name("a_seconds").unit("seconds").help("h").create(); - assertEquals("a_seconds", g2.fullname); - } - - @Test - public void testSetChild() { - metric.setChild(new Gauge.Child(){ - public double get() { - return 42; - } - }, "a"); - assertEquals(42.0, getValue("a").doubleValue(), .001); - } - - @Test - public void testSetChildReturnsGauge() { - Gauge g = metric.setChild(new Gauge.Child(){ - public double get() { - return 42; - } - }, "a"); - } - - @Test - public void testCreateReturnsGauge() { - Gauge g = Gauge.build().name("labels").help("help").labelNames("l").create(); - } -} diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java deleted file mode 100644 index 0d197bac0..000000000 --- a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarConfigTest.java +++ /dev/null @@ -1,178 +0,0 @@ -package io.prometheus.client.exemplars; - -import io.prometheus.client.Counter; -import io.prometheus.client.Histogram; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class ExemplarConfigTest { - - private boolean origEnabled; - private CounterExemplarSampler origCounterExemplarSampler; - private HistogramExemplarSampler origHistogramExemplarSampler; - - private TestExemplarSampler defaultSampler; - private TestExemplarSampler customSampler; - - @Before - public void setUp() { - origEnabled = ExemplarConfig.isExemplarsEnabled(); - origCounterExemplarSampler = ExemplarConfig.getCounterExemplarSampler(); - origHistogramExemplarSampler = ExemplarConfig.getHistogramExemplarSampler(); - - defaultSampler = new TestExemplarSampler(); - customSampler = new TestExemplarSampler(); - ExemplarConfig.enableExemplars(); - ExemplarConfig.setCounterExemplarSampler(defaultSampler); - ExemplarConfig.setHistogramExemplarSampler(defaultSampler); - } - - @After - public void tearDown() { - ExemplarConfig.setCounterExemplarSampler(origCounterExemplarSampler); - ExemplarConfig.setHistogramExemplarSampler(origHistogramExemplarSampler); - if (origEnabled) { - ExemplarConfig.enableExemplars(); - } else { - ExemplarConfig.disableExemplars(); - } - } - - private static class TestExemplarSampler implements ExemplarSampler { - - private boolean called = false; - - @Override - public Exemplar sample(double increment, Exemplar previous) { - called = true; - return null; - } - - @Override - public Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous) { - called = true; - return null; - } - } - - @Test - public void testCounterWithExemplarSampler() { - Counter counter = Counter.build() - .withExemplarSampler(customSampler) - .name("test") - .help("help") - .create(); - counter.inc(3); - Assert.assertTrue(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testCounterWithoutExemplars() { - Counter counter = Counter.build() - .withoutExemplars() - .name("test") - .help("help") - .create(); - counter.inc(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testCounterWithExemplars() { - ExemplarConfig.disableExemplars(); - Counter counter = Counter.build() - .withExemplars() - .name("test") - .help("help") - .create(); - counter.inc(3); - Assert.assertFalse(customSampler.called); - Assert.assertTrue(defaultSampler.called); - } - - @Test - public void testCounterDefaultDisabled() { - ExemplarConfig.disableExemplars(); - Counter counter = Counter.build() - .name("test") - .help("help") - .create(); - counter.inc(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testCounterIncWithExemplar() { - Counter counter = Counter.build() - .name("test") - .help("help") - .create(); - counter.incWithExemplar(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testHistogramWithExemplarSampler() { - Histogram histogram = Histogram.build() - .withExemplarSampler(customSampler) - .name("test") - .help("help") - .create(); - histogram.observe(3); - Assert.assertTrue(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testHistogramWithoutExemplars() { - Histogram histogram = Histogram.build() - .withoutExemplars() - .name("test") - .help("help") - .create(); - histogram.observe(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - - @Test - public void testHistogramWithExemplars() { - ExemplarConfig.disableExemplars(); - Histogram histogram = Histogram.build() - .withExemplars() - .name("test") - .help("help") - .create(); - histogram.observe(3); - Assert.assertFalse(customSampler.called); - Assert.assertTrue(defaultSampler.called); - } - - @Test - public void testHistogramDefaultDisabled() { - ExemplarConfig.disableExemplars(); - Histogram histogram = Histogram.build() - .name("test") - .help("help") - .create(); - histogram.observe(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } - @Test - public void testHistogramObserveWithExemplar() { - Histogram histogram = Histogram.build() - .name("test") - .help("help") - .create(); - histogram.observeWithExemplar(3); - Assert.assertFalse(customSampler.called); - Assert.assertFalse(defaultSampler.called); - } -} diff --git a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java b/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java deleted file mode 100644 index a7960aa8a..000000000 --- a/simpleclient/src/test/java/io/prometheus/client/exemplars/ExemplarTest.java +++ /dev/null @@ -1,186 +0,0 @@ -package io.prometheus.client.exemplars; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; - -public class ExemplarTest { - - private final String SPAN_ID = "span_id"; - private final String TRACE_ID = "trace_id"; - - @Test - public void testCompleteExemplar() { - double value = 42; - long timestamp = System.currentTimeMillis(); - String traceId = "abc"; - String spanId = "def"; - Exemplar exemplar = new Exemplar(value, timestamp, SPAN_ID, spanId, TRACE_ID, traceId); - Assert.assertEquals(42, exemplar.getValue(), 0.001); - Assert.assertEquals(timestamp, exemplar.getTimestampMs().longValue()); - Assert.assertEquals(2, exemplar.getNumberOfLabels()); - Assert.assertEquals(SPAN_ID, exemplar.getLabelName(0)); - Assert.assertEquals(spanId, exemplar.getLabelValue(0)); - Assert.assertEquals(TRACE_ID, exemplar.getLabelName(1)); - Assert.assertEquals(traceId, exemplar.getLabelValue(1)); - } - - @Test - public void testNoTimestamp() { - double value = 42; - String traceId = "abc"; - String spanId = "def"; - Exemplar exemplar = new Exemplar(value, SPAN_ID, spanId, TRACE_ID, traceId); - Assert.assertEquals(42, exemplar.getValue(), 0.001); - Assert.assertNull(exemplar.getTimestampMs()); - Assert.assertEquals(2, exemplar.getNumberOfLabels()); - Assert.assertEquals(SPAN_ID, exemplar.getLabelName(0)); - Assert.assertEquals(spanId, exemplar.getLabelValue(0)); - Assert.assertEquals(TRACE_ID, exemplar.getLabelName(1)); - Assert.assertEquals(traceId, exemplar.getLabelValue(1)); - } - - @Test - public void testNoLabels() { - double value = 42; - long timestamp = System.currentTimeMillis(); - Exemplar exemplar = new Exemplar(value, timestamp); - Assert.assertEquals(42, exemplar.getValue(), 0.001); - Assert.assertEquals(timestamp, exemplar.getTimestampMs().longValue()); - Assert.assertEquals(0, exemplar.getNumberOfLabels()); - } - - @Test - public void testMissingLabelValue() { - try { - new Exemplar(42, TRACE_ID); - } catch (IllegalArgumentException e) { - return; - } - Assert.fail("expected IllegalArgumentException"); - } - - @Test - public void testNullLabelValue() { - try { - new Exemplar(42, TRACE_ID, null); - } catch (IllegalArgumentException e) { - return; - } - Assert.fail("expected IllegalArgumentException"); - } - - @Test - public void testMaxLabelLength() { - String eight = "_2345678"; - String ten = "_234567890"; - String twenty = ten + ten; - String thirty = twenty + ten; - String forty = thirty + ten; - new Exemplar(42, ten, twenty, thirty, forty, eight, twenty); // 128 chars total - try { - new Exemplar(42, ten, twenty, thirty, forty, eight, twenty + "1"); // 129 chars total - } catch (IllegalArgumentException e) { - return; - } - Assert.fail("expected IllegalArgumentException"); - } - - @Test - public void testSortedLabels() { - Exemplar exemplar = new Exemplar(42, "name4", "value4", "name3", "value3", - "name2", "value2", "name5", "value5", "name1", "value1"); - Assert.assertEquals(5, exemplar.getNumberOfLabels()); - for (int i=0; i map = new TreeMap(); - map.put("label1", "value1"); - map.put("label2", "value2"); - Exemplar e = new Exemplar(3, map); - Assert.assertEquals(3, e.getValue(), 0.001); - Assert.assertNull(e.getTimestampMs()); - Assert.assertEquals(2, e.getNumberOfLabels()); - Assert.assertEquals("label1", e.getLabelName(0)); - Assert.assertEquals("value1", e.getLabelValue(0)); - Assert.assertEquals("label2", e.getLabelName(1)); - Assert.assertEquals("value2", e.getLabelValue(1)); - } - - @Test - public void testEmptyLabelMap() { - Map map = new HashMap(); - long timestamp = System.currentTimeMillis(); - Exemplar e = new Exemplar(3, timestamp, map); - Assert.assertEquals(3, e.getValue(), 0.001); - Assert.assertEquals(timestamp, e.getTimestampMs().longValue()); - Assert.assertEquals(0, e.getNumberOfLabels()); - } -} diff --git a/simpleclient/version-rules.xml b/simpleclient/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file From 5ba957e24a2ba555243923e3d5b1f3fe427abe1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 24 Sep 2023 22:51:42 +0200 Subject: [PATCH 239/980] Move simpleclient_common to prometheus-metrics modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../pom.xml | 0 .../OpenMetricsTextFormatWriter.java | 0 .../ExpositionFormatsTest.java | 0 .../client/exporter/common/ExemplarTest.java | 391 ------------------ .../exporter/common/TextFormatTest.java | 244 ----------- simpleclient_common/version-rules.xml | 6 - 6 files changed, 641 deletions(-) rename {simpleclient_common => prometheus-metrics-exposition-formats}/pom.xml (100%) rename simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java => prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java (100%) rename simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java => prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java (100%) delete mode 100644 simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java delete mode 100644 simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java delete mode 100644 simpleclient_common/version-rules.xml diff --git a/simpleclient_common/pom.xml b/prometheus-metrics-exposition-formats/pom.xml similarity index 100% rename from simpleclient_common/pom.xml rename to prometheus-metrics-exposition-formats/pom.xml diff --git a/simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java similarity index 100% rename from simpleclient_common/src/main/java/io/prometheus/client/exporter/common/TextFormat.java rename to prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java similarity index 100% rename from simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatOpenMetricsTest.java rename to prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java deleted file mode 100644 index 2ab2821f9..000000000 --- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/ExemplarTest.java +++ /dev/null @@ -1,391 +0,0 @@ -package io.prometheus.client.exporter.common; - -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Counter; -import io.prometheus.client.Gauge; -import io.prometheus.client.Histogram; -import io.prometheus.client.Summary; -import io.prometheus.client.exemplars.CounterExemplarSampler; -import io.prometheus.client.exemplars.Exemplar; -import io.prometheus.client.exemplars.ExemplarConfig; -import io.prometheus.client.exemplars.HistogramExemplarSampler; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.io.StringWriter; - -public class ExemplarTest { - - private final String defaultTraceId = "default-trace-id"; - private final String defaultSpanId = "default-span-id"; - private final String customTraceId = "custom-trace-id"; - private final String customSpanId = "custom-span-id"; - private final String defaultExemplarLabels = "{span_id=\"" + defaultSpanId + "\",trace_id=\"" + defaultTraceId + "\"}"; - private final String customExemplarLabels = "{span_id=\"" + customSpanId + "\",trace_id=\"" + customTraceId + "\"}"; - private final long timestamp = System.currentTimeMillis(); - - private CollectorRegistry registry; - - private final CounterExemplarSampler origCounterExemplarSampler = ExemplarConfig.getCounterExemplarSampler(); - private final HistogramExemplarSampler origHistogramExemplarSampler = ExemplarConfig.getHistogramExemplarSampler(); - - @Before - public void setUp() { - registry = new CollectorRegistry(); - TestExemplarSampler defaultExemplarSampler = new TestExemplarSampler(defaultTraceId, defaultSpanId, timestamp); - ExemplarConfig.setCounterExemplarSampler(defaultExemplarSampler); - ExemplarConfig.setHistogramExemplarSampler(defaultExemplarSampler); - } - - @After - public void tearDown() { - ExemplarConfig.setCounterExemplarSampler(origCounterExemplarSampler); - ExemplarConfig.setHistogramExemplarSampler(origHistogramExemplarSampler); - } - - @Test - public void testCounterNoLabelsDefaultExemplar() throws IOException { - Counter noLabelsDefaultExemplar = Counter.build() - .name("no_labels_default_exemplar") - .help("help") - .register(registry); - noLabelsDefaultExemplar.inc(3); - assertOpenMetrics100Format("no_labels_default_exemplar_total 3.0 # " + defaultExemplarLabels + " 3.0 " + timestampString() + "\n"); - assert004Format("no_labels_default_exemplar_total 3.0\n"); - noLabelsDefaultExemplar.inc(2); - // The TestExemplarSampler always produces a new Exemplar. - // The Exemplar with value 3.0 should be replaced with an Exemplar with value 2.0. - assertOpenMetrics100Format("no_labels_default_exemplar_total 5.0 # " + defaultExemplarLabels + " 2.0 " + timestampString() + "\n"); - assert004Format("no_labels_default_exemplar_total 5.0\n"); - } - - @Test - public void testCounterLabelsDefaultExemplar() throws IOException { - Counter labelsDefaultExemplar = Counter.build() - .name("labels_default_exemplar") - .help("help") - .labelNames("label") - .register(registry); - labelsDefaultExemplar.labels("test").inc(); - assertOpenMetrics100Format("labels_default_exemplar_total{label=\"test\"} 1.0 # " + defaultExemplarLabels + " 1.0 " + timestampString() + "\n"); - assert004Format("labels_default_exemplar_total{label=\"test\",} 1.0\n"); - } - - @Test - public void testCounterNoLabelsNoExemplar() throws IOException { - Counter noLabelsNoExemplar = Counter.build() - .name("no_labels_no_exemplar") - .help("help") - .withoutExemplars() - .register(registry); - noLabelsNoExemplar.inc(); - assertOpenMetrics100Format("no_labels_no_exemplar_total 1.0\n"); - assert004Format("no_labels_no_exemplar_total 1.0\n"); - } - - @Test - public void testCounterLabelsNoExemplar() throws IOException { - Counter labelsNoExemplar = Counter.build() - .name("labels_no_exemplar") - .help("help") - .labelNames("label") - .withoutExemplars() - .register(registry); - labelsNoExemplar.labels("test").inc(); - assertOpenMetrics100Format("labels_no_exemplar_total{label=\"test\"} 1.0\n"); - assert004Format("labels_no_exemplar_total{label=\"test\",} 1.0\n"); - } - - @Test - public void testCounterNoLabelsCustomExemplar() throws IOException { - Counter noLabelsCustomExemplar = Counter.build() - .name("no_labels_custom_exemplar") - .help("help") - .withExemplarSampler(new TestExemplarSampler(customTraceId, customSpanId, timestamp)) - .register(registry); - noLabelsCustomExemplar.inc(); - assertOpenMetrics100Format("no_labels_custom_exemplar_total 1.0 # " + customExemplarLabels + " 1.0 " + timestampString() + "\n"); - assert004Format("no_labels_custom_exemplar_total 1.0\n"); - } - - @Test - public void testCounterLabelsCustomExemplar() throws IOException { - Counter labelsCustomExemplar = Counter.build() - .name("labels_custom_exemplar") - .help("help") - .withExemplarSampler(new TestExemplarSampler(customTraceId, customSpanId, timestamp)) - .labelNames("label") - .register(registry); - labelsCustomExemplar.labels("test").inc(); - assertOpenMetrics100Format("labels_custom_exemplar_total{label=\"test\"} 1.0 # " + customExemplarLabels + " 1.0 " + timestampString() + "\n"); - assert004Format("labels_custom_exemplar_total{label=\"test\",} 1.0\n"); - } - - @Test - public void testGaugeNoLabels() throws IOException { - Gauge noLabelsDefaultExemplar = Gauge.build() - .name("no_labels_default_exemplar") - .help("help") - .register(registry); - noLabelsDefaultExemplar.set(37); - // Gauges do not have Exemplars according to the OpenMetrics spec. - // Make sure there are no Exemplars. - assertOpenMetrics100Format("no_labels_default_exemplar 37.0\n"); - assert004Format("no_labels_default_exemplar 37.0\n"); - } - - @Test - public void testGaugeLabels() throws IOException { - Gauge labelsDefaultExemplar = Gauge.build() - .name("labels_default_exemplar") - .help("help") - .labelNames("label") - .register(registry); - labelsDefaultExemplar.labels("test").inc(); - // Gauges do not have Exemplars according to the OpenMetrics spec. - // Make sure there are no Exemplars. - assertOpenMetrics100Format("labels_default_exemplar{label=\"test\"} 1.0\n"); - assert004Format("labels_default_exemplar{label=\"test\",} 1.0\n"); - } - - @Test - public void testHistogramNoLabelsDefaultExemplar() throws IOException { - Histogram noLabelsDefaultExemplar = Histogram.build() - .name("no_labels_default_exemplar") - .help("help") - .buckets(5.0, 8.0) - .register(registry); - noLabelsDefaultExemplar.observe(3.0); - noLabelsDefaultExemplar.observe(6.0); - noLabelsDefaultExemplar.observe(9.0); - - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"5.0\"} 1.0 # " + defaultExemplarLabels + " 3.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"8.0\"} 2.0 # " + defaultExemplarLabels + " 6.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"+Inf\"} 3.0 # " + defaultExemplarLabels + " 9.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_count 3.0\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_sum 18.0\n"); - - assert004Format("no_labels_default_exemplar_bucket{le=\"5.0\",} 1.0\n"); - assert004Format("no_labels_default_exemplar_bucket{le=\"8.0\",} 2.0\n"); - assert004Format("no_labels_default_exemplar_bucket{le=\"+Inf\",} 3.0\n"); - assert004Format("no_labels_default_exemplar_count 3.0\n"); - assert004Format("no_labels_default_exemplar_sum 18.0\n"); - - noLabelsDefaultExemplar.observe(4.0); - // The TestExemplarSampler always produces a new Exemplar. - // The Exemplar with value 3.0 should be replaced with an Exemplar with value 4.0. - - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"5.0\"} 2.0 # " + defaultExemplarLabels + " 4.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"8.0\"} 3.0 # " + defaultExemplarLabels + " 6.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_bucket{le=\"+Inf\"} 4.0 # " + defaultExemplarLabels + " 9.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_count 4.0\n"); - assertOpenMetrics100Format("no_labels_default_exemplar_sum 22.0\n"); - - assert004Format("no_labels_default_exemplar_bucket{le=\"5.0\",} 2.0\n"); - assert004Format("no_labels_default_exemplar_bucket{le=\"8.0\",} 3.0\n"); - assert004Format("no_labels_default_exemplar_bucket{le=\"+Inf\",} 4.0\n"); - assert004Format("no_labels_default_exemplar_count 4.0\n"); - assert004Format("no_labels_default_exemplar_sum 22.0\n"); - } - - @Test - public void testHistogramLabelsDefaultExemplar() throws IOException { - Histogram noLabelsDefaultExemplar = Histogram.build() - .name("labels_default_exemplar") - .help("help") - .buckets(5.0) - .labelNames("label") - .register(registry); - noLabelsDefaultExemplar.labels("test").observe(3.0); - noLabelsDefaultExemplar.labels("test").observe(6.0); - - assertOpenMetrics100Format("labels_default_exemplar_bucket{label=\"test\",le=\"5.0\"} 1.0 # " + defaultExemplarLabels + " 3.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("labels_default_exemplar_bucket{label=\"test\",le=\"+Inf\"} 2.0 # " + defaultExemplarLabels + " 6.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("labels_default_exemplar_count{label=\"test\"} 2.0\n"); - assertOpenMetrics100Format("labels_default_exemplar_sum{label=\"test\"} 9.0\n"); - - assert004Format("labels_default_exemplar_bucket{label=\"test\",le=\"5.0\",} 1.0\n"); - assert004Format("labels_default_exemplar_bucket{label=\"test\",le=\"+Inf\",} 2.0\n"); - assert004Format("labels_default_exemplar_count{label=\"test\",} 2.0\n"); - assert004Format("labels_default_exemplar_sum{label=\"test\",} 9.0\n"); - } - - @Test - public void testHistogramNoLabelsNoExemplar() throws IOException { - Histogram noLabelsNoExemplar = Histogram.build() - .name("no_labels_no_exemplar") - .help("help") - .buckets(5.0) - .withoutExemplars() - .register(registry); - noLabelsNoExemplar.observe(3.0); - noLabelsNoExemplar.observe(6.0); - assertOpenMetrics100Format("no_labels_no_exemplar_bucket{le=\"5.0\"} 1.0\n"); - assertOpenMetrics100Format("no_labels_no_exemplar_bucket{le=\"+Inf\"} 2.0\n"); - assertOpenMetrics100Format("no_labels_no_exemplar_count 2.0\n"); - assertOpenMetrics100Format("no_labels_no_exemplar_sum 9.0\n"); - - assert004Format("no_labels_no_exemplar_bucket{le=\"5.0\",} 1.0\n"); - assert004Format("no_labels_no_exemplar_bucket{le=\"+Inf\",} 2.0\n"); - assert004Format("no_labels_no_exemplar_count 2.0\n"); - assert004Format("no_labels_no_exemplar_sum 9.0\n"); - } - - @Test - public void testHistogramLabelsNoExemplar() throws IOException { - Histogram labelsNoExemplar = Histogram.build() - .name("labels_no_exemplar") - .help("help") - .buckets(5.0) - .labelNames("label") - .withoutExemplars() - .register(registry); - labelsNoExemplar.labels("test").observe(3.0); - labelsNoExemplar.labels("test").observe(6.0); - - assertOpenMetrics100Format("labels_no_exemplar_bucket{label=\"test\",le=\"5.0\"} 1.0\n"); - assertOpenMetrics100Format("labels_no_exemplar_bucket{label=\"test\",le=\"+Inf\"} 2.0\n"); - assertOpenMetrics100Format("labels_no_exemplar_count{label=\"test\"} 2.0\n"); - assertOpenMetrics100Format("labels_no_exemplar_sum{label=\"test\"} 9.0\n"); - - assert004Format("labels_no_exemplar_bucket{label=\"test\",le=\"5.0\",} 1.0\n"); - assert004Format("labels_no_exemplar_bucket{label=\"test\",le=\"+Inf\",} 2.0\n"); - assert004Format("labels_no_exemplar_count{label=\"test\",} 2.0\n"); - assert004Format("labels_no_exemplar_sum{label=\"test\",} 9.0\n"); - } - - @Test - public void testHistogramNoLabelsCustomExemplar() throws IOException { - Histogram noLabelsCustomExemplar = Histogram.build() - .name("no_labels_custom_exemplar") - .help("help") - .buckets(5.0) - .withExemplarSampler(new TestExemplarSampler(customTraceId, customSpanId, timestamp)) - .register(registry); - noLabelsCustomExemplar.observe(3.0); - noLabelsCustomExemplar.observe(6.0); - - assertOpenMetrics100Format("no_labels_custom_exemplar_bucket{le=\"5.0\"} 1.0 # " + customExemplarLabels + " 3.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_custom_exemplar_bucket{le=\"+Inf\"} 2.0 # " + customExemplarLabels + " 6.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("no_labels_custom_exemplar_count 2.0\n"); - assertOpenMetrics100Format("no_labels_custom_exemplar_sum 9.0\n"); - - assert004Format("no_labels_custom_exemplar_bucket{le=\"5.0\",} 1.0\n"); - assert004Format("no_labels_custom_exemplar_bucket{le=\"+Inf\",} 2.0\n"); - assert004Format("no_labels_custom_exemplar_count 2.0\n"); - assert004Format("no_labels_custom_exemplar_sum 9.0\n"); - } - - @Test - public void testHistogramLabelsCustomExemplar() throws IOException { - Histogram labelsCustomExemplar = Histogram.build() - .name("labels_custom_exemplar") - .help("help") - .buckets(5.0) - .withExemplarSampler(new TestExemplarSampler(customTraceId, customSpanId, timestamp)) - .labelNames("label") - .register(registry); - labelsCustomExemplar.labels("test").observe(3.0); - labelsCustomExemplar.labels("test").observe(6.0); - - assertOpenMetrics100Format("labels_custom_exemplar_bucket{label=\"test\",le=\"5.0\"} 1.0 # " + customExemplarLabels + " 3.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("labels_custom_exemplar_bucket{label=\"test\",le=\"+Inf\"} 2.0 # " + customExemplarLabels + " 6.0 " + timestampString() + "\n"); - assertOpenMetrics100Format("labels_custom_exemplar_count{label=\"test\"} 2.0\n"); - assertOpenMetrics100Format("labels_custom_exemplar_sum{label=\"test\"} 9.0\n"); - - assert004Format("labels_custom_exemplar_bucket{label=\"test\",le=\"5.0\",} 1.0\n"); - assert004Format("labels_custom_exemplar_bucket{label=\"test\",le=\"+Inf\",} 2.0\n"); - assert004Format("labels_custom_exemplar_count{label=\"test\",} 2.0\n"); - assert004Format("labels_custom_exemplar_sum{label=\"test\",} 9.0\n"); - } - - - @Test - public void testSummaryNoLabels() throws IOException { - Summary noLabelsDefaultExemplar = Summary.build() - .name("no_labels") - .help("help") - .quantile(0.5, 0.01) - .register(registry); - for (int i=1; i<=11; i++) { // median is 6 - noLabelsDefaultExemplar.observe(i); - } - // Summaries don't have Exemplars according to the OpenMetrics spec. - assertOpenMetrics100Format("no_labels{quantile=\"0.5\"} 6.0\n"); - assertOpenMetrics100Format("no_labels_count 11.0\n"); - assertOpenMetrics100Format("no_labels_sum 66.0\n"); - - assert004Format("no_labels{quantile=\"0.5\",} 6.0\n"); - assert004Format("no_labels_count 11.0\n"); - assert004Format("no_labels_sum 66.0\n"); - } - - @Test - public void testSummaryLabels() throws IOException { - Summary labelsNoExemplar = Summary.build() - .name("labels") - .help("help") - .labelNames("label") - .quantile(0.5, 0.01) - .register(registry); - for (int i=1; i<=11; i++) { // median is 6 - labelsNoExemplar.labels("test").observe(i); - } - // Summaries don't have Exemplars according to the OpenMetrics spec. - assertOpenMetrics100Format("labels{label=\"test\",quantile=\"0.5\"} 6.0\n"); - assertOpenMetrics100Format("labels_count{label=\"test\"} 11.0\n"); - assertOpenMetrics100Format("labels_sum{label=\"test\"} 66.0\n"); - - assert004Format("labels{label=\"test\",quantile=\"0.5\",} 6.0\n"); - assert004Format("labels_count{label=\"test\",} 11.0\n"); - assert004Format("labels_sum{label=\"test\",} 66.0\n"); - } - - private static class TestExemplarSampler implements CounterExemplarSampler, HistogramExemplarSampler { - - private final String traceId; - private final String spanId; - private final long timestamp; - - private TestExemplarSampler(String traceId, String spanId, long timestamp) { - this.traceId = traceId; - this.spanId = spanId; - this.timestamp = timestamp; - } - - @Override - public Exemplar sample(double increment, Exemplar previous) { - return new Exemplar(increment, timestamp, "trace_id", traceId, "span_id", spanId); - } - - @Override - public Exemplar sample(double value, double bucketFrom, double bucketTo, Exemplar previous) { - return new Exemplar(value, timestamp, "trace_id", traceId, "span_id", spanId); - } - } - - private void assert004Format(String line) throws IOException { - StringWriter writer = new StringWriter(); - TextFormat.write004(writer, registry.metricFamilySamples()); - String metrics = writer.toString(); - Assert.assertTrue("Line not found. Expected metric:\n" + line + "Actual metrics:\n" + metrics, - metrics.contains("\n" + line)); - } - - private void assertOpenMetrics100Format(String line) throws IOException { - StringWriter writer = new StringWriter(); - TextFormat.writeOpenMetrics100(writer, registry.metricFamilySamples()); - String metrics = writer.toString(); - Assert.assertTrue("Line not found. Expected metric:\n" + line + "Actual metrics:\n" + metrics, - metrics.contains("\n" + line)); - } - - private String timestampString() throws IOException { - StringWriter stringWriter = new StringWriter(); - TextFormat.omWriteTimestamp(stringWriter, timestamp); - return stringWriter.toString(); - } -} diff --git a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java b/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java deleted file mode 100644 index 7ecac1a76..000000000 --- a/simpleclient_common/src/test/java/io/prometheus/client/exporter/common/TextFormatTest.java +++ /dev/null @@ -1,244 +0,0 @@ -package io.prometheus.client.exporter.common; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import io.prometheus.client.Collector; -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Counter; -import io.prometheus.client.Gauge; -import io.prometheus.client.Info; -import io.prometheus.client.Summary; - - -public class TextFormatTest { - CollectorRegistry registry; - StringWriter writer; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - writer = new StringWriter(); - } - - @Test - public void testGaugeOutput() throws IOException { - Gauge noLabels = Gauge.build().name("nolabels").help("help").register(registry); - noLabels.inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels help\n" - + "# TYPE nolabels gauge\n" - + "nolabels 1.0\n", writer.toString()); - } - - @Test - public void testValueInfinity() throws IOException { - Gauge noLabels = Gauge.build().name("nolabels").help("help").register(registry); - noLabels.set(Double.POSITIVE_INFINITY); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels help\n" - + "# TYPE nolabels gauge\n" - + "nolabels +Inf\n", writer.toString()); - } - - @Test - public void testCounterOutput() throws IOException { - Counter noLabels = Counter.build().name("nolabels").help("help").register(registry); - noLabels.inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels_total help\n" - + "# TYPE nolabels_total counter\n" - + "nolabels_total 1.0\n" - + "# HELP nolabels_created help\n" - + "# TYPE nolabels_created gauge\n" - + "nolabels_created 1234.0\n", - writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0")); - } - - @Test - public void testCounterWithTotalOutput() throws IOException { - Counter noLabels = Counter.build().name("nolabels_total").help("help").register(registry); - noLabels.inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels_total help\n" - + "# TYPE nolabels_total counter\n" - + "nolabels_total 1.0\n" - + "# HELP nolabels_created help\n" - + "# TYPE nolabels_created gauge\n" - + "nolabels_created 1234.0\n", - writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0")); - } - - @Test - public void testInfoOutput() throws IOException { - Info noLabels = Info.build().name("nolabels").help("help").register(registry); - noLabels.info("foo", "bar"); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels_info help\n" - + "# TYPE nolabels_info gauge\n" - + "nolabels_info{foo=\"bar\",} 1.0\n", writer.toString()); - } - - @Test - public void testCounterSamplesMissingTotal() throws IOException { - - class CustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - ArrayList labelNames = new ArrayList(); - ArrayList labelValues = new ArrayList(); - ArrayList samples = new ArrayList(); - MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0); - samples.add(sample); - mfs.add(new MetricFamilySamples("nolabels", Collector.Type.COUNTER, "help", samples)); - return mfs; - } - } - - new CustomCollector().register(registry); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels_total help\n" - + "# TYPE nolabels_total counter\n" - + "nolabels_total 1.0\n", writer.toString()); - } - - @Test - public void testMetricOutputWithTimestamp() throws IOException { - - class CustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - ArrayList labelNames = new ArrayList(); - ArrayList labelValues = new ArrayList(); - ArrayList samples = new ArrayList(); - MetricFamilySamples.Sample sample = new MetricFamilySamples.Sample("nolabels", labelNames, labelValues, 1.0, 1518123456L); - samples.add(sample); - mfs.add(new MetricFamilySamples("nolabels", Collector.Type.UNKNOWN, "help", samples)); - return mfs; - } - } - - new CustomCollector().register(registry); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels help\n" - + "# TYPE nolabels untyped\n" - + "nolabels 1.0 1518123456\n", writer.toString()); - } - - @Test - public void testSummaryOutput() throws IOException { - Summary noLabels = Summary.build().name("nolabels").help("help").register(registry); - noLabels.observe(2); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels help\n" - + "# TYPE nolabels summary\n" - + "nolabels_count 1.0\n" - + "nolabels_sum 2.0\n" - + "# HELP nolabels_created help\n" - + "# TYPE nolabels_created gauge\n" - + "nolabels_created 1234.0\n", - writer.toString().replaceAll("_created [0-9E.]+", "_created 1234.0")); - } - - @Test - public void testSummaryOutputWithQuantiles() throws IOException { - Summary labelsAndQuantiles = Summary.build() - .quantile(0.5, 0.05).quantile(0.9, 0.01).quantile(0.99, 0.001) - .labelNames("l").name("labelsAndQuantiles").help("help").register(registry); - labelsAndQuantiles.labels("a").observe(2); - writer = new StringWriter(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP labelsAndQuantiles help\n" - + "# TYPE labelsAndQuantiles summary\n" - + "labelsAndQuantiles{l=\"a\",quantile=\"0.5\",} 2.0\n" - + "labelsAndQuantiles{l=\"a\",quantile=\"0.9\",} 2.0\n" - + "labelsAndQuantiles{l=\"a\",quantile=\"0.99\",} 2.0\n" - + "labelsAndQuantiles_count{l=\"a\",} 1.0\n" - + "labelsAndQuantiles_sum{l=\"a\",} 2.0\n" - + "# HELP labelsAndQuantiles_created help\n" - + "# TYPE labelsAndQuantiles_created gauge\n" - + "labelsAndQuantiles_created{l=\"a\",} 1234.0\n", - writer.toString().replaceAll("(_created\\{.*\\}) [0-9E.]+", "$1 1234.0")); - } - - @Test - public void testGaugeHistogramOutput() throws IOException { - class CustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - ArrayList labelNames = new ArrayList(); - ArrayList labelValues = new ArrayList(); - ArrayList samples = new ArrayList(); - samples.add(new MetricFamilySamples.Sample("nolabels_bucket", Arrays.asList("le"), Arrays.asList("+Inf"), 2.0)); - samples.add(new MetricFamilySamples.Sample("nolabels_gcount", labelNames, labelValues, 2.0)); - samples.add(new MetricFamilySamples.Sample("nolabels_gsum", labelNames, labelValues, 7.0)); - samples.add(new MetricFamilySamples.Sample("nolabels_created", labelNames, labelValues, 1234.0)); - mfs.add(new MetricFamilySamples("nolabels", Collector.Type.GAUGE_HISTOGRAM, "help", samples)); - return mfs; - } - } - new CustomCollector().register(registry); - writer = new StringWriter(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels help\n" - + "# TYPE nolabels histogram\n" - + "nolabels_bucket{le=\"+Inf\",} 2.0\n" - + "# HELP nolabels_created help\n" - + "# TYPE nolabels_created gauge\n" - + "nolabels_created 1234.0\n" - + "# HELP nolabels_gcount help\n" - + "# TYPE nolabels_gcount gauge\n" - + "nolabels_gcount 2.0\n" - + "# HELP nolabels_gsum help\n" - + "# TYPE nolabels_gsum gauge\n" - + "nolabels_gsum 7.0\n", writer.toString()); - } - - @Test - public void testLabelsOutput() throws IOException { - Gauge labels = Gauge.build().name("labels").help("help").labelNames("l").register(registry); - labels.labels("a").inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP labels help\n" - + "# TYPE labels gauge\n" - + "labels{l=\"a\",} 1.0\n", writer.toString()); - } - - @Test - public void testLabelValuesEscaped() throws IOException { - Gauge labels = Gauge.build().name("labels").help("help").labelNames("l").register(registry); - labels.labels("ąćčęntěd a\nb\\c\"d").inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP labels help\n" - + "# TYPE labels gauge\n" - + "labels{l=\"ąćčęntěd a\\nb\\\\c\\\"d\",} 1.0\n", writer.toString()); - } - - @Test - public void testHelpEscaped() throws IOException { - Gauge noLabels = Gauge.build().name("nolabels").help("ąćčęntěd h\"e\\l\np").register(registry); - noLabels.inc(); - TextFormat.write004(writer, registry.metricFamilySamples()); - assertEquals("# HELP nolabels ąćčęntěd h\"e\\\\l\\np\n" - + "# TYPE nolabels gauge\n" - + "nolabels 1.0\n", writer.toString()); - } - - @Test - public void testChooseContentType() throws IOException { - assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType(null)); - assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType("")); - assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType("text/plain;version=0.0.4")); - assertEquals(TextFormat.CONTENT_TYPE_004, TextFormat.chooseContentType("foo")); - assertEquals(TextFormat.CONTENT_TYPE_OPENMETRICS_100, TextFormat.chooseContentType("application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1")); - assertEquals(TextFormat.CONTENT_TYPE_OPENMETRICS_100, TextFormat.chooseContentType("application/openmetrics-text; version=1.0.0")); - } -} diff --git a/simpleclient_common/version-rules.xml b/simpleclient_common/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient_common/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file From 549aa9e80aa9fafe0ab63b0c11906e1767e17c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 10:55:47 +0200 Subject: [PATCH 240/980] Move simpleclient_hotspot to prometheus-metrics modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../pom.xml | 0 .../jvm/JvmBufferPoolMetrics.java | 0 .../jvm/JvmClassLoadingMetrics.java | 0 .../jvm/JvmCompilationMetrics.java | 0 .../jvm/JvmGarbageCollectorMetrics.java | 0 .../instrumentation/jvm/JvmMemoryMetrics.java | 0 .../jvm/JvmMemoryPoolAllocationMetrics.java | 0 .../instrumentation/jvm/JvmMetrics.java | 0 .../jvm/JvmRuntimeInfoMetric.java | 0 .../jvm/JvmThreadsMetrics.java | 0 .../jvm}/NativeImageChecker.java | 0 .../instrumentation/jvm/ProcessMetrics.java | 0 .../jvm/JvmClassLoadingMetricsTest.java | 0 .../jvm/JvmCompilationMetricsTest.java | 0 .../jvm/JvmGarbageCollectorMetricsTest.java | 0 .../jvm/JvmMemoryMetricsTest.java | 0 .../JvmMemoryPoolAllocationMetricsTest.java | 0 .../jvm/JvmRuntimeInfoMetricTest.java | 0 .../jvm/JvmThreadsMetricsTest.java | 0 .../jvm/ProcessMetricsTest.java | 0 .../client/hotspot/ExampleExporter.java | 23 ------------------- simpleclient_hotspot/version-rules.xml | 12 ---------- 22 files changed, 35 deletions(-) rename {simpleclient_hotspot => prometheus-metrics-instrumentation-jvm}/pom.xml (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java (100%) rename {simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm}/NativeImageChecker.java (100%) rename simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/StandardExports.java => prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/GarbageCollectorExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java (100%) rename simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/StandardExportsTest.java => prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java (100%) delete mode 100644 simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ExampleExporter.java delete mode 100644 simpleclient_hotspot/version-rules.xml diff --git a/simpleclient_hotspot/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml similarity index 100% rename from simpleclient_hotspot/pom.xml rename to prometheus-metrics-instrumentation-jvm/pom.xml diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/BufferPoolsExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ClassLoadingExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/CompilationExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/GarbageCollectorExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryPoolsExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/MemoryAllocationExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/DefaultExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/VersionInfoExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/ThreadExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/NativeImageChecker.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java diff --git a/simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/StandardExports.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java similarity index 100% rename from simpleclient_hotspot/src/main/java/io/prometheus/client/hotspot/StandardExports.java rename to prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ClassLoadingExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/CompilationExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/GarbageCollectorExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/GarbageCollectorExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryAllocationExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/MemoryPoolsExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/VersionInfoExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ThreadExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/StandardExportsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java similarity index 100% rename from simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/StandardExportsTest.java rename to prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java diff --git a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ExampleExporter.java b/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ExampleExporter.java deleted file mode 100644 index 7c7212c8b..000000000 --- a/simpleclient_hotspot/src/test/java/io/prometheus/client/hotspot/ExampleExporter.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.prometheus.client.hotspot; - -import io.prometheus.client.exporter.MetricsServlet; -import io.prometheus.client.hotspot.StandardExports; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; - - -public class ExampleExporter { - - public static void main(String[] args) throws Exception { - DefaultExports.initialize(); - Server server = new Server(1234); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - server.setHandler(context); - context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics"); - server.start(); - server.join(); - } - -} diff --git a/simpleclient_hotspot/version-rules.xml b/simpleclient_hotspot/version-rules.xml deleted file mode 100644 index 904c3c3a1..000000000 --- a/simpleclient_hotspot/version-rules.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - [^9].* - - - - From 6beb21134901870e2c4fa5c7abd7edbddc2f83b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 12:42:12 +0200 Subject: [PATCH 241/980] Move simpleclient_tracer to prometheus-metrics modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- {simpleclient_tracer => prometheus-metrics-tracer}/pom.xml | 0 .../prometheus-metrics-tracer-common}/pom.xml | 0 .../io/prometheus/metrics/tracer/common/SpanContext.java | 0 .../prometheus-metrics-tracer-otel-agent}/pom.xml | 0 .../tracer/otel_agent/OpenTelemetryAgentSpanContext.java | 0 .../prometheus-metrics-tracer-otel}/pom.xml | 0 .../metrics/tracer/otel/OpenTelemetrySpanContext.java | 0 .../simpleclient_tracer_common/version-rules.xml | 6 ------ .../simpleclient_tracer_otel/version-rules.xml | 6 ------ .../simpleclient_tracer_otel_agent/version-rules.xml | 6 ------ simpleclient_tracer/version-rules.xml | 6 ------ 11 files changed, 24 deletions(-) rename {simpleclient_tracer => prometheus-metrics-tracer}/pom.xml (100%) rename {simpleclient_tracer/simpleclient_tracer_common => prometheus-metrics-tracer/prometheus-metrics-tracer-common}/pom.xml (100%) rename simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java => prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java (100%) rename {simpleclient_tracer/simpleclient_tracer_otel_agent => prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent}/pom.xml (100%) rename simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java => prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java (100%) rename {simpleclient_tracer/simpleclient_tracer_otel => prometheus-metrics-tracer/prometheus-metrics-tracer-otel}/pom.xml (100%) rename simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java => prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java (100%) delete mode 100644 simpleclient_tracer/simpleclient_tracer_common/version-rules.xml delete mode 100644 simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml delete mode 100644 simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml delete mode 100644 simpleclient_tracer/version-rules.xml diff --git a/simpleclient_tracer/pom.xml b/prometheus-metrics-tracer/pom.xml similarity index 100% rename from simpleclient_tracer/pom.xml rename to prometheus-metrics-tracer/pom.xml diff --git a/simpleclient_tracer/simpleclient_tracer_common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_common/pom.xml rename to prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml diff --git a/simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_common/src/main/java/io/prometheus/client/exemplars/tracer/common/SpanContextSupplier.java rename to prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_otel_agent/pom.xml rename to prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_otel_agent/src/main/java/io/prometheus/client/exemplars/tracer/otel_agent/OpenTelemetryAgentSpanContextSupplier.java rename to prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java diff --git a/simpleclient_tracer/simpleclient_tracer_otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_otel/pom.xml rename to prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml diff --git a/simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java similarity index 100% rename from simpleclient_tracer/simpleclient_tracer_otel/src/main/java/io/prometheus/client/exemplars/tracer/otel/OpenTelemetrySpanContextSupplier.java rename to prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java diff --git a/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient_tracer/simpleclient_tracer_common/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient_tracer/simpleclient_tracer_otel/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml b/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient_tracer/simpleclient_tracer_otel_agent/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/simpleclient_tracer/version-rules.xml b/simpleclient_tracer/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/simpleclient_tracer/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file From ca8a56963e21b10a2774fa094a71c67f257af35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 12:58:33 +0200 Subject: [PATCH 242/980] Move simpleclient_servlet_jakarta partly to prometheus-metrics modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../exporter/servlet/jakarta/PrometheusMetricsServlet.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java => prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java (100%) diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java similarity index 100% rename from simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/exporter/MetricsServlet.java rename to prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java From 3a9fe4e9359b4924da0e17f859564ff2afa93ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 13:01:06 +0200 Subject: [PATCH 243/980] Move pending simpleclient modules to archive --- OTEL_EXEMPLARS.md | 80 ------------------ .../integration_tests}/it_common/pom.xml | 0 .../client/it/common/Downloader.java | 0 .../client/it/common/LogConsumer.java | 0 .../prometheus/client/it/common/Scraper.java | 0 .../prometheus/client/it/common/Version.java | 0 .../prometheus/client/it/common/Volume.java | 0 .../test/resources/project_version.properties | 0 .../it_common/version-rules.xml | 0 .../it_exemplars_otel_agent/pom.xml | 0 .../ExampleSpringBootApp.java | 0 .../src/main/resources/application.properties | 0 .../ExemplarsOpenTelemetryAgentIT.java | 0 .../src/test/resources/logback-test.xml | 0 .../it_exemplars_otel_agent/version-rules.xml | 0 .../it_exemplars_otel_sdk/pom.xml | 0 .../it/exemplars_otel/ExampleApplication.java | 0 .../ExemplarsOpenTelemetrySdkIT.java | 0 .../src/test/resources/logback-test.xml | 0 .../it_exemplars_otel_sdk/version-rules.xml | 0 .../it_java_versions/pom.xml | 0 .../it/java_versions/ExampleApplication.java | 0 .../it/java_versions/JavaVersionsIT.java | 0 .../src/test/resources/logback-test.xml | 0 .../it_java_versions/version-rules.xml | 0 .../integration_tests}/it_log4j2/pom.xml | 0 .../client/it/log4j2/ExampleApplication.java | 0 .../it_log4j2/src/main/resources/log4j2.xml | 0 .../prometheus/client/it/log4j2/Log4j2IT.java | 0 .../src/test/resources/logback-test.xml | 0 .../it_log4j2/version-rules.xml | 0 .../integration_tests}/it_pushgateway/pom.xml | 0 .../it/pushgateway/ExampleBatchJob.java | 0 .../client/it/pushgateway/PushGatewayIT.java | 0 .../src/test/resources/logback-test.xml | 0 .../src/test/resources/web-config.yml | 0 .../it_pushgateway/version-rules.xml | 0 .../pom.xml | 0 .../it/servlet/jakarta/ExampleServlet.java | 0 .../src/main/webapp/WEB-INF/web.xml | 0 .../ServletJakartaExporterWebXmlIT.java | 0 .../src/test/resources/Dockerfile | 0 .../src/test/resources/logback-test.xml | 0 .../version-rules.xml | 0 .../integration_tests}/pom.xml | 0 .../integration_tests}/version-rules.xml | 0 .../simpleclient_bom}/pom.xml | 0 .../simpleclient_caffeine}/pom.xml | 0 .../cache/caffeine/CacheMetricsCollector.java | 0 .../caffeine/CacheMetricsCollectorTest.java | 0 .../simpleclient_caffeine}/version-rules.xml | 0 .../simpleclient_dropwizard}/pom.xml | 0 .../client/dropwizard/DropwizardExports.java | 0 .../CustomMappingSampleBuilder.java | 0 .../samplebuilder/DefaultSampleBuilder.java | 0 .../samplebuilder/GraphiteNamePattern.java | 0 .../samplebuilder/MapperConfig.java | 0 .../samplebuilder/SampleBuilder.java | 0 .../dropwizard/DropwizardExportsTest.java | 0 .../CustomMappingSampleBuilderTest.java | 0 .../DefaultSampleBuilderTest.java | 0 .../GraphiteNamePatternTest.java | 0 .../samplebuilder/MapperConfigTest.java | 0 .../version-rules.xml | 0 .../simpleclient_graphite_bridge}/pom.xml | 0 .../io/prometheus/client/bridge/Graphite.java | 0 .../client/bridge/GraphiteTest.java | 0 .../version-rules.xml | 0 .../simpleclient_guava}/pom.xml | 0 .../guava/cache/CacheMetricsCollector.java | 0 .../cache/CacheMetricsCollectorTest.java | 0 .../simpleclient_guava}/version-rules.xml | 0 .../simpleclient_hibernate}/pom.xml | 0 .../HibernateStatisticsCollector.java | 0 .../HibernateStatisticsCollectorTest.java | 0 .../simpleclient_hibernate}/version-rules.xml | 0 .../simpleclient_httpserver}/pom.xml | 0 .../client/exporter/HTTPServer.java | 0 .../exporter/SampleNameFilterSupplier.java | 0 .../client/exporter/ExampleExporter.java | 0 .../client/exporter/HttpRequest.java | 0 .../client/exporter/HttpResponse.java | 0 .../client/exporter/TestDaemonFlags.java | 0 .../client/exporter/TestHTTPServer.java | 0 .../src/test/resources/keystore.pkcs12 | Bin .../version-rules.xml | 0 .../simpleclient_jetty}/pom.xml | 0 .../jetty/JettyStatisticsCollector.java | 0 .../jetty/JettyStatisticsCollectorTest.java | 0 .../simpleclient_jetty}/version-rules.xml | 0 .../simpleclient_jetty_jdk8}/pom.xml | 0 .../QueuedThreadPoolStatisticsCollector.java | 0 ...euedThreadPoolStatisticsCollectorTest.java | 0 .../version-rules.xml | 0 .../simpleclient_log4j}/pom.xml | 0 .../client/log4j/InstrumentedAppender.java | 0 .../log4j/InstrumentedAppenderTest.java | 0 .../simpleclient_log4j}/version-rules.xml | 0 .../simpleclient_log4j2}/pom.xml | 0 .../client/log4j2/InstrumentedAppender.java | 0 .../log4j2/InstrumentedAppenderTest.java | 0 .../simpleclient_log4j2}/version-rules.xml | 0 .../simpleclient_logback}/pom.xml | 0 .../client/logback/InstrumentedAppender.java | 0 .../logback/InstrumentedAppenderTest.java | 0 .../simpleclient_logback}/version-rules.xml | 0 .../simpleclient_pushgateway}/pom.xml | 0 .../io/prometheus/client/exporter/Base64.java | 0 .../BasicAuthHttpConnectionFactory.java | 0 .../DefaultHttpConnectionFactory.java | 0 .../exporter/HttpConnectionFactory.java | 0 .../client/exporter/PushGateway.java | 0 .../exporter/BasicAuthPushGatewayTest.java | 0 .../client/exporter/ExamplePushGateway.java | 0 .../client/exporter/PushGatewayTest.java | 0 .../version-rules.xml | 0 .../simpleclient_servlet}/pom.xml | 0 .../client/exporter/MetricsServlet.java | 0 .../client/filter/MetricsFilter.java | 0 .../prometheus/client/internal/Adapter.java | 0 .../client/exporter/ExampleBenchmark.java | 0 .../client/exporter/ExampleExporter.java | 0 .../simpleclient_servlet}/version-rules.xml | 0 .../simpleclient_servlet_common}/pom.xml | 0 .../common/adapter/FilterConfigAdapter.java | 0 .../adapter/HttpServletRequestAdapter.java | 0 .../adapter/HttpServletResponseAdapter.java | 0 .../common/adapter/ServletConfigAdapter.java | 0 .../servlet/common/exporter/Exporter.java | 0 .../ServletConfigurationException.java | 0 .../client/servlet/common/filter/Filter.java | 0 .../filter/FilterConfigurationException.java | 0 .../servlet/common/exporter/ExporterTest.java | 0 .../servlet/common/filter/FilterTest.java | 0 .../version-rules.xml | 0 .../simpleclient_servlet_jakarta}/pom.xml | 0 .../client/servlet/jakarta/Adapter.java | 0 .../servlet/jakarta/filter/MetricsFilter.java | 0 .../client/exporter/ExampleBenchmark.java | 0 .../client/exporter/ExampleExporter.java | 0 .../version-rules.xml | 0 .../simpleclient_spring_boot}/pom.xml | 0 .../spring/boot/EnablePrometheusEndpoint.java | 0 .../EnableSpringBootMetricsCollector.java | 0 .../spring/boot/PrometheusEndpoint.java | 0 .../boot/PrometheusEndpointConfiguration.java | 0 .../boot/PrometheusMetricsConfiguration.java | 0 .../spring/boot/PrometheusMvcEndpoint.java | 0 .../boot/SpringBootMetricsCollector.java | 0 .../client/matchers/CustomMatchers.java | 0 .../spring/boot/DummyBootApplication.java | 0 .../spring/boot/PrometheusEndpointTest.java | 0 .../boot/PrometheusMvcEndpointTest.java | 0 .../boot/SpringBootMetricsCollectorTest.java | 0 .../version-rules.xml | 0 .../simpleclient_spring_web}/pom.xml | 0 .../spring/web/EnablePrometheusTiming.java | 0 .../client/spring/web/MethodTimer.java | 0 .../spring/web/PrometheusTimeMethod.java | 0 .../client/spring/web/MethodTimerAppTest.java | 0 .../client/spring/web/MethodTimerTest.java | 0 .../version-rules.xml | 0 .../simpleclient_vertx}/pom.xml | 0 .../client/vertx/MetricsHandler.java | 0 .../client/vertx/ExampleExporter.java | 0 .../client/vertx/MetricsHandlerTest.java | 0 .../simpleclient_vertx}/version-rules.xml | 0 .../simpleclient_vertx4}/pom.xml | 0 .../client/vertx/MetricsHandler.java | 0 .../client/vertx/ExampleExporter.java | 0 .../client/vertx/MetricsHandlerTest.java | 0 .../simpleclient_vertx4}/version-rules.xml | 0 172 files changed, 80 deletions(-) delete mode 100644 OTEL_EXEMPLARS.md rename {integration_tests => simpleclient-archive/integration_tests}/it_common/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/java/io/prometheus/client/it/common/Version.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/java/io/prometheus/client/it/common/Volume.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/src/test/resources/project_version.properties (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_common/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/src/main/resources/application.properties (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_agent/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_sdk/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_sdk/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_exemplars_otel_sdk/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_java_versions/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_java_versions/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_java_versions/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/src/main/resources/log4j2.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_log4j2/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/src/test/resources/web-config.yml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_pushgateway/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/it_servlet_jakarta_exporter_webxml/version-rules.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/pom.xml (100%) rename {integration_tests => simpleclient-archive/integration_tests}/version-rules.xml (100%) rename {simpleclient_bom => simpleclient-archive/simpleclient_bom}/pom.xml (100%) rename {simpleclient_caffeine => simpleclient-archive/simpleclient_caffeine}/pom.xml (100%) rename {simpleclient_caffeine => simpleclient-archive/simpleclient_caffeine}/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java (100%) rename {simpleclient_caffeine => simpleclient-archive/simpleclient_caffeine}/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java (100%) rename {simpleclient_caffeine => simpleclient-archive/simpleclient_caffeine}/version-rules.xml (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/pom.xml (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java (100%) rename {simpleclient_dropwizard => simpleclient-archive/simpleclient_dropwizard}/version-rules.xml (100%) rename {simpleclient_graphite_bridge => simpleclient-archive/simpleclient_graphite_bridge}/pom.xml (100%) rename {simpleclient_graphite_bridge => simpleclient-archive/simpleclient_graphite_bridge}/src/main/java/io/prometheus/client/bridge/Graphite.java (100%) rename {simpleclient_graphite_bridge => simpleclient-archive/simpleclient_graphite_bridge}/src/test/java/io/prometheus/client/bridge/GraphiteTest.java (100%) rename {simpleclient_graphite_bridge => simpleclient-archive/simpleclient_graphite_bridge}/version-rules.xml (100%) rename {simpleclient_guava => simpleclient-archive/simpleclient_guava}/pom.xml (100%) rename {simpleclient_guava => simpleclient-archive/simpleclient_guava}/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java (100%) rename {simpleclient_guava => simpleclient-archive/simpleclient_guava}/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java (100%) rename {simpleclient_guava => simpleclient-archive/simpleclient_guava}/version-rules.xml (100%) rename {simpleclient_hibernate => simpleclient-archive/simpleclient_hibernate}/pom.xml (100%) rename {simpleclient_hibernate => simpleclient-archive/simpleclient_hibernate}/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java (100%) rename {simpleclient_hibernate => simpleclient-archive/simpleclient_hibernate}/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java (100%) rename {simpleclient_hibernate => simpleclient-archive/simpleclient_hibernate}/version-rules.xml (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/pom.xml (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/main/java/io/prometheus/client/exporter/HTTPServer.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/java/io/prometheus/client/exporter/ExampleExporter.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/java/io/prometheus/client/exporter/HttpRequest.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/java/io/prometheus/client/exporter/HttpResponse.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/src/test/resources/keystore.pkcs12 (100%) rename {simpleclient_httpserver => simpleclient-archive/simpleclient_httpserver}/version-rules.xml (100%) rename {simpleclient_jetty => simpleclient-archive/simpleclient_jetty}/pom.xml (100%) rename {simpleclient_jetty => simpleclient-archive/simpleclient_jetty}/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java (100%) rename {simpleclient_jetty => simpleclient-archive/simpleclient_jetty}/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java (100%) rename {simpleclient_jetty => simpleclient-archive/simpleclient_jetty}/version-rules.xml (100%) rename {simpleclient_jetty_jdk8 => simpleclient-archive/simpleclient_jetty_jdk8}/pom.xml (100%) rename {simpleclient_jetty_jdk8 => simpleclient-archive/simpleclient_jetty_jdk8}/src/main/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollector.java (100%) rename {simpleclient_jetty_jdk8 => simpleclient-archive/simpleclient_jetty_jdk8}/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java (100%) rename {simpleclient_jetty_jdk8 => simpleclient-archive/simpleclient_jetty_jdk8}/version-rules.xml (100%) rename {simpleclient_log4j => simpleclient-archive/simpleclient_log4j}/pom.xml (100%) rename {simpleclient_log4j => simpleclient-archive/simpleclient_log4j}/src/main/java/io/prometheus/client/log4j/InstrumentedAppender.java (100%) rename {simpleclient_log4j => simpleclient-archive/simpleclient_log4j}/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java (100%) rename {simpleclient_log4j => simpleclient-archive/simpleclient_log4j}/version-rules.xml (100%) rename {simpleclient_log4j2 => simpleclient-archive/simpleclient_log4j2}/pom.xml (100%) rename {simpleclient_log4j2 => simpleclient-archive/simpleclient_log4j2}/src/main/java/io/prometheus/client/log4j2/InstrumentedAppender.java (100%) rename {simpleclient_log4j2 => simpleclient-archive/simpleclient_log4j2}/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java (100%) rename {simpleclient_log4j2 => simpleclient-archive/simpleclient_log4j2}/version-rules.xml (100%) rename {simpleclient_logback => simpleclient-archive/simpleclient_logback}/pom.xml (100%) rename {simpleclient_logback => simpleclient-archive/simpleclient_logback}/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java (100%) rename {simpleclient_logback => simpleclient-archive/simpleclient_logback}/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java (100%) rename {simpleclient_logback => simpleclient-archive/simpleclient_logback}/version-rules.xml (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/pom.xml (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/main/java/io/prometheus/client/exporter/Base64.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/main/java/io/prometheus/client/exporter/PushGateway.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java (100%) rename {simpleclient_pushgateway => simpleclient-archive/simpleclient_pushgateway}/version-rules.xml (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/pom.xml (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/src/main/java/io/prometheus/client/exporter/MetricsServlet.java (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/src/main/java/io/prometheus/client/filter/MetricsFilter.java (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/src/main/java/io/prometheus/client/internal/Adapter.java (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/src/test/java/io/prometheus/client/exporter/ExampleExporter.java (100%) rename {simpleclient_servlet => simpleclient-archive/simpleclient_servlet}/version-rules.xml (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/pom.xml (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java (100%) rename {simpleclient_servlet_common => simpleclient-archive/simpleclient_servlet_common}/version-rules.xml (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/pom.xml (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/src/test/java/io/prometheus/client/exporter/ExampleExporter.java (100%) rename {simpleclient_servlet_jakarta => simpleclient-archive/simpleclient_servlet_jakarta}/version-rules.xml (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/pom.xml (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/test/java/io/prometheus/client/matchers/CustomMatchers.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java (100%) rename {simpleclient_spring_boot => simpleclient-archive/simpleclient_spring_boot}/version-rules.xml (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/pom.xml (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/src/main/java/io/prometheus/client/spring/web/EnablePrometheusTiming.java (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/src/main/java/io/prometheus/client/spring/web/MethodTimer.java (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/src/main/java/io/prometheus/client/spring/web/PrometheusTimeMethod.java (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java (100%) rename {simpleclient_spring_web => simpleclient-archive/simpleclient_spring_web}/version-rules.xml (100%) rename {simpleclient_vertx => simpleclient-archive/simpleclient_vertx}/pom.xml (100%) rename {simpleclient_vertx => simpleclient-archive/simpleclient_vertx}/src/main/java/io/prometheus/client/vertx/MetricsHandler.java (100%) rename {simpleclient_vertx => simpleclient-archive/simpleclient_vertx}/src/test/java/io/prometheus/client/vertx/ExampleExporter.java (100%) rename {simpleclient_vertx => simpleclient-archive/simpleclient_vertx}/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java (100%) rename {simpleclient_vertx => simpleclient-archive/simpleclient_vertx}/version-rules.xml (100%) rename {simpleclient_vertx4 => simpleclient-archive/simpleclient_vertx4}/pom.xml (100%) rename {simpleclient_vertx4 => simpleclient-archive/simpleclient_vertx4}/src/main/java/io/prometheus/client/vertx/MetricsHandler.java (100%) rename {simpleclient_vertx4 => simpleclient-archive/simpleclient_vertx4}/src/test/java/io/prometheus/client/vertx/ExampleExporter.java (100%) rename {simpleclient_vertx4 => simpleclient-archive/simpleclient_vertx4}/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java (100%) rename {simpleclient_vertx4 => simpleclient-archive/simpleclient_vertx4}/version-rules.xml (100%) diff --git a/OTEL_EXEMPLARS.md b/OTEL_EXEMPLARS.md deleted file mode 100644 index 1034d52be..000000000 --- a/OTEL_EXEMPLARS.md +++ /dev/null @@ -1,80 +0,0 @@ -# OpenTelemetry Exemplars - -The `DefaultExemplarSampler` will provide OpenTelemetry exemplars if the [opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java) library version 0.16.0 or higher is found. When `client_java` 0.11.0 was released, the current [opentelemetry-java](https://github.com/open-telemetry/opentelemetry-java) version was 1.2.0. - -## Running the Example - -If you want to see this in action, you can run the example from the `ExemplarsClientJavaIT`: - -``` -./mvnw package -cd integration_tests/it_exemplars_otel_agent/target/ -curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.10.1/opentelemetry-javaagent.jar -java -Dotel.traces.exporter=logging -Dotel.metrics.exporter=none -javaagent:./opentelemetry-javaagent.jar -jar ./example-spring-boot-app.jar -``` - -Now you have a Spring REST service running on [http://localhost:8080/hello](http://localhost:8080/hello) that is instrumented with the OpenTelemetry Java agent. - -Run a request to generate an OpenTelemetry trace - -``` -curl http://localhost:8080/hello -``` - -In order to get metrics in [OpenMetrics](http://openmetrics.io) format, run - -``` -curl -H 'Accept: application/openmetrics-text; version=1.0.0; charset=utf-8' http://localhost:8080/metrics -``` - -You should see metrics with Exemplars, for example in the `request_duration_histogram` metric: - -``` -request_duration_histogram_bucket{path="/god-of-fire",le="0.004"} 4.0 # {trace_id="043cd631811e373e4180a678c06b128e",span_id="cd122e457d2ca5b0"} 0.0033 1618261159.027 -``` - -Note that this is an example application for demonstration, so durations don't represent real durations, and some example metrics might not make sense in the real world. - -## Disabling OpenTelemetry Exemplars - -If you use OpenTelemetry tracing but do not want Exemplars, you can disable OpenTelemetries in multiple ways. - -### Disabling OpenTelemetry Exemplars in Code - -The default exemplar sampler can be disabled via the `ExemplarConfig` API. This is described in [README.md], as this is not specific to OpenTelemetry. - -### Disabling OpenTelemetry Exemplars at Compile Time - -If you don't want to change code, but still build an application that uses OpenTelemetry but does not provide OpenTelemetry exemplars, -you can exclude the corresponding dependencies in your `pom.xml`: - -```xml - - - io.prometheus - simpleclient - 0.12.0 - - - - io.prometheus - simpleclient_tracer_otel - - - - io.prometheus - simpleclient_tracer_otel_agent - - - - -``` - -### Disable OpenTelemetry Exemplars at Runtime - -If your application uses OpenTelemetry tracing, but you want to disable OpenTelemetry at runtime without changing code, -start your application with the `io.prometheus.otelExemplars` system property: - -``` -java -Dio.prometheus.otelExemplars=inactive -jar my-application.jar -``` diff --git a/integration_tests/it_common/pom.xml b/simpleclient-archive/integration_tests/it_common/pom.xml similarity index 100% rename from integration_tests/it_common/pom.xml rename to simpleclient-archive/integration_tests/it_common/pom.xml diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java b/simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java similarity index 100% rename from integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java rename to simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Downloader.java diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java b/simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java similarity index 100% rename from integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java rename to simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/LogConsumer.java diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java b/simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java similarity index 100% rename from integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java rename to simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Scraper.java diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java b/simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java similarity index 100% rename from integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java rename to simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Version.java diff --git a/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java b/simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java similarity index 100% rename from integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java rename to simpleclient-archive/integration_tests/it_common/src/test/java/io/prometheus/client/it/common/Volume.java diff --git a/integration_tests/it_common/src/test/resources/project_version.properties b/simpleclient-archive/integration_tests/it_common/src/test/resources/project_version.properties similarity index 100% rename from integration_tests/it_common/src/test/resources/project_version.properties rename to simpleclient-archive/integration_tests/it_common/src/test/resources/project_version.properties diff --git a/integration_tests/it_common/version-rules.xml b/simpleclient-archive/integration_tests/it_common/version-rules.xml similarity index 100% rename from integration_tests/it_common/version-rules.xml rename to simpleclient-archive/integration_tests/it_common/version-rules.xml diff --git a/integration_tests/it_exemplars_otel_agent/pom.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml similarity index 100% rename from integration_tests/it_exemplars_otel_agent/pom.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml diff --git a/integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java similarity index 100% rename from integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/main/java/io/prometheus/client/it/exemplars_otel_agent/ExampleSpringBootApp.java diff --git a/integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties similarity index 100% rename from integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/main/resources/application.properties diff --git a/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java similarity index 100% rename from integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/test/java/io/prometheus/client/it/exemplars_otel_agent/ExemplarsOpenTelemetryAgentIT.java diff --git a/integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/src/test/resources/logback-test.xml diff --git a/integration_tests/it_exemplars_otel_agent/version-rules.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/version-rules.xml similarity index 100% rename from integration_tests/it_exemplars_otel_agent/version-rules.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/version-rules.xml diff --git a/integration_tests/it_exemplars_otel_sdk/pom.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml similarity index 100% rename from integration_tests/it_exemplars_otel_sdk/pom.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml diff --git a/integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java similarity index 100% rename from integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/main/java/io/prometheus/client/it/exemplars_otel/ExampleApplication.java diff --git a/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java similarity index 100% rename from integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/test/java/io/prometheus/client/it/exemplars_otel/ExemplarsOpenTelemetrySdkIT.java diff --git a/integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/src/test/resources/logback-test.xml diff --git a/integration_tests/it_exemplars_otel_sdk/version-rules.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/version-rules.xml similarity index 100% rename from integration_tests/it_exemplars_otel_sdk/version-rules.xml rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/version-rules.xml diff --git a/integration_tests/it_java_versions/pom.xml b/simpleclient-archive/integration_tests/it_java_versions/pom.xml similarity index 100% rename from integration_tests/it_java_versions/pom.xml rename to simpleclient-archive/integration_tests/it_java_versions/pom.xml diff --git a/integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java b/simpleclient-archive/integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java similarity index 100% rename from integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java rename to simpleclient-archive/integration_tests/it_java_versions/src/main/java/io/prometheus/client/it/java_versions/ExampleApplication.java diff --git a/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java b/simpleclient-archive/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java similarity index 100% rename from integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java rename to simpleclient-archive/integration_tests/it_java_versions/src/test/java/io/prometheus/client/it/java_versions/JavaVersionsIT.java diff --git a/integration_tests/it_java_versions/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_java_versions/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_java_versions/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_java_versions/src/test/resources/logback-test.xml diff --git a/integration_tests/it_java_versions/version-rules.xml b/simpleclient-archive/integration_tests/it_java_versions/version-rules.xml similarity index 100% rename from integration_tests/it_java_versions/version-rules.xml rename to simpleclient-archive/integration_tests/it_java_versions/version-rules.xml diff --git a/integration_tests/it_log4j2/pom.xml b/simpleclient-archive/integration_tests/it_log4j2/pom.xml similarity index 100% rename from integration_tests/it_log4j2/pom.xml rename to simpleclient-archive/integration_tests/it_log4j2/pom.xml diff --git a/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java b/simpleclient-archive/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java similarity index 100% rename from integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java rename to simpleclient-archive/integration_tests/it_log4j2/src/main/java/io/prometheus/client/it/log4j2/ExampleApplication.java diff --git a/integration_tests/it_log4j2/src/main/resources/log4j2.xml b/simpleclient-archive/integration_tests/it_log4j2/src/main/resources/log4j2.xml similarity index 100% rename from integration_tests/it_log4j2/src/main/resources/log4j2.xml rename to simpleclient-archive/integration_tests/it_log4j2/src/main/resources/log4j2.xml diff --git a/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java b/simpleclient-archive/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java similarity index 100% rename from integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java rename to simpleclient-archive/integration_tests/it_log4j2/src/test/java/io/prometheus/client/it/log4j2/Log4j2IT.java diff --git a/integration_tests/it_log4j2/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_log4j2/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_log4j2/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_log4j2/src/test/resources/logback-test.xml diff --git a/integration_tests/it_log4j2/version-rules.xml b/simpleclient-archive/integration_tests/it_log4j2/version-rules.xml similarity index 100% rename from integration_tests/it_log4j2/version-rules.xml rename to simpleclient-archive/integration_tests/it_log4j2/version-rules.xml diff --git a/integration_tests/it_pushgateway/pom.xml b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml similarity index 100% rename from integration_tests/it_pushgateway/pom.xml rename to simpleclient-archive/integration_tests/it_pushgateway/pom.xml diff --git a/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java b/simpleclient-archive/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java similarity index 100% rename from integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java rename to simpleclient-archive/integration_tests/it_pushgateway/src/main/java/io/prometheus/client/it/pushgateway/ExampleBatchJob.java diff --git a/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java b/simpleclient-archive/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java similarity index 100% rename from integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java rename to simpleclient-archive/integration_tests/it_pushgateway/src/test/java/io/prometheus/client/it/pushgateway/PushGatewayIT.java diff --git a/integration_tests/it_pushgateway/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_pushgateway/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_pushgateway/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_pushgateway/src/test/resources/logback-test.xml diff --git a/integration_tests/it_pushgateway/src/test/resources/web-config.yml b/simpleclient-archive/integration_tests/it_pushgateway/src/test/resources/web-config.yml similarity index 100% rename from integration_tests/it_pushgateway/src/test/resources/web-config.yml rename to simpleclient-archive/integration_tests/it_pushgateway/src/test/resources/web-config.yml diff --git a/integration_tests/it_pushgateway/version-rules.xml b/simpleclient-archive/integration_tests/it_pushgateway/version-rules.xml similarity index 100% rename from integration_tests/it_pushgateway/version-rules.xml rename to simpleclient-archive/integration_tests/it_pushgateway/version-rules.xml diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/java/io/prometheus/client/it/servlet/jakarta/ExampleServlet.java diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/main/webapp/WEB-INF/web.xml diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/java/io/prometheus/client/it/servlet/jakarta/ServletJakartaExporterWebXmlIT.java diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/Dockerfile diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/src/test/resources/logback-test.xml diff --git a/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml similarity index 100% rename from integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/version-rules.xml diff --git a/integration_tests/pom.xml b/simpleclient-archive/integration_tests/pom.xml similarity index 100% rename from integration_tests/pom.xml rename to simpleclient-archive/integration_tests/pom.xml diff --git a/integration_tests/version-rules.xml b/simpleclient-archive/integration_tests/version-rules.xml similarity index 100% rename from integration_tests/version-rules.xml rename to simpleclient-archive/integration_tests/version-rules.xml diff --git a/simpleclient_bom/pom.xml b/simpleclient-archive/simpleclient_bom/pom.xml similarity index 100% rename from simpleclient_bom/pom.xml rename to simpleclient-archive/simpleclient_bom/pom.xml diff --git a/simpleclient_caffeine/pom.xml b/simpleclient-archive/simpleclient_caffeine/pom.xml similarity index 100% rename from simpleclient_caffeine/pom.xml rename to simpleclient-archive/simpleclient_caffeine/pom.xml diff --git a/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java b/simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java similarity index 100% rename from simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java rename to simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java diff --git a/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java b/simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java similarity index 100% rename from simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java rename to simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java diff --git a/simpleclient_caffeine/version-rules.xml b/simpleclient-archive/simpleclient_caffeine/version-rules.xml similarity index 100% rename from simpleclient_caffeine/version-rules.xml rename to simpleclient-archive/simpleclient_caffeine/version-rules.xml diff --git a/simpleclient_dropwizard/pom.xml b/simpleclient-archive/simpleclient_dropwizard/pom.xml similarity index 100% rename from simpleclient_dropwizard/pom.xml rename to simpleclient-archive/simpleclient_dropwizard/pom.xml diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java diff --git a/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java similarity index 100% rename from simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java rename to simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java similarity index 100% rename from simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java rename to simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java similarity index 100% rename from simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java rename to simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java similarity index 100% rename from simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java rename to simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java similarity index 100% rename from simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java rename to simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java diff --git a/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java similarity index 100% rename from simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java rename to simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java diff --git a/simpleclient_dropwizard/version-rules.xml b/simpleclient-archive/simpleclient_dropwizard/version-rules.xml similarity index 100% rename from simpleclient_dropwizard/version-rules.xml rename to simpleclient-archive/simpleclient_dropwizard/version-rules.xml diff --git a/simpleclient_graphite_bridge/pom.xml b/simpleclient-archive/simpleclient_graphite_bridge/pom.xml similarity index 100% rename from simpleclient_graphite_bridge/pom.xml rename to simpleclient-archive/simpleclient_graphite_bridge/pom.xml diff --git a/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java b/simpleclient-archive/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java similarity index 100% rename from simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java rename to simpleclient-archive/simpleclient_graphite_bridge/src/main/java/io/prometheus/client/bridge/Graphite.java diff --git a/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java b/simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java similarity index 100% rename from simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java rename to simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java diff --git a/simpleclient_graphite_bridge/version-rules.xml b/simpleclient-archive/simpleclient_graphite_bridge/version-rules.xml similarity index 100% rename from simpleclient_graphite_bridge/version-rules.xml rename to simpleclient-archive/simpleclient_graphite_bridge/version-rules.xml diff --git a/simpleclient_guava/pom.xml b/simpleclient-archive/simpleclient_guava/pom.xml similarity index 100% rename from simpleclient_guava/pom.xml rename to simpleclient-archive/simpleclient_guava/pom.xml diff --git a/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java b/simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java similarity index 100% rename from simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java rename to simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java diff --git a/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java b/simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java similarity index 100% rename from simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java rename to simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java diff --git a/simpleclient_guava/version-rules.xml b/simpleclient-archive/simpleclient_guava/version-rules.xml similarity index 100% rename from simpleclient_guava/version-rules.xml rename to simpleclient-archive/simpleclient_guava/version-rules.xml diff --git a/simpleclient_hibernate/pom.xml b/simpleclient-archive/simpleclient_hibernate/pom.xml similarity index 100% rename from simpleclient_hibernate/pom.xml rename to simpleclient-archive/simpleclient_hibernate/pom.xml diff --git a/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java b/simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java similarity index 100% rename from simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java rename to simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java diff --git a/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java similarity index 100% rename from simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java rename to simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java diff --git a/simpleclient_hibernate/version-rules.xml b/simpleclient-archive/simpleclient_hibernate/version-rules.xml similarity index 100% rename from simpleclient_hibernate/version-rules.xml rename to simpleclient-archive/simpleclient_hibernate/version-rules.xml diff --git a/simpleclient_httpserver/pom.xml b/simpleclient-archive/simpleclient_httpserver/pom.xml similarity index 100% rename from simpleclient_httpserver/pom.xml rename to simpleclient-archive/simpleclient_httpserver/pom.xml diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java b/simpleclient-archive/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java similarity index 100% rename from simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java rename to simpleclient-archive/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java diff --git a/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java b/simpleclient-archive/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java similarity index 100% rename from simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java rename to simpleclient-archive/simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/SampleNameFilterSupplier.java diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/ExampleExporter.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/ExampleExporter.java similarity index 100% rename from simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/ExampleExporter.java rename to simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/ExampleExporter.java diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java similarity index 100% rename from simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java rename to simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpRequest.java diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java similarity index 100% rename from simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java rename to simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/HttpResponse.java diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java similarity index 100% rename from simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java rename to simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java diff --git a/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java similarity index 100% rename from simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java rename to simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java diff --git a/simpleclient_httpserver/src/test/resources/keystore.pkcs12 b/simpleclient-archive/simpleclient_httpserver/src/test/resources/keystore.pkcs12 similarity index 100% rename from simpleclient_httpserver/src/test/resources/keystore.pkcs12 rename to simpleclient-archive/simpleclient_httpserver/src/test/resources/keystore.pkcs12 diff --git a/simpleclient_httpserver/version-rules.xml b/simpleclient-archive/simpleclient_httpserver/version-rules.xml similarity index 100% rename from simpleclient_httpserver/version-rules.xml rename to simpleclient-archive/simpleclient_httpserver/version-rules.xml diff --git a/simpleclient_jetty/pom.xml b/simpleclient-archive/simpleclient_jetty/pom.xml similarity index 100% rename from simpleclient_jetty/pom.xml rename to simpleclient-archive/simpleclient_jetty/pom.xml diff --git a/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java b/simpleclient-archive/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java similarity index 100% rename from simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java rename to simpleclient-archive/simpleclient_jetty/src/main/java/io/prometheus/client/jetty/JettyStatisticsCollector.java diff --git a/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java similarity index 100% rename from simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java rename to simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java diff --git a/simpleclient_jetty/version-rules.xml b/simpleclient-archive/simpleclient_jetty/version-rules.xml similarity index 100% rename from simpleclient_jetty/version-rules.xml rename to simpleclient-archive/simpleclient_jetty/version-rules.xml diff --git a/simpleclient_jetty_jdk8/pom.xml b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml similarity index 100% rename from simpleclient_jetty_jdk8/pom.xml rename to simpleclient-archive/simpleclient_jetty_jdk8/pom.xml diff --git a/simpleclient_jetty_jdk8/src/main/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollector.java b/simpleclient-archive/simpleclient_jetty_jdk8/src/main/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollector.java similarity index 100% rename from simpleclient_jetty_jdk8/src/main/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollector.java rename to simpleclient-archive/simpleclient_jetty_jdk8/src/main/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollector.java diff --git a/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java similarity index 100% rename from simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java rename to simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java diff --git a/simpleclient_jetty_jdk8/version-rules.xml b/simpleclient-archive/simpleclient_jetty_jdk8/version-rules.xml similarity index 100% rename from simpleclient_jetty_jdk8/version-rules.xml rename to simpleclient-archive/simpleclient_jetty_jdk8/version-rules.xml diff --git a/simpleclient_log4j/pom.xml b/simpleclient-archive/simpleclient_log4j/pom.xml similarity index 100% rename from simpleclient_log4j/pom.xml rename to simpleclient-archive/simpleclient_log4j/pom.xml diff --git a/simpleclient_log4j/src/main/java/io/prometheus/client/log4j/InstrumentedAppender.java b/simpleclient-archive/simpleclient_log4j/src/main/java/io/prometheus/client/log4j/InstrumentedAppender.java similarity index 100% rename from simpleclient_log4j/src/main/java/io/prometheus/client/log4j/InstrumentedAppender.java rename to simpleclient-archive/simpleclient_log4j/src/main/java/io/prometheus/client/log4j/InstrumentedAppender.java diff --git a/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java similarity index 100% rename from simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java rename to simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java diff --git a/simpleclient_log4j/version-rules.xml b/simpleclient-archive/simpleclient_log4j/version-rules.xml similarity index 100% rename from simpleclient_log4j/version-rules.xml rename to simpleclient-archive/simpleclient_log4j/version-rules.xml diff --git a/simpleclient_log4j2/pom.xml b/simpleclient-archive/simpleclient_log4j2/pom.xml similarity index 100% rename from simpleclient_log4j2/pom.xml rename to simpleclient-archive/simpleclient_log4j2/pom.xml diff --git a/simpleclient_log4j2/src/main/java/io/prometheus/client/log4j2/InstrumentedAppender.java b/simpleclient-archive/simpleclient_log4j2/src/main/java/io/prometheus/client/log4j2/InstrumentedAppender.java similarity index 100% rename from simpleclient_log4j2/src/main/java/io/prometheus/client/log4j2/InstrumentedAppender.java rename to simpleclient-archive/simpleclient_log4j2/src/main/java/io/prometheus/client/log4j2/InstrumentedAppender.java diff --git a/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java similarity index 100% rename from simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java rename to simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java diff --git a/simpleclient_log4j2/version-rules.xml b/simpleclient-archive/simpleclient_log4j2/version-rules.xml similarity index 100% rename from simpleclient_log4j2/version-rules.xml rename to simpleclient-archive/simpleclient_log4j2/version-rules.xml diff --git a/simpleclient_logback/pom.xml b/simpleclient-archive/simpleclient_logback/pom.xml similarity index 100% rename from simpleclient_logback/pom.xml rename to simpleclient-archive/simpleclient_logback/pom.xml diff --git a/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java b/simpleclient-archive/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java similarity index 100% rename from simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java rename to simpleclient-archive/simpleclient_logback/src/main/java/io/prometheus/client/logback/InstrumentedAppender.java diff --git a/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java similarity index 100% rename from simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java rename to simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java diff --git a/simpleclient_logback/version-rules.xml b/simpleclient-archive/simpleclient_logback/version-rules.xml similarity index 100% rename from simpleclient_logback/version-rules.xml rename to simpleclient-archive/simpleclient_logback/version-rules.xml diff --git a/simpleclient_pushgateway/pom.xml b/simpleclient-archive/simpleclient_pushgateway/pom.xml similarity index 100% rename from simpleclient_pushgateway/pom.xml rename to simpleclient-archive/simpleclient_pushgateway/pom.xml diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java b/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java similarity index 100% rename from simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java rename to simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java b/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java similarity index 100% rename from simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java rename to simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java b/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java similarity index 100% rename from simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java rename to simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java b/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java similarity index 100% rename from simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java rename to simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java diff --git a/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java similarity index 100% rename from simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java rename to simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java b/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java similarity index 100% rename from simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java rename to simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java b/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java similarity index 100% rename from simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java rename to simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java diff --git a/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java similarity index 100% rename from simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java rename to simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java diff --git a/simpleclient_pushgateway/version-rules.xml b/simpleclient-archive/simpleclient_pushgateway/version-rules.xml similarity index 100% rename from simpleclient_pushgateway/version-rules.xml rename to simpleclient-archive/simpleclient_pushgateway/version-rules.xml diff --git a/simpleclient_servlet/pom.xml b/simpleclient-archive/simpleclient_servlet/pom.xml similarity index 100% rename from simpleclient_servlet/pom.xml rename to simpleclient-archive/simpleclient_servlet/pom.xml diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java b/simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java similarity index 100% rename from simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java rename to simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/exporter/MetricsServlet.java diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java b/simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java similarity index 100% rename from simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java rename to simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/filter/MetricsFilter.java diff --git a/simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java b/simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java similarity index 100% rename from simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java rename to simpleclient-archive/simpleclient_servlet/src/main/java/io/prometheus/client/internal/Adapter.java diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java b/simpleclient-archive/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java similarity index 100% rename from simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java rename to simpleclient-archive/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java diff --git a/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleExporter.java b/simpleclient-archive/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleExporter.java similarity index 100% rename from simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleExporter.java rename to simpleclient-archive/simpleclient_servlet/src/test/java/io/prometheus/client/exporter/ExampleExporter.java diff --git a/simpleclient_servlet/version-rules.xml b/simpleclient-archive/simpleclient_servlet/version-rules.xml similarity index 100% rename from simpleclient_servlet/version-rules.xml rename to simpleclient-archive/simpleclient_servlet/version-rules.xml diff --git a/simpleclient_servlet_common/pom.xml b/simpleclient-archive/simpleclient_servlet_common/pom.xml similarity index 100% rename from simpleclient_servlet_common/pom.xml rename to simpleclient-archive/simpleclient_servlet_common/pom.xml diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/FilterConfigAdapter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletRequestAdapter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/HttpServletResponseAdapter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/adapter/ServletConfigAdapter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/Exporter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/exporter/ServletConfigurationException.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/Filter.java diff --git a/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java b/simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java similarity index 100% rename from simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java rename to simpleclient-archive/simpleclient_servlet_common/src/main/java/io/prometheus/client/servlet/common/filter/FilterConfigurationException.java diff --git a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java similarity index 100% rename from simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java rename to simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java diff --git a/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java similarity index 100% rename from simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java rename to simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java diff --git a/simpleclient_servlet_common/version-rules.xml b/simpleclient-archive/simpleclient_servlet_common/version-rules.xml similarity index 100% rename from simpleclient_servlet_common/version-rules.xml rename to simpleclient-archive/simpleclient_servlet_common/version-rules.xml diff --git a/simpleclient_servlet_jakarta/pom.xml b/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml similarity index 100% rename from simpleclient_servlet_jakarta/pom.xml rename to simpleclient-archive/simpleclient_servlet_jakarta/pom.xml diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java b/simpleclient-archive/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java similarity index 100% rename from simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java rename to simpleclient-archive/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/Adapter.java diff --git a/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java b/simpleclient-archive/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java similarity index 100% rename from simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java rename to simpleclient-archive/simpleclient_servlet_jakarta/src/main/java/io/prometheus/client/servlet/jakarta/filter/MetricsFilter.java diff --git a/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java b/simpleclient-archive/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java similarity index 100% rename from simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java rename to simpleclient-archive/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleBenchmark.java diff --git a/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java b/simpleclient-archive/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java similarity index 100% rename from simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java rename to simpleclient-archive/simpleclient_servlet_jakarta/src/test/java/io/prometheus/client/exporter/ExampleExporter.java diff --git a/simpleclient_servlet_jakarta/version-rules.xml b/simpleclient-archive/simpleclient_servlet_jakarta/version-rules.xml similarity index 100% rename from simpleclient_servlet_jakarta/version-rules.xml rename to simpleclient-archive/simpleclient_servlet_jakarta/version-rules.xml diff --git a/simpleclient_spring_boot/pom.xml b/simpleclient-archive/simpleclient_spring_boot/pom.xml similarity index 100% rename from simpleclient_spring_boot/pom.xml rename to simpleclient-archive/simpleclient_spring_boot/pom.xml diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java diff --git a/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java similarity index 100% rename from simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java rename to simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java similarity index 100% rename from simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java rename to simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java similarity index 100% rename from simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java rename to simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java similarity index 100% rename from simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java rename to simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java similarity index 100% rename from simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java rename to simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java diff --git a/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java similarity index 100% rename from simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java rename to simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java diff --git a/simpleclient_spring_boot/version-rules.xml b/simpleclient-archive/simpleclient_spring_boot/version-rules.xml similarity index 100% rename from simpleclient_spring_boot/version-rules.xml rename to simpleclient-archive/simpleclient_spring_boot/version-rules.xml diff --git a/simpleclient_spring_web/pom.xml b/simpleclient-archive/simpleclient_spring_web/pom.xml similarity index 100% rename from simpleclient_spring_web/pom.xml rename to simpleclient-archive/simpleclient_spring_web/pom.xml diff --git a/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/EnablePrometheusTiming.java b/simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/EnablePrometheusTiming.java similarity index 100% rename from simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/EnablePrometheusTiming.java rename to simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/EnablePrometheusTiming.java diff --git a/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/MethodTimer.java b/simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/MethodTimer.java similarity index 100% rename from simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/MethodTimer.java rename to simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/MethodTimer.java diff --git a/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/PrometheusTimeMethod.java b/simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/PrometheusTimeMethod.java similarity index 100% rename from simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/PrometheusTimeMethod.java rename to simpleclient-archive/simpleclient_spring_web/src/main/java/io/prometheus/client/spring/web/PrometheusTimeMethod.java diff --git a/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java similarity index 100% rename from simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java rename to simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java diff --git a/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java similarity index 100% rename from simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java rename to simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java diff --git a/simpleclient_spring_web/version-rules.xml b/simpleclient-archive/simpleclient_spring_web/version-rules.xml similarity index 100% rename from simpleclient_spring_web/version-rules.xml rename to simpleclient-archive/simpleclient_spring_web/version-rules.xml diff --git a/simpleclient_vertx/pom.xml b/simpleclient-archive/simpleclient_vertx/pom.xml similarity index 100% rename from simpleclient_vertx/pom.xml rename to simpleclient-archive/simpleclient_vertx/pom.xml diff --git a/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java b/simpleclient-archive/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java similarity index 100% rename from simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java rename to simpleclient-archive/simpleclient_vertx/src/main/java/io/prometheus/client/vertx/MetricsHandler.java diff --git a/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/ExampleExporter.java b/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/ExampleExporter.java similarity index 100% rename from simpleclient_vertx/src/test/java/io/prometheus/client/vertx/ExampleExporter.java rename to simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/ExampleExporter.java diff --git a/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java b/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java similarity index 100% rename from simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java rename to simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java diff --git a/simpleclient_vertx/version-rules.xml b/simpleclient-archive/simpleclient_vertx/version-rules.xml similarity index 100% rename from simpleclient_vertx/version-rules.xml rename to simpleclient-archive/simpleclient_vertx/version-rules.xml diff --git a/simpleclient_vertx4/pom.xml b/simpleclient-archive/simpleclient_vertx4/pom.xml similarity index 100% rename from simpleclient_vertx4/pom.xml rename to simpleclient-archive/simpleclient_vertx4/pom.xml diff --git a/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java b/simpleclient-archive/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java similarity index 100% rename from simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java rename to simpleclient-archive/simpleclient_vertx4/src/main/java/io/prometheus/client/vertx/MetricsHandler.java diff --git a/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java b/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java similarity index 100% rename from simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java rename to simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/ExampleExporter.java diff --git a/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java b/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java similarity index 100% rename from simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java rename to simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java diff --git a/simpleclient_vertx4/version-rules.xml b/simpleclient-archive/simpleclient_vertx4/version-rules.xml similarity index 100% rename from simpleclient_vertx4/version-rules.xml rename to simpleclient-archive/simpleclient_vertx4/version-rules.xml From d26a5f3dc1b2e349b40ecb5e48371cfea2b288a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 16:04:12 +0200 Subject: [PATCH 244/980] Resolve merge conflicts with unit tests --- pom.xml | 28 +- prometheus-metrics-core/pom.xml | 10 +- .../metrics/core/datapoints/TimerApiTest.java | 23 +- .../core/metrics/CKMSQuantilesTest.java | 6 +- .../core/metrics/CounterWithCallbackTest.java | 91 +---- .../core/metrics/GaugeWithCallbackTest.java | 65 +--- .../metrics/core/metrics/SummaryTest.java | 232 +----------- .../core/metrics/SummaryWithCallbackTest.java | 68 +--- .../model/registry/MetricNameFilterTest.java | 341 +++--------------- 9 files changed, 80 insertions(+), 784 deletions(-) diff --git a/pom.xml b/pom.xml index 0aecb9e0d..864672026 100644 --- a/pom.xml +++ b/pom.xml @@ -60,34 +60,8 @@ prometheus-metrics-simpleclient-bridge examples - integration-tests - - simpleclient - simpleclient_common - simpleclient_caffeine - simpleclient_dropwizard - simpleclient_graphite_bridge - simpleclient_hibernate - simpleclient_guava - simpleclient_hotspot - simpleclient_httpserver - simpleclient_log4j - simpleclient_log4j2 - simpleclient_logback - simpleclient_pushgateway - simpleclient_servlet - simpleclient_servlet_common - simpleclient_servlet_jakarta - simpleclient_spring_web - - simpleclient_jetty - simpleclient_jetty_jdk8 - simpleclient_tracer - simpleclient_vertx - simpleclient_vertx4 - simpleclient_bom benchmarks - integration_tests + integration-tests diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index d24afafe1..7670d32b2 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -48,14 +48,20 @@ prometheus-metrics-tracer-initializer ${project.version} + + io.prometheus prometheus-metrics-exposition-formats ${project.version} test - - + + org.apache.commons + commons-math3 + 3.6.1 + test + junit junit diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java index d988ae703..4ae0cd0bb 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java @@ -1,23 +1,6 @@ -package io.prometheus.client; +package io.prometheus.metrics.core.datapoints; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class SimpleTimerTest { - @Test - public void elapsedSeconds() throws Exception { - SimpleTimer.TimeProvider provider = new SimpleTimer.TimeProvider() { - long value = (long)(30 * 1e9); - long nanoTime() { - value += (long)(10 * 1e9); - return value; - } - }; - - SimpleTimer timer = new SimpleTimer(provider); - assertEquals(10, timer.elapsedSeconds(), .001); - - } +public class TimerApiTest { + // TODO: Port this from the simpleclient SimpleTimerTest } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java index f00371fec..ef90f85cf 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java @@ -1,6 +1,6 @@ -package io.prometheus.client; +package io.prometheus.metrics.core.metrics; -import io.prometheus.client.CKMSQuantiles.Quantile; +import io.prometheus.metrics.core.metrics.CKMSQuantiles.Quantile; import org.apache.commons.math3.distribution.NormalDistribution; import org.apache.commons.math3.random.JDKRandomGenerator; import org.apache.commons.math3.random.RandomGenerator; @@ -337,4 +337,4 @@ private void validateResults(CKMSQuantiles ckms) { assertTrue(errorMessage, ok); } } -} \ No newline at end of file +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java index ffa8396a4..f7c18666d 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java @@ -1,91 +1,6 @@ -package io.prometheus.client; +package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import org.junit.Before; -import org.junit.Test; - - -public class CounterMetricFamilyTest { - - CollectorRegistry registry; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - } - - @Test - public void testJavadocExample() { - class YourCustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - // With no labels. - mfs.add(new CounterMetricFamily("my_counter", "help", 42)); - // With labels - CounterMetricFamily labeledCounter = new CounterMetricFamily("my_other_counter", "help", Arrays.asList("labelname")); - labeledCounter.addMetric(Arrays.asList("foo"), 4); - labeledCounter.addMetric(Arrays.asList("bar"), 5); - mfs.add(labeledCounter); - return mfs; - } - } - new YourCustomCollector().register(registry); - - assertEquals(42.0, registry.getSampleValue("my_counter_total").doubleValue(), .001); - assertEquals(null, registry.getSampleValue("my_other_counter_total")); - assertEquals(4.0, registry.getSampleValue("my_other_counter_total", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001); - assertEquals(5.0, registry.getSampleValue("my_other_counter_total", new String[]{"labelname"}, new String[]{"bar"}).doubleValue(), .001); - } - - @Test - public void testBuilderStyleUsage() { - class YourCustomCollector extends Collector { - public List collect() { - return Arrays.asList( - new CounterMetricFamily("my_metric", "help", Arrays.asList("name")) - .addMetric(Arrays.asList("value1"), 1.0) - .addMetric(Arrays.asList("value2"), 2.0) - ); - } - } - new YourCustomCollector().register(registry); - - assertEquals(1.0, - registry.getSampleValue("my_metric_total", new String[]{"name"}, new String[]{"value1"}) - .doubleValue(), .001); - assertEquals(2.0, - registry.getSampleValue("my_metric_total", new String[]{"name"}, new String[]{"value2"}) - .doubleValue(), .001); - } - - @Test - public void testTotalHandling() { - class YourCustomCollector extends Collector { - public List collect() { - return Arrays.asList( - new CounterMetricFamily("a_total", "help", Arrays.asList("name")) - .addMetric(Arrays.asList("value"), 1.0), - new CounterMetricFamily("b", "help", Arrays.asList("name")) - .addMetric(Arrays.asList("value"), 2.0), - new CounterMetricFamily("c_total", "help", 3.0), - new CounterMetricFamily("d_total", "help", 4.0) - ); - } - } - new YourCustomCollector().register(registry); - - assertEquals(1.0, - registry.getSampleValue("a_total", new String[]{"name"}, new String[]{"value"}) - .doubleValue(), .001); - assertEquals(2.0, - registry.getSampleValue("b_total", new String[]{"name"}, new String[]{"value"}) - .doubleValue(), .001); - assertEquals(3.0, registry.getSampleValue("c_total").doubleValue(), .001); - assertEquals(4.0, registry.getSampleValue("d_total").doubleValue(), .001); - } +public class CounterWithCallbackTest { + // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java index 06373dbd0..f8f54aa69 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java @@ -1,65 +1,6 @@ -package io.prometheus.client; +package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import org.junit.Before; -import org.junit.Test; - - -public class GaugeMetricFamilyTest { - - CollectorRegistry registry; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - } - - @Test - public void testJavadocExample() { - class YourCustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - // With no labels. - mfs.add(new GaugeMetricFamily("my_gauge", "help", 42)); - // With labels - GaugeMetricFamily labeledGauge = new GaugeMetricFamily("my_other_gauge", "help", Arrays.asList("labelname")); - labeledGauge.addMetric(Arrays.asList("foo"), 4); - labeledGauge.addMetric(Arrays.asList("bar"), 5); - mfs.add(labeledGauge); - return mfs; - } - } - new YourCustomCollector().register(registry); - - assertEquals(42.0, registry.getSampleValue("my_gauge").doubleValue(), .001); - assertEquals(null, registry.getSampleValue("my_other_gauge")); - assertEquals(4.0, registry.getSampleValue("my_other_gauge", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001); - assertEquals(5.0, registry.getSampleValue("my_other_gauge", new String[]{"labelname"}, new String[]{"bar"}).doubleValue(), .001); - } - - @Test - public void testBuilderStyleUsage() { - class YourCustomCollector extends Collector { - public List collect() { - return Arrays.asList( - new GaugeMetricFamily("my_metric", "help", Arrays.asList("name")) - .addMetric(Arrays.asList("value1"), 1.0) - .addMetric(Arrays.asList("value2"), 2.0) - ); - } - } - new YourCustomCollector().register(registry); - - assertEquals(1.0, - registry.getSampleValue("my_metric", new String[]{"name"}, new String[]{"value1"}) - .doubleValue(), .001); - assertEquals(2.0, - registry.getSampleValue("my_metric", new String[]{"name"}, new String[]{"value2"}) - .doubleValue(), .001); - } +public class GaugeWithCallbackTest { + // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java index f135e98e9..d5bc791a8 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java @@ -1,233 +1,5 @@ -package io.prometheus.client; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; - -import static java.util.Arrays.asList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - +package io.prometheus.metrics.core.metrics; public class SummaryTest { - - CollectorRegistry registry; - Summary noLabels, labels, labelsAndQuantiles, noLabelsAndQuantiles; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - noLabels = Summary.build().name("nolabels").help("help").register(registry); - labels = Summary.build().name("labels").help("help").labelNames("l").register(registry); - noLabelsAndQuantiles = Summary.build() - .quantile(0.5, 0.05) - .quantile(0.9, 0.01) - .quantile(0.99, 0.001) - .name("no_labels_and_quantiles").help("help").register(registry); - labelsAndQuantiles = Summary.build() - .quantile(0.5, 0.05) - .quantile(0.9, 0.01) - .quantile(0.99, 0.001) - .labelNames("l") - .name("labels_and_quantiles").help("help").register(registry); - } - - @After - public void tearDown() { - SimpleTimer.defaultTimeProvider = new SimpleTimer.TimeProvider(); - } - - private double getCount() { - return registry.getSampleValue("nolabels_count").doubleValue(); - } - private double getSum() { - return registry.getSampleValue("nolabels_sum").doubleValue(); - } - private double getNoLabelQuantile(double q) { - return registry.getSampleValue("no_labels_and_quantiles", new String[]{"quantile"}, new String[]{Collector.doubleToGoString(q)}).doubleValue(); - } - private double getLabeledQuantile(String labelValue, double q) { - return registry.getSampleValue("labels_and_quantiles", new String[]{"l", "quantile"}, new String[]{labelValue, Collector.doubleToGoString(q)}).doubleValue(); - } - - @Test - public void testObserve() { - noLabels.observe(2); - assertEquals(1.0, getCount(), .001); - assertEquals(2.0, getSum(), .001); - assertEquals(1.0, noLabels.get().count, .001); - assertEquals(2.0, noLabels.get().sum, .001); - noLabels.labels().observe(4); - assertEquals(2.0, getCount(), .001); - assertEquals(6.0, getSum(), .001); - assertEquals(2.0, noLabels.get().count, .001); - assertEquals(6.0, noLabels.get().sum, .001); - } - - @Test - // See https://github.com/prometheus/client_java/issues/646 - public void testNegativeAmount() { - noLabels.observe(-1); - noLabels.observe(-3); - assertEquals(2.0, getCount(), .001); - assertEquals(-4.0, getSum(), .001); - } - - @Test - public void testQuantiles() { - int nSamples = 1000000; // simulate one million samples - - for (int i=1; i<=nSamples; i++) { - // In this test, we observe the numbers from 1 to nSamples, - // because that makes it easy to verify if the quantiles are correct. - labelsAndQuantiles.labels("a").observe(i); - noLabelsAndQuantiles.observe(i); - } - assertEquals(getNoLabelQuantile(0.5), 0.5 * nSamples, 0.05 * nSamples); - assertEquals(getNoLabelQuantile(0.9), 0.9 * nSamples, 0.01 * nSamples); - assertEquals(getNoLabelQuantile(0.99), 0.99 * nSamples, 0.001 * nSamples); - - assertEquals(getLabeledQuantile("a", 0.5), 0.5 * nSamples, 0.05 * nSamples); - assertEquals(getLabeledQuantile("a", 0.9), 0.9 * nSamples, 0.01 * nSamples); - assertEquals(getLabeledQuantile("a", 0.99), 0.99 * nSamples, 0.001 * nSamples); - } - - @Test - public void testMaxAge() throws InterruptedException { - Summary summary = Summary.build() - .quantile(0.99, 0.001) - .maxAgeSeconds(1) // After 1s, all observations will be discarded. - .ageBuckets(2) // We got 2 buckets, so we discard one bucket every 500ms. - .name("short_attention_span").help("help").register(registry); - summary.observe(8.0); - double val = registry.getSampleValue("short_attention_span", new String[]{"quantile"}, new String[]{Collector.doubleToGoString(0.99)}).doubleValue(); - assertEquals(8.0, val, 0.0); // From bucket 1. - Thread.sleep(600); - val = registry.getSampleValue("short_attention_span", new String[]{"quantile"}, new String[]{Collector.doubleToGoString(0.99)}).doubleValue(); - assertEquals(8.0, val, 0.0); // From bucket 2. - Thread.sleep(600); - val = registry.getSampleValue("short_attention_span", new String[]{"quantile"}, new String[]{Collector.doubleToGoString(0.99)}).doubleValue(); - assertEquals(Double.NaN, val, 0.0); // Bucket 1 again, now it is empty. - } - - @Test - public void testTimer() { - SimpleTimer.defaultTimeProvider = new SimpleTimer.TimeProvider() { - long value = (long)(30 * 1e9); - long nanoTime() { - value += (long)(10 * 1e9); - return value; - } - }; - - double elapsed = noLabels.time(new Runnable() { - @Override - public void run() { - //no op - } - }); - assertEquals(10, elapsed, .001); - - int result = noLabels.time(new Callable() { - @Override - public Integer call() { - return 123; - } - }); - assertEquals(123, result); - - Summary.Timer timer = noLabels.startTimer(); - elapsed = timer.observeDuration(); - assertEquals(3, getCount(), .001); - assertEquals(30, getSum(), .001); - assertEquals(10, elapsed, .001); - } - - @Test - public void noLabelsDefaultZeroValue() { - assertEquals(0.0, getCount(), .001); - assertEquals(0.0, getSum(), .001); - } - - private Double getLabelsCount(String labelValue) { - return registry.getSampleValue("labels_count", new String[]{"l"}, new String[]{labelValue}); - } - private Double getLabelsSum(String labelValue) { - return registry.getSampleValue("labels_sum", new String[]{"l"}, new String[]{labelValue}); - } - - @Test - public void testLabels() { - assertEquals(null, getLabelsCount("a")); - assertEquals(null, getLabelsSum("a")); - assertEquals(null, getLabelsCount("b")); - assertEquals(null, getLabelsSum("b")); - labels.labels("a").observe(2); - assertEquals(1.0, getLabelsCount("a").doubleValue(), .001); - assertEquals(2.0, getLabelsSum("a").doubleValue(), .001); - assertEquals(null, getLabelsCount("b")); - assertEquals(null, getLabelsSum("b")); - labels.labels("b").observe(3); - assertEquals(1.0, getLabelsCount("a").doubleValue(), .001); - assertEquals(2.0, getLabelsSum("a").doubleValue(), .001); - assertEquals(1.0, getLabelsCount("b").doubleValue(), .001); - assertEquals(3.0, getLabelsSum("b").doubleValue(), .001); - } - - @Test - public void testCollect() { - labels.labels("a").observe(2); - List mfs = labels.collect(); - - ArrayList samples = new ArrayList(); - ArrayList labelNames = new ArrayList(); - labelNames.add("l"); - ArrayList labelValues = new ArrayList(); - labelValues.add("a"); - samples.add(new Collector.MetricFamilySamples.Sample("labels_count", labelNames, labelValues, 1.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_sum", labelNames, labelValues, 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_created", labelNames, labelValues, labels.labels("a").get().created / 1000.0)); - Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels", Collector.Type.SUMMARY, "help", samples); - - assertEquals(1, mfs.size()); - assertEquals(mfsFixture, mfs.get(0)); - } - - @Test - public void testCollectWithQuantiles() { - labelsAndQuantiles.labels("a").observe(2); - List mfs = labelsAndQuantiles.collect(); - - ArrayList samples = new ArrayList(); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles", asList("l", "quantile"), asList("a", "0.5"), 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles", asList("l", "quantile"), asList("a", "0.9"), 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles", asList("l", "quantile"), asList("a", "0.99"), 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_count", asList("l"), asList("a"), 1.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_sum", asList("l"), asList("a"), 2.0)); - samples.add(new Collector.MetricFamilySamples.Sample("labels_and_quantiles_created", asList("l"), asList("a"), labelsAndQuantiles.labels("a").get().created / 1000.0)); - Collector.MetricFamilySamples mfsFixture = new Collector.MetricFamilySamples("labels_and_quantiles", Collector.Type.SUMMARY, "help", samples); - - assertEquals(1, mfs.size()); - assertEquals(mfsFixture, mfs.get(0)); - } - - @Test - public void testChildAndValuePublicApi() throws Exception { - assertTrue(Modifier.isPublic(Summary.Child.class.getModifiers())); - - final Method getMethod = Summary.Child.class.getMethod("get"); - assertTrue(Modifier.isPublic(getMethod.getModifiers())); - assertEquals(Summary.Child.Value.class, getMethod.getReturnType()); - - assertTrue(Modifier.isPublic(Summary.Child.Value.class.getModifiers())); - assertTrue(Modifier.isPublic(Summary.Child.Value.class.getField("count").getModifiers())); - assertTrue(Modifier.isPublic(Summary.Child.Value.class.getField("sum").getModifiers())); - assertTrue(Modifier.isPublic(Summary.Child.Value.class.getField("quantiles").getModifiers())); - } + // TODO, port the SummaryTest from simpleclient over. } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java index 23dd488d6..cbd9ef53f 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java @@ -1,68 +1,6 @@ -package io.prometheus.client; +package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; -import org.junit.Before; -import org.junit.Test; - - -public class SummaryMetricFamilyTest { - - CollectorRegistry registry; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - } - - @Test - public void testJavadocExample() { - class YourCustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - // With no labels. - mfs.add(new SummaryMetricFamily("my_summary", "help", 1, 42)); - // With labels. Record 95th percentile as 3, and 99th percentile as 5. - SummaryMetricFamily labeledSummary = new SummaryMetricFamily("my_other_summary", "help", - Arrays.asList("labelname"), Arrays.asList(.95, .99)); - labeledSummary.addMetric(Arrays.asList("foo"), 2, 10, Arrays.asList(3.0, 5.0)); - mfs.add(labeledSummary); - return mfs; - } - } - new YourCustomCollector().register(registry); - - assertEquals(1.0, registry.getSampleValue("my_summary_count").doubleValue(), .001); - assertEquals(42.0, registry.getSampleValue("my_summary_sum").doubleValue(), .001); - - assertEquals(2.0, registry.getSampleValue("my_other_summary_count", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001); - assertEquals(10.0, registry.getSampleValue("my_other_summary_sum", new String[]{"labelname"}, new String[]{"foo"}).doubleValue(), .001); - assertEquals(3.0, registry.getSampleValue("my_other_summary", new String[]{"labelname", "quantile"}, new String[]{"foo", "0.95"}).doubleValue(), .001); - assertEquals(5.0, registry.getSampleValue("my_other_summary", new String[]{"labelname", "quantile"}, new String[]{"foo", "0.99"}).doubleValue(), .001); - } - - @Test - public void testBuilderStyleUsage() { - class YourCustomCollector extends Collector { - public List collect() { - return Arrays.asList( - new SummaryMetricFamily("my_metric", "help", Arrays.asList("name")) - .addMetric(Arrays.asList("value1"), 1, 1.0) - .addMetric(Arrays.asList("value2"), 2, 2.0) - ); - } - } - new YourCustomCollector().register(registry); - - assertEquals(1.0, - registry.getSampleValue("my_metric_count", new String[]{"name"}, new String[]{"value1"}) - .doubleValue(), .001); - assertEquals(2.0, - registry.getSampleValue("my_metric_count", new String[]{"name"}, new String[]{"value2"}) - .doubleValue(), .001); - } +public class SummaryWithCallbackTest { + // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. } 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 b2c9f157b..3b74f9dee 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 @@ -1,304 +1,71 @@ -package io.prometheus.client; +package io.prometheus.metrics.model.registry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +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.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +public class MetricNameFilterTest { -import static org.junit.Assert.assertEquals; - -public class SampleNameFilterTest { - - private CollectorRegistry registry; + private PrometheusRegistry registry; @Before public void setUp() { - registry = new CollectorRegistry(true); + registry = new PrometheusRegistry(); } @Test public void testCounter() { - // It should not make any difference whether a counter is created as "my_counter" or as "my_counter_total". - // We test both ways here and expect the same output. - for (String suffix : new String[] { "", "_total"}) { - registry.clear(); - Counter counter1 = Counter.build() - .name("counter1" + suffix) - .help("test counter 1") - .labelNames("path") - .register(registry); - counter1.labels("/hello").inc(); - counter1.labels("/goodbye").inc(); - Counter counter2 = Counter.build() - .name("counter2" + suffix) - .help("test counter 2") - .register(registry); - counter2.inc(); - - SampleNameFilter filter = new SampleNameFilter.Builder().build(); - List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter1_total", 2); - assertSamplesInclude(mfsList, "counter1_created", 2); - assertSamplesInclude(mfsList, "counter2_total", 1); - assertSamplesInclude(mfsList, "counter2_created", 1); - assertTotalNumberOfSamples(mfsList, 6); - - filter = new SampleNameFilter.Builder().nameMustStartWith("counter1").build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter1_total", 2); - assertSamplesInclude(mfsList, "counter1_created", 2); - assertTotalNumberOfSamples(mfsList, 4); - - filter = new SampleNameFilter.Builder().nameMustNotStartWith("counter1").build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter2_total", 1); - assertSamplesInclude(mfsList, "counter2_created", 1); - assertTotalNumberOfSamples(mfsList, 2); - - filter = new SampleNameFilter.Builder() - .nameMustBeEqualTo("counter2_total") - .nameMustBeEqualTo("counter1_total") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter1_total", 2); - assertSamplesInclude(mfsList, "counter2_total", 1); - assertTotalNumberOfSamples(mfsList, 3); - - filter = new SampleNameFilter.Builder() - .nameMustStartWith("counter1") - .nameMustNotStartWith("counter1_created") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter1_total", 2); - assertTotalNumberOfSamples(mfsList, 2); - - // The following filter would be weird in practice, but let's test this anyways :) - filter = new SampleNameFilter.Builder() - .nameMustBeEqualTo("counter1_created") - .nameMustBeEqualTo("counter2_created") - .nameMustNotStartWith("counter1") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "counter2_created", 1); - assertTotalNumberOfSamples(mfsList, 1); - - // And finally one that should not match anything - filter = new SampleNameFilter.Builder() - .nameMustBeEqualTo("counter1_total") - .nameMustNotBeEqualTo("counter1_total") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertTotalNumberOfSamples(mfsList, 0); - - } - } - - @Test - public void testCustomCollector() { - Collector myCollector = new Collector() { - @Override - public List collect() { - List result = new ArrayList(); - - String name = "temperature_centigrade"; - List labelNames = Collections.singletonList("location"); - GaugeMetricFamily temperatureCentigrade = new GaugeMetricFamily(name, "temperature centigrade", labelNames); - temperatureCentigrade.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("outside"), 26.0)); - temperatureCentigrade.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("inside"), 22.0)); - result.add(temperatureCentigrade); - - name = "temperature_fahrenheit"; - GaugeMetricFamily temperatureFahrenheit = new GaugeMetricFamily(name, "temperature fahrenheit", labelNames); - temperatureFahrenheit.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("outside"), 78.8)); - temperatureFahrenheit.samples.add(new MetricFamilySamples.Sample(name, labelNames, Collections.singletonList("inside"), 71.6)); - result.add(temperatureFahrenheit); - - return result; - } - }; - registry.register(myCollector); - - SampleNameFilter filter = new SampleNameFilter.Builder() - .nameMustStartWith("temperature_centigrade") - .build(); - List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "temperature_centigrade", 2); - assertTotalNumberOfSamples(mfsList, 2); - - filter = new SampleNameFilter.Builder() - .nameMustNotStartWith("temperature_centigrade") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "temperature_fahrenheit", 2); - assertTotalNumberOfSamples(mfsList, 2); - - filter = new SampleNameFilter.Builder() - .nameMustNotStartWith("temperature") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertTotalNumberOfSamples(mfsList, 0); - - filter = new SampleNameFilter.Builder() - .nameMustBeEqualTo("temperature_centigrade") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "temperature_centigrade", 2); - assertTotalNumberOfSamples(mfsList, 2); - - filter = new SampleNameFilter.Builder() - .nameMustNotBeEqualTo("temperature_centigrade") + registry.register(() -> CounterSnapshot.builder() + .name("counter1") + .help("test counter 1") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/hello")) + .value(1.0) + .build() + ) + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/goodbye")) + .value(2.0) + .build() + ) + .build() + ); + registry.register(() -> CounterSnapshot.builder() + .name("counter2") + .help("test counter 2") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .value(1.0) + .build() + ) + .build() + ); + + 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().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(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "temperature_fahrenheit", 2); - assertTotalNumberOfSamples(mfsList, 2); + snapshots = registry.scrape(filter); + Assert.assertEquals(2, snapshots.size()); - filter = new SampleNameFilter.Builder() - .nameMustStartWith("temperature_c") + filter = MetricNameFilter.builder() + .nameMustBeEqualTo("counter1_total") + .nameMustNotBeEqualTo("counter1_total") .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "temperature_centigrade", 2); - assertTotalNumberOfSamples(mfsList, 2); - } - - @Test - public void testHistogram() { - Histogram histogram = Histogram.build() - .name("test_histogram") - .help("test histogram") - .create(); - histogram.observe(100); - histogram.observe(200); - registry.register(histogram); - - SampleNameFilter filter = new SampleNameFilter.Builder().build(); - List mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "test_histogram_bucket", 15); - assertSamplesInclude(mfsList, "test_histogram_count", 1); - assertSamplesInclude(mfsList, "test_histogram_sum", 1); - assertSamplesInclude(mfsList, "test_histogram_created", 1); - assertTotalNumberOfSamples(mfsList, 18); - - filter = new SampleNameFilter.Builder() - .nameMustStartWith("test_histogram") - // nameMustStartWith() is for the names[] query parameter in HTTP exporters. - // If histogram_created is missing in the names[] list, it should not be exported - // even though includePrefixes matches histogram_created. - .nameMustBeEqualTo("test_histogram_bucket") - .nameMustBeEqualTo("test_histogram_count") - .nameMustBeEqualTo("test_histogram_sum") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "test_histogram_bucket", 15); - assertSamplesInclude(mfsList, "test_histogram_count", 1); - assertSamplesInclude(mfsList, "test_histogram_sum", 1); - assertTotalNumberOfSamples(mfsList, 17); - - filter = new SampleNameFilter.Builder() - .nameMustStartWith("test_histogram") - // histogram without buckets - .nameMustNotStartWith("test_histogram_bucket") - .build(); - mfsList = Collections.list(registry.filteredMetricFamilySamples(filter)); - assertSamplesInclude(mfsList, "test_histogram_count", 1); - assertSamplesInclude(mfsList, "test_histogram_sum", 1); - assertSamplesInclude(mfsList, "test_histogram_created", 1); - assertTotalNumberOfSamples(mfsList, 3); - } - - /** - * Before {@link SampleNameFilter} was introduced, the {@link CollectorRegistry#filteredMetricFamilySamples(Set)} - * method could be used to pass included names directly. That method still there for compatibility. - * This is the original test copied over from {@link CollectorRegistryTest}. - */ - @Test - public void testLegacyApi() { - Gauge.build().name("g").help("h").register(registry); - Counter.build().name("c").help("h").register(registry); - Summary.build().name("s").help("h").register(registry); - new EmptyCollector().register(registry); - SkippedCollector sr = new SkippedCollector().register(registry); - PartiallyFilterCollector pfr = new PartiallyFilterCollector().register(registry); - HashSet metrics = new HashSet(); - HashSet series = new HashSet(); - Set includedNames = new HashSet(Arrays.asList("", "s_sum", "c_total", "part_filter_a", "part_filter_c")); - List mfsList = Collections.list(registry.filteredMetricFamilySamples(includedNames)); - for (Collector.MetricFamilySamples metricFamilySamples : mfsList) { - metrics.add(metricFamilySamples.name); - for (Collector.MetricFamilySamples.Sample sample : metricFamilySamples.samples) { - series.add(sample.name); - } - } - assertEquals(1, sr.collectCallCount); - assertEquals(2, pfr.collectCallCount); - assertEquals(new HashSet(Arrays.asList("s", "c", "part_filter_a", "part_filter_c")), metrics); - assertEquals(new HashSet(Arrays.asList("s_sum", "c_total", "part_filter_a", "part_filter_c")), series); - } - - private static class EmptyCollector extends Collector { - public List collect() { - return new ArrayList(); - } - } - - private static class SkippedCollector extends Collector implements Collector.Describable { - public int collectCallCount = 0; - - @Override - public List collect() { - collectCallCount++; - List mfs = new ArrayList(); - mfs.add(new GaugeMetricFamily("slow_gauge", "help", 123)); - return mfs; - } - - @Override - public List describe() { - return collect(); - } - } - - private static class PartiallyFilterCollector extends Collector implements Collector.Describable { - public int collectCallCount = 0; - - @Override - public List collect() { - collectCallCount++; - List mfs = new ArrayList(); - mfs.add(new GaugeMetricFamily("part_filter_a", "help", 123)); - mfs.add(new GaugeMetricFamily("part_filter_b", "help", 123)); - mfs.add(new GaugeMetricFamily("part_filter_c", "help", 123)); - return mfs; - } - - @Override - public List describe() { - return collect(); - } - } - - private void assertSamplesInclude(List mfsList, String name, int times) { - int count = 0; - for (Collector.MetricFamilySamples mfs : mfsList) { - for (Collector.MetricFamilySamples.Sample sample : mfs.samples) { - if (sample.name.equals(name)) { - count++; - } - } - } - Assert.assertEquals("Wrong number of samples for " + name, times, count); - } - - private void assertTotalNumberOfSamples(List mfsList, int n) { - int count = 0; - for (Collector.MetricFamilySamples mfs : mfsList) { - count += mfs.samples.size(); - } - Assert.assertEquals("Wrong total number of samples", n, count); + Assert.assertEquals(0, registry.scrape(filter).size()); } -} \ No newline at end of file +} From 83f133302f109a47b492981ba0dcc843965a1e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 17:31:21 +0200 Subject: [PATCH 245/980] Update README.md for the 1.0.0 release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- README.md | 918 +-------------------------------- simpleclient-archive/README.md | 3 + 2 files changed, 14 insertions(+), 907 deletions(-) create mode 100644 simpleclient-archive/README.md diff --git a/README.md b/README.md index b8655dea7..bcab4daf1 100644 --- a/README.md +++ b/README.md @@ -1,919 +1,23 @@ -# Prometheus JVM Client -It supports Java, Clojure, Scala, JRuby, and anything else that runs on the JVM. +# Prometheus Java Metrics Library [![Build Status](https://circleci.com/gh/prometheus/client_java.svg?style=svg)](https://circleci.com/gh/prometheus/client_java) +Release date for 1.0.0 is 27 Sep 2023. Pre-releases are [available](https://github.com/prometheus/client_java/releases). -Table of Contents -================= +# Documentation - * [Using](#using) - * [Assets](#assets) - * [Javadocs](#javadocs) - * [Building](#building) - * [Instrumenting](#instrumenting) - * [Counter](#counter) - * [Gauge](#gauge) - * [Summary](#summary) - * [Histogram](#histogram) - * [Labels](#labels) - * [Registering Metrics](#registering-metrics) - * [Exemplars](#exemplars) - * [Global Exemplar Samplers](#global-exemplar-samplers) - * [Per Metric Exemplar Samplers](#per-metric-exemplar-samplers) - * [Per Observation Exemplars](#per-observation-exemplars) - * [Built-in Support for Tracing Systems](#built-in-support-for-tracing-systems) - * [Included Collectors](#included-collectors) - * [Logging](#logging) - * [Caches](#caches) - * [Hibernate](#hibernate) - * [Jetty](#jetty) - * [Exporting](#exporting) - * [HTTP](#http) - * [Exporting to a Pushgateway](#exporting-to-a-pushgateway) - * [Bridges](#bridges) - * [Graphite](#graphite) - * [Custom Collectors](#custom-collectors) - * [Contact](#contact) +[https://prometheus.github.io/client_java](https://prometheus.github.io/client_java) -## Using -### Assets -If you use Maven, you can simply reference the assets below. The latest -version can be found on in the maven repository for -[io.prometheus](http://mvnrepository.com/artifact/io.prometheus). +# Contributing and community -```xml - - - io.prometheus - simpleclient - 0.16.0 - - - - io.prometheus - simpleclient_hotspot - 0.16.0 - - - - io.prometheus - simpleclient_httpserver - 0.16.0 - - - - io.prometheus - simpleclient_pushgateway - 0.16.0 - -``` +See [CONTRIBUTING.md](CONTRIBUTING.md) and the [community section](http://prometheus.io/community/) of the Prometheus homepage. -### Javadocs -There are canonical examples defined in the class definition Javadoc of the client packages. +The Prometheus Java community is present on the [CNCF Slack](https://cloud-native.slack.com) on `#prometheus-java`, and we have a fortnightly community call in the [Prometheus public calendar](https://prometheus.io/community/). -Documentation can be found at the [Java Client -Github Project Page](http://prometheus.github.io/client_java). +# Previous Releases -### Disabling `_created` metrics +The source code for 0.16.0 and older is on the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) branch. -By default, counters, histograms, and summaries export an additional series -suffixed with `_created` and a value of the unix timestamp for when the metric -was created. If this information is not helpful, it can be disabled by setting -the environment variable `PROMETHEUS_DISABLE_CREATED_SERIES=true`. +# License -## Building - -Building the repository needs Java 11 (The project the project still supports Java 6 and Java versions > 11 dropped support for Java 6 output). We recommend to use an [up-to-data Java 8 installation](https://adoptium.net/en-GB/marketplace/?version=8). The project provides the maven wrapper and therefore no local maven installation is needed. To build the repository just call `./mvnw verify`. - -## Instrumenting - -Four types of metrics are offered: Counter, Gauge, Summary and Histogram. -See the documentation on [metric types](http://prometheus.io/docs/concepts/metric_types/) -and [instrumentation best practices](http://prometheus.io/docs/practices/instrumentation/#counter-vs.-gauge,-summary-vs.-histogram) -on how to use them. - -### Counter - -Counters go up, and reset when the process restarts. - - -```java -import io.prometheus.client.Counter; -class YourClass { - static final Counter requests = Counter.build() - .name("requests_total").help("Total requests.").register(); - - void processRequest() { - requests.inc(); - // Your code here. - } -} -``` - -### Gauge - -Gauges can go up and down. - -```java -class YourClass { - static final Gauge inprogressRequests = Gauge.build() - .name("inprogress_requests").help("Inprogress requests.").register(); - - void processRequest() { - inprogressRequests.inc(); - // Your code here. - inprogressRequests.dec(); - } -} -``` - -There are utilities for common use cases: - -```java -gauge.setToCurrentTime(); // Set to current unixtime. -``` - -As an advanced use case, a `Gauge` can also take its value from a callback by using the -[setChild()](https://prometheus.io/client_java/io/prometheus/client/SimpleCollector.html#setChild-Child-java.lang.String...-) -method. Keep in mind that the default `inc()`, `dec()` and `set()` methods on Gauge take care of thread safety, so -when using this approach ensure the value you are reporting accounts for concurrency. - - -### Summary - -Summaries and Histograms can both be used to monitor distributions, like latencies or request sizes. - -An overview of when to use Summaries and when to use Histograms can be found on [https://prometheus.io/docs/practices/histograms](https://prometheus.io/docs/practices/histograms). - -The following example shows how to measure latencies and request sizes: - -```java -class YourClass { - - private static final Summary requestLatency = Summary.build() - .name("requests_latency_seconds") - .help("request latency in seconds") - .register(); - - private static final Summary receivedBytes = Summary.build() - .name("requests_size_bytes") - .help("request size in bytes") - .register(); - - public void processRequest(Request req) { - Summary.Timer requestTimer = requestLatency.startTimer(); - try { - // Your code here. - } finally { - requestTimer.observeDuration(); - receivedBytes.observe(req.size()); - } - } -} -``` - -The `Summary` class provides different utility methods for observing values, like `observe(double)`, `startTimer(); timer.observeDuration()`, `time(Callable)`, etc. - -By default, `Summary` metrics provide the `count` and the `sum`. For example, if you measure latencies of a REST service, the `count` will tell you how often the REST service was called, and the `sum` will tell you the total aggregated response time. You can calculate the average response time using a Prometheus query dividing `sum / count`. - -In addition to `count` and `sum`, you can configure a Summary to provide quantiles: - -```java -Summary requestLatency = Summary.build() - .name("requests_latency_seconds") - .help("Request latency in seconds.") - .quantile(0.5, 0.01) // 0.5 quantile (median) with 0.01 allowed error - .quantile(0.95, 0.005) // 0.95 quantile with 0.005 allowed error - // ... - .register(); -``` - -As an example, a `0.95` quantile of `120ms` tells you that `95%` of the calls were faster than `120ms`, and `5%` of the calls were slower than `120ms`. - -Tracking exact quantiles require a large amount of memory, because all observations need to be stored in a sorted list. Therefore, we allow an error to significantly reduce memory usage. - -In the example, the allowed error of `0.005` means that you will not get the exact `0.95` quantile, but anything between the `0.945` quantile and the `0.955` quantile. - -Experiments show that the `Summary` typically needs to keep less than 100 samples to provide that precision, even if you have hundreds of millions of observations. - -There are a few special cases: - -* You can set an allowed error of `0`, but then the `Summary` will keep all observations in memory. -* You can track the minimum value with `.quantile(0, 0)`. This special case will not use additional memory even though the allowed error is `0`. -* You can track the maximum value with `.quantile(1, 0)`. This special case will not use additional memory even though the allowed error is `0`. - -Typically, you don't want to have a `Summary` representing the entire runtime of the application, but you want to look at a reasonable time interval. `Summary` metrics implement a configurable sliding time window: - -```java -Summary requestLatency = Summary.build() - .name("requests_latency_seconds") - .help("Request latency in seconds.") - .maxAgeSeconds(10 * 60) - .ageBuckets(5) - // ... - .register(); -``` - -The default is a time window of 10 minutes and 5 age buckets, i.e. the time window is 10 minutes wide, and * we slide it forward every 2 minutes. - -### Histogram - -Like Summaries, Histograms can be used to monitor latencies (or other things like request sizes). - -An overview of when to use Summaries and when to use Histograms can be found on [https://prometheus.io/docs/practices/histograms](https://prometheus.io/docs/practices/histograms). - -```java -class YourClass { - static final Histogram requestLatency = Histogram.build() - .name("requests_latency_seconds").help("Request latency in seconds.").register(); - - void processRequest(Request req) { - Histogram.Timer requestTimer = requestLatency.startTimer(); - try { - // Your code here. - } finally { - requestTimer.observeDuration(); - } - } -} -``` - -The default buckets are intended to cover a typical web/rpc request from milliseconds to seconds. -They can be overridden with the `buckets()` method on the [Histogram.Builder](https://prometheus.github.io/client_java/io/prometheus/client/Histogram.Builder.html#buckets-double...-). - -There are utilities for timing code: - -```java -class YourClass { - static final Histogram requestLatency = Histogram.build() - .name("requests_latency_seconds").help("Request latency in seconds.").register(); - - void processRequest(Request req) { - requestLatency.time(new Runnable() { - public abstract void run() { - // Your code here. - } - }); - - - // Or the Java 8 lambda equivalent - requestLatency.time(() -> { - // Your code here. - }); - } -} -``` - -### Labels - -All metrics can have labels, allowing grouping of related time series. - -See the best practices on [naming](http://prometheus.io/docs/practices/naming/) -and [labels](http://prometheus.io/docs/practices/instrumentation/#use-labels). - -Taking a counter as an example: - -```java -class YourClass { - static final Counter requests = Counter.build() - .name("my_library_requests_total").help("Total requests.") - .labelNames("method").register(); - - void processGetRequest() { - requests.labels("get").inc(); - // Your code here. - } -} -``` - -### Registering Metrics - -The best way to register a metric is via a `static final` class variable as is common with loggers. - -```java -static final Counter requests = Counter.build() - .name("my_library_requests_total").help("Total requests.").labelNames("path").register(); -``` - -Using the default registry with variables that are `static` is ideal since registering a metric with the same name -is not allowed and the default registry is also itself static. You can think of registering a metric, more like -registering a definition (as in the `TYPE` and `HELP` sections). The metric 'definition' internally holds the samples -that are reported and pulled out by Prometheus. Here is an example of registering a metric that has no labels. - -```java -class YourClass { - static final Gauge activeTransactions = Gauge.build() - .name("my_library_transactions_active") - .help("Active transactions.") - .register(); - - void processThatCalculates(String key) { - activeTransactions.inc(); - try { - // Perform work. - } finally{ - activeTransactions.dec(); - } - } -} -``` - -To create timeseries with labels, include `labelNames()` with the builder. The `labels()` method looks up or creates -the corresponding labelled timeseries. You might also consider storing the labelled timeseries as an instance variable if it is -appropriate. It is thread safe and can be used multiple times, which can help performance. - - -```java -class YourClass { - static final Counter calculationsCounter = Counter.build() - .name("my_library_calculations_total").help("Total calls.") - .labelNames("key").register(); - - void processThatCalculates(String key) { - calculationsCounter.labels(key).inc(); - // Run calculations. - } -} -``` - -## Exemplars - -Exemplars are a feature of the [OpenMetrics](http://openmetrics.io) format that allows applications to link metrics to example traces. -In order to see exemplars, you need to set the `Accept` header for the [OpenMetrics](http://openmetrics.io) format like this: - -``` -curl -H 'Accept: application/openmetrics-text; version=1.0.0; charset=utf-8' http://localhost:8080/metrics -``` - -Exemplars are supported since `client_java` version 0.11.0. Exemplars are supported for `Counter` and `Histogram` metrics. - -### Global Exemplar Samplers - -An `ExemplarSampler` is used implicitly under the hood to add exemplars to your metrics. The idea is that you get exemplars without changing your code. - -The `DefaultExemplarSampler` comes with built-in support for [OpenTelemetry tracing](https://github.com/open-telemetry/opentelemetry-java), see [built-in support for tracing systems](#built-in-support-for-tracing-systems) below. - -You can disable the default exemplar samplers globally with: - -```java -ExemplarConfig.disableExemplars(); -``` - -You can set your own custom implementation of `ExemplarSampler` as a global default like this: - -```java -ExemplarSampler myExemplarSampler = new MyExemplarSampler(); -ExemplarConfig.setCounterExemplarSampler(myExemplarSampler); -ExemplarConfig.setHistogramExemplarSampler(myExemplarSampler); -``` - -### Per Metric Exemplar Samplers - -The metric builders for `Counter` and `Histogram` have methods for setting the exemplar sampler for that individual metric. This takes precedence over the global setting in `ExemplarConfig`. - -The following calls enable the default exemplar sampler for individual metrics. This is useful if you disabled the exemplar sampler globally with `ExemplarConfig.disableExemplars()`. - -```java -Counter myCounter = Counter.build() - .name("number_of_events_total") - .help("help") - .withExemplars() - ... - .register(); -``` - -```java -Histogram myHistogram = Histogram.build() - .name("my_latency") - .help("help") - .withExemplars() - ... - .register(); -``` - -The following calls disable exemplars for individual metrics: - -```java -Counter myCounter = Counter.build() - .name("number_of_events_total") - .help("help") - .withoutExemplars() - ... - .register(); -``` - -```java -Histogram myHistogram = Histogram.build() - .name("my_latency") - .help("help") - .withoutExemplars() - ... - .register(); -``` - -The following calls enable exemplars and set a custom `MyExemplarSampler` for individual metrics: - -```java -// CounterExemplarSampler -Counter myCounter = Counter.build() - .name("number_of_events_total") - .help("help") - .withExemplarSampler(new MyExemplarSampler()) - ... - .register(); -``` - -```java -// HistogramExemplarSampler -Histogram myHistogram = Histogram.build() - .name("my_latency") - .help("help") - .withExemplarSampler(new MyExemplarSampler()) - ... - .register(); -``` - -### Per Observation Exemplars - -You can explicitly provide an exemplar for an individual observation. This takes precedence over the exemplar sampler configured with the metric. - -The following call will increment a counter, and create an exemplar with the specified `span_id` and `trace_id` labels: - -```java -myCounter.incWithExemplar("span_id", "abcdef", "trace_id", "123456"); -``` - -The following call will observe a value of `0.12` in a histogram, and create an exemplar with the specified `span_id` and `trace_id` labels: - -```java -myHistogram.observeWithExemplar(0.12, "span_id", "abcdef", "trace_id", "123456"); -``` - -All methods for observing and incrementing values have `...withExemplar` equivalents. There are versions taking the exemplar labels as a `String...` as shown in the example, as well as versions taking the exemplar labels as a `Map`. - -### Built-in Support for Tracing Systems - -The `DefaultExemplarSampler` detects if a tracing library is found on startup, and provides exemplars for that tracing library by default. Currently, only [OpenTelemetry tracing](https://github.com/open-telemetry/opentelemetry-java) is supported. -If you are a tracing vendor, feel free to open a PR and add support for your tracing library. - -Documentation of the individual tracer integrations: - -* [OTEL_EXEMPLARS.md](OTEL_EXEMPLARS.md): OpenTelemetry - -## Included Collectors - -The Java client includes collectors for garbage collection, memory pools, classloading, and thread counts. -These can be added individually or just use the `DefaultExports` to conveniently register them. - -```java -DefaultExports.initialize(); -``` - -### Logging - -There are logging collectors for log4j, log4j2 and logback. - -To register the Logback collector can be added to the root level like so: - -```xml - - - - - - - - - - - -``` - -To register the log4j collector at root level: - -```xml - - - - - - - - - -``` - -To register the log4j2 collector at root level: - -```xml - - - - - - - - - - - -``` - -See `./integration_tests/it_log4j2/` for a log4j2 example. - -### Caches - -To register the Guava cache collector, be certain to add `recordStats()` when building -the cache and adding it to the registered collector. - -```java -CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register(); - -Cache cache = CacheBuilder.newBuilder().recordStats().build(); -cacheMetrics.addCache("myCacheLabel", cache); -``` - -The Caffeine equivalent is nearly identical. Again, be certain to call `recordStats()` - when building the cache so that metrics are collected. - -```java -CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register(); - -Cache cache = Caffeine.newBuilder().recordStats().build(); -cacheMetrics.addCache("myCacheLabel", cache); -``` - -### Hibernate - -There is a collector for Hibernate which allows to collect metrics from one or more -`SessionFactory` instances. - -If you want to collect metrics from a single `SessionFactory`, you can register -the collector like this: - -```java -new HibernateStatisticsCollector(sessionFactory, "myapp").register(); -``` - -In some situations you may want to collect metrics from multiple factories. In this -case just call `add()` on the collector for each of them. - -```java -new HibernateStatisticsCollector() - .add(sessionFactory1, "myapp1") - .add(sessionFactory2, "myapp2") - .register(); -``` - -If you are using Hibernate in a JPA environment and only have access to the `EntityManager` -or `EntityManagerFactory`, you can use this code to access the underlying `SessionFactory`: - -```java -SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class); -``` - -respectively - -```java -SessionFactory sessionFactory = entityManager.unwrap(Session.class).getSessionFactory(); -``` -### Jetty - -There is a collector for recording various Jetty server metrics. You can do it by registering the collector like this: - -```java -// Configure StatisticsHandler. -StatisticsHandler stats = new StatisticsHandler(); -stats.setHandler(server.getHandler()); -server.setHandler(stats); -// Register collector. -new JettyStatisticsCollector(stats).register(); - -``` - -Also, you can collect `QueuedThreadPool` metrics. If there is a single `QueuedThreadPool` -to keep track of, use the following: - -```java -new QueuedThreadPoolStatisticsCollector(queuedThreadPool, "myapp").register(); -``` - -If you want to collect multiple `QueuedThreadPool` metrics, also you can achieve it like this: - -```java -new QueuedThreadPoolStatisticsCollector() - .add(queuedThreadPool1, "myapp1") - .add(queuedThreadPool2, "myapp2") - .register(); -``` - -#### Servlet Filter - -There is a servlet filter available for measuring the duration taken by servlet requests: - -* `javax` version: `io.prometheus.client.filter.MetricsFilter` provided by `simpleclient_servlet` -* `jakarta` version: `io.prometheus.client.servlet.jakarta.filter.MetricsFilter` provided by `simpleclient_servlet_jakarta` - -Both versions implement the same functionality. - -Configuration is as follows: - -The `metric-name` init parameter is required, and is the name of the -metric prometheus will expose for the timing metrics. Help text via the `help` -init parameter is not required, although it is highly recommended. The number -of buckets is overridable, and can be configured by passing a comma-separated -string of doubles as the `buckets` init parameter. The granularity of path -measuring is also configurable, via the `path-components` init parameter. By -default, the servlet filter will record each path differently, but by setting an -integer here, you can tell the filter to only record up to the Nth slashes. That -is, all requests with greater than N "/" characters in the servlet URI path will -be measured in the same bucket, and you will lose that granularity. The init -parameter `strip-context-path` can be used to strip the leading part of the URL -which is part of the deployment context (i.e. the folder the servlet is deployed to), -so that the same servlet deployed to different paths can lead to similar metrics. - -The code below is an example of the XML configuration for the filter. You will -need to place this (replace your own values) code in your -`webapp/WEB-INF/web.xml` file. - -```xml - - prometheusFilter - - - io.prometheus.client.filter.MetricsFilter - - metric-name - webapp_metrics_filter - - - - help - This is the help for your metrics filter - - - - buckets - 0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10 - - - - path-components - 1 - - - - strip-context-path - false - - - - - - prometheusFilter - /* - -``` - -Additionally, you can instantiate your servlet filter directly in Java code. To -do this, you just need to call the non-empty constructor. The first parameter, -the metric name, is required. The second, help, is optional but highly -recommended. The other parameters are optional and will default sensibly if omitted. - -#### Spring AOP - -There is a Spring AOP collector that allows you to annotate methods that you -would like to instrument with a [Summary](#Summary), but without going through -the process of manually instantiating and registering your metrics classes. To -use the metrics annotations, simply add `simpleclient_spring_web` as a -dependency, annotate a configuration class with `@EnablePrometheusTiming`, then -annotate your Spring components as such: - -```java -@Controller -public class MyController { - @RequestMapping("/") - @PrometheusTimeMethod(name = "my_controller_path_duration_seconds", help = "Some helpful info here") - public Object handleMain() { - // Do something - } -} -``` - -## Exporting - -There are several options for exporting metrics. - -### HTTP - -Metrics are usually exposed over HTTP, to be read by the Prometheus server. - -There are HTTPServer, Servlet, SpringBoot, and Vert.x integrations included in the client library. -The simplest of these is the HTTPServer: - -```java -HTTPServer server = new HTTPServer.Builder() - .withPort(1234) - .build(); -``` - -The `HTTPServer.Builder` supports configuration of a `SampleNameFilter` which can be used to -restrict the time series being exported by name. - -To add Prometheus exposition to an existing HTTP server using servlets, see the `MetricsServlet`. -It also serves as a simple example of how to write a custom endpoint. - -To expose the metrics used in your code, you would add the Prometheus servlet to your Jetty server: - -```java -Server server = new Server(1234); -ServletContextHandler context = new ServletContextHandler(); -context.setContextPath("/"); -server.setHandler(context); - -context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics"); -``` - -Like the HTTPServer, the `MetricsServlet` can be configured with a `SampleNameFilter` which can -be used to restrict the time series being exported by name. See `integration_tests/servlet_jakarta_exporter_webxml/` -for an example how to configure this in `web.xml`. - -All HTTP exposition integrations support restricting which time series to return -using `?name[]=` URL parameters. Due to implementation limitations, this may -have false negatives. - -## Exporting to a Pushgateway - -The [Pushgateway](https://github.com/prometheus/pushgateway) -allows ephemeral and batch jobs to expose their metrics to Prometheus. - -```java -void executeBatchJob() throws Exception { - CollectorRegistry registry = new CollectorRegistry(); - Gauge duration = Gauge.build() - .name("my_batch_job_duration_seconds").help("Duration of my batch job in seconds.").register(registry); - Gauge.Timer durationTimer = duration.startTimer(); - try { - // Your code here. - - // This is only added to the registry after success, - // so that a previous success in the Pushgateway isn't overwritten on failure. - Gauge lastSuccess = Gauge.build() - .name("my_batch_job_last_success").help("Last time my batch job succeeded, in unixtime.").register(registry); - lastSuccess.setToCurrentTime(); - } finally { - durationTimer.setDuration(); - PushGateway pg = new PushGateway("127.0.0.1:9091"); - pg.pushAdd(registry, "my_batch_job"); - } -} - ``` - -A separate registry is used, as the default registry may contain other metrics -such as those from the Process Collector. See the -[Pushgateway documentation](https://github.com/prometheus/pushgateway/blob/master/README.md) -for more information. - - -#### with Basic Auth -```java -PushGateway pushgateway = new PushGateway("127.0.0.1:9091"); -pushgateway.setConnectionFactory(new BasicAuthHttpConnectionFactory("my_user", "my_password")); -``` - -#### with Custom Connection Preparation Logic -```java -PushGateway pushgateway = new PushGateway("127.0.0.1:9091"); -pushgateway.setConnectionFactory(new MyHttpConnectionFactory()); -``` -where -```java -class MyHttpConnectionFactory implements HttpConnectionFactory { - @Override - public HttpURLConnection create(String url) throws IOException { - HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); - // add any connection preparation logic you need - return connection; - } -} -``` - -## Bridges - -It is also possible to expose metrics to systems other than Prometheus. -This allows you to take advantage of Prometheus instrumentation even -if you are not quite ready to fully transition to Prometheus yet. - -### Graphite - -Metrics are pushed over TCP in the Graphite plaintext format. - -```java -Graphite g = new Graphite("localhost", 2003); -// Push the default registry once. -g.push(CollectorRegistry.defaultRegistry); - -// Push the default registry every 60 seconds. -Thread thread = g.start(CollectorRegistry.defaultRegistry, 60); -// Stop pushing. -thread.interrupt(); -thread.join(); -``` - -## Custom Collectors - -Sometimes it is not possible to directly instrument code, as it is not -in your control. This requires you to proxy metrics from other systems. - -To do so you need to create a custom collector (which will need to be registered as a normal metric), for example: - -```java -class YourCustomCollector extends Collector { - public List collect() { - List mfs = new ArrayList(); - // With no labels. - mfs.add(new GaugeMetricFamily("my_gauge", "help", 42)); - // With labels - GaugeMetricFamily labeledGauge = new GaugeMetricFamily("my_other_gauge", "help", Arrays.asList("labelname")); - labeledGauge.addMetric(Arrays.asList("foo"), 4); - labeledGauge.addMetric(Arrays.asList("bar"), 5); - mfs.add(labeledGauge); - return mfs; - } -} - -// Registration -static final YourCustomCollector requests = new YourCustomCollector().register() -``` - -`SummaryMetricFamily` works similarly. - -A collector may implement a `describe` method which returns metrics in the same -format as `collect` (though you don't have to include the samples). This is -used to predetermine the names of time series a `CollectorRegistry` exposes and -thus to detect collisions and duplicate registrations. - -Usually custom collectors do not have to implement `describe`. If `describe` is -not implemented and the CollectorRegistry was created with `auto_describe=True` -(which is the case for the default registry) then `collect` will be called at -registration time instead of `describe`. If this could cause problems, either -implement a proper `describe`, or if that's not practical have `describe` -return an empty list. - -### DropwizardExports Collector - -DropwizardExports collector is available to proxy metrics from Dropwizard. - -```java -// Dropwizard MetricRegistry -MetricRegistry metricRegistry = new MetricRegistry(); -new DropwizardExports(metricRegistry).register(); -``` - -By default Dropwizard metrics are translated to Prometheus sample sanitizing their names, i.e. replacing unsupported chars with `_`, for example: -``` -Dropwizard metric name: -org.company.controller.save.status.400 -Prometheus metric: -org_company_controller_save_status_400 -``` - -It is also possible add custom labels and name to newly created `Sample`s by using a `CustomMappingSampleBuilder` with custom `MapperConfig`s: - -```java -// Dropwizard MetricRegistry -MetricRegistry metricRegistry = new MetricRegistry(); -MapperConfig config = new MapperConfig(); -// The match field in MapperConfig is a simplified glob expression that only allows * wildcard. -config.setMatch("org.company.controller.*.status.*"); -// The new Sample's template name. -config.setName("org.company.controller"); -Map labels = new HashMap(); -// ... more configs -// Labels to be extracted from the metric. Key=label name. Value=label template -labels.put("name", "${0}"); -labels.put("status", "${1}"); -config.setLabels(labels); - -SampleBuilder sampleBuilder = new CustomMappingSampleBuilder(Arrays.asList(config)); -new DropwizardExports(metricRegistry, sampleBuilder).register(); -``` - -When a new metric comes to the collector, `MapperConfig`s are scanned to find the first one that matches the incoming metric name. The name set in the configuration will -be used and labels will be extracted. Using the `CustomMappingSampleBuilder` in the previous example leads to the following result: -``` -Dropwizard metric name -org.company.controller.save.status.400 -Prometheus metric -org_company_controller{name="save",status="400"} -``` - -Template with placeholders can be used both as names and label values. Placeholders are in the `${n}` format where n is the zero based index of the Dropwizard metric name wildcard group we want to extract. - -## Contact -The [Prometheus Users Mailinglist](https://groups.google.com/forum/?fromgroups#!forum/prometheus-users) is the best place to ask questions. - -Details for those wishing to develop the library can be found on the [wiki](https://github.com/prometheus/client_java/wiki/Development) +Apache License 2.0, see [LICENSE](LICENSE). diff --git a/simpleclient-archive/README.md b/simpleclient-archive/README.md new file mode 100644 index 000000000..b7e2a9463 --- /dev/null +++ b/simpleclient-archive/README.md @@ -0,0 +1,3 @@ +This is not functional source code. We just keep these files around so we don't loose the Github history once we copy them to the new 1.0.x modules. + +If you are looking for the source code for the latest 0.x.x release, see the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) branch. From a8902cb4718bcbb369b50b64cf7e851362193dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 25 Sep 2023 18:08:18 +0200 Subject: [PATCH 246/980] Switch github pages workflow to the main branch --- .github/workflows/github-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index b3910f43c..30569cd58 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -4,7 +4,7 @@ on: # Runs on pushes targeting the 1.0.x branch push: branches: - - 1.0.x + - main # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From db047023162da51e9217c3cf7e264c9863a97cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 26 Sep 2023 22:10:46 +0200 Subject: [PATCH 247/980] Add OTel docs outline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/otel/names.md | 5 ++++- docs/content/otel/otlp.md | 5 ++++- docs/content/otel/tracing.md | 11 ++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/content/otel/names.md b/docs/content/otel/names.md index 89f6515c7..45b94fcc2 100644 --- a/docs/content/otel/names.md +++ b/docs/content/otel/names.md @@ -3,4 +3,7 @@ title: Names weight: 3 --- -TODO: How to iplement OpenTelemetry semantic conventions, and how OpenTelemetry metric and label names are converted to Prometheus. +TODO: This section will contain information on: + +* Mapping Prometheus metric names to OpenTelemetry when using the `OpenTelemetryExporter`. See OpenTelemetry's [Prometheus and OpenMetrics Compatibility](https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/). +* Using dots in label and metric names to implement OpenTelemetry's semantic conventions. diff --git a/docs/content/otel/otlp.md b/docs/content/otel/otlp.md index 9c7938d99..345542606 100644 --- a/docs/content/otel/otlp.md +++ b/docs/content/otel/otlp.md @@ -3,4 +3,7 @@ title: OTLP weight: 1 --- -TODO: How to push metrics to an OpenTelemetry endpoint using the OpenTelemetry exporter. +TODO: This section will describe how to push metrics to an OpenTelemetry endpoint using the OpenTelemetry exporter. + +In the meantime, have a look at the example in [examples/example-exporter-opentelemetry](https://github.com/prometheus/client_java/tree/main/examples/example-exporter-opentelemetry). +It has an example Java program with the `OpenTelemetryExporter`, and a Docker compose setting up a pipeline with the OpenTelemetry collector and a Prometheus server. diff --git a/docs/content/otel/tracing.md b/docs/content/otel/tracing.md index 47af209cc..99bcbd6cb 100644 --- a/docs/content/otel/tracing.md +++ b/docs/content/otel/tracing.md @@ -3,4 +3,13 @@ title: Tracing weight: 2 --- -TODO: How to integrate Prometheus metrics with OTel traces. +It is a common scenario that you use the Prometheus Java client for metrics, and the OpenTelemetry Java instrumentation agent for tracing. + +The Prometheus Java client has some awesome features under the hood to support integration with OpenTelemetry tracing: + +* `service.name` and `service.instance.id` are used in OpenTelemetry to uniquely identify a service instance. If an OpenTelemetry Java agent is attached, the Prometheus library will automatically use the same `service.name` and `service.instance.id` as the agent when pushing metrics in OpenTelemetry format. That way the monitoring backend will see that the metrics and the traces are coming from the same instance. +* Exemplars are added automatically if a Prometheus metric is updated in the context of a distributed OpenTelemetry trace. +* If a Span is used as an Exemplar, the Span is marked with the Span attribute `exemplar="true"`. This can be used in the OpenTelemetry's sampling policy to make sure Exemplars are always sampled. + +TODO: We will add more information on integration OTel tracing with Prometheus metrics here. +In the meantime, have a look at the tail sampling end-to-end example in [examples/example-exemplars-tail-sampling](https://github.com/prometheus/client_java/tree/main/examples/example-exemplars-tail-sampling). From 491d226b1fd40a3612d4a888165e23f342379d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 26 Sep 2023 23:00:22 +0200 Subject: [PATCH 248/980] Add more 0.16.0 migration docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/migration/simpleclient.md | 58 +++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md index 661c1aeea..4f4ebf290 100644 --- a/docs/content/migration/simpleclient.md +++ b/docs/content/migration/simpleclient.md @@ -3,15 +3,17 @@ title: Simpleclient weight: 1 --- -The Prometheus Java client library 1.0.0 is a complete rewrite, and is not backwards compatible with the old `simpleclient` modules for a variety of reasons: +The Prometheus Java client library 1.0.0 is a complete rewrite of the underlying data model, and is not backwards compatible with releases 0.16.0 and older for a variety of reasons: -* We rewrote the underlying data model. The `simpleclient` data model is based on [OpenMetrics](https://openmetrics.io/), which is based on the assumption that each data point has exactly one `double` value (`Collector.Sample.value` in `simpleclient`). With the new Prometheus native histograms this is no longer true. Native histograms have a complex data structure as value. This is the reason why native histograms cannot be exposed in OpenMetrics text format. The new `prometheus-metrics-model` implements the current Prometheus data model and is not based on OpenMetrics. -* We refactored the package names. The simpleclient has package names that are reused by multiple Maven modules, which causes issues with the Java module system. The new `prometheus-metrics` modules each has their own package name, package names are not reused. +* The old data model was based on [OpenMetrics](https://openmetrics.io). Native histograms don't fit with the OpenMetrics model because they don't follow the "every sample has exactly one double value" paradigm. It was a lot cleaner to implement a dedicated `prometheus-metrics-model` than trying to fit native histograms into the existing OpenMetrics-based model. +* Version 0.16.0 and older has multiple Maven modules sharing the same Java package name. This is not supported by the Java module system. To support users of Java modules, we renamed all packages and made sure no package is reused across multiple Maven modules. -Migrating from Simpleclient ---------------------------- +Migration using the Simpleclient Bridge +--------------------------------------- -For users of previous versions of the Prometheus Java client we provide a migration module for bridging the simpleclient `CollectorRegistry` to the new `PromethesuRegistry`. +Good news: Users of version 0.16.0 and older do not need to refactor all their instrumentation code to get started with 1.0.0. + +We provide a migration module for bridging the old simpleclient `CollectorRegistry` to the new `PromethesuRegistry`. To use the bridge, add the following dependency: @@ -50,3 +52,47 @@ SimpleclientCollector.builder() .collectorRegistry(simpleclientRegistry) .register(prometheusRegistry); ``` + +Refactoring the Instrumentation Code +------------------------------------ + +If you decide to get rid of the old 0.16.0 dependencies and use 1.0.0 only, you need to refactor your code: + +Dependencies: + +* `simpleclient` -> `prometheus-metrics-core` +* `simpleclient_hotspot` -> `prometheus-metrics-instrumentation-jvm` +* `simpleclient_httpserver` -> `prometheus-metrics-exporter-httpserver` +* `simpleclient_servlet_jakarta` -> `prometheus-metrics-exporter-servlet-jakarta` + +As long as you are using high-level metric API like `Counter`, `Gauge`, `Histogram`, and `Summary` converting code to the new API is relatively straightforward. You will need to adapt the package name and apply some minor changes like using `builder()` instead of `build()` or using `labelValues()` instead of `labels()`. + +Example of the old 0.16.0 API: + +```java +import io.prometheus.client.Counter; + +Counter counter = Counter.build() + .name("test") + .help("test counter") + .labelNames("path") + .register(); + +counter.labels("/hello-world").inc(); +``` + +Example of the new 1.0.0 API: + +```java +import io.prometheus.metrics.core.metrics.Counter; + +Counter counter = Counter.builder() + .name("test") + .help("test counter") + .labelNames("path") + .register(); + +counter.labelValues("/hello-world").inc(); +``` + +If you are using the low level `Collector` API directly, you should have a look at the new callback metric types, see [/getting-started/callbacks/](../../getting-started/callbacks/). Chances are good that the new callback metrics have an easier way to achieve what you need than the old 0.16.0 code. From 728729c22162e25b0f911ee1953ea8c3fcd3ae75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 09:31:34 +0200 Subject: [PATCH 249/980] Temporarily add shaded dependencies to prepare for releas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 864672026..f6c0aa8e3 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - + prometheus-metrics-shaded-dependencies examples benchmarks integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index e3b78f14b..f7cad4ce6 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.0.0-beta-1 + ${project.version} From a94d774be80784142dc860a9bcf03e770cbdfd31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 09:32:55 +0200 Subject: [PATCH 250/980] [maven-release-plugin] prepare release v1.0.0 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 4 ++-- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 37 files changed, 40 insertions(+), 40 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 9a25ea843..a4b548162 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 766239bb9..336a98e73 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 994abd895..c0d99cf50 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index f2dee4476..184183369 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 19bece513..c49813754 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 05feaa7e8..99d6743ad 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 3dbc14da3..53fed0486 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 720fb621e..9d0ace19d 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 13738efc3..0d455acd4 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 46b76f86b..d6aab5d54 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0-beta-2-SNAPSHOT + 1.0.0 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index a52a32f73..481051e60 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index af01b17a1..6f318863a 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 2e15dbd60..dd646dc12 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 10d6db685..45ca15545 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index e7cec4152..a2e3eca52 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 44f065e29..a944e4555 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 2d8b7b851..580f2ef8a 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0-beta-2-SNAPSHOT + 1.0.0 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0 diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ce770704b..c95fff352 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 integration-tests diff --git a/pom.xml b/pom.xml index f6c0aa8e3..08b7f588a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.0.0 diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 7d556ad5f..02221376f 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 7670d32b2..ea4196e3c 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 7846bd500..f7a946b57 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 13edaa55f..d5aba5909 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index f7cad4ce6..6c970262b 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 1a9411d8c..df5dc0034 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 75e07f6d1..f5f79e31f 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 0212c043b..a2e0912ef 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index b81fb509d..5c1254faf 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 508185dfa..8cf558888 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 3484a5435..7f4ba2e44 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index d136434d5..4f01b6ba1 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index b4480483b..ef169da3c 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-simpleclient-bridge @@ -72,7 +72,7 @@ io.prometheus prometheus-metrics-config - 1.0.0-beta-2-SNAPSHOT + 1.0.0 compile diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 90927f4d6..1c4d883d2 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index d1571414c..4fd20013c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 22995a855..1bbcba70c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index af73f9d22..b9cc7e555 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 5f6cee34f..3de9b4308 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0-beta-2-SNAPSHOT + 1.0.0 prometheus-metrics-tracer-otel From 9f2a654675fe50f858cebac09e7d92007c866f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 09:32:59 +0200 Subject: [PATCH 251/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 4 ++-- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 37 files changed, 40 insertions(+), 40 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index a4b548162..18f8f7b34 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 336a98e73..29827ffbe 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0 + 1.1.0-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index c0d99cf50..bc6db20f7 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.0.0 + 1.1.0-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 184183369..0e77e6206 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index c49813754..1e2e29293 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 99d6743ad..78d4ce8af 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 53fed0486..75f3beeab 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 9d0ace19d..b094f76db 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 0d455acd4..14dad20ff 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index d6aab5d54..3abc5f5ba 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.0.0 + 1.1.0-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 481051e60..0b293cedc 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 6f318863a..ccff0a33c 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0 + 1.1.0-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index dd646dc12..3638eb7e1 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0 + 1.1.0-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 45ca15545..823997f40 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0 + 1.1.0-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index a2e3eca52..1cef98dd0 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0 + 1.1.0-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index a944e4555..05661f8c0 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.0.0 + 1.1.0-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 580f2ef8a..2802e6231 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.0.0 + 1.1.0-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0 + HEAD diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index c95fff352..d2f1a7fb5 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT integration-tests diff --git a/pom.xml b/pom.xml index 08b7f588a..348b58831 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -25,7 +25,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.0.0 + HEAD diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 02221376f..4e8a2328a 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index ea4196e3c..25007d1e9 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index f7a946b57..ceea4b6a2 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index d5aba5909..1495ea259 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 6c970262b..6b7711112 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index df5dc0034..6e09cfdee 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index f5f79e31f..14ad61102 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index a2e0912ef..95c6dfe97 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 5c1254faf..f5c922707 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 8cf558888..a7ff63c82 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 7f4ba2e44..bc1e62549 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 4f01b6ba1..917892a98 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index ef169da3c..5287de079 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-simpleclient-bridge @@ -72,7 +72,7 @@ io.prometheus prometheus-metrics-config - 1.0.0 + 1.1.0-SNAPSHOT compile diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 1c4d883d2..fef4bb904 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 4fd20013c..aadc50e21 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 1bbcba70c..7801c6712 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index b9cc7e555..76f7ce66e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 3de9b4308..a7396d514 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.0.0 + 1.1.0-SNAPSHOT prometheus-metrics-tracer-otel From 7ff57d17cc4fd30f1b1387e5a6e4d7cd620e985d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 09:52:47 +0200 Subject: [PATCH 252/980] Exclude shaded dependencies from the build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 348b58831..2845c00d0 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ prometheus-metrics-exporter-opentelemetry prometheus-metrics-instrumentation-jvm prometheus-metrics-simpleclient-bridge - prometheus-metrics-shaded-dependencies + examples benchmarks integration-tests diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 6b7711112..424b9afa3 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,7 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - ${project.version} + 1.0.0 From 312ce6d1b121947f230ecd1dd6739f00127f1394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 10:54:17 +0200 Subject: [PATCH 253/980] Add a paragraph to the simpleclient migration docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/migration/simpleclient.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md index 4f4ebf290..5b1ee6a15 100644 --- a/docs/content/migration/simpleclient.md +++ b/docs/content/migration/simpleclient.md @@ -95,4 +95,6 @@ Counter counter = Counter.builder() counter.labelValues("/hello-world").inc(); ``` +Reasons why we changed the API: Changing the package names was a neccessity because the previous package names were incompatible with the Java module system. However, renaming packages requires chaning code anyway, so we decided to clean up some things. For example, the name `builder()` for a builder method is very common in the Java ecosystem, it's used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library more aligned with the broader Java ecosystem. + If you are using the low level `Collector` API directly, you should have a look at the new callback metric types, see [/getting-started/callbacks/](../../getting-started/callbacks/). Chances are good that the new callback metrics have an easier way to achieve what you need than the old 0.16.0 code. From 8a2d3239ed078da9dc0e022e3d0f47cb5032d13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 12:48:35 +0200 Subject: [PATCH 254/980] Add OpenTelemetryExporter docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/otel/otlp.md | 38 ++++++++++++++++++++++++--- docs/static/images/otel-pipeline.png | Bin 0 -> 58434 bytes 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 docs/static/images/otel-pipeline.png diff --git a/docs/content/otel/otlp.md b/docs/content/otel/otlp.md index 345542606..d81ed822e 100644 --- a/docs/content/otel/otlp.md +++ b/docs/content/otel/otlp.md @@ -3,7 +3,39 @@ title: OTLP weight: 1 --- -TODO: This section will describe how to push metrics to an OpenTelemetry endpoint using the OpenTelemetry exporter. +The Prometheus Java client library allows you to push metrics to an OpenTelemetry endpoint using the OTLP protocol. -In the meantime, have a look at the example in [examples/example-exporter-opentelemetry](https://github.com/prometheus/client_java/tree/main/examples/example-exporter-opentelemetry). -It has an example Java program with the `OpenTelemetryExporter`, and a Docker compose setting up a pipeline with the OpenTelemetry collector and a Prometheus server. +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/images/otel-pipeline.png) + +To implement this, you need to include `prometheus-metrics-exporter` as a dependency + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-exporter-opentelemetry:1.0.0' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-exporter-opentelemetry + 1.0.0 + +``` +{{< /tab >}} +{{< /tabs >}} + +Initialize the `OpenTelemetryExporter` in your Java code: + +```java +OpenTelemetryExporter.builder() + // optional: call configuration methods here + .buildAndStart(); +``` + +By default, the `OpenTelemetryExporter` will push metrics every 60 seconds to `localhost:4317` using `grpc` protocol. You can configure this in code using the [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html), or at runtime via [`io.prometheus.exporter.opentelemetry.*`](../../config/config/#exporter-opentelemetry-properties) properties. + +In addition to the Prometheus Java client configuration, the exporter also recognizes standard OpenTelemetry configuration. For example, you can set the [OTEL_EXPORTER_OTLP_METRICS_ENDPOINT](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/#otel_exporter_otlp_metrics_endpoint) environment variable to configure the endpoint. The Javadoc for [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html) shows which settings have corresponding OTel configuration. The intended use case is that if you attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) for tracing, and use the Prometheus Java client for metrics, it is sufficient to configure the OTel agent because the Prometheus library will pick up the same configuration. + +The [examples/example-exporter-opentelemetry](https://github.com/prometheus/client_java/tree/main/examples/example-exporter-opentelemetry) folder has a docker compose with a complete end-to-end example, including a Java app, the OTel collector, and a Prometheus server. diff --git a/docs/static/images/otel-pipeline.png b/docs/static/images/otel-pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..5cf8eda3dd3d877bea1444d4ae0989eeaa07b621 GIT binary patch literal 58434 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 z zMH+yBKj~9iAj5kYJezV!MsN^?fc)J%R*xg_;C|=Y)^$P8h?{Al6(Gj=9HjtquDNVd zsn9Q`*;>MY3$Jyn;u}AcxKKre(}t(9otLY0Vs{6n4{Sy}`kuuc>+qHaL*9N1W2^8u6Fa4ICKnFXe z6_H0G_0aR1uVlyzQiRF0rQ{W_K2kvaVL0qlWOOiKf)MxOSCK+R*V`L@42toyuTZMDmH9OP=3OCv$k5L}PPMhoSo_goK)ACO)zxnz%uwkENQ&>naSmj2*2-9)!)Ey8 zLH&&}da{XQM-HJAx|QEDlq}mn=*WWv=vqcAe&82(dF_{)G=wdLHW$9A?auZACL+m( z@%mg#CLjMz`(lI-ahQaTJf@<5HC~1JdNH#eV2@WT=H;X6mMrz>2NX$IJVSV~K}?mF zV=XJ&06RRyzxl0yU*H6~CPToE`bpa{^zdnZBGh0Gba)lQDuq<_+7t7qwHs92yIfWz zi^+;;TNz7LDAF%i>IAoZ#bCUlUqL}P$Ewx>L89U{sJ!F|c?0LX{CQ~F&FBN$8jDOu zKBME5$qi94A{*Z~jg(3Jx~&#AtD{kjAC%DN05UP}SRs>O%7JNIxAhc6R=)iL3*%<( zraP4zjliX3HF|P^yE!T*mtDUORwfqQnoGu(NhvPX=G-WDD*VdX3ufqwCUCSIc{04d zwM-{+Pksw#oWwI@qwbJo(%d1+yE?P!7GjwcsL6CVEq-EM(rXg`1Iq~ti2DO$vf5sV=1JnvZ_`~F7CDv;G@twk<86RvH^h#{I*0|z zlk0YMTS}p+c61Yk4`7YG^<3V*rg#EZ#FRKrQT*Irs~~FqM|BR{sa-e3<#yqa{5_Sr zA!qfQeaoit@I&|avlx3S5$4TgQAXI<#w>>9a;B*wUPVL#<*i8sUMJ4i$fGpfJ%?K+ zi37#**{xQh2)!hN$32Xpc^fAEe3V11f)LeK7{-REJihg(`yHcZX;HKUJKbO99^D(# zXtvr@uik0}9)o!qmeHyGE4d%_;KiSl~WlSxN{f880`P^Y#Tw&$wv`=@Mg{$o{J##*jeBj&r-6^ zjlA%$Pzm*11zti!op}2K8t16w+kISWS$K{y+@Z#MA{aE&U+&`ductLsd@{>wRVi@# z-7vE%dF&)pr}Z7|ySB3#8Efx2meo(%7Ldfio5B&e7r4}h;9eJ@U;l@MtV7JFsHj(o zO%2?)P|OR-L>@XAwe1eF)_80HRQa;8NuRD>Sgwwp*AfIzXD0~`y$Du;GRmV4UU9s= zs?G|5SwWGSu(wJQ1QSVu`^CQpC5s+G5IFORTPZbS+X(Q5v8*8P9a==2(LuGA>iEbOG*7OVgzBc+4bamqfk+J8p`p*u^XIbOg9dHG=Q*JXI-(vA*P(MiDF|Rw$xmCZhFmd@?0Aud;M#Oq9IYykTM! zkcWudHhO>vGena8#(Mo2u4FOhuOJVs!0>Lc7+~#HUM+SQLS5sWps{`=zbZ$}QBV;? zr42AFiF>mk#L-N_&C=*mPY9fgJ+TU9Y#I*9tK;T{AA^Gr)Wc0`jC@iY59IPu(ZoP2 z+1<->Vqza8xP2W3xSjiN>i-Z#-=05zpW`y9Fe$@z*EOBB=$c(uf=OSWwKAWA7Eq7O zqrX<`Yvuwwik;}96NAj2l`4XL?nREDlMTL)S!*WYo@$3T{(iT{N|RHUJh*n445-%e zbT|S@6OpsU);I9X=0n!e2_k~0b2*#`b9D|xBN@_VD%;Dn5ym5_&S0lL|83kiEMQW{ zm437*e_{C!FLrxgsC)u`zd#xK7iLn`x^KGs^-}tx!Cl5dHZvlP?Pe!hsvc-vDX`uU zxgV&gyaHPOs~PgYCor&?KQWuAjvsQB&K%EGD7X}z8hA%kN1_5=p5|?(Y@H4zvZ1lS zqZByuvBTv?HgD`xm9;X(wGsFtPgKJbBk!I?u}T^$IJXC4dh+5tS0pj4 zN)nS48IC24ke(n|RMr?z5(kkDE*ZC>DAZCJn~^=~@z3eDoSsKWvD$m}Q+_OIld4ur zO)Cty=4lpt-oenmGkXjlt%U>!7$EZDOJ2H5{^|SUUpxca$qfi-AXB=zXoAErTe~%o z%e|%HQ07eqAQt%y0AZFEi7MvL6I%llS^>v5K=n;?Ts^*ASQ<#S?Id;;02Dh6kc8dM z<&NifUdBB;Sg*S6?x^vZ(O(nIz`@OTq4Wx~v{y+bd7?|EIAUgAdFP>9T7nn=9 zAvB54N^wA6r09hRjK$#8ddneb$|F<3$iW_&r?y(2*#0uCzIWv`SfKprXZzfqhB+F6 zoZ*}63dxVN+-8})(GkHISOULr))l)z=~a=sei4j=@y7_Xa*F?|7)oHly^FVS_uqIe z3Hw}XKewFf@+VuiatJsE=<=38j}|il-M+Iad2n3s*@j$RxR--sQrY;mEISbh*M3l- zrq#DCqcBUrZ~v}*o(FL0nl!!!sC+;74%y}u?R?G+Ai22W+Z-0u;G}TZ>Y1Lbv*{Tw zu`zKtnmk0H@T6zfUNfb*exA2PqQ*!n!@(eP+PmQQQ()%j;FY;*vbzcH-{9sp(W+J) zMizCnL^W&}N#cmJpxgnZIu7t{o|0qJA(hJ$yi-;2V;I!wzQ!!$zykU^c%YYf|2we8 zj6l~EVso7_C9|sy{M#1r8SImMT%z6Mat{dm4d|A#%!DTD(Oc~FWOf~6fuwxsCiiWu zNHAx$vP7BbK_*#=d_UIe-sqy76Yaaj_J>B;P&EIi1XBXjA?A0Uk*|?9zVH8e)-i=< zRpz>!w0J%mh@j^}pjN}lOrB!GJmMj7+;LBf_8%0V{KJUeo-&0kf%UuJ< zcF6s2lON->_!_^U5X?a(ZV?d~;T5uICo=p-EHcSyXq(=8m=X`_ov3Z_;1DhDyn>Zxz(_f&t9Z1%ehZbje>976nbtKSEOHg$piKpP;?2yQK(08{D$p?WF$h zKIh7NDwArqkZmUPLOf|d|M}yi=k0dw^=;lV(*0o%@GY9eM$cN689+Y%HO5z<(~FLtAE;ZR;Qy{FhM!5uIBghl?sX8vM!N-v}7fQ zuL^^9F0LiZ>#FMUTyg{E9QI1xp(eQ}3W$mRk-bd}itHn0XEHmuFAj-{iaL2ZJ}N16 zOG>iO$?wn<8NC?0S7Xj3!IMkZY?;v*2Tu-aI=ztgxEtQM0U(9=Ijh!*=r4}&H0D+U zadfDwZDMW_ORrkvuopQB9<#WzMGQ9$)c*WwxgUGh?G-Jg+l$9em`ID zE(%O42ux}K)rWp^mFbVmN4&~O5}G1TUM)!c8hKf0)AvyV?_rIW{l@(X@1yP;gnN)9rGMt895);>}!G7_W`lc%f@SE>+!l51+gJwhdPU+0sZiWUJDohS|xkMkAAj#FF#}?GVl{E0bj3v`$1tJv>m5 z)zaGct8ycg8@VC?9g%(OK~0laMJiRp!{Iq#ix9=tHrgC9fVmyIwoBM=a8OqNOptGP z1jWF?*i>Y_94F#A9P9O6qxPDd>IHn`tF zQsMFItX0>@d2{mEYEO+0Y%e6=x zONXuX#;pr;ylM6mKXmbKvvSLf1_+w#^I;kun_o>_c2kLZL^i>LVP~^e3|Asym6{}{ z8Jt?k22osoS5tg?Z5+wr0dun1tt|ZhD9SAhtuMPa$oCCdlNNa`9Mb)9(sL}{@gC$N zyQ70!v(vSkd%ReqgQ-hg-!~yT%d@J+pHm8NV-*W+cxhV8u7r4BBMMK0)03AvwUsut znPz8mZ(c;T5pX_su}rZ#zM?8rULL}jMB-7gW9~}6=FZ9f?zv)1w7=&qr>p3iy+x#+ zw?td|w^UNC%BncM5y&Bz5D2*r)SJIn3$g-1N*=03@>ffl@5Q6Bue^xhQ`JLJvo?N; zQXt6G8h(+0UtTJO+NcyF8;!ysbm?_Bed5}R5b@bwi-vjD5{&+k@Wo5>u~Du>QzD^ z(*4A0ex+x&&FYSJGA0F=7=`N?Sp7&NNKOUEBWrPRNC*IxB(wpAhW6$@vJ8jCVHd4- z$~4{X&}v>PH$36830}-X%tW%Ts#ERn?|D@gD}R8=5S}|Ti74Y-Vqf?+xxUnwC3*es_O03{O%N83r^b* z?hcu52FCO=i3snm^#JE+3a5LasBpY$1CReh4ww{CF8|jr*>74+$x5Ni2L1A>e-QoR z5TY1izRNWan@|QDuf%zsPNG^{MhkTPSyoC?6DxkRER^cKlIi3VNGX|f?gI1p0}IY^ zrb9h^Nf*dpP9Qfb<{X~IYb#(>$G11Qw!6{0jjTV9K2%uj;?;8JQ%waQ`;Oy}uS2`X zclrf>g@^z}IdLc&$x0r!pQm;^IjM32)O<}4H7GCcV=ASYVn-qm2L)mSlVv2`w#kFO zk_J4!?>@`K7A4T^Y{!Mf4Ekc#wE~GD*Zfwg(mxe;9}&VjN#liphlfJ~^XiQy(r27( zY;q#GAF-wqq})RMSF;#MD$UBnS(NA;vd;jzXb$lNptv9Ijy?;3ULDKT>D_!xNeq{F zht8-=jzT?4)!x3>!6SMYRA04wW8L)cpXy%c9mwVa$+QF`=)5K4l-c`mGcQG z6;3_coGT!^xH5$9ATxO0Ca}j=HH}-V5{TJ3MSC5%>s!#0g=Di1T)HY3%rKQGr@#|X z$hllJv0SkU!{dI~c04;Yd_=Vt`930_nJew0y+K%kp>$t5{Vh z^$;soW-OcH#G|Lgt9lQ5+#)171_kleEFzvfuN7cD(^Miqa-;(B7JXsuuE>E;ZBSAj zL584FX{L+|x#p!>hB@XO4{=#!oJb0`0nr(b*~!WBsZUQ@ zXcD|{AckbkX8V|4z-EZLN* zt8o1s>r}LpvBXDwkNwYl-p7bY;Q(SPK)u`+9@cOt~>9WX8MHhCqOam^3jen+mmgT`Cik zmgU5_tN(U((cn14vrsUL34gg2req%m`W7f?eUkCz?D?0@-I0%3Ee(?apH)df%ad|H zeSZ*MTpP}Y2m3;e69KibC_l>mVT#=bB70IidR|xb{$fV+cb6tj;5ebfKIMwD zT)%FCCeC{=A<4}yN#*&wWXpMPg0fF0G!8>aK5(^EA%d7};r6)U_;;`u3I9+DWV(VD zNJs8+wP{{jVTWC#>W{01o&XYYuBaMd`Q=58xQIGhi8Y`7Z zZhZ6677xx8`;r=oV>?ka6gbv2*Y+yfYhpKK^3FV^YEv;Tg7hM+nvx6$Vr?8A&x zroPzLA#W}(ma0oQEOlN*pk&TU9ADiK)Da>e4;)kKp)y{j)}@Xo{aowf!te;6%P7lC zw*sH7x%$2Nz>?O1*YP^5{jLo ze8Pq^tHVUNKcI}TNw3-!^SjcM%;y2krs_AIss@?QgFoMN;ZAw9LR;dX`vc$qXFKQ` zWa;yI^~FVtPMWDsxPXFk^Gx{1o&okatN?#Q|15EiYMXzhs%g6GU)fw?c>zy`>E>nT zle5iezw|q%B-s;ObS^|QMH0c}GxH!u5TGIJDF&Jf!AnLwPqvsaml*t0-GWHe1VmvD z?qA{1yqqfpkOFnb^%g`GUIe3m{5K7l4sI*h5I~7O<8NA9EAp~a7TRo!SywCk3oG+T zVGHgMGB`y>>{|2a(|7UP71PS_~REnqAZ%~FO+ zvCw=#2PfbdpVTjDsGcT&8uE3XFgFORpPSqJ*8+I<5UUXvIzG{AW%2Qo2VEf{y;D40 zbbwd*=+4uf4&!k%*gNEQKBOTq_KObWlivSjpgAlc9x`{r*F_4+}wb_UGX@xtvd{vCBuKSDfM@0u|=XrmOG#AMv z`O-mcGfWLo%EO1o=NKxfd%X??I=hiEgJxSQ93~-eGPI5HX|~05gQwVX6|Nh|TEF^J z)J=n7tPiqH0kfeq3x5L;8bagt!o~V{3&G*yr&KeGQ1eFHX4Wcg@)#?1DH)&UNMUZ+ zIjQgMr6g`w--((Gm+&ZaJh58KPYQPq0y%3YeA@n2=&z!sMH~|Hn!`)PkR`C$3kBgCy8X0?n6w`jkJ9r%eWUT&|fp{)f(o z6Z9&gwq9gQ(HRRj82^@eh{E4RuE0n%gyz&~99+(J=5;1kj58 zp#ew?Sr#YN(r_PPq?L>88@Y&A!AH1oqXj4G)W$Z2Rhbhmq<`8EBO`keeqa)CUQrj7 zrNqfc4IuC1(Zx{Du%0iGZx0kWs`$L%isrNlEs76UQ}N`uH`XH{`#|6_)@HuE2fQ zIc@7{H`XX+YJVvI8i@&yonf#Ih1fF9kB1T!NOWi)Htx^5qh+>Byh^BF;HKLb7XEE^>Hu@C-MV zBt|!CWqep$t6jY3hLS;V2WFyN9?;*#u~sv20_73;tseX!=|_kf>JJ@oNko>U$krMN zZQBZKO~o?HgZ(ovAw;e4)7*o!Rk{UIcrnAim*g3;?IO755Sro~Rthp06sb0n6NQ~e z9_&L7uvW(5!jM`YO-md~UOr*qB5rG7F|On^nob zwu>68hdn+DyD9k*+icT~APJ-5;46L;2YYo2| zEB^|8)M;?fsV}o5VFE=iS4wSKh%S3Y3n{Pet6Tm%?suETc-fF8GQ>Cv@F+Gjs zr}4zydJA=Uf-xRmF<9JY9qHU;9C7=gQ0jOR?S`#*I|T99N?g!^19@#WVT2sb${7{W z24o03oB;^$s+#sZ9>vWjML-}}O1&+!?Y4g#C`XvhMx*-h}}du*}xgwKQP zZUVQ|L~>Xc+RdX~;h*-UOSEU(YOS3*@wxte|IxfSlR0@mnpMduuCFI192}AQVPjX* z(P}z78Wc$U2jE*+f%4{NKVb0Zw}pK=t0?{<|&JE=|0X`8Op^Tg^!;V zM3mRdM&@}}CIsEFzDaZ;*}nJG$f!e)>Y4h=^hbr{(pMEB3(Awt$H<5W7TFS2XrWO7Iz7Al5&P=}A)Q-QthK~c`Hpa_PJ^wLMQyanyN zOLiEHn!!8z^?b4{;ql4bCy9%h147z)7 z-sI{cR`~MODU7Cvk@QK@I&e?;Mk-in4Zq@R0`QVOXc#BT$PWOHusC1DK**<90UAiW z%N?lb#cXVtU6s3K5I2e`M%b4*GCYSJXC4bxGHQjkCFzTee(K%dE^_6N`52)Mvz>08 z&n(NVY4V2F9l^iTVZ!o%eK_RDA8Nn^pfH}A*JkMbPH}L709V9!KD#DXW@fN~0K$Ivc75tR)i3$0+*1ANy z{qgau^mKESi0Zv(@=v41%MG$W98twBrmnk5o!%INKPjTa&w zYUJ!TAUO*<9i3f}8z)jqB1V{`w<3zB_`ZXSmh5{4Gd${FLqv*;jCgeG%Y`n~boaFz zBR&boWoI%gR*uT1m&L^+rOCsq-pHwGSfMCqEA`7H8#(pa@#d-FriDoM35jW~2#-Sx}Iu6})-iF5)cfzDpP_E`u0MK_%CSo=< zAJ1H+_0mfwVrY>NR4D#Q4&caZYf!KR^f}O6+tn;MI9bbS+ST{C>EyxDk!HSWwteHzq{EuHMSIq6x`;RUy}s6Hl|LFyB&6B9XaNE2`T)`Z9ET zK1D;b|H8)q=ib8Zuwk9w!bXB(nbqP?_W!c+jndld|7QV6L1_S$(zuY*N?Tc;gQv3i zs;b*+AE)7PJdeM%_^*tgWf_6}7O!-E-7L|2^a#!LHUR5ox7OI_(~Ywg!(ARK(kaFN zD}{$U=)fk>48GD^X`&!QM1hsV-*Frr1zzm9RkE@ESos*m9Sn%V1@-fa`j+8IgGS|+ z6Q;>6>}=xV=;F$={Z@qdOqny)H`K(3L4qt^YFa6lO&IH8^=wY z&nFdRKWj2WvPk40;y{rgX4Q0P9hXtK?mkB4A=cPcBtyPsV1Lj=q`Jq#ZStrntM&co zlExERXT0XuF7Y^>=6qe>DwV2@`H@quaPVB#W;Qr#vo%)|C9Z}?UX2nG4I~H)L+NF@ zD4xS0E!gH#nlR_&M2iQuZ&lyt6MX;Bj?U;@jV@6sYnqj5kEO2=&(Jw&Q#(tJ0<+{9 zQ5#yC22UT_^YS5a{#9Kffw}{faIb7QHY2jwVhz5bymI+(AcVjM$ml6UiEKtN8*+&} z*wiQ9o8i1IZJ>Rv4W%Jb@P~wK9#s&>x=sa#H+|)a4`%&b#Jvu$7%*v_17iMeR*#25 zOfyVzy;)6ivK`gcRdb22xEp6uegd-7*p)sAC2$zAN?Nvf9$ke+g*|@vA>)YhI?)!btIe*}Mc*f{K`b+P0uT`sR)~s4< z{-)ZTtKHY%9gqK|+x^kR)KoS!II3XIn)XOPh0kn)=@TKB;Oi^hGG9)KRsjC;c&BXANV70}|_sP}gMx`>d~a?AeI7 zW(ad%$GYL&Peua!3Bw?xNAco>pQ4&I<-PdkT2?;7yySOeBrp%g2dE3BjpZ?I^kM<@7}9#7#Tm*>AP zOtC{*;60zzYVA3MFb%ZxL0dv|toKTN6&t1|jg2GfXxJ!lP} zMoa>2b91SbJzcCL%sIPOS*C~{^Tj*(91dpaBu%Obdkg_lD z7m8++u)p5TS+3hOogNERvgmb9g(turDp1zy!^w2&LuVFjjMQeF_k7_sty&4nl1oL? z4x^mN&8$4Lk&+u4k&5QNr{lk4P5=SgR%*lAALF0e3*;AUK(`Spezv-5SPvJ@3Jv^$ zEv4ou@ix0ZUjLa5y@vAD{myEJxuS-O0BVnrpk99 ztx7BOacNZhUT55zT5{Pk(RxsnwEn?n)bqyOSAXbiTmNz`v6*WPi@N*+NchYlFJ`FM zq3_TN8Df|aYkygQe+l^>R3&#j)CjF`Cw^-6E;iJgc?Rw}yc_WA-N~8~G z$J6TPCx=4>hZA~C{@X)=iW;1;jz(~O*IS1Qijnfm!NbAyt1`2^5%U9>z^%S2Qm#FY za;GjjvtVD=YQ6#rt*WeV8Cv4vX@A-_!#N!gIg(wy)R@0ERN)^x&t@@O7MICvb7|tG zF`t^lYrc->|0XQDTPP|AGA}JBV^K&)!@_xHJu%Zu`&h!!HaqQBO5|(5W&m^AtND%R zBo+qD!EutFGf|O+q7#DYms%I_(d2u*+{Y=}Xt>(nCgl^G5*nA~=UlEG4#T3{$l%#| zX&3UaB1`8l491ir?VI;dSV(2B zu|8~x%kpPr`071o)zsYO@fUE+tXR4oa99EnNQ4Lg#l(TbH?d=4k019=R6Bibhn=k^ zi^W@sw|=8+UtU7p4%Sb7Gv3=AHkNoa23dTMz~i8uM&Q61633_~L1}{^Dt0yMxdbj$ zg^@_*H(DL+PR!b*ENiRSe|8PXG2XaC%;odw)t)_B8$bgAoq35D^q)EE_o?MoPK$)f z)JzjREnt&oNK`-f<(BD6E*9r)!JnRq4>)j~v^RxJGCtyvyl$FP$e_nM>Zd`ikn-@s z47brOO*eS}^CJXvN9gH0n3vLM)YcXmPfQkyr%o5DR4b)SSHw@{(kV)D{8>&LQ*rpM1kJ9gB%xUlFE?6C zhWgTMIaW}M_XBx{{iV$UgqhabdSPL~)N{dvzlERKFM`_hA7Z-%b|(y6(gli)+`F-H z@cf>D8?`P}^g1NPFRLw}AqG z{3jktS@{DaL`z1FIFGbDgVQ6hA@g0e8> zjRi~i+)8TniflFJ@Mv^(a78vYCbz=(>Jm-Avm4Tv;}s?FiKqWO|64ghdIepl@d@XP zf{+AAvw#m-iPt2&$A%l!+K^$25XxTIP#b#$bj8hWjtr*cG3;J6Dah}twG^&hYQ~P$ zeq~|>_$8rlK=FkGpWUuP+=6HG;0=dumRk0gT~oh0l#$#Zs4*(7AzP`tNrsa7yU5pK zRUv9lRqW^Innut@JU=Ex zi32TmyCcfv+_5G1b0QNlL|jqkQxsf!M9sm(w87#U2Z-FH5lzN5u51@|pTRGx(nll5 zVBZ8>{@tI@q%<*zm{ZrDE(=gZ&er!baF}Uu$oO=f6jq;>+gRp52{Ras zn76GFcYi{W(q84Ghyu)~j%$*zps@3v|#nYE^+mP&ckMJ}CYKsiROVjS#N;Pg8?Q6aWj*o#y zsBFk=^Y-2DdNW6{KgUH%eqkjT(EfIlQnGHrxw>k`YRg~=Y4+jK;!~R>9EszONMJeV zjlYA4yH>&e33*vUOy7P7ZRVpmjn_jMObweOX;4j5Qm6W3DvsqcISPs$4BFIe>pprJ z8vB;YtmmRX&TDplD7r%&$P-G$)~Y%=-3j6XvU0#zW1qlkXSuBFev!bpoeT;ZNec_+ zm|J1F6TBjbp&2QP8Y_NnUGLTU_;vJYs|aT}Bc7m09u5A`p2DZLi+=(slig|(cH<+a z4Tx$@AKGauUzE5Yu)?u0ge|9jMiEgAe*c2(l5Rr9D4zvVrbhO5$@8nn&?F~^F|c)> zXfkn1tQf2K(`2XUnW$q~po*)zTi5uftOTiBCet2z>HwCccL@ZP!!I8!k`?(z10|r5tW%j8=RKYheAj2D=1jLep@TXZ&NRmq}@hxHTpdVW@KaBi@ z**dyeG6vlmY}Y8IW1uxW4 zQB?-%5_y-S_R%pAy4xsQYJU%Wg@-M@uqgu^dU+&7yDNi6S?Cpgvh9PJv&G{USk>X3 zqjPT5&to_41-f|^{D{zwoY&dgpSy^X*uKsd-%Z$-`+)-}@&{tQ#EUF2hRj=2(!IL9*%}1Xv_~r@il}p4A^Uq=w~bE`ft#d%Enx>9c8e9(Aw^Lpk@9+He4`S@0THtT zytKHsc8;)1vP(C>b#{@`Rx9S6nI)d@nmZnP9P@{ZLC!x&{-?`A+X90Vy?j0PdmFr& zhedK=Q8f7t1|OVm?S9G3$(8H&SJH^Vg%Wop%{osjndY=-DeiF?OkZkh^a-H`^yHej z7+DKTEyD4OiS!8ZXk6nX)5-MeXVr@h3AAZ#KeRl?-Ql>huu@09jDvO#$&bBv3CV%S zRJN-irvvWvgbS*G~@I(!dC!rzF-;dyaKTCiAnu zvEf%Ic4!Ho2={S?9EP8g-_(+16%qUL@ipE}$9x%DuNLUl%VsVI*ev=z6J`MKDwgW5GEr zf^v`QG9V(Sf&d@ct-&n;4Ns|GLMva<|3>IYj}?|P<50_Mn-e2sVcDxaI( z%6Nl8dApyD70#gK^pHtcB%=j1T{7(u;d!9P|Hs5ECcnwbK&D&272FlXaa4zJh}yKE zX%($d;qFf&Mf;5)_HXN6uE49W!|FhPP*DO0Imj}6>h)pFY(QJMoEQ~9St>!ky(F!i zj_}08myKkSb~+Q@@a)$*@)Z(Bmk$d=Z7%?I|m?Ze^5{c4dg9Ptf2uO zbP@RA>F?F{lo%Wnqwc#DE9E&Q6*IIZGLF7WTwS@!>2rO|8)%aiCX${n!5{QJ+Yhe9Rvh~l`At$q&Ho*er@IVp++Z8B zi0?9v(oz=k!4hdwvw1S{TAKW3v<75O1iZm?MqBx1VC1q7{J~)deI2#H{D|B6)sh&r z7?Aq0J>&4TV1H-P2ry^*7D6ptEFzmb#R2N3UYVAaeXz$KgIjdZ*=7ezFyMDYP%8T) zRY(o`Sm8gy2)iS&d#3xm{#;PjC<;=;?Oq-?m)PO7pU<9#IdpBsUyIJKxF%w#Ry0cJ zL-0X2zmzmEYD2Ui!D}E?pg}Ejv6B%m<}t@(T35;Z)Vt0C{dVB>>Kg+;MOjPD3`@ly z{Ug(M!13$z3lCqbzhe2}JUAsNWY3RwLu@GF7Qo@J|&S zZ?TN0FDUUO_}Z?*x~i!>TUHwzF3;thE3t5idWk7Zd9K;eo3RDdU4Ov3M*k45Tk2xS z831jZ8}O*s0D^`lpJXmy`x1ETt!ojCQVdxnN#(UoeobI+I6}#vW4$iyD}%Ti`1dJR zhi>E>;cxdg5MWw^GfE2ahy^#9Cq;ivtrw2?vix$LZEpIdcz`VHbPm|Y-%E}H)znsB zPF6+=e?NNH7q3LlNq!1L{6oD#gfxamnI1+x?VG;ly%>dX`NhoFpAtD(Ne0wbWHarX zm>_R*9QYb!Jf?QGV?6@w;|N`TwhlwA$|~#!E+j)And-;-y~}J5a93@dUb+eBIi@|5 zJ}4-BmO!Kl5Z6hT!jPkhbFcl{4=EC;?DCfJ0UMSYV#;LqhHwknw`*~Dj-F0AM~tqE;_iz^|kO}*p7%k1B*n#OukI&lX{8#ppxkM9p>J= zPP!`OtxX4%;Mj91ImU1f9>S5G;9WbD`v5DG`Cc8hBTK(g;HDc$+tsx)` zVufxF`0V969zlra4u*@Dx3H(Zuj>!}e_|_Pr}FqYG(A=&=p6G&nythF zgVy6z%dEfL0uA6BV~YGH3MD`FH|-O>@5!R50XnoOCIo|F>MI$Zpc(S|yZlO(vrsX} zv$+3LT&NXlK6ZT3WdtG@ada=cc)+Odt7r<^D?h)K(KtGJi`fj`wE)*=DIDt^1w}`* zVm5U*Vo!5~JWMnZq5<~)rs}GCVhtMF_Md$!=>BJZNfsIu$qu_r84K+$d$R#7O>GE*## zQxU?Yd6VQ#n9L=i2Y5XRC*a(esBRQfe5WD3Gdrem`-Mw(O%4fUJx~8`!h%8(`RlJH z#Q0_$`uSWsd&+@Q`yC1uO6gm9gC+H>5OJVoGlZ?l!gTaJ31zC(q-#)Rf>o8>W!@GP z2^H_!dDf9B)xRPu_u24QTtulHd_N`#A1Y^@U$y>*M)l%|xu;$xcVRg8pSDJTnl-WU zUU)n=#8Dk5DVvMF*i-m)Q|paWJ1iEzytp09rD*x&Y+pi8bEHB?ks`H8UsA>+%T`w+ z>N1;^#dYrz{BZVxoy!rH)XDwm9~>3Mr-jZpvQz+r6B{BRMVLv$EM{+zf0d<{FC+%R zkA`*XMFd5Y+2sm$C)K8m*w#*|mQ5t=*A7jFYl|sWxt3!WbLLFioiXC0ep2|{>zSFA z&a&%=E-pMvgorE$|MhK(k8PP$PD;-Dw8h?AVQJqY3SA$JqhZ~ z#lm}5a%|J7o(~xfmr;CnqF$f`Ai4J+ zjKWf?gy+Xn(E$%?Z9up>V#EZXAWIcu+~BcQT`TUO%teh6r)9h<#%^Q)@Aq zp~7R8J-*8U=mPmC$B~9LcfxBkx+?rLrkKUWM6v9S*j+Ws-)|$l*N(*4{4fcT;fy1;7L8~4Bnlg93f7U+TXB(MPH3spN+ zM#q^Gr>&PU#hc&w6bLB8uM8_07Mja2lY?tVDokw_p~LAS&uOXJ_MyHvvt}&nURL<< z$M=9``bWo_@XOo$2Ou9mEsK7m(Lhl1tcB|cQ7{AF3M7&}cOXcxBL5`}v+Cbu^$0<( z>M?wo%;s5D!J3J8S3h%h_5^gDrC=UbXClb!`h8lLs}A0XWk--?xH)-qU4Ir#(_e57 z{~Hano>BSam2*FQPDMuNaIud72@ET~#dqk;8v3a&u^SQPQ(zzZ>8faKttoY8Mh}+( z-({`_e$!=^&u-bg_g#LdlUFM2Nf@ z^jYy;pV{~)g)0|k`49PG(5FDa4<5-=9^TqfDEx(n5vC{>NKdmgr9fJCc{#o`uAR?( zDMmaV^(J4yWis=f`_s*2d$lw^*L|feRvOp-o<`eG{w4*N=#8S0RJ?Gr4RU!-5DU8> z4sFiT*aDSgty!)o1ieVTRwTvVq2!0u?JsZW2=aD1fT{2zmQmY?2NN#Sa!S4tE2ICM zQc$8ytg`=co9fi6KFBw(Bb*RFz2Nd(-Q#SSOKpveqL=1{`r?Deg@Fpfdkum&5%H9{ znuLma3~<%YmEyIWu!3qna01afjJJ1K9IhjED>S$ zSjmOqnE2O!Cnl&Xb^%IyBnEqboPb@`K9Ho973>l|hZ+!y|2!`7(TcFg=at@@U$Vv4~Z_ksn!J~%r?yE)xQU&53iiAn{4V$Bi+8950YP_=(-+_zS6(1SUm8g-%$ z*;%L1c(uyETU%vt-4YkbTOb{07?AzrY6+m+y?@Kv6nWYrod%n0B#?3{I_v9Zmp^S> ziUfMf*A&N7PnijPcV}c*x6}6IP~xgGBAs4zv+>83MAJnYkj)C#x$LLV$kJ}3w|VlW zw|Z(rWTSDAOj2{uFC8Y7`0kXlKAXrdETtL&!x&z9+YhfWwJ#+9KQBod= za0+Sd9HoW^r9PDwXkO~6_BAXYX;K|AE#@3d&Kx!J7a}+N=F=1_NE*8jOdfH|f8uw4 zqJVz)m!I>(_#xxFSMrmcC=q{|m{YRn3(e<=(os=?V+LRwtb3ZB`}D2Ab-R<4N$M^I?miOJMuj?%O2 zG502R8KD5*30ql7BrFAPGH&Wh&dgi+-bMqCff$Nr3yA@%@ivSVhj#|VhXR>bqihmJmsL<%`+nCTZ3up6 zCR)a!YIU`Wt3UORBYpV`G&;y2$Liz|XW_e7OE~oQ&`}=Qt=toD^-5KU)r5yz zMXXblQ=X2YQ70}2494#eWc-CPv}D=^;$_8X9J^YYF8jEdaYez-&BKlL(BX@B4t?Bf>=^#*!O5b8pc^+geHoaHX>P+utYO_ajKe!iJ40Wu})ycOpd1FcuYI% zp`3iqBwa-nvR}P5tg-l0X#Ytx|2iTfZvns{$VfWR|NZgNZ_v>uO8n`Do6%M!t)L-l zZ1OFl&>!^CdxH?Izg43Dj?d^DAXiC$wf2`seW6m{c%OVJY064-$>|FeKg(-@P2k`+ zkvGHpQ#meJvf=CBNRg^No(JtFhraYb$2kfacm@4V^$q5iVgq1xX3&l)kY5gsXR)|; zoADKAxj&hNsRy{^@_ChclW7>dR*^aQkESC#Isg;>=aHAEK6|H~t`}G{c@lzQ4gWUN zk})zO{AP$C-P`EnQLhutQ`>T{?jSw(T31;|LPB&G`xp1V%#U{lDgfFrTw8$NfWHf| zNrbN!uZj7HgjwjtEdO%_p`HjiHUg{rUyCz=o

    DjolkgXc|%|NokCf1n{HmK0f4@44 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 literal 0 HcmV?d00001 From d942530483af473b085b08562c5f7a62f34cf353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 13:22:21 +0200 Subject: [PATCH 255/980] Add OTel trace sampling docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/otel/tracing.md | 46 ++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/docs/content/otel/tracing.md b/docs/content/otel/tracing.md index 99bcbd6cb..406575a63 100644 --- a/docs/content/otel/tracing.md +++ b/docs/content/otel/tracing.md @@ -3,13 +3,49 @@ title: Tracing weight: 2 --- -It is a common scenario that you use the Prometheus Java client for metrics, and the OpenTelemetry Java instrumentation agent for tracing. +OpenTelemetry’s [vision statement](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md) says that [telemetry should be loosely coupled](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md#telemetry-should-be-loosely-coupled), allowing end users to pick and choose from the pieces they want without having to bring in the rest of the project, too. In that spirit, you might choose to instrument your Java application with the Prometheus Java client library for metrics, and attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) to get distributed tracing. -The Prometheus Java client has some awesome features under the hood to support integration with OpenTelemetry tracing: +First, if you attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) you might want to turn off OTel's built-in metrics, because otherwise you get metrics from both the Prometheus Java client library and the OpenTelemetry agent (technically it's no problem to get both metrics, it's just not a common use case). -* `service.name` and `service.instance.id` are used in OpenTelemetry to uniquely identify a service instance. If an OpenTelemetry Java agent is attached, the Prometheus library will automatically use the same `service.name` and `service.instance.id` as the agent when pushing metrics in OpenTelemetry format. That way the monitoring backend will see that the metrics and the traces are coming from the same instance. +```bash +# This will tell the OpenTelemetry agent not to send metrics, just traces and logs. +export OTEL_METRICS_EXPORTER=none +``` + +Now, start your application with the OpenTelemetry Java agent attached for traces and logs. + +```bash +java -javaagent:path/to/opentelemetry-javaagent.jar -jar myapp.jar +``` + +With the OpenTelemetry Java agent attached, the Prometheus client library will do a lot of magic under the hood. + +* `service.name` and `service.instance.id` are used in OpenTelemetry to uniquely identify a service instance. The Prometheus client library will automatically use the same `service.name` and `service.instance.id` as the agent when pushing metrics in OpenTelemetry format. That way the monitoring backend will see that the metrics and the traces are coming from the same instance. * Exemplars are added automatically if a Prometheus metric is updated in the context of a distributed OpenTelemetry trace. * If a Span is used as an Exemplar, the Span is marked with the Span attribute `exemplar="true"`. This can be used in the OpenTelemetry's sampling policy to make sure Exemplars are always sampled. -TODO: We will add more information on integration OTel tracing with Prometheus metrics here. -In the meantime, have a look at the tail sampling end-to-end example in [examples/example-exemplars-tail-sampling](https://github.com/prometheus/client_java/tree/main/examples/example-exemplars-tail-sampling). +Here's more context on the `exemplar="true"` Span attribute: Many users of tracing libraries don't keep 100% of their trace data, because traces are very repetitive. It is very common to sample only 10% of traces and discard 90%. However, this can be an issue with Exemplars: In 90% of the cases Exemplars would point to a trace that has been thrown away. + +To solve this, the Prometheus Java client library annotates each Span that has been used as an Exemplar with the `exemplar="true"` Span attribute. + +The sampling policy in the OpenTelemetry collector can be configured to keep traces with this attribute. There's no risk that this results in a significant increase in trace data, because new Exemplars are only selected every [`minRetentionPeriodSeconds`](../../config/config/#exemplar-properties) seconds. + +Here's an example of how to configure OpenTelemetry's [tail sampling processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/) to sample all Spans marked with `exemplar="true"`, and then discard 90% of the traces: + +```yaml +policies: + [ + { + name: keep-exemplars, + type: string_attribute, + string_attribute: { key: "exemplar", values: [ "true" ] } + }, + { + name: keep-10-percent, + type: probabilistic, + probabilistic: { sampling_percentage: 10 } + }, + ] +``` + +The [examples/example-exemplar-tail-sampling/](https://github.com/prometheus/client_java/tree/main/examples/example-exemplars-tail-sampling) directory has a complete end-to-end example, with a distributed Java application with two services, an OpenTelemetry collector, Prometheus, Tempo as a trace database, and Grafana dashboards. Use docker-compose as described in the example's README to run the example and explore the results. From 089433431934f821b29066362cd44c967b798ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 13:47:37 +0200 Subject: [PATCH 256/980] Add OTel naming docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/otel/names.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/content/otel/names.md b/docs/content/otel/names.md index 45b94fcc2..2cd892c3c 100644 --- a/docs/content/otel/names.md +++ b/docs/content/otel/names.md @@ -3,7 +3,26 @@ title: Names weight: 3 --- -TODO: This section will contain information on: +OpenTelemetry naming conventions are different from Prometheus naming conventions. The mapping from OpenTelemetry metric names to Prometheus metric names is well defined in OpenTelemetry's [Prometheus and OpenMetrics Compatibility](https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/) spec, and the [OpenTelemetryExporter](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.html) implements that specification. -* Mapping Prometheus metric names to OpenTelemetry when using the `OpenTelemetryExporter`. See OpenTelemetry's [Prometheus and OpenMetrics Compatibility](https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/). -* Using dots in label and metric names to implement OpenTelemetry's semantic conventions. +The goal is, if you set up a pipeline as illustrated below, you will see the same metric names in the Prometheus server as if you had exposed Prometheus metrics directly. + +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/images/otel-pipeline.png) + +The main steps when converting OpenTelemetry metric names to Prometheus metric names are: + +* Replace dots with underscores. +* If the metric has a unit, append the unit to the metric name, like `_seconds`. +* If the metric type has a suffix, append it, like `_total` for counters. + +Dots in Metric and Label Names +------------------------------ + +OpenTelemetry defines not only a line protocol, but also _semantic conventions_, i.e. standardized metric and label names. For example, OpenTelemetry's [Semantic Conventions for HTTP Metrics](https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/http-metrics/) say that if you instrument an HTTP server with OpenTelemetry, you must have a histogram named `http.server.duration`. + +Most names defined in semantic conventions use dots. In the Prometheus server, the dot is an illegal character (this might change in future versions of the Prometheus server). + +The Prometheus Java client library allows dots, so that you can use metric names and label names as defined in OpenTelemetry's semantic conventions. +The dots will automatically be replaced with underscores if you expose metrics in Prometheus format, but you will see the original names with dots if you push your metrics in OpenTelemetry format. + +That way, you can use OTel-compliant metric and label names today when instrumenting your application with the Prometheus Java client, and you are prepared in case your monitoring backend adds features in the future that require OTel-compliant instrumentation. From 839e676cc41602b92006afb359f48ab5bf34c374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 14:54:43 +0200 Subject: [PATCH 257/980] Add doc on the internal architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/internals/_index.md | 4 ++++ docs/content/internals/model.md | 31 +++++++++++++++++++++++++++++++ docs/static/images/model.png | Bin 0 -> 33959 bytes 3 files changed, 35 insertions(+) create mode 100644 docs/content/internals/_index.md create mode 100644 docs/content/internals/model.md create mode 100644 docs/static/images/model.png diff --git a/docs/content/internals/_index.md b/docs/content/internals/_index.md new file mode 100644 index 000000000..f279a3539 --- /dev/null +++ b/docs/content/internals/_index.md @@ -0,0 +1,4 @@ +--- +title: Internals +weight: 6 +--- diff --git a/docs/content/internals/model.md b/docs/content/internals/model.md new file mode 100644 index 000000000..d2dd5148a --- /dev/null +++ b/docs/content/internals/model.md @@ -0,0 +1,31 @@ +--- +title: Model +weight: 1 +--- + +The illustration below shows the internal architecture of the Prometheus Java client library. + +![Internal architecture of the Prometheus Java client library](/images/model.png) + +prometheus-metrics-core +----------------------- + +This is the user facing metrics library, implementing the core metric types, like [Counter](/client_java/api/io/prometheus/metrics/core/metrics/Counter.html), [Gauge](/client_java/api/io/prometheus/metrics/core/metrics/Gauge.html) [Histogram](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.html), and so on. + +All metric types implement the [Collector](/client_java/api/io/prometheus/metrics/model/registry/Collector.html) interface, i.e. they provide a [collect()](/client_java/api/io/prometheus/metrics/model/registry/Collector.html#collect()) method to produce snapshots. + +prometheus-metrics-model +------------------------ + +The model is an internal library, implementing read-only immutable snapshots. These snapshots are returned by the [Collector.collect()](/client_java/api/io/prometheus/metrics/model/registry/Collector.html#collect()) method. + +There is no need for users to use `prometheus-metrics-model` directly. Users should use the API provided by `prometheus-metrics-core`, which includes the core metrics as well as callback metrics. + +However, maintianers of 3rd party metrics libraries might want to use `prometheus-metrics-model` if they want to add Prometheus exposition formats to their metrics library. + +exporters and exposition formats +-------------------------------- + +The `prometheus-metrics-exposition-formats` module converts snapshots to Prometheus exposition formats, like text format, OpenMetrics text format, or Prometheus protobuf format. + +The exporters like `prometheus-metrics-exporter-httpserver` or `prometheus-metrics-exporter-servlet-jakarta` use this to convert snapshots into the right format depending on the `Accept` header in the scrape request. diff --git a/docs/static/images/model.png b/docs/static/images/model.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5094596f0fbe21f7f65f29523873f363fea11c GIT binary patch literal 33959 zcmeFZbyU@D_da+q5d#ziX%VFnX=x;-k!}=_4(SdRloaXilJ4e!L8r7d(%m6(IKPd) z@2v04tTk)?nLlRDoX2N9=Q+nu-S>`b?|ogzPhM91CKeGE0)ezAT(zccW|GBUKTtNnbaG^pVyu1;JWBABx34ySGfg~2B{`mbai5QwW@2*jl#1Omeh{-u-{Csl#7AS6VdDLIXh75N(sO7N+zjK4CX)ft*mm}uyJ%=WW`HN{S;hD71IAs zcZHCamFCiYg23JNQsMv2y1Mz#?dN#|Ly_t{|&3u_y22fll(?TSws1nLj~GtO4*^N<=k9cj~Eyj zo@_0AdoTWpTp%VSgksfkI9K(suz@V3znt4)ZTru5*f^?5IXCj;I5Ide&~&uyrjhDz zv42Zz6(RY0XE`frZ*4>-gQZuRjhVT)j6o+=WShf6W3txK^LQ`m>}V0|^<}@PD5L(& zARnBMw@8t$hm)>4ME}Cb*1@mQQ3egRO08;^J^@7qg^h_?a{Pn70VU;B5o>B{aSD-a zg-20Lx_i4lyPW2~82T#-?>X%T3k^HxlUwsZ0uuomIi4;D+&>5>CVE2g2{S!RcYx!Lk#jHnb(3Z?$quR^JC8rf=$(SPxB+JZ(o$6&FW z)ElR_w>Qc2Y<_n!UG-7T`-61erD_Ur9VpbTbg~YH8!$1vNz7sQ)r()qH&bRzL`-b3P&do<@bP?m zM0tfuOJn1e%M;^BSM(X`Og-3D&&X&jUvu$zf7Qv!36=)Vf91;L-l2fo*7Waz0i^^V zWxBx_R&j3}Vou8#F56GJxg8(L9dcC*Kc%JVySR+@XZ747XryX<)jfBeK|zBHV#nbntpWME{}t;6JTSeuJwUw!c4LAsA- zx#?tqcAP>6uZ6j}4${T`?6hgh6FvLw{YUjRY54!qax=x0cfs%93o9rnJZ~+vU3_dl zQM2AlIq^*Mu?}wrs>h_CN+ym&!eyeuf}qRq;muK-L(4b8WbWn`7A}VyBk2;9s;a8E zxU;eB#OYaCo~PDRJp$wpyrWr-evg(D?`=fH#Kbh9Wv^ckh+_JoS-BCNn5gqaK=Pld zeclWV42)$rWAJv`r?YAKH0p40y z0)AO*IWekT>u|b~Tl}GZYq(I?XtZo|(3HLl58Qy7xqlDcWsk+91Yt-AF(OIQ{^b_pnrYjRA}0z9Z3q8k0;KJS>XFN#s@jlQmo)q24-Y zT;XS8sAGFZ1_p1Olfx5&UwFd*u*FwR`2sD%~>4giCBvKK%Tm` z)#u(~{aSds=Eg?z(Y?d{)wkEKT?6;9TkiWdHkK z;xqVZM^qu0J{K1kyRm#vTU&2OhwXCT<%?HtIPc7vEHo_5%<#G&8&EW^44N@%*TjGR zJUy?x@&mi}F8zW|Ui3+@fb7Pw)tdz@Qm*;=`D*hKAs!x0ibn8gYT5W(*RPir7Z<3P z)>KwTm6z{##`KE?pB=P@%#MstS6QclNziydmy;8)Us;=|b%fv-aM#xAS5du>kLYak z&9yai0hFDHjg8HMJu%yt;R=gYV$KVkmgC1WqR}74i|gH8?=r3|z#UqQI%1RY=BO5S zXDb>xY)%s3ACwrssO(PQQOZ;M*4b%3S|$MjZMZG8v#U!rPmLi+9hZQ>^Yl-fcraP6 z5*37qe7MVyklyKU7a15j7dzFzsL!t!wqQ|clo=0|yk@0nOc548SQ}yLa@nU-FoM9} z^k+NGAKzZ;`SZ`8@)8pAl{gniN*5te=PP7{7FszI5EvmD<6=3j7?3|t{oeWg!+|^6 z5S;r0AdDEL;42d^Z6 zcMMwZ{gwSBK3D#iU*%;wt+!_cY8^MVE6iV2+q`a%WSmHThKwJI`1#7ffX#VFWO?J2i zX%*{pbsJ>o+wYznZsv0`nvPZMPa;pKWsWHr8D;2xPt+d5`hM>(O%Imif@I@~Dt8{r ztM2;_v2U{4w#RWQX!U1GzDB-ff2L12qUOg(>=h>Q;6xlDh}e?PnnNgCGH6|#T_X4P7^+SBr>+w`_6rCYj;XbpdP}EFcZ~v;Kh*h+ zmaVOAwrLyc1lw}5PW!Wf%z5^rNru#4|7WH&Mfj>zxu8_|);;DKTa!)>1j0akCF&Vw zN@eDI3b{mYOp3hx{0uBKcVAzhSa4#p1T&jq=bxkIAVCU|;ev$mi2&1{-ql-tbvyErblkbCwyUoS4UE;Z^2)8RDfTe^8YM={Ic zbw?z=(CJP`dj!4e>cHkxr>!EqE;UWf!=>K&a?LQY;=4lLA3tJ~omRt%y?y=t$@q@P zTn{&{Q}7>u$;!?)Szv_k<>EM`B$*$A+jm6fhwDJTV^AwnGK$dkIC8XX@~^hKq%|ZhG&Iy3=lxaeR(p(%ky6j*z>yfm8x-CR=-=VtcoZVL z3o2bUH5}EE((#O z9sXDY8R0O?wXsFruL3fV@3wTJx$XOquAFDbtJv#)XJ@ql;I;=FFTS;{K&{x!^}OsERoN=u8bMo8YVF)`OD z4%T^I8aGkPB}(dk?}$2Ve5@A@$QD@rKa0J6M)Yc7Zl)Z%?I+8R4>#FaSv4Cx^p%vt4QC)q!1k%9iIso2iTXs! z^GxCb!aziEaH_qX?!?Rl|5LDBD?Anke^^);Ilr4yO<84WX_#SZ?McJnqlKO%)Tn@k znOT^#9=@sScfk9JCJehHEap8aV*2i+KrgYSq%;EL=b%gy*0!~g&3U7sMUWYY7 zj>(ez$xyfVoO?-ol60OBa=0mT3>!{$rNWBt*{uC)tEzH>4L0nG&C@}uup*zmcPYGC zjdjZu3VAFNTiacSb$%S7Q`F(D_2umBY#zsryFvz8G7Qk;@E;%&!c6Hm5gke|tOo$Q zz3o!N>l+x@uBV;-$j9NX-vd#S5_Fa=Ue#O#$$ART_x5&{)ysB7j&;9>CcPsfG6pU- z)iRhvXtdQ z&DrU1KQ3O`GwDkYfpjw&S%5&`Ngr-pmSUn)$t!X{DOk(X)7RIAs)53LfcUi`U4#UF zZmtp?g|~z14atmttdbqFin3s&>D3e?ERu1~m5zsJ_NcAgb$Ob3&MFaZI&?3-Sv=#IbU zWD$aY2|U8a z{TpS;5a7-1gr;g+g1yHtt*n?tic$tMYVQ61eLI$xNw+>+C!U}5&B;N+1vN<~-7}sG z9gt{Ca1H8I)P6}>SrtY{NAr%1#`*gBNk~evu(R{oE{xYs#CUn_{{H>@)~#DzvFsu5 z00(GuY>DSN#6?-y{yE^IlMh9zCMZE zZ;!BD>`5B0vHt;JanLlkZX%4B^D%h1``%Jv8S#jrN|tQ?BdLW1KG(H{t_}>07L|OB z$rNGD^~-<_Ak{WQWJrG{4i{%a*=|m*j|R|2NSb)>nhjeToY9+@m<$(a69^4_c@czr z1#zDeKIrqpJ2-G4<#yW|oev5O1UOEMoNPcRPrfd>*VZvPIr$?k8Y(_ECD!euT~A$C zmq?oEjC2z(N@dZu+?zRrEAbo}ZP*G&Q4H#*6B}YKF2_(B`rrV>2}xuH5KHF`3&rPg zI>5t}u?GDruXm|-CWT1X%3u<%&X%ma>c6inqc#8%8)KD7cUQh(p7k-$H%mV!-(Eb4 zV$^JIZ||F&EKqnfWj!l)bh23>|84Q+p+QfgMJyjPD=WSBs9Edhw^whiv9LWo1)Oqr zx?35^7{|kn&&JRTH7w9=;Lhrjk%~H~C@R7cf?W{aya4#=w$MGIaWXI? zvx%C9bmk@jw3}~0fbGzAY@z|(V;0YuMp|KgpXVr|rNNT<27QHiZhJA-?Y(70Hr4Y| zLzx@-#-^q#tD5`*&1!9*pgej1&hi=s5vOIeXhRBQ*l?omx* zc6wpqcv#o7s-~u~sR<3~`wS(pJW{$j*CxR4dN4jd?sl-Y3^mH2PW|hS1>41Lg>30W z{+ltpM=gnbCkLD8w(mYt`g(e#qyYfTYecREbB^GG>9w|gxqLlxZ=L6hcrd@f>66u? zU3q%?j;4S`!?SIp@7~N8uO1KxY1P;r0YHU{#cb*4Z$KK|aGZMSajK|oMiX3Sdq4m8 zs-`f}w#P(GP@e$&g#siyZAxov>*o*T9cvpCFDXQd^){@YekF!7egt|FmF6Q<-bED^ zI(1H#`08RkiP`{8?|VO&l}+TdDo$x?58noO_IhENgJTHd&}|_I$x?%Y4}$x zPrDNIOcS3s4wH^|Q*-n3gm71(fVo(0-{a`*E;I-WB`&WCDky{sr9^Yt zY6RfR*mL~KQxB69AZ75D&mDx`g$uQ4ne{CGGH37^%GLAi2nRO|ZD+hPKhI@0#75x_ zp&^A|zC0s6y)&U!9`lu%S*hDmDl{p|7l{Z7-M5>JJUsTjaU?T#wr8`Bj)&g8vt0jG zta*;7GQi`Z%s1^Ruc$a%&LRh^r-^9){Mkrhp7f?nTHH{6+-kVQ#`7O}k+id@?G|^R z^Cf@{d+|7llKbS6mt#*yuF{VW9zwn*{f6T;`$>tF4<6`rMKimCiL9@$1J=vfJb(^> z{hK$>Wn@UXY|0GfUD^QFX34~{J8nSLo~!z0+7{*V^3y@O5^WE(6TESz+*oC^W;eFB zd?6&{X;$Vyeo1fIi8>6n7ja)6x^WhT%WA<&)L0btg>z^|s6 z+vG{SxAK$sv%03H?G6Gl_lTBudAFxQ3%qE#Z_>26xPx7gTNe5Q?* zTrABfMHuIx{xx=`3?m#Fq9kuyzik0`M98)#rcz z5Qox%T)-ndBco|=S@FXS!h1Mx_!-tRA|jN7h?F~`(3SQp?=DO2*kcAWJfx=fJe(NF zkXpSh5`r^xUXSNJD>56N1ndbg{`-%#U&s5o zkF{&uX2s+U48luG^`R+|LGe5+OcBb>(CVmd-a}|d0xYFf&Ph+wo#1ml<9FWKg9;0f zb^zS@ub*-&%M1_a)E7*jf?eIZRlm8c-q(^fKILhJiB*#!Pa_sYl(gy&O;R*zua8$#?~cQ{SM0V2bChi<8lkVbUlBb~ZF}f_ zO`n8hO|#N6r2oF~=uQyvGXkcwFlS4_uSXDBYHMl+@-;QFSfpiSGN$1n8Wa>2Sqpc1 z#V^`u5J4Oh@?BcGCw$$wgxEyleD5C2D5KAWKinkl%hxo5M}elE&3rrN3o+Li2!`F! z+q-6-6xdibN8rEiC+ka+5pML#JA;Y)Jp!sw`Q>$ElZEDMR*H*=NGJ04wzrpv_|0%n zm{L(ub;ngY^=Ia97Wslx>~9KyH^-2XH9?Pq)e*k}(A#pqk&)+nTqW~7uO3)F zsiuSN%DE~-i6=9nzpAXK=J&E`9iigqKXYn@;0DnnTPdd#8LW+Taqo=2#?0(O<_+6Z zVm@-ATw{G@WoBjNfj9J8(+B1_2*~(cY-YuhscJ@RRmo-}osH)%u&fFdL$KDRH2fUp6=~~ zth1)v`k9i}@+o1!MEzy!!8%k-*8yp$W=P(JHuKEPjMZdaxlzv<6nI9(K561|b}IvE zidhHtt3wBS46jT~2#JXg=i0(pjk+x+PaV~MbvWvXK>r8wj@;@HV;q}_QiZvRre<7Y zV|r0h(RG5ek$U&60SeEqSo2mEauu%+ORu9vHvizLmmorL7L|oi<6k7Ik zvd|{-!676hWFaaP5emA2a5{uh0+g-}-6~K)4GgFjK7g35r4@gJadu|rfw$B40|rOe z68)9}$c|yC`HTc?Z0w$}zR&Lh8N}p=0~4qiVc_5uUs6&6t?Ue(8JJ2ayw)L15xat@ zb5&@GVK-IkF!b?tJ$&bb1MfM@1iNAfy>Y6IS!wfURy8T&Is{zyL`)SmY8~?H=x);D z(5iG!3vMWE&ItMX`eMqG!P&L`tmHC59`V76<3uyoCQt)9cI=r#f5!RV+?*-=u_9)X z!*YCU>o@Y_t@RK~jv3GOdoUePEBm6kFb^?^)_yQ1K;s=WZm&~-qrAvf3F@?k5m6im zBm3P4-Z*}Ke$W-YBeb_NIPptOja( znm4~garB1r$XSN{?y(q5fA_KNPUKT5T|lc|IYJ!@c;kQ@M?ZO1$u3!_GqE~cs99Il zGMI}V!OfO<4*kTvjUV$Js(`DvzuGB%k=MbrhFq(mK}3xWx6k41?95>{luu1M zci0$T+t9H)IS5)EvVc~$xwN$T_DoYOhXq5>jK_lX*J@j|z|JaEl(4nX$BE*1cZr}? zbXgz030b?OxELxlnW)F4J~)u^`R!K%50a|h{8oT`Xf~L`Y&L|w*sYCu)15+j^>dxe z-J_*mee7U8h}ztCOV1bh^5nmX8_$!1OSFE1HK%;=0196xr^dE0BbB^A>+>CNxax2F zWMyH0#6@7e^S|rviL&>5{~p=B2O)HOmKr)NibgIlEAu$Dwpn;3`QyirtJr6!?Ga|9 zxPUwdU{nb`&;6xdan{}`&nT$cngTpySdHEue7{Tghe5ag*ND2DQ7WXuleN;27cX9n z;zCWCDT^u)4=#v_Y5?S#{4A-dvC&wrtfFGFjDLzvK@ zPi-^IhIP1!?d%wA4%V0{M0yh4dy*PjO)er@twb3VFN%#1CEiKO+e*;>6pB$6VJkV# zz9c|e#^)=~uDuXJ?ioNth>(}pLb~KD=N_O=4oybOUijT<^1*?#Jhh&g%Te~^b=soY z-2pce@I2FN@E{+|*KCeOI@^BTV+^XT{;ds};t*6;e^3Ai0b}HJqO> zV_+}K&0S+Q z94z+fv`#d@@ZjKpEMjqoB1&d0hFX(Ln3%&n)fcQ|QtrHQ^3Hg%n@_bsYj>Mg6Dp~$#&7Sh z0!V({q2m2fTwVnJ-X=AW1OzemXM;<uU(iJeVaoM{^0_)-UvoYfvofP0fk1YM zpWuE0f%OG!BZ5v@XSZj1`eeRcIaBTYQnqkke_#JM2pB#|<<)vBoMz;lA9xT3!GC8M zf)tCER%H%F+EFWpZz;0FuiST>3qg3H-;_!2Tg%#&%hKwFtmMhsmr0ki$OKC$G(RL1 zrKZzuCe*#f+(4oi5}lfy2lR)Zb#=>mmP11e{$8$a;aB7_&j(%J8FWZXzbfvg*_Eh3 zdgX_-Jh@t~h8`OsO_Om$XkPX#1XOlI1YHc`Y?a|USI6a21igg3&Qq)|KGm`|otOg+ zxpEU9Mb_$Z4b`6-svCKCJq|OLGwCZd3r6cDpQJvA<3GYPsq2nuBvQrFmeFHiU4=Du zB3HJNT6%G${Bh@nAr+xj6>Z@IiP_i>pUjAAP&HlSv$DaIGBi4fuRM#hhIM7ZLA5AP zp@U?jON4^2&iNjjx22R_TCiU5(KqZ^OLXoAIex(z9HMsVzdLqBO`_Xq*f^Z=3YNBhXoS{e3JwG?7@lI)rdgXb^I#>f%oKDXIg~2 z=`WI$H00vO32Z7bmqdzd{dhD<@)RK`TRle1xNb44sDyTm_j>7adf}L zcPi7Yj%V#MT*fm9lft{!LNdxf1h&ZL5(Z)@5kb0v56 zuBTh(GR9dqw-ec$vMU1Ps3rjRqUX;x8tA-{*Wth0$cM}w{2zB*d= z?t^uP8x`E2d^wK|je7MD^GbfnuFq_n3AiL58QG=2`0+@m*YC#r3y4U%u35J z*dHt;y_qw{l=+<9gR{y(=Y7Z7 z&5p zi7fLT5tvJwLrwWn`M`Tj)cc5VTiNk#>o@yN&vYXZbvexBmYN@6g#Y9JeP`;)THF8R{l z+6hB)dzagB4fZ78X9LkS=2;vvh3QNR%p7-Q>h$Srs7Pv!BEoaxr?yRC*FJD4cXMq| zTiC0SL|nx{pkG-OM31(OzRbEuC}eO<==AMdRZ;XfwqRmp%GPdRm<$HSWkIluF{EXW z{?2?`7;vQon;E40#MwQ1YfZiT-dwKDdO>9y%wth&85Xjwa+nXH$C)&dTWtk>c}+BM zyNkf^reu>LGQ>+f5_!hZ{q_pN_)isK&zh-)aiDSt3>$pWlRJ8M`sh8;J2%mmCN1gQ zk7mrf`kr3;YR2cs!bN6&7e7u{KpgsoURv(cxG0PM#ctF0_OB^%1M!pSc3MPF!pj`{ ztA>YoEmX!nXHGI(m4pNjMLs?G`R>O}1WqBTzOt_N4GNL3$T^)3N?N|;pMdueN7hBs zsN(%n!;G6(F8R^=>s};LxrFB&c3WacvQjc+irv#Pr7!1a?oU+ynl2$aE_YrcUEt0+9!Kv%ZaiEO`quTW ztbYjYz#o)>(3^WQLSEnBL-M~*4F1qR=56reHsw<-cEhN#jI7JW6dytq+%%}oy{Duy zcI@5l4O|dGvTUYRjr80hWV0C4?sE`r4{&+jcS+bS52MVb^`FaxYTNOi) zjDO3If2&Pfm=+>{-iCFS3ccjrPCQ}EkjTeFT4kPFlDa*E+&z&omNG+zCSdAsZXv$9 ze(~fBNT6IRjniA&-BTu_y&~WGB$E_@XQz_6Tsq2cq2BybG>{dWp=HC`^^S?c*QwS~ z9c(_*(EZMz&fJ5CWg`t@jge**m(hF|5Ig>mO@uVvmTfw;c)=IkjIIzmelyU?WY>@5NWF)7A`<$ zbF^BL&oC(k(HCXg`@^UHhJ9 z_^PrFebjDAjGh7AhihGl=O=nK?@5`x{!X<}f}F+XNr1y6!4v}nqs8a60I`0SNO#6! zlSkV9MDO9>GaYi(_M82tV&lvMd(U%qvXVo}6_v_mvTkk>Nfu^o$JH1QLl>+JuqZ|X z+@yNR+;tN@Q@uY2FPA2_r~FpCsXo6(_+Yc2cS=fGWRm*NmO~#0=S%mq_Q*&P1jynq z|8Z@*dYg_AnZ1yqk2jKcLeFPscrS5ZSND(4YkG1FMC(vwfZt8S4_3%%<2TntE2yrF z8@1j^#yN+Ob^6Ky&4rt&WR2oWNLzC8oGa#AzdU|$PzqBN9^S<>tyq%|0rz?!98MP+ zMAh!UCdO0s|T({L#_{=5y>pl>w4iO+^XJ;(Y}@!6!0OUP8X$;nSplirRBc@{QX^>gl*IHzSUb?0 zinOj20^sFpFCffK(v_PWzmt`_GJK1(?Ca*@nz*?w(|8b7s6qsUGR=Y!OQc~g&i7tA zb|V?tvz7^t*B#25vUG5|5A3Dp^JWK|0wvnY)}!6g55*WTuqe;LqiYU90J?Pehot54 z$$ofjSYGwZq{o#We720-y-Q9-gPV(_?}WOfgIG!islVVm#)T)#mrlP?lx0NFG)m$# z$L^+-7w-sgwlszZMinos7+&GQa6hKA80r1p6F5@(N|fz25{Jv+r?)m9Yy1 zSWn(q_?h)|PW9|uyTv(i*PwKz4%MNCE1s()p1XGTPGyAg)u8iL*(Y!b{KE>`7b2CS zr*ovtVHHhOSww4>_Fld$K?gmQ#HI;{O}syKw_HMfaQDT@&I?I*b|A7e7Gm6@tRUD~ zcsLRgo>NDnSHD4C`@V7z!12g3?!YJmA64&?O{*&r0z)umI3sohAuzG=xqDJ7v5t>} zR{7GUERq}2bo0h@mW8g^6E@7-JCwi~z&fvAT6GiL(o`Hg=PYy4>U1pMmUi=-hIC4L zoUCHQ48+yqi_sSQC9I-}VlirQnS^wF67#9oR?)>$lFAB}fc$=G(5UQHva6yN@ngbc znU@Z~wEpo7+bD|O125LU!x^B?7HNa0eV z2C=&N%TA3gwv**q+uLzul9HMI#5O8uU5FQ=iHsg*(Oo1{SI~m1NiTmX&=9JeZw>vi zeNwPmL0ElC^Llvjp(9V4f-IUth!Dvfd*Kom{dp0efj~GHD32^{#tJy9tZuGSFlsX& zR?Wh*u&~hNkbKeRt(R(Q?XC}rF=E%6K|L(Nxutd;v6&B*$m)k*%hES)Nugd^ij@40 z#qa8flQlQmfA}DOc;|UL4o%+qCIxe;XULkN^0FNRQ!c~u+(3_^uqL?YBFoh^cKeti zy#Y!akREsGau|^1#JY;Wx*8Gk3zdP)O0y(SLV7sg#W{^lWXkKh%Wp|#wE2i&v=3v_ z^?Vv$H}Id(2@@fi;|ep5_Z%*~pOjvxR7ZyA+`wYjJPe)~GONI%kmPz8Lu3S(;XQ2K zk-&=py!zzcP-jU*p=EyuBf%Y&1WBj$8j0+8lgwV{c5{W=6Cggxqpl~A7T~$C z_(sk}GK~Q`vO-qWIAuV{*o3ft)yl$k^q47nY$fk1Cq&z(vToA^NdC<3jtsO{5ZB%h z0zx>kY{+#WNR-I-U;Y^Hn$P&mKV)iY4caYl9}jk#M)g^EIUnfkK%B1ZN*0r7Qp|X;QOSj822~3xHh!f z7`H2TZ+YsLrm#WBCv%%zZA5)#h!8z*e2R*)o4huS?uC9T6zGnHky&ju6b{_D?|&!= zL=%Td!+Ea5)#2sT0&z>jh>ww(+B}G&36cCyLh_Y|BegmMcCz#k*7?Fa!VoO4$6(m- z+EnmKZGKOzu_WzwH|lJ5Lk;VypdloDcuf*!2uZKzaVXH)Wy(#Fc07NC*n9A|{@?1} z%Qf0qwM=E*UPI1->i})b1%N8NoH(`eB6KT?24bSY!Csl&@VWRE=RcQfJ|rEC%&gIs z@ZciyL_ZRaKs@pN+ZOoB0~LLav$JA?-?vxUQrImoo+3*ANg<{!O66&(?B$IT`Cpky zvy?L<4F1s}zm6R!UzbuPrcChDeEbk%hCCeek6S;TpCdm|WyNQk;8!@)=Q&O)^&8>D z`0pmHf)yw-?Nx|r?{fENZGH+0>`8V*)ZzaX*mzZD>GIj?I^rhyfrVRDM?e3KXub8H zR#hoejpkJ|NW*AY5HuuuVc`U1nw{J$ZmT{f z9_9^><*MY$LDS6`2p=)6lARg-fEe+3%laoB`(pK*UnQ%Hs z+hAzNx02oH`Q7P#a8rOlJ^U--pF^1eky}53YR`F3a?mMTHPLFQ zht*QK=OZ2y0*^nKQaLDcZl}4ouFh0lS2MwHI5FK$XO9l~((zMq%Hew=vTYLg`{MZV zZ{j__GYeG2=i4>*giXH3NPe?ZB=y)dEPgRAUo)QgDgsZo$vlkD+}3us=IAVdS%_COS_?P<37PkRA=GU@8*{YhccCtFL()c0Oz?)VHY2P#eB76Kr3(mzk6gR z`$)?(R^#hbVL2fu`+d$e#+}ttVWXsTo7qtX8+2cdS(SFfkKkAoB=Na;KMR5uyyhtX zhYe1W;U;MnX+|JuJ_p)Xjvk(9pH&&lZDV+?t)b@%R72(}(T-V1JZO)}w>wu6BO|O! zI)quAMDKF`yQ^oMp{G_4JIbVI!tU0Wc34{?M%%d_Z4lv|I-KDHRy)5S0fE_k6eEK@ zRr8|^&j!X1-!VS({PTyMj{n#%_X3%(D_MdpSO@7p>o`hvc2?fq$>hc@ReL?21!?DrZ*dKxax-ucYScH7scZ~kLux4P<<7ul6F_r+8#D1G10%Er6p#raSE zbw5~{#&oxtwwN(Nt}OXT9>ZmYmzW1Ch60?*EXg<6K0}(VOr*&|Fud% ze6HW1;>JZ;Jv^Fvp7{n*$Mx?fotKaM!>LNY!&CzO>%n7M)QJUi_zf@K|6Y*qhTO?k zRO>ZOeJD$PaBQ&~`GRG$)DUym{)u1&6FXXQRxjSUb@|bLfyLQL+a;_^f;#6@6o^Wv zI}f-MLL?D$|M4>@+WtL1wD13ICF1`%t(&~pz~hYA!LAwzA^sPu`& z0BREcot?lw=xjzRWSjS<#zaKS1BqsKc9s?gkHnN!6nc@`IdOb`&v&ttjPgo)y>iV6r4n0Y}B%y#po+>=vUR`e>wKpxPD3 zDTT@WQZPw2!3C)F@>GbDWQA<#>OSy(YPZx11Z0}e-whgldt46Blpv7oMNRG_QlC$5OZ0hdjprbSW@u4gHL*Ti##qG%EFNLJBxp`jidIa5( zBooYx`FQ;&s%}5ezOc!)fw{Ta6!J|@)&xrL+(Uv(gq!(f zd^O=TFHWJS&RfwQ0OYL#Z5}L&3X8FrTAqH`1s(@;BO@c%<-YS7m|{Ajin6Zqs^x5R z{(MIiD+kA9(JS2fYt_a&lV#4%{r`$BW1H0BIDy9tDIj7IIGWR^I448e-ZsFaow<*U z0&Zjs>tZ~gt89vV-N%-J@o_D>W{WY0I|eYe_Bxb$vxRb4uL1QIzsp{9g%4tjALd&y z$XNu*4opeIugo=#YEiIrIo}C6IBD~K|4c&eK_5-z_m;7-j$gmjFpDk53P^bz6z`vR zQzm(U4GE*3RA`*vzFkOjsWrA1+1q%4=HTLbLusmfBhHX z92OfdZJu?|5K^|H#496<6*D(yfQ2!NrTIB!S<8L4nGwd*Fo@e2-b@3gNqj;Ake)${ z14Hvd-G&#NU&4SaOZp@^7$?=Fp96Gb3EbtIKT|BWXUKq3o#eqi1N8sV>#qM(H6)qw z!pZ4R1pP1!wQPZqjO3xRXLJ9j+#w+$f!V_3myjgj%DK6H2g?1~vDq#RiPIlVjBB~> zEh!Z0kWy1qQ#1mT0!~nBzk0B@XD7Tl+TC5DS=qh6I=sEL^@N=r21GY*)Gcp%{sF>i zb~d`&7n_hp-c;uiOiWQTO^SW1z=&}}qp**A?&!|~0nKge89nG{=;?ETMk5vV*lN6r zebwVZX@lwmSL966)8AIFUY#osKw`$QI}S9QN|XK)pu~&%KZWTA0n>Mo$hGTwTGTu5 z2GzW69lmI!r`HE!kA<$d@W<=b%o?wz-^+g&kaFzuNuw;#F*tr{SU( z30+-l!3SV^o8@GUZEIV)v=j}dPyY0caZe&DM(#UjH6|tn@aUZ9+XunWbZhKlG^H?J zR9de4T=&Em3MAwE{WFC!F%de*CtrYZ1eb;h{^6#;QG9ikmT!RTbhy0xDuONoXf%`$ zbWpoJ5kQtR@hHmIs@5AWAf;E%QA_s~7805P9vg@GFS`Y4LHx0vWt7nB_~XGe@u-!- z-0G^Qj~+b&WuE!wVuGkru!&*&+-#ln3mHr`;@`i18Ig*YvZnp?_a zx2qKx3{>7~z;XzE)WK?H+8*u)V?IgD;+Nk-VK9tE!4^f;2JDwinYf2Y%dv_M*!$9Y zv(x=y@((KH%z6WDVOdjil<^6*bq6fg*4rQ`GY8fpP#uM6fEEcv$IVO`PpKq3;B*4h zg$?w2#=WWd_zM&iJwWfQFzh;J;BSSkMNPj~ff?#k9v%<~0Tmheej`9n0y3@L23|)L z6VO`x7m`SMDpr3LC+r=cY8y3gIiafY_R?WSR+7QuqThhtsX!X+YJIk!DlN%?EWOaJYDQ zcqGsu_{>!=bpd9>aGpA+=h+PK>VcbP{Q7madcDx)B&@q`Ky-a#GiQwCYyusHbld?_ z!y+SQW^Qh2ZtmBYkSQ+=_j;5=-$d;Hat_*l7_?Of}2TbQST*4Vq| zp2EpIb%8HRRI#N4!cOQ2n2S05LbYv^yM4-7OEa0ys- z$tTYi=NYv^=A5SOO0d`ULww#ji{l8fftKeZdHt|kytY<6M1pf*VAYV|_GhaX@B#0e zmjW`5UUU&T9w=@Iv%SQwCI#5lwYqz&hrLCwgxTkTDmq}g2|P+-jy+29^ep+Z|Vj z&e_PIB((OgS4p|a0-_9$SNxun!x^F!NI5cz-D<8?J)HO8BM@nQiYmly< zY7iIq_V$31CE!VBYGRTyF}2y~r=M|;fs%5zGsX+JE{~|GU7hgEKpGemqYf+>AP!x< zd91Y=Eof+%iA(*dytr7W)DQ@P1R(GOznUo4=K(=wrB&h5(h{)NA5muk_X`NVtDuSi z?jwL6Q%g&oT8A$9a#>5>8z*0*JeuY8JGL)2FJJxy8Ve<5T6}ywNMshlcR<-_xBL#{ z;s;*m9VHD9^x6A9!Mor(!m&I1!}=KnA3UUqd8<4jg$oJmk_dRPunA^-hs-*=T8;O(I_|KMx`o zXb08;CNty(kQif9+`-+CH!&?AJe-ny!peI6x+@``9V-RJ_F!)7aJ|er5@%42|elXGs>QGY^W=>A@e3VaLWh_YV{+y7*;#J4Qn5>VMuM8Ka zspJwcC4y!i&ABWldtwLq>I~S^l$4Z!I#8!8BO@b`Oq=I4VGq=m)w*xk{KosJ!zoGZ zs7lL;YPTavkw$tTz1P^Afj$7(q;o5S^!!H#YJl;yv@QXS`H_8c0?3(G21Y0C?jSsYFMo}UfSF;g2;!4~^=|a0tZwpOOsGy~>G zeC*Lg`b;=Q9{8Exy1Moky2gOOVING(M@L6pK*z@CvgdrHa7cYvdF1ST zUG*UsSrsS>B^uIzu`2NNPrX8R>+#2*@7%!qtE!#?S)A&@13f?ukS46{82VC##~?B0 zDCKO{6E7~S>-|hVgY^EZ=#}D|t&6U%Ct^V>l^|yWE!a+53#cIZJ+pm|u%E0c=L z0#&gEGTiAvCk4r4gtqPl0Ya016Bzq#ArL44Yj_7}vta(f)G`~&vjoMb(-z|T^<6Go zd{Y&WO#(apGUz8*+1W{%XLdnnY-+WYTUakogSWiA+@IMcDJ9ik&sJ{SoAT4sVy0QDCi+#W^GAed?Io-vH#*`|l?~vk0*}VZwaf{?>nP-Eijg2HwWx&&oO-x>t zo6f^yyeLjBjEn1lyqs2{@zr?M3n5>SLS!puNtI3(%~X%y z9lbBiJ?nYq{H?~`(}W6WbCY#PR?FSnP>O+U>E~E;I$RkjPOtmYO=9|M0d_v`$pfL( zxs>x@WOhky4q|&DxJIyCHHa2YPj}ySYC1SFnOa$KI&Ce+22cI|(E@Zdev>{Yibe?N zAnG_iB+tw4vfr7D`H%MX`}b4;+1zphj~{mfp9y%j{y{-;Pp$nAp7WL(b{*~Ye*@A{ zab+cZw)UCgN5(QRTH&_{Quc(1N@WzWRhWR#3X&X9Q(JMzhH_7P$> zmiJ7!Pf6gqPX#K{evqtCG(r#)5Bwvx+E;1;cG+-Nqn59NO@6j~4v-AIKh^QQfp85g z2*IVRwH5M46X+kxSLCvZESY-mIdJa zlmW4wE{6cq;P()mck#_U#8l`a;DL_7oPm5z4L4e9B+zxsabx_Mi{V7kt6k7>via0` zpfcfC6Xd`do10yLX$C^f@Y>Mfcv;{;3Y`7v2X-)9DNr(jdQ-i%BBQv`wxbZ zadCjWbm=47!^6Wj8_+Lmk0Y|Pm$!Z=0fm*5hi9xUtYLk46Bjuj)+Cw?uH8pb<%$0G z<;4`JsRUU&;Ck)hn-IYi!LdN?0Lrql6E{a%dH%C1E0Ao$9+WrOLFy`0&c%m_T~<;O z&t`HePVSyp-EJ-Z^PI5@U4_{exlvGO8P24NcHlpbSNz932EjI{d{EB0+2B5j! zB4p7j1;QU0KPcM5X>omUKqcRMjm5^jVQZU~dXOtPIGCL0pca&N#)hCjfZC-Rq<0_4 zcx|@t-4|cwFLn<*#@=ucQ}60--8;6oXDf?~H?NMaf)U$qGn-IUOVjTkA0=tU7EG;m zbTS~4io=f}1oN*r?=4+hzv2aV#$`QI2K;{T3G-h?61GwnBPB6Pn!gJhDvUXKqa2#y zmokoZ8~|74F{z9Kb-T3GrJjGs1Reu|XcC9jBo%5Gh{bRwpv*@A;7s6g#6g>VqweB! z-1rWf7|#=n?8-`22o|9AHo@i|E1VKn@VAB(TUbw&HsNgqieAWoG@2E5z`3MT+N$JqLiF~yt!%Te#9ZU@-AAN;

    8wF2?V!R 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 KNT!Kjx%Y2R5rcsM literal 0 HcmV?d00001 From 298730a3382c18dc49be958cb4f54e64bdb0bfb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 15:00:08 +0200 Subject: [PATCH 258/980] Fix image URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/internals/model.md | 2 +- docs/content/otel/names.md | 2 +- docs/content/otel/otlp.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/internals/model.md b/docs/content/internals/model.md index d2dd5148a..1f222c3e4 100644 --- a/docs/content/internals/model.md +++ b/docs/content/internals/model.md @@ -5,7 +5,7 @@ weight: 1 The illustration below shows the internal architecture of the Prometheus Java client library. -![Internal architecture of the Prometheus Java client library](/images/model.png) +![Internal architecture of the Prometheus Java client library](/client_java/images/model.png) prometheus-metrics-core ----------------------- diff --git a/docs/content/otel/names.md b/docs/content/otel/names.md index 2cd892c3c..3d25dd3d4 100644 --- a/docs/content/otel/names.md +++ b/docs/content/otel/names.md @@ -7,7 +7,7 @@ OpenTelemetry naming conventions are different from Prometheus naming convention The goal is, if you set up a pipeline as illustrated below, you will see the same metric names in the Prometheus server as if you had exposed Prometheus metrics directly. -![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/images/otel-pipeline.png) +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) The main steps when converting OpenTelemetry metric names to Prometheus metric names are: diff --git a/docs/content/otel/otlp.md b/docs/content/otel/otlp.md index d81ed822e..ea39f178f 100644 --- a/docs/content/otel/otlp.md +++ b/docs/content/otel/otlp.md @@ -5,7 +5,7 @@ weight: 1 The Prometheus Java client library allows you to push metrics to an OpenTelemetry endpoint using the OTLP protocol. -![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/images/otel-pipeline.png) +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) To implement this, you need to include `prometheus-metrics-exporter` as a dependency From 8240ff93d6b6034b85163883468298ec8b0a0a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 27 Sep 2023 17:36:31 +0200 Subject: [PATCH 259/980] Update docs start page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/_index.md | 69 ++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/docs/content/_index.md b/docs/content/_index.md index 2fda09ae1..7ccbab1f3 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,43 +2,32 @@ title: "client_java" --- -This is the documentation for the upcoming [Prometheus client_java 1.0.0](https://github.com/prometheus/client_java) release. - -These docs are currently in progress. Source code is on the [1.0.x](https://github.com/prometheus/client_java/tree/1.0.x) feature branch. - -Target for the release is end of September 2023. - - +This is the documentation for the [Prometheus Java client library](https://github.com/prometheus/client_java) verion 1.0.0 and higher. + +The main new features of the 1.0.0 release are: + +* **Prometheus native histograms:** Support for the new Prometheus histogram type. +* **OpenTelemetry Exporter:** Push metrics in OTLP format to an OpenTelemetry endpoint. +* **Runtime configuration:** Configure metrics, exporters, and more at runtime using a properties file or system properties. + +**Documentation and Examples** + +In addition to this documentation page we created an [examples/](https://github.com/prometheus/client_java/tree/main/examples) directory with end-to-end scenarios (Docker compose) illustrating new features. + +**Performance Benchmarks** + +Initial performance benchmarks are looking great: All core metric types (including native histograms) allow concurrent updates, so if you instrument a performance critical Web service that utilizes all processor cores in parallel the metrics library will not introduce additional synchronization. See Javadoc comments in [benchmarks/](https://github.com/prometheus/client_java/tree/main/benchmarks) for benchmark results. + +**More Info** + +The Grafana Labs Blog has a post [Introducing the Prometheus Java Client 1.0.0](https://grafana.com/blog/2023/09/27/introducing-the-prometheus-java-client-1.0.0/) with a good overview of the release. + +There will also be a presentation at the [PromCon](https://promcon.io) conference on 29 Sep 2023. Tune in to the live stream on [https://promcon.io](https://promcon.io) or watch the recording on YouTube. + +**For users of the 0.16.0 version and older** + +Updating to the 1.0.0 version is a breaking change. However, there's a `prometheus-metrics-simpleclient-bridge` module available that allows you to use your existing simpleclient 0.16.0 metrics with the new 1.0.0 `PrometheusRegistry`. So you don't need to upgrade your instrumentation code, you can keep using your existing metrics. See the [compatibility > simpleclient](https://prometheus.github.io/client_java/migration/simpleclient/) in the menu on the left. + +The pre 1.0.0 code is now maintained on the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) feature branch. + +Not all `simpleclient` modules from 0.16.0 are included in the initial 1.0.0 release. Over the next couple of weeks we will work on porting the remaining modules, starting with `pushgateway` and the Servlet filter. From 2f1fe6599d9cf57e6750b4920bf392fa145c5468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 30 Sep 2023 19:06:39 +0200 Subject: [PATCH 260/980] Minor update to performance.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/getting-started/performance.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md index de68e3d11..ec4423473 100644 --- a/docs/content/getting-started/performance.md +++ b/docs/content/getting-started/performance.md @@ -51,7 +51,19 @@ In performance critical applications we recommend to use either the classic repr You can either configure this in code for each histogram by calling [classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) or [nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()), or you use the corresponding [config options](http://localhost:1313/config/config/). -One way to do this via global config for all histograms is to add a file `prometheus.properties` to your classpath with the following line: +One way to do this is with system properties in the command line when you start your application + +```sh +java -Dio.prometheus.metrics.histogramClassicOnly=true my-app.jar +``` + +or + +```sh +java -Dio.prometheus.metrics.histogramNativeOnly=true my-app.jar +``` + +If you don't want to add a command line parameter every time you start your application, you can add a `prometheus.properties` file to your classpath (put it in the `src/main/resources/` directory so that it gets packed into your JAR file). The `prometheus.properties` file should have the following line: ```properties io.prometheus.metrics.histogramClassicOnly=true @@ -63,5 +75,4 @@ or io.prometheus.metrics.histogramNativeOnly=true ``` -Alternatively, you pass the parameter `-Dio.prometheus.metrics.histogramNativeOnly=true` on application startup, or define an external configuration file at runtime as described in the [config section](../../config/config). -Future releases will add support for configuration via environment variable`IO_PROMETHEUS_METRICS_HISTOGRAM_NATIVE_ONLY=true`. +Future releases will add more configuration options, like support for configuration via environment variable`IO_PROMETHEUS_METRICS_HISTOGRAM_NATIVE_ONLY=true`. From 1bce0ebc6093717be083d6883a6b12a70aafee1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sat, 30 Sep 2023 19:56:24 +0200 Subject: [PATCH 261/980] Add docs on JVM metrics --- docs/content/config/_index.md | 2 +- docs/content/instrumentation/_index.md | 4 + docs/content/instrumentation/jvm.md | 263 +++++++++++++++++++++++++ docs/content/internals/_index.md | 2 +- docs/content/migration/_index.md | 2 +- docs/content/otel/_index.md | 2 +- 6 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 docs/content/instrumentation/_index.md create mode 100644 docs/content/instrumentation/jvm.md diff --git a/docs/content/config/_index.md b/docs/content/config/_index.md index 15545d2a8..dc32223b0 100644 --- a/docs/content/config/_index.md +++ b/docs/content/config/_index.md @@ -1,4 +1,4 @@ --- title: Config -weight: 4 +weight: 5 --- diff --git a/docs/content/instrumentation/_index.md b/docs/content/instrumentation/_index.md new file mode 100644 index 000000000..3e255f9fe --- /dev/null +++ b/docs/content/instrumentation/_index.md @@ -0,0 +1,4 @@ +--- +title: Instrumentation +weight: 3 +--- diff --git a/docs/content/instrumentation/jvm.md b/docs/content/instrumentation/jvm.md new file mode 100644 index 000000000..4b6f90cc7 --- /dev/null +++ b/docs/content/instrumentation/jvm.md @@ -0,0 +1,263 @@ +--- +title: JVM +weight: 1 +--- + +The JVM instrumentation module provides a variety of out-of-the-box JVM and process metrics. To use it, add the following dependency: + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm:1.0.0' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-instrumentation-jvm + 1.0.0 + +``` +{{< /tab >}} +{{< /tabs >}} + +Now, you can register the JVM metrics as follows: + +```java +JvmMetrics.builder().register(); +``` + +The line above will initialize all JVM metrics and register them with the default registry. If you want to register the metrics with a custom `PrometheusRegistry`, you can pass the registry as parameter to the `register()` call. + +The sections below describe the individual classes providing JVM metrics. If you don't want to register all JVM metrics, you can register each of these classes individually rather than using `JvmMetrics`. + +JVM Buffer Pool Metrics +----------------------- + +JVM buffer pool metrics are provided by the [JvmBufferPoolMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.html) class. The data is coming from the [BufferPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/BufferPoolMXBean.html). Example metrics: + +``` +# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool. +# TYPE jvm_buffer_pool_capacity_bytes gauge +jvm_buffer_pool_capacity_bytes{pool="direct"} 8192.0 +jvm_buffer_pool_capacity_bytes{pool="mapped"} 0.0 +# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool. +# TYPE jvm_buffer_pool_used_buffers gauge +jvm_buffer_pool_used_buffers{pool="direct"} 1.0 +jvm_buffer_pool_used_buffers{pool="mapped"} 0.0 +# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool. +# TYPE jvm_buffer_pool_used_bytes gauge +jvm_buffer_pool_used_bytes{pool="direct"} 8192.0 +jvm_buffer_pool_used_bytes{pool="mapped"} 0.0 +``` + +JVM Class Loading Metrics +------------------------- + +JVM class loading metrics are provided by the [JvmClassLoadingMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.html) class. The data is coming from the [ClassLoadingMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ClassLoadingMXBean.html). Example metrics: + +``` +# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM +# TYPE jvm_classes_currently_loaded gauge +jvm_classes_currently_loaded 1109.0 +# HELP jvm_classes_loaded_total The total number of classes that have been loaded since the JVM has started execution +# TYPE jvm_classes_loaded_total counter +jvm_classes_loaded_total 1109.0 +# HELP jvm_classes_unloaded_total The total number of classes that have been unloaded since the JVM has started execution +# TYPE jvm_classes_unloaded_total counter +jvm_classes_unloaded_total 0.0 +``` + +JVM Compilation Metrics +----------------------- + +JVM compilation metrics are provided by the [JvmCompilationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.html) class. The data is coming from the [CompilationMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/CompilationMXBean.html). Example metrics: + +``` +# HELP jvm_compilation_time_seconds_total The total time in seconds taken for HotSpot class compilation +# TYPE jvm_compilation_time_seconds_total counter +jvm_compilation_time_seconds_total 0.152 +``` + +JVM Garbage Collector Metrics +----------------------------- + +JVM garbage collector metrics are provided by the [JvmGarbageCollectorMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.html) class. The data is coming from the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). Example metrics: + +``` +# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds. +# TYPE jvm_gc_collection_seconds summary +jvm_gc_collection_seconds_count{gc="PS MarkSweep"} 0 +jvm_gc_collection_seconds_sum{gc="PS MarkSweep"} 0.0 +jvm_gc_collection_seconds_count{gc="PS Scavenge"} 0 +jvm_gc_collection_seconds_sum{gc="PS Scavenge"} 0.0 +``` + +JVM Memory Metrics +------------------ + +JVM memory metrics are provided by the [JvmMemoryMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.html) class. The data is coming from the [MemoryMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryMXBean.html) and the [MemoryPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html). Example metrics: + +``` +# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area. +# TYPE jvm_memory_committed_bytes gauge +jvm_memory_committed_bytes{area="heap"} 4.98597888E8 +jvm_memory_committed_bytes{area="nonheap"} 1.1993088E7 +# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area. +# TYPE jvm_memory_init_bytes gauge +jvm_memory_init_bytes{area="heap"} 5.20093696E8 +jvm_memory_init_bytes{area="nonheap"} 2555904.0 +# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area. +# TYPE jvm_memory_max_bytes gauge +jvm_memory_max_bytes{area="heap"} 7.38983936E9 +jvm_memory_max_bytes{area="nonheap"} -1.0 +# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue. +# TYPE jvm_memory_objects_pending_finalization gauge +jvm_memory_objects_pending_finalization 0.0 +# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_collection_committed_bytes gauge +jvm_memory_pool_collection_committed_bytes{pool="PS Eden Space"} 1.30023424E8 +jvm_memory_pool_collection_committed_bytes{pool="PS Old Gen"} 3.47078656E8 +jvm_memory_pool_collection_committed_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_collection_init_bytes gauge +jvm_memory_pool_collection_init_bytes{pool="PS Eden Space"} 1.30023424E8 +jvm_memory_pool_collection_init_bytes{pool="PS Old Gen"} 3.47078656E8 +jvm_memory_pool_collection_init_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool. +# TYPE jvm_memory_pool_collection_max_bytes gauge +jvm_memory_pool_collection_max_bytes{pool="PS Eden Space"} 2.727870464E9 +jvm_memory_pool_collection_max_bytes{pool="PS Old Gen"} 5.542248448E9 +jvm_memory_pool_collection_max_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool. +# TYPE jvm_memory_pool_collection_used_bytes gauge +jvm_memory_pool_collection_used_bytes{pool="PS Eden Space"} 0.0 +jvm_memory_pool_collection_used_bytes{pool="PS Old Gen"} 1249696.0 +jvm_memory_pool_collection_used_bytes{pool="PS Survivor Space"} 0.0 +# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_committed_bytes gauge +jvm_memory_pool_committed_bytes{pool="Code Cache"} 4128768.0 +jvm_memory_pool_committed_bytes{pool="Compressed Class Space"} 917504.0 +jvm_memory_pool_committed_bytes{pool="Metaspace"} 6946816.0 +jvm_memory_pool_committed_bytes{pool="PS Eden Space"} 1.30023424E8 +jvm_memory_pool_committed_bytes{pool="PS Old Gen"} 3.47078656E8 +jvm_memory_pool_committed_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_init_bytes gauge +jvm_memory_pool_init_bytes{pool="Code Cache"} 2555904.0 +jvm_memory_pool_init_bytes{pool="Compressed Class Space"} 0.0 +jvm_memory_pool_init_bytes{pool="Metaspace"} 0.0 +jvm_memory_pool_init_bytes{pool="PS Eden Space"} 1.30023424E8 +jvm_memory_pool_init_bytes{pool="PS Old Gen"} 3.47078656E8 +jvm_memory_pool_init_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_max_bytes gauge +jvm_memory_pool_max_bytes{pool="Code Cache"} 2.5165824E8 +jvm_memory_pool_max_bytes{pool="Compressed Class Space"} 1.073741824E9 +jvm_memory_pool_max_bytes{pool="Metaspace"} -1.0 +jvm_memory_pool_max_bytes{pool="PS Eden Space"} 2.727870464E9 +jvm_memory_pool_max_bytes{pool="PS Old Gen"} 5.542248448E9 +jvm_memory_pool_max_bytes{pool="PS Survivor Space"} 2.1495808E7 +# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool. +# TYPE jvm_memory_pool_used_bytes gauge +jvm_memory_pool_used_bytes{pool="Code Cache"} 4065472.0 +jvm_memory_pool_used_bytes{pool="Compressed Class Space"} 766680.0 +jvm_memory_pool_used_bytes{pool="Metaspace"} 6659432.0 +jvm_memory_pool_used_bytes{pool="PS Eden Space"} 7801536.0 +jvm_memory_pool_used_bytes{pool="PS Old Gen"} 1249696.0 +jvm_memory_pool_used_bytes{pool="PS Survivor Space"} 0.0 +# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area. +# TYPE jvm_memory_used_bytes gauge +jvm_memory_used_bytes{area="heap"} 9051232.0 +jvm_memory_used_bytes{area="nonheap"} 1.1490688E7 +``` + +JVM Memory Pool Allocation Metrics +---------------------------------- + +JVM memory pool allocation metrics are provided by the [JvmMemoryPoolAllocationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.html) class. The data is obtained by adding a [NotificationListener](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/javax/management/NotificationListener.html) to the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). Example metrics: + +``` +# HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously. +# TYPE jvm_memory_pool_allocated_bytes_total counter +jvm_memory_pool_allocated_bytes_total{pool="Code Cache"} 4336448.0 +jvm_memory_pool_allocated_bytes_total{pool="Compressed Class Space"} 875016.0 +jvm_memory_pool_allocated_bytes_total{pool="Metaspace"} 7480456.0 +jvm_memory_pool_allocated_bytes_total{pool="PS Eden Space"} 1.79232824E8 +jvm_memory_pool_allocated_bytes_total{pool="PS Old Gen"} 1428888.0 +jvm_memory_pool_allocated_bytes_total{pool="PS Survivor Space"} 4115280.0 +``` + +JVM Runtime Info Metric +----------------------- + + +The JVM runtime info metric is provided by the [JvmRuntimeInfoMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.html) class. The data is obtained via system properties and will not change throughout the lifetime of the application. Example metric: + +``` +# TYPE jvm_runtime info +# HELP jvm_runtime JVM runtime info +jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1 +``` + +JVM Thread Metrics +------------------ + +JVM thread metrics are provided by the [JvmThreadsMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.html) class. The data is coming from the [ThreadMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ThreadMXBean.html). Example metrics: + +``` +# HELP jvm_threads_current Current thread count of a JVM +# TYPE jvm_threads_current gauge +jvm_threads_current 10.0 +# HELP jvm_threads_daemon Daemon thread count of a JVM +# TYPE jvm_threads_daemon gauge +jvm_threads_daemon 8.0 +# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers +# TYPE jvm_threads_deadlocked gauge +jvm_threads_deadlocked 0.0 +# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors +# TYPE jvm_threads_deadlocked_monitor gauge +jvm_threads_deadlocked_monitor 0.0 +# HELP jvm_threads_peak Peak thread count of a JVM +# TYPE jvm_threads_peak gauge +jvm_threads_peak 10.0 +# HELP jvm_threads_started_total Started thread count of a JVM +# TYPE jvm_threads_started_total counter +jvm_threads_started_total 10.0 +# HELP jvm_threads_state Current count of threads by state +# TYPE jvm_threads_state gauge +jvm_threads_state{state="BLOCKED"} 0.0 +jvm_threads_state{state="NEW"} 0.0 +jvm_threads_state{state="RUNNABLE"} 5.0 +jvm_threads_state{state="TERMINATED"} 0.0 +jvm_threads_state{state="TIMED_WAITING"} 2.0 +jvm_threads_state{state="UNKNOWN"} 0.0 +jvm_threads_state{state="WAITING"} 3.0 +``` + +Process Metrics +--------------- + +Process metrics are provided by the [ProcessMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.html) class. The data is coming from the [OperatingSystemMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html), the [RuntimeMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/RuntimeMXBean.html), and from the `/proc/self/status` file on Linux. The metrics with prefix `process_` are not specific to Java, but should be provided by every Prometheus client library, see [Process Metrics](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) in the Prometheus [writing client libraries](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) documentation. Example metrics: + +``` +# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. +# TYPE process_cpu_seconds_total counter +process_cpu_seconds_total 1.63 +# HELP process_max_fds Maximum number of open file descriptors. +# TYPE process_max_fds gauge +process_max_fds 524288.0 +# HELP process_open_fds Number of open file descriptors. +# TYPE process_open_fds gauge +process_open_fds 28.0 +# HELP process_resident_memory_bytes Resident memory size in bytes. +# TYPE process_resident_memory_bytes gauge +process_resident_memory_bytes 7.8577664E7 +# HELP process_start_time_seconds Start time of the process since unix epoch in seconds. +# TYPE process_start_time_seconds gauge +process_start_time_seconds 1.693829439767E9 +# HELP process_virtual_memory_bytes Virtual memory size in bytes. +# TYPE process_virtual_memory_bytes gauge +process_virtual_memory_bytes 1.2683624448E10 +``` diff --git a/docs/content/internals/_index.md b/docs/content/internals/_index.md index f279a3539..9cce8243e 100644 --- a/docs/content/internals/_index.md +++ b/docs/content/internals/_index.md @@ -1,4 +1,4 @@ --- title: Internals -weight: 6 +weight: 7 --- diff --git a/docs/content/migration/_index.md b/docs/content/migration/_index.md index cae50cc47..7055c0287 100644 --- a/docs/content/migration/_index.md +++ b/docs/content/migration/_index.md @@ -1,4 +1,4 @@ --- title: Compatibility -weight: 5 +weight: 6 --- diff --git a/docs/content/otel/_index.md b/docs/content/otel/_index.md index 1f637f6b9..79e89d3a5 100644 --- a/docs/content/otel/_index.md +++ b/docs/content/otel/_index.md @@ -1,4 +1,4 @@ --- title: OpenTelemetry -weight: 3 +weight: 4 --- From 28338f74d893d5c68cb7f896e43491181dd8302b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 5 Oct 2023 22:20:59 +0200 Subject: [PATCH 262/980] Fix Java 21 build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/core/metrics/HistogramTest.java | 4 ++-- .../jvm/JvmThreadsMetricsTest.java | 22 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index b021bf8ce..2e0df7b01 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -530,7 +530,7 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio "sample_count: 2 " + "sample_sum: -7.0 " + "schema: 2 " + - "zero_threshold: 2.9387358770557188E-39 " + + "zero_threshold: " + Math.pow(2.0, -128.0) + " " + "zero_count: 0 " + "negative_span { offset: 7 length: 2 } " + "negative_delta: 1 " + @@ -564,7 +564,7 @@ public void testGolangTests() throws NoSuchFieldException, IllegalAccessExceptio "sample_count: 2 " + "sample_sum: 7.0 " + "schema: 2 " + - "zero_threshold: 2.9387358770557188E-39 " + + "zero_threshold: " + Math.pow(2.0, -128.0) + " " + "zero_count: 0 " + "positive_span { offset: 7 length: 2 } " + "positive_delta: 1 " + diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index e88e86811..7be7892a9 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -107,14 +107,21 @@ public void testIgnoredMetricNotScraped() { @Test public void testInvalidThreadIds() { + try { + int javaVersion = Integer.parseInt(System.getProperty("java.version")); + if (javaVersion >= 21) { + // With Java 21 and newer you can no longer have invalid thread ids. + return; + } + } catch (NumberFormatException ignored) { + } PrometheusRegistry registry = new PrometheusRegistry(); JvmThreadsMetrics.builder().register(registry); - MetricSnapshots snapshots = registry.scrape(); // Number of threads to create with invalid thread ids int numberOfInvalidThreadIds = 2; - Map expected = getCountByState(snapshots); + Map expected = getCountByState(registry.scrape()); expected.compute("UNKNOWN", (key, oldValue) -> oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); @@ -122,7 +129,7 @@ public void testInvalidThreadIds() { try { // Create and start threads with invalid thread ids (id=0, id=-1, etc.) for (int i = 0; i < numberOfInvalidThreadIds; i++) { - new TestThread(-i, new TestRunnable(countDownLatch)).start(); + new ThreadWithInvalidId(-i, new TestRunnable(countDownLatch)).start(); } Map actual = getCountByState(registry.scrape()); @@ -152,16 +159,21 @@ private Map getCountByState(MetricSnapshots snapshots) { return result; } - private static class TestThread extends Thread { + private static class ThreadWithInvalidId extends Thread { private final long id; - public TestThread(long id, Runnable runnable) { + public ThreadWithInvalidId(long id, Runnable runnable) { super(runnable); setDaemon(true); this.id = id; } + /** + * Note that only Java versions < 21 call this to get the thread id. + * With Java 21 and newer it's no longer possible to make an invalid thread id. + */ + @Override public long getId() { return this.id; } From 586c2f9e4c62553eb157c82b292377521375f554 Mon Sep 17 00:00:00 2001 From: Kibet Theo <61080898+kibettheophilus@users.noreply.github.com> Date: Thu, 5 Oct 2023 03:00:45 +0300 Subject: [PATCH 263/980] Update _index.md Signed-off-by: Kibet Theo <61080898+kibettheophilus@users.noreply.github.com> --- docs/content/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/_index.md b/docs/content/_index.md index 7ccbab1f3..9de934995 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,7 +2,7 @@ title: "client_java" --- -This is the documentation for the [Prometheus Java client library](https://github.com/prometheus/client_java) verion 1.0.0 and higher. +This is the documentation for the [Prometheus Java client library](https://github.com/prometheus/client_java) version 1.0.0 and higher. The main new features of the 1.0.0 release are: From 5817253028476ab2d17eb6a0613fe3da3bc185f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 15 Oct 2023 22:08:05 +0200 Subject: [PATCH 264/980] Remove scrape() from getPrometheusName() default implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../exporter/httpserver/HTTPServerSample.java | 13 +---- .../jetty/ExporterServletJettySample.java | 13 +---- .../tomcat/ExporterServletTomcatSample.java | 13 +---- .../metrics/model/registry/Collector.java | 16 +++++- .../model/registry/MultiCollector.java | 16 ++++-- .../model/registry/PrometheusRegistry.java | 7 ++- .../registry/PrometheusRegistryTest.java | 56 +++++++++++++------ .../bridge/SimpleclientCollector.java | 10 ---- 8 files changed, 75 insertions(+), 69 deletions(-) diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index 65cb2c27b..9187ecfcb 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -53,17 +53,8 @@ public static void main(String[] args) throws IOException, InterruptedException gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { - Collector failingCollector = new Collector() { - - @Override - public String getPrometheusName() { - return null; - } - - @Override - public MetricSnapshot collect() { - throw new RuntimeException("Simulating an error."); - } + Collector failingCollector = () -> { + throw new RuntimeException("Simulating an error."); }; PrometheusRegistry.defaultRegistry.register(failingCollector); diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java index 19bbddac2..9e1a22487 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java @@ -57,17 +57,8 @@ public static void main(String[] args) throws Exception { gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { - Collector failingCollector = new Collector() { - - @Override - public String getPrometheusName() { - return null; - } - - @Override - public MetricSnapshot collect() { - throw new RuntimeException("Simulating an error."); - } + Collector failingCollector = () -> { + throw new RuntimeException("Simulating an error."); }; PrometheusRegistry.defaultRegistry.register(failingCollector); diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java index 7e2e31e04..8d13082b7 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java @@ -61,17 +61,8 @@ public static void main(String[] args) throws LifecycleException, IOException { gauge.labelValues("outside").set(27.0); if (mode == Mode.error) { - Collector failingCollector = new Collector() { - - @Override - public String getPrometheusName() { - return null; - } - - @Override - public MetricSnapshot collect() { - throw new RuntimeException("Simulating an error."); - } + Collector failingCollector = () -> { + throw new RuntimeException("Simulating an error."); }; PrometheusRegistry.defaultRegistry.register(failingCollector); 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 f66d00b67..d180eda63 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 @@ -34,10 +34,20 @@ default MetricSnapshot collect(Predicate includedNames) { } /** - * Override this and return {@code null} if a collector does not have a constant name, - * or if you don't want this library to call {@link #collect()} during registration of this collector. + * This is called in two places: + *

      + *
    1. During registration to check if a metric with that name already exists.
    2. + *
    3. During scrape to check if this collector can be skipped because a name filter is present and the metric name is excluded.
    4. + *
    + * 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 collect().getMetadata().getPrometheusName(); + return null; } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java index 92fcf9012..1edb5cfc6 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -3,9 +3,9 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.util.Collections; import java.util.List; import java.util.function.Predicate; -import java.util.stream.Collectors; /** * Like {@link Collector}, but collecting multiple Snapshots at once. @@ -35,10 +35,18 @@ default MetricSnapshots collect(Predicate includedNames) { } /** - * Override this and return an empty list if the MultiCollector does not return a constant list of names - * (names may be added / removed between scrapes). + * This is called in two places: + *

      + *
    1. During registration to check if a metric with that name already exists.
    2. + *
    3. During scrape to check if the collector can be skipped because a name filter is present and all names are excluded.
    4. + *
    + * Returning an empty list means checks are omitted (registration metric always succeeds), + * and the collector is always scraped (if a name filter is present and all names are excluded the result is dropped). + *

    + * If your collector returns a constant list of metrics that have names that do not change at runtime + * it is a good idea to overwrite this and return the names. */ default List getPrometheusNames() { - return collect().stream().map(snapshot -> snapshot.getMetadata().getPrometheusName()).collect(Collectors.toList()); + return Collections.emptyList(); } } 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 21665499d..0fe565947 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 @@ -40,7 +40,10 @@ public void register(MultiCollector collector) { public void unregister(Collector collector) { collectors.remove(collector); - prometheusNames.remove(collector.getPrometheusName()); + String prometheusName = collector.getPrometheusName(); + if (prometheusName != null) { + prometheusNames.remove(collector.getPrometheusName()); + } } public void unregister(MultiCollector collector) { @@ -88,7 +91,7 @@ public MetricSnapshots scrape(Predicate includedNames) { } for (MultiCollector collector : multiCollectors) { List prometheusNames = collector.getPrometheusNames(); - boolean excluded = true; // the multi-collector is excluded unless at least one name matches + boolean excluded = prometheusNames.size() > 0; // the multi-collector is excluded unless at least one name matches for (String prometheusName : prometheusNames) { if (includedNames.test(prometheusName)) { excluded = false; 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 a7626713c..498d2354b 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 @@ -9,35 +9,57 @@ public class PrometheusRegistryTest { - Collector noName = new Collector() { + Collector noName = () -> GaugeSnapshot.builder() + .name("no_name_gauge") + .build(); + + Collector counterA1 = new Collector() { @Override public MetricSnapshot collect() { - return GaugeSnapshot.builder() - .name("no_name_gauge") - .build(); + return CounterSnapshot.builder().name("counter_a").build(); } @Override public String getPrometheusName() { - return null; + return "counter_a"; } }; - Collector counterA1 = () -> CounterSnapshot.builder() - .name("counter_a") - .build(); + Collector counterA2 = new Collector() { + @Override + public MetricSnapshot collect() { + return CounterSnapshot.builder().name("counter.a").build(); + } - Collector counterA2 = () -> CounterSnapshot.builder() - .name("counter.a") - .build(); + @Override + public String getPrometheusName() { + return "counter_a"; + } + }; - Collector counterB = () -> CounterSnapshot.builder() - .name("counter_b") - .build(); + Collector counterB = new Collector() { + @Override + public MetricSnapshot collect() { + return CounterSnapshot.builder().name("counter_b").build(); + } - Collector gaugeA = () -> GaugeSnapshot.builder() - .name("gauge_a") - .build(); + @Override + public String getPrometheusName() { + return "counter_b"; + } + }; + + Collector gaugeA = new Collector() { + @Override + public MetricSnapshot collect() { + return GaugeSnapshot.builder().name("gauge_a").build(); + } + + @Override + public String getPrometheusName() { + return "gauge_a"; + } + }; @Test public void registerNoName() { diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index a728ef0e1..dfb88dda9 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -61,16 +61,6 @@ public MetricSnapshots collect() { return convert(simpleclientRegistry.metricFamilySamples()); } - @Override - public MetricSnapshots collect(Predicate includedNames) { - return MultiCollector.super.collect(includedNames); - } - - @Override - public List getPrometheusNames() { - return MultiCollector.super.getPrometheusNames(); - } - private MetricSnapshots convert(Enumeration samples) { MetricSnapshots.Builder result = MetricSnapshots.builder(); while (samples.hasMoreElements()) { From 18bdc332eb66a6600bec896dcfd10a13be6ab0f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 15 Oct 2023 22:28:53 +0200 Subject: [PATCH 265/980] Remove unneccessary name filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/exporter/common/PrometheusHttpRequest.java | 7 ++++++- .../metrics/exporter/common/PrometheusScrapeHandler.java | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java index a5502003c..b855ce0dc 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java @@ -62,7 +62,12 @@ default String[] getParameterValues(String name) { } } } - return result.toArray(new String[0]); + if (result.isEmpty()) { + // Servlet API: getParameterValues() returns null if the parameter does not exist. + return null; + } else { + return result.toArray(new String[0]); + } } catch (UnsupportedEncodingException e) { // UTF-8 encoding not supported. throw new RuntimeException(e); diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index b095007e0..6fae1218e 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -114,7 +114,7 @@ private MetricSnapshots scrape(PrometheusHttpRequest request) { private Predicate makeNameFilter(String[] includedNames) { Predicate result = null; - if (includedNames != null) { + if (includedNames != null && includedNames.length > 0) { result = MetricNameFilter.builder().nameMustBeEqualTo(includedNames).build(); } if (result != null && nameFilter != null) { From 6843727564f84679e4391dcdfa263ad5c7be4425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 22 Oct 2023 10:53:48 +0200 Subject: [PATCH 266/980] Fix time unit for process_cpu_seconds_total #881 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../prometheus/metrics/instrumentation/jvm/ProcessMetrics.java | 2 +- .../metrics/instrumentation/jvm/ProcessMetricsTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java index 19c9c4bb0..bca58942a 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java @@ -94,7 +94,7 @@ private void register(PrometheusRegistry registry) { // through implemented interfaces until the method can be made accessible and invoked. Long processCpuTime = callLongGetter("getProcessCpuTime", osBean); if (processCpuTime != null) { - callback.call(Unit.millisToSeconds(processCpuTime)); + callback.call(Unit.nanosToSeconds(processCpuTime)); } } catch (Exception ignored) { } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java index e3304f4d9..92f286e01 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java @@ -11,6 +11,7 @@ import java.io.File; import java.io.IOException; import java.lang.management.RuntimeMXBean; +import java.util.concurrent.TimeUnit; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; import static org.mockito.ArgumentMatchers.any; @@ -29,7 +30,7 @@ public class ProcessMetricsTest { @Before public void setUp() throws IOException { - when(sunOsBean.getProcessCpuTime()).thenReturn(72L); + when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); when(runtimeBean.getStartTime()).thenReturn(37100L); From 03378b80f201afd80aa51107bcd2d7979c75d625 Mon Sep 17 00:00:00 2001 From: Maxim Solodovnik Date: Sun, 15 Oct 2023 10:15:03 +0700 Subject: [PATCH 267/980] Fixes issue #871: Automatic-Module-Names are added Signed-off-by: Maxim Solodovnik --- pom.xml | 14 ++++++++++---- prometheus-metrics-config/pom.xml | 4 ++++ prometheus-metrics-core/pom.xml | 4 ++++ prometheus-metrics-exporter-common/pom.xml | 4 ++++ prometheus-metrics-exporter-httpserver/pom.xml | 4 ++++ prometheus-metrics-exporter-opentelemetry/pom.xml | 1 + .../pom.xml | 4 ++++ prometheus-metrics-exposition-formats/pom.xml | 4 ++++ prometheus-metrics-instrumentation-jvm/pom.xml | 4 ++++ prometheus-metrics-model/pom.xml | 4 ++++ prometheus-metrics-simpleclient-bridge/pom.xml | 4 ++++ .../prometheus-metrics-tracer-common/pom.xml | 4 ++++ .../prometheus-metrics-tracer-initializer/pom.xml | 4 ++++ .../prometheus-metrics-tracer-otel-agent/pom.xml | 4 ++++ .../prometheus-metrics-tracer-otel/pom.xml | 4 ++++ 15 files changed, 63 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2845c00d0..114e35d4a 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,11 @@ The Prometheus Java Metrics Library + + UTF-8 + --module-name-need-to-be-overriden-- + + The Apache Software License, Version 2.0 @@ -64,10 +69,6 @@ integration-tests - - UTF-8 - - ossrh @@ -192,6 +193,11 @@ maven-bundle-plugin 2.4.0 true + + + ${automatic.module.name} + + org.apache.maven.plugins diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 4e8a2328a..6ed2c6411 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -16,6 +16,10 @@ Configuration for Prometheus metrics and exposition formats. + + io.prometheus.metrics.config + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 25007d1e9..ce4d35525 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -32,6 +32,10 @@ + + io.prometheus.metrics.core + + io.prometheus diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index ceea4b6a2..8e64daaba 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -16,6 +16,10 @@ Common functionality for implementing a Prometheus scrape endpoint. + + io.prometheus.metrics.exporter.common + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 1495ea259..069e963bf 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -32,6 +32,10 @@ + + io.prometheus.metrics.exporter.httpserver + + io.prometheus diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 424b9afa3..4367ef43f 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -19,6 +19,7 @@ 1.28.0 ${otel.version}-alpha + io.prometheus.metrics.exporter.opentelemetry diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 6e09cfdee..e562fbdee 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -16,6 +16,10 @@ Jakarta Servlet for exposing a Prometheus scrape endpoint. + + io.prometheus.metrics.exporter.servlet.jakarta + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 83267baf7..3a59b3271 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -32,6 +32,10 @@ + + io.prometheus.metrics.expositionformats + + io.prometheus diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 95c6dfe97..1b42d176d 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -16,6 +16,10 @@ Instrumentation library for JVM metrics + + io.prometheus.metrics.instrumentation.jvm + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index f5c922707..1a017636e 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -32,6 +32,10 @@ + + io.prometheus.metrics.model + + diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 5287de079..49efc4b4f 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -16,6 +16,10 @@ Bridge the old simpleclient CollectorRegistry to the new PrometheusRegistry + + io.prometheus.metrics.simpleclient.bridge + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index aadc50e21..e17e57f4a 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -31,4 +31,8 @@ fabian@fstab.de + + + io.prometheus.metrics.tracer.common + diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 7801c6712..f769c41d5 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -16,6 +16,10 @@ Initialize Prometheus integrations with distributed tracing libraries. + + io.prometheus.metrics.tracer.initializer + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 76f7ce66e..03864b703 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -16,6 +16,10 @@ Prometheus integration with the OpenTelemetry Java agent for distributed tracing. + + io.prometheus.metrics.tracer.otel_agent + + The Apache Software License, Version 2.0 diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index a7396d514..385a892db 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -32,6 +32,10 @@ + + io.prometheus.metrics.tracer.otel + + io.prometheus From ee99bb85e1cc771e6b8b451b143a2af7d521ff01 Mon Sep 17 00:00:00 2001 From: Maxim Solodovnik Date: Mon, 23 Oct 2023 08:40:11 +0700 Subject: [PATCH 268/980] Properties section is moved to proper place Signed-off-by: Maxim Solodovnik --- prometheus-metrics-core/pom.xml | 8 ++++---- prometheus-metrics-exporter-httpserver/pom.xml | 8 ++++---- prometheus-metrics-exposition-formats/pom.xml | 8 ++++---- prometheus-metrics-model/pom.xml | 8 ++++---- .../prometheus-metrics-tracer-common/pom.xml | 8 ++++---- .../prometheus-metrics-tracer-otel/pom.xml | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index ce4d35525..70cc9c1b2 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -16,6 +16,10 @@ Core Prometheus metric types + + io.prometheus.metrics.core + + The Apache Software License, Version 2.0 @@ -32,10 +36,6 @@ - - io.prometheus.metrics.core - - io.prometheus diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 069e963bf..b2e446fe1 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -16,6 +16,10 @@ HTTP Server providing a Prometheus scrape endpoint. + + io.prometheus.metrics.exporter.httpserver + + The Apache Software License, Version 2.0 @@ -32,10 +36,6 @@ - - io.prometheus.metrics.exporter.httpserver - - io.prometheus diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 3a59b3271..4c58ecc5b 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -16,6 +16,10 @@ Prometheus exposition formats. + + io.prometheus.metrics.expositionformats + + The Apache Software License, Version 2.0 @@ -32,10 +36,6 @@ - - io.prometheus.metrics.expositionformats - - io.prometheus diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 1a017636e..06d0c56d9 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -16,6 +16,10 @@ Data model for read-only immutable Prometheus metrics snapshots. + + io.prometheus.metrics.model + + The Apache Software License, Version 2.0 @@ -32,10 +36,6 @@ - - io.prometheus.metrics.model - - diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index e17e57f4a..0135ce7e3 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -16,6 +16,10 @@ Common Module for Prometheus integrations with distributed tracing libraries. + + io.prometheus.metrics.tracer.common + + The Apache Software License, Version 2.0 @@ -31,8 +35,4 @@ fabian@fstab.de - - - io.prometheus.metrics.tracer.common - diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 385a892db..4dcc2d56c 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -16,6 +16,10 @@ Prometheus integration with the OpenTelemetry distributed tracing library. + + io.prometheus.metrics.tracer.otel + + The Apache Software License, Version 2.0 @@ -32,10 +36,6 @@ - - io.prometheus.metrics.tracer.otel - - io.prometheus From cff40ddc7b992efba0bf913212985d3593a2b994 Mon Sep 17 00:00:00 2001 From: ganzuoni <49481173+ganzuoni@users.noreply.github.com> Date: Mon, 30 Oct 2023 22:41:15 +0100 Subject: [PATCH 269/980] Support multi-target pattern (#873) Add multi-target pattern support Signed-off-by: Guido Anzuoni --- docs/content/getting-started/multi-target.md | 114 ++++++++++ .../example-exporter-multi-target/README.md | 33 +++ .../example-exporter-multi-target/pom.xml | 76 +++++++ .../metrics/examples/multitarget/Main.java | 23 ++ .../multitarget/SampleMultiCollector.java | 88 ++++++++ examples/pom.xml | 1 + .../common/PrometheusHttpRequest.java | 4 +- .../common/PrometheusScrapeHandler.java | 5 +- .../httpserver/HttpExchangeAdapter.java | 3 +- .../servlet/jakarta/HttpExchangeAdapter.java | 2 +- .../metrics/model/registry/Collector.java | 23 ++ .../model/registry/MultiCollector.java | 21 +- .../model/registry/PrometheusRegistry.java | 196 ++++++++++-------- .../registry/PrometheusScrapeRequest.java | 11 + 14 files changed, 503 insertions(+), 97 deletions(-) create mode 100644 docs/content/getting-started/multi-target.md create mode 100644 examples/example-exporter-multi-target/README.md create mode 100644 examples/example-exporter-multi-target/pom.xml create mode 100644 examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java create mode 100644 examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java diff --git a/docs/content/getting-started/multi-target.md b/docs/content/getting-started/multi-target.md new file mode 100644 index 000000000..6a1c0412c --- /dev/null +++ b/docs/content/getting-started/multi-target.md @@ -0,0 +1,114 @@ +--- +title: Multi-Target Pattern +weight: 7 +--- + +{{< hint type=note >}} +This is for the upcoming release 1.1.0. +{{< /hint >}} + +To support multi-target pattern you can create a custom collector overriding the purposed internal method in ExtendedMultiCollector +see SampleExtendedMultiCollector in io.prometheus.metrics.examples.httpserver + +```java +public class SampleExtendedMultiCollector extends ExtendedMultiCollector { + + public SampleExtendedMultiCollector() { + super(); + } + + @Override + protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { + + GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); + gaugeBuilder.name("x_load").help("process load"); + + CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); + counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); + + String[] targetNames = scrapeRequest.getParameterValues("target"); + String targetName; + String[] procs = scrapeRequest.getParameterValues("proc"); + if (targetNames == null || targetNames.length == 0) { + targetName = "defaultTarget"; + procs = null; //ignore procs param + } else { + targetName = targetNames[0]; + } + Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); + io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); + Labels lbls = Labels.of("target", targetName); + + if (procs == null || procs.length == 0) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + counterDataPointBuilder.value(70); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + + } else { + for (int i = 0; i < procs.length; i++) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + counterDataPointBuilder.value(Math.random()); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + } + } + Collection snaps = new ArrayList(); + snaps.add(counterBuilder.build()); + snaps.add(gaugeBuilder.build()); + MetricSnapshots msnaps = new MetricSnapshots(snaps); + return msnaps; + } + + public List getPrometheusNames() { + List names = new ArrayList(); + names.add("x_calls_total"); + names.add("x_load"); + return names; + } + +} + +``` +`PrometheusScrapeRequest` provides methods to access http-related infos from the request originally received by the endpoint + +```java +public interface PrometheusScrapeRequest { + String getRequestURI(); + + String[] getParameterValues(String name); +} + +``` + + +Sample Prometheus scrape_config + +``` + - job_name: "multi-target" + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + params: + proc: [proc1, proc2] + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - source_labels: [__param_target] + target_label: instance + - target_label: __address__ + replacement: localhost:9401 + static_configs: + - targets: ["target1", "target2"] +``` +It's up to the specific MultiCollector implementation how to interpret the _target_ parameter. +It might be an explicit real target (i.e. via host name/ip address) or as an alias in some internal configuration. +The latter is more suitable when the MultiCollector implementation is a proxy (see https://github.com/prometheus/snmp_exporter) +In this case, invoking real target might require extra parameters (e.g. credentials) that might be complex to manage in Prometheus configuration +(not considering the case where the proxy might become an "open relay") \ No newline at end of file diff --git a/examples/example-exporter-multi-target/README.md b/examples/example-exporter-multi-target/README.md new file mode 100644 index 000000000..b21f9ce9e --- /dev/null +++ b/examples/example-exporter-multi-target/README.md @@ -0,0 +1,33 @@ +# Multi-Target pattern example + +## Build + +This example is built as part of the `client_java` project. + +``` +./mvnw package +``` + +## Run + +The build creates a JAR file with the example application in `./examples/example-exporter-multi-target/target/`. + +``` +java -jar ./examples/example-exporter-multi-target/target/example-exporter-multi-target.jar +``` + +## Manually testing the Metrics Endpoint + +Accessing [http://localhost:9400/metrics](http://localhost:9400/metrics) with a Web browser should yield an example of a counter metric. + +``` +# HELP uptime_seconds_total total number of seconds since this application was started +# TYPE uptime_seconds_total counter +uptime_seconds_total 301.0 +``` + +The exporter supports a `debug` URL parameter to quickly view other formats in your Web browser: + +* [http://localhost:9400/metrics?debug=text](http://localhost:9400/metrics?debug=text): Prometheus text format, same as without the `debug` option. +* [http://localhost:9400/metrics?debug=openmetrics](http://localhost:9400/metrics?debug=openmetrics): OpenMetrics text format. +* [http://localhost:9400/metrics?debug=prometheus-protobuf](http://localhost:9400/metrics?debug=prometheus-protobuf): Text representation of the Prometheus protobuf format. diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml new file mode 100644 index 000000000..fa9d1a94a --- /dev/null +++ b/examples/example-exporter-multi-target/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + io.prometheus + examples + 1.1.0-SNAPSHOT + + + example-exporter-multi-target + + Example - HTTPServer Exporter Multi Target + + Prometheus Metrics Example for multi-target pattern implementation + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + fstab + Guido Anzuoni + ganzuoni@gmail.com + + + + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-instrumentation-jvm + ${project.version} + + + io.prometheus + prometheus-metrics-exporter-httpserver + ${project.version} + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.prometheus.metrics.examples.multitarget.Main + + + + + + + + + diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java new file mode 100644 index 000000000..da36346b9 --- /dev/null +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java @@ -0,0 +1,23 @@ +package io.prometheus.metrics.examples.multitarget; + +import java.io.IOException; + +import io.prometheus.metrics.exporter.httpserver.HTTPServer; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +/** + * Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. + */ +public class Main { + + public static void main(String[] args) throws IOException, InterruptedException { + + SampleMultiCollector xmc = new SampleMultiCollector(); + PrometheusRegistry.defaultRegistry.register(xmc); + HTTPServer server = HTTPServer.builder() + .port(9401) + .buildAndStart(); + + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + } +} diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java new file mode 100644 index 000000000..819bb3028 --- /dev/null +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java @@ -0,0 +1,88 @@ +package io.prometheus.metrics.examples.multitarget; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import io.prometheus.metrics.model.registry.MultiCollector; +import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot.Builder; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; + +public class SampleMultiCollector implements MultiCollector { + + public SampleMultiCollector() { + super(); + } + + @Override + public MetricSnapshots collect() { + return new MetricSnapshots(); + } + + @Override + public MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { + return collectMetricSnapshots(scrapeRequest); + } + + protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { + + GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); + gaugeBuilder.name("x_load").help("process load"); + + CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); + counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); + + String[] targetNames = scrapeRequest.getParameterValues("target"); + String targetName; + String[] procs = scrapeRequest.getParameterValues("proc"); + if (targetNames == null || targetNames.length == 0) { + targetName = "defaultTarget"; + procs = null; //ignore procs param + } else { + targetName = targetNames[0]; + } + Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); + io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); + Labels lbls = Labels.of("target", targetName); + + if (procs == null || procs.length == 0) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + counterDataPointBuilder.value(70); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + + } else { + for (int i = 0; i < procs.length; i++) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + counterDataPointBuilder.value(Math.random()); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + } + } + Collection snaps = new ArrayList(); + snaps.add(counterBuilder.build()); + snaps.add(gaugeBuilder.build()); + MetricSnapshots msnaps = new MetricSnapshots(snaps); + return msnaps; + } + + public List getPrometheusNames() { + List names = new ArrayList(); + names.add("x_calls_total"); + names.add("x_load"); + return names; + } + +} diff --git a/examples/pom.xml b/examples/pom.xml index 0b293cedc..61db27a97 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -36,6 +36,7 @@ example-exemplars-tail-sampling example-exporter-servlet-tomcat example-exporter-httpserver + example-exporter-multi-target example-exporter-opentelemetry example-simpleclient-bridge example-native-histogram diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java index b855ce0dc..f7b5346a5 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java @@ -5,7 +5,9 @@ import java.util.ArrayList; import java.util.Enumeration; -public interface PrometheusHttpRequest { +import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; + +public interface PrometheusHttpRequest extends PrometheusScrapeRequest { /** * See {@code jakarta.servlet.http.HttpServletRequest.getQueryString()} diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index 6fae1218e..5155457df 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -104,11 +104,12 @@ private Predicate makeNameFilter(ExporterFilterProperties props) { } private MetricSnapshots scrape(PrometheusHttpRequest request) { + Predicate filter = makeNameFilter(request.getParameterValues("name[]")); if (filter != null) { - return registry.scrape(filter); + return registry.scrape(filter, request); } else { - return registry.scrape(); + return registry.scrape(request); } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java index 4f1b4f63a..daaeb2dbd 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java @@ -9,6 +9,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Enumeration; @@ -29,7 +30,7 @@ public HttpExchangeAdapter(HttpExchange httpExchange) { public class HttpRequest implements PrometheusHttpRequest { - @Override + @Override public String getQueryString() { return httpExchange.getRequestURI().getRawQuery(); } diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java index 656d661eb..c55eb7967 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java @@ -53,7 +53,7 @@ public Request(HttpServletRequest request) { this.request = request; } - @Override + @Override public String getQueryString() { return request.getQueryString(); } 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 d180eda63..0c69a89a9 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 @@ -19,6 +19,14 @@ public interface Collector { */ 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}. *

    @@ -32,6 +40,21 @@ default MetricSnapshot collect(Predicate includedNames) { 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: diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java index 1edb5cfc6..5434c0ec0 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -18,13 +18,31 @@ public interface MultiCollector { */ MetricSnapshots 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 MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { + return collect(); + } + + /** * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} is {@code true}. *

    * Override this if there is a more efficient way than first collecting all snapshot and then discarding the excluded ones. */ default MetricSnapshots collect(Predicate includedNames) { - MetricSnapshots allSnapshots = collect(); + return collect(includedNames, 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 MetricSnapshots collect(Predicate includedNames, PrometheusScrapeRequest scrapeRequest) { + MetricSnapshots allSnapshots = scrapeRequest == null ? collect(): collect(scrapeRequest); MetricSnapshots.Builder result = MetricSnapshots.builder(); for (MetricSnapshot snapshot : allSnapshots) { if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { @@ -34,6 +52,7 @@ default MetricSnapshots collect(Predicate includedNames) { return result.build(); } + /** * This is called in two places: *

      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 0fe565947..a8ab5a762 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 @@ -1,7 +1,6 @@ package io.prometheus.metrics.model.registry; -import io.prometheus.metrics.model.snapshots.MetricSnapshot; -import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; import java.util.List; import java.util.Set; @@ -9,104 +8,119 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Predicate; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; public class PrometheusRegistry { - public static final PrometheusRegistry defaultRegistry = new 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 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() { - MetricSnapshots.Builder result = MetricSnapshots.builder(); - for (Collector collector : collectors) { - MetricSnapshot snapshot = collector.collect(); - 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) { - for (MetricSnapshot snapshot : collector.collect()) { - 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) { + if (includedNames == null) { + return scrape(); + } + return scrape(includedNames, null); + } - public MetricSnapshots scrape(Predicate includedNames) { - if (includedNames == null) { - return scrape(); - } - MetricSnapshots.Builder result = MetricSnapshots.builder(); - for (Collector collector : collectors) { - String prometheusName = collector.getPrometheusName(); - if (prometheusName == null || includedNames.test(prometheusName)) { - MetricSnapshot snapshot = collector.collect(includedNames); - if (snapshot != null) { - result.metricSnapshot(snapshot); - } - } - } - for (MultiCollector collector : multiCollectors) { - List prometheusNames = collector.getPrometheusNames(); - boolean excluded = prometheusNames.size() > 0; // the multi-collector is excluded unless at least one name matches - for (String prometheusName : prometheusNames) { - if (includedNames.test(prometheusName)) { - excluded = false; - break; - } - } - if (!excluded) { - for (MetricSnapshot snapshot : collector.collect(includedNames)) { - if (snapshot != null) { - 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(); + 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(); + boolean excluded = true; // the multi-collector is excluded unless + // at least one name matches + for (String prometheusName : prometheusNames) { + if (includedNames.test(prometheusName)) { + excluded = false; + break; + } + } + if (!excluded) { + MetricSnapshots snaphots = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest); + for (MetricSnapshot snapshot : snaphots) { + if (snapshot != null) { + result.metricSnapshot(snapshot); + } + } + } + } + return result.build(); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java new file mode 100644 index 000000000..268a326e1 --- /dev/null +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java @@ -0,0 +1,11 @@ +package io.prometheus.metrics.model.registry; + +/** + * Infos extracted from the request received by the endpoint + * + */ +public interface PrometheusScrapeRequest { + + String[] getParameterValues(String name); + +} From 348bf3776f34e55f2a3852610c7892f8ad3f549b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Mon, 30 Oct 2023 23:24:30 +0100 Subject: [PATCH 270/980] Remove automatic module name #884 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 114e35d4a..9cf80aa67 100644 --- a/pom.xml +++ b/pom.xml @@ -193,11 +193,13 @@ maven-bundle-plugin 2.4.0 true + org.apache.maven.plugins From e9a04680a1f175bd50cf8aab74ea2a5468a73172 Mon Sep 17 00:00:00 2001 From: Greg Eales <0x006EA1E5@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:59:30 +0000 Subject: [PATCH 271/980] #887 otlp exporter exemplars (#883) Signed-off-by: Greg Eales <0x006ea1e5@gmail.com> --- .../pom.xml | 24 +++ .../opentelemetry/OpenTelemetryExporter.java | 10 +- .../otelmodel/PrometheusData.java | 51 ++++++- .../exporter/opentelemetry/ExemplarTest.java | 139 ++++++++++++++++++ 4 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 4367ef43f..175c9a5dd 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -79,6 +79,30 @@ 4.13.2 test + + org.wiremock + wiremock + 3.2.0 + test + + + org.awaitility + awaitility + 4.2.0 + test + + + io.opentelemetry + opentelemetry-proto + 0.17.1 + test + + + io.opentelemetry + opentelemetry-sdk-trace + ${otel.version} + test + diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index 9c69faf3e..31f263fd9 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -18,7 +18,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -public class OpenTelemetryExporter { +public class OpenTelemetryExporter implements AutoCloseable { + private final PeriodicMetricReader reader; private OpenTelemetryExporter(Builder builder, PrometheusProperties config, PrometheusRegistry registry) { InstrumentationScopeInfo instrumentationScopeInfo = PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); @@ -42,13 +43,18 @@ private OpenTelemetryExporter(Builder builder, PrometheusProperties config, Prom } exporter = exporterBuilder.build(); } - PeriodicMetricReader reader = PeriodicMetricReader.builder(exporter) + reader = PeriodicMetricReader.builder(exporter) .setInterval(Duration.ofSeconds(ConfigHelper.getIntervalSeconds(builder, properties))) .build(); + PrometheusMetricProducer prometheusMetricProducer = new PrometheusMetricProducer(registry, instrumentationScopeInfo, resource); reader.register(prometheusMetricProducer); } + public void close() { + reader.shutdown(); + } + private Resource initResourceAttributes(Builder builder, ExporterOpenTelemetryProperties properties, InstrumentationScopeInfo instrumentationScopeInfo) { String serviceName = ConfigHelper.getServiceName(builder, properties); String serviceNamespace = ConfigHelper.getServiceNamespace(builder, properties); diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index 353a1623c..56d10847b 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -1,19 +1,22 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.model.snapshots.DataPointSnapshot; -import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.*; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.SpanContext; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.TraceFlags; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.TraceState; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.Data; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.PointData; -import io.prometheus.metrics.model.snapshots.Exemplar; -import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; -import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; abstract class PrometheusData implements Data { @@ -44,8 +47,41 @@ protected List convertExemplar(Exemplar exemplar) { } protected List convertExemplars(Exemplars exemplars) { - // TODO: Exemplars not implemented yet. - return Collections.emptyList(); + return StreamSupport.stream(exemplars.spliterator(), false) + .map(this::toDoubleExemplarData) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + protected DoubleExemplarData toDoubleExemplarData(Exemplar exemplar) { + if (exemplar == null) { + return null; + } + + AttributesBuilder filteredAttributesBuilder = Attributes.builder(); + String traceId = null; + String spanId = null; + for (Label label : exemplar.getLabels()) { + if (label.getName().equals(Exemplar.TRACE_ID)) { + traceId = label.getValue(); + } + else if (label.getName().equals(Exemplar.SPAN_ID)) { + spanId = label.getValue(); + } else { + filteredAttributesBuilder.put(label.getName(), label.getValue()); + } + } + Attributes filteredAttributes = filteredAttributesBuilder.build(); + + SpanContext spanContext = (traceId != null && spanId != null) + ? SpanContext.create(traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()) + : SpanContext.getInvalid(); + + return ImmutableDoubleExemplarData.create( + filteredAttributes, + TimeUnit.MILLISECONDS.toNanos(exemplar.getTimestampMillis()), + spanContext, + exemplar.getValue()); } protected long getStartEpochNanos(DataPointSnapshot dataPoint) { @@ -55,4 +91,5 @@ protected long getStartEpochNanos(DataPointSnapshot dataPoint) { protected long getEpochNanos(DataPointSnapshot dataPoint, long currentTimeMillis) { return dataPoint.hasScrapeTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getScrapeTimestampMillis()) : TimeUnit.MILLISECONDS.toNanos(currentTimeMillis); } + } diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java new file mode 100644 index 000000000..0226c131c --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java @@ -0,0 +1,139 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import com.github.tomakehurst.wiremock.http.Request; +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.github.tomakehurst.wiremock.matching.MatchResult; +import com.github.tomakehurst.wiremock.matching.ValueMatcher; +import com.google.protobuf.InvalidProtocolBufferException; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Scope; +import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; +import io.opentelemetry.proto.metrics.v1.DoubleDataPoint; +import io.opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics; +import io.opentelemetry.proto.metrics.v1.Metric; +import io.opentelemetry.proto.metrics.v1.ResourceMetrics; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.awaitility.core.ConditionTimeoutException; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; + +public class ExemplarTest { + private static final String ENDPOINT_PATH = "/v1/metrics"; + private static final int TIMEOUT = 3; + private static final String INSTRUMENTATION_SCOPE_NAME = "testInstrumentationScope"; + private static final String SPAN_NAME = "test-span"; + public static final String TEST_COUNTER_NAME = "test_counter"; + private Counter testCounter; + private OpenTelemetryExporter openTelemetryExporter; + @Rule + public WireMockRule wireMockRule = new WireMockRule(4317); + + @Before + public void setUp() { + openTelemetryExporter = OpenTelemetryExporter.builder() + .endpoint("http://localhost:4317") + .protocol("http/protobuf") + .intervalSeconds(1) + .buildAndStart(); + + testCounter = Counter.builder() + .name(TEST_COUNTER_NAME) + .withExemplars() + .register(); + + wireMockRule.stubFor(post(ENDPOINT_PATH) + .withHeader("Content-Type", containing("application/x-protobuf")) + .willReturn(ok() + .withHeader("Content-Type", "application/json") + .withBody("{\"partialSuccess\":{}}"))); + } + + @After + public void tearDown() { + PrometheusRegistry.defaultRegistry.unregister(testCounter); + openTelemetryExporter.close(); + } + + @Test + public void sampledExemplarIsForwarded() { + try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + .setSampler(Sampler.alwaysOn()) + .build()) { + + Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); + Span span = test.spanBuilder(SPAN_NAME) + .startSpan(); + try (Scope scope = span.makeCurrent()) { + testCounter.inc(2); + } + } + + + await().atMost(TIMEOUT, SECONDS) + .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) + .until(() -> { + verify(postRequestedFor(urlEqualTo(ENDPOINT_PATH)) + .withHeader("Content-Type", equalTo("application/x-protobuf")) + .andMatching(getExemplarCountMatcher(1))); + return true; + }); + + } + + @Test(expected = ConditionTimeoutException.class) + public void notSampledExemplarIsNotForwarded() { + try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + .setSampler(Sampler.alwaysOff()) + .build()) { + + Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); + Span span = test.spanBuilder(SPAN_NAME) + .startSpan(); + try (Scope scope = span.makeCurrent()) { + testCounter.inc(2); + } + } + + await().atMost(TIMEOUT, SECONDS) + .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) + .until(() -> { + verify(postRequestedFor(urlEqualTo(ENDPOINT_PATH)) + .withHeader("Content-Type", equalTo("application/x-protobuf")) + .andMatching(getExemplarCountMatcher(1))); + return true; + }); + + } + + private static ValueMatcher getExemplarCountMatcher(int expectedCount) { + return request -> { + try { + ExportMetricsServiceRequest exportMetricsServiceRequest = ExportMetricsServiceRequest.parseFrom(request.getBody()); + for (ResourceMetrics resourceMetrics : exportMetricsServiceRequest.getResourceMetricsList()) { + for (InstrumentationLibraryMetrics instrumentationLibraryMetrics : resourceMetrics.getInstrumentationLibraryMetricsList()) { + for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) { + for (DoubleDataPoint doubleDataPoint : metric.getDoubleSum().getDataPointsList()) { + if (doubleDataPoint.getExemplarsCount() == expectedCount) { + return MatchResult.exactMatch(); + } + } + } + } + } + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(e); + } + return MatchResult.noMatch(); + }; + } +} From c4dc8338780594f85d2e9e75518ab24b8b00de42 Mon Sep 17 00:00:00 2001 From: Aleksandr Turchenko Date: Fri, 3 Nov 2023 01:02:43 +0400 Subject: [PATCH 272/980] Fixes issue #887: Sort histogram bounds before validation (#888) Signed-off-by: Aleksandr Turchenko --- .../metrics/simpleclient/bridge/SimpleclientCollector.java | 2 +- .../metrics/simpleclient/bridge/SimpleclientCollectorTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index dfb88dda9..a775b2f55 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -288,8 +288,8 @@ private Unit convertUnit(Collector.MetricFamilySamples samples) { private ClassicHistogramBuckets makeBuckets(Map cumulativeBuckets) { List upperBounds = new ArrayList<>(cumulativeBuckets.size()); - Collections.sort(upperBounds); upperBounds.addAll(cumulativeBuckets.keySet()); + Collections.sort(upperBounds); ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.builder(); long previousCount = 0L; for (Double upperBound : upperBounds) { diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java index a3445c9af..9d1e8f1b9 100644 --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -94,7 +94,7 @@ public void testHistogramComplete() throws IOException, InterruptedException { .name("response_size_bytes") .help("response size in Bytes") .labelNames("status") - .buckets(64, 256) + .buckets(64, 256, 512.1) .register(origRegistry); histogram.labels("200").observeWithExemplar(38, "trace_id", "1", "span_id", "2"); histogram.labels("200").observeWithExemplar(127, "trace_id", "3", "span_id", "4"); From a192c7887e7542c982d7f07e30fcd2737b4a73ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 2 Nov 2023 22:20:35 +0100 Subject: [PATCH 273/980] Restore automatic module name #884 (#889) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .github/workflows/github-pages.yaml | 2 +- pom.xml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 30569cd58..6edc0639a 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -62,7 +62,7 @@ jobs: - name: Build client_java run: ./mvnw -B clean install -DskipTests - name: Make Javadoc - run: ./mvnw -B compile javadoc:javadoc javadoc:aggregate + run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate - name: Move the Javadoc to docs/static/api/ run: mv ./target/site/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api - name: Setup Pages diff --git a/pom.xml b/pom.xml index 9cf80aa67..114e35d4a 100644 --- a/pom.xml +++ b/pom.xml @@ -193,13 +193,11 @@ maven-bundle-plugin 2.4.0 true - org.apache.maven.plugins From bc2244d635598813d0845900c4d4db94895ca224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 9 Nov 2023 17:33:05 +0100 Subject: [PATCH 274/980] Fix sliding window rotation #894 (#896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/core/metrics/SlidingWindow.java | 9 ++- .../core/metrics/SlidingWindowTest.java | 77 +++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java index b789e809c..62164a48b 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -2,6 +2,7 @@ import java.lang.reflect.Array; import java.util.concurrent.TimeUnit; +import java.util.function.LongSupplier; import java.util.function.ObjDoubleConsumer; import java.util.function.Supplier; @@ -22,6 +23,7 @@ public class SlidingWindow { private int currentBucket; private long lastRotateTimestampMillis; private final long durationBetweenRotatesMillis; + LongSupplier currentTimeMillis = System::currentTimeMillis; // to be replaced in unit tests /** * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of {@code T} @@ -56,11 +58,14 @@ public synchronized T current() { * Observe a value. */ public synchronized void observe(double value) { - observeFunction.accept(rotate(), value); + rotate(); + for (T t : ringBuffer) { + observeFunction.accept(t, value); + } } private T rotate() { - long timeSinceLastRotateMillis = System.currentTimeMillis() - lastRotateTimestampMillis; + long timeSinceLastRotateMillis = currentTimeMillis.getAsLong() - lastRotateTimestampMillis; while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { ringBuffer[currentBucket] = constructor.get(); if (++currentBucket >= ringBuffer.length) { diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java new file mode 100644 index 000000000..3b57220f8 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java @@ -0,0 +1,77 @@ +package io.prometheus.metrics.core.metrics; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +public class SlidingWindowTest { + + static class Observer { + + List values = new ArrayList<>(); + + public void observe(double value) { + values.add(value); + } + + void assertValues(double... expectedValues) { + ArrayList expectedList = new ArrayList<>(); + for (double expectedValue : expectedValues) { + expectedList.add(expectedValue); + } + Assert.assertEquals(expectedList, values); + } + } + + private final AtomicLong currentTimeMillis = new AtomicLong(); + private SlidingWindow ringBuffer; + private final long maxAgeSeconds = 30; + private final int ageBuckets = 5; + private final long timeBetweenRotateMillis = maxAgeSeconds * 1000 / ageBuckets + 2; + + @Before + public void setUp() { + currentTimeMillis.set(System.currentTimeMillis()); + ringBuffer = new SlidingWindow<>(Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets); + ringBuffer.currentTimeMillis = currentTimeMillis::get; + } + + @Test + public void testRotate() { + for (int i=0; i first observation evicted + ringBuffer.current().assertValues(2.0); + ringBuffer.observe(3.0); + ringBuffer.current().assertValues(2.0, 3.0); + currentTimeMillis.addAndGet(2 * timeBetweenRotateMillis); // 7/5 of max age + ringBuffer.current().assertValues(3.0); + currentTimeMillis.addAndGet(3 * timeBetweenRotateMillis); // 10/5 of max age + ringBuffer.current().assertValues(); // empty + } +} From 60c2553663b0ca3c6defa1f6622473078f8a35b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Sun, 12 Nov 2023 11:43:15 +0100 Subject: [PATCH 275/980] Fix metric name filter in MultiCollector #891 (#893) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../model/registry/PrometheusRegistry.java | 11 +- .../model/registry/MetricNameFilterTest.java | 15 ++- .../MultiCollectorNameFilterTest.java | 100 ++++++++++++++++++ 3 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java 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 a8ab5a762..8b059adb3 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 @@ -94,6 +94,8 @@ public MetricSnapshots scrape(Predicate includedNames, PrometheusScrapeR 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) { @@ -103,8 +105,9 @@ public MetricSnapshots scrape(Predicate includedNames, PrometheusScrapeR } for (MultiCollector collector : multiCollectors) { List prometheusNames = collector.getPrometheusNames(); - boolean excluded = true; // the multi-collector is excluded unless - // at least one name matches + // 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; @@ -112,8 +115,8 @@ public MetricSnapshots scrape(Predicate includedNames, PrometheusScrapeR } } if (!excluded) { - MetricSnapshots snaphots = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest); - for (MetricSnapshot snapshot : snaphots) { + MetricSnapshots snapshots = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest); + for (MetricSnapshot snapshot : snapshots) { if (snapshot != null) { result.metricSnapshot(snapshot); } 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 3b74f9dee..91bcf74fc 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 @@ -1,12 +1,21 @@ package io.prometheus.metrics.model.registry; 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; @@ -21,12 +30,12 @@ public void testCounter() { registry.register(() -> CounterSnapshot.builder() .name("counter1") .help("test counter 1") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .dataPoint(CounterDataPointSnapshot.builder() .labels(Labels.of("path", "/hello")) .value(1.0) .build() ) - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .dataPoint(CounterDataPointSnapshot.builder() .labels(Labels.of("path", "/goodbye")) .value(2.0) .build() @@ -36,7 +45,7 @@ public void testCounter() { registry.register(() -> CounterSnapshot.builder() .name("counter2") .help("test counter 2") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() + .dataPoint(CounterDataPointSnapshot.builder() .value(1.0) .build() ) 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 new file mode 100644 index 000000000..b36d58aa6 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java @@ -0,0 +1,100 @@ +package io.prometheus.metrics.model.registry; + +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.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; + +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; + } + }); + } + + @Test + public void testPartialFilter() { + + 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()); + } + + @Test + public void testPartialFilterWithPrometheusNames() { + + 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()); + } + + @Test + public void testCompleteFilter_CollectCalled() { + + includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2"); + + MetricSnapshots snapshots = registry.scrape(includedNames); + Assert.assertTrue(collectCalled[0]); + Assert.assertEquals(0, snapshots.size()); + } + + @Test + public void testCompleteFilter_CollectNotCalled() { + + 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()); + } +} From e8b3f87184db6caceebce90595f610b273c0be35 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Sun, 12 Nov 2023 05:43:47 -0500 Subject: [PATCH 276/980] Added equals and hashcode. Changed code to catch an empty String (#897) Signed-off-by: dhoard --- .../metrics/model/snapshots/Unit.java | 19 ++++++- .../metrics/model/snapshots/UnitTest.java | 51 +++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index d73980a97..94827c64c 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Objects; + /** * Some pre-defined units for convenience. You can create your own units with *
      @@ -23,13 +25,13 @@ public class Unit {
           public static final Unit AMPERES = new Unit("amperes");
       
           public Unit(String name) {
      -        this.name = name;
               if (name == null) {
                   throw new NullPointerException("Unit name cannot be null.");
               }
      -        if (name.isEmpty()) {
      +        if (name.trim().isEmpty()) {
                   throw new IllegalArgumentException("Unit name cannot be empty.");
               }
      +        this.name = name.trim();
           }
       
           @Override
      @@ -52,4 +54,17 @@ public static double secondsToMillis(double seconds) {
           public static double kiloBytesToBytes(double kilobytes) {
               return kilobytes * 1024;
           }
      +
      +    @Override
      +    public boolean equals(Object o) {
      +        if (this == o) return true;
      +        if (o == null || getClass() != o.getClass()) return false;
      +        Unit unit = (Unit) o;
      +        return Objects.equals(name, unit.name);
      +    }
      +
      +    @Override
      +    public int hashCode() {
      +        return Objects.hash(name);
      +    }
       }
      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
      new file mode 100644
      index 000000000..f88458cc3
      --- /dev/null
      +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java
      @@ -0,0 +1,51 @@
      +package io.prometheus.metrics.model.snapshots;
      +
      +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);
      +    }
      +}
      
      From dd31ee650585052affa76f3bdfa71e19ceda6c32 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 12:21:04 +0100
      Subject: [PATCH 277/980] Fix breaking scrape API change #892 (#898)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../httpserver/HttpExchangeAdapter.java       | 11 +++++++++++
       .../servlet/jakarta/HttpExchangeAdapter.java  | 19 +++++++++++++++++++
       .../registry/PrometheusScrapeRequest.java     | 12 +++++++++---
       3 files changed, 39 insertions(+), 3 deletions(-)
      
      diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java
      index daaeb2dbd..3636acedf 100644
      --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java
      +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java
      @@ -49,6 +49,17 @@ public Enumeration getHeaders(String name) {
               public String getMethod() {
                   return httpExchange.getRequestMethod();
               }
      +
      +        @Override
      +        public String getRequestPath() {
      +            URI requestURI = httpExchange.getRequestURI();
      +            String uri = requestURI.toString();
      +            int qx = uri.indexOf('?');
      +            if (qx != -1) {
      +                uri = uri.substring(0, qx);
      +            }
      +            return uri;
      +        }
           }
       
           public class HttpResponse implements PrometheusHttpResponse {
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java
      index c55eb7967..afcfb6cbc 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java
      +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java
      @@ -8,6 +8,7 @@
       
       import java.io.IOException;
       import java.io.OutputStream;
      +import java.net.URI;
       import java.util.Enumeration;
       
       public class HttpExchangeAdapter implements PrometheusHttpExchange {
      @@ -67,6 +68,24 @@ public Enumeration getHeaders(String name) {
               public String getMethod() {
                   return request.getMethod();
               }
      +
      +        @Override
      +        public String getRequestPath() {
      +            StringBuilder uri = new StringBuilder();
      +            String contextPath = request.getContextPath();
      +            if (contextPath.startsWith("/")) {
      +                uri.append(contextPath);
      +            }
      +            String servletPath = request.getServletPath();
      +            if (servletPath.startsWith("/")) {
      +                uri.append(servletPath);
      +            }
      +            String pathInfo = request.getPathInfo();
      +            if (pathInfo != null) {
      +                uri.append(pathInfo);
      +            }
      +            return uri.toString();
      +        }
           }
       
           public static class Response implements PrometheusHttpResponse {
      diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java
      index 268a326e1..e8651292e 100644
      --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java
      +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java
      @@ -2,10 +2,16 @@
       
       /**
        * Infos extracted from the request received by the endpoint
      - * 
        */
       public interface PrometheusScrapeRequest {
      -	
      -	String[] getParameterValues(String name);
       
      +	/**
      +	 * Absolute path of the HTTP request.
      +	 */
      +	String getRequestPath();
      +
      +	/**
      +	 * See {@code jakarta.servlet.ServletRequest.getParameterValues(String name)}
      +	 */
      +	String[] getParameterValues(String name);
       }
      
      From edaa65ee91750bb74bbe7c69e41e86b44aff5836 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 13:55:53 +0100
      Subject: [PATCH 278/980] Bump dependency versions (#899)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../example-greeting-service/pom.xml               |  2 +-
       .../example-greeting-service/version-rules.xml     | 12 ++++++++++++
       .../example-hello-world-app/pom.xml                |  2 +-
       .../example-hello-world-app/version-rules.xml      | 12 ++++++++++++
       examples/example-exporter-servlet-tomcat/pom.xml   |  2 +-
       .../version-rules.xml                              | 12 ++++++++++++
       .../example-simpleclient-bridge/version-rules.xml  | 12 ++++++++++++
       .../version-rules.xml                              |  6 ++++++
       .../it-exporter-servlet-jetty-sample/pom.xml       |  4 ++--
       .../version-rules.xml                              |  6 ++++++
       .../it-exporter-servlet-tomcat-sample/pom.xml      |  2 +-
       .../version-rules.xml                              | 12 ++++++++++++
       .../it-exporter/it-exporter-test/pom.xml           |  2 +-
       .../it-exporter/it-exporter-test/version-rules.xml |  6 ++++++
       integration-tests/it-exporter/version-rules.xml    |  6 ++++++
       integration-tests/pom.xml                          |  2 +-
       integration-tests/version-rules.xml                |  6 ++++++
       .../version-rules.xml                              |  6 ------
       .../version-rules.xml                              |  6 ------
       prometheus-metrics-exporter-opentelemetry/pom.xml  |  8 ++++----
       .../exporter/opentelemetry/ExemplarTest.java       | 14 ++++++++++----
       .../version-rules.xml                              |  6 ++++++
       .../version-rules.xml                              |  6 ------
       prometheus-metrics-instrumentation-jvm/pom.xml     |  2 +-
       .../version-rules.xml                              |  6 ------
       .../version-rules.xml                              |  6 ++++++
       .../version-rules.xml                              |  6 ++++++
       .../version-rules.xml                              |  6 +++---
       28 files changed, 134 insertions(+), 44 deletions(-)
       create mode 100644 examples/example-exemplars-tail-sampling/example-greeting-service/version-rules.xml
       create mode 100644 examples/example-exemplars-tail-sampling/example-hello-world-app/version-rules.xml
       create mode 100644 examples/example-exporter-servlet-tomcat/version-rules.xml
       create mode 100644 examples/example-simpleclient-bridge/version-rules.xml
       create mode 100644 integration-tests/it-exporter/it-exporter-httpserver-sample/version-rules.xml
       create mode 100644 integration-tests/it-exporter/it-exporter-servlet-jetty-sample/version-rules.xml
       create mode 100644 integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/version-rules.xml
       create mode 100644 integration-tests/it-exporter/it-exporter-test/version-rules.xml
       create mode 100644 integration-tests/it-exporter/version-rules.xml
       create mode 100644 integration-tests/version-rules.xml
       create mode 100644 prometheus-metrics-exporter-opentelemetry/version-rules.xml
       create mode 100644 prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml
       create mode 100644 prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml
      
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 29827ffbe..d797655ad 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.11
      +            10.1.15
               
           
       
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/version-rules.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/version-rules.xml
      new file mode 100644
      index 000000000..7b60b893a
      --- /dev/null
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/version-rules.xml
      @@ -0,0 +1,12 @@
      +
      +    
      +        
      +            
      +                
      +                .*-M[0-9]+
      +            
      +        
      +    
      +
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index bc6db20f7..e8b06203c 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.11
      +            10.1.15
               
           
       
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/version-rules.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/version-rules.xml
      new file mode 100644
      index 000000000..7b60b893a
      --- /dev/null
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/version-rules.xml
      @@ -0,0 +1,12 @@
      +
      +    
      +        
      +            
      +                
      +                .*-M[0-9]+
      +            
      +        
      +    
      +
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 75f3beeab..b4dd55ce3 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.11
      +            10.1.15
               
           
       
      diff --git a/examples/example-exporter-servlet-tomcat/version-rules.xml b/examples/example-exporter-servlet-tomcat/version-rules.xml
      new file mode 100644
      index 000000000..7b60b893a
      --- /dev/null
      +++ b/examples/example-exporter-servlet-tomcat/version-rules.xml
      @@ -0,0 +1,12 @@
      +
      +    
      +        
      +            
      +                
      +                .*-M[0-9]+
      +            
      +        
      +    
      +
      diff --git a/examples/example-simpleclient-bridge/version-rules.xml b/examples/example-simpleclient-bridge/version-rules.xml
      new file mode 100644
      index 000000000..366b579fe
      --- /dev/null
      +++ b/examples/example-simpleclient-bridge/version-rules.xml
      @@ -0,0 +1,12 @@
      +
      +    
      +        
      +            
      +                
      +                .*(alpha|beta)-[0-9]
      +            
      +        
      +    
      +
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/version-rules.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 823997f40..6d2bc1a45 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -45,12 +45,12 @@
               
                   org.eclipse.jetty
                   jetty-server
      -            11.0.15
      +            11.0.18
               
               
                   org.eclipse.jetty
                   jetty-servlet
      -            11.0.15
      +            11.0.18
               
           
       
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/version-rules.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index 1cef98dd0..d0ab3c886 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -45,7 +45,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.11
      +            10.1.15
               
           
       
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/version-rules.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/version-rules.xml
      new file mode 100644
      index 000000000..7b60b893a
      --- /dev/null
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/version-rules.xml
      @@ -0,0 +1,12 @@
      +
      +    
      +        
      +            
      +                
      +                .*-M[0-9]+
      +            
      +        
      +    
      +
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index 05661f8c0..ef92990f1 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -51,7 +51,7 @@
               
                   commons-io
                   commons-io
      -            2.13.0
      +            2.15.0
                   test
               
               
      diff --git a/integration-tests/it-exporter/it-exporter-test/version-rules.xml b/integration-tests/it-exporter/it-exporter-test/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/it-exporter/it-exporter-test/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/integration-tests/it-exporter/version-rules.xml b/integration-tests/it-exporter/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/it-exporter/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index d2f1a7fb5..223543b6d 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -55,7 +55,7 @@
                   
                       org.testcontainers
                       testcontainers
      -                1.17.2
      +                1.19.1
                       test
                   
               
      diff --git a/integration-tests/version-rules.xml b/integration-tests/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/prometheus-metrics-exporter-common/version-rules.xml b/prometheus-metrics-exporter-common/version-rules.xml
      index 318e865f5..5c6d39593 100644
      --- a/prometheus-metrics-exporter-common/version-rules.xml
      +++ b/prometheus-metrics-exporter-common/version-rules.xml
      @@ -2,11 +2,5 @@
                xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
           
      -        
      -            
      -                
      -                [^8].*
      -            
      -        
           
       
      diff --git a/prometheus-metrics-exporter-httpserver/version-rules.xml b/prometheus-metrics-exporter-httpserver/version-rules.xml
      index 318e865f5..5c6d39593 100644
      --- a/prometheus-metrics-exporter-httpserver/version-rules.xml
      +++ b/prometheus-metrics-exporter-httpserver/version-rules.xml
      @@ -2,11 +2,5 @@
                xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
           
      -        
      -            
      -                
      -                [^8].*
      -            
      -        
           
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 175c9a5dd..9f6ace627 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -82,7 +82,7 @@
               
                   org.wiremock
                   wiremock
      -            3.2.0
      +            3.3.1
                   test
               
               
      @@ -94,7 +94,7 @@
               
                   io.opentelemetry
                   opentelemetry-proto
      -            0.17.1
      +            1.7.1-alpha
                   test
               
               
      @@ -134,13 +134,13 @@
                           
                               io.opentelemetry
                               opentelemetry-api
      -                        1.29.0
      +                        ${otel.version}
                               ${project.basedir}/src/main/resources/lib/
                           
                           
                               io.opentelemetry
                               opentelemetry-context
      -                        1.29.0
      +                        ${otel.version}
                               ${project.basedir}/src/main/resources/lib/
                           
                       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java
      index 0226c131c..2482d6857 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java
      @@ -9,9 +9,9 @@
       import io.opentelemetry.api.trace.Tracer;
       import io.opentelemetry.context.Scope;
       import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;
      -import io.opentelemetry.proto.metrics.v1.DoubleDataPoint;
       import io.opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics;
       import io.opentelemetry.proto.metrics.v1.Metric;
      +import io.opentelemetry.proto.metrics.v1.NumberDataPoint;
       import io.opentelemetry.proto.metrics.v1.ResourceMetrics;
       import io.opentelemetry.sdk.trace.SdkTracerProvider;
       import io.opentelemetry.sdk.trace.samplers.Sampler;
      @@ -23,7 +23,13 @@
       import org.junit.Rule;
       import org.junit.Test;
       
      -import static com.github.tomakehurst.wiremock.client.WireMock.*;
      +import static com.github.tomakehurst.wiremock.client.WireMock.containing;
      +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
      +import static com.github.tomakehurst.wiremock.client.WireMock.ok;
      +import static com.github.tomakehurst.wiremock.client.WireMock.post;
      +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
      +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
      +import static com.github.tomakehurst.wiremock.client.WireMock.verify;
       import static java.util.concurrent.TimeUnit.SECONDS;
       import static org.awaitility.Awaitility.await;
       
      @@ -122,8 +128,8 @@ private static ValueMatcher getExemplarCountMatcher(int expectedCount)
                       for (ResourceMetrics resourceMetrics : exportMetricsServiceRequest.getResourceMetricsList()) {
                           for (InstrumentationLibraryMetrics instrumentationLibraryMetrics : resourceMetrics.getInstrumentationLibraryMetricsList()) {
                               for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) {
      -                            for (DoubleDataPoint doubleDataPoint : metric.getDoubleSum().getDataPointsList()) {
      -                                if (doubleDataPoint.getExemplarsCount() == expectedCount) {
      +                            for (NumberDataPoint numberDataPoint : metric.getSum().getDataPointsList()) {
      +                                if (numberDataPoint.getExemplarsCount() == expectedCount) {
                                           return MatchResult.exactMatch();
                                       }
                                   }
      diff --git a/prometheus-metrics-exporter-opentelemetry/version-rules.xml b/prometheus-metrics-exporter-opentelemetry/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/prometheus-metrics-exporter-opentelemetry/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml b/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml
      index 318e865f5..5c6d39593 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/version-rules.xml
      @@ -2,11 +2,5 @@
                xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
           
      -        
      -            
      -                
      -                [^8].*
      -            
      -        
           
       
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index 1b42d176d..56b2dc46a 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -58,7 +58,7 @@
               
                   org.mockito
                   mockito-core
      -            4.11.0
      +            5.7.0
                   test
               
               
      diff --git a/prometheus-metrics-instrumentation-jvm/version-rules.xml b/prometheus-metrics-instrumentation-jvm/version-rules.xml
      index 904c3c3a1..5c6d39593 100644
      --- a/prometheus-metrics-instrumentation-jvm/version-rules.xml
      +++ b/prometheus-metrics-instrumentation-jvm/version-rules.xml
      @@ -2,11 +2,5 @@
                xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
           
      -        
      -            
      -                
      -                [^9].*
      -            
      -        
           
       
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/prometheus-metrics-simpleclient-bridge/version-rules.xml b/prometheus-metrics-simpleclient-bridge/version-rules.xml
      index 904c3c3a1..c0e533e9e 100644
      --- a/prometheus-metrics-simpleclient-bridge/version-rules.xml
      +++ b/prometheus-metrics-simpleclient-bridge/version-rules.xml
      @@ -2,10 +2,10 @@
                xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0 https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
           
      -        
      +        
                   
      -                
      -                [^9].*
      +                
      +                .*(alpha|beta)-[0-9]
                   
               
           
      
      From 0f27ea13a6700b13ff72633e082531f9b3b3eddf Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 12:38:43 +0100
      Subject: [PATCH 279/980] Temporarily add shaded dependencies to prepare for
       release
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml                                           | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +-
       prometheus-metrics-exposition-formats/pom.xml     | 2 +-
       3 files changed, 3 insertions(+), 3 deletions(-)
      
      diff --git a/pom.xml b/pom.xml
      index 114e35d4a..bda8ea060 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -63,7 +63,7 @@
               prometheus-metrics-exporter-opentelemetry
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-simpleclient-bridge
      -        
      +        prometheus-metrics-shaded-dependencies
               examples
               benchmarks
               integration-tests
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 9f6ace627..fa2538a9b 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -47,7 +47,7 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-opentelemetry
      -            1.0.0
      +            ${project.version}
               
               
      
      From cb5a6d58d3eb812956a5baba8e601bfb7bca9ad2 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 16:21:01 +0100
      Subject: [PATCH 280/980] Update OpenTelemetry version
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../pom.xml                                   | 25 +------------------
       .../opentelemetry/OpenTelemetryExporter.java  | 18 ++++++-------
       .../PrometheusInstrumentationScope.java       |  2 +-
       .../PrometheusMetricProducer.java             | 16 ++++++------
       .../otelmodel/DoublePointDataImpl.java        |  6 ++---
       .../ExponentialHistogramBucketsImpl.java      |  2 +-
       .../ExponentialHistogramPointDataImpl.java    |  8 +++---
       .../otelmodel/HistogramPointDataImpl.java     |  6 ++---
       .../otelmodel/MetricDataFactory.java          |  6 ++---
       .../otelmodel/PointDataImpl.java              |  8 +++---
       .../otelmodel/PrometheusClassicHistogram.java |  8 +++---
       .../otelmodel/PrometheusCounter.java          |  8 +++---
       .../otelmodel/PrometheusData.java             | 20 +++++++--------
       .../otelmodel/PrometheusGauge.java            |  6 ++---
       .../otelmodel/PrometheusInfo.java             |  8 +++---
       .../otelmodel/PrometheusMetricData.java       | 12 ++++-----
       .../otelmodel/PrometheusNativeHistogram.java  | 10 ++++----
       .../otelmodel/PrometheusStateSet.java         |  8 +++---
       .../otelmodel/PrometheusSummary.java          |  6 ++---
       .../otelmodel/PrometheusUnknown.java          |  6 ++---
       .../otelmodel/SummaryPointDataImpl.java       |  8 +++---
       .../otelmodel/ValueAtQuantileImpl.java        |  2 +-
       .../pom.xml                                   | 10 ++------
       23 files changed, 90 insertions(+), 119 deletions(-)
      
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index fa2538a9b..e84bef9b8 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -17,8 +17,7 @@
           
       
           
      -        1.28.0
      -        ${otel.version}-alpha
      +        1.31.0
               io.prometheus.metrics.exporter.opentelemetry
           
       
      @@ -49,28 +48,6 @@
                   prometheus-metrics-shaded-opentelemetry
                   ${project.version}
               
      -        
       
               
               
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java
      index 31f263fd9..a59948002 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java
      @@ -3,15 +3,15 @@
       import io.prometheus.metrics.config.ExporterOpenTelemetryProperties;
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.metrics.OtlpGrpcMetricExporter;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.export.MetricExporter;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.export.PeriodicMetricReader;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.ResourceBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.metrics.OtlpGrpcMetricExporter;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.MetricExporter;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.PeriodicMetricReader;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.ResourceBuilder;
       
       import java.time.Duration;
       import java.util.HashMap;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java
      index 1f38e66e2..da78e2e41 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java
      @@ -1,6 +1,6 @@
       package io.prometheus.metrics.exporter.opentelemetry;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo;
       
       import java.util.Properties;
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java
      index fc7e047b1..72dd968db 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java
      @@ -12,19 +12,19 @@
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.AttributesBuilder;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.internal.export.MetricProducer;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.ResourceBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.AttributesBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.CollectionRegistration;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.ResourceBuilder;
       
       import java.util.ArrayList;
       import java.util.Collection;
       import java.util.List;
       
      -class PrometheusMetricProducer implements MetricProducer {
      +class PrometheusMetricProducer implements CollectionRegistration {
       
           private final PrometheusRegistry registry;
           private final Resource resource;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java
      index 6c93f74e7..5f6e22ff1 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java
      @@ -1,8 +1,8 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
       
       import java.util.List;
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java
      index d365c26fb..2f7c2ca9f 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java
      @@ -1,6 +1,6 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets;
       
       import java.util.ArrayList;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java
      index 86d56d2d7..e28deaf65 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramPointData;
       
       import java.util.List;
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java
      index 7908bee2b..68e2eefaf 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java
      @@ -1,8 +1,8 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramPointData;
       
       import java.util.List;
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java
      index 8557e0a29..26fb13738 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java
      @@ -7,9 +7,9 @@
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource;
       
       public class MetricDataFactory {
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java
      index a0b4aed83..c57b0e064 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.PointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.PointData;
       
       import java.util.List;
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java
      index 08ef9ffc1..03144ed0e 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java
      @@ -2,10 +2,10 @@
       
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.HistogramPointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
       
       import java.util.ArrayList;
       import java.util.Collection;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java
      index ed58fa5c7..6bf81e945 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       
       import java.util.Collection;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java
      index 56d10847b..747fa7b25 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java
      @@ -1,16 +1,16 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
       import io.prometheus.metrics.model.snapshots.*;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.AttributesBuilder;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.SpanContext;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.TraceFlags;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.trace.TraceState;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.Data;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.PointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.AttributesBuilder;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.SpanContext;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.TraceFlags;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.TraceState;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.Data;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.PointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData;
       
       import java.util.List;
       import java.util.Objects;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java
      index 1278a6af3..73635e69a 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
       import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.GaugeData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.GaugeData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
       
       import java.util.Collection;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java
      index e5244a058..1c7ab6fff 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java
      @@ -1,10 +1,10 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
       import io.prometheus.metrics.model.snapshots.InfoSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData;
       
       import java.util.Collection;
       import java.util.Collections;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      index ddf2160d0..0ecbfd76e 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      @@ -3,12 +3,12 @@
       import io.prometheus.metrics.model.snapshots.MetricMetadata;
       import io.prometheus.metrics.model.snapshots.PrometheusNaming;
       import io.prometheus.metrics.model.snapshots.Unit;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.common.InstrumentationScopeInfo;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.resources.Resource;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource;
       
       class PrometheusMetricData> implements MetricData {
       
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java
      index 9610a7bf9..e150e44a1 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java
      @@ -2,11 +2,11 @@
       
       import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
       import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramBuckets;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ExponentialHistogramPointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
       
       import java.util.Collection;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java
      index 9b871d50c..0ebaf572c 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java
      @@ -2,10 +2,10 @@
       
       import io.prometheus.metrics.model.snapshots.Labels;
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.AggregationTemporality;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SumData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData;
       
       import java.util.ArrayList;
       import java.util.Collection;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java
      index a89bc4058..7b7ba858b 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java
      @@ -2,9 +2,9 @@
       
       import io.prometheus.metrics.model.snapshots.Quantile;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryPointData;
       
       import java.util.Collection;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java
      index 2f717a652..064774420 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoublePointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.GaugeData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.MetricDataType;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.GaugeData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType;
       
       import java.util.Collection;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java
      index 0e9c61c1f..f5af6589c 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java
      @@ -1,9 +1,9 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.api.common.Attributes;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.DoubleExemplarData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.SummaryPointData;
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ValueAtQuantile;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryPointData;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ValueAtQuantile;
       
       import java.util.ArrayList;
       import java.util.List;
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java
      index fafc2be77..4d1c2002f 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java
      @@ -1,6 +1,6 @@
       package io.prometheus.metrics.exporter.opentelemetry.otelmodel;
       
      -import io.prometheus.metrics.shaded.io_opentelemetry_1_28_0.sdk.metrics.data.ValueAtQuantile;
      +import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ValueAtQuantile;
       
       public class ValueAtQuantileImpl implements ValueAtQuantile {
       
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index bc1e62549..05389d1ee 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -16,9 +16,8 @@
           
       
           
      -        1.28.0
      -        ${otel.version}-alpha
      -        1_28_0
      +        1.31.0
      +        1_31_0
           
       
           
      @@ -48,11 +47,6 @@
                   opentelemetry-sdk
                   ${otel.version}
               
      -        
      -            io.opentelemetry
      -            opentelemetry-semconv
      -            ${otel.semconv.version}
      -        
               
                   io.opentelemetry
                   opentelemetry-exporter-otlp
      
      From 0ae1ec08deb54b03bfb40b7b69f41c8f7522d730 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 16:32:34 +0100
      Subject: [PATCH 281/980] [maven-release-plugin] prepare release v1.1.0
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 4 ++--
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       38 files changed, 41 insertions(+), 41 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index 18f8f7b34..1fc1b45f2 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index d797655ad..1c699d4ec 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index e8b06203c..d48a5a627 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index 0e77e6206..7482831b2 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index 1e2e29293..524b00e33 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index fa9d1a94a..d3ad59be2 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index 78d4ce8af..cbd85a325 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index b4dd55ce3..caabaa0ad 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index b094f76db..c519cb092 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index 14dad20ff..e7ccdacb3 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index 3abc5f5ba..cf8dd8eb8 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index 61db27a97..3817ee353 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index ccff0a33c..2d4665483 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index 3638eb7e1..5cb35c318 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 6d2bc1a45..54e6d3dab 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index d0ab3c886..be71fb3db 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index ef92990f1..88d1a1964 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index 2802e6231..82e49c8e5 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.1.0
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 223543b6d..987e8d0b2 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index bda8ea060..db5c2a62e 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.1.0-SNAPSHOT
      +    1.1.0
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.1.0
           
       
           
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index 6ed2c6411..e0a4d469d 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 70cc9c1b2..9ab34cbe6 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index 8e64daaba..78ac62b9e 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index b2e446fe1..e1a8519ce 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index e84bef9b8..fc05aa5e3 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index e562fbdee..46c79695c 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 471b29da5..1703f0f77 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index 56b2dc46a..f452d488b 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index 06d0c56d9..b3d56a29f 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index a7ff63c82..30f980c79 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 05389d1ee..39818a25d 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index 917892a98..aaf664ef8 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index 49efc4b4f..72577ec03 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0-SNAPSHOT
      +        1.1.0
           
       
           prometheus-metrics-simpleclient-bridge
      @@ -76,7 +76,7 @@
               
                   io.prometheus
                   prometheus-metrics-config
      -            1.1.0-SNAPSHOT
      +            1.1.0
                   compile
               
           
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index fef4bb904..b27041f59 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.1.0-SNAPSHOT
      +    1.1.0
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index 0135ce7e3..9297bf610 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0-SNAPSHOT
      +    1.1.0
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index f769c41d5..697f5b700 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0-SNAPSHOT
      +    1.1.0
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index 03864b703..524c2f0b6 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0-SNAPSHOT
      +    1.1.0
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index 4dcc2d56c..b2f6f781b 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0-SNAPSHOT
      +    1.1.0
         
       
         prometheus-metrics-tracer-otel
      
      From 49afd6fc998b66b2843cc8255dbe7efeafac01ee Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 16:32:37 +0100
      Subject: [PATCH 282/980] [maven-release-plugin] prepare for next development
       iteration
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 4 ++--
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       38 files changed, 41 insertions(+), 41 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index 1fc1b45f2..b57d082df 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 1c699d4ec..5e58d1e78 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index d48a5a627..98b910a47 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index 7482831b2..d0d0d2d4c 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index 524b00e33..b556efaf3 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index d3ad59be2..1bc04d401 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index cbd85a325..06cae160a 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index caabaa0ad..50cb17c84 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index c519cb092..4f7180bad 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index e7ccdacb3..60249fbee 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index cf8dd8eb8..981255de6 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index 3817ee353..aaf81b19f 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index 2d4665483..04198dc37 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index 5cb35c318..846018037 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 54e6d3dab..eca28e70f 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index be71fb3db..558590380 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index 88d1a1964..7300b9318 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index 82e49c8e5..c54b423f8 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.1.0
      +        HEAD
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 987e8d0b2..d76fae256 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index db5c2a62e..27aa8721f 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.1.0
      +    1.2.0-SNAPSHOT
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.1.0
      +        HEAD
           
       
           
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index e0a4d469d..2247a8e8f 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 9ab34cbe6..7773301d0 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index 78ac62b9e..53828db1d 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index e1a8519ce..b99959fc4 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index fc05aa5e3..8b67e75d9 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index 46c79695c..204ff2fa7 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 1703f0f77..8f071f855 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index f452d488b..f55dd9c6f 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index b3d56a29f..f45d5b6fb 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index 30f980c79..395fcdfd8 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 39818a25d..73f96d5f5 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index aaf664ef8..224571946 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index 72577ec03..10d9ac8d6 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.1.0
      +        1.2.0-SNAPSHOT
           
       
           prometheus-metrics-simpleclient-bridge
      @@ -76,7 +76,7 @@
               
                   io.prometheus
                   prometheus-metrics-config
      -            1.1.0
      +            1.2.0-SNAPSHOT
                   compile
               
           
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index b27041f59..98286194e 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.1.0
      +    1.2.0-SNAPSHOT
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index 9297bf610..ed86d6249 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0
      +    1.2.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index 697f5b700..8c5657755 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0
      +    1.2.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index 524c2f0b6..19db2bdf6 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0
      +    1.2.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index b2f6f781b..a5a34c38b 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.1.0
      +    1.2.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel
      
      From 608e92421f562b4d23a7e156a3bf2664f7f7143b Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 17:09:05 +0100
      Subject: [PATCH 283/980] Exclude shaded dependencies from the build
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml                                           | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +-
       prometheus-metrics-exposition-formats/pom.xml     | 2 +-
       3 files changed, 3 insertions(+), 3 deletions(-)
      
      diff --git a/pom.xml b/pom.xml
      index 27aa8721f..dd91272fd 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -63,7 +63,7 @@
               prometheus-metrics-exporter-opentelemetry
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-simpleclient-bridge
      -        prometheus-metrics-shaded-dependencies
      +        
               examples
               benchmarks
               integration-tests
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 8b67e75d9..b99ee75cf 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -46,7 +46,7 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-opentelemetry
      -            ${project.version}
      +            1.1.0
               
       
               
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 8f071f855..c1f0fdf77 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -50,7 +50,7 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-protobuf
      -            ${project.version}
      +            1.1.0
               
       
               
      
      From 881755ae207edad0661710f7c8f32c00515b68a0 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 12 Nov 2023 17:11:29 +0100
      Subject: [PATCH 284/980] Update README
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       MAINTAINER_NOTES.md | 4 ++--
       README.md           | 2 --
       2 files changed, 2 insertions(+), 4 deletions(-)
      
      diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md
      index 593603a3a..90f030c23 100644
      --- a/MAINTAINER_NOTES.md
      +++ b/MAINTAINER_NOTES.md
      @@ -11,8 +11,8 @@ Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/i
       ## Release
       
       ```
      -./mvnw release:prepare -DreleaseVersion=0.16.0 -DdevelopmentVersion=0.16.1-SNAPSHOT
      -./mvnw release:perform -DreleaseVersion=0.16.0 -DdevelopmentVersion=0.16.1-SNAPSHOT
      +./mvnw release:prepare -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT
      +./mvnw release:perform -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT
       ```
       
       `release:prepare` does Github tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org).
      diff --git a/README.md b/README.md
      index bcab4daf1..0cf4f3b80 100644
      --- a/README.md
      +++ b/README.md
      @@ -2,8 +2,6 @@
       
       [![Build Status](https://circleci.com/gh/prometheus/client_java.svg?style=svg)](https://circleci.com/gh/prometheus/client_java)
       
      -Release date for 1.0.0 is 27 Sep 2023. Pre-releases are [available](https://github.com/prometheus/client_java/releases).
      -
       # Documentation
       
       [https://prometheus.github.io/client_java](https://prometheus.github.io/client_java)
      
      From 60f72b6d27d31a4a566670cebdfb2699073c705a Mon Sep 17 00:00:00 2001
      From: Sean Roberts 
      Date: Wed, 15 Nov 2023 07:54:44 -0600
      Subject: [PATCH 285/980] Update metric-types.md: typo (#900)
      
      Signed-off-by: Sean Roberts 
      ---
       docs/content/getting-started/metric-types.md | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md
      index 51d07bdbf..d3451b3d9 100644
      --- a/docs/content/getting-started/metric-types.md
      +++ b/docs/content/getting-started/metric-types.md
      @@ -54,7 +54,7 @@ Histogram
       Histograms are for observing distributions, like latency distributions for HTTP services or the distribution of request sizes.
       Unlike with counters and gauges, each histogram data point has a complex data structure representing different aspects of the distribution:
       
      -* Count: The toal number of observations.
      +* Count: The total number of observations.
       * Sum: The sum of all observed values, e.g. the total time spent serving requests.
       * Buckets: The histogram buckets representing the distribution.
       
      
      From 1fd8c7df9f88981a603ce4821f5637b719f663ea Mon Sep 17 00:00:00 2001
      From: choi se 
      Date: Wed, 17 Jan 2024 19:25:59 +0900
      Subject: [PATCH 286/980] Add Backwards-Compatibility (#911)
      
      * Add Backwards-Compatibility
      - metrics name
      
      Signed-off-by: thinker0 
      
      * Update code
      
      Signed-off-by: thinker0 
      
      * Update code
      
      Signed-off-by: thinker0 
      
      ---------
      
      Signed-off-by: thinker0 
      ---
       .../bridge/SimpleclientCollector.java            | 16 +++++++++-------
       1 file changed, 9 insertions(+), 7 deletions(-)
      
      diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java
      index a775b2f55..e1b5a3113 100644
      --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java
      +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java
      @@ -1,5 +1,7 @@
       package io.prometheus.metrics.simpleclient.bridge;
       
      +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName;
      +
       import io.prometheus.client.Collector;
       import io.prometheus.client.CollectorRegistry;
       import io.prometheus.metrics.config.PrometheusProperties;
      @@ -99,7 +101,7 @@ private MetricSnapshots convert(Enumeration sampl
       
           private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) {
               CounterSnapshot.Builder counter = CounterSnapshot.builder()
      -                .name(stripSuffix(samples.name, "_total"))
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help)
                       .unit(convertUnit(samples));
               Map dataPoints = new HashMap<>();
      @@ -123,7 +125,7 @@ private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) {
       
           private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) {
               GaugeSnapshot.Builder gauge = GaugeSnapshot.builder()
      -                .name(samples.name)
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help)
                       .unit(convertUnit(samples));
               for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      @@ -141,7 +143,7 @@ private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) {
       
           private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, boolean isGaugeHistogram) {
               HistogramSnapshot.Builder histogram = HistogramSnapshot.builder()
      -                .name(samples.name)
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help)
                       .unit(convertUnit(samples))
                       .gaugeHistogram(isGaugeHistogram);
      @@ -181,7 +183,7 @@ private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, b
       
           private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) {
               SummarySnapshot.Builder summary = SummarySnapshot.builder()
      -                .name(samples.name)
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help)
                       .unit(convertUnit(samples));
               Map dataPoints = new HashMap<>();
      @@ -225,7 +227,7 @@ private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) {
       
           private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) {
               StateSetSnapshot.Builder stateSet = StateSetSnapshot.builder()
      -                .name(samples.name)
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help);
               Map dataPoints = new HashMap<>();
               for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      @@ -254,7 +256,7 @@ private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) {
       
           private MetricSnapshot convertUnknown(Collector.MetricFamilySamples samples) {
               UnknownSnapshot.Builder unknown = UnknownSnapshot.builder()
      -                .name(samples.name)
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help)
                       .unit(convertUnit(samples));
               for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      @@ -334,7 +336,7 @@ private Labels labelsWithout(Collector.MetricFamilySamples.Sample sample, String
       
           private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) {
               InfoSnapshot.Builder info = InfoSnapshot.builder()
      -                .name(stripSuffix(samples.name, "_info"))
      +                .name(sanitizeMetricName(samples.name))
                       .help(samples.help);
               for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
                   info.dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder()
      
      From b2298884a93d5d884e4128aee9af5b18eb439819 Mon Sep 17 00:00:00 2001
      From: "Capt. Cutlass" <5120290+ParanoidUser@users.noreply.github.com>
      Date: Fri, 19 Jan 2024 10:47:15 -0500
      Subject: [PATCH 287/980] fix: broken links and minor typos (#913)
      
      Signed-off-by: Capt. Cutlass <5120290+ParanoidUser@users.noreply.github.com>
      ---
       docs/content/config/config.md                |  4 ++--
       docs/content/exporters/httpserver.md         |  6 +++---
       docs/content/exporters/spring.md             |  4 ++--
       docs/content/getting-started/metric-types.md | 10 +++++-----
       docs/content/getting-started/performance.md  |  4 ++--
       docs/content/getting-started/registry.md     |  2 +-
       docs/content/internals/model.md              |  2 +-
       docs/content/migration/simpleclient.md       |  2 +-
       8 files changed, 17 insertions(+), 17 deletions(-)
      
      diff --git a/docs/content/config/config.md b/docs/content/config/config.md
      index 285637f5d..43a396174 100644
      --- a/docs/content/config/config.md
      +++ b/docs/content/config/config.md
      @@ -46,8 +46,8 @@ Metrics Properties
       | io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxZeroThreshold(double)) | |
       | io.prometheus.metrics.histogramNativeMaxNumberOfBuckets | [Histogram.Builder.nativeMaxNumberOfBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxNumberOfBuckets(int)) | |
       | io.prometheus.metrics.histogramNativeResetDurationSeconds | [Histogram.Builder.nativeResetDuration()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeResetDuration(long,java.util.concurrent.TimeUnit)) | |
      -| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](https://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (4) |
      -| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](ihttps://prometheus.github.io/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (5) |
      +| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (4) |
      +| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (5) |
       | io.prometheus.metrics.summaryMaxAgeSeconds | [Summary.Builder.maxAgeSeconds()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#maxAgeSeconds(long)) | |
       | io.prometheus.metrics.summaryNumberOfAgeBuckets | [Summary.Builder.numberOfAgeBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#numberOfAgeBuckets(int)) | |
       
      diff --git a/docs/content/exporters/httpserver.md b/docs/content/exporters/httpserver.md
      index 17824775f..e524b4cd1 100644
      --- a/docs/content/exporters/httpserver.md
      +++ b/docs/content/exporters/httpserver.md
      @@ -13,7 +13,7 @@ HTTPServer server = HTTPServer.builder()
       
       By default, `HTTPServer` binds to any IP address, you can change this with [hostname()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#hostname(java.lang.String)) or [inetAddress()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#inetAddress(java.net.InetAddress)).
       
      -`HTTPServer` is configured with three endoints:
      +`HTTPServer` is configured with three endpoints:
       
       * `/metrics` for Prometheus scraping.
       * `/-/healthy` for simple health checks.
      @@ -24,8 +24,8 @@ The default handler can be changed with [defaultHandler()](/client_java/api/io/p
       Authentication and HTTPS
       ------------------------
       
      -* [authenticator()](https://prometheus.github.io/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#authenticator(com.sun.net.httpserver.Authenticator)) is for configuring authentication.
      -* [httpsConfigurator()](https://prometheus.github.io/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#httpsConfigurator(com.sun.net.httpserver.HttpsConfigurator)) is for configuring HTTPS.
      +* [authenticator()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#authenticator(com.sun.net.httpserver.Authenticator)) is for configuring authentication.
      +* [httpsConfigurator()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#httpsConfigurator(com.sun.net.httpserver.HttpsConfigurator)) is for configuring HTTPS.
       
       You can find an example of authentication and SSL in the [jmx_exporter](https://github.com/prometheus/jmx_exporter).
       
      diff --git a/docs/content/exporters/spring.md b/docs/content/exporters/spring.md
      index e2c0a4f64..73e4b2549 100644
      --- a/docs/content/exporters/spring.md
      +++ b/docs/content/exporters/spring.md
      @@ -21,7 +21,7 @@ Use the Prometheus Metrics Library in Spring
       
       However, you may have your reasons why you want to use the Prometheus metrics library in Spring anyway. Maybe you want full support for all Prometheus metric types, or you want to use the new Prometheus native histograms.
       
      -The easiest way to use the Prometheus metrics library in Spring is to configure the [PrometheusMetricsServlet](http://localhost:1313/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics.
      +The easiest way to use the Prometheus metrics library in Spring is to configure the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics.
       
       Dependencies:
       
      @@ -68,7 +68,7 @@ public class DemoApplication {
       }
       ```
       
      -The important part are the last three lines: They configure the [PrometheusMetricsServlet](http://localhost:1313/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics on `/metrics`:
      +The important part are the last three lines: They configure the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics on `/metrics`:
       
       ```java
       @Bean
      diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md
      index d3451b3d9..e10d51e9a 100644
      --- a/docs/content/getting-started/metric-types.md
      +++ b/docs/content/getting-started/metric-types.md
      @@ -61,7 +61,7 @@ Unlike with counters and gauges, each histogram data point has a complex data st
       Prometheus supports two flavors of histograms:
       
       * Classic histograms: Bucket boundaries are explicitly defined when the histogram is created.
      -* Native histograms (exponential histograms): Infinitly many virtual buckets.
      +* Native histograms (exponential histograms): Infinitely many virtual buckets.
       
       By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server.
       * By default, the Prometheus server will scrape metrics in OpenMetrics format and get the classic histogram flavor.
      @@ -91,7 +91,7 @@ The histogram builder provides a lot of configuration for fine-tuning the histog
       * `classicBuckets(...)`: Set the classic bucket boundaries. Default buckets are `.005`, `.01`, `.025`, `.05`, `.1`, `.25`, `.5`, `1`, `2.5`, `5`, `and 10`. The default bucket boundaries are designed for measuring request durations in seconds.
       * `nativeMaxNumberOfBuckets()`: Upper limit for the number of native histogram buckets. Default is 160. When the maximum is reached, the native histogram automatically reduces resolution to stay below the limit.
       
      -See Javadoc for [Histogram.Builder](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html) for a complete list of options. Some options can be configured at runtime, see [config](/config/config).
      +See Javadoc for [Histogram.Builder](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html) for a complete list of options. Some options can be configured at runtime, see [config](../../config/config).
       
       Histograms and summaries are both used for observing distributions. Therefore, the both implement the `DistributionDataPoint` interface. Using the `DistributionDataPoint` interface directly gives you the option to switch between histograms and summaries later with minimal code changes.
       
      @@ -148,19 +148,19 @@ Summary requestLatency = Summary.builder()
       requestLatency.labelValues("ok").observe(2.7);
       ```
       
      -The example above creates a summary with the 50th percentile (median), the 95th percentila, and the 99th percentile. Quantiles are optional, you can create a summary without quantiles if all you need is the count and the sum.
      +The example above creates a summary with the 50th percentile (median), the 95th percentile, and the 99th percentile. Quantiles are optional, you can create a summary without quantiles if all you need is the count and the sum.
       
       {{< hint type=note >}}
       The terms "percentile" and "quantile" mean the same thing. We use percentile when we express it as a number in [0, 100], and we use quantile when we express it as a number in [0.0, 1.0].
       {{< /hint >}}
       
      -The second parameter to `quantile()` is the maximum acceptable error. The call `.quantile(0.5, 0.01)` means that the actual quantile is somewhere in [0.49, 0.51]. Higher presicion means higher memory usage.
      +The second parameter to `quantile()` is the maximum acceptable error. The call `.quantile(0.5, 0.01)` means that the actual quantile is somewhere in [0.49, 0.51]. Higher precision means higher memory usage.
       
       The 0.0 quantile (min value) and the 1.0 quantile (max value) are special cases because you can get the precise values (error 0.0) with almost no memory overhead.
       
       Quantile values are calculated based on a 5 minutes moving time window. The default time window can be changed with `maxAgeSeconds()` and `numberOfAgeBuckets()`.
       
      -Some options can be configured at runtime, see [config](/config/config).
      +Some options can be configured at runtime, see [config](../../config/config).
       
       In general you should prefer histograms over summaries. The Prometheus query language has a function [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for calculating quantiles from histograms. The advantage of query-time quantile calculation is that you can aggregate histograms before calculating the quantile. With summaries you must use the quantile with all its labels as it is.
       
      diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md
      index ec4423473..43e95c430 100644
      --- a/docs/content/getting-started/performance.md
      +++ b/docs/content/getting-started/performance.md
      @@ -26,7 +26,7 @@ You could increment the counter above like this:
       requestCount.labelValue("/", "200").inc();
       ```
       
      -However, the line above does not only increment the counter, it also lookus up the label values to find the right data point.
      +However, the line above does not only increment the counter, it also looks up the label values to find the right data point.
       
       In high performance applications you can optimize this by looking up the data point only once:
       
      @@ -49,7 +49,7 @@ While this default provides the flexibility to scrape different representations
       
       In performance critical applications we recommend to use either the classic representation or the native representation, but not both.
       
      -You can either configure this in code for each histogram by calling [classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) or [nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()), or you use the corresponding [config options](http://localhost:1313/config/config/).
      +You can either configure this in code for each histogram by calling [classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) or [nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()), or you use the corresponding [config options](../../config/config/).
       
       One way to do this is with system properties in the command line when you start your application
       
      diff --git a/docs/content/getting-started/registry.md b/docs/content/getting-started/registry.md
      index 403d834dd..7ae1bcbff 100644
      --- a/docs/content/getting-started/registry.md
      +++ b/docs/content/getting-started/registry.md
      @@ -34,7 +34,7 @@ Counter eventsTotal = Counter.builder()
       Registering a Metric with Multiple Registries
       ---------------------------------------------
       
      -As an alternative to calling `register()` direclty, you can `build()` metrics without registering them,
      +As an alternative to calling `register()` directly, you can `build()` metrics without registering them,
       and register them later:
       
       ```java
      diff --git a/docs/content/internals/model.md b/docs/content/internals/model.md
      index 1f222c3e4..e02517777 100644
      --- a/docs/content/internals/model.md
      +++ b/docs/content/internals/model.md
      @@ -21,7 +21,7 @@ The model is an internal library, implementing read-only immutable snapshots. Th
       
       There is no need for users to use `prometheus-metrics-model` directly. Users should use the API provided by `prometheus-metrics-core`, which includes the core metrics as well as callback metrics.
       
      -However, maintianers of 3rd party metrics libraries might want to use `prometheus-metrics-model` if they want to add Prometheus exposition formats to their metrics library.
      +However, maintainers of 3rd party metrics libraries might want to use `prometheus-metrics-model` if they want to add Prometheus exposition formats to their metrics library.
       
       exporters and exposition formats
       --------------------------------
      diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md
      index 5b1ee6a15..a954c9c04 100644
      --- a/docs/content/migration/simpleclient.md
      +++ b/docs/content/migration/simpleclient.md
      @@ -95,6 +95,6 @@ Counter counter = Counter.builder()
       counter.labelValues("/hello-world").inc();
       ```
       
      -Reasons why we changed the API: Changing the package names was a neccessity because the previous package names were incompatible with the Java module system. However, renaming packages requires chaning code anyway, so we decided to clean up some things. For example, the name `builder()` for a builder method is very common in the Java ecosystem, it's used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library more aligned with the broader Java ecosystem.
      +Reasons why we changed the API: Changing the package names was a necessity because the previous package names were incompatible with the Java module system. However, renaming packages requires changing code anyway, so we decided to clean up some things. For example, the name `builder()` for a builder method is very common in the Java ecosystem, it's used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library more aligned with the broader Java ecosystem.
       
       If you are using the low level `Collector` API directly, you should have a look at the new callback metric types, see [/getting-started/callbacks/](../../getting-started/callbacks/). Chances are good that the new callback metrics have an easier way to achieve what you need than the old 0.16.0 code.
      
      From bf6bc2c12a12ae481f9cca91fde446bdfd1967df Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Mon, 22 Jan 2024 13:49:45 +0100
      Subject: [PATCH 288/980] Fix flaky JVM Thread metrics test (#915)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../metrics/instrumentation/jvm/JvmThreadsMetricsTest.java   | 5 +++--
       1 file changed, 3 insertions(+), 2 deletions(-)
      
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      index 7be7892a9..94cadc268 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      @@ -108,8 +108,9 @@ public void testIgnoredMetricNotScraped() {
           @Test
           public void testInvalidThreadIds() {
               try {
      -            int javaVersion = Integer.parseInt(System.getProperty("java.version"));
      -            if (javaVersion >= 21) {
      +            String javaVersion = System.getProperty("java.version"); // Example: "21.0.2"
      +            String majorJavaVersion = javaVersion.replaceAll("\\..*", ""); // Example: "21"
      +            if (Integer.parseInt(majorJavaVersion) >= 21) {
                       // With Java 21 and newer you can no longer have invalid thread ids.
                       return;
                   }
      
      From e6edcabcccfe01645b1e19603a44add34259a9f0 Mon Sep 17 00:00:00 2001
      From: Kinshuk Bairagi 
      Date: Fri, 9 Feb 2024 19:24:59 +0530
      Subject: [PATCH 289/980] Support for Dropwizard Instrumentation with 1.0.0
       (#912)
      
      * Rename project simpleclient-archive/simpleclient_dropwizard to prometheus-metrics-instrumentation-dropwizard
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Implement DropwizardExports
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Label Changes Attempt 1
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Label Changes Attempt2
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Support for Custom Labels
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Minor Refactor
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Add builder for dwexports and change package name to dw5
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Rename package to dw5
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Rename to dropwizard5
      
      Signed-off-by: Kinshuk Bairagi 
      
      ---------
      
      Signed-off-by: Kinshuk Bairagi 
      ---
       pom.xml                                       |   1 +
       .../pom.xml                                   |  40 +-
       .../dropwizard5/DropwizardExports.java        | 221 +++++++++++
       .../dropwizard5/labels/CustomLabelMapper.java |  34 +-
       .../labels}/GraphiteNamePattern.java          |   4 +-
       .../dropwizard5/labels}/MapperConfig.java     |   2 +-
       .../dropwizard5/DropwizardExportsTest.java    | 255 +++++++++++++
       .../labels/CustomLabelMapperTest.java         | 210 +++++++++++
       .../labels}/GraphiteNamePatternTest.java      |   2 +-
       .../dropwizard5/labels}/MapperConfigTest.java |   3 +-
       .../version-rules.xml                         |   0
       .../client/dropwizard/DropwizardExports.java  | 201 ----------
       .../samplebuilder/DefaultSampleBuilder.java   |  29 --
       .../samplebuilder/SampleBuilder.java          |  23 --
       .../dropwizard/DropwizardExportsTest.java     | 352 ------------------
       .../CustomMappingSampleBuilderTest.java       | 182 ---------
       .../DefaultSampleBuilderTest.java             |  31 --
       17 files changed, 735 insertions(+), 855 deletions(-)
       rename {simpleclient-archive/simpleclient_dropwizard => prometheus-metrics-instrumentation-dropwizard5}/pom.xml (61%)
       create mode 100644 prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
       rename simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java => prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java (69%)
       rename {simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder => prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels}/GraphiteNamePattern.java (95%)
       rename {simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder => prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels}/MapperConfig.java (98%)
       create mode 100644 prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
       create mode 100644 prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
       rename {simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder => prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels}/GraphiteNamePatternTest.java (98%)
       rename {simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder => prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels}/MapperConfigTest.java (94%)
       rename {simpleclient-archive/simpleclient_dropwizard => prometheus-metrics-instrumentation-dropwizard5}/version-rules.xml (100%)
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java
       delete mode 100644 simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java
      
      diff --git a/pom.xml b/pom.xml
      index dd91272fd..145abe041 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -62,6 +62,7 @@
               prometheus-metrics-exporter-httpserver
               prometheus-metrics-exporter-opentelemetry
               prometheus-metrics-instrumentation-jvm
      +        prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
               
               examples
      diff --git a/simpleclient-archive/simpleclient_dropwizard/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      similarity index 61%
      rename from simpleclient-archive/simpleclient_dropwizard/pom.xml
      rename to prometheus-metrics-instrumentation-dropwizard5/pom.xml
      index 4366d9e15..eb07172f0 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      @@ -5,17 +5,21 @@
           
               io.prometheus
               client_java
      -        1.0.0-beta-2-SNAPSHOT
      +        1.2.0-SNAPSHOT
           
       
      -    simpleclient_dropwizard
      +    prometheus-metrics-instrumentation-dropwizard5
           bundle
       
      -    Prometheus Java Simpleclient Dropwizard
      +    Prometheus Metrics Instrumentation - Dropwizard 5.x
           
      -        Collector of data from Dropwizard metrics library.
      +        Instrumentation library for Dropwizard metrics 5.x
           
       
      +    
      +        io.prometheus.metrics.instrumentation.dropwizard5
      +    
      +
           
               
                   The Apache Software License, Version 2.0
      @@ -29,17 +33,25 @@
                   Francois Visconte
                   f.visconte@gmail.com
               
      +
      +        
      +            kingster
      +            Kinshuk Bairagi
      +            hi@kinsh.uk
      +        
      +
           
      +
           
               
                   io.prometheus
      -            simpleclient
      +            prometheus-metrics-core
                   ${project.version}
               
               
      -            io.dropwizard.metrics
      +            io.dropwizard.metrics5
                   metrics-core
      -            4.2.9
      +            5.0.0
                   provided
               
               
      @@ -61,6 +73,20 @@
                   4.6.1
                   test
               
      +
      +        
      +            io.prometheus
      +            prometheus-metrics-exporter-httpserver
      +            ${project.version}
      +            test
      +        
      +        
      +            io.prometheus
      +            prometheus-metrics-exposition-formats
      +            ${project.version}
      +            test
      +        
      +
           
       
       
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      new file mode 100644
      index 000000000..9748504a4
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      @@ -0,0 +1,221 @@
      +package io.prometheus.metrics.instrumentation.dropwizard5;
      +
      +import io.dropwizard.metrics5.Timer;
      +import io.dropwizard.metrics5.*;
      +import io.prometheus.metrics.instrumentation.dropwizard5.labels.CustomLabelMapper;
      +import io.prometheus.metrics.model.registry.MultiCollector;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +import io.prometheus.metrics.model.snapshots.*;
      +
      +import java.util.*;
      +import java.util.concurrent.TimeUnit;
      +import java.util.logging.Level;
      +import java.util.logging.Logger;
      +
      +/**
      + * Collect Dropwizard metrics from a MetricRegistry.
      + */
      +public class DropwizardExports implements MultiCollector {
      +    private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName());
      +    private final MetricRegistry registry;
      +    private final MetricFilter metricFilter;
      +    private final Optional labelMapper;
      +
      +    /**
      +     * Creates a new DropwizardExports and {@link MetricFilter#ALL}.
      +     *
      +     * @param registry a metric registry to export in prometheus.
      +     */
      +    DropwizardExports(MetricRegistry registry) {
      +        super();
      +        this.registry = registry;
      +        this.metricFilter = MetricFilter.ALL;
      +        this.labelMapper = Optional.empty();
      +    }
      +
      +    /**
      +     * Creates a new DropwizardExports with a custom {@link MetricFilter}.
      +     *
      +     * @param registry     a metric registry to export in prometheus.
      +     * @param metricFilter a custom metric filter.
      +     */
      +    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) {
      +        this.registry = registry;
      +        this.metricFilter = metricFilter;
      +        this.labelMapper = Optional.empty();
      +    }
      +
      +    /**
      +     * @param registry     a metric registry to export in prometheus.
      +     * @param metricFilter a custom metric filter.
      +     * @param labelMapper  a labelMapper to use to map labels.
      +     */
      +    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter, CustomLabelMapper labelMapper) {
      +        this.registry = registry;
      +        this.metricFilter = metricFilter;
      +        this.labelMapper = Optional.ofNullable(labelMapper);
      +    }
      +
      +    private static String getHelpMessage(String metricName, Metric metric) {
      +        return String.format("Generated from Dropwizard metric import (metric=%s, type=%s)",
      +                metricName, metric.getClass().getName());
      +    }
      +
      +
      +    private static MetricMetadata getMetricMetaData(String metricName, Metric metric) {
      +        return new MetricMetadata(PrometheusNaming.sanitizeMetricName(metricName), getHelpMessage(metricName, metric));
      +    }
      +
      +    /**
      +     * Export counter as Prometheus Gauge.
      +     */
      +    MetricSnapshot fromCounter(String dropwizardName, Counter counter) {
      +        MetricMetadata metadata = getMetricMetaData(dropwizardName, counter);
      +        CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(Long.valueOf(counter.getCount()).doubleValue());
      +        labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +        return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +    }
      +
      +    /**
      +     * Export gauge as a prometheus gauge.
      +     */
      +    MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) {
      +        Object obj = gauge.getValue();
      +        double value;
      +        if (obj instanceof Number) {
      +            value = ((Number) obj).doubleValue();
      +        } else if (obj instanceof Boolean) {
      +            value = ((Boolean) obj) ? 1 : 0;
      +        } else {
      +            LOGGER.log(Level.FINE, String.format("Invalid type for Gauge %s: %s", PrometheusNaming.sanitizeMetricName(dropwizardName),
      +                    obj == null ? "null" : obj.getClass().getName()));
      +            return null;
      +        }
      +        MetricMetadata metadata = getMetricMetaData(dropwizardName, gauge);
      +        GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder().value(value);
      +        labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +        return new GaugeSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +    }
      +
      +    /**
      +     * Export a histogram snapshot as a prometheus SUMMARY.
      +     *
      +     * @param dropwizardName metric name.
      +     * @param snapshot       the histogram snapshot.
      +     * @param count          the total sample count for this snapshot.
      +     * @param factor         a factor to apply to histogram values.
      +     */
      +    MetricSnapshot fromSnapshotAndCount(String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) {
      +        Quantiles quantiles = Quantiles.builder()
      +                .quantile(0.5, snapshot.getMedian() * factor)
      +                .quantile(0.75, snapshot.get75thPercentile() * factor)
      +                .quantile(0.95, snapshot.get95thPercentile() * factor)
      +                .quantile(0.98, snapshot.get98thPercentile() * factor)
      +                .quantile(0.99, snapshot.get99thPercentile() * factor)
      +                .quantile(0.999, snapshot.get999thPercentile() * factor)
      +                .build();
      +
      +        MetricMetadata metadata = new MetricMetadata(PrometheusNaming.sanitizeMetricName(dropwizardName), helpMessage);
      +        SummarySnapshot.SummaryDataPointSnapshot.Builder dataPointBuilder = SummarySnapshot.SummaryDataPointSnapshot.builder().quantiles(quantiles).count(count);
      +        labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +        return new SummarySnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +    }
      +
      +    /**
      +     * Convert histogram snapshot.
      +     */
      +    MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) {
      +        return fromSnapshotAndCount(dropwizardName, histogram.getSnapshot(), histogram.getCount(), 1.0,
      +                getHelpMessage(dropwizardName, histogram));
      +    }
      +
      +    /**
      +     * Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit.
      +     */
      +    MetricSnapshot fromTimer(String dropwizardName, Timer timer) {
      +        return fromSnapshotAndCount(dropwizardName, timer.getSnapshot(), timer.getCount(),
      +                1.0D / TimeUnit.SECONDS.toNanos(1L), getHelpMessage(dropwizardName, timer));
      +    }
      +
      +    /**
      +     * Export a Meter as a prometheus COUNTER.
      +     */
      +    MetricSnapshot fromMeter(String dropwizardName, Meter meter) {
      +        MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter);
      +        CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount());
      +        labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +        return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +    }
      +
      +    @Override
      +    public MetricSnapshots collect() {
      +        MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder();
      +        for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) {
      +            Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue())).map(metricSnapshots::metricSnapshot);
      +        }
      +        for (SortedMap.Entry entry : registry.getCounters(metricFilter).entrySet()) {
      +            metricSnapshots.metricSnapshot(fromCounter(entry.getKey().getKey(), entry.getValue()));
      +        }
      +        for (SortedMap.Entry entry : registry.getHistograms(metricFilter).entrySet()) {
      +            metricSnapshots.metricSnapshot(fromHistogram(entry.getKey().getKey(), entry.getValue()));
      +        }
      +        for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) {
      +            metricSnapshots.metricSnapshot(fromTimer(entry.getKey().getKey(), entry.getValue()));
      +        }
      +        for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) {
      +            metricSnapshots.metricSnapshot(fromMeter(entry.getKey().getKey(), entry.getValue()));
      +        }
      +        return metricSnapshots.build();
      +    }
      +
      +    public static Builder builder() {
      +        return new Builder();
      +    }
      +
      +    //Builder class for DropwizardExports
      +    public static class Builder {
      +        private MetricRegistry registry;
      +        private MetricFilter metricFilter;
      +        private CustomLabelMapper labelMapper;
      +
      +        private Builder() {
      +            this.metricFilter = MetricFilter.ALL;
      +        }
      +
      +        public Builder dropwizardRegistry(MetricRegistry registry) {
      +            this.registry = registry;
      +            return this;
      +        }
      +
      +        public Builder metricFilter(MetricFilter metricFilter) {
      +            this.metricFilter = metricFilter;
      +            return this;
      +        }
      +
      +        public Builder customLabelMapper(CustomLabelMapper labelMapper) {
      +            this.labelMapper = labelMapper;
      +            return this;
      +        }
      +
      +        DropwizardExports build() {
      +            if (registry == null) {
      +                throw new IllegalArgumentException("MetricRegistry must be set");
      +            }
      +            if (labelMapper == null) {
      +                return new DropwizardExports(registry, metricFilter);
      +            } else {
      +                return new DropwizardExports(registry, metricFilter, labelMapper);
      +            }
      +        }
      +
      +        public void register() {
      +            register(PrometheusRegistry.defaultRegistry);
      +        }
      +
      +        public void register(PrometheusRegistry registry) {
      +            DropwizardExports dropwizardExports = build();
      +            registry.register(dropwizardExports);
      +        }
      +    }
      +
      +}
      \ No newline at end of file
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      similarity index 69%
      rename from simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java
      rename to prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      index 30435b7ce..1739f6fa6 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilder.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      @@ -1,25 +1,22 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
       
      -import io.prometheus.client.Collector;
      +import io.prometheus.metrics.model.snapshots.Labels;
       
       import java.util.ArrayList;
      -import java.util.Collections;
       import java.util.List;
       import java.util.Map;
       
       /**
      - * Custom {@link SampleBuilder} implementation to allow Dropwizard metrics to be translated to Prometheus metrics including custom labels and names.
      + * A LabelMapper to allow Dropwizard metrics to be translated to Prometheus metrics including custom labels and names.
        * Prometheus metric name and labels are extracted from the Dropwizard name based on the provided list of {@link MapperConfig}s.
        * The FIRST matching config will be used.
      - * If no config is matched, the {@link DefaultSampleBuilder} is used.
        */
      -public class CustomMappingSampleBuilder implements SampleBuilder {
      +public class CustomLabelMapper  {
           private final List compiledMapperConfigs;
      -    private final DefaultSampleBuilder defaultMetricSampleBuilder = new DefaultSampleBuilder();
       
      -    public CustomMappingSampleBuilder(final List mapperConfigs) {
      +    public CustomLabelMapper(final List mapperConfigs) {
               if (mapperConfigs == null || mapperConfigs.isEmpty()) {
      -            throw new IllegalArgumentException("CustomMappingSampleBuilder needs some mapper configs!");
      +            throw new IllegalArgumentException("CustomLabelMapper needs some mapper configs!");
               }
       
               this.compiledMapperConfigs = new ArrayList(mapperConfigs.size());
      @@ -28,8 +25,8 @@ public CustomMappingSampleBuilder(final List mapperConfigs) {
               }
           }
       
      -    @Override
      -    public Collector.MetricFamilySamples.Sample createSample(final String dropwizardName, final String nameSuffix, final List additionalLabelNames, final List additionalLabelValues, final double value) {
      +
      +    public Labels getLabels(final String dropwizardName, final List additionalLabelNames, final List additionalLabelValues){
               if (dropwizardName == null) {
                   throw new IllegalArgumentException("Dropwizard metric name cannot be null");
               }
      @@ -47,21 +44,10 @@ public Collector.MetricFamilySamples.Sample createSample(final String dropwizard
                   final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params);
                   nameAndLabels.labelNames.addAll(additionalLabelNames);
                   nameAndLabels.labelValues.addAll(additionalLabelValues);
      -            return defaultMetricSampleBuilder.createSample(
      -                    nameAndLabels.name, nameSuffix,
      -                    nameAndLabels.labelNames,
      -                    nameAndLabels.labelValues,
      -                    value
      -            );
      +            return Labels.of(nameAndLabels.labelNames, nameAndLabels.labelValues);
               }
       
      -
      -        return defaultMetricSampleBuilder.createSample(
      -                dropwizardName, nameSuffix,
      -                additionalLabelNames,
      -                additionalLabelValues,
      -                value
      -        );
      +        return Labels.of(additionalLabelNames, additionalLabelValues);
           }
       
           protected NameAndLabels getNameAndLabels(final MapperConfig config, final Map parameters) {
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java
      similarity index 95%
      rename from simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java
      rename to prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java
      index 45767e3fc..4823c736f 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePattern.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java
      @@ -1,11 +1,11 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
       
       import java.util.HashMap;
       import java.util.Map;
       import java.util.regex.Matcher;
       import java.util.regex.Pattern;
       
      -import static io.prometheus.client.dropwizard.samplebuilder.MapperConfig.METRIC_GLOB_REGEX;
      +import static io.prometheus.metrics.instrumentation.dropwizard5.labels.MapperConfig.METRIC_GLOB_REGEX;
       
       /**
        * GraphiteNamePattern is initialised with a simplified glob pattern that only allows '*' as special character.
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java
      similarity index 98%
      rename from simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java
      rename to prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java
      index 887226635..c1eb1ae08 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfig.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
       
       import java.util.HashMap;
       import java.util.Map;
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
      new file mode 100644
      index 000000000..ae27ce62c
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
      @@ -0,0 +1,255 @@
      +package io.prometheus.metrics.instrumentation.dropwizard5;
      +
      +import io.dropwizard.metrics5.*;
      +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      +import io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExports;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      +import org.junit.Before;
      +import org.junit.Test;
      +
      +import java.io.ByteArrayOutputStream;
      +import java.io.IOException;
      +import java.nio.charset.StandardCharsets;
      +import java.util.concurrent.TimeUnit;
      +
      +import static org.junit.Assert.assertEquals;
      +import static org.junit.Assert.assertTrue;
      +
      +
      +public class DropwizardExportsTest {
      +
      +    private PrometheusRegistry registry = new PrometheusRegistry();
      +    private MetricRegistry metricRegistry;
      +
      +
      +    @Before
      +    public void setUp() {
      +        metricRegistry = new MetricRegistry();
      +        DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(registry);
      +    }
      +
      +
      +    @Test
      +    public void testCounter()  {
      +        metricRegistry.counter("foo.bar").inc(1);
      +        String expected = "# TYPE foo_bar counter\n" +
      +                "# HELP foo_bar Generated from Dropwizard metric import (metric=foo.bar, type=io.dropwizard.metrics5.Counter)\n" +
      +                "foo_bar_total 1.0\n" +
      +                "# EOF\n";
      +
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +    }
      +
      +    @Test
      +    public void testGauge()  {
      +        Gauge integerGauge = new Gauge() {
      +            @Override
      +            public Integer getValue() {
      +                return 1234;
      +            }
      +        };
      +        Gauge doubleGauge = new Gauge() {
      +            @Override
      +            public Double getValue() {
      +                return 1.234D;
      +            }
      +        };
      +        Gauge longGauge = new Gauge() {
      +            @Override
      +            public Long getValue() {
      +                return 1234L;
      +            }
      +        };
      +        Gauge floatGauge = new Gauge() {
      +            @Override
      +            public Float getValue() {
      +                return 0.1234F;
      +            }
      +        };
      +        Gauge booleanGauge = new Gauge() {
      +            @Override
      +            public Boolean getValue() {
      +                return true;
      +            }
      +        };
      +
      +        metricRegistry.register("double.gauge", doubleGauge);
      +        metricRegistry.register("long.gauge", longGauge);
      +        metricRegistry.register("integer.gauge", integerGauge);
      +        metricRegistry.register("float.gauge", floatGauge);
      +        metricRegistry.register("boolean.gauge", booleanGauge);
      +
      +        String expected = "# TYPE boolean_gauge gauge\n" +
      +                "# HELP boolean_gauge Generated from Dropwizard metric import (metric=boolean.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$5)\n" +
      +                "boolean_gauge 1.0\n" +
      +                "# TYPE double_gauge gauge\n" +
      +                "# HELP double_gauge Generated from Dropwizard metric import (metric=double.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$2)\n" +
      +                "double_gauge 1.234\n" +
      +                "# TYPE float_gauge gauge\n" +
      +                "# HELP float_gauge Generated from Dropwizard metric import (metric=float.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$4)\n" +
      +                "float_gauge 0.1234000027179718\n" +
      +                "# TYPE integer_gauge gauge\n" +
      +                "# HELP integer_gauge Generated from Dropwizard metric import (metric=integer.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$1)\n" +
      +                "integer_gauge 1234.0\n" +
      +                "# TYPE long_gauge gauge\n" +
      +                "# HELP long_gauge Generated from Dropwizard metric import (metric=long.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$3)\n" +
      +                "long_gauge 1234.0\n" +
      +                "# EOF\n";
      +
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +    }
      +
      +    @Test
      +    public void testInvalidGaugeType()  {
      +        Gauge invalidGauge = new Gauge() {
      +            @Override
      +            public String getValue() {
      +                return "foobar";
      +            }
      +        };
      +
      +        metricRegistry.register("invalid_gauge", invalidGauge);
      +
      +        String expected = "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +    }
      +
      +    @Test
      +    public void testGaugeReturningNullValue() {
      +        Gauge invalidGauge = new Gauge() {
      +            @Override
      +            public String getValue() {
      +                return null;
      +            }
      +        };
      +        metricRegistry.register("invalid_gauge", invalidGauge);
      +        String expected = "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +    }
      +
      +    @Test
      +    public void testHistogram() throws IOException {
      +        // just test the standard mapper
      +        final MetricRegistry metricRegistry = new MetricRegistry();
      +        PrometheusRegistry pmRegistry = new PrometheusRegistry();
      +        DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(pmRegistry);
      +
      +        Histogram hist = metricRegistry.histogram("hist");
      +        int i = 0;
      +        while (i < 100) {
      +            hist.update(i);
      +            i += 1;
      +        }
      +
      +        String expected = "# TYPE hist summary\n" +
      +                "# HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)\n" +
      +                "hist{quantile=\"0.5\"} 49.0\n" +
      +                "hist{quantile=\"0.75\"} 74.0\n" +
      +                "hist{quantile=\"0.95\"} 94.0\n" +
      +                "hist{quantile=\"0.98\"} 97.0\n" +
      +                "hist{quantile=\"0.99\"} 98.0\n" +
      +                "hist{quantile=\"0.999\"} 99.0\n" +
      +                "hist_count 100\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(pmRegistry));
      +    }
      +
      +    @Test
      +    public void testMeter()  {
      +        Meter meter = metricRegistry.meter("meter");
      +        meter.mark();
      +        meter.mark();
      +
      +        String expected = "# TYPE meter counter\n" +
      +                "# HELP meter Generated from Dropwizard metric import (metric=meter_total, type=io.dropwizard.metrics5.Meter)\n" +
      +                "meter_total 2.0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +
      +    }
      +
      +    @Test
      +    public void testTimer() throws InterruptedException {
      +        final MetricRegistry metricRegistry = new MetricRegistry();
      +        DropwizardExports exports = new DropwizardExports(metricRegistry);
      +        Timer t = metricRegistry.timer("timer");
      +        Timer.Context time = t.time();
      +        Thread.sleep(100L);
      +        long timeSpentNanos = time.stop();
      +        double timeSpentMillis = TimeUnit.NANOSECONDS.toMillis(timeSpentNanos);
      +        System.out.println(timeSpentMillis);
      +
      +        SummarySnapshot.SummaryDataPointSnapshot dataPointSnapshot = (SummarySnapshot.SummaryDataPointSnapshot) exports.collect().stream().flatMap(i -> i.getDataPoints().stream()).findFirst().get();
      +        // We slept for 1Ms so we ensure that all timers are above 1ms:
      +        assertTrue(dataPointSnapshot.getQuantiles().size() > 1);
      +        dataPointSnapshot.getQuantiles().forEach( i-> {
      +            System.out.println(i.getQuantile() + " : " + i.getValue());
      +            assertTrue(i.getValue() > timeSpentMillis/1000d);
      +        });
      +        assertEquals(1, dataPointSnapshot.getCount());
      +    }
      +
      +    @Test
      +    public void testThatMetricHelpUsesOriginalDropwizardName() {
      +
      +        metricRegistry.timer("my.application.namedTimer1");
      +        metricRegistry.counter("my.application.namedCounter1");
      +        metricRegistry.meter("my.application.namedMeter1");
      +        metricRegistry.histogram("my.application.namedHistogram1");
      +        metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge());
      +
      +        String expected  = "# TYPE my_application_namedCounter1 counter\n" +
      +                "# HELP my_application_namedCounter1 Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=io.dropwizard.metrics5.Counter)\n" +
      +                "my_application_namedCounter1_total 0.0\n" +
      +                "# TYPE my_application_namedGauge1 gauge\n" +
      +                "# HELP my_application_namedGauge1 Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$ExampleDoubleGauge)\n" +
      +                "my_application_namedGauge1 0.0\n" +
      +                "# TYPE my_application_namedHistogram1 summary\n" +
      +                "# HELP my_application_namedHistogram1 Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=io.dropwizard.metrics5.Histogram)\n" +
      +                "my_application_namedHistogram1{quantile=\"0.5\"} 0.0\n" +
      +                "my_application_namedHistogram1{quantile=\"0.75\"} 0.0\n" +
      +                "my_application_namedHistogram1{quantile=\"0.95\"} 0.0\n" +
      +                "my_application_namedHistogram1{quantile=\"0.98\"} 0.0\n" +
      +                "my_application_namedHistogram1{quantile=\"0.99\"} 0.0\n" +
      +                "my_application_namedHistogram1{quantile=\"0.999\"} 0.0\n" +
      +                "my_application_namedHistogram1_count 0\n" +
      +                "# TYPE my_application_namedMeter1 counter\n" +
      +                "# HELP my_application_namedMeter1 Generated from Dropwizard metric import (metric=my.application.namedMeter1_total, type=io.dropwizard.metrics5.Meter)\n" +
      +                "my_application_namedMeter1_total 0.0\n" +
      +                "# TYPE my_application_namedTimer1 summary\n" +
      +                "# HELP my_application_namedTimer1 Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=io.dropwizard.metrics5.Timer)\n" +
      +                "my_application_namedTimer1{quantile=\"0.5\"} 0.0\n" +
      +                "my_application_namedTimer1{quantile=\"0.75\"} 0.0\n" +
      +                "my_application_namedTimer1{quantile=\"0.95\"} 0.0\n" +
      +                "my_application_namedTimer1{quantile=\"0.98\"} 0.0\n" +
      +                "my_application_namedTimer1{quantile=\"0.99\"} 0.0\n" +
      +                "my_application_namedTimer1{quantile=\"0.999\"} 0.0\n" +
      +                "my_application_namedTimer1_count 0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat());
      +    }
      +
      +
      +    private static class ExampleDoubleGauge implements Gauge {
      +        @Override
      +        public Double getValue() {
      +            return 0.0;
      +        }
      +    }
      +
      +    private String convertToOpenMetricsFormat(PrometheusRegistry _registry)  {
      +        ByteArrayOutputStream out = new ByteArrayOutputStream();
      +        OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true);
      +        try {
      +            writer.write(out, _registry.scrape());
      +            return out.toString(StandardCharsets.UTF_8.name());
      +        } catch (IOException e) {
      +            throw new RuntimeException(e);
      +        }
      +    }
      +
      +    private String convertToOpenMetricsFormat() {
      +        return convertToOpenMetricsFormat(registry);
      +    }
      +}
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
      new file mode 100644
      index 000000000..e6bbdbed8
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
      @@ -0,0 +1,210 @@
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
      +
      +import io.dropwizard.metrics5.MetricFilter;
      +import io.dropwizard.metrics5.MetricRegistry;
      +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      +import io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExports;
      +import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      +import org.junit.Before;
      +import org.junit.Test;
      +
      +import java.io.ByteArrayOutputStream;
      +import java.io.IOException;
      +import java.nio.charset.StandardCharsets;
      +import java.util.*;
      +
      +import static org.junit.Assert.assertEquals;
      +
      +public class CustomLabelMapperTest {
      +    private MetricRegistry metricRegistry;
      +
      +
      +    @Before
      +    public void setUp() {
      +        metricRegistry = new MetricRegistry();
      +    }
      +
      +    @Test(expected = IllegalArgumentException.class)
      +    public void test_WHEN_EmptyConfig_THEN_Fail() {
      +        final CustomLabelMapper converter = new CustomLabelMapper(Collections.emptyList());
      +    }
      +
      +    @Test
      +    public void test_WHEN_NoMatches_THEN_ShouldReturnDefaultSample() {
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                new MapperConfig("*.client-nope.*.*.*"),
      +                new MapperConfig("not.even.this.*.*.*")
      +        );
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper);
      +
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.service.total").inc(1);
      +        System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect()));
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_service counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_service Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.service.total, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_service_total 1.0\n" +
      +                "# EOF\n";
      +
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +    }
      +
      +    @Test
      +    public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() {
      +        final Map labels = new HashMap();
      +        labels.put("service", "${0}");
      +        final MapperConfig mapperConfig = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.total",
      +                "app.okhttpclient.client.HttpClient.total",
      +                labels
      +        );
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                mapperConfig,
      +                new MapperConfig("not.even.this.*.*.*")
      +        );
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper);
      +
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1);
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService\"} 1.0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +    }
      +
      +    @Test
      +    public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() {
      +        final Map labels = new HashMap();
      +        labels.put("service", "${0}");
      +        final MapperConfig mapperConfig = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.total",
      +                "app.okhttpclient.client.HttpClient.total",
      +                labels
      +        );
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                mapperConfig,
      +                new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well
      +        );
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper);
      +
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1);
      +
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService\"} 1.0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +    }
      +
      +    @Test
      +    public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() {
      +        final Map labels = new LinkedHashMap();
      +        labels.put("service", "${0}");
      +        labels.put("status", "${1}");
      +        final MapperConfig mapperConfig = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.*",
      +                "app.okhttpclient.client.HttpClient",
      +                labels
      +        );
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                mapperConfig,
      +                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +        );
      +
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper);
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1);
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400_total{service=\"greatService\",status=\"400\"} 1.0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +
      +    }
      +
      +    @Test
      +    public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() {
      +        final Map labels = new LinkedHashMap();
      +        labels.put("service", "${0}_${1}");
      +        labels.put("status", "s_${1}");
      +        final MapperConfig mapperConfig = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.*",
      +                "app.okhttpclient.client.HttpClient.${0}",
      +                labels
      +        );
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                mapperConfig,
      +                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +        );
      +
      +
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry,MetricFilter.ALL,  labelMapper);
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1);
      +        System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect()));
      +
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +    }
      +
      +
      +    @Test
      +    public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() {
      +        final Map labels = new LinkedHashMap();
      +        labels.put("service", "${0}");
      +        labels.put("status", "s_${1}");
      +        final MapperConfig mapperConfig = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.*",
      +                "app.okhttpclient.client.HttpClient.${0}",
      +                labels
      +        );
      +        final List mapperConfigs = Arrays.asList(
      +                new MapperConfig("client-nope.*.*.*"),
      +                mapperConfig,
      +                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +        );
      +
      +        final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
      +        DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry,MetricFilter.ALL,  labelMapper);
      +        metricRegistry.histogram("app.okhttpclient.client.HttpClient.greatService.400");
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 summary\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Histogram)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.5\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.75\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.95\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.98\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.99\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.999\"} 0.0\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_400_count{service=\"greatService\",status=\"s_400\"} 0\n" +
      +                "# EOF\n";
      +        assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
      +    }
      +
      +
      +    private String convertToOpenMetricsFormat(MetricSnapshots snapshots)  {
      +        ByteArrayOutputStream out = new ByteArrayOutputStream();
      +        OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true);
      +        try {
      +            writer.write(out, snapshots);
      +            return out.toString(StandardCharsets.UTF_8.name());
      +        } catch (IOException e) {
      +            throw new RuntimeException(e);
      +        }
      +    }
      +
      +}
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java
      similarity index 98%
      rename from simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java
      rename to prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java
      index 8b95e8e3e..5b704e6bd 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/GraphiteNamePatternTest.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
       
       import org.assertj.core.api.Assertions;
       import org.junit.Test;
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java
      similarity index 94%
      rename from simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java
      rename to prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java
      index e0ded6978..03d244b89 100644
      --- a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/MapperConfigTest.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java
      @@ -1,6 +1,5 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      +package io.prometheus.metrics.instrumentation.dropwizard5.labels;
       
      -import io.prometheus.client.dropwizard.samplebuilder.MapperConfig;
       import org.junit.Test;
       
       import java.util.Collections;
      diff --git a/simpleclient-archive/simpleclient_dropwizard/version-rules.xml b/prometheus-metrics-instrumentation-dropwizard5/version-rules.xml
      similarity index 100%
      rename from simpleclient-archive/simpleclient_dropwizard/version-rules.xml
      rename to prometheus-metrics-instrumentation-dropwizard5/version-rules.xml
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
      deleted file mode 100644
      index 4bf89899f..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/DropwizardExports.java
      +++ /dev/null
      @@ -1,201 +0,0 @@
      -package io.prometheus.client.dropwizard;
      -
      -import com.codahale.metrics.Counter;
      -import com.codahale.metrics.Gauge;
      -import com.codahale.metrics.Histogram;
      -import com.codahale.metrics.Meter;
      -import com.codahale.metrics.Metric;
      -import com.codahale.metrics.MetricFilter;
      -import com.codahale.metrics.MetricRegistry;
      -import com.codahale.metrics.Snapshot;
      -import com.codahale.metrics.Timer;
      -import io.prometheus.client.dropwizard.samplebuilder.SampleBuilder;
      -import io.prometheus.client.dropwizard.samplebuilder.DefaultSampleBuilder;
      -
      -import java.util.ArrayList;
      -import java.util.Arrays;
      -import java.util.HashMap;
      -import java.util.List;
      -import java.util.Map;
      -import java.util.SortedMap;
      -import java.util.concurrent.TimeUnit;
      -import java.util.logging.Level;
      -import java.util.logging.Logger;
      -
      -/**
      - * Collect Dropwizard metrics from a MetricRegistry.
      - */
      -public class DropwizardExports extends io.prometheus.client.Collector implements io.prometheus.client.Collector.Describable {
      -    private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName());
      -    private MetricRegistry registry;
      -    private MetricFilter metricFilter;
      -    private SampleBuilder sampleBuilder;
      -
      -    /**
      -     * Creates a new DropwizardExports with a {@link DefaultSampleBuilder} and {@link MetricFilter#ALL}.
      -     *
      -     * @param registry a metric registry to export in prometheus.
      -     */
      -    public DropwizardExports(MetricRegistry registry) {
      -        this.registry = registry;
      -        this.metricFilter = MetricFilter.ALL;
      -        this.sampleBuilder = new DefaultSampleBuilder();
      -    }
      -
      -    /**
      -     * Creates a new DropwizardExports with a {@link DefaultSampleBuilder} and custom {@link MetricFilter}.
      -     *
      -     * @param registry     a metric registry to export in prometheus.
      -     * @param metricFilter a custom metric filter.
      -     */
      -    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) {
      -        this.registry = registry;
      -        this.metricFilter = metricFilter;
      -        this.sampleBuilder = new DefaultSampleBuilder();
      -    }
      -
      -    /**
      -     * @param registry      a metric registry to export in prometheus.
      -     * @param sampleBuilder sampleBuilder to use to create prometheus samples.
      -     */
      -    public DropwizardExports(MetricRegistry registry, SampleBuilder sampleBuilder) {
      -        this.registry = registry;
      -        this.metricFilter = MetricFilter.ALL;
      -        this.sampleBuilder = sampleBuilder;
      -    }
      -
      -    /**
      -     * @param registry      a metric registry to export in prometheus.
      -     * @param metricFilter  a custom metric filter.
      -     * @param sampleBuilder sampleBuilder to use to create prometheus samples.
      -     */
      -    public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter, SampleBuilder sampleBuilder) {
      -        this.registry = registry;
      -        this.metricFilter = metricFilter;
      -        this.sampleBuilder = sampleBuilder;
      -    }
      -
      -    private static String getHelpMessage(String metricName, Metric metric) {
      -        return String.format("Generated from Dropwizard metric import (metric=%s, type=%s)",
      -                metricName, metric.getClass().getName());
      -    }
      -
      -    /**
      -     * Export counter as Prometheus Gauge.
      -     */
      -    MetricFamilySamples fromCounter(String dropwizardName, Counter counter) {
      -        MetricFamilySamples.Sample sample = sampleBuilder.createSample(dropwizardName, "", new ArrayList(), new ArrayList(),
      -                new Long(counter.getCount()).doubleValue());
      -        return new MetricFamilySamples(sample.name, Type.GAUGE, getHelpMessage(dropwizardName, counter), Arrays.asList(sample));
      -    }
      -
      -    /**
      -     * Export gauge as a prometheus gauge.
      -     */
      -    MetricFamilySamples fromGauge(String dropwizardName, Gauge gauge) {
      -        Object obj = gauge.getValue();
      -        double value;
      -        if (obj instanceof Number) {
      -            value = ((Number) obj).doubleValue();
      -        } else if (obj instanceof Boolean) {
      -            value = ((Boolean) obj) ? 1 : 0;
      -        } else {
      -            LOGGER.log(Level.FINE, String.format("Invalid type for Gauge %s: %s", sanitizeMetricName(dropwizardName),
      -                    obj == null ? "null" : obj.getClass().getName()));
      -            return null;
      -        }
      -        MetricFamilySamples.Sample sample = sampleBuilder.createSample(dropwizardName, "",
      -                new ArrayList(), new ArrayList(), value);
      -        return new MetricFamilySamples(sample.name, Type.GAUGE, getHelpMessage(dropwizardName, gauge), Arrays.asList(sample));
      -    }
      -
      -    /**
      -     * Export a histogram snapshot as a prometheus SUMMARY.
      -     *
      -     * @param dropwizardName metric name.
      -     * @param snapshot       the histogram snapshot.
      -     * @param count          the total sample count for this snapshot.
      -     * @param factor         a factor to apply to histogram values.
      -     */
      -    MetricFamilySamples fromSnapshotAndCount(String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) {
      -        List samples = Arrays.asList(
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.5"), snapshot.getMedian() * factor),
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.75"), snapshot.get75thPercentile() * factor),
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.95"), snapshot.get95thPercentile() * factor),
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.98"), snapshot.get98thPercentile() * factor),
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.99"), snapshot.get99thPercentile() * factor),
      -                sampleBuilder.createSample(dropwizardName, "", Arrays.asList("quantile"), Arrays.asList("0.999"), snapshot.get999thPercentile() * factor),
      -                sampleBuilder.createSample(dropwizardName, "_count", new ArrayList(), new ArrayList(), count)
      -        );
      -        return new MetricFamilySamples(samples.get(0).name, Type.SUMMARY, helpMessage, samples);
      -    }
      -
      -    /**
      -     * Convert histogram snapshot.
      -     */
      -    MetricFamilySamples fromHistogram(String dropwizardName, Histogram histogram) {
      -        return fromSnapshotAndCount(dropwizardName, histogram.getSnapshot(), histogram.getCount(), 1.0,
      -                getHelpMessage(dropwizardName, histogram));
      -    }
      -
      -    /**
      -     * Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit.
      -     */
      -    MetricFamilySamples fromTimer(String dropwizardName, Timer timer) {
      -        return fromSnapshotAndCount(dropwizardName, timer.getSnapshot(), timer.getCount(),
      -                1.0D / TimeUnit.SECONDS.toNanos(1L), getHelpMessage(dropwizardName, timer));
      -    }
      -
      -    /**
      -     * Export a Meter as as prometheus COUNTER.
      -     */
      -    MetricFamilySamples fromMeter(String dropwizardName, Meter meter) {
      -        final MetricFamilySamples.Sample sample = sampleBuilder.createSample(dropwizardName, "_total",
      -                new ArrayList(),
      -                new ArrayList(),
      -                meter.getCount());
      -        return new MetricFamilySamples(sample.name, Type.COUNTER, getHelpMessage(dropwizardName, meter),
      -                        Arrays.asList(sample));
      -    }
      -
      -    @Override
      -    public List collect() {
      -        Map mfSamplesMap = new HashMap();
      -
      -        for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) {
      -            addToMap(mfSamplesMap, fromGauge(entry.getKey(), entry.getValue()));
      -        }
      -        for (SortedMap.Entry entry : registry.getCounters(metricFilter).entrySet()) {
      -            addToMap(mfSamplesMap, fromCounter(entry.getKey(), entry.getValue()));
      -        }
      -        for (SortedMap.Entry entry : registry.getHistograms(metricFilter).entrySet()) {
      -            addToMap(mfSamplesMap, fromHistogram(entry.getKey(), entry.getValue()));
      -        }
      -        for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) {
      -            addToMap(mfSamplesMap, fromTimer(entry.getKey(), entry.getValue()));
      -        }
      -        for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) {
      -            addToMap(mfSamplesMap, fromMeter(entry.getKey(), entry.getValue()));
      -        }
      -        return new ArrayList(mfSamplesMap.values());
      -    }
      -
      -    private void addToMap(Map mfSamplesMap, MetricFamilySamples newMfSamples)
      -    {
      -        if (newMfSamples != null) {
      -            MetricFamilySamples currentMfSamples = mfSamplesMap.get(newMfSamples.name);
      -            if (currentMfSamples == null) {
      -                mfSamplesMap.put(newMfSamples.name, newMfSamples);
      -            } else {
      -                List samples = new ArrayList(currentMfSamples.samples);
      -                samples.addAll(newMfSamples.samples);
      -                mfSamplesMap.put(newMfSamples.name, new MetricFamilySamples(newMfSamples.name, currentMfSamples.type, currentMfSamples.help, samples));
      -            }
      -        }
      -    }
      -
      -    @Override
      -    public List describe() {
      -        return new ArrayList();
      -    }
      -}
      \ No newline at end of file
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java
      deleted file mode 100644
      index 230edb4a7..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilder.java
      +++ /dev/null
      @@ -1,29 +0,0 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      -
      -import io.prometheus.client.Collector;
      -
      -import java.util.ArrayList;
      -import java.util.Collections;
      -import java.util.List;
      -
      -
      -/**
      - * Default implementation of {@link SampleBuilder}.
      - * Sanitises the metric name if necessary.
      - *
      - * @see io.prometheus.client.Collector#sanitizeMetricName(String)
      - */
      -public class DefaultSampleBuilder implements SampleBuilder {
      -    @Override
      -    public Collector.MetricFamilySamples.Sample createSample(final String dropwizardName, final String nameSuffix, final List additionalLabelNames, final List additionalLabelValues, final double value) {
      -        final String suffix = nameSuffix == null ? "" : nameSuffix;
      -        final List labelNames = additionalLabelNames == null ? Collections.emptyList() : additionalLabelNames;
      -        final List labelValues = additionalLabelValues == null ? Collections.emptyList() : additionalLabelValues;
      -        return new Collector.MetricFamilySamples.Sample(
      -                Collector.sanitizeMetricName(dropwizardName + suffix),
      -                new ArrayList(labelNames),
      -                new ArrayList(labelValues),
      -                value
      -        );
      -    }
      -}
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java b/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java
      deleted file mode 100644
      index eb570fd6a..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/main/java/io/prometheus/client/dropwizard/samplebuilder/SampleBuilder.java
      +++ /dev/null
      @@ -1,23 +0,0 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      -
      -import io.prometheus.client.Collector;
      -
      -import java.util.List;
      -
      -/**
      - * SampleBuilder defines the action of creating a {@link io.prometheus.client.Collector.MetricFamilySamples.Sample} for the given parameters.
      - */
      -public interface SampleBuilder {
      -
      -    /**
      -     * Creates a new {@link io.prometheus.client.Collector.MetricFamilySamples.Sample} for the given parameters.
      -     *
      -     * @param dropwizardName        Metric name coming from Dropwizard.
      -     * @param nameSuffix            Optional suffix to add.
      -     * @param additionalLabelNames  Optional additional label names. Needs to have same size as additionalLabelValues.
      -     * @param additionalLabelValues Optional additional label values. Needs to have same size as additionalLabelNames.
      -     * @param value                 Metric value
      -     * @return A new {@link io.prometheus.client.Collector.MetricFamilySamples.Sample}.
      -     */
      -    Collector.MetricFamilySamples.Sample createSample(String dropwizardName, String nameSuffix, List additionalLabelNames, List additionalLabelValues, double value);
      -}
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
      deleted file mode 100644
      index 33a031b54..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/DropwizardExportsTest.java
      +++ /dev/null
      @@ -1,352 +0,0 @@
      -package io.prometheus.client.dropwizard;
      -
      -import com.codahale.metrics.*;
      -import com.codahale.metrics.Timer;
      -import io.prometheus.client.Collector;
      -import io.prometheus.client.CollectorRegistry;
      -import io.prometheus.client.dropwizard.samplebuilder.SampleBuilder;
      -import org.junit.Before;
      -import org.junit.Test;
      -import org.mockito.Mockito;
      -
      -import java.io.IOException;
      -import java.util.Arrays;
      -import java.util.Collections;
      -import java.util.Enumeration;
      -import java.util.HashMap;
      -import java.util.Map;
      -
      -import static org.hamcrest.CoreMatchers.is;
      -import static org.junit.Assert.assertEquals;
      -import static org.junit.Assert.assertNotEquals;
      -import static org.junit.Assert.assertNotNull;
      -import static org.junit.Assert.assertThat;
      -import static org.junit.Assert.assertTrue;
      -import static org.mockito.ArgumentMatchers.anyDouble;
      -import static org.mockito.ArgumentMatchers.anyList;
      -import static org.mockito.ArgumentMatchers.anyString;
      -import static org.mockito.ArgumentMatchers.eq;
      -
      -
      -public class DropwizardExportsTest {
      -
      -    private CollectorRegistry registry = new CollectorRegistry();
      -    private MetricRegistry metricRegistry;
      -
      -    private SampleBuilder sampleBuilder;
      -
      -    @Before
      -    public void setUp() {
      -        metricRegistry = new MetricRegistry();
      -        sampleBuilder = Mockito.mock(SampleBuilder.class);
      -        new DropwizardExports(metricRegistry, sampleBuilder).register(registry);
      -    }
      -
      -    @Test
      -    public void testCounter() {
      -        Mockito.when(sampleBuilder.createSample("foo.bar", "", Collections.emptyList(), Collections.emptyList(), 1d)).thenReturn(new Collector.MetricFamilySamples.Sample("foo_bar", Collections.emptyList(), Collections.emptyList(), 1d));
      -        metricRegistry.counter("foo.bar").inc();
      -        assertEquals(new Double(1),
      -                registry.getSampleValue("foo_bar")
      -        );
      -    }
      -
      -    @Test
      -    public void testGauge() {
      -        Gauge integerGauge = new Gauge() {
      -            @Override
      -            public Integer getValue() {
      -                return 1234;
      -            }
      -        };
      -        Gauge doubleGauge = new Gauge() {
      -            @Override
      -            public Double getValue() {
      -                return 1.234D;
      -            }
      -        };
      -        Gauge longGauge = new Gauge() {
      -            @Override
      -            public Long getValue() {
      -                return 1234L;
      -            }
      -        };
      -        Gauge floatGauge = new Gauge() {
      -            @Override
      -            public Float getValue() {
      -                return 0.1234F;
      -            }
      -        };
      -        Gauge booleanGauge = new Gauge() {
      -            @Override
      -            public Boolean getValue() {
      -                return true;
      -            }
      -        };
      -
      -        Mockito.when(sampleBuilder.createSample("integer.gauge", "", Collections.emptyList(), Collections.emptyList(), 1234)).thenReturn(new Collector.MetricFamilySamples.Sample("integer_gauge", Collections.emptyList(), Collections.emptyList(), 1234));
      -        Mockito.when(sampleBuilder.createSample("long.gauge", "", Collections.emptyList(), Collections.emptyList(), 1234)).thenReturn(new Collector.MetricFamilySamples.Sample("long_gauge", Collections.emptyList(), Collections.emptyList(), 1234));
      -        Mockito.when(sampleBuilder.createSample("double.gauge", "", Collections.emptyList(), Collections.emptyList(), 1.234)).thenReturn(new Collector.MetricFamilySamples.Sample("double_gauge", Collections.emptyList(), Collections.emptyList(), 1.234));
      -        Mockito.when(sampleBuilder.createSample("float.gauge", "", Collections.emptyList(), Collections.emptyList(), 0.1234F)).thenReturn(new Collector.MetricFamilySamples.Sample("float_gauge", Collections.emptyList(), Collections.emptyList(), 0.1234F));
      -        Mockito.when(sampleBuilder.createSample("boolean.gauge", "", Collections.emptyList(), Collections.emptyList(), 1)).thenReturn(new Collector.MetricFamilySamples.Sample("boolean_gauge", Collections.emptyList(), Collections.emptyList(), 1));
      -
      -        metricRegistry.register("double.gauge", doubleGauge);
      -        metricRegistry.register("long.gauge", longGauge);
      -        metricRegistry.register("integer.gauge", integerGauge);
      -        metricRegistry.register("float.gauge", floatGauge);
      -        metricRegistry.register("boolean.gauge", booleanGauge);
      -
      -        assertEquals(new Double(1234),
      -                registry.getSampleValue("integer_gauge", new String[]{}, new String[]{}));
      -        assertEquals(new Double(1234),
      -                registry.getSampleValue("long_gauge", new String[]{}, new String[]{}));
      -        assertEquals(new Double(1.234),
      -                registry.getSampleValue("double_gauge", new String[]{}, new String[]{}));
      -        assertEquals(new Double(0.1234F),
      -                registry.getSampleValue("float_gauge", new String[]{}, new String[]{}));
      -        assertEquals(new Double(1),
      -                registry.getSampleValue("boolean_gauge", new String[]{}, new String[]{}));
      -    }
      -
      -    @Test
      -    public void testInvalidGaugeType() {
      -        Gauge invalidGauge = new Gauge() {
      -            @Override
      -            public String getValue() {
      -                return "foobar";
      -            }
      -        };
      -
      -        metricRegistry.register("invalid_gauge", invalidGauge);
      -        assertEquals(null, registry.getSampleValue("invalid_gauge"));
      -        Mockito.verifyNoInteractions(sampleBuilder);
      -    }
      -
      -    @Test
      -    public void testGaugeReturningNullValue() {
      -        Gauge invalidGauge = new Gauge() {
      -            @Override
      -            public String getValue() {
      -                return null;
      -            }
      -        };
      -        metricRegistry.register("invalid_gauge", invalidGauge);
      -        assertEquals(null, registry.getSampleValue("invalid_gauge"));
      -        Mockito.verifyNoInteractions(sampleBuilder);
      -    }
      -
      -    void assertRegistryContainsMetrics(String... metrics) {
      -        for (String metric : metrics) {
      -            assertNotEquals(String.format("Metric %s should exist", metric), null,
      -                    registry.getSampleValue(metric, new String[]{}, new String[]{}));
      -        }
      -    }
      -
      -    @Test
      -    public void testHistogram() throws IOException {
      -        // just test the standard mapper
      -        final MetricRegistry metricRegistry = new MetricRegistry();
      -        final CollectorRegistry registry = new CollectorRegistry();
      -        new DropwizardExports(metricRegistry).register(registry);
      -        Histogram hist = metricRegistry.histogram("hist");
      -        int i = 0;
      -        while (i < 100) {
      -            hist.update(i);
      -            i += 1;
      -        }
      -        assertEquals(new Double(100), registry.getSampleValue("hist_count"));
      -        for (Double d : Arrays.asList(0.75, 0.95, 0.98, 0.99)) {
      -            assertEquals(new Double((d - 0.01) * 100), registry.getSampleValue("hist",
      -                    new String[]{"quantile"}, new String[]{d.toString()}));
      -        }
      -        assertEquals(new Double(99), registry.getSampleValue("hist", new String[]{"quantile"},
      -                new String[]{"0.999"}));
      -    }
      -
      -    @Test
      -    public void testMeter() throws IOException, InterruptedException {
      -        Mockito.when(sampleBuilder.createSample("meter", "_total", Collections.emptyList(), Collections.emptyList(), 2)).thenReturn(new Collector.MetricFamilySamples.Sample("meter_total", Collections.emptyList(), Collections.emptyList(), 2));
      -        Meter meter = metricRegistry.meter("meter");
      -        meter.mark();
      -        meter.mark();
      -        assertEquals(new Double(2), registry.getSampleValue("meter_total"));
      -    }
      -
      -    @Test
      -    public void testTimer() throws IOException, InterruptedException {
      -        // just test the standard mapper
      -        final MetricRegistry metricRegistry = new MetricRegistry();
      -        final CollectorRegistry registry = new CollectorRegistry();
      -        new DropwizardExports(metricRegistry).register(registry);
      -
      -        Timer t = metricRegistry.timer("timer");
      -        Timer.Context time = t.time();
      -        Thread.sleep(1L);
      -        time.stop();
      -        // We slept for 1Ms so we ensure that all timers are above 1ms:
      -        assertTrue(registry.getSampleValue("timer", new String[]{"quantile"}, new String[]{"0.99"}) > 0.001);
      -        assertEquals(new Double(1.0D), registry.getSampleValue("timer_count"));
      -    }
      -
      -    @Test
      -    public void testThatMetricHelpUsesOriginalDropwizardName() {
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedTimer1", Collections.emptyList(), Collections.emptyList(), 1234));
      -
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedCounter1", Collections.emptyList(), Collections.emptyList(), 1234));
      -
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedMeter1_total", Collections.emptyList(), Collections.emptyList(), 1234));
      -
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedHistogram1", Collections.emptyList(), Collections.emptyList(), 1234));
      -
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(new Collector.MetricFamilySamples.Sample("my_application_namedGauge1", Collections.emptyList(), Collections.emptyList(), 1234));
      -
      -        metricRegistry.timer("my.application.namedTimer1");
      -        metricRegistry.counter("my.application.namedCounter1");
      -        metricRegistry.meter("my.application.namedMeter1");
      -        metricRegistry.histogram("my.application.namedHistogram1");
      -        metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge());
      -
      -        Enumeration metricFamilySamples = registry.metricFamilySamples();
      -
      -
      -        Map elements = new HashMap();
      -
      -        while (metricFamilySamples.hasMoreElements()) {
      -            Collector.MetricFamilySamples element = metricFamilySamples.nextElement();
      -            elements.put(element.name, element);
      -        }
      -        assertEquals(5, elements.size());
      -
      -        assertTrue(elements.keySet().contains("my_application_namedTimer1"));
      -        assertTrue(elements.keySet().contains("my_application_namedCounter1"));
      -        assertTrue(elements.keySet().contains("my_application_namedMeter1"));
      -        assertTrue(elements.keySet().contains("my_application_namedHistogram1"));
      -        assertTrue(elements.keySet().contains("my_application_namedGauge1"));
      -
      -        assertThat(elements.get("my_application_namedTimer1").help,
      -                is("Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=com.codahale.metrics.Timer)"));
      -
      -        assertThat(elements.get("my_application_namedCounter1").help,
      -                is("Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=com.codahale.metrics.Counter)"));
      -
      -        assertThat(elements.get("my_application_namedMeter1").help,
      -                is("Generated from Dropwizard metric import (metric=my.application.namedMeter1, type=com.codahale.metrics.Meter)"));
      -
      -        assertThat(elements.get("my_application_namedHistogram1").help,
      -                is("Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=com.codahale.metrics.Histogram)"));
      -
      -        assertThat(elements.get("my_application_namedGauge1").help,
      -                is("Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.client.dropwizard.DropwizardExportsTest$ExampleDoubleGauge)"));
      -
      -    }
      -
      -    @Test
      -    public void testThatMetricsMappedToSameNameAreGroupedInSameFamily() {
      -        final Collector.MetricFamilySamples.Sample namedTimerSample1 = new Collector.MetricFamilySamples.Sample("my_application_namedTimer", Collections.emptyList(), Collections.emptyList(), 1234);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedTimerSample1);
      -
      -        final Collector.MetricFamilySamples.Sample namedTimerSample2 = new Collector.MetricFamilySamples.Sample("my_application_namedTimer", Collections.emptyList(), Collections.emptyList(), 1235);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedTimer2"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedTimerSample2);
      -
      -        final Collector.MetricFamilySamples.Sample namedCounter1 = new Collector.MetricFamilySamples.Sample("my_application_namedCounter", Collections.emptyList(), Collections.emptyList(), 1234);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedCounter1);
      -
      -        final Collector.MetricFamilySamples.Sample namedCounter2 = new Collector.MetricFamilySamples.Sample("my_application_namedCounter", Collections.emptyList(), Collections.emptyList(), 1235);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedCounter2"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedCounter2);
      -
      -        final Collector.MetricFamilySamples.Sample namedMeter1 = new Collector.MetricFamilySamples.Sample("my_application_namedMeter_total", Collections.emptyList(), Collections.emptyList(), 1234);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedMeter1);
      -
      -        final Collector.MetricFamilySamples.Sample namedMeter2 = new Collector.MetricFamilySamples.Sample("my_application_namedMeter_total", Collections.emptyList(), Collections.emptyList(), 1235);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedMeter2"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedMeter2);
      -
      -        final Collector.MetricFamilySamples.Sample namedHistogram1 = new Collector.MetricFamilySamples.Sample("my_application_namedHistogram", Collections.emptyList(), Collections.emptyList(), 1234);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedHistogram1);
      -
      -        final Collector.MetricFamilySamples.Sample namedHistogram2 = new Collector.MetricFamilySamples.Sample("my_application_namedHistogram", Collections.emptyList(), Collections.emptyList(), 1235);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedHistogram2"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedHistogram2);
      -
      -        final Collector.MetricFamilySamples.Sample namedGauge1 = new Collector.MetricFamilySamples.Sample("my_application_namedGauge", Collections.emptyList(), Collections.emptyList(), 1234);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge1"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedGauge1);
      -
      -        final Collector.MetricFamilySamples.Sample namedGauge2 = new Collector.MetricFamilySamples.Sample("my_application_namedGauge", Collections.emptyList(), Collections.emptyList(), 1235);
      -        Mockito.when(sampleBuilder.createSample(eq("my.application.namedGauge2"), anyString(), anyList(), anyList(), anyDouble()))
      -                .thenReturn(namedGauge2);
      -
      -        metricRegistry.timer("my.application.namedTimer1");
      -        metricRegistry.timer("my.application.namedTimer2");
      -        metricRegistry.counter("my.application.namedCounter1");
      -        metricRegistry.counter("my.application.namedCounter2");
      -        metricRegistry.meter("my.application.namedMeter1");
      -        metricRegistry.meter("my.application.namedMeter2");
      -        metricRegistry.histogram("my.application.namedHistogram1");
      -        metricRegistry.histogram("my.application.namedHistogram2");
      -        metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge());
      -        metricRegistry.register("my.application.namedGauge2", new ExampleDoubleGauge());
      -
      -        Enumeration metricFamilySamples = registry.metricFamilySamples();
      -
      -
      -        Map elements = new HashMap();
      -
      -        while (metricFamilySamples.hasMoreElements()) {
      -            Collector.MetricFamilySamples element = metricFamilySamples.nextElement();
      -            elements.put(element.name, element);
      -        }
      -        assertEquals(5, elements.size());
      -
      -        final Collector.MetricFamilySamples namedTimer = elements.get("my_application_namedTimer");
      -        assertNotNull(namedTimer);
      -        assertEquals(Collector.Type.SUMMARY, namedTimer.type);
      -        assertEquals(14, namedTimer.samples.size());
      -
      -        final Collector.MetricFamilySamples namedCounter = elements.get("my_application_namedCounter");
      -        assertNotNull(namedCounter);
      -        assertEquals(Collector.Type.GAUGE, namedCounter.type);
      -        assertEquals(2, namedCounter.samples.size());
      -        assertTrue(namedCounter.samples.contains(namedCounter1));
      -        assertTrue(namedCounter.samples.contains(namedCounter2));
      -
      -        final Collector.MetricFamilySamples namedMeter = elements.get("my_application_namedMeter");
      -        assertNotNull(namedMeter);
      -        assertEquals(Collector.Type.COUNTER, namedMeter.type);
      -        assertEquals(2, namedMeter.samples.size());
      -        assertTrue(namedMeter.samples.contains(namedMeter1));
      -        assertTrue(namedMeter.samples.contains(namedMeter2));
      -
      -        final Collector.MetricFamilySamples namedHistogram = elements.get("my_application_namedHistogram");
      -        assertNotNull(namedHistogram);
      -        assertEquals(Collector.Type.SUMMARY, namedHistogram.type);
      -        assertEquals(Collector.Type.SUMMARY, namedHistogram.type);
      -        assertEquals(14, namedHistogram.samples.size());
      -
      -        final Collector.MetricFamilySamples namedGauge = elements.get("my_application_namedGauge");
      -        assertNotNull(namedGauge);
      -        assertEquals(Collector.Type.GAUGE, namedGauge.type);
      -        assertEquals(2, namedGauge.samples.size());
      -        assertTrue(namedGauge.samples.contains(namedGauge1));
      -        assertTrue(namedGauge.samples.contains(namedGauge2));
      -
      -    }
      -
      -    private static class ExampleDoubleGauge implements Gauge {
      -        @Override
      -        public Double getValue() {
      -            return 0.0;
      -        }
      -    }
      -}
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java
      deleted file mode 100644
      index c4af8f93e..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/CustomMappingSampleBuilderTest.java
      +++ /dev/null
      @@ -1,182 +0,0 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      -
      -import io.prometheus.client.Collector;
      -import org.junit.Test;
      -
      -import java.util.Arrays;
      -import java.util.Collections;
      -import java.util.HashMap;
      -import java.util.LinkedHashMap;
      -import java.util.List;
      -import java.util.Map;
      -
      -import static org.junit.Assert.assertEquals;
      -
      -public class CustomMappingSampleBuilderTest {
      -    @Test(expected = IllegalArgumentException.class)
      -    public void test_WHEN_EmptyConfig_THEN_Fail() {
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(Collections.emptyList());
      -    }
      -
      -    @Test
      -    public void test_WHEN_NoMatches_THEN_ShouldReturnDefaultSample() {
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                new MapperConfig("*.client-nope.*.*.*"),
      -                new MapperConfig("not.even.this.*.*.*")
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.service.total", "", Collections.singletonList("quantile"), Collections.singletonList("0.99"), 0d);
      -
      -        assertEquals(new Collector.MetricFamilySamples.Sample("app_okhttpclient_client_HttpClient_service_total", Collections.singletonList("quantile"), Collections.singletonList("0.99"), 0d), result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() {
      -        final Map labels = new HashMap();
      -        labels.put("service", "${0}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.total",
      -                "app.okhttpclient.client.HttpClient.total",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("not.even.this.*.*.*")
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient_total", Collections.singletonList("service"), Collections.singletonList("greatService"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.total", "", Collections.emptyList(), Collections.emptyList(), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() {
      -        final Map labels = new HashMap();
      -        labels.put("service", "${0}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.total",
      -                "app.okhttpclient.client.HttpClient.total",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient_total", Collections.singletonList("service"), Collections.singletonList("greatService"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.total", "", Collections.emptyList(), Collections.emptyList(), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() {
      -        final Map labels = new LinkedHashMap();
      -        labels.put("service", "${0}");
      -        labels.put("status", "${1}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.*",
      -                "app.okhttpclient.client.HttpClient",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient", Arrays.asList("service", "status"), Arrays.asList("greatService", "400"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.400", "", Collections.emptyList(), Collections.emptyList(), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() {
      -        final Map labels = new LinkedHashMap();
      -        labels.put("service", "${0}_${1}");
      -        labels.put("status", "s_${1}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.*",
      -                "app.okhttpclient.client.HttpClient.${0}",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient_greatService", Arrays.asList("service", "status"), Arrays.asList("greatService_400", "s_400"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.400", "", Collections.emptyList(), Collections.emptyList(), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_MetricNameSuffixRequested_THEN_ShouldReturnCorrectSample() {
      -        final Map labels = new LinkedHashMap();
      -        labels.put("service", "${0}");
      -        labels.put("status", "s_${1}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.*",
      -                "app.okhttpclient.client.HttpClient.${0}",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient_greatService_suffix", Arrays.asList("service", "status"), Arrays.asList("greatService", "s_400"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.400", "_suffix", Collections.emptyList(), Collections.emptyList(), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() {
      -        final Map labels = new LinkedHashMap();
      -        labels.put("service", "${0}");
      -        labels.put("status", "s_${1}");
      -        final MapperConfig mapperConfig = new MapperConfig(
      -                "app.okhttpclient.client.HttpClient.*.*",
      -                "app.okhttpclient.client.HttpClient.${0}",
      -                labels
      -        );
      -        final List mapperConfigs = Arrays.asList(
      -                new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      -        );
      -        final CustomMappingSampleBuilder converter = new CustomMappingSampleBuilder(mapperConfigs);
      -        final Collector.MetricFamilySamples.Sample expectedResult = new Collector.MetricFamilySamples.Sample(
      -                "app_okhttpclient_client_HttpClient_greatService_suffix", Arrays.asList("service", "status", "another"), Arrays.asList("greatService", "s_400", "label"), 1d);
      -
      -        final Collector.MetricFamilySamples.Sample result = converter.createSample(
      -                "app.okhttpclient.client.HttpClient.greatService.400", "_suffix", Collections.singletonList("another"), Collections.singletonList("label"), 1d);
      -
      -        assertEquals(expectedResult, result);
      -    }
      -}
      diff --git a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java b/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java
      deleted file mode 100644
      index fa6c30288..000000000
      --- a/simpleclient-archive/simpleclient_dropwizard/src/test/java/io/prometheus/client/dropwizard/samplebuilder/DefaultSampleBuilderTest.java
      +++ /dev/null
      @@ -1,31 +0,0 @@
      -package io.prometheus.client.dropwizard.samplebuilder;
      -
      -import io.prometheus.client.Collector;
      -import io.prometheus.client.dropwizard.samplebuilder.DefaultSampleBuilder;
      -import org.junit.Assert;
      -import org.junit.Test;
      -
      -import java.util.Arrays;
      -import java.util.Collections;
      -
      -public class DefaultSampleBuilderTest {
      -    @Test
      -    public void test_WHEN_NoSuffixAndExtraLabels_THEN_ShouldReturnCorrectSample() {
      -        final DefaultSampleBuilder builder = new DefaultSampleBuilder();
      -        final Collector.MetricFamilySamples.Sample result = builder.createSample("org.github.name", null, null, null, 1d);
      -        Assert.assertEquals(
      -                new Collector.MetricFamilySamples.Sample("org_github_name", Collections.emptyList(), Collections.emptyList(), 1d)
      -                , result);
      -    }
      -
      -    @Test
      -    public void test_WHEN_SuffixAndExtraLabels_THEN_ShouldReturnCorrectSample() {
      -        final DefaultSampleBuilder builder = new DefaultSampleBuilder();
      -        final Collector.MetricFamilySamples.Sample result = builder.createSample("org.github.name", "suffix.test", Collections.singletonList("another"), Arrays.asList("label"), 1d);
      -        Assert.assertEquals(
      -                new Collector.MetricFamilySamples.Sample("org_github_namesuffix_test", Collections.singletonList("another"),
      -                        Arrays.asList("label"), 1d), result);
      -
      -    }
      -
      -}
      \ No newline at end of file
      
      From 051ff61cdee9baa2b6250b6beb657c9abb5c6e7f Mon Sep 17 00:00:00 2001
      From: "Capt. Cutlass" <5120290+ParanoidUser@users.noreply.github.com>
      Date: Fri, 9 Feb 2024 10:45:58 -0500
      Subject: [PATCH 290/980] chore: remove duplicate maven dependencies (#914)
      
      Signed-off-by: Capt. Cutlass <5120290+ParanoidUser@users.noreply.github.com>
      ---
       prometheus-metrics-exporter-common/pom.xml     | 5 -----
       prometheus-metrics-simpleclient-bridge/pom.xml | 6 ------
       2 files changed, 11 deletions(-)
      
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index 53828db1d..94a1e74cb 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -47,11 +47,6 @@
                   prometheus-metrics-exposition-formats
                   ${project.version}
               
      -        
      -            io.prometheus
      -            prometheus-metrics-exposition-formats
      -            ${project.version}
      -        
           
       
       
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index 10d9ac8d6..aa355d50c 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -73,11 +73,5 @@
                   0.16.0
                   test
               
      -        
      -            io.prometheus
      -            prometheus-metrics-config
      -            1.2.0-SNAPSHOT
      -            compile
      -        
           
       
      
      From c1442e8faaa8523e41f917a321dd9f76dbb944ed Mon Sep 17 00:00:00 2001
      From: Kinshuk Bairagi 
      Date: Fri, 9 Feb 2024 21:24:10 +0530
      Subject: [PATCH 291/980] Add a javax.servlet-api exporter  (#918)
      
      * Add prometheus-metrics-exporter-servlet-javax
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Add comments for ci to pass
      
      Signed-off-by: Kinshuk Bairagi 
      
      ---------
      
      Signed-off-by: Kinshuk Bairagi 
      ---
       pom.xml                                       |   1 +
       .../pom.xml                                   |  53 ++++++
       .../servlet/javax/HttpExchangeAdapter.java    | 153 ++++++++++++++++++
       .../javax/PrometheusMetricsServlet.java       |  67 ++++++++
       .../version-rules.xml                         |   6 +
       5 files changed, 280 insertions(+)
       create mode 100644 prometheus-metrics-exporter-servlet-javax/pom.xml
       create mode 100644 prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java
       create mode 100644 prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java
       create mode 100644 prometheus-metrics-exporter-servlet-javax/version-rules.xml
      
      diff --git a/pom.xml b/pom.xml
      index 145abe041..4ee0e39ae 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -59,6 +59,7 @@
               prometheus-metrics-exposition-formats
               prometheus-metrics-exporter-common
               prometheus-metrics-exporter-servlet-jakarta
      +        prometheus-metrics-exporter-servlet-javax
               prometheus-metrics-exporter-httpserver
               prometheus-metrics-exporter-opentelemetry
               prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml
      new file mode 100644
      index 000000000..8cd2f452e
      --- /dev/null
      +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml
      @@ -0,0 +1,53 @@
      +
      +
      +    4.0.0
      +
      +    
      +        io.prometheus
      +        client_java
      +        1.2.0-SNAPSHOT
      +    
      +
      +    prometheus-metrics-exporter-servlet-javax
      +    bundle
      +
      +    Prometheus Metrics Exporter - Servlet JavaX
      +    
      +        JavaX Servlet for exposing a Prometheus scrape endpoint.
      +    
      +
      +    
      +        io.prometheus.metrics.exporter.servlet.javax
      +    
      +
      +    
      +        
      +            The Apache Software License, Version 2.0
      +            http://www.apache.org/licenses/LICENSE-2.0.txt
      +            repo
      +        
      +    
      +
      +    
      +        
      +            kingster
      +            Kinshuk Bairagi
      +            hi@kinsh.uk
      +        
      +    
      +
      +    
      +        
      +            io.prometheus
      +            prometheus-metrics-exporter-common
      +            ${project.version}
      +        
      +        
      +            javax.servlet
      +            javax.servlet-api
      +            3.1.0
      +            provided
      +        
      +    
      +
      +
      diff --git a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java
      new file mode 100644
      index 000000000..0073db368
      --- /dev/null
      +++ b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java
      @@ -0,0 +1,153 @@
      +package io.prometheus.metrics.exporter.servlet.javax;
      +
      +import io.prometheus.metrics.exporter.common.PrometheusHttpExchange;
      +import io.prometheus.metrics.exporter.common.PrometheusHttpRequest;
      +import io.prometheus.metrics.exporter.common.PrometheusHttpResponse;
      +
      +import javax.servlet.http.HttpServletRequest;
      +import javax.servlet.http.HttpServletResponse;
      +import java.io.IOException;
      +import java.io.OutputStream;
      +import java.util.Enumeration;
      +
      +/**
      + * This class is an adapter for HTTP exchanges, implementing the PrometheusHttpExchange interface.
      + * It wraps HttpServletRequest and HttpServletResponse objects into Request and Response inner classes.
      + */
      +public class HttpExchangeAdapter implements PrometheusHttpExchange {
      +
      +    private final Request request;
      +    private final Response response;
      +
      +    /**
      +     * Constructs a new HttpExchangeAdapter with the given HttpServletRequest and HttpServletResponse.
      +     *
      +     * @param request  the HttpServletRequest to be adapted
      +     * @param response the HttpServletResponse to be adapted
      +     */
      +    public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) {
      +        this.request = new Request(request);
      +        this.response = new Response(response);
      +    }
      +
      +    /**
      +     * Returns the adapted HttpServletRequest.
      +     *
      +     * @return the adapted HttpServletRequest
      +     */
      +    @Override
      +    public PrometheusHttpRequest getRequest() {
      +        return request;
      +    }
      +
      +    /**
      +     * Returns the adapted HttpServletResponse.
      +     *
      +     * @return the adapted HttpServletResponse
      +     */
      +    @Override
      +    public PrometheusHttpResponse getResponse() {
      +        return response;
      +    }
      +
      +    @Override
      +    public void handleException(IOException e) throws IOException {
      +        throw e; // leave exception handling to the servlet container
      +    }
      +
      +    @Override
      +    public void handleException(RuntimeException e) {
      +        throw e; // leave exception handling to the servlet container
      +    }
      +
      +    @Override
      +    public void close() {
      +        // nothing to do for Servlets.
      +    }
      +
      +    /**
      +     * This inner class adapts a HttpServletRequest to a PrometheusHttpRequest.
      +     */
      +    public static class Request implements PrometheusHttpRequest {
      +
      +        private final HttpServletRequest request;
      +
      +        /**
      +         * Constructs a new Request with the given HttpServletRequest.
      +         *
      +         * @param request the HttpServletRequest to be adapted
      +         */
      +        public Request(HttpServletRequest request) {
      +            this.request = request;
      +        }
      +
      +        @Override
      +        public String getQueryString() {
      +            return request.getQueryString();
      +        }
      +
      +
      +        @Override
      +        public Enumeration getHeaders(String name) {
      +            return request.getHeaders(name);
      +        }
      +
      +
      +        @Override
      +        public String getMethod() {
      +            return request.getMethod();
      +        }
      +
      +
      +        @Override
      +        public String getRequestPath() {
      +            StringBuilder uri = new StringBuilder();
      +            String contextPath = request.getContextPath();
      +            if (contextPath.startsWith("/")) {
      +                uri.append(contextPath);
      +            }
      +            String servletPath = request.getServletPath();
      +            if (servletPath.startsWith("/")) {
      +                uri.append(servletPath);
      +            }
      +            String pathInfo = request.getPathInfo();
      +            if (pathInfo != null) {
      +                uri.append(pathInfo);
      +            }
      +            return uri.toString();
      +        }
      +    }
      +
      +    /**
      +     * This inner class adapts a HttpServletResponse to a PrometheusHttpResponse.
      +     */
      +    public static class Response implements PrometheusHttpResponse {
      +
      +        private final HttpServletResponse response;
      +
      +        /**
      +         * Constructs a new Response with the given HttpServletResponse.
      +         *
      +         * @param response the HttpServletResponse to be adapted
      +         */
      +        public Response(HttpServletResponse response) {
      +            this.response = response;
      +        }
      +
      +
      +        @Override
      +        public void setHeader(String name, String value) {
      +            response.setHeader(name, value);
      +        }
      +
      +
      +        @Override
      +        public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException {
      +            if (response.getHeader("Content-Length") == null && contentLength > 0) {
      +                response.setContentLength(contentLength);
      +            }
      +            response.setStatus(statusCode);
      +            return response.getOutputStream();
      +        }
      +    }
      +}
      \ No newline at end of file
      diff --git a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java
      new file mode 100644
      index 000000000..88564d118
      --- /dev/null
      +++ b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java
      @@ -0,0 +1,67 @@
      +package io.prometheus.metrics.exporter.servlet.javax;
      +
      +import io.prometheus.metrics.config.PrometheusProperties;
      +import io.prometheus.metrics.exporter.common.PrometheusScrapeHandler;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +
      +import javax.servlet.http.HttpServlet;
      +import javax.servlet.http.HttpServletRequest;
      +import javax.servlet.http.HttpServletResponse;
      +import java.io.IOException;
      +
      +/**
      + * This class extends HttpServlet to create a servlet for exporting Prometheus metrics.
      + * It uses a PrometheusScrapeHandler to handle HTTP GET requests and export metrics.
      + * The servlet can be configured with custom PrometheusProperties and a PrometheusRegistry.
      + */
      +public class PrometheusMetricsServlet extends HttpServlet {
      +
      +    private final PrometheusScrapeHandler handler;
      +
      +    /**
      +     * Default constructor. Uses the default PrometheusProperties and PrometheusRegistry.
      +     */
      +    public PrometheusMetricsServlet() {
      +        this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry);
      +    }
      +
      +    /**
      +     * Constructor with a custom PrometheusRegistry. Uses the default PrometheusProperties.
      +     *
      +     * @param registry the PrometheusRegistry to use
      +     */
      +    public PrometheusMetricsServlet(PrometheusRegistry registry) {
      +        this(PrometheusProperties.get(), registry);
      +    }
      +
      +    /**
      +     * Constructor with custom PrometheusProperties. Uses the default PrometheusRegistry.
      +     *
      +     * @param config the PrometheusProperties to use
      +     */
      +    public PrometheusMetricsServlet(PrometheusProperties config) {
      +        this(config, PrometheusRegistry.defaultRegistry);
      +    }
      +
      +    /**
      +     * Constructor with custom PrometheusProperties and PrometheusRegistry.
      +     *
      +     * @param config   the PrometheusProperties to use
      +     * @param registry the PrometheusRegistry to use
      +     */
      +    public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) {
      +        this.handler = new PrometheusScrapeHandler(config, registry);
      +    }
      +
      +    /**
      +     * Handles HTTP GET requests. Exports Prometheus metrics by delegating to the PrometheusScrapeHandler.
      +     *
      +     * @param request  the HttpServletRequest
      +     * @param response the HttpServletResponse
      +     * @throws IOException if an I/O error occurs
      +     */
      +    @Override
      +    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
      +        handler.handleRequest(new HttpExchangeAdapter(request, response));
      +    }
      +}
      \ No newline at end of file
      diff --git a/prometheus-metrics-exporter-servlet-javax/version-rules.xml b/prometheus-metrics-exporter-servlet-javax/version-rules.xml
      new file mode 100644
      index 000000000..5c6d39593
      --- /dev/null
      +++ b/prometheus-metrics-exporter-servlet-javax/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      
      From 3fdba974aa96c8f2ebb89eee78787e2bd52c3042 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Thu, 15 Feb 2024 12:00:32 +0100
      Subject: [PATCH 292/980] Remove Spring Boot 1 instrumentation (#923)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../simpleclient_spring_boot/pom.xml          | 108 ------------------
       .../spring/boot/EnablePrometheusEndpoint.java |  44 -------
       .../EnableSpringBootMetricsCollector.java     |  15 ---
       .../spring/boot/PrometheusEndpoint.java       |  39 -------
       .../boot/PrometheusEndpointConfiguration.java |  23 ----
       .../boot/PrometheusMetricsConfiguration.java  |  17 ---
       .../spring/boot/PrometheusMvcEndpoint.java    |  47 --------
       .../boot/SpringBootMetricsCollector.java      |  54 ---------
       .../client/matchers/CustomMatchers.java       |  45 --------
       .../spring/boot/DummyBootApplication.java     |  12 --
       .../spring/boot/PrometheusEndpointTest.java   |  72 ------------
       .../boot/PrometheusMvcEndpointTest.java       |  85 --------------
       .../boot/SpringBootMetricsCollectorTest.java  |  57 ---------
       .../version-rules.xml                         |  11 --
       14 files changed, 629 deletions(-)
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/pom.xml
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java
       delete mode 100644 simpleclient-archive/simpleclient_spring_boot/version-rules.xml
      
      diff --git a/simpleclient-archive/simpleclient_spring_boot/pom.xml b/simpleclient-archive/simpleclient_spring_boot/pom.xml
      deleted file mode 100644
      index 0f8e40208..000000000
      --- a/simpleclient-archive/simpleclient_spring_boot/pom.xml
      +++ /dev/null
      @@ -1,108 +0,0 @@
      -
      -
      -    4.0.0
      -
      -    
      -        io.prometheus
      -        client_java
      -        1.0.0-alpha-1-SNAPSHOT
      -    
      -
      -    simpleclient_spring_boot
      -    bundle
      -
      -    Prometheus Java Simpleclient Spring Boot Metric
      -    
      -        Collect information from Spring Boot actuator.
      -    
      -
      -    
      -        
      -            The Apache Software License, Version 2.0
      -            http://www.apache.org/licenses/LICENSE-2.0.txt
      -            repo
      -        
      -    
      -
      -    
      -        
      -            tokuhirom
      -            Tokuhiro Matsuno
      -            tokuhirom@gmail.com
      -        
      -        
      -            Marco Aust
      -            github@marcoaust.de
      -            private
      -            https://github.com/maust
      -        
      -        
      -            eliezio
      -            Eliezio Oliveira
      -            eliezio.oliveira@gmail.com
      -        
      -    
      -
      -    
      -        UTF-8
      -    
      -
      -    
      -        
      -            io.prometheus
      -            simpleclient
      -            ${project.version}
      -        
      -        
      -            io.prometheus
      -            simpleclient_common
      -            ${project.version}
      -        
      -        
      -          io.prometheus
      -          simpleclient_spring_web
      -          ${project.version}
      -        
      -        
      -            org.springframework.boot
      -            spring-boot-actuator
      -            1.5.22.RELEASE
      -        
      -        
      -            org.springframework.boot
      -            spring-boot-starter-aop
      -            1.5.22.RELEASE
      -        
      -        
      -            org.apache.commons
      -            commons-lang3
      -            3.12.0
      -        
      -
      -        
      -        
      -            junit
      -            junit
      -            4.13.2
      -            test
      -        
      -        
      -            org.cthul
      -            cthul-matchers
      -            1.1.0
      -            test
      -        
      -        
      -            org.springframework.boot
      -            spring-boot-starter-test
      -            1.5.22.RELEASE
      -            test
      -        
      -        
      -            org.springframework.boot
      -            spring-boot-starter-web
      -            1.5.22.RELEASE
      -            test
      -        
      -    
      -
      diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java
      deleted file mode 100644
      index e799756e9..000000000
      --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnablePrometheusEndpoint.java
      +++ /dev/null
      @@ -1,44 +0,0 @@
      -package io.prometheus.client.spring.boot;
      -
      -import org.springframework.context.annotation.Import;
      -
      -import java.lang.annotation.Documented;
      -import java.lang.annotation.ElementType;
      -import java.lang.annotation.Retention;
      -import java.lang.annotation.RetentionPolicy;
      -import java.lang.annotation.Target;
      -
      -/**
      - * Enable an endpoint that exposes Prometheus metrics from its default collector.
      - * 

      - * Usage: - *
      Just add this annotation to the main class of your Spring Boot application, e.g.: - *

      
      - * {@literal @}SpringBootApplication
      - * {@literal @}EnablePrometheusEndpoint
      - *  public class Application {
      - *
      - *    public static void main(String[] args) {
      - *      SpringApplication.run(Application.class, args);
      - *    }
      - *  }
      - * 
      - *

      - * Configuration: - *
      You can customize this endpoint at runtime using the following spring properties: - *

        - *
      • {@code endpoints.prometheus.id} (default: "prometheus")
      • - *
      • {@code endpoints.prometheus.enabled} (default: {@code true})
      • - *
      • {@code endpoints.prometheus.sensitive} (default: {@code true})
      • - *
      - * - * @author Marco Aust - * @author Eliezio Oliveira - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(PrometheusEndpointConfiguration.class) -public @interface EnablePrometheusEndpoint { - -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java deleted file mode 100644 index ddd204a5b..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/EnableSpringBootMetricsCollector.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.prometheus.client.spring.boot; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.springframework.context.annotation.Import; - - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Import(PrometheusMetricsConfiguration.class) -public @interface EnableSpringBootMetricsCollector {} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java deleted file mode 100644 index 995077c39..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpoint.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.exporter.common.TextFormat; -import org.springframework.boot.actuate.endpoint.AbstractEndpoint; -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Collections; -import java.util.Set; - -@ConfigurationProperties("endpoints.prometheus") -class PrometheusEndpoint extends AbstractEndpoint { - - private final CollectorRegistry collectorRegistry; - - PrometheusEndpoint(CollectorRegistry collectorRegistry) { - super("prometheus"); - this.collectorRegistry = collectorRegistry; - } - - @Override - public String invoke() { - return writeRegistry(Collections.emptySet(), ""); - } - - public String writeRegistry(Set metricsToInclude, String contentType) { - try { - Writer writer = new StringWriter(); - TextFormat.writeFormat(contentType, writer, collectorRegistry.filteredMetricFamilySamples(metricsToInclude)); - return writer.toString(); - } catch (IOException e) { - // This actually never happens since StringWriter::write() doesn't throw any IOException - throw new RuntimeException("Writing metrics failed", e); - } - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java deleted file mode 100644 index 5f561c050..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusEndpointConfiguration.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.CollectorRegistry; -import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -class PrometheusEndpointConfiguration { - - @Bean - public PrometheusEndpoint prometheusEndpoint() { - return new PrometheusEndpoint(CollectorRegistry.defaultRegistry); - } - - @Bean - @ConditionalOnBean(PrometheusEndpoint.class) - @ConditionalOnEnabledEndpoint("prometheus") - public PrometheusMvcEndpoint prometheusEndpointFix(PrometheusEndpoint prometheusEndpoint) { - return new PrometheusMvcEndpoint(prometheusEndpoint); - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java deleted file mode 100644 index 9d72a1a3f..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMetricsConfiguration.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.prometheus.client.spring.boot; - -import java.util.Collection; -import org.springframework.boot.actuate.endpoint.PublicMetrics; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -class PrometheusMetricsConfiguration { - - @Bean - public SpringBootMetricsCollector springBootMetricsCollector(Collection publicMetrics) { - SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics); - springBootMetricsCollector.register(); - return springBootMetricsCollector; - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java deleted file mode 100644 index fafd4dc69..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/PrometheusMvcEndpoint.java +++ /dev/null @@ -1,47 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.exporter.common.TextFormat; -import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import java.util.Set; - -import static org.springframework.http.HttpHeaders.CONTENT_TYPE; - -@ConfigurationProperties("endpoints.prometheus") -public class PrometheusMvcEndpoint extends EndpointMvcAdapter { - - private final PrometheusEndpoint delgate; - - public PrometheusMvcEndpoint(PrometheusEndpoint delegate) { - super(delegate); - this.delgate = delegate; - } - - @RequestMapping( - method = {RequestMethod.GET}, - produces = { "*/*" } - ) - @ResponseBody - public ResponseEntity value( - @RequestParam(value = "name[]", required = false, defaultValue = "") Set name, - @RequestHeader(value = "Accept", required = false, defaultValue = "") String accept) { - if (!getDelegate().isEnabled()) { - // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's - // disabled - return getDisabledResponse(); - } - - String contentType = TextFormat.chooseContentType(accept); - String result = delgate.writeRegistry(name, contentType); - return ResponseEntity.ok() - .header(CONTENT_TYPE, contentType) - .body(result); - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java b/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java deleted file mode 100644 index 2cf1f7d8b..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/main/java/io/prometheus/client/spring/boot/SpringBootMetricsCollector.java +++ /dev/null @@ -1,54 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.Collector; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.endpoint.PublicMetrics; -import org.springframework.boot.actuate.metrics.Metric; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - *

      Spring boot metrics integration for Prometheus exporter.

      - * - *
      {@literal @}Bean
      - * public SpringBootMetricsCollector springBootMetricsCollector(Collection{@literal <}PublicMetrics{@literal >} publicMetrics) {
      - *   SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics);
      - *   springBootMetricsCollector.register();
      - *   return springBootMetricsCollector;
      - * }
      - * 
      - */ -@Component -public class SpringBootMetricsCollector extends Collector implements Collector.Describable { - private final Collection publicMetrics; - - @Autowired - public SpringBootMetricsCollector(Collection publicMetrics) { - this.publicMetrics = publicMetrics; - } - - @Override - public List collect() { - ArrayList samples = new ArrayList(); - for (PublicMetrics publicMetrics : this.publicMetrics) { - for (Metric metric : publicMetrics.metrics()) { - String name = Collector.sanitizeMetricName(metric.getName()); - double value = metric.getValue().doubleValue(); - MetricFamilySamples metricFamilySamples = new MetricFamilySamples( - name, Type.GAUGE, name, Collections.singletonList( - new MetricFamilySamples.Sample(name, Collections.emptyList(), Collections.emptyList(), value))); - samples.add(metricFamilySamples); - } - } - return samples; - } - - @Override - public List describe() { - return new ArrayList(); - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java deleted file mode 100644 index dddec7b61..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/matchers/CustomMatchers.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.prometheus.client.matchers; - -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.core.IsCollectionContaining; - -/** - * @author BretC - * - * @see this StackOverflow answer - * - * Licensed under Creative Commons BY-SA 3.0 - */ -public final class CustomMatchers { - - private CustomMatchers() { - } - - public static Matcher> exactlyNItems(final int n, final Matcher elementMatcher) { - return new IsCollectionContaining(elementMatcher) { - @Override - protected boolean matchesSafely(Iterable collection, Description mismatchDescription) { - int count = 0; - boolean isPastFirst = false; - - for (Object item : collection) { - - if (elementMatcher.matches(item)) { - count++; - } - if (isPastFirst) { - mismatchDescription.appendText(", "); - } - elementMatcher.describeMismatch(item, mismatchDescription); - isPastFirst = true; - } - - if (count != n) { - mismatchDescription.appendText(". Expected exactly " + n + " but got " + count); - } - return count == n; - } - }; - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java deleted file mode 100644 index a011d137d..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/DummyBootApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.prometheus.client.spring.boot; - -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Dummy class to satisfy Spring Boot Test requirement of a class annotated either with {code @SpringBootApplication} or - * {code @SpringBootConfiguration}. - */ -@SpringBootApplication -class DummyBootApplication { - -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java deleted file mode 100644 index 737788f76..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusEndpointTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.Counter; -import io.prometheus.client.exporter.common.TextFormat; -import io.prometheus.client.matchers.CustomMatchers; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.Arrays; -import java.util.List; - -import static org.cthul.matchers.CthulMatchers.matchesPattern; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@EnablePrometheusEndpoint -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = DummyBootApplication.class) -@TestPropertySource(properties = "management.security.enabled=false") -public class PrometheusEndpointTest { - - @Value("${local.server.port}") - int localServerPort; - - @Autowired - TestRestTemplate template; - - @Test - public void testMetricsExportedThroughPrometheusEndpoint() { - // given: - final Counter promCounter = Counter.build("foo_bar", "test counter") - .labelNames("label1", "label2") - .register(); - final Counter filteredCounter = Counter.build("filtered_foo_bar", "test counter") - .labelNames("label1", "label2") - .register(); - - // when: - promCounter.labels("val1", "val2").inc(3); - filteredCounter.labels("val1", "val2").inc(6); - - HttpHeaders headers = new HttpHeaders(); - headers.set("Accept", "text/plain"); - - ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus?name[]=foo_bar_total", HttpMethod.GET, new HttpEntity(headers), String.class); - - // then: - assertEquals(HttpStatus.OK, metricsResponse.getStatusCode()); - assertEquals(StringUtils.deleteWhitespace(TextFormat.CONTENT_TYPE_004), metricsResponse.getHeaders().getContentType().toString().toLowerCase()); - - List responseLines = Arrays.asList(metricsResponse.getBody().split("\n")); - assertThat(responseLines, CustomMatchers.exactlyNItems(1, - matchesPattern("foo_bar_total\\{label1=\"val1\",label2=\"val2\",?\\} 3.0"))); - } - - private String getBaseUrl() { - return "http://localhost:" + localServerPort; - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java deleted file mode 100644 index 5f7eea102..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/PrometheusMvcEndpointTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.exporter.common.TextFormat; -import org.apache.commons.lang3.StringUtils; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, classes = DummyBootApplication.class) -@TestPropertySource(properties = "management.security.enabled=false") -public class PrometheusMvcEndpointTest { - - @Value("${local.server.port}") - int localServerPort; - - @Autowired - TestRestTemplate template; - - @Test - public void testNameParamIsNull() throws Exception { - ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus", HttpMethod.GET, getEntity(), String.class); - - assertEquals(HttpStatus.OK, metricsResponse.getStatusCode()); - assertEquals(StringUtils.deleteWhitespace(TextFormat.CONTENT_TYPE_004), metricsResponse.getHeaders().getContentType().toString().toLowerCase()); - - } - - @Test - public void testAcceptPlainText() throws Exception { - - HttpHeaders headers = new HttpHeaders(); - headers.set("Accept", "text/plain"); - - ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus", HttpMethod.GET, new HttpEntity(headers), String.class); - - assertEquals(HttpStatus.OK, metricsResponse.getStatusCode()); - } - - @Test - public void testAcceptOpenMetrics() throws Exception { - - HttpHeaders headers = new HttpHeaders(); - headers.set("Accept", "application/openmetrics-text; version=0.0.1,text/plain;version=0.0.4;q=0.5,*/*;q=0.1"); - - ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus", HttpMethod.GET, new HttpEntity(headers), String.class); - - assertEquals(HttpStatus.OK, metricsResponse.getStatusCode()); - assertEquals(StringUtils.deleteWhitespace(TextFormat.CONTENT_TYPE_OPENMETRICS_100), metricsResponse.getHeaders().getContentType().toString().toLowerCase()); - assertTrue(metricsResponse.getBody().contains("# EOF")); - } - - @Test - public void testNameParamIsNotNull() { - ResponseEntity metricsResponse = template.exchange(getBaseUrl() + "/prometheus?name[]=foo_bar", HttpMethod.GET, getEntity(), String.class); - - assertEquals(HttpStatus.OK, metricsResponse.getStatusCode()); - assertEquals(StringUtils.deleteWhitespace(TextFormat.CONTENT_TYPE_004), metricsResponse.getHeaders().getContentType().toString().toLowerCase()); - - } - - public HttpEntity getEntity() { - HttpHeaders headers = new HttpHeaders(); - headers.set("Accept", "text/plain; version=0.0.4; charset=utf-8"); - return new HttpEntity(headers); - } - - private String getBaseUrl() { - return "http://localhost:" + localServerPort; - } -} diff --git a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java b/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java deleted file mode 100644 index a3f161bd9..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/src/test/java/io/prometheus/client/spring/boot/SpringBootMetricsCollectorTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.prometheus.client.spring.boot; - -import io.prometheus.client.CollectorRegistry; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.endpoint.PublicMetrics; -import org.springframework.boot.actuate.metrics.CounterService; -import org.springframework.boot.actuate.metrics.GaugeService; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Bean; -import org.springframework.test.context.junit4.SpringRunner; - -import java.util.Collection; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; - -@RunWith(SpringRunner.class) -@EnableAutoConfiguration -@SpringBootTest(classes = MetricsBootApplication.class) -public class SpringBootMetricsCollectorTest { - - @Autowired - private SpringBootMetricsCollector springBootMetricsCollector; - - @Autowired - private CounterService counterService; - - @Autowired - private GaugeService gaugeService; - - @Test - public void collect() throws Exception { - counterService.increment("foo"); - gaugeService.submit("bar", 3.14); - - CollectorRegistry defaultRegistry = CollectorRegistry.defaultRegistry; - assertThat(defaultRegistry.getSampleValue("counter_foo"), is(1.0)); - assertThat(defaultRegistry.getSampleValue("gauge_bar"), is(3.14)); - } -} - - -@SpringBootApplication -class MetricsBootApplication { - - @Bean - public SpringBootMetricsCollector springBootMetricsCollector(Collection publicMetrics) { - SpringBootMetricsCollector springBootMetricsCollector = new SpringBootMetricsCollector(publicMetrics); - springBootMetricsCollector.register(); - return springBootMetricsCollector; - } - -} \ No newline at end of file diff --git a/simpleclient-archive/simpleclient_spring_boot/version-rules.xml b/simpleclient-archive/simpleclient_spring_boot/version-rules.xml deleted file mode 100644 index f1b170b69..000000000 --- a/simpleclient-archive/simpleclient_spring_boot/version-rules.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - 2\..* - - - - From 8bb75446c6dca2a4e2c074e39fe34c1b061b028a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 8 Mar 2024 15:53:53 +0100 Subject: [PATCH 293/980] Document which JVM metric names have changed with 1.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/migration/simpleclient.md | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md index a954c9c04..82937a64b 100644 --- a/docs/content/migration/simpleclient.md +++ b/docs/content/migration/simpleclient.md @@ -98,3 +98,35 @@ counter.labelValues("/hello-world").inc(); Reasons why we changed the API: Changing the package names was a necessity because the previous package names were incompatible with the Java module system. However, renaming packages requires changing code anyway, so we decided to clean up some things. For example, the name `builder()` for a builder method is very common in the Java ecosystem, it's used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library more aligned with the broader Java ecosystem. If you are using the low level `Collector` API directly, you should have a look at the new callback metric types, see [/getting-started/callbacks/](../../getting-started/callbacks/). Chances are good that the new callback metrics have an easier way to achieve what you need than the old 0.16.0 code. + +JVM Metrics +----------- + +Version 0.16.0 provided the `simpleclient_hotspot` module for exposing built-in JVM metrics: + +```java +DefaultExports.initialize(); +``` + +With version 1.0.0 these metrics moved to the `prometheus-metrics-instrumentation-jvm` module and are initialized as follows: + +```java +JvmMetrics.builder().register(); +``` + +A full list of the available JVM metrics can be found on [/instrumentation/jvm](../../instrumentation/jvm/). + +Most JVM metric names remained the same, except for a few cases where the old 0.16.0 metric names were not compliant with the [OpenMetrics](https://openmetrics.io) specification. OpenMetrics requires the unit to be a suffix, so we renamed metrics where the unit was in the middle of the metric name and moved the unit to the end of the metric name. The following metric names changed: + +* `jvm_memory_bytes_committed` -> `jvm_memory_committed_bytes` +* `jvm_memory_bytes_init` -> `jvm_memory_init_bytes` +* `jvm_memory_bytes_max` -> `jvm_memory_max_bytes` +* `jvm_memory_pool_bytes_committed` -> `jvm_memory_pool_committed_bytes` +* `jvm_memory_pool_bytes_init` -> `jvm_memory_pool_init_bytes` +* `jvm_memory_pool_bytes_max` -> `jvm_memory_pool_max_bytes` +* `jvm_memory_pool_bytes_used` -> `jvm_memory_pool_used_bytes` +* `jvm_memory_pool_collection_bytes_committed` -> `jvm_memory_pool_collection_committed_bytes` +* `jvm_memory_pool_collection_bytes_init` -> `jvm_memory_pool_collection_init_bytes` +* `jvm_memory_pool_collection_bytes_max` -> `jvm_memory_pool_collection_max_bytes` +* `jvm_memory_pool_collection_bytes_used` -> `jvm_memory_pool_collection_used_bytes` +* `jvm_info` -> `jvm_runtime_info` From d84b0fababc439d5f8ccad33edea68a62b8082f6 Mon Sep 17 00:00:00 2001 From: dhoard Date: Thu, 21 Mar 2024 00:15:28 -0400 Subject: [PATCH 294/980] Added try/finally to close the HttpExchange Signed-off-by: dhoard --- .../metrics/exporter/httpserver/DefaultHandler.java | 13 ++++++++----- .../metrics/exporter/httpserver/HealthyHandler.java | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java index e8a54e0cf..0e6342a34 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java @@ -58,10 +58,13 @@ public DefaultHandler() { @Override public void handle(HttpExchange exchange) throws IOException { - exchange.getResponseHeaders().set("Content-Type", contentType); - exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); - exchange.sendResponseHeaders(200, responseBytes.length); - exchange.getResponseBody().write(responseBytes); - exchange.close(); + try { + exchange.getResponseHeaders().set("Content-Type", contentType); + exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); + exchange.sendResponseHeaders(200, responseBytes.length); + exchange.getResponseBody().write(responseBytes); + } finally { + exchange.close(); + } } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java index 03b647d99..4fbdb9426 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java @@ -22,10 +22,13 @@ public HealthyHandler() { @Override public void handle(HttpExchange exchange) throws IOException { - exchange.getResponseHeaders().set("Content-Type", contentType); - exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); - exchange.sendResponseHeaders(200, responseBytes.length); - exchange.getResponseBody().write(responseBytes); - exchange.close(); + try { + exchange.getResponseHeaders().set("Content-Type", contentType); + exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); + exchange.sendResponseHeaders(200, responseBytes.length); + exchange.getResponseBody().write(responseBytes); + } finally { + exchange.close(); + } } } From 7f0265184adb86182fb7be029acbf5c2efd1c742 Mon Sep 17 00:00:00 2001 From: Breno A Date: Thu, 21 Mar 2024 14:58:34 -0300 Subject: [PATCH 295/980] fix: gdoc-md overflow (#926) Signed-off-by: Breno A --- docs/static/custom.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/static/custom.css b/docs/static/custom.css index 41ab7c562..ed919a35d 100644 --- a/docs/static/custom.css +++ b/docs/static/custom.css @@ -37,3 +37,7 @@ --footer-link-color-visited: #ffffff; } } + +.gdoc-markdown pre,.gdoc-markdown code { + overflow: auto; +} \ No newline at end of file From fc447f8861a48040ad4b956cf3e5af86f99985e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 21 Mar 2024 20:11:43 +0100 Subject: [PATCH 296/980] Add optional SpanContext parameter to ExemplarSampler (#929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/config/ExemplarsProperties.java | 2 +- .../core/exemplars/ExemplarSampler.java | 14 ++- .../core/exemplars/ExemplarSamplerTest.java | 19 +--- .../exemplars/SpanContextSupplierTest.java | 103 ++++++++++++++++++ .../metrics/tracer/common/SpanContext.java | 4 +- 5 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java index 258e7f45d..ff955bc50 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java @@ -107,7 +107,7 @@ public Builder sampleIntervalMilliseconds(int sampleIntervalMilliseconds) { return this; } - public ExemplarsProperties builder() { + public ExemplarsProperties build() { return new ExemplarsProperties(minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds); } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java index 9472b237f..af898724d 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -37,11 +37,23 @@ public class ExemplarSampler { // to be overwritten by automatic exemplar sampling. exemplars.lengt == customExemplars.length private final AtomicBoolean acceptingNewExemplars = new AtomicBoolean(true); private final AtomicBoolean acceptingNewCustomExemplars = new AtomicBoolean(true); + private final SpanContext spanContext; // may be null, in that case SpanContextSupplier.getSpanContext() is used. public ExemplarSampler(ExemplarSamplerConfig config) { + this(config, null); + } + + /** + * Constructor with an additional {code spanContext} argument. + * This is useful for testing, but may also be useful in some production scenarios. + * If {@code spanContext != null} that spanContext is used and {@link SpanContextSupplier} is not used. + * If {@code spanContext == null} the {@link SpanContextSupplier#getSpanContext()} is called to find a span context. + */ + public ExemplarSampler(ExemplarSamplerConfig config, SpanContext spanContext) { this.config = config; this.exemplars = new Exemplar[config.getNumberOfExemplars()]; this.customExemplars = new Exemplar[exemplars.length]; + this.spanContext = spanContext; } public Exemplars collect() { @@ -307,8 +319,8 @@ private long updateExemplar(int index, double value, long now) { } private Labels doSampleExemplar() { + SpanContext spanContext = this.spanContext != null ? this.spanContext : SpanContextSupplier.getSpanContext(); try { - SpanContext spanContext = SpanContextSupplier.getSpanContext(); if (spanContext != null) { if (spanContext.isCurrentSpanSampled()) { String spanId = spanContext.getCurrentSpanId(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java index 24882065e..1af5da42b 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java @@ -76,8 +76,7 @@ public void tearDown() { public void testIsSampled() throws Exception { SpanContext context = new SpanContext(); context.isSampled = false; - SpanContextSupplier.setSpanContext(context); - ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(), context); Thread.sleep(tick); // t = 1 tick sampler.observe(0.3); // no sampled, because isSampled() returns false assertExemplars(sampler); // empty @@ -85,9 +84,7 @@ public void testIsSampled() throws Exception { @Test public void testDefaultConfigHasFourExemplars() throws Exception { - SpanContext context = new SpanContext(); - SpanContextSupplier.setSpanContext(context); - ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext()); Thread.sleep(tick); // t = 1 tick sampler.observe(0.3); Thread.sleep(sampleInterval + tick); // t = 12 tick @@ -104,9 +101,7 @@ public void testDefaultConfigHasFourExemplars() throws Exception { @Test public void testEmptyBuckets() throws Exception { - SpanContext context = new SpanContext(); - SpanContextSupplier.setSpanContext(context); - ExemplarSampler sampler = new ExemplarSampler(makeConfig(Double.POSITIVE_INFINITY)); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(Double.POSITIVE_INFINITY), new SpanContext()); Thread.sleep(tick); // t = 1 tick sampler.observe(0.8); // observed in the +Inf bucket Thread.sleep(sampleInterval + tick); // t = 12 tick @@ -117,9 +112,7 @@ public void testEmptyBuckets() throws Exception { @Test public void testDefaultExemplarsBuckets() throws Exception { - SpanContext context = new SpanContext(); - SpanContextSupplier.setSpanContext(context); - ExemplarSampler sampler = new ExemplarSampler(makeConfig(0.2, 0.4, 0.6, 0.8, 1.0, Double.POSITIVE_INFINITY)); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(0.2, 0.4, 0.6, 0.8, 1.0, Double.POSITIVE_INFINITY), new SpanContext()); Scheduler.awaitInitialization(); Thread.sleep(tick); // t = 1 tick sampler.observe(0.3); @@ -150,9 +143,7 @@ public void testCustomExemplarsNoBuckets() throws Exception { @Test public void testDefaultExemplarsNoBuckets() throws Exception { - SpanContext context = new SpanContext(); - SpanContextSupplier.setSpanContext(context); - ExemplarSampler sampler = new ExemplarSampler(makeConfig()); + ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext()); Scheduler.awaitInitialization(); Thread.sleep(tick); // t = 1 tick sampler.observe(1); // observed diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java new file mode 100644 index 000000000..033420950 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java @@ -0,0 +1,103 @@ +package io.prometheus.metrics.core.exemplars; + +import io.prometheus.metrics.config.ExemplarsProperties; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import org.junit.*; + +import static io.prometheus.metrics.model.snapshots.Exemplar.TRACE_ID; + +public class SpanContextSupplierTest { + + public SpanContext makeSpanContext(String traceId, String spanId) { + + return new SpanContext() { + @Override + public String getCurrentTraceId() { + return traceId; + } + + @Override + public String getCurrentSpanId() { + return spanId; + } + + @Override + public boolean isCurrentSpanSampled() { + return true; + } + + @Override + public void markCurrentSpanAsExemplar() { + } + }; + } + + SpanContext spanContextA = makeSpanContext("A", "a"); + SpanContext spanContextB = makeSpanContext("B", "b"); + SpanContext origSpanContext; + + ExemplarSamplerConfig config = new ExemplarSamplerConfig( + 10, // min retention period in milliseconds + 20, // max retention period in milliseconds + 5, // sample interval in millisecnods + 1, // number of exemplars + null // histogram upper bounds + ); + + @Before + public void setUp() { + origSpanContext = SpanContextSupplier.getSpanContext(); + } + + @After + public void tearDown() { + SpanContextSupplier.setSpanContext(origSpanContext); + } + + /** + * Test: When a {@link SpanContext} is provided as a constructor argument to the {@link ExemplarSampler}, + * then that {@link SpanContext} is used, not the one from the {@link SpanContextSupplier}. + */ + @Test + public void testConstructorInjection() { + ExemplarsProperties properties = ExemplarsProperties.builder().build(); + ExemplarSamplerConfig config = new ExemplarSamplerConfig(properties, 1); + ExemplarSampler exemplarSampler = new ExemplarSampler(config, spanContextA); + + SpanContextSupplier.setSpanContext(spanContextB); + exemplarSampler.observe(1.0); + Exemplars exemplars = exemplarSampler.collect(); + Assert.assertEquals(1, exemplars.size()); + Exemplar exemplar = exemplars.get(0); + Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID)); + } + + /** + * When the global {@link SpanContext} is updated via {@link SpanContextSupplier#setSpanContext(SpanContext)}, + * the {@link ExemplarSampler} recognizes the update (unless a {@link ExemplarSampler} was provided as + * constructor argument to {@link ExemplarSampler}). + */ + @Test + public void testUpdateSpanContext() throws InterruptedException { + ExemplarSampler exemplarSampler = new ExemplarSampler(config); + + SpanContextSupplier.setSpanContext(spanContextB); + exemplarSampler.observe(1.0); + Exemplars exemplars = exemplarSampler.collect(); + Assert.assertEquals(1, exemplars.size()); + Exemplar exemplar = exemplars.get(0); + Assert.assertEquals("B", exemplar.getLabels().get(TRACE_ID)); + + Thread.sleep(15); // more than the minimum retention period defined in config above. + + SpanContextSupplier.setSpanContext(spanContextA); + exemplarSampler.observe(1.0); + exemplars = exemplarSampler.collect(); + Assert.assertEquals(1, exemplars.size()); + exemplar = exemplars.get(0); + Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID)); + } +} diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java index b53fe4d20..e71cef98e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java @@ -2,8 +2,8 @@ public interface SpanContext { - public static final String EXEMPLAR_ATTRIBUTE_NAME = "exemplar"; - public static final String EXEMPLAR_ATTRIBUTE_VALUE = "true"; + String EXEMPLAR_ATTRIBUTE_NAME = "exemplar"; + String EXEMPLAR_ATTRIBUTE_VALUE = "true"; /** * @return the current trace id, or {@code null} if this call is not happening within a span context. From 40c3599d8b49b63bf84900921af43b6b0a9f5f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 21 Mar 2024 20:38:02 +0100 Subject: [PATCH 297/980] Allow Exemplars on histogram _count (#930) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/config/ExporterProperties.java | 2 +- .../OpenMetricsTextFormatWriter.java | 20 +-- .../ExpositionFormatsTest.java | 164 ++++++++++++++++-- .../metrics/model/snapshots/Exemplars.java | 21 ++- .../model/snapshots/ExemplarsTest.java | 12 ++ .../bridge/SimpleclientCollectorTest.java | 2 +- 6 files changed, 184 insertions(+), 37 deletions(-) diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java index e715a7a2c..9493b571c 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -27,7 +27,7 @@ public boolean getIncludeCreatedTimestamps() { /** * Allow Exemplars on all metric types in OpenMetrics format? - * Default is {@code false}, which means Exemplars will only be added for Counters and Histograms. + * Default is {@code false}, which means Exemplars will only be added for Counters and Histogram buckets. */ public boolean getExemplarsOnAllMetricTypes() { return exemplarsOnAllMetricTypes != null && exemplarsOnAllMetricTypes; diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index eae5c1b8c..dd92391ff 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -138,11 +138,9 @@ private void writeClassicHistogramBuckets(OutputStreamWriter writer, MetricMetad } writeScrapeTimestampAndExemplar(writer, data, exemplar); } + // In OpenMetrics format, histogram _count and _sum are either both present or both absent. if (data.hasCount() && data.hasSum()) { - // In OpenMetrics format, histogram _count and _sum are either both present or both absent. - // While Prometheus allows Exemplars for histogram's _count and _sum now, we don't - // use Exemplars here to be backwards compatible with previous behavior. - writeCountAndSum(writer, metadata, data, countSuffix, sumSuffix, Exemplars.EMPTY); + writeCountAndSum(writer, metadata, data, countSuffix, sumSuffix, exemplars); } writeCreated(writer, metadata, data); } @@ -241,7 +239,7 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) t writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); writeDouble(writer, data.getValue()); if (exemplarsOnAllMetricTypesEnabled) { - writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); } else { writeScrapeTimestampAndExemplar(writer, data, null); } @@ -249,13 +247,11 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) t } private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata, DistributionDataPointSnapshot data, String countSuffix, String sumSuffix, Exemplars exemplars) throws IOException { - int exemplarIndex = 0; if (data.hasCount()) { writeNameAndLabels(writer, metadata.getPrometheusName(), countSuffix, data.getLabels()); writeLong(writer, data.getCount()); - if (exemplars.size() > 0) { - writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); - exemplarIndex = exemplarIndex + 1 % exemplars.size(); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, exemplars.getLatest()); } else { writeScrapeTimestampAndExemplar(writer, data, null); } @@ -263,11 +259,7 @@ private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata if (data.hasSum()) { writeNameAndLabels(writer, metadata.getPrometheusName(), sumSuffix, data.getLabels()); writeDouble(writer, data.getSum()); - if (exemplars.size() > 0) { - writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); - } else { - writeScrapeTimestampAndExemplar(writer, data, null); - } + writeScrapeTimestampAndExemplar(writer, data, null); } } diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 7451e7c10..10c7d3a0d 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -234,6 +234,13 @@ public void testCounterWithDots() throws IOException { @Test public void testGaugeComplete() throws IOException { String openMetricsText = "" + + "# TYPE disk_usage_ratio gauge\n" + + "# UNIT disk_usage_ratio ratio\n" + + "# HELP disk_usage_ratio percentage used\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + "# TYPE disk_usage_ratio gauge\n" + "# UNIT disk_usage_ratio ratio\n" + "# HELP disk_usage_ratio percentage used\n" + @@ -282,6 +289,7 @@ public void testGaugeComplete() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, gauge); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gauge); assertPrometheusText(prometheusText, gauge); assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); assertPrometheusTextWithoutCreated(prometheusText, gauge); @@ -315,6 +323,12 @@ public void testGaugeMinimal() throws IOException { @Test public void testGaugeWithDots() throws IOException { String openMetricsText = "" + + "# TYPE my_temperature_celsius gauge\n" + + "# UNIT my_temperature_celsius celsius\n" + + "# HELP my_temperature_celsius Temperature\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + "# TYPE my_temperature_celsius gauge\n" + "# UNIT my_temperature_celsius celsius\n" + "# HELP my_temperature_celsius Temperature\n" + @@ -350,6 +364,7 @@ public void testGaugeWithDots() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, gauge); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gauge); assertPrometheusText(prometheusText, gauge); assertPrometheusProtobuf(prometheusProtobuf, gauge); } @@ -357,6 +372,23 @@ public void testGaugeWithDots() throws IOException { @Test public void testSummaryComplete() throws IOException { String openMetricsText = "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + "# TYPE http_request_duration_seconds summary\n" + "# UNIT http_request_duration_seconds seconds\n" + "# HELP http_request_duration_seconds request duration\n" + @@ -364,13 +396,13 @@ public void testSummaryComplete() throws IOException { "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + "# EOF\n"; String prometheusText = "" + @@ -394,16 +426,16 @@ public void testSummaryComplete() throws IOException { "# TYPE http_request_duration_seconds summary\n" + "# UNIT http_request_duration_seconds seconds\n" + "# HELP http_request_duration_seconds request duration\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = "" + "# HELP http_request_duration_seconds request duration\n" + @@ -481,6 +513,7 @@ public void testSummaryComplete() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, summary); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, summary); assertPrometheusText(prometheusText, summary); assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, summary); assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, summary); @@ -689,11 +722,18 @@ public void testSummaryEmptyAndNonEmpty() throws IOException { @Test public void testSummaryWithDots() throws IOException { String openMetricsText = "" + + "# TYPE my_request_duration_seconds summary\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + "# TYPE my_request_duration_seconds summary\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 1 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + "# EOF\n"; String prometheusText = "" + "# HELP my_request_duration_seconds Request duration in seconds\n" + @@ -725,6 +765,7 @@ public void testSummaryWithDots() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, summary); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, summary); assertPrometheusText(prometheusText, summary); assertPrometheusProtobuf(prometheusProtobuf, summary); } @@ -747,6 +788,22 @@ public void testClassicHistogramComplete() throws Exception { "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; String prometheusText = "" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + @@ -860,6 +917,7 @@ public void testClassicHistogramComplete() throws Exception { .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); assertPrometheusText(prometheusText, histogram); assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, histogram); assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, histogram); @@ -968,6 +1026,21 @@ public void testClassicGaugeHistogramComplete() throws IOException { "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + + "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; String prometheusText = "" + "# HELP cache_size_bytes number of bytes in the cache\n" + "# TYPE cache_size_bytes histogram\n" + @@ -1084,6 +1157,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gaugeHistogram); assertPrometheusText(prometheusText, gaugeHistogram); assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, gaugeHistogram); assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, gaugeHistogram); @@ -1190,6 +1264,14 @@ public void testClassicHistogramWithDots() throws IOException { "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + + "# EOF\n"; String prometheusText = "" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# TYPE my_request_duration_seconds histogram\n" + @@ -1227,6 +1309,7 @@ public void testClassicHistogramWithDots() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); assertPrometheusText(prometheusText, histogram); assertPrometheusProtobuf(prometheusProtobuf, histogram); } @@ -1237,15 +1320,28 @@ public void testNativeHistogramComplete() throws IOException { "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + + "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + + "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + + "# EOF\n"; String prometheusText = "" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + @@ -1263,10 +1359,10 @@ public void testNativeHistogramComplete() throws IOException { "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + "# EOF\n"; @@ -1388,6 +1484,7 @@ public void testNativeHistogramComplete() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, nativeHistogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, nativeHistogram); assertPrometheusText(prometheusText, nativeHistogram); assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, nativeHistogram); assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, nativeHistogram); @@ -1438,6 +1535,14 @@ public void testNativeHistogramWithDots() throws IOException { "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4 # " + exemplarWithDotsString + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + + "# EOF\n"; String prometheusText = "" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# TYPE my_request_duration_seconds histogram\n" + @@ -1483,6 +1588,7 @@ public void testNativeHistogramWithDots() throws IOException { .build()) .build(); assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); assertPrometheusText(prometheusText, histogram); assertPrometheusProtobuf(prometheusProtobuf, histogram); } @@ -1653,6 +1759,13 @@ public void testStateSetWithDots() throws IOException { @Test public void testUnknownComplete() throws IOException { String openMetrics = "" + + "# TYPE my_special_thing_bytes unknown\n" + + "# UNIT my_special_thing_bytes bytes\n" + + "# HELP my_special_thing_bytes help message\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n" + + "# EOF\n"; + String openMetricsWithExemplarsOnAllTimeSeries = "" + "# TYPE my_special_thing_bytes unknown\n" + "# UNIT my_special_thing_bytes bytes\n" + "# HELP my_special_thing_bytes help message\n" + @@ -1682,6 +1795,7 @@ public void testUnknownComplete() throws IOException { .build()) .build(); assertOpenMetricsText(openMetrics, unknown); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsWithExemplarsOnAllTimeSeries, unknown); assertPrometheusText(prometheus, unknown); assertOpenMetricsTextWithoutCreated(openMetrics, unknown); assertPrometheusTextWithoutCreated(prometheus, unknown); @@ -1711,6 +1825,12 @@ public void testUnknownMinimal() throws IOException { @Test public void testUnknownWithDots() throws IOException { String openMetrics = "" + + "# TYPE some_unknown_metric unknown\n" + + "# UNIT some_unknown_metric bytes\n" + + "# HELP some_unknown_metric help message\n" + + "some_unknown_metric{test_env=\"7\"} 0.7\n" + + "# EOF\n"; + String openMetricsWithExemplarsOnAllTimeSeries = "" + "# TYPE some_unknown_metric unknown\n" + "# UNIT some_unknown_metric bytes\n" + "# HELP some_unknown_metric help message\n" + @@ -1741,6 +1861,7 @@ public void testUnknownWithDots() throws IOException { .build()) .build(); assertOpenMetricsText(openMetrics, unknown); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsWithExemplarsOnAllTimeSeries, unknown); assertPrometheusText(prometheus, unknown); assertPrometheusProtobuf(prometheusProtobuf, unknown); } @@ -1789,6 +1910,13 @@ public void testLabelValueEscape() throws IOException { } private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } + + private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); writer.write(out, MetricSnapshots.of(snapshot)); @@ -1797,7 +1925,7 @@ private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) thr private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); writer.write(out, MetricSnapshots.of(snapshot)); Assert.assertEquals(expected, out.toString()); } 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 dc77be55a..b5286b0c2 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 @@ -21,7 +21,14 @@ public class Exemplars implements Iterable { private final List exemplars; private Exemplars(Collection exemplars) { - this.exemplars = Collections.unmodifiableList(new ArrayList<>(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); } /** @@ -61,16 +68,24 @@ public Exemplar get(int 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 (int i = 0; i < exemplars.size(); i++) { Exemplar exemplar = exemplars.get(i); double value = exemplar.getValue(); if (value > lowerBound && value <= upperBound) { - return exemplar; + if (result == null) { + result = exemplar; + } else if (result.hasTimestamp() && exemplar.hasTimestamp()) { + if (exemplar.getTimestampMillis() > result.getTimestampMillis()) { + result = exemplar; + } + } } } - return null; + return result; } /** diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java index 5549c0efd..4ca64d6fb 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -37,4 +37,16 @@ public void testImmutable() { iterator.next(); iterator.remove(); } + + @Test + public void testGet() { + Exemplar oldest = Exemplar.builder().timestampMillis(System.currentTimeMillis() - 100).value(1.8).build(); + Exemplar middle = Exemplar.builder().timestampMillis(System.currentTimeMillis() - 50).value(1.2).build(); + Exemplar newest = Exemplar.builder().timestampMillis(System.currentTimeMillis()).value(1.0).build(); + Exemplars exemplars = Exemplars.of(oldest, newest, middle); + Exemplar result = exemplars.get(1.1, 1.9); // newest is not within these bounds + Assert.assertSame(result, middle); + result = exemplars.get(0.9, Double.POSITIVE_INFINITY); + Assert.assertSame(result, newest); + } } diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java index 9d1e8f1b9..8a5e2c018 100644 --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -242,7 +242,7 @@ private String origOpenMetrics() throws IOException { private String newOpenMetrics() throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); writer.write(out, newRegistry.scrape()); return out.toString(StandardCharsets.UTF_8.name()); } From b16dda738cea375e65fae64d977bd82119a1c880 Mon Sep 17 00:00:00 2001 From: Christoph MEIER Date: Wed, 31 Jan 2024 13:26:23 +0100 Subject: [PATCH 298/980] feat: add jvm native memory metrics Signed-off-by: Christoph MEIER --- .../instrumentation/jvm/JvmMetrics.java | 1 + .../jvm/JvmNativeMemoryMetrics.java | 212 ++++++++++++++++ .../jvm/JvmNativeMemoryMetricsTest.java | 226 ++++++++++++++++++ 3 files changed, 439 insertions(+) create mode 100644 prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java index 32602bd69..fa909f629 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java @@ -60,6 +60,7 @@ public void register(PrometheusRegistry registry) { JvmGarbageCollectorMetrics.builder(config).register(registry); JvmMemoryPoolAllocationMetrics.builder(config).register(registry); JvmMemoryMetrics.builder(config).register(registry); + JvmNativeMemoryMetrics.builder(config).register(registry); JvmRuntimeInfoMetric.builder(config).register(registry); ProcessMetrics.builder(config).register(registry); } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java new file mode 100644 index 000000000..8e60a31d9 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java @@ -0,0 +1,212 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.metrics.GaugeWithCallback; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Unit; + +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import java.lang.management.ManagementFactory; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * JVM native memory. JVM native memory tracking is disabled by default. You need to enable it by starting your JVM with this flag: + *
      -XX:NativeMemoryTracking=summary
      + *

      + * When native memory tracking is disabled the metrics are not registered either. + *

      + *

      + * The {@link JvmNativeMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + *

      {@code
      + *   JvmMetrics.builder().register();
      + * }
      + * However, if you want only the {@link JvmNativeMemoryMetrics} you can also register them directly: + *
      {@code
      + *   JvmNativeMemoryMetrics.builder().register();
      + * }
      + * Example metrics being exported: + *
      + * # HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.
      + * # TYPE jvm_native_memory_committed_bytes gauge
      + * jvm_native_memory_committed_bytes{pool="Arena Chunk"} 58480.0
      + * jvm_native_memory_committed_bytes{pool="Arguments"} 25119.0
      + * jvm_native_memory_committed_bytes{pool="Class"} 1.00609438E8
      + * jvm_native_memory_committed_bytes{pool="Code"} 2.7980888E7
      + * jvm_native_memory_committed_bytes{pool="Compiler"} 529922.0
      + * jvm_native_memory_committed_bytes{pool="GC"} 515466.0
      + * jvm_native_memory_committed_bytes{pool="Internal"} 673194.0
      + * jvm_native_memory_committed_bytes{pool="Java Heap"} 4.0923136E7
      + * jvm_native_memory_committed_bytes{pool="Logging"} 4596.0
      + * jvm_native_memory_committed_bytes{pool="Module"} 96408.0
      + * jvm_native_memory_committed_bytes{pool="Native Memory Tracking"} 3929432.0
      + * jvm_native_memory_committed_bytes{pool="Other"} 667656.0
      + * jvm_native_memory_committed_bytes{pool="Safepoint"} 8192.0
      + * jvm_native_memory_committed_bytes{pool="Symbol"} 2.4609808E7
      + * jvm_native_memory_committed_bytes{pool="Synchronizer"} 272520.0
      + * jvm_native_memory_committed_bytes{pool="Thread"} 3546896.0
      + * jvm_native_memory_committed_bytes{pool="Total"} 2.0448392E8
      + * jvm_native_memory_committed_bytes{pool="Tracing"} 1.0
      + * jvm_native_memory_committed_bytes{pool="Unknown"} 32768.0
      + * # HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.
      + * # TYPE jvm_native_memory_reserved_bytes gauge
      + * jvm_native_memory_reserved_bytes{pool="Arena Chunk"} 25736.0
      + * jvm_native_memory_reserved_bytes{pool="Arguments"} 25119.0
      + * jvm_native_memory_reserved_bytes{pool="Class"} 1.162665374E9
      + * jvm_native_memory_reserved_bytes{pool="Code"} 2.55386712E8
      + * jvm_native_memory_reserved_bytes{pool="Compiler"} 529922.0
      + * jvm_native_memory_reserved_bytes{pool="GC"} 1695114.0
      + * jvm_native_memory_reserved_bytes{pool="Internal"} 673191.0
      + * jvm_native_memory_reserved_bytes{pool="Java Heap"} 4.02653184E8
      + * jvm_native_memory_reserved_bytes{pool="Logging"} 4596.0
      + * jvm_native_memory_reserved_bytes{pool="Module"} 96408.0
      + * jvm_native_memory_reserved_bytes{pool="Native Memory Tracking"} 3929400.0
      + * jvm_native_memory_reserved_bytes{pool="Other"} 667656.0
      + * jvm_native_memory_reserved_bytes{pool="Safepoint"} 8192.0
      + * jvm_native_memory_reserved_bytes{pool="Symbol"} 2.4609808E7
      + * jvm_native_memory_reserved_bytes{pool="Synchronizer"} 272520.0
      + * jvm_native_memory_reserved_bytes{pool="Thread"} 3.383272E7
      + * jvm_native_memory_reserved_bytes{pool="Total"} 1.887108421E9
      + * jvm_native_memory_reserved_bytes{pool="Tracing"} 1.0
      + * jvm_native_memory_reserved_bytes{pool="Unknown"} 32768.0
      + * 
      + */ +public class JvmNativeMemoryMetrics { + private static final String JVM_NATIVE_MEMORY_RESERVED_BYTES = "jvm_native_memory_reserved_bytes"; + private static final String JVM_NATIVE_MEMORY_COMMITTED_BYTES = "jvm_native_memory_committed_bytes"; + + private static final Pattern pattern = Pattern.compile("\\s*([A-Z][A-Za-z\\s]*[A-Za-z]+).*reserved=(\\d+), committed=(\\d+)"); + + /** + * Package private. For testing only. + */ + static final AtomicBoolean isEnabled = new AtomicBoolean(true); + + private final PrometheusProperties config; + private final PlatformMBeanServerAdapter adapter; + + private JvmNativeMemoryMetrics(PrometheusProperties config, PlatformMBeanServerAdapter adapter) { + this.config = config; + this.adapter = adapter; + } + + private void register(PrometheusRegistry registry) { + // first call will check if enabled and set the flag + vmNativeMemorySummaryInBytesOrEmpty(); + if (isEnabled.get()) { + GaugeWithCallback.builder(config) + .name(JVM_NATIVE_MEMORY_RESERVED_BYTES) + .help("Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.") + .unit(Unit.BYTES) + .labelNames("pool") + .callback(makeCallback(true)) + .register(registry); + + GaugeWithCallback.builder(config) + .name(JVM_NATIVE_MEMORY_COMMITTED_BYTES) + .help("Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.") + .unit(Unit.BYTES) + .labelNames("pool") + .callback(makeCallback(false)) + .register(registry); + } + } + + private Consumer makeCallback(Boolean reserved) { + return callback -> { + String summary = vmNativeMemorySummaryInBytesOrEmpty(); + if (!summary.isEmpty()) { + Matcher matcher = pattern.matcher(summary); + while (matcher.find()) { + String category = matcher.group(1); + long value; + if (reserved) { + value = Long.parseLong(matcher.group(2)); + } else { + value = Long.parseLong(matcher.group(3)); + } + callback.call(value, category); + } + } + }; + } + + private String vmNativeMemorySummaryInBytesOrEmpty() { + if (!isEnabled.get()) { + return ""; + } + try { + // requires -XX:NativeMemoryTracking=summary + String summary = adapter.vmNativeMemorySummaryInBytes(); + if (summary.isEmpty() || summary.trim().contains("Native memory tracking is not enabled")) { + isEnabled.set(false); + return ""; + } else { + return summary; + } + } catch (Exception ex) { + // ignore errors + isEnabled.set(false); + return ""; + } + } + + interface PlatformMBeanServerAdapter { + String vmNativeMemorySummaryInBytes(); + } + + static class DefaultPlatformMBeanServerAdapter implements PlatformMBeanServerAdapter { + @Override + public String vmNativeMemorySummaryInBytes() { + try { + return (String) ManagementFactory.getPlatformMBeanServer().invoke( + new ObjectName("com.sun.management:type=DiagnosticCommand"), + "vmNativeMemory", + new Object[]{new String[]{"summary", "scale=B"}}, + new String[]{"[Ljava.lang.String;"}); + } catch (ReflectionException | MalformedObjectNameException | InstanceNotFoundException | MBeanException e) { + throw new IllegalStateException("Native memory tracking is not enabled", e); + } + } + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private final PlatformMBeanServerAdapter adapter; + + private Builder(PrometheusProperties config) { + this(config, new DefaultPlatformMBeanServerAdapter()); + } + + /** + * Package private. For testing only. + */ + Builder(PrometheusProperties config, PlatformMBeanServerAdapter adapter) { + this.config = config; + this.adapter = adapter; + } + + public void register() { + register(PrometheusRegistry.defaultRegistry); + } + + public void register(PrometheusRegistry registry) { + new JvmNativeMemoryMetrics(config, adapter).register(registry); + } + } +} diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java new file mode 100644 index 000000000..4b9321660 --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java @@ -0,0 +1,226 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; + +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.when; + +public class JvmNativeMemoryMetricsTest extends TestCase { + + @Test + public void testNativeMemoryTrackingFail() throws IOException { + JvmNativeMemoryMetrics.isEnabled.set(true); + + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()).thenThrow(new RuntimeException("mock")); + + PrometheusRegistry registry = new PrometheusRegistry(); + new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testNativeMemoryTrackingEmpty() throws IOException { + JvmNativeMemoryMetrics.isEnabled.set(true); + + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()).thenReturn(""); + + PrometheusRegistry registry = new PrometheusRegistry(); + new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testNativeMemoryTrackingDisabled() throws IOException { + JvmNativeMemoryMetrics.isEnabled.set(true); + + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()).thenReturn("Native memory tracking is not enabled"); + + PrometheusRegistry registry = new PrometheusRegistry(); + new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testNativeMemoryTrackingEnabled() throws IOException { + JvmNativeMemoryMetrics.isEnabled.set(true); + + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()).thenReturn( + "Native Memory Tracking:\n" + + "\n" + + "Total: reserved=10341970661, committed=642716389\n" + + " malloc: 27513573 #22947\n" + + " mmap: reserved=10314457088, committed=615202816\n" + + "\n" + + "- Java Heap (reserved=8531214336, committed=536870912)\n" + + " (mmap: reserved=8531214336, committed=536870912) \n" + + " \n" + + "- Class (reserved=1073899939, committed=616867)\n" + + " (classes #1630)\n" + + " ( instance classes #1462, array classes #168)\n" + + " (malloc=158115 #2350) \n" + + " (mmap: reserved=1073741824, committed=458752) \n" + + " ( Metadata: )\n" + + " ( reserved=67108864, committed=2818048)\n" + + " ( used=2748008)\n" + + " ( waste=70040 =2.49%)\n" + + " ( Class space:)\n" + + " ( reserved=1073741824, committed=458752)\n" + + " ( used=343568)\n" + + " ( waste=115184 =25.11%)\n" + + " \n" + + "- Thread (reserved=21020080, committed=847280)\n" + + " (thread #20)\n" + + " (stack: reserved=20971520, committed=798720)\n" + + " (malloc=27512 #125) \n" + + " (arena=21048 #37)\n" + + " \n" + + "- Code (reserved=253796784, committed=7836080)\n" + + " (malloc=105944 #1403) \n" + + " (mmap: reserved=253689856, committed=7729152) \n" + + " (arena=984 #1)\n" + + " \n" + + "- GC (reserved=373343252, committed=76530708)\n" + + " (malloc=22463508 #720) \n" + + " (mmap: reserved=350879744, committed=54067200) \n" + + " \n" + + "- Compiler (reserved=1926356, committed=1926356)\n" + + " (malloc=20428 #73) \n" + + " (arena=1905928 #20)\n" + + " \n" + + "- Internal (reserved=242257, committed=242257)\n" + + " (malloc=176721 #1808) \n" + + " (mmap: reserved=65536, committed=65536) \n" + + " \n" + + "- Other (reserved=4096, committed=4096)\n" + + " (malloc=4096 #2) \n" + + " \n" + + "- Symbol (reserved=1505072, committed=1505072)\n" + + " (malloc=1136432 #14482) \n" + + " (arena=368640 #1)\n" + + " \n" + + "- Native Memory Tracking (reserved=373448, committed=373448)\n" + + " (malloc=6280 #91) \n" + + " (tracking overhead=367168)\n" + + " \n" + + "- Shared class space (reserved=16777216, committed=12386304)\n" + + " (mmap: reserved=16777216, committed=12386304) \n" + + " \n" + + "- Arena Chunk (reserved=503216, committed=503216)\n" + + " (malloc=503216) \n" + + " \n" + + "- Tracing (reserved=33097, committed=33097)\n" + + " (malloc=369 #10) \n" + + " (arena=32728 #1)\n" + + " \n" + + "- Arguments (reserved=160, committed=160)\n" + + " (malloc=160 #5) \n" + + " \n" + + "- Module (reserved=169168, committed=169168)\n" + + " (malloc=169168 #1266) \n" + + " \n" + + "- Safepoint (reserved=8192, committed=8192)\n" + + " (mmap: reserved=8192, committed=8192) \n" + + " \n" + + "- Synchronization (reserved=31160, committed=31160)\n" + + " (malloc=31160 #452) \n" + + " \n" + + "- Serviceability (reserved=600, committed=600)\n" + + " (malloc=600 #6) \n" + + " \n" + + "- Metaspace (reserved=67120768, committed=2829952)\n" + + " (malloc=11904 #12) \n" + + " (mmap: reserved=67108864, committed=2818048) \n" + + " \n" + + "- String Deduplication (reserved=632, committed=632)\n" + + " (malloc=632 #8) \n" + + " \n" + + "- Object Monitors (reserved=832, committed=832)\n" + + " (malloc=832 #4) \n" + + " \n" + + "\n" + ); + + PrometheusRegistry registry = new PrometheusRegistry(); + new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = "" + + "# TYPE jvm_native_memory_committed_bytes gauge\n" + + "# UNIT jvm_native_memory_committed_bytes bytes\n" + + "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + + "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Class\"} 616867.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Code\"} 7836080.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_committed_bytes{pool=\"GC\"} 7.6530708E7\n" + + "jvm_native_memory_committed_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Java Heap\"} 5.36870912E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Metaspace\"} 2829952.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Shared class space\"} 1.2386304E7\n" + + "jvm_native_memory_committed_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Thread\"} 847280.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Total\"} 6.42716389E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Tracing\"} 33097.0\n" + + "# TYPE jvm_native_memory_reserved_bytes gauge\n" + + "# UNIT jvm_native_memory_reserved_bytes bytes\n" + + "# HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Class\"} 1.073899939E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Code\"} 2.53796784E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"GC\"} 3.73343252E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Java Heap\"} 8.531214336E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Metaspace\"} 6.7120768E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Shared class space\"} 1.6777216E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Thread\"} 2.102008E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Total\"} 1.0341970661E10\n" + + "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } +} From 48d139469b2710e5b2aa9db7f0e67d4adad4ee0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 21 Mar 2024 20:56:57 +0100 Subject: [PATCH 299/980] Add BOM module (#931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 1 + .../pom.xml | 73 ++++++++----------- 2 files changed, 32 insertions(+), 42 deletions(-) rename {simpleclient-archive/simpleclient_bom => prometheus-metrics-bom}/pom.xml (62%) diff --git a/pom.xml b/pom.xml index 4ee0e39ae..dd1edea32 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,7 @@ + prometheus-metrics-bom prometheus-metrics-core prometheus-metrics-config prometheus-metrics-model diff --git a/simpleclient-archive/simpleclient_bom/pom.xml b/prometheus-metrics-bom/pom.xml similarity index 62% rename from simpleclient-archive/simpleclient_bom/pom.xml rename to prometheus-metrics-bom/pom.xml index 417c679bd..f11653adc 100644 --- a/simpleclient-archive/simpleclient_bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,17 +5,21 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.2.0-SNAPSHOT - simpleclient_bom + prometheus-metrics-bom pom - Prometheus Java Simpleclient BOM + Prometheus Metrics BOM - Bill of Materials for the Simpleclient. + Bill of Materials for the Prometheus Metrics library + + 1.1.0 + + The Apache Software License, Version 2.0 @@ -28,118 +32,103 @@ io.prometheus - simpleclient - ${project.version} - - - io.prometheus - simpleclient_caffeine - ${project.version} - - - io.prometheus - simpleclient_common - ${project.version} - - - io.prometheus - simpleclient_dropwizard + prometheus-metrics-config ${project.version} io.prometheus - simpleclient_graphite_bridge + prometheus-metrics-core ${project.version} io.prometheus - simpleclient_guava + prometheus-metrics-exporter-common ${project.version} io.prometheus - simpleclient_hibernate + prometheus-metrics-exporter-httpserver ${project.version} io.prometheus - simpleclient_hotspot + prometheus-metrics-exporter-opentelemetry ${project.version} io.prometheus - simpleclient_httpserver + prometheus-metrics-exporter-servlet-jakarta ${project.version} io.prometheus - simpleclient_tracer_common + prometheus-metrics-exporter-servlet-javax ${project.version} io.prometheus - simpleclient_jetty + prometheus-metrics-exposition-formats ${project.version} io.prometheus - simpleclient_jetty_jdk8 + prometheus-metrics-instrumentation-dropwizard5 ${project.version} io.prometheus - simpleclient_log4j + prometheus-metrics-instrumentation-jvm ${project.version} io.prometheus - simpleclient_log4j2 + prometheus-metrics-model ${project.version} io.prometheus - simpleclient_logback + prometheus-metrics-simpleclient-bridge ${project.version} io.prometheus - simpleclient_pushgateway + prometheus-metrics-tracer ${project.version} io.prometheus - simpleclient_servlet + prometheus-metrics-tracer-common ${project.version} io.prometheus - simpleclient_servlet_jakarta + prometheus-metrics-tracer-initializer ${project.version} io.prometheus - simpleclient_spring_boot + prometheus-metrics-tracer-otel ${project.version} io.prometheus - simpleclient_spring_web + prometheus-metrics-tracer-otel-agent ${project.version} io.prometheus - simpleclient_tracer_otel - ${project.version} + prometheus-metrics-shaded-dependencies + ${prometheus.metrics.shaded.dependencies.version} io.prometheus - simpleclient_tracer_otel_agent - ${project.version} + prometheus-metrics-shaded-protobuf + ${prometheus.metrics.shaded.dependencies.version} io.prometheus - simpleclient_vertx - ${project.version} + prometheus-metrics-shaded-opentelemetry + ${prometheus.metrics.shaded.dependencies.version} From 66c97259c0dbfd266267c230ab83ca9afd811bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 21 Mar 2024 21:34:59 +0100 Subject: [PATCH 300/980] Add clear() method to StatefulMetric (#917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/core/metrics/StatefulMetric.java | 8 ++++-- .../core/metrics/StatefulMetricTest.java | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 426f4efa8..43555167a 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -109,8 +109,12 @@ public void remove(String... labelValues) { data.remove(Arrays.asList(labelValues)); } - // TODO: Write a clear() method that resets the metric (removes all data points), - // see https://prometheus.io/docs/instrumenting/writing_clientlibs/#labels + /** + * Reset the metric (remove all data points). + */ + public void clear() { + data.clear(); + } protected abstract T newDataPoint(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index 0baddd5fd..b1c45fa80 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -33,4 +33,32 @@ public void testLabelRemoveWhileCollecting() throws Exception { Assert.assertNotNull(entry.getValue()); } } + + @Test + public void testClear() { + Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build(); + counter.labelValues("a", "b").inc(3.0); + counter.labelValues("c", "d").inc(3.0); + counter.labelValues("a", "b").inc(); + Assert.assertEquals(2, counter.collect().getDataPoints().size()); + + counter.clear(); + Assert.assertEquals(0, counter.collect().getDataPoints().size()); + + counter.labelValues("a", "b").inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + } + + @Test + public void testClearNoLabels() { + Counter counter = Counter.builder().name("test").build(); + counter.inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + + counter.clear(); + // No labels is always present, but as no value has been observed after clear() the value should be 0.0 + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + } } From 5b286bcbf073e18fa33d3c41138b1563a44de3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 21 Mar 2024 21:27:24 +0100 Subject: [PATCH 301/980] Add get() method for Counter and Gauge (#920) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../core/datapoints/CounterDataPoint.java | 10 +++++++ .../core/datapoints/GaugeDataPoint.java | 5 ++++ .../metrics/core/metrics/Counter.java | 30 ++++++++++++++++++- .../metrics/core/metrics/Gauge.java | 18 ++++++++++- 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java index 49cb95008..51b45c62a 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java @@ -85,4 +85,14 @@ default void incWithExemplar(long amount, Labels labels) { * Throws an {@link IllegalArgumentException} if {@code amount} is negative. */ void incWithExemplar(double amount, Labels labels); + + /** + * Get the current value. + */ + double get(); + + /** + * Get the current value as a {@code long}. Decimal places will be discarded. + */ + long getLongValue(); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java index 9daf01428..c208d5414 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java @@ -66,6 +66,11 @@ default void decWithExemplar(double amount, Labels labels) { */ void set(double value); + /** + * Get the current value. + */ + double get(); + /** * Set the gauge to {@code value}, and create a custom exemplar with the given labels. */ diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index 4c764cf2a..c5a55ca78 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -77,6 +77,20 @@ public void incWithExemplar(double amount, Labels labels) { getNoLabels().incWithExemplar(amount, labels); } + /** + * {@inheritDoc} + */ + public double get() { + return getNoLabels().get(); + } + + /** + * {@inheritDoc} + */ + public long getLongValue() { + return getNoLabels().getLongValue(); + } + /** * {@inheritDoc} */ @@ -129,6 +143,20 @@ private DataPoint(ExemplarSampler exemplarSampler) { this.exemplarSampler = exemplarSampler; } + /** + * {@inheritDoc} + */ + public double get() { + return longValue.sum() + doubleValue.sum(); + } + + /** + * {@inheritDoc} + */ + public long getLongValue() { + return longValue.sum() + (long) doubleValue.sum(); + } + /** * {@inheritDoc} */ @@ -199,7 +227,7 @@ private CounterSnapshot.CounterDataPointSnapshot collect(Labels labels) { } } } - return new CounterSnapshot.CounterDataPointSnapshot(longValue.sum() + doubleValue.sum(), labels, latestExemplar, createdTimeMillis); + return new CounterSnapshot.CounterDataPointSnapshot(get(), labels, latestExemplar, createdTimeMillis); } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java index 466c31276..1c46435f6 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java @@ -60,6 +60,14 @@ public void inc(double amount) { getNoLabels().inc(amount); } + /** + * {@inheritDoc} + */ + @Override + public double get() { + return getNoLabels().get(); + } + /** * {@inheritDoc} */ @@ -158,6 +166,14 @@ public void set(double value) { } } + /** + * {@inheritDoc} + */ + @Override + public double get() { + return Double.longBitsToDouble(value.get()); + } + /** * {@inheritDoc} */ @@ -182,7 +198,7 @@ private GaugeSnapshot.GaugeDataPointSnapshot collect(Labels labels) { } } } - return new GaugeSnapshot.GaugeDataPointSnapshot(Double.longBitsToDouble(value.get()), labels, oldest); + return new GaugeSnapshot.GaugeDataPointSnapshot(get(), labels, oldest); } } From 5102909a837f0f9e8e7e525a38a3a9f04386d0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Mar 2024 15:51:46 +0100 Subject: [PATCH 302/980] Fix NullPointerException in OpenTelemetry exporter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../exporter/opentelemetry/otelmodel/PrometheusData.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index 747fa7b25..d42132959 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -12,8 +12,8 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.PointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; +import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -43,13 +43,15 @@ protected Attributes labelsToAttributes(Labels labels) { } protected List convertExemplar(Exemplar exemplar) { + if (exemplar == null) { + return Collections.emptyList(); + } return convertExemplars(Exemplars.of(exemplar)); } protected List convertExemplars(Exemplars exemplars) { return StreamSupport.stream(exemplars.spliterator(), false) .map(this::toDoubleExemplarData) - .filter(Objects::nonNull) .collect(Collectors.toList()); } From 200be28f1b814ab1aeee46ac86abb5c515ff572f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Mar 2024 10:29:12 +0100 Subject: [PATCH 303/980] Bump dependency versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 4 ++-- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/pom.xml | 2 +- prometheus-metrics-bom/version-rules.xml | 6 ++++++ prometheus-metrics-exporter-opentelemetry/pom.xml | 6 +++--- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 4 ++-- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- 13 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 prometheus-metrics-bom/version-rules.xml diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 5e58d1e78..30a0821fa 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.15 + 10.1.19 diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 98b910a47..089ce016a 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.15 + 10.1.19 diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 50cb17c84..3e73b5db9 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.15 + 10.1.19 diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index eca28e70f..6904718a6 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -45,12 +45,12 @@ org.eclipse.jetty jetty-server - 11.0.18 + 11.0.20 org.eclipse.jetty jetty-servlet - 11.0.18 + 11.0.20 diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 558590380..194374da2 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -45,7 +45,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.15 + 10.1.19 diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 7300b9318..d3b80d268 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -51,7 +51,7 @@ commons-io commons-io - 2.15.0 + 2.15.1 test diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index d76fae256..13a450d09 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -55,7 +55,7 @@ org.testcontainers testcontainers - 1.19.1 + 1.19.7 test diff --git a/prometheus-metrics-bom/version-rules.xml b/prometheus-metrics-bom/version-rules.xml new file mode 100644 index 000000000..76f8da4fd --- /dev/null +++ b/prometheus-metrics-bom/version-rules.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index b99ee75cf..10101fe59 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -17,7 +17,7 @@ - 1.31.0 + 1.36.0 io.prometheus.metrics.exporter.opentelemetry @@ -59,13 +59,13 @@ org.wiremock wiremock - 3.3.1 + 3.4.2 test org.awaitility awaitility - 4.2.0 + 4.2.1 test diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index 8cd2f452e..023506a68 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -45,7 +45,7 @@ javax.servlet javax.servlet-api - 3.1.0 + 4.0.1 provided diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index eb07172f0..7c1763cad 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -64,13 +64,13 @@ org.assertj assertj-core - 3.23.1 + 3.25.3 test org.mockito mockito-core - 4.6.1 + 5.11.0 test diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index f55dd9c6f..b9490532b 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -58,7 +58,7 @@ org.mockito mockito-core - 5.7.0 + 5.11.0 test diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 98286194e..3d7b44fae 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -37,7 +37,7 @@ io.opentelemetry opentelemetry-api - 1.28.0 + 1.36.0 From 292409441d0f9ebe2da4ffee82b0b81869f45d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 22 Mar 2024 16:08:59 +0100 Subject: [PATCH 304/980] Bump shaded dependency versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/it/exporter/test/ExporterIT.java | 2 +- .../metrics/core/metrics/CounterTest.java | 4 +- .../metrics/core/metrics/HistogramTest.java | 4 +- .../metrics/core/metrics/InfoTest.java | 4 +- .../pom.xml | 3 +- .../opentelemetry/OpenTelemetryExporter.java | 18 +- .../PrometheusInstrumentationScope.java | 2 +- .../PrometheusMetricProducer.java | 14 +- .../otelmodel/DoublePointDataImpl.java | 6 +- .../ExponentialHistogramBucketsImpl.java | 2 +- .../ExponentialHistogramPointDataImpl.java | 8 +- .../otelmodel/HistogramPointDataImpl.java | 6 +- .../otelmodel/MetricDataFactory.java | 6 +- .../otelmodel/PointDataImpl.java | 8 +- .../otelmodel/PrometheusClassicHistogram.java | 8 +- .../otelmodel/PrometheusCounter.java | 8 +- .../otelmodel/PrometheusData.java | 20 +- .../otelmodel/PrometheusGauge.java | 6 +- .../otelmodel/PrometheusInfo.java | 8 +- .../otelmodel/PrometheusMetricData.java | 12 +- .../otelmodel/PrometheusNativeHistogram.java | 10 +- .../otelmodel/PrometheusStateSet.java | 8 +- .../otelmodel/PrometheusSummary.java | 6 +- .../otelmodel/PrometheusUnknown.java | 6 +- .../otelmodel/SummaryPointDataImpl.java | 8 +- .../otelmodel/ValueAtQuantileImpl.java | 2 +- .../generate-protobuf.sh | 3 +- prometheus-metrics-exposition-formats/pom.xml | 3 +- .../Metrics.java | 4630 ++++++++++------- .../PrometheusProtobufWriter.java | 4 +- .../expositionformats/ProtobufUtil.java | 2 +- .../src/main/protobuf/metrics.proto | 6 +- .../ExpositionFormatsTest.java | 4 +- .../pom.xml | 4 +- .../pom.xml | 4 +- 35 files changed, 2787 insertions(+), 2062 deletions(-) rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_3_21_7 => com_google_protobuf_3_25_3}/Metrics.java (76%) diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 2f7baf908..657b890db 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -2,7 +2,7 @@ import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Volume; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Assert; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 7311c84f6..7be2a3869 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 2e0df7b01..8df44b43e 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1,11 +1,11 @@ package io.prometheus.metrics.core.metrics; -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index f88c98d7c..f2ddbc456 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -3,9 +3,9 @@ import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import org.junit.Assert; import org.junit.Test; diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 10101fe59..1586387d0 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,7 +46,8 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.1.0 + ${project.version} + diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index a59948002..6cb3b4731 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -3,15 +3,15 @@ import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.MetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.PeriodicMetricReader; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.ResourceBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.MetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.PeriodicMetricReader; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.ResourceBuilder; import java.time.Duration; import java.util.HashMap; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java index da78e2e41..acaf0d2a9 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; import java.util.Properties; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 72dd968db..63b042ecd 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -12,13 +12,13 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.export.CollectionRegistration; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.ResourceBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.CollectionRegistration; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.ResourceBuilder; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java index 5f6e22ff1..b8b850367 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java index 2f7c2ca9f..664d03cc1 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java index e28deaf65..1756bf63f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramPointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java index 68e2eefaf..9e2eb70dd 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramPointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 26fb13738..24dd549e4 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -7,9 +7,9 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; public class MetricDataFactory { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java index c57b0e064..c9b3713e7 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.PointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.PointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index 03144ed0e..55eddc9be 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -2,10 +2,10 @@ import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.HistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java index 6bf81e945..be0a54a19 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index d42132959..ef5028871 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -1,16 +1,16 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.*; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.SpanContext; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.TraceFlags; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.trace.TraceState; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.Data; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.PointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.SpanContext; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.TraceFlags; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.TraceState; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.Data; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.PointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import java.util.Collections; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java index 73635e69a..21136b338 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index 1c7ab6fff..88be12ba7 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -1,10 +1,10 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; import java.util.Collection; import java.util.Collections; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java index 0ecbfd76e..a12e63f76 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -3,12 +3,12 @@ import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.PrometheusNaming; import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; class PrometheusMetricData> implements MetricData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java index e150e44a1..c0fcfdf13 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -2,11 +2,11 @@ import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ExponentialHistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java index 0ebaf572c..6631813fb 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java @@ -2,10 +2,10 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java index 7b7ba858b..29f861e2e 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java @@ -2,9 +2,9 @@ import io.prometheus.metrics.model.snapshots.Quantile; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryPointData; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java index 064774420..bcda2e74a 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java index f5af6589c..03a9179c5 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.SummaryPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ValueAtQuantile; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ValueAtQuantile; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java index 4d1c2002f..09c244534 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_31_0.sdk.metrics.data.ValueAtQuantile; +import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ValueAtQuantile; public class ValueAtQuantileImpl implements ValueAtQuantile { diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index 24a9f8dff..c68ce46c9 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -6,7 +6,8 @@ set -e # I could not figure out how to use a protoc Maven plugin to use the shaded module, so I ran this command to generate the sources manually. # The version string must be the same as in protobuf-shaded/pom.xml. -export PROTOBUF_VERSION_STRING="3_21_7" +#export PROTOBUF_VERSION_STRING="3_21_7" +export PROTOBUF_VERSION_STRING="3_25_3" rm -rf src/main/protobuf/* curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/prometheus/client/metrics.proto -o src/main/protobuf/metrics.proto diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index c1f0fdf77..f8e904561 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -50,7 +50,8 @@ io.prometheus prometheus-metrics-shaded-protobuf - 1.1.0 + ${project.version} + diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java similarity index 76% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java index d66bf16a8..3b821ba09 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_21_7/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java @@ -1,24 +1,25 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: src/main/protobuf/metrics.proto -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7; +// Protobuf Java Version: 3.25.3 +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3; public final class Metrics { private Metrics() {} public static void registerAllExtensions( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite registry) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite registry) { } public static void registerAllExtensions( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistry registry) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistry registry) { registerAllExtensions( - (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite) registry); + (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite) registry); } /** * Protobuf enum {@code io.prometheus.client.MetricType} */ public enum MetricType - implements io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ProtocolMessageEnum { + implements io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ProtocolMessageEnum { /** *
            * COUNTER must use the Metric field "counter".
      @@ -149,35 +150,35 @@ public static MetricType forNumber(int value) {
             }
           }
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap
               internalGetValueMap() {
             return internalValueMap;
           }
      -    private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap<
      +    private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap<
               MetricType> internalValueMap =
      -          new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.EnumLiteMap() {
      +          new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap() {
                   public MetricType findValueByNumber(int number) {
                     return MetricType.forNumber(number);
                   }
                 };
       
      -    public final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor
      +    public final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumValueDescriptor
               getValueDescriptor() {
             return getDescriptor().getValues().get(ordinal());
           }
      -    public final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
      +    public final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumDescriptor
               getDescriptorForType() {
             return getDescriptor();
           }
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumDescriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumDescriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.getDescriptor().getEnumTypes().get(0);
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.getDescriptor().getEnumTypes().get(0);
           }
       
           private static final MetricType[] VALUES = values();
       
           public static MetricType valueOf(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.EnumValueDescriptor desc) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumValueDescriptor desc) {
             if (desc.getType() != getDescriptor()) {
               throw new java.lang.IllegalArgumentException(
                 "EnumValueDescriptor is not for this type.");
      @@ -196,7 +197,7 @@ private MetricType(int value) {
       
         public interface LabelPairOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.LabelPair)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional string name = 1;
      @@ -212,7 +213,7 @@ public interface LabelPairOrBuilder extends
            * optional string name = 1;
            * @return The bytes for name.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getNameBytes();
       
           /**
      @@ -229,19 +230,19 @@ public interface LabelPairOrBuilder extends
            * optional string value = 2;
            * @return The bytes for value.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getValueBytes();
         }
         /**
          * Protobuf type {@code io.prometheus.client.LabelPair}
          */
         public static final class LabelPair extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.LabelPair)
             LabelPairOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use LabelPair.newBuilder() to construct.
      -    private LabelPair(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private LabelPair(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private LabelPair() {
      @@ -256,17 +257,17 @@ protected java.lang.Object newInstance(
             return new LabelPair();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder.class);
           }
       
           private int bitField0_;
      @@ -291,8 +292,8 @@ public java.lang.String getName() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      +            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
      @@ -305,17 +306,17 @@ public java.lang.String getName() {
            * @return The bytes for name.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
             }
           }
       
      @@ -340,8 +341,8 @@ public java.lang.String getValue() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      +            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 value_ = s;
      @@ -354,17 +355,17 @@ public java.lang.String getValue() {
            * @return The bytes for value.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getValueBytes() {
             java.lang.Object ref = value_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               value_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
             }
           }
       
      @@ -380,13 +381,13 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, value_);
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 2, value_);
             }
             getUnknownFields().writeTo(output);
           }
      @@ -398,10 +399,10 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, value_);
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(2, value_);
             }
             size += getUnknownFields().getSerializedSize();
             memoizedSize = size;
      @@ -413,10 +414,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -452,75 +453,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -529,7 +530,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -540,7 +541,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -548,29 +549,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.LabelPair}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -584,19 +585,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -604,14 +605,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -631,44 +632,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -691,8 +692,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -723,7 +724,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -747,8 +748,8 @@ public boolean hasName() {
             public java.lang.String getName() {
               java.lang.Object ref = name_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      +              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   name_ = s;
      @@ -762,17 +763,17 @@ public java.lang.String getName() {
              * optional string name = 1;
              * @return The bytes for name.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
                 getNameBytes() {
               java.lang.Object ref = name_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 name_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               }
             }
             /**
      @@ -804,7 +805,7 @@ public Builder clearName() {
              * @return This builder for chaining.
              */
             public Builder setNameBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               name_ = value;
               bitField0_ |= 0x00000001;
      @@ -827,8 +828,8 @@ public boolean hasValue() {
             public java.lang.String getValue() {
               java.lang.Object ref = value_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      +              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   value_ = s;
      @@ -842,17 +843,17 @@ public java.lang.String getValue() {
              * optional string value = 2;
              * @return The bytes for value.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
                 getValueBytes() {
               java.lang.Object ref = value_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 value_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               }
             }
             /**
      @@ -884,7 +885,7 @@ public Builder clearValue() {
              * @return This builder for chaining.
              */
             public Builder setValueBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               value_ = value;
               bitField0_ |= 0x00000002;
      @@ -893,13 +894,13 @@ public Builder setValueBytes(
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -908,48 +909,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public LabelPair parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -957,7 +958,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface GaugeOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Gauge)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -974,12 +975,12 @@ public interface GaugeOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Gauge}
          */
         public static final class Gauge extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Gauge)
             GaugeOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Gauge.newBuilder() to construct.
      -    private Gauge(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Gauge(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Gauge() {
      @@ -992,17 +993,17 @@ protected java.lang.Object newInstance(
             return new Gauge();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder.class);
           }
       
           private int bitField0_;
      @@ -1037,7 +1038,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -1052,7 +1053,7 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -1065,10 +1066,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1089,7 +1090,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -1097,75 +1098,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -1174,7 +1175,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1185,7 +1186,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -1193,29 +1194,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Gauge}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -1228,19 +1229,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1248,14 +1249,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1271,44 +1272,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1324,8 +1325,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -1351,7 +1352,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -1401,13 +1402,13 @@ public Builder clearValue() {
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -1416,48 +1417,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Gauge parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1465,7 +1466,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface CounterOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Counter)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -1487,11 +1488,11 @@ public interface CounterOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
       
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
      @@ -1502,22 +1503,22 @@ public interface CounterOrBuilder extends
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Counter}
          */
         public static final class Counter extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Counter)
             CounterOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Counter.newBuilder() to construct.
      -    private Counter(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Counter(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Counter() {
      @@ -1530,17 +1531,17 @@ protected java.lang.Object newInstance(
             return new Counter();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder.class);
           }
       
           private int bitField0_;
      @@ -1564,7 +1565,7 @@ public double getValue() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return Whether the exemplar field is set.
      @@ -1578,19 +1579,19 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            * @return Whether the createdTimestamp field is set.
      @@ -1604,15 +1605,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -1627,7 +1628,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -1648,15 +1649,15 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(2, getExemplar());
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(3, getCreatedTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -1669,10 +1670,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1703,7 +1704,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             if (hasExemplar()) {
      @@ -1719,75 +1720,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -1796,7 +1797,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1807,7 +1808,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -1815,34 +1816,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Counter}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                       .alwaysUseFieldBuilders) {
                 getExemplarFieldBuilder();
                 getCreatedTimestampFieldBuilder();
      @@ -1867,19 +1868,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1887,14 +1888,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1922,44 +1923,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1981,8 +1982,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -2022,7 +2023,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -2071,9 +2072,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return Whether the exemplar field is set.
      @@ -2085,9 +2086,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -2095,7 +2096,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2112,7 +2113,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -2125,11 +2126,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -2137,8 +2138,10 @@ public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.c
               } else {
                 exemplarBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000002;
      -        onChanged();
      +        if (exemplar_ != null) {
      +          bitField0_ |= 0x00000002;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -2157,7 +2160,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -2165,23 +2168,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
      -          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>(
      +          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -2190,9 +2193,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return exemplarBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              * @return Whether the createdTimestamp field is set.
      @@ -2204,9 +2207,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -2214,7 +2217,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2231,7 +2234,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -2244,11 +2247,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -2256,8 +2259,10 @@ public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_pro
               } else {
                 createdTimestampBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000004;
      -        onChanged();
      +        if (createdTimestamp_ != null) {
      +          bitField0_ |= 0x00000004;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -2276,7 +2281,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -2284,23 +2289,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -2310,13 +2315,13 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilde
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -2325,48 +2330,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Counter parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2374,7 +2379,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface QuantileOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Quantile)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional double quantile = 1;
      @@ -2402,12 +2407,12 @@ public interface QuantileOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Quantile}
          */
         public static final class Quantile extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Quantile)
             QuantileOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Quantile.newBuilder() to construct.
      -    private Quantile(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Quantile(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Quantile() {
      @@ -2420,17 +2425,17 @@ protected java.lang.Object newInstance(
             return new Quantile();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder.class);
           }
       
           private int bitField0_;
      @@ -2484,7 +2489,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, quantile_);
      @@ -2502,11 +2507,11 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(1, quantile_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(2, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -2519,10 +2524,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile) obj;
       
             if (hasQuantile() != other.hasQuantile()) return false;
             if (hasQuantile()) {
      @@ -2549,12 +2554,12 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasQuantile()) {
               hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getQuantile()));
             }
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -2562,75 +2567,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -2639,7 +2644,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -2650,7 +2655,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -2658,29 +2663,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Quantile}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -2694,19 +2699,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -2714,14 +2719,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -2741,44 +2746,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance()) return this;
               if (other.hasQuantile()) {
                 setQuantile(other.getQuantile());
               }
      @@ -2797,8 +2802,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -2829,7 +2834,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -2919,13 +2924,13 @@ public Builder clearValue() {
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -2934,48 +2939,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Quantile parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2983,7 +2988,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface SummaryOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Summary)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional uint64 sample_count = 1;
      @@ -3010,12 +3015,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index);
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      @@ -3023,12 +3028,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileOrBuilderList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index);
       
           /**
      @@ -3040,22 +3045,22 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Summary}
          */
         public static final class Summary extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Summary)
             SummaryOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Summary.newBuilder() to construct.
      -    private Summary(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Summary(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Summary() {
      @@ -3069,17 +3074,17 @@ protected java.lang.Object newInstance(
             return new Summary();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder.class);
           }
       
           private int bitField0_;
      @@ -3123,19 +3128,19 @@ public double getSampleSum() {
       
           public static final int QUANTILE_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List quantile_;
      +    private java.util.List quantile_;
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List getQuantileList() {
      +    public java.util.List getQuantileList() {
             return quantile_;
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getQuantileOrBuilderList() {
             return quantile_;
           }
      @@ -3150,20 +3155,20 @@ public int getQuantileCount() {
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index) {
             return quantile_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index) {
             return quantile_.get(index);
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            * @return Whether the createdTimestamp field is set.
      @@ -3177,15 +3182,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -3200,7 +3205,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeUInt64(1, sampleCount_);
      @@ -3224,19 +3229,19 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeUInt64Size(1, sampleCount_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(2, sampleSum_);
             }
             for (int i = 0; i < quantile_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(3, quantile_.get(i));
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(4, getCreatedTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -3249,10 +3254,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -3285,12 +3290,12 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasSampleCount()) {
               hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   getSampleCount());
             }
             if (hasSampleSum()) {
               hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getSampleSum()));
             }
             if (getQuantileCount() > 0) {
      @@ -3306,75 +3311,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -3383,7 +3388,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -3394,7 +3399,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -3402,34 +3407,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Summary}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                       .alwaysUseFieldBuilders) {
                 getQuantileFieldBuilder();
                 getCreatedTimestampFieldBuilder();
      @@ -3457,19 +3462,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -3477,15 +3482,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result) {
               if (quantileBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0)) {
                   quantile_ = java.util.Collections.unmodifiableList(quantile_);
      @@ -3497,7 +3502,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -3523,44 +3528,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -3586,7 +3591,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     quantile_ = other.quantile_;
                     bitField0_ = (bitField0_ & ~0x00000004);
                     quantileBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
                          getQuantileFieldBuilder() : null;
                   } else {
                     quantileBuilder_.addAllMessages(other.quantile_);
      @@ -3608,8 +3613,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -3633,9 +3638,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.PARSER,
                               extensionRegistry);
                       if (quantileBuilder_ == null) {
                         ensureQuantileIsMutable();
      @@ -3660,7 +3665,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -3749,22 +3754,22 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List quantile_ =
      +      private java.util.List quantile_ =
               java.util.Collections.emptyList();
             private void ensureQuantileIsMutable() {
               if (!((bitField0_ & 0x00000004) != 0)) {
      -          quantile_ = new java.util.ArrayList(quantile_);
      +          quantile_ = new java.util.ArrayList(quantile_);
                 bitField0_ |= 0x00000004;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> quantileBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder> quantileBuilder_;
       
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List getQuantileList() {
      +      public java.util.List getQuantileList() {
               if (quantileBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(quantile_);
               } else {
      @@ -3784,7 +3789,7 @@ public int getQuantileCount() {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile getQuantile(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);
               } else {
      @@ -3795,7 +3800,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3812,7 +3817,7 @@ public Builder setQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.set(index, builderForValue.build());
      @@ -3825,7 +3830,7 @@ public Builder setQuantile(
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) {
      +      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3842,7 +3847,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3859,7 +3864,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(builderForValue.build());
      @@ -3873,7 +3878,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(index, builderForValue.build());
      @@ -3887,10 +3892,10 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addAllQuantile(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, quantile_);
                 onChanged();
               } else {
      @@ -3927,14 +3932,14 @@ public Builder removeQuantile(int index) {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder getQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder getQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
                 int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);  } else {
      @@ -3944,7 +3949,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileOrBuilderList() {
               if (quantileBuilder_ != null) {
                 return quantileBuilder_.getMessageOrBuilderList();
      @@ -3955,31 +3960,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder addQuantileBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder addQuantileBuilder() {
               return getQuantileFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder addQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder addQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileBuilderList() {
               return getQuantileFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder> 
                 getQuantileFieldBuilder() {
               if (quantileBuilder_ == null) {
      -          quantileBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.QuantileOrBuilder>(
      +          quantileBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder>(
                         quantile_,
                         ((bitField0_ & 0x00000004) != 0),
                         getParentForChildren(),
      @@ -3989,9 +3994,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return quantileBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              * @return Whether the createdTimestamp field is set.
      @@ -4003,9 +4008,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -4013,7 +4018,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -4030,7 +4035,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -4043,11 +4048,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -4055,8 +4060,10 @@ public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_pro
               } else {
                 createdTimestampBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000008;
      -        onChanged();
      +        if (createdTimestamp_ != null) {
      +          bitField0_ |= 0x00000008;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -4075,7 +4082,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -4083,23 +4090,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -4109,13 +4116,13 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilde
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -4124,48 +4131,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Summary parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4173,7 +4180,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface UntypedOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Untyped)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -4190,12 +4197,12 @@ public interface UntypedOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Untyped}
          */
         public static final class Untyped extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Untyped)
             UntypedOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Untyped.newBuilder() to construct.
      -    private Untyped(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Untyped(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Untyped() {
      @@ -4208,17 +4215,17 @@ protected java.lang.Object newInstance(
             return new Untyped();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder.class);
           }
       
           private int bitField0_;
      @@ -4253,7 +4260,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -4268,7 +4275,7 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -4281,10 +4288,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -4305,7 +4312,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -4313,75 +4320,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -4390,7 +4397,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -4401,7 +4408,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -4409,29 +4416,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Untyped}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -4444,19 +4451,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -4464,14 +4471,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -4487,44 +4494,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -4540,8 +4547,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -4567,7 +4574,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -4617,13 +4624,13 @@ public Builder clearValue() {
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -4632,48 +4639,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Untyped parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4681,7 +4688,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface HistogramOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Histogram)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional uint64 sample_count = 1;
      @@ -4731,7 +4738,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketList();
           /**
            * 
      @@ -4740,7 +4747,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4756,7 +4763,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4765,7 +4772,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4777,11 +4784,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
       
           /**
            * 
      @@ -4874,7 +4881,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4883,7 +4890,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4899,7 +4906,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4908,7 +4915,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4985,7 +4992,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4997,7 +5004,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5019,7 +5026,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -5031,7 +5038,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -5097,17 +5104,61 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * @return The positiveCount at the given index.
            */
           double getPositiveCount(int index);
      +
      +    /**
      +     * 
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + java.util.List + getExemplarsList(); + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index); + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + int getExemplarsCount(); + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + java.util.List + getExemplarsOrBuilderList(); + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder( + int index); } /** * Protobuf type {@code io.prometheus.client.Histogram} */ public static final class Histogram extends - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements // @@protoc_insertion_point(message_implements:io.prometheus.client.Histogram) HistogramOrBuilder { private static final long serialVersionUID = 0L; // Use Histogram.newBuilder() to construct. - private Histogram(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) { + private Histogram(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) { super(builder); } private Histogram() { @@ -5118,6 +5169,7 @@ private Histogram() { positiveSpan_ = java.util.Collections.emptyList(); positiveDelta_ = emptyLongList(); positiveCount_ = emptyDoubleList(); + exemplars_ = java.util.Collections.emptyList(); } @java.lang.Override @@ -5127,17 +5179,17 @@ protected java.lang.Object newInstance( return new Histogram(); } - public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor + public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; } @java.lang.Override - protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder.class); } private int bitField0_; @@ -5208,7 +5260,7 @@ public double getSampleSum() { public static final int BUCKET_FIELD_NUMBER = 3; @SuppressWarnings("serial") - private java.util.List bucket_; + private java.util.List bucket_; /** *
            * Buckets for the conventional histogram.
      @@ -5217,7 +5269,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5228,7 +5280,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5251,7 +5303,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5262,13 +5314,13 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 15;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            * @return Whether the createdTimestamp field is set.
      @@ -5282,15 +5334,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           public static final int SCHEMA_FIELD_NUMBER = 5;
      @@ -5411,7 +5463,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5420,7 +5472,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5431,7 +5483,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5454,7 +5506,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5465,14 +5517,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
       
           public static final int NEGATIVE_DELTA_FIELD_NUMBER = 10;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList negativeDelta_ =
      +        emptyLongList();
           /**
            * 
            * Use either "negative_delta" or "negative_count", the former for
      @@ -5518,7 +5571,8 @@ public long getNegativeDelta(int index) {
       
           public static final int NEGATIVE_COUNT_FIELD_NUMBER = 11;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList negativeCount_ =
      +        emptyDoubleList();
           /**
            * 
            * Absolute count of each bucket.
      @@ -5558,7 +5612,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5570,7 +5624,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5584,7 +5638,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5613,7 +5667,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5627,14 +5681,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
       
           public static final int POSITIVE_DELTA_FIELD_NUMBER = 13;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList positiveDelta_ =
      +        emptyLongList();
           /**
            * 
            * Use either "positive_delta" or "positive_count", the former for
      @@ -5680,7 +5735,8 @@ public long getPositiveDelta(int index) {
       
           public static final int POSITIVE_COUNT_FIELD_NUMBER = 14;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList positiveCount_ =
      +        emptyDoubleList();
           /**
            * 
            * Absolute count of each bucket.
      @@ -5718,6 +5774,67 @@ public double getPositiveCount(int index) {
             return positiveCount_.getDouble(index);
           }
       
      +    public static final int EXEMPLARS_FIELD_NUMBER = 16;
      +    @SuppressWarnings("serial")
      +    private java.util.List exemplars_;
      +    /**
      +     * 
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + @java.lang.Override + public java.util.List getExemplarsList() { + return exemplars_; + } + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + @java.lang.Override + public java.util.List + getExemplarsOrBuilderList() { + return exemplars_; + } + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + @java.lang.Override + public int getExemplarsCount() { + return exemplars_.size(); + } + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index) { + return exemplars_.get(index); + } + /** + *
      +     * Only used for native histograms. These exemplars MUST have a timestamp.
      +     * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + @java.lang.Override + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder( + int index) { + return exemplars_.get(index); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -5730,7 +5847,7 @@ public final boolean isInitialized() { } @java.lang.Override - public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output) + public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output) throws java.io.IOException { if (((bitField0_ & 0x00000001) != 0)) { output.writeUInt64(1, sampleCount_); @@ -5777,6 +5894,9 @@ public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Code if (((bitField0_ & 0x00000008) != 0)) { output.writeMessage(15, getCreatedTimestamp()); } + for (int i = 0; i < exemplars_.size(); i++) { + output.writeMessage(16, exemplars_.get(i)); + } getUnknownFields().writeTo(output); } @@ -5787,45 +5907,45 @@ public int getSerializedSize() { size = 0; if (((bitField0_ & 0x00000001) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeUInt64Size(1, sampleCount_); } if (((bitField0_ & 0x00000004) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeDoubleSize(2, sampleSum_); } for (int i = 0; i < bucket_.size(); i++) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeMessageSize(3, bucket_.get(i)); } if (((bitField0_ & 0x00000002) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeDoubleSize(4, sampleCountFloat_); } if (((bitField0_ & 0x00000010) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeSInt32Size(5, schema_); } if (((bitField0_ & 0x00000020) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeDoubleSize(6, zeroThreshold_); } if (((bitField0_ & 0x00000040) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeUInt64Size(7, zeroCount_); } if (((bitField0_ & 0x00000080) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeDoubleSize(8, zeroCountFloat_); } for (int i = 0; i < negativeSpan_.size(); i++) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeMessageSize(9, negativeSpan_.get(i)); } { int dataSize = 0; for (int i = 0; i < negativeDelta_.size(); i++) { - dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeSInt64SizeNoTag(negativeDelta_.getLong(i)); } size += dataSize; @@ -5838,13 +5958,13 @@ public int getSerializedSize() { size += 1 * getNegativeCountList().size(); } for (int i = 0; i < positiveSpan_.size(); i++) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeMessageSize(12, positiveSpan_.get(i)); } { int dataSize = 0; for (int i = 0; i < positiveDelta_.size(); i++) { - dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeSInt64SizeNoTag(positiveDelta_.getLong(i)); } size += dataSize; @@ -5857,9 +5977,13 @@ public int getSerializedSize() { size += 1 * getPositiveCountList().size(); } if (((bitField0_ & 0x00000008) != 0)) { - size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream .computeMessageSize(15, getCreatedTimestamp()); } + for (int i = 0; i < exemplars_.size(); i++) { + size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream + .computeMessageSize(16, exemplars_.get(i)); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -5870,10 +5994,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram) obj; if (hasSampleCount() != other.hasSampleCount()) return false; if (hasSampleCount()) { @@ -5933,6 +6057,8 @@ public boolean equals(final java.lang.Object obj) { .equals(other.getPositiveDeltaList())) return false; if (!getPositiveCountList() .equals(other.getPositiveCountList())) return false; + if (!getExemplarsList() + .equals(other.getExemplarsList())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @@ -5946,17 +6072,17 @@ public int hashCode() { hash = (19 * hash) + getDescriptor().hashCode(); if (hasSampleCount()) { hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( getSampleCount()); } if (hasSampleCountFloat()) { hash = (37 * hash) + SAMPLE_COUNT_FLOAT_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( java.lang.Double.doubleToLongBits(getSampleCountFloat())); } if (hasSampleSum()) { hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( java.lang.Double.doubleToLongBits(getSampleSum())); } if (getBucketCount() > 0) { @@ -5973,17 +6099,17 @@ public int hashCode() { } if (hasZeroThreshold()) { hash = (37 * hash) + ZERO_THRESHOLD_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( java.lang.Double.doubleToLongBits(getZeroThreshold())); } if (hasZeroCount()) { hash = (37 * hash) + ZERO_COUNT_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( getZeroCount()); } if (hasZeroCountFloat()) { hash = (37 * hash) + ZERO_COUNT_FLOAT_FIELD_NUMBER; - hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong( + hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong( java.lang.Double.doubleToLongBits(getZeroCountFloat())); } if (getNegativeSpanCount() > 0) { @@ -6010,80 +6136,84 @@ public int hashCode() { hash = (37 * hash) + POSITIVE_COUNT_FIELD_NUMBER; hash = (53 * hash) + getPositiveCountList().hashCode(); } + if (getExemplarsCount() > 0) { + hash = (37 * hash) + EXEMPLARS_FIELD_NUMBER; + hash = (53 * hash) + getExemplarsList().hashCode(); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( java.nio.ByteBuffer data) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( java.nio.ByteBuffer data, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(byte[] data) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(byte[] data) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( byte[] data, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(java.io.InputStream input) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( java.io.InputStream input, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseDelimitedFrom( java.io.InputStream input, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram parseFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom( + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .parseWithIOException(PARSER, input, extensionRegistry); } @@ -6092,7 +6222,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -6103,7 +6233,7 @@ public Builder toBuilder() { @java.lang.Override protected Builder newBuilderForType( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) { Builder builder = new Builder(parent); return builder; } @@ -6111,39 +6241,40 @@ protected Builder newBuilderForType( * Protobuf type {@code io.prometheus.client.Histogram} */ public static final class Builder extends - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder { - public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder { + public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; } @java.lang.Override - protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable + protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.newBuilder() private Builder() { maybeForceBuilderInitialization(); } private Builder( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) { super(parent); maybeForceBuilderInitialization(); } private void maybeForceBuilderInitialization() { - if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 + if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 .alwaysUseFieldBuilders) { getBucketFieldBuilder(); getCreatedTimestampFieldBuilder(); getNegativeSpanFieldBuilder(); getPositiveSpanFieldBuilder(); + getExemplarsFieldBuilder(); } } @java.lang.Override @@ -6187,23 +6318,30 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00001000); positiveDelta_ = emptyLongList(); positiveCount_ = emptyDoubleList(); + if (exemplarsBuilder_ == null) { + exemplars_ = java.util.Collections.emptyList(); + } else { + exemplars_ = null; + exemplarsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00008000); return this; } @java.lang.Override - public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor + public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -6211,15 +6349,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram(this); buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result) { + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result) { if (bucketBuilder_ == null) { if (((bitField0_ & 0x00000008) != 0)) { bucket_ = java.util.Collections.unmodifiableList(bucket_); @@ -6238,16 +6376,6 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } else { result.negativeSpan_ = negativeSpanBuilder_.build(); } - if (((bitField0_ & 0x00000400) != 0)) { - negativeDelta_.makeImmutable(); - bitField0_ = (bitField0_ & ~0x00000400); - } - result.negativeDelta_ = negativeDelta_; - if (((bitField0_ & 0x00000800) != 0)) { - negativeCount_.makeImmutable(); - bitField0_ = (bitField0_ & ~0x00000800); - } - result.negativeCount_ = negativeCount_; if (positiveSpanBuilder_ == null) { if (((bitField0_ & 0x00001000) != 0)) { positiveSpan_ = java.util.Collections.unmodifiableList(positiveSpan_); @@ -6257,19 +6385,18 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } else { result.positiveSpan_ = positiveSpanBuilder_.build(); } - if (((bitField0_ & 0x00002000) != 0)) { - positiveDelta_.makeImmutable(); - bitField0_ = (bitField0_ & ~0x00002000); - } - result.positiveDelta_ = positiveDelta_; - if (((bitField0_ & 0x00004000) != 0)) { - positiveCount_.makeImmutable(); - bitField0_ = (bitField0_ & ~0x00004000); + if (exemplarsBuilder_ == null) { + if (((bitField0_ & 0x00008000) != 0)) { + exemplars_ = java.util.Collections.unmodifiableList(exemplars_); + bitField0_ = (bitField0_ & ~0x00008000); + } + result.exemplars_ = exemplars_; + } else { + result.exemplars_ = exemplarsBuilder_.build(); } - result.positiveCount_ = positiveCount_; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -6306,6 +6433,22 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com result.zeroCountFloat_ = zeroCountFloat_; to_bitField0_ |= 0x00000080; } + if (((from_bitField0_ & 0x00000400) != 0)) { + negativeDelta_.makeImmutable(); + result.negativeDelta_ = negativeDelta_; + } + if (((from_bitField0_ & 0x00000800) != 0)) { + negativeCount_.makeImmutable(); + result.negativeCount_ = negativeCount_; + } + if (((from_bitField0_ & 0x00002000) != 0)) { + positiveDelta_.makeImmutable(); + result.positiveDelta_ = positiveDelta_; + } + if (((from_bitField0_ & 0x00004000) != 0)) { + positiveCount_.makeImmutable(); + result.positiveCount_ = positiveCount_; + } result.bitField0_ |= to_bitField0_; } @@ -6315,44 +6458,44 @@ public Builder clone() { } @java.lang.Override public Builder setField( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field, java.lang.Object value) { return super.setField(field, value); } @java.lang.Override public Builder clearField( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) { return super.clearField(field); } @java.lang.Override public Builder clearOneof( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) { return super.clearOneof(oneof); } @java.lang.Override public Builder setRepeatedField( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { return super.setRepeatedField(field, index, value); } @java.lang.Override public Builder addRepeatedField( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field, java.lang.Object value) { return super.addRepeatedField(field, value); } @java.lang.Override - public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram)other); + public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) { + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance()) return this; if (other.hasSampleCount()) { setSampleCount(other.getSampleCount()); } @@ -6381,7 +6524,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g bucket_ = other.bucket_; bitField0_ = (bitField0_ & ~0x00000008); bucketBuilder_ = - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ? getBucketFieldBuilder() : null; } else { bucketBuilder_.addAllMessages(other.bucket_); @@ -6422,7 +6565,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g negativeSpan_ = other.negativeSpan_; bitField0_ = (bitField0_ & ~0x00000200); negativeSpanBuilder_ = - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ? getNegativeSpanFieldBuilder() : null; } else { negativeSpanBuilder_.addAllMessages(other.negativeSpan_); @@ -6432,7 +6575,8 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g if (!other.negativeDelta_.isEmpty()) { if (negativeDelta_.isEmpty()) { negativeDelta_ = other.negativeDelta_; - bitField0_ = (bitField0_ & ~0x00000400); + negativeDelta_.makeImmutable(); + bitField0_ |= 0x00000400; } else { ensureNegativeDeltaIsMutable(); negativeDelta_.addAll(other.negativeDelta_); @@ -6442,7 +6586,8 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g if (!other.negativeCount_.isEmpty()) { if (negativeCount_.isEmpty()) { negativeCount_ = other.negativeCount_; - bitField0_ = (bitField0_ & ~0x00000800); + negativeCount_.makeImmutable(); + bitField0_ |= 0x00000800; } else { ensureNegativeCountIsMutable(); negativeCount_.addAll(other.negativeCount_); @@ -6468,7 +6613,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g positiveSpan_ = other.positiveSpan_; bitField0_ = (bitField0_ & ~0x00001000); positiveSpanBuilder_ = - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ? + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ? getPositiveSpanFieldBuilder() : null; } else { positiveSpanBuilder_.addAllMessages(other.positiveSpan_); @@ -6478,7 +6623,8 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g if (!other.positiveDelta_.isEmpty()) { if (positiveDelta_.isEmpty()) { positiveDelta_ = other.positiveDelta_; - bitField0_ = (bitField0_ & ~0x00002000); + positiveDelta_.makeImmutable(); + bitField0_ |= 0x00002000; } else { ensurePositiveDeltaIsMutable(); positiveDelta_.addAll(other.positiveDelta_); @@ -6488,13 +6634,40 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g if (!other.positiveCount_.isEmpty()) { if (positiveCount_.isEmpty()) { positiveCount_ = other.positiveCount_; - bitField0_ = (bitField0_ & ~0x00004000); + positiveCount_.makeImmutable(); + bitField0_ |= 0x00004000; } else { ensurePositiveCountIsMutable(); positiveCount_.addAll(other.positiveCount_); } onChanged(); } + if (exemplarsBuilder_ == null) { + if (!other.exemplars_.isEmpty()) { + if (exemplars_.isEmpty()) { + exemplars_ = other.exemplars_; + bitField0_ = (bitField0_ & ~0x00008000); + } else { + ensureExemplarsIsMutable(); + exemplars_.addAll(other.exemplars_); + } + onChanged(); + } + } else { + if (!other.exemplars_.isEmpty()) { + if (exemplarsBuilder_.isEmpty()) { + exemplarsBuilder_.dispose(); + exemplarsBuilder_ = null; + exemplars_ = other.exemplars_; + bitField0_ = (bitField0_ & ~0x00008000); + exemplarsBuilder_ = + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ? + getExemplarsFieldBuilder() : null; + } else { + exemplarsBuilder_.addAllMessages(other.exemplars_); + } + } + } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; @@ -6507,8 +6680,8 @@ public final boolean isInitialized() { @java.lang.Override public Builder mergeFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { if (extensionRegistry == null) { throw new java.lang.NullPointerException(); @@ -6532,9 +6705,9 @@ public Builder mergeFrom( break; } // case 17 case 26: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.PARSER, + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.PARSER, extensionRegistry); if (bucketBuilder_ == null) { ensureBucketIsMutable(); @@ -6570,9 +6743,9 @@ public Builder mergeFrom( break; } // case 65 case 74: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.PARSER, + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.PARSER, extensionRegistry); if (negativeSpanBuilder_ == null) { ensureNegativeSpanIsMutable(); @@ -6607,7 +6780,8 @@ public Builder mergeFrom( case 90: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); - ensureNegativeCountIsMutable(); + int alloc = length > 4096 ? 4096 : length; + ensureNegativeCountIsMutable(alloc / 8); while (input.getBytesUntilLimit() > 0) { negativeCount_.addDouble(input.readDouble()); } @@ -6615,9 +6789,9 @@ public Builder mergeFrom( break; } // case 90 case 98: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.PARSER, + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.PARSER, extensionRegistry); if (positiveSpanBuilder_ == null) { ensurePositiveSpanIsMutable(); @@ -6652,7 +6826,8 @@ public Builder mergeFrom( case 114: { int length = input.readRawVarint32(); int limit = input.pushLimit(length); - ensurePositiveCountIsMutable(); + int alloc = length > 4096 ? 4096 : length; + ensurePositiveCountIsMutable(alloc / 8); while (input.getBytesUntilLimit() > 0) { positiveCount_.addDouble(input.readDouble()); } @@ -6666,6 +6841,19 @@ public Builder mergeFrom( bitField0_ |= 0x00000010; break; } // case 122 + case 130: { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar m = + input.readMessage( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.PARSER, + extensionRegistry); + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + exemplars_.add(m); + } else { + exemplarsBuilder_.addMessage(m); + } + break; + } // case 130 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -6674,7 +6862,7 @@ public Builder mergeFrom( } // default: } // switch (tag) } // while (!done) - } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) { throw e.unwrapIOException(); } finally { onChanged(); @@ -6819,17 +7007,17 @@ public Builder clearSampleSum() { return this; } - private java.util.List bucket_ = + private java.util.List bucket_ = java.util.Collections.emptyList(); private void ensureBucketIsMutable() { if (!((bitField0_ & 0x00000008) != 0)) { - bucket_ = new java.util.ArrayList(bucket_); + bucket_ = new java.util.ArrayList(bucket_); bitField0_ |= 0x00000008; } } - private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> bucketBuilder_; + private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder> bucketBuilder_; /** *
      @@ -6838,7 +7026,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6866,7 +7054,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6881,7 +7069,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6902,7 +7090,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6919,7 +7107,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6940,7 +7128,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6961,7 +7149,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6979,7 +7167,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6997,10 +7185,10 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, bucket_);
                 onChanged();
               } else {
      @@ -7049,7 +7237,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().getBuilder(index);
             }
      @@ -7060,7 +7248,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7074,7 +7262,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7089,9 +7277,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder addBucketBuilder() {
               return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7100,10 +7288,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7112,16 +7300,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return getBucketFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder> 
                 getBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
      -          bucketBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder>(
      +          bucketBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7131,9 +7319,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return bucketBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> createdTimestampBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              * @return Whether the createdTimestamp field is set.
      @@ -7145,9 +7333,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCreatedTimestamp() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -7155,7 +7343,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7172,7 +7360,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -7185,11 +7373,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -7197,8 +7385,10 @@ public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_pro
               } else {
                 createdTimestampBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000010;
      -        onChanged();
      +        if (createdTimestamp_ != null) {
      +          bitField0_ |= 0x00000010;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -7217,7 +7407,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -7225,23 +7415,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -7490,17 +7680,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7509,7 +7699,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7537,7 +7727,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7552,7 +7742,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7573,7 +7763,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7590,7 +7780,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7611,7 +7801,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7632,7 +7822,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7650,7 +7840,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7668,10 +7858,10 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, negativeSpan_);
                 onChanged();
               } else {
      @@ -7720,7 +7910,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7731,7 +7921,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7745,7 +7935,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7760,9 +7950,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7771,10 +7961,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7783,16 +7973,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return getNegativeSpanFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> 
                 getNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
      -          negativeSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>(
      +          negativeSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7802,12 +7992,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return negativeSpanBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList negativeDelta_ = emptyLongList();
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList negativeDelta_ = emptyLongList();
             private void ensureNegativeDeltaIsMutable() {
      -        if (!((bitField0_ & 0x00000400) != 0)) {
      -          negativeDelta_ = mutableCopy(negativeDelta_);
      -          bitField0_ |= 0x00000400;
      +        if (!negativeDelta_.isModifiable()) {
      +          negativeDelta_ = makeMutableCopy(negativeDelta_);
               }
      +        bitField0_ |= 0x00000400;
             }
             /**
              * 
      @@ -7821,8 +8011,8 @@ private void ensureNegativeDeltaIsMutable() {
              */
             public java.util.List
                 getNegativeDeltaList() {
      -        return ((bitField0_ & 0x00000400) != 0) ?
      -                 java.util.Collections.unmodifiableList(negativeDelta_) : negativeDelta_;
      +        negativeDelta_.makeImmutable();
      +        return negativeDelta_;
             }
             /**
              * 
      @@ -7868,6 +8058,7 @@ public Builder setNegativeDelta(
       
               ensureNegativeDeltaIsMutable();
               negativeDelta_.setLong(index, value);
      +        bitField0_ |= 0x00000400;
               onChanged();
               return this;
             }
      @@ -7886,6 +8077,7 @@ public Builder addNegativeDelta(long value) {
       
               ensureNegativeDeltaIsMutable();
               negativeDelta_.addLong(value);
      +        bitField0_ |= 0x00000400;
               onChanged();
               return this;
             }
      @@ -7903,8 +8095,9 @@ public Builder addNegativeDelta(long value) {
             public Builder addAllNegativeDelta(
                 java.lang.Iterable values) {
               ensureNegativeDeltaIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                   values, negativeDelta_);
      +        bitField0_ |= 0x00000400;
               onChanged();
               return this;
             }
      @@ -7925,12 +8118,18 @@ public Builder clearNegativeDelta() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList negativeCount_ = emptyDoubleList();
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList negativeCount_ = emptyDoubleList();
             private void ensureNegativeCountIsMutable() {
      -        if (!((bitField0_ & 0x00000800) != 0)) {
      -          negativeCount_ = mutableCopy(negativeCount_);
      -          bitField0_ |= 0x00000800;
      +        if (!negativeCount_.isModifiable()) {
      +          negativeCount_ = makeMutableCopy(negativeCount_);
               }
      +        bitField0_ |= 0x00000800;
      +      }
      +      private void ensureNegativeCountIsMutable(int capacity) {
      +        if (!negativeCount_.isModifiable()) {
      +          negativeCount_ = makeMutableCopy(negativeCount_, capacity);
      +        }
      +        bitField0_ |= 0x00000800;
             }
             /**
              * 
      @@ -7942,8 +8141,8 @@ private void ensureNegativeCountIsMutable() {
              */
             public java.util.List
                 getNegativeCountList() {
      -        return ((bitField0_ & 0x00000800) != 0) ?
      -                 java.util.Collections.unmodifiableList(negativeCount_) : negativeCount_;
      +        negativeCount_.makeImmutable();
      +        return negativeCount_;
             }
             /**
              * 
      @@ -7983,6 +8182,7 @@ public Builder setNegativeCount(
       
               ensureNegativeCountIsMutable();
               negativeCount_.setDouble(index, value);
      +        bitField0_ |= 0x00000800;
               onChanged();
               return this;
             }
      @@ -7999,6 +8199,7 @@ public Builder addNegativeCount(double value) {
       
               ensureNegativeCountIsMutable();
               negativeCount_.addDouble(value);
      +        bitField0_ |= 0x00000800;
               onChanged();
               return this;
             }
      @@ -8014,8 +8215,9 @@ public Builder addNegativeCount(double value) {
             public Builder addAllNegativeCount(
                 java.lang.Iterable values) {
               ensureNegativeCountIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                   values, negativeCount_);
      +        bitField0_ |= 0x00000800;
               onChanged();
               return this;
             }
      @@ -8034,17 +8236,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -8056,7 +8258,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8090,7 +8292,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8108,7 +8310,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8132,7 +8334,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8152,7 +8354,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8176,7 +8378,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8200,7 +8402,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8221,7 +8423,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8242,10 +8444,10 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, positiveSpan_);
                 onChanged();
               } else {
      @@ -8303,7 +8505,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8317,7 +8519,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8334,7 +8536,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8352,9 +8554,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8366,10 +8568,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8381,16 +8583,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return getPositiveSpanFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> 
                 getPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
      -          positiveSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder>(
      +          positiveSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8400,12 +8602,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return positiveSpanBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.LongList positiveDelta_ = emptyLongList();
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList positiveDelta_ = emptyLongList();
             private void ensurePositiveDeltaIsMutable() {
      -        if (!((bitField0_ & 0x00002000) != 0)) {
      -          positiveDelta_ = mutableCopy(positiveDelta_);
      -          bitField0_ |= 0x00002000;
      +        if (!positiveDelta_.isModifiable()) {
      +          positiveDelta_ = makeMutableCopy(positiveDelta_);
               }
      +        bitField0_ |= 0x00002000;
             }
             /**
              * 
      @@ -8419,8 +8621,8 @@ private void ensurePositiveDeltaIsMutable() {
              */
             public java.util.List
                 getPositiveDeltaList() {
      -        return ((bitField0_ & 0x00002000) != 0) ?
      -                 java.util.Collections.unmodifiableList(positiveDelta_) : positiveDelta_;
      +        positiveDelta_.makeImmutable();
      +        return positiveDelta_;
             }
             /**
              * 
      @@ -8466,6 +8668,7 @@ public Builder setPositiveDelta(
       
               ensurePositiveDeltaIsMutable();
               positiveDelta_.setLong(index, value);
      +        bitField0_ |= 0x00002000;
               onChanged();
               return this;
             }
      @@ -8484,6 +8687,7 @@ public Builder addPositiveDelta(long value) {
       
               ensurePositiveDeltaIsMutable();
               positiveDelta_.addLong(value);
      +        bitField0_ |= 0x00002000;
               onChanged();
               return this;
             }
      @@ -8501,8 +8705,9 @@ public Builder addPositiveDelta(long value) {
             public Builder addAllPositiveDelta(
                 java.lang.Iterable values) {
               ensurePositiveDeltaIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                   values, positiveDelta_);
      +        bitField0_ |= 0x00002000;
               onChanged();
               return this;
             }
      @@ -8523,12 +8728,18 @@ public Builder clearPositiveDelta() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.DoubleList positiveCount_ = emptyDoubleList();
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList positiveCount_ = emptyDoubleList();
             private void ensurePositiveCountIsMutable() {
      -        if (!((bitField0_ & 0x00004000) != 0)) {
      -          positiveCount_ = mutableCopy(positiveCount_);
      -          bitField0_ |= 0x00004000;
      +        if (!positiveCount_.isModifiable()) {
      +          positiveCount_ = makeMutableCopy(positiveCount_);
      +        }
      +        bitField0_ |= 0x00004000;
      +      }
      +      private void ensurePositiveCountIsMutable(int capacity) {
      +        if (!positiveCount_.isModifiable()) {
      +          positiveCount_ = makeMutableCopy(positiveCount_, capacity);
               }
      +        bitField0_ |= 0x00004000;
             }
             /**
              * 
      @@ -8540,8 +8751,8 @@ private void ensurePositiveCountIsMutable() {
              */
             public java.util.List
                 getPositiveCountList() {
      -        return ((bitField0_ & 0x00004000) != 0) ?
      -                 java.util.Collections.unmodifiableList(positiveCount_) : positiveCount_;
      +        positiveCount_.makeImmutable();
      +        return positiveCount_;
             }
             /**
              * 
      @@ -8581,6 +8792,7 @@ public Builder setPositiveCount(
       
               ensurePositiveCountIsMutable();
               positiveCount_.setDouble(index, value);
      +        bitField0_ |= 0x00004000;
               onChanged();
               return this;
             }
      @@ -8597,6 +8809,7 @@ public Builder addPositiveCount(double value) {
       
               ensurePositiveCountIsMutable();
               positiveCount_.addDouble(value);
      +        bitField0_ |= 0x00004000;
               onChanged();
               return this;
             }
      @@ -8612,8 +8825,9 @@ public Builder addPositiveCount(double value) {
             public Builder addAllPositiveCount(
                 java.lang.Iterable values) {
               ensurePositiveCountIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                   values, positiveCount_);
      +        bitField0_ |= 0x00004000;
               onChanged();
               return this;
             }
      @@ -8631,15 +8845,327 @@ public Builder clearPositiveCount() {
               onChanged();
               return this;
             }
      +
      +      private java.util.List exemplars_ =
      +        java.util.Collections.emptyList();
      +      private void ensureExemplarsIsMutable() {
      +        if (!((bitField0_ & 0x00008000) != 0)) {
      +          exemplars_ = new java.util.ArrayList(exemplars_);
      +          bitField0_ |= 0x00008000;
      +         }
      +      }
      +
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +
      +      /**
      +       * 
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public java.util.List getExemplarsList() { + if (exemplarsBuilder_ == null) { + return java.util.Collections.unmodifiableList(exemplars_); + } else { + return exemplarsBuilder_.getMessageList(); + } + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public int getExemplarsCount() { + if (exemplarsBuilder_ == null) { + return exemplars_.size(); + } else { + return exemplarsBuilder_.getCount(); + } + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index) { + if (exemplarsBuilder_ == null) { + return exemplars_.get(index); + } else { + return exemplarsBuilder_.getMessage(index); + } + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder setExemplars( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) { + if (exemplarsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureExemplarsIsMutable(); + exemplars_.set(index, value); + onChanged(); + } else { + exemplarsBuilder_.setMessage(index, value); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder setExemplars( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) { + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + exemplars_.set(index, builderForValue.build()); + onChanged(); + } else { + exemplarsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) { + if (exemplarsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureExemplarsIsMutable(); + exemplars_.add(value); + onChanged(); + } else { + exemplarsBuilder_.addMessage(value); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder addExemplars( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) { + if (exemplarsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureExemplarsIsMutable(); + exemplars_.add(index, value); + onChanged(); + } else { + exemplarsBuilder_.addMessage(index, value); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder addExemplars( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) { + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + exemplars_.add(builderForValue.build()); + onChanged(); + } else { + exemplarsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder addExemplars( + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) { + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + exemplars_.add(index, builderForValue.build()); + onChanged(); + } else { + exemplarsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder addAllExemplars( + java.lang.Iterable values) { + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll( + values, exemplars_); + onChanged(); + } else { + exemplarsBuilder_.addAllMessages(values); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder clearExemplars() { + if (exemplarsBuilder_ == null) { + exemplars_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00008000); + onChanged(); + } else { + exemplarsBuilder_.clear(); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public Builder removeExemplars(int index) { + if (exemplarsBuilder_ == null) { + ensureExemplarsIsMutable(); + exemplars_.remove(index); + onChanged(); + } else { + exemplarsBuilder_.remove(index); + } + return this; + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarsBuilder( + int index) { + return getExemplarsFieldBuilder().getBuilder(index); + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder( + int index) { + if (exemplarsBuilder_ == null) { + return exemplars_.get(index); } else { + return exemplarsBuilder_.getMessageOrBuilder(index); + } + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public java.util.List + getExemplarsOrBuilderList() { + if (exemplarsBuilder_ != null) { + return exemplarsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(exemplars_); + } + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder addExemplarsBuilder() { + return getExemplarsFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()); + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder addExemplarsBuilder( + int index) { + return getExemplarsFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()); + } + /** + *
      +       * Only used for native histograms. These exemplars MUST have a timestamp.
      +       * 
      + * + * repeated .io.prometheus.client.Exemplar exemplars = 16; + */ + public java.util.List + getExemplarsBuilderList() { + return getExemplarsFieldBuilder().getBuilderList(); + } + private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> + getExemplarsFieldBuilder() { + if (exemplarsBuilder_ == null) { + exemplarsBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3< + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>( + exemplars_, + ((bitField0_ & 0x00008000) != 0), + getParentForChildren(), + isClean()); + exemplars_ = null; + } + return exemplarsBuilder_; + } @java.lang.Override public final Builder setUnknownFields( - final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); } @java.lang.Override public final Builder mergeUnknownFields( - final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) { + final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) { return super.mergeUnknownFields(unknownFields); } @@ -8648,48 +9174,48 @@ public final Builder mergeUnknownFields( } // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstance() { return DEFAULT_INSTANCE; } - @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser - PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() { + @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser + PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() { @java.lang.Override public Histogram parsePartialFrom( - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input, - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry) - throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input, + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry) + throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException { Builder builder = newBuilder(); try { builder.mergeFrom(input, extensionRegistry); - } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) { + } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(builder.buildPartial()); - } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) { + } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) { throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); } catch (java.io.IOException e) { - throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e) + throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e) .setUnfinishedMessage(builder.buildPartial()); } return builder.buildPartial(); } }; - public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() { + public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() { return PARSER; } @java.lang.Override - public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() { + public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() { return PARSER; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -8697,7 +9223,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2 public interface BucketOrBuilder extends // @@protoc_insertion_point(interface_extends:io.prometheus.client.Bucket) - io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder { + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder { /** *
      @@ -8765,11 +9291,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -8780,12 +9306,12 @@ public interface BucketOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Bucket}
          */
         public static final class Bucket extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Bucket)
             BucketOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Bucket.newBuilder() to construct.
      -    private Bucket(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Bucket(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Bucket() {
      @@ -8798,17 +9324,17 @@ protected java.lang.Object newInstance(
             return new Bucket();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -8894,7 +9420,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -8908,15 +9434,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -8931,7 +9457,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeUInt64(1, cumulativeCount_);
      @@ -8955,19 +9481,19 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeUInt64Size(1, cumulativeCount_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(2, upperBound_);
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(3, getExemplar());
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(4, cumulativeCountFloat_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -8980,10 +9506,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9020,17 +9546,17 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasCumulativeCount()) {
               hash = (37 * hash) + CUMULATIVE_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   getCumulativeCount());
             }
             if (hasCumulativeCountFloat()) {
               hash = (37 * hash) + CUMULATIVE_COUNT_FLOAT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getCumulativeCountFloat()));
             }
             if (hasUpperBound()) {
               hash = (37 * hash) + UPPER_BOUND_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getUpperBound()));
             }
             if (hasExemplar()) {
      @@ -9042,75 +9568,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -9119,7 +9645,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9130,7 +9656,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -9143,34 +9669,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Bucket}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                       .alwaysUseFieldBuilders) {
                 getExemplarFieldBuilder();
               }
      @@ -9191,19 +9717,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9211,14 +9737,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9248,44 +9774,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9310,8 +9836,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -9354,7 +9880,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -9531,9 +10057,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar exemplar_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9545,9 +10071,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9555,7 +10081,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9572,7 +10098,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9585,11 +10111,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9597,8 +10123,10 @@ public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.c
               } else {
                 exemplarBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000008;
      -        onChanged();
      +        if (exemplar_ != null) {
      +          bitField0_ |= 0x00000008;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -9617,7 +10145,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -9625,23 +10153,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
      -          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder>(
      +          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9651,13 +10179,13 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -9666,48 +10194,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Bucket parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9715,7 +10243,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface BucketSpanOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.BucketSpan)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * 
      @@ -9768,12 +10296,12 @@ public interface BucketSpanOrBuilder extends
          * Protobuf type {@code io.prometheus.client.BucketSpan}
          */
         public static final class BucketSpan extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.BucketSpan)
             BucketSpanOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use BucketSpan.newBuilder() to construct.
      -    private BucketSpan(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private BucketSpan(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private BucketSpan() {
      @@ -9786,17 +10314,17 @@ protected java.lang.Object newInstance(
             return new BucketSpan();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -9866,7 +10394,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeSInt32(1, offset_);
      @@ -9884,11 +10412,11 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeSInt32Size(1, offset_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeUInt32Size(2, length_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -9901,10 +10429,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -9940,75 +10468,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -10017,7 +10545,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10028,7 +10556,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -10045,29 +10573,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.BucketSpan}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpanOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -10081,19 +10609,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10101,14 +10629,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10128,44 +10656,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10184,8 +10712,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -10216,7 +10744,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -10338,13 +10866,13 @@ public Builder clearLength() {
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -10353,48 +10881,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public BucketSpan parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10402,17 +10930,17 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface ExemplarOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Exemplar)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10420,12 +10948,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10456,7 +10984,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .google.protobuf.Timestamp timestamp = 3;
            * @return The timestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp();
           /**
            * 
            * OpenMetrics-style.
      @@ -10464,18 +10992,18 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder();
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Exemplar}
          */
         public static final class Exemplar extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Exemplar)
             ExemplarOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Exemplar.newBuilder() to construct.
      -    private Exemplar(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Exemplar(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Exemplar() {
      @@ -10489,35 +11017,35 @@ protected java.lang.Object newInstance(
             return new Exemplar();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10532,14 +11060,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10564,7 +11092,7 @@ public double getValue() {
           }
       
           public static final int TIMESTAMP_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp timestamp_;
      +    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp timestamp_;
           /**
            * 
            * OpenMetrics-style.
      @@ -10586,8 +11114,8 @@ public boolean hasTimestamp() {
            * @return The timestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
      -      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp() {
      +      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
           }
           /**
            * 
      @@ -10597,8 +11125,8 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTime
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
      -      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder() {
      +      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -10613,7 +11141,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             for (int i = 0; i < label_.size(); i++) {
               output.writeMessage(1, label_.get(i));
      @@ -10634,15 +11162,15 @@ public int getSerializedSize() {
       
             size = 0;
             for (int i = 0; i < label_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(1, label_.get(i));
             }
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeDoubleSize(2, value_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(3, getTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -10655,10 +11183,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10690,7 +11218,7 @@ public int hashCode() {
             }
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             if (hasTimestamp()) {
      @@ -10702,75 +11230,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -10779,7 +11307,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10790,7 +11318,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -10798,34 +11326,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Exemplar}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.ExemplarOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                       .alwaysUseFieldBuilders) {
                 getLabelFieldBuilder();
                 getTimestampFieldBuilder();
      @@ -10852,19 +11380,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10872,15 +11400,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -10892,7 +11420,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -10914,44 +11442,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -10971,7 +11499,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     label_ = other.label_;
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
                          getLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
      @@ -10996,8 +11524,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -11011,9 +11539,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.PARSER,
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11043,7 +11571,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -11052,22 +11580,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11087,7 +11615,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11098,7 +11626,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11115,7 +11643,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11128,7 +11656,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11145,7 +11673,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11162,7 +11690,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11176,7 +11704,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11190,10 +11718,10 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, label_);
                 onChanged();
               } else {
      @@ -11230,14 +11758,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11247,7 +11775,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11258,31 +11786,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
      -          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>(
      +          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11332,9 +11860,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp timestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> timestampBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp timestamp_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> timestampBuilder_;
             /**
              * 
              * OpenMetrics-style.
      @@ -11354,9 +11882,9 @@ public boolean hasTimestamp() {
              * optional .google.protobuf.Timestamp timestamp = 3;
              * @return The timestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTimestamp() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp() {
               if (timestampBuilder_ == null) {
      -          return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
      +          return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
               } else {
                 return timestampBuilder_.getMessage();
               }
      @@ -11368,7 +11896,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp getTime
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (timestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11389,7 +11917,7 @@ public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_2
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
             public Builder setTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder builderForValue) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
               if (timestampBuilder_ == null) {
                 timestamp_ = builderForValue.build();
               } else {
      @@ -11406,11 +11934,11 @@ public Builder setTimestamp(
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public Builder mergeTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp value) {
      +      public Builder mergeTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
               if (timestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   timestamp_ != null &&
      -            timestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance()) {
      +            timestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
                   getTimestampBuilder().mergeFrom(value);
                 } else {
                   timestamp_ = value;
      @@ -11418,8 +11946,10 @@ public Builder mergeTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3
               } else {
                 timestampBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000004;
      -        onChanged();
      +        if (timestamp_ != null) {
      +          bitField0_ |= 0x00000004;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -11446,7 +11976,7 @@ public Builder clearTimestamp() {
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder getTimestampBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getTimestampBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getTimestampFieldBuilder().getBuilder();
      @@ -11458,12 +11988,12 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder getTimestampOrBuilder() {
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder() {
               if (timestampBuilder_ != null) {
                 return timestampBuilder_.getMessageOrBuilder();
               } else {
                 return timestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.getDefaultInstance() : timestamp_;
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
               }
             }
             /**
      @@ -11473,12 +12003,12 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilde
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
                 getTimestampFieldBuilder() {
               if (timestampBuilder_ == null) {
      -          timestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilder>(
      +          timestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
                         getTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -11488,13 +12018,13 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampOrBuilde
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -11503,48 +12033,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Exemplar parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11552,17 +12082,17 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface MetricOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Metric)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11570,12 +12100,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11587,11 +12117,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11602,11 +12132,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11617,11 +12147,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11632,11 +12162,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11647,11 +12177,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11668,12 +12198,12 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Met
          * Protobuf type {@code io.prometheus.client.Metric}
          */
         public static final class Metric extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Metric)
             MetricOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use Metric.newBuilder() to construct.
      -    private Metric(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private Metric(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private Metric() {
      @@ -11687,35 +12217,35 @@ protected java.lang.Object newInstance(
             return new Metric();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11730,20 +12260,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11757,19 +12287,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11783,19 +12313,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11809,19 +12339,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11835,19 +12365,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11861,15 +12391,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -11903,7 +12433,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             for (int i = 0; i < label_.size(); i++) {
               output.writeMessage(1, label_.get(i));
      @@ -11936,31 +12466,31 @@ public int getSerializedSize() {
       
             size = 0;
             for (int i = 0; i < label_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(1, label_.get(i));
             }
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(2, getGauge());
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(3, getCounter());
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(4, getSummary());
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(5, getUntyped());
             }
             if (((bitField0_ & 0x00000020) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeInt64Size(6, timestampMs_);
             }
             if (((bitField0_ & 0x00000010) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(7, getHistogram());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -11973,10 +12503,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12047,7 +12577,7 @@ public int hashCode() {
             }
             if (hasTimestampMs()) {
               hash = (37 * hash) + TIMESTAMP_MS_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Internal.hashLong(
      +        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
                   getTimestampMs());
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -12055,75 +12585,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -12132,7 +12662,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12143,7 +12673,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -12151,34 +12681,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Metric}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                       .alwaysUseFieldBuilders) {
                 getLabelFieldBuilder();
                 getGaugeFieldBuilder();
      @@ -12229,19 +12759,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12249,15 +12779,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12269,7 +12799,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12315,44 +12845,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12372,7 +12902,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     label_ = other.label_;
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
                          getLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
      @@ -12409,8 +12939,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -12424,9 +12954,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.PARSER,
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12484,7 +13014,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -12493,22 +13023,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> labelBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12528,7 +13058,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12539,7 +13069,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12556,7 +13086,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12569,7 +13099,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12586,7 +13116,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12603,7 +13133,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12617,7 +13147,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12631,10 +13161,10 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, label_);
                 onChanged();
               } else {
      @@ -12671,14 +13201,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12688,7 +13218,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12699,31 +13229,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
      -          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.LabelPairOrBuilder>(
      +          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12733,9 +13263,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge gauge_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12747,9 +13277,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12757,7 +13287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12774,7 +13304,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12787,11 +13317,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12799,8 +13329,10 @@ public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_
               } else {
                 gaugeBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000002;
      -        onChanged();
      +        if (gauge_ != null) {
      +          bitField0_ |= 0x00000002;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -12819,7 +13351,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getGaugeFieldBuilder().getBuilder();
      @@ -12827,23 +13359,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder> 
                 getGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
      -          gaugeBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.GaugeOrBuilder>(
      +          gaugeBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12852,9 +13384,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter counter_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> counterBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter counter_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12866,9 +13398,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12876,7 +13408,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12893,7 +13425,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -12906,11 +13438,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -12918,8 +13450,10 @@ public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.co
               } else {
                 counterBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000004;
      -        onChanged();
      +        if (counter_ != null) {
      +          bitField0_ |= 0x00000004;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -12938,7 +13472,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCounterFieldBuilder().getBuilder();
      @@ -12946,23 +13480,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder> 
                 getCounterFieldBuilder() {
               if (counterBuilder_ == null) {
      -          counterBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.CounterOrBuilder>(
      +          counterBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -12971,9 +13505,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary summary_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> summaryBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary summary_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -12985,9 +13519,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -12995,7 +13529,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13012,7 +13546,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13025,11 +13559,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13037,8 +13571,10 @@ public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.co
               } else {
                 summaryBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000008;
      -        onChanged();
      +        if (summary_ != null) {
      +          bitField0_ |= 0x00000008;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -13057,7 +13593,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getSummaryFieldBuilder().getBuilder();
      @@ -13065,23 +13601,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder> 
                 getSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
      -          summaryBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.SummaryOrBuilder>(
      +          summaryBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13090,9 +13626,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped untyped_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> untypedBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13104,9 +13640,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13114,7 +13650,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13131,7 +13667,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13144,11 +13680,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13156,8 +13692,10 @@ public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.co
               } else {
                 untypedBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000010;
      -        onChanged();
      +        if (untyped_ != null) {
      +          bitField0_ |= 0x00000010;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -13176,7 +13714,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getUntypedFieldBuilder().getBuilder();
      @@ -13184,23 +13722,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder> 
                 getUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
      -          untypedBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.UntypedOrBuilder>(
      +          untypedBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13209,9 +13747,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram histogram_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> histogramBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13223,9 +13761,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13233,7 +13771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13250,7 +13788,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13263,11 +13801,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13275,8 +13813,10 @@ public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.
               } else {
                 histogramBuilder_.mergeFrom(value);
               }
      -        bitField0_ |= 0x00000020;
      -        onChanged();
      +        if (histogram_ != null) {
      +          bitField0_ |= 0x00000020;
      +          onChanged();
      +        }
               return this;
             }
             /**
      @@ -13295,7 +13835,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return getHistogramFieldBuilder().getBuilder();
      @@ -13303,23 +13843,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder> 
                 getHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
      -          histogramBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.HistogramOrBuilder>(
      +          histogramBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13369,13 +13909,13 @@ public Builder clearTimestampMs() {
             }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -13384,48 +13924,48 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public Metric parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13433,7 +13973,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface MetricFamilyOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.MetricFamily)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.MessageOrBuilder {
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
       
           /**
            * optional string name = 1;
      @@ -13449,7 +13989,7 @@ public interface MetricFamilyOrBuilder extends
            * optional string name = 1;
            * @return The bytes for name.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getNameBytes();
       
           /**
      @@ -13466,7 +14006,7 @@ public interface MetricFamilyOrBuilder extends
            * optional string help = 2;
            * @return The bytes for help.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getHelpBytes();
       
           /**
      @@ -13478,17 +14018,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13496,24 +14036,41 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
      +
      +    /**
      +     * optional string unit = 5;
      +     * @return Whether the unit field is set.
      +     */
      +    boolean hasUnit();
      +    /**
      +     * optional string unit = 5;
      +     * @return The unit.
      +     */
      +    java.lang.String getUnit();
      +    /**
      +     * optional string unit = 5;
      +     * @return The bytes for unit.
      +     */
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +        getUnitBytes();
         }
         /**
          * Protobuf type {@code io.prometheus.client.MetricFamily}
          */
         public static final class MetricFamily extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3 implements
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.MetricFamily)
             MetricFamilyOrBuilder {
         private static final long serialVersionUID = 0L;
           // Use MetricFamily.newBuilder() to construct.
      -    private MetricFamily(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder builder) {
      +    private MetricFamily(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
             super(builder);
           }
           private MetricFamily() {
      @@ -13521,6 +14078,7 @@ private MetricFamily() {
             help_ = "";
             type_ = 0;
             metric_ = java.util.Collections.emptyList();
      +      unit_ = "";
           }
       
           @java.lang.Override
      @@ -13530,17 +14088,17 @@ protected java.lang.Object newInstance(
             return new MetricFamily();
           }
       
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13565,8 +14123,8 @@ public java.lang.String getName() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      +            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
      @@ -13579,17 +14137,17 @@ public java.lang.String getName() {
            * @return The bytes for name.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
             }
           }
       
      @@ -13614,8 +14172,8 @@ public java.lang.String getHelp() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      +            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 help_ = s;
      @@ -13628,17 +14186,17 @@ public java.lang.String getHelp() {
            * @return The bytes for help.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
               getHelpBytes() {
             java.lang.Object ref = help_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               help_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
             }
           }
       
      @@ -13655,26 +14213,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13689,18 +14247,67 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
       
      +    public static final int UNIT_FIELD_NUMBER = 5;
      +    @SuppressWarnings("serial")
      +    private volatile java.lang.Object unit_ = "";
      +    /**
      +     * optional string unit = 5;
      +     * @return Whether the unit field is set.
      +     */
      +    @java.lang.Override
      +    public boolean hasUnit() {
      +      return ((bitField0_ & 0x00000008) != 0);
      +    }
      +    /**
      +     * optional string unit = 5;
      +     * @return The unit.
      +     */
      +    @java.lang.Override
      +    public java.lang.String getUnit() {
      +      java.lang.Object ref = unit_;
      +      if (ref instanceof java.lang.String) {
      +        return (java.lang.String) ref;
      +      } else {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      +            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        java.lang.String s = bs.toStringUtf8();
      +        if (bs.isValidUtf8()) {
      +          unit_ = s;
      +        }
      +        return s;
      +      }
      +    }
      +    /**
      +     * optional string unit = 5;
      +     * @return The bytes for unit.
      +     */
      +    @java.lang.Override
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +        getUnitBytes() {
      +      java.lang.Object ref = unit_;
      +      if (ref instanceof java.lang.String) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +                (java.lang.String) ref);
      +        unit_ = b;
      +        return b;
      +      } else {
      +        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +      }
      +    }
      +
           private byte memoizedIsInitialized = -1;
           @java.lang.Override
           public final boolean isInitialized() {
      @@ -13713,13 +14320,13 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream output)
      +    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 1, name_);
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.writeString(output, 2, help_);
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 2, help_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
               output.writeEnum(3, type_);
      @@ -13727,6 +14334,9 @@ public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Code
             for (int i = 0; i < metric_.size(); i++) {
               output.writeMessage(4, metric_.get(i));
             }
      +      if (((bitField0_ & 0x00000008) != 0)) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 5, unit_);
      +      }
             getUnknownFields().writeTo(output);
           }
       
      @@ -13737,19 +14347,22 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(1, name_);
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.computeStringSize(2, help_);
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(2, help_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeEnumSize(3, type_);
             }
             for (int i = 0; i < metric_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedOutputStream
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
                 .computeMessageSize(4, metric_.get(i));
             }
      +      if (((bitField0_ & 0x00000008) != 0)) {
      +        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(5, unit_);
      +      }
             size += getUnknownFields().getSerializedSize();
             memoizedSize = size;
             return size;
      @@ -13760,10 +14373,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13781,6 +14394,11 @@ public boolean equals(final java.lang.Object obj) {
             }
             if (!getMetricList()
                 .equals(other.getMetricList())) return false;
      +      if (hasUnit() != other.hasUnit()) return false;
      +      if (hasUnit()) {
      +        if (!getUnit()
      +            .equals(other.getUnit())) return false;
      +      }
             if (!getUnknownFields().equals(other.getUnknownFields())) return false;
             return true;
           }
      @@ -13808,80 +14426,84 @@ public int hashCode() {
               hash = (37 * hash) + METRIC_FIELD_NUMBER;
               hash = (53 * hash) + getMetricList().hashCode();
             }
      +      if (hasUnit()) {
      +        hash = (37 * hash) + UNIT_FIELD_NUMBER;
      +        hash = (53 * hash) + getUnit().hashCode();
      +      }
             hash = (29 * hash) + getUnknownFields().hashCode();
             memoizedHashCode = hash;
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(byte[] data)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3
      +      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -13890,7 +14512,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -13901,7 +14523,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -13909,29 +14531,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.MetricFamily}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.Builder implements
      +        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamilyOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamilyOrBuilder {
      +      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.BuilderParent parent) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
               super(parent);
       
             }
      @@ -13949,23 +14571,24 @@ public Builder clear() {
                 metricBuilder_.clear();
               }
               bitField0_ = (bitField0_ & ~0x00000008);
      +        unit_ = "";
               return this;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -13973,15 +14596,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -13993,7 +14616,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14008,6 +14631,10 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
                 result.type_ = type_;
                 to_bitField0_ |= 0x00000004;
               }
      +        if (((from_bitField0_ & 0x00000010) != 0)) {
      +          result.unit_ = unit_;
      +          to_bitField0_ |= 0x00000008;
      +        }
               result.bitField0_ |= to_bitField0_;
             }
       
      @@ -14017,44 +14644,44 @@ public Builder clone() {
             }
             @java.lang.Override
             public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.setField(field, value);
             }
             @java.lang.Override
             public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
               return super.clearField(field);
             }
             @java.lang.Override
             public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.OneofDescriptor oneof) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
               return super.clearOneof(oneof);
             }
             @java.lang.Override
             public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 int index, java.lang.Object value) {
               return super.setRepeatedField(field, index, value);
             }
             @java.lang.Override
             public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FieldDescriptor field,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
                 java.lang.Object value) {
               return super.addRepeatedField(field, value);
             }
             @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily)other);
      +      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14087,13 +14714,18 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     metric_ = other.metric_;
                     bitField0_ = (bitField0_ & ~0x00000008);
                     metricBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
                          getMetricFieldBuilder() : null;
                   } else {
                     metricBuilder_.addAllMessages(other.metric_);
                   }
                 }
               }
      +        if (other.hasUnit()) {
      +          unit_ = other.unit_;
      +          bitField0_ |= 0x00000010;
      +          onChanged();
      +        }
               this.mergeUnknownFields(other.getUnknownFields());
               onChanged();
               return this;
      @@ -14106,8 +14738,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -14132,8 +14764,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14143,9 +14775,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.PARSER,
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14155,6 +14787,11 @@ public Builder mergeFrom(
                       }
                       break;
                     } // case 34
      +              case 42: {
      +                unit_ = input.readBytes();
      +                bitField0_ |= 0x00000010;
      +                break;
      +              } // case 42
                     default: {
                       if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                         done = true; // was an endgroup tag
      @@ -14163,7 +14800,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -14187,8 +14824,8 @@ public boolean hasName() {
             public java.lang.String getName() {
               java.lang.Object ref = name_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      +              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   name_ = s;
      @@ -14202,17 +14839,17 @@ public java.lang.String getName() {
              * optional string name = 1;
              * @return The bytes for name.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
                 getNameBytes() {
               java.lang.Object ref = name_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 name_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               }
             }
             /**
      @@ -14244,7 +14881,7 @@ public Builder clearName() {
              * @return This builder for chaining.
              */
             public Builder setNameBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               name_ = value;
               bitField0_ |= 0x00000001;
      @@ -14267,8 +14904,8 @@ public boolean hasHelp() {
             public java.lang.String getHelp() {
               java.lang.Object ref = help_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      +              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   help_ = s;
      @@ -14282,17 +14919,17 @@ public java.lang.String getHelp() {
              * optional string help = 2;
              * @return The bytes for help.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
                 getHelpBytes() {
               java.lang.Object ref = help_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString.copyFromUtf8(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 help_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString) ref;
      +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
               }
             }
             /**
      @@ -14324,7 +14961,7 @@ public Builder clearHelp() {
              * @return This builder for chaining.
              */
             public Builder setHelpBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ByteString value) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               help_ = value;
               bitField0_ |= 0x00000002;
      @@ -14345,16 +14982,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14374,22 +15011,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> metricBuilder_;
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14409,7 +15046,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14420,7 +15057,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14437,7 +15074,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14450,7 +15087,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14467,7 +15104,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14484,7 +15121,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14498,7 +15135,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14512,10 +15149,10 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractMessageLite.Builder.addAll(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
                     values, metric_);
                 onChanged();
               } else {
      @@ -14552,14 +15189,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14569,7 +15206,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14580,31 +15217,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder addMetricBuilder() {
               return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return getMetricFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder> 
      +      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder> 
                 getMetricFieldBuilder() {
               if (metricBuilder_ == null) {
      -          metricBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricOrBuilder>(
      +          metricBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14613,15 +15250,95 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               }
               return metricBuilder_;
             }
      +
      +      private java.lang.Object unit_ = "";
      +      /**
      +       * optional string unit = 5;
      +       * @return Whether the unit field is set.
      +       */
      +      public boolean hasUnit() {
      +        return ((bitField0_ & 0x00000010) != 0);
      +      }
      +      /**
      +       * optional string unit = 5;
      +       * @return The unit.
      +       */
      +      public java.lang.String getUnit() {
      +        java.lang.Object ref = unit_;
      +        if (!(ref instanceof java.lang.String)) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      +              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          java.lang.String s = bs.toStringUtf8();
      +          if (bs.isValidUtf8()) {
      +            unit_ = s;
      +          }
      +          return s;
      +        } else {
      +          return (java.lang.String) ref;
      +        }
      +      }
      +      /**
      +       * optional string unit = 5;
      +       * @return The bytes for unit.
      +       */
      +      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +          getUnitBytes() {
      +        java.lang.Object ref = unit_;
      +        if (ref instanceof String) {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      +              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +                  (java.lang.String) ref);
      +          unit_ = b;
      +          return b;
      +        } else {
      +          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        }
      +      }
      +      /**
      +       * optional string unit = 5;
      +       * @param value The unit to set.
      +       * @return This builder for chaining.
      +       */
      +      public Builder setUnit(
      +          java.lang.String value) {
      +        if (value == null) { throw new NullPointerException(); }
      +        unit_ = value;
      +        bitField0_ |= 0x00000010;
      +        onChanged();
      +        return this;
      +      }
      +      /**
      +       * optional string unit = 5;
      +       * @return This builder for chaining.
      +       */
      +      public Builder clearUnit() {
      +        unit_ = getDefaultInstance().getUnit();
      +        bitField0_ = (bitField0_ & ~0x00000010);
      +        onChanged();
      +        return this;
      +      }
      +      /**
      +       * optional string unit = 5;
      +       * @param value The bytes for unit to set.
      +       * @return This builder for chaining.
      +       */
      +      public Builder setUnitBytes(
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +        if (value == null) { throw new NullPointerException(); }
      +        unit_ = value;
      +        bitField0_ |= 0x00000010;
      +        onChanged();
      +        return this;
      +      }
             @java.lang.Override
             public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.setUnknownFields(unknownFields);
             }
       
             @java.lang.Override
             public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UnknownFieldSet unknownFields) {
      +          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
               return super.mergeUnknownFields(unknownFields);
             }
       
      @@ -14630,119 +15347,119 @@ public final Builder mergeUnknownFields(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.AbstractParser() {
      +    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      +        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
             @java.lang.Override
             public MetricFamily parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.UninitializedMessageException e) {
      +        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.InvalidProtocolBufferException(e)
      +          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser parser() {
      +    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Parser getParserForType() {
      +    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
         }
       
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_LabelPair_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_LabelPair_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Gauge_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Gauge_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Counter_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Counter_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Quantile_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Quantile_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Summary_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Summary_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Untyped_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Untyped_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Histogram_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Histogram_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Bucket_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Bucket_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_BucketSpan_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Exemplar_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Exemplar_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_Metric_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_Metric_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.Descriptor
      +  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
           internal_static_io_prometheus_client_MetricFamily_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
             internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable;
       
      -  public static io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
      +  public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
             getDescriptor() {
           return descriptor;
         }
      -  private static  io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
      +  private static  io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
             descriptor;
         static {
           java.lang.String[] descriptorData = {
      @@ -14758,7 +15475,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             "\001 \001(\004\022\022\n\nsample_sum\030\002 \001(\001\0220\n\010quantile\030\003 " +
             "\003(\0132\036.io.prometheus.client.Quantile\0225\n\021c" +
             "reated_timestamp\030\004 \001(\0132\032.google.protobuf" +
      -      ".Timestamp\"\030\n\007Untyped\022\r\n\005value\030\001 \001(\001\"\336\003\n" +
      +      ".Timestamp\"\030\n\007Untyped\022\r\n\005value\030\001 \001(\001\"\221\004\n" +
             "\tHistogram\022\024\n\014sample_count\030\001 \001(\004\022\032\n\022samp" +
             "le_count_float\030\004 \001(\001\022\022\n\nsample_sum\030\002 \001(\001" +
             "\022,\n\006bucket\030\003 \003(\0132\034.io.prometheus.client." +
      @@ -14770,112 +15487,113 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             "Span\022\026\n\016negative_delta\030\n \003(\022\022\026\n\016negative" +
             "_count\030\013 \003(\001\0227\n\rpositive_span\030\014 \003(\0132 .io" +
             ".prometheus.client.BucketSpan\022\026\n\016positiv" +
      -      "e_delta\030\r \003(\022\022\026\n\016positive_count\030\016 \003(\001\"\211\001" +
      -      "\n\006Bucket\022\030\n\020cumulative_count\030\001 \001(\004\022\036\n\026cu" +
      -      "mulative_count_float\030\004 \001(\001\022\023\n\013upper_boun" +
      -      "d\030\002 \001(\001\0220\n\010exemplar\030\003 \001(\0132\036.io.prometheu" +
      -      "s.client.Exemplar\",\n\nBucketSpan\022\016\n\006offse" +
      -      "t\030\001 \001(\021\022\016\n\006length\030\002 \001(\r\"x\n\010Exemplar\022.\n\005l" +
      -      "abel\030\001 \003(\0132\037.io.prometheus.client.LabelP" +
      -      "air\022\r\n\005value\030\002 \001(\001\022-\n\ttimestamp\030\003 \001(\0132\032." +
      -      "google.protobuf.Timestamp\"\276\002\n\006Metric\022.\n\005" +
      -      "label\030\001 \003(\0132\037.io.prometheus.client.Label" +
      -      "Pair\022*\n\005gauge\030\002 \001(\0132\033.io.prometheus.clie" +
      -      "nt.Gauge\022.\n\007counter\030\003 \001(\0132\035.io.prometheu" +
      -      "s.client.Counter\022.\n\007summary\030\004 \001(\0132\035.io.p" +
      -      "rometheus.client.Summary\022.\n\007untyped\030\005 \001(" +
      -      "\0132\035.io.prometheus.client.Untyped\0222\n\thist" +
      -      "ogram\030\007 \001(\0132\037.io.prometheus.client.Histo" +
      -      "gram\022\024\n\014timestamp_ms\030\006 \001(\003\"\210\001\n\014MetricFam" +
      -      "ily\022\014\n\004name\030\001 \001(\t\022\014\n\004help\030\002 \001(\t\022.\n\004type\030" +
      -      "\003 \001(\0162 .io.prometheus.client.MetricType\022" +
      -      ",\n\006metric\030\004 \003(\0132\034.io.prometheus.client.M" +
      -      "etric*b\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUG" +
      -      "E\020\001\022\013\n\007SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGR" +
      -      "AM\020\004\022\023\n\017GAUGE_HISTOGRAM\020\005B\212\001\nLio.prometh" +
      -      "eus.metrics.expositionformats.generated." +
      -      "com_google_protobuf_3_21_7Z:github.com/p" +
      -      "rometheus/client_model/go;io_prometheus_" +
      -      "client"
      +      "e_delta\030\r \003(\022\022\026\n\016positive_count\030\016 \003(\001\0221\n" +
      +      "\texemplars\030\020 \003(\0132\036.io.prometheus.client." +
      +      "Exemplar\"\211\001\n\006Bucket\022\030\n\020cumulative_count\030" +
      +      "\001 \001(\004\022\036\n\026cumulative_count_float\030\004 \001(\001\022\023\n" +
      +      "\013upper_bound\030\002 \001(\001\0220\n\010exemplar\030\003 \001(\0132\036.i" +
      +      "o.prometheus.client.Exemplar\",\n\nBucketSp" +
      +      "an\022\016\n\006offset\030\001 \001(\021\022\016\n\006length\030\002 \001(\r\"x\n\010Ex" +
      +      "emplar\022.\n\005label\030\001 \003(\0132\037.io.prometheus.cl" +
      +      "ient.LabelPair\022\r\n\005value\030\002 \001(\001\022-\n\ttimesta" +
      +      "mp\030\003 \001(\0132\032.google.protobuf.Timestamp\"\276\002\n" +
      +      "\006Metric\022.\n\005label\030\001 \003(\0132\037.io.prometheus.c" +
      +      "lient.LabelPair\022*\n\005gauge\030\002 \001(\0132\033.io.prom" +
      +      "etheus.client.Gauge\022.\n\007counter\030\003 \001(\0132\035.i" +
      +      "o.prometheus.client.Counter\022.\n\007summary\030\004" +
      +      " \001(\0132\035.io.prometheus.client.Summary\022.\n\007u" +
      +      "ntyped\030\005 \001(\0132\035.io.prometheus.client.Unty" +
      +      "ped\0222\n\thistogram\030\007 \001(\0132\037.io.prometheus.c" +
      +      "lient.Histogram\022\024\n\014timestamp_ms\030\006 \001(\003\"\226\001" +
      +      "\n\014MetricFamily\022\014\n\004name\030\001 \001(\t\022\014\n\004help\030\002 \001" +
      +      "(\t\022.\n\004type\030\003 \001(\0162 .io.prometheus.client." +
      +      "MetricType\022,\n\006metric\030\004 \003(\0132\034.io.promethe" +
      +      "us.client.Metric\022\014\n\004unit\030\005 \001(\t*b\n\nMetric" +
      +      "Type\022\013\n\007COUNTER\020\000\022\t\n\005GAUGE\020\001\022\013\n\007SUMMARY\020" +
      +      "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
      +      "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
      +      "ositionformats.generated.com_google_prot" +
      +      "obuf_3_25_3Z:github.com/prometheus/clien" +
      +      "t_model/go;io_prometheus_client"
           };
      -    descriptor = io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor
      +    descriptor = io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
             .internalBuildGeneratedFileFrom(descriptorData,
      -        new io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Descriptors.FileDescriptor[] {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampProto.getDescriptor(),
      +        new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor[] {
      +          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampProto.getDescriptor(),
               });
           internal_static_io_prometheus_client_LabelPair_descriptor =
             getDescriptor().getMessageTypes().get(0);
           internal_static_io_prometheus_client_LabelPair_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_LabelPair_descriptor,
               new java.lang.String[] { "Name", "Value", });
           internal_static_io_prometheus_client_Gauge_descriptor =
             getDescriptor().getMessageTypes().get(1);
           internal_static_io_prometheus_client_Gauge_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Gauge_descriptor,
               new java.lang.String[] { "Value", });
           internal_static_io_prometheus_client_Counter_descriptor =
             getDescriptor().getMessageTypes().get(2);
           internal_static_io_prometheus_client_Counter_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Counter_descriptor,
               new java.lang.String[] { "Value", "Exemplar", "CreatedTimestamp", });
           internal_static_io_prometheus_client_Quantile_descriptor =
             getDescriptor().getMessageTypes().get(3);
           internal_static_io_prometheus_client_Quantile_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Quantile_descriptor,
               new java.lang.String[] { "Quantile", "Value", });
           internal_static_io_prometheus_client_Summary_descriptor =
             getDescriptor().getMessageTypes().get(4);
           internal_static_io_prometheus_client_Summary_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Summary_descriptor,
               new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", "CreatedTimestamp", });
           internal_static_io_prometheus_client_Untyped_descriptor =
             getDescriptor().getMessageTypes().get(5);
           internal_static_io_prometheus_client_Untyped_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Untyped_descriptor,
               new java.lang.String[] { "Value", });
           internal_static_io_prometheus_client_Histogram_descriptor =
             getDescriptor().getMessageTypes().get(6);
           internal_static_io_prometheus_client_Histogram_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Histogram_descriptor,
      -        new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "CreatedTimestamp", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", });
      +        new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "CreatedTimestamp", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", "Exemplars", });
           internal_static_io_prometheus_client_Bucket_descriptor =
             getDescriptor().getMessageTypes().get(7);
           internal_static_io_prometheus_client_Bucket_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Bucket_descriptor,
               new java.lang.String[] { "CumulativeCount", "CumulativeCountFloat", "UpperBound", "Exemplar", });
           internal_static_io_prometheus_client_BucketSpan_descriptor =
             getDescriptor().getMessageTypes().get(8);
           internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_BucketSpan_descriptor,
               new java.lang.String[] { "Offset", "Length", });
           internal_static_io_prometheus_client_Exemplar_descriptor =
             getDescriptor().getMessageTypes().get(9);
           internal_static_io_prometheus_client_Exemplar_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Exemplar_descriptor,
               new java.lang.String[] { "Label", "Value", "Timestamp", });
           internal_static_io_prometheus_client_Metric_descriptor =
             getDescriptor().getMessageTypes().get(10);
           internal_static_io_prometheus_client_Metric_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_Metric_descriptor,
               new java.lang.String[] { "Label", "Gauge", "Counter", "Summary", "Untyped", "Histogram", "TimestampMs", });
           internal_static_io_prometheus_client_MetricFamily_descriptor =
             getDescriptor().getMessageTypes().get(11);
           internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.GeneratedMessageV3.FieldAccessorTable(
      +      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
               internal_static_io_prometheus_client_MetricFamily_descriptor,
      -        new java.lang.String[] { "Name", "Help", "Type", "Metric", });
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TimestampProto.getDescriptor();
      +        new java.lang.String[] { "Name", "Help", "Type", "Metric", "Unit", });
      +    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampProto.getDescriptor();
         }
       
         // @@protoc_insertion_point(outer_class_scope)
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      index 090ac2a89..e0103059a 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      @@ -1,7 +1,7 @@
       package io.prometheus.metrics.expositionformats;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics;
      +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      index e8beeee6c..ad3a28828 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      @@ -1,6 +1,6 @@
       package io.prometheus.metrics.expositionformats;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.Timestamp;
      +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp;
       
       public class ProtobufUtil {
       
      diff --git a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
      index 1faefbca4..724f96643 100644
      --- a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
      +++ b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
      @@ -14,7 +14,7 @@
       syntax = "proto2";
       
       package io.prometheus.client;
      -option java_package = "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7";
      +option java_package = "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3";
       option go_package = "github.com/prometheus/client_model/go;io_prometheus_client";
       
       import "google/protobuf/timestamp.proto";
      @@ -107,6 +107,9 @@ message Histogram {
         // histograms.
         repeated sint64 positive_delta    = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
         repeated double positive_count    = 14; // Absolute count of each bucket.
      +
      +  // Only used for native histograms. These exemplars MUST have a timestamp.
      +  repeated Exemplar exemplars = 16;
       }
       
       // A Bucket of a conventional histogram, each of which is treated as
      @@ -150,4 +153,5 @@ message MetricFamily {
         optional string     help   = 2;
         optional MetricType type   = 3;
         repeated Metric     metric = 4;
      +  optional string     unit   = 5;
       }
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      index 10c7d3a0d..c86bc6520 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      @@ -1,7 +1,7 @@
       package io.prometheus.metrics.expositionformats;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics;
      +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
       import io.prometheus.metrics.model.snapshots.Exemplar;
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 73f96d5f5..8c8d58696 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -16,8 +16,8 @@
           
       
           
      -        1.31.0
      -        1_31_0
      +        1.36.0
      +        1_36_0
           
       
           
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index 224571946..8d99fd238 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -20,9 +20,9 @@
           
               
               
      -        3.21.7
      +        3.25.3
               
      -        3_21_7
      +        3_25_3
           
       
           
      
      From 53d622bcbc807762ff5b93d84e9150be92e21c38 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 16:47:50 +0100
      Subject: [PATCH 305/980] Temporarily add shaded dependencies to prepare for
       release
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index dd1edea32..ee7c38843 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -66,7 +66,7 @@
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
      -        
      +        prometheus-metrics-shaded-dependencies
               examples
               benchmarks
               integration-tests
      
      From 71cf428df6450b2365917e772dce4d32f1aeaa32 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 16:53:11 +0100
      Subject: [PATCH 306/980] Update release docs
      
      ---
       MAINTAINER_NOTES.md | 46 +++++++++++++++++++++++++++++++++++++++++++--
       1 file changed, 44 insertions(+), 2 deletions(-)
      
      diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md
      index 90f030c23..deeaee4dd 100644
      --- a/MAINTAINER_NOTES.md
      +++ b/MAINTAINER_NOTES.md
      @@ -8,15 +8,57 @@ Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/i
       ./mvnw versions:use-latest-releases
       ```
       
      +The versions plugin does not catch the `otel.version` in `prometheus-metrics-exporter-opentelemetry`. This needs to be updated manually.
      +
      +## Update Shaded Dependencies
      +
      +There are two modules for shaded dependencies:
      +* `prometheus-metrics-shaded-opentelemetry`: OpenTelemetry data model.
      +* `prometheus-metrics-shaded-protobuf`: Google's protobuf library.
      +
      +The shaded modules are commented out in the root `pom.xml`. Instead of using the shaded dependencies from the project, we use the latest shaded dependencies from Maven central (or from the local Maven repository in `~/.m2/repository/`). This way we can `include` the shaded package name directly. We find this easier than importing the original package name and have it renamed at build time.
      +
      +In order to update dependencies of the shaded modules (like Google's protobuf library or the OpenTelemetry library), do the following:
      +
      +Step 1: Install updated versions of the shaded dependencies in your local Maven repository.
      +
      +* Update the dependency versions in the shaded modules (both `*.version` and `*.version.string`).
      +* `cd ./prometheus-metrics-shaded-dependencies ; ../mvnw install ; cd ..`
      +
      +Step 2: Update `prometheus-metrics-expositon-formats`
      +
      +* Change the version of the `prometheus-metrics-shaded-protobuf` dependency in `pom.xml` to `${project.version}`.
      +* Update `PROTOBUF_VERSION_STRING` in `generate-protobuf.sh` and run the script to update the source code.
      +* Use find-and-replace to update the version numbers in the imported package names in the source code of `prometheus-metrics-exposition-formats` and `prometheus-metrics-core`.
      +
      +Step 3: Update `prometheus-metrics-exporter-opentelemetry`
      +
      +* Change the version of the `prometheus-metrics-shaded-opentelemetry` dependency in `pom.xml` to `${project.version}`.
      +* Use find-and-replace to update the version numbers in the imported package names in the source code of `prometheus-metrics-exporter-opentelemetry`.
      +
      +Step 4: Release
      +
      +_see below_
      +
       ## Release
       
      +Create a commit to temporarily add shaded dependencies to the project:
      +
      +* Add the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`.
      +* Change the versions of the shaded dependencies to `${project.version}` in `prometheus-metrics-exporter-opentelemetry` and `prometheus-metrics-exposition-formats`.
      +
      +Release:
      +
       ```
       ./mvnw release:prepare -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT
       ./mvnw release:perform -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT
       ```
       
      -`release:prepare` does Github tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org).
      +`release:prepare` does GitHub tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org).
       
       After that, manually verify the uploaded artifacts on [https://oss.sonatype.org/#stagingRepositories](https://oss.sonatype.org/#stagingRepositories), click `Close` to trigger Sonatype's verification, and then `Release`.
       
      -Note: We release only the parent module and the modules starting with simpleclient. Currently, we manually remove the benchmark and integration test modules. Todo: Instead of manually removing these modules, we should reconfigure the build to make sure that these modules aren't released.
      +Create a commit to remove dependencies from the build (undoing the first step):
      +
      +* Comment out the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`.
      +* Change the versions of the shaded dependencies to the latest released version on Maven Central in `prometheus-metrics-exporter-opentelemetry` and `prometheus-metrics-exposition-formats`.
      
      From fbb6ae746735204f8990e84bd8c24d0006896b09 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 17:04:47 +0100
      Subject: [PATCH 307/980] Update shaded dependencies in BOM
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       MAINTAINER_NOTES.md            | 10 +++++++---
       prometheus-metrics-bom/pom.xml |  9 ++++++---
       2 files changed, 13 insertions(+), 6 deletions(-)
      
      diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md
      index deeaee4dd..a58e73a45 100644
      --- a/MAINTAINER_NOTES.md
      +++ b/MAINTAINER_NOTES.md
      @@ -36,7 +36,11 @@ Step 3: Update `prometheus-metrics-exporter-opentelemetry`
       * Change the version of the `prometheus-metrics-shaded-opentelemetry` dependency in `pom.xml` to `${project.version}`.
       * Use find-and-replace to update the version numbers in the imported package names in the source code of `prometheus-metrics-exporter-opentelemetry`.
       
      -Step 4: Release
      +Step 4: Update `prometheus-metrics-bom`
      +
      +* Set the shaded dependency version property to `${project.version}` in `prometheus-metrics-bom/pom.xml`
      +
      +Step 5: Release
       
       _see below_
       
      @@ -45,7 +49,7 @@ _see below_
       Create a commit to temporarily add shaded dependencies to the project:
       
       * Add the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`.
      -* Change the versions of the shaded dependencies to `${project.version}` in `prometheus-metrics-exporter-opentelemetry` and `prometheus-metrics-exposition-formats`.
      +* Change the versions of the shaded dependencies to `${project.version}` in `prometheus-metrics-exporter-opentelemetry`, `prometheus-metrics-exposition-formats`, and `prometheus-metrics-bom`.
       
       Release:
       
      @@ -61,4 +65,4 @@ After that, manually verify the uploaded artifacts on [https://oss.sonatype.org/
       Create a commit to remove dependencies from the build (undoing the first step):
       
       * Comment out the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`.
      -* Change the versions of the shaded dependencies to the latest released version on Maven Central in `prometheus-metrics-exporter-opentelemetry` and `prometheus-metrics-exposition-formats`.
      +* Change the versions of the shaded dependencies to the latest released version on Maven Central in `prometheus-metrics-exporter-opentelemetry`, `prometheus-metrics-exposition-formats`, and `prometheus-metrics-bom`.
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index f11653adc..7e10fca3a 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -118,17 +118,20 @@
                   
                       io.prometheus
                       prometheus-metrics-shaded-dependencies
      -                ${prometheus.metrics.shaded.dependencies.version}
      +                
      +                ${project.version}
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-protobuf
      -                ${prometheus.metrics.shaded.dependencies.version}
      +                
      +                ${project.version}
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-opentelemetry
      -                ${prometheus.metrics.shaded.dependencies.version}
      +                
      +                ${project.version}
                   
               
           
      
      From 1eee0a4431daf30653642d3405c4cf73cf3344e5 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 17:10:15 +0100
      Subject: [PATCH 308/980] [maven-release-plugin] prepare release v1.2.0
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-bom/pom.xml                                | 2 +-
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exporter-servlet-javax/pom.xml             | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-dropwizard5/pom.xml        | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 2 +-
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       41 files changed, 43 insertions(+), 43 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index b57d082df..6ec3d3e7c 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 30a0821fa..6b719886b 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index 089ce016a..44c5da96d 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index d0d0d2d4c..cf06a084c 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index b556efaf3..cab23d9b1 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index 1bc04d401..5db678446 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index 06cae160a..61bff84e9 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 3e73b5db9..99035bb4b 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index 4f7180bad..ed9514562 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index 60249fbee..d2de5ee12 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index 981255de6..40dc51a57 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index aaf81b19f..aa7f467ff 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index 04198dc37..b08f7193e 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index 846018037..93b40e6ae 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 6904718a6..b2724708f 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index 194374da2..b97d8fcb9 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index d3b80d268..7619da2a7 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index c54b423f8..43c62b1c1 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.2.0
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 13a450d09..46b4788c5 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index ee7c38843..2a347ee09 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.2.0-SNAPSHOT
      +    1.2.0
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.2.0
           
       
           
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index 7e10fca3a..c5b39b16f 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-bom
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index 2247a8e8f..b01e1f1f9 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 7773301d0..411e7d434 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index 94a1e74cb..a882004f0 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index b99959fc4..c8c54cabc 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 1586387d0..6b21e6b0c 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index 204ff2fa7..b7ff5abe5 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml
      index 023506a68..7b327a5a2 100644
      --- a/prometheus-metrics-exporter-servlet-javax/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exporter-servlet-javax
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index f8e904561..553c0ffe6 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      index 7c1763cad..b7562eae3 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-instrumentation-dropwizard5
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index b9490532b..a7e67754f 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index f45d5b6fb..d81352042 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index 395fcdfd8..95b567bb6 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 8c8d58696..75323e37e 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index 8d99fd238..ab0aad2e1 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index aa355d50c..0119b57fb 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0-SNAPSHOT
      +        1.2.0
           
       
           prometheus-metrics-simpleclient-bridge
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index 3d7b44fae..2a08bd8f1 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.2.0-SNAPSHOT
      +    1.2.0
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index ed86d6249..ab332a884 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0-SNAPSHOT
      +    1.2.0
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index 8c5657755..dc2fd28f7 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0-SNAPSHOT
      +    1.2.0
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index 19db2bdf6..bab8227f0 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0-SNAPSHOT
      +    1.2.0
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index a5a34c38b..92c5614c1 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0-SNAPSHOT
      +    1.2.0
         
       
         prometheus-metrics-tracer-otel
      
      From f668a420306f1c62d0ee85fb36f60684361f5c93 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 17:10:19 +0100
      Subject: [PATCH 309/980] [maven-release-plugin] prepare for next development
       iteration
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-bom/pom.xml                                | 2 +-
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exporter-servlet-javax/pom.xml             | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-dropwizard5/pom.xml        | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 2 +-
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       41 files changed, 43 insertions(+), 43 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index 6ec3d3e7c..89181cfb9 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 6b719886b..1b20a0470 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index 44c5da96d..5baa99dd8 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index cf06a084c..9d10957fb 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index cab23d9b1..a48c660d2 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index 5db678446..25ed35b83 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index 61bff84e9..9d5162f0d 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 99035bb4b..bf6598e6f 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index ed9514562..fb86430ef 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index d2de5ee12..6566acff3 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index 40dc51a57..73453d437 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index aa7f467ff..c5ba5bff4 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index b08f7193e..e9fc2d60a 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index 93b40e6ae..0d49e17a5 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index b2724708f..a17fcb2c7 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index b97d8fcb9..016433ec2 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index 7619da2a7..def7ff0ca 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index 43c62b1c1..2d012f5dd 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.2.0
      +        HEAD
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 46b4788c5..7523ab9b6 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index 2a347ee09..38b18b61f 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.2.0
      +    1.3.0-SNAPSHOT
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.2.0
      +        HEAD
           
       
           
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index c5b39b16f..1b4439da5 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-bom
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index b01e1f1f9..ec8e44b56 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 411e7d434..283a00a0b 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index a882004f0..d8f89cef0 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index c8c54cabc..34908364e 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 6b21e6b0c..3b857aa6a 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index b7ff5abe5..63d05d998 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml
      index 7b327a5a2..41984e48b 100644
      --- a/prometheus-metrics-exporter-servlet-javax/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-servlet-javax
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 553c0ffe6..018d2ece3 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      index b7562eae3..92fc3de4c 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-instrumentation-dropwizard5
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index a7e67754f..2b0208e5a 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index d81352042..e6ac36c97 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index 95b567bb6..ded184f1a 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 75323e37e..e613da510 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index ab0aad2e1..cb0ca8ee7 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index 0119b57fb..ed4dd8921 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.0
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-simpleclient-bridge
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index 2a08bd8f1..5a547bfce 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.2.0
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index ab332a884..b44735d05 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index dc2fd28f7..3b9aa5e5e 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index bab8227f0..a5ed05f54 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index 92c5614c1..f10225ae1 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.0
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel
      
      From eb9a77f1dccdd025aeecc63c0b3a3e5f2398e18f Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 22 Mar 2024 18:26:23 +0100
      Subject: [PATCH 310/980] Exclude shaded dependencies from the build
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml                                           |  2 +-
       prometheus-metrics-bom/pom.xml                    | 14 +++++++-------
       prometheus-metrics-exporter-opentelemetry/pom.xml |  3 +--
       prometheus-metrics-exposition-formats/pom.xml     |  3 +--
       4 files changed, 10 insertions(+), 12 deletions(-)
      
      diff --git a/pom.xml b/pom.xml
      index 38b18b61f..057a36d2b 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -66,7 +66,7 @@
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
      -        prometheus-metrics-shaded-dependencies
      +        
               examples
               benchmarks
               integration-tests
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index 1b4439da5..16aa8e3c7 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -17,7 +17,7 @@
           
       
           
      -        1.1.0
      +        1.2.0
           
       
           
      @@ -118,20 +118,20 @@
                   
                       io.prometheus
                       prometheus-metrics-shaded-dependencies
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-protobuf
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-opentelemetry
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
               
           
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 3b857aa6a..2a78d8d4c 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -46,8 +46,7 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-opentelemetry
      -            ${project.version}
      -            
      +            1.2.0
               
       
               
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 018d2ece3..6ce225873 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -50,8 +50,7 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-protobuf
      -            ${project.version}
      -            
      +            1.2.0
               
       
               
      
      From 4b6e78fbff8e794cb141e02c46a4d1d36113db4b Mon Sep 17 00:00:00 2001
      From: Jonatan Ivanov 
      Date: Wed, 27 Mar 2024 21:36:46 -0700
      Subject: [PATCH 311/980] Add load(Map) overload to PrometheusPropertiesLoader
      
      Signed-off-by: Jonatan Ivanov 
      ---
       .../config/PrometheusPropertiesLoader.java    |  9 +++--
       .../PrometheusPropertiesLoaderTests.java      | 33 +++++++++++++++++++
       2 files changed, 40 insertions(+), 2 deletions(-)
       create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java
      
      diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      index c4a09be7b..1cde3a188 100644
      --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      @@ -25,7 +25,11 @@ public class PrometheusPropertiesLoader {
            * See {@link PrometheusProperties#get()}.
            */
           public static PrometheusProperties load() throws PrometheusPropertiesException {
      -        Map properties = loadProperties();
      +        return load(new Properties());
      +    }
      +
      +    public static PrometheusProperties load(Map externalProperties) throws PrometheusPropertiesException {
      +        Map properties = loadProperties(externalProperties);
               Map metricsConfigs = loadMetricsConfigs(properties);
               MetricsProperties defaultMetricsProperties = MetricsProperties.load("io.prometheus.metrics", properties);
               ExemplarsProperties exemplarConfig = ExemplarsProperties.load("io.prometheus.exemplars", properties);
      @@ -72,11 +76,12 @@ private static void validateAllPropertiesProcessed(Map propertie
               }
           }
       
      -    private static Map loadProperties() {
      +    private static Map loadProperties(Map externalProperties) {
               Map properties = new HashMap<>();
               properties.putAll(loadPropertiesFromClasspath());
               properties.putAll(loadPropertiesFromFile()); // overriding the entries from the classpath file
               properties.putAll(System.getProperties()); // overriding the entries from the properties file
      +        properties.putAll(externalProperties); // overriding all the entries above
               // TODO: Add environment variables like EXEMPLARS_ENABLED.
               return properties;
           }
      diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java
      new file mode 100644
      index 000000000..79c20702c
      --- /dev/null
      +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java
      @@ -0,0 +1,33 @@
      +package io.prometheus.metrics.config;
      +
      +import java.util.Properties;
      +
      +import org.junit.Assert;
      +import org.junit.Test;
      +
      +/**
      + * Tests for {@link PrometheusPropertiesLoader}.
      + */
      +public class PrometheusPropertiesLoaderTests {
      +
      +	@Test
      +	public void propertiesShouldBeLoadedFromPropertiesFile() {
      +		PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load();
      +		Assert.assertEquals(11, prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size());
      +		Assert.assertEquals(4, prometheusProperties.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size());
      +		Assert.assertTrue(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes());
      +	}
      +
      +	@Test
      +	public void externalPropertiesShouldOverridePropertiesFile() {
      +		Properties properties = new Properties();
      +		properties.setProperty("io.prometheus.metrics.histogramClassicUpperBounds", ".005, .01");
      +		properties.setProperty("io.prometheus.metrics.http_duration_seconds.histogramClassicUpperBounds", ".005, .01, .015");
      +		properties.setProperty("io.prometheus.exporter.exemplarsOnAllMetricTypes", "false");
      +
      +		PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(properties);
      +		Assert.assertEquals(2, prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size());
      +		Assert.assertEquals(3, prometheusProperties.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size());
      +		Assert.assertFalse(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes());
      +	}
      +}
      
      From 966360b2735fb975a7110699efd4cb62284dfc0b Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Wed, 3 Apr 2024 23:29:48 +0200
      Subject: [PATCH 312/980] Remove import for SpanContextSupplier
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../metrics/core/exemplars/ExemplarSampler.java     | 13 +++++++++----
       1 file changed, 9 insertions(+), 4 deletions(-)
      
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      index af898724d..7c46c244d 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      @@ -1,7 +1,6 @@
       package io.prometheus.metrics.core.exemplars;
       
       import io.prometheus.metrics.tracer.common.SpanContext;
      -import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import io.prometheus.metrics.model.snapshots.Exemplar;
       import io.prometheus.metrics.model.snapshots.Exemplars;
       import io.prometheus.metrics.model.snapshots.Labels;
      @@ -46,8 +45,11 @@ public ExemplarSampler(ExemplarSamplerConfig config) {
           /**
            * Constructor with an additional {code spanContext} argument.
            * This is useful for testing, but may also be useful in some production scenarios.
      -     * If {@code spanContext != null} that spanContext is used and {@link SpanContextSupplier} is not used.
      -     * If {@code spanContext == null} the {@link SpanContextSupplier#getSpanContext()} is called to find a span context.
      +     * If {@code spanContext != null} that spanContext is used and
      +     * {@link io.prometheus.metrics.tracer.initializer.SpanContextSupplier SpanContextSupplier} is not used.
      +     * If {@code spanContext == null}
      +     * {@link io.prometheus.metrics.tracer.initializer.SpanContextSupplier#getSpanContext() SpanContextSupplier.getSpanContext()}
      +     * is called to find a span context.
            */
           public ExemplarSampler(ExemplarSamplerConfig config, SpanContext spanContext) {
               this.config = config;
      @@ -319,7 +321,10 @@ private long updateExemplar(int index, double value, long now) {
           }
       
           private Labels doSampleExemplar() {
      -        SpanContext spanContext = this.spanContext != null ? this.spanContext : SpanContextSupplier.getSpanContext();
      +        // Using the qualified name so that Micrometer can exclude the dependency on prometheus-metrics-tracer-initializer
      +        // as they provide their own implementation of SpanContextSupplier.
      +        // If we had an import statement for SpanContextSupplier the dependency would be needed in any case.
      +        SpanContext spanContext = this.spanContext != null ? this.spanContext : io.prometheus.metrics.tracer.initializer.SpanContextSupplier.getSpanContext();
               try {
                   if (spanContext != null) {
                       if (spanContext.isCurrentSpanSampled()) {
      
      From c475384ef17032f5a83d83d1cad98daa7862c87d Mon Sep 17 00:00:00 2001
      From: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com>
      Date: Mon, 1 Apr 2024 16:36:33 +0900
      Subject: [PATCH 313/980] Fix link to JavaDocs
      
      The links in the table were swapped. This swaps them so the right method is linked.
      
      Signed-off-by: Tommy Ludwig <8924140+shakuzen@users.noreply.github.com>
      ---
       docs/content/config/config.md | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/docs/content/config/config.md b/docs/content/config/config.md
      index 43a396174..543ce26e4 100644
      --- a/docs/content/config/config.md
      +++ b/docs/content/config/config.md
      @@ -89,8 +89,8 @@ Exporter Properties
       
       | Name            | Javadoc | Note |
       | --------------- | --------|------|
      -| io.prometheus.exporter.includeCreatedTimestamps  | [ExporterProperties.getExemplarsOnAllMetricTypes()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getExemplarsOnAllMetricTypes()) | (1) |
      -| io.prometheus.exporter.exemplarsOnAllMetricTypes  | [ExporterProperties.getIncludeCreatedTimestamps()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getIncludeCreatedTimestamps()) | (1) |
      +| io.prometheus.exporter.includeCreatedTimestamps  | [ExporterProperties.getIncludeCreatedTimestamps()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getIncludeCreatedTimestamps()) | (1) |
      +| io.prometheus.exporter.exemplarsOnAllMetricTypes  | [ExporterProperties.getExemplarsOnAllMetricTypes()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getExemplarsOnAllMetricTypes()) | (1) |
       
       (1) Boolean value, `true` or `false`. Default see Javadoc.
       
      
      From 9ac45d509c82cae087a4dc46e0c8e5ab6b94f3b7 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Thu, 4 Apr 2024 22:43:39 +0200
      Subject: [PATCH 314/980] Temporarily add shaded dependencies to prepare for
       release
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml                                           |  2 +-
       prometheus-metrics-bom/pom.xml                    | 12 ++++++------
       prometheus-metrics-exporter-opentelemetry/pom.xml |  3 ++-
       prometheus-metrics-exposition-formats/pom.xml     |  3 ++-
       4 files changed, 11 insertions(+), 9 deletions(-)
      
      diff --git a/pom.xml b/pom.xml
      index 057a36d2b..38b18b61f 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -66,7 +66,7 @@
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
      -        
      +        prometheus-metrics-shaded-dependencies
               examples
               benchmarks
               integration-tests
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index 16aa8e3c7..fce579b40 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -118,20 +118,20 @@
                   
                       io.prometheus
                       prometheus-metrics-shaded-dependencies
      -                ${prometheus.metrics.shaded.dependencies.version}
      -                
      +                
      +                ${project.version}
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-protobuf
      -                ${prometheus.metrics.shaded.dependencies.version}
      -                
      +                
      +                ${project.version}
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-opentelemetry
      -                ${prometheus.metrics.shaded.dependencies.version}
      -                
      +                
      +                ${project.version}
                   
               
           
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 2a78d8d4c..a54f33dae 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -46,7 +46,8 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-opentelemetry
      -            1.2.0
      +            
      +            ${project.version}
               
       
               
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 6ce225873..7a0e5784b 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -50,7 +50,8 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-protobuf
      -            1.2.0
      +            
      +            ${project.version}
               
       
               
      
      From 092f90b4c97d20c2d77cd6264d2c2a18f7f5663b Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Thu, 4 Apr 2024 22:47:01 +0200
      Subject: [PATCH 315/980] [maven-release-plugin] prepare release v1.2.1
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-bom/pom.xml                                | 2 +-
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exporter-servlet-javax/pom.xml             | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-dropwizard5/pom.xml        | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 2 +-
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       41 files changed, 43 insertions(+), 43 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index 89181cfb9..153fe35bb 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 1b20a0470..4136bcd9d 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index 5baa99dd8..c0cdb2009 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index 9d10957fb..e4c76db5f 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index a48c660d2..4eff2570a 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index 25ed35b83..a7d749a7d 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index 9d5162f0d..791f29a96 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index bf6598e6f..65b9325f6 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index fb86430ef..459fe67f8 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index 6566acff3..e55f0ab3f 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index 73453d437..8644d8269 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index c5ba5bff4..9eac97c75 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index e9fc2d60a..8cd43c2a9 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index 0d49e17a5..e624ede8f 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index a17fcb2c7..07f1aea24 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index 016433ec2..00247b3de 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index def7ff0ca..3cdd94910 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index 2d012f5dd..a0292b604 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.2.1
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 7523ab9b6..79c644108 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index 38b18b61f..1556b6672 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.3.0-SNAPSHOT
      +    1.2.1
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        HEAD
      +        v1.2.1
           
       
           
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index fce579b40..887cfd13b 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-bom
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index ec8e44b56..a8aa1e40f 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 283a00a0b..2ecba82b8 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index d8f89cef0..5ac0bb795 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index 34908364e..32921708f 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index a54f33dae..db29f75bf 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index 63d05d998..9f1d8eaa8 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml
      index 41984e48b..be403ae96 100644
      --- a/prometheus-metrics-exporter-servlet-javax/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exporter-servlet-javax
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 7a0e5784b..ee7c7110e 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      index 92fc3de4c..5c96adbd3 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-instrumentation-dropwizard5
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index 2b0208e5a..8a7d818dc 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index e6ac36c97..b5feb8533 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index ded184f1a..7964f3e86 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index e613da510..b68c3afc7 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index cb0ca8ee7..8c51e8a24 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index ed4dd8921..c5fbb134b 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.3.0-SNAPSHOT
      +        1.2.1
           
       
           prometheus-metrics-simpleclient-bridge
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index 5a547bfce..0db442a5f 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.3.0-SNAPSHOT
      +    1.2.1
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index b44735d05..58416dd03 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.3.0-SNAPSHOT
      +    1.2.1
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index 3b9aa5e5e..5e9b1a103 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.3.0-SNAPSHOT
      +    1.2.1
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index a5ed05f54..9a644e27d 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.3.0-SNAPSHOT
      +    1.2.1
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index f10225ae1..b6b334be4 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.3.0-SNAPSHOT
      +    1.2.1
         
       
         prometheus-metrics-tracer-otel
      
      From 39d3600c68229a20e196851144a60eb123f3dc5b Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Thu, 4 Apr 2024 22:47:05 +0200
      Subject: [PATCH 316/980] [maven-release-plugin] prepare for next development
       iteration
      
      ---
       benchmarks/pom.xml                                            | 2 +-
       .../example-greeting-service/pom.xml                          | 2 +-
       .../example-hello-world-app/pom.xml                           | 2 +-
       examples/example-exemplars-tail-sampling/pom.xml              | 2 +-
       examples/example-exporter-httpserver/pom.xml                  | 2 +-
       examples/example-exporter-multi-target/pom.xml                | 2 +-
       examples/example-exporter-opentelemetry/pom.xml               | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml              | 2 +-
       examples/example-native-histogram/pom.xml                     | 2 +-
       examples/example-prometheus-properties/pom.xml                | 2 +-
       examples/example-simpleclient-bridge/pom.xml                  | 2 +-
       examples/pom.xml                                              | 2 +-
       integration-tests/it-common/pom.xml                           | 2 +-
       .../it-exporter/it-exporter-httpserver-sample/pom.xml         | 2 +-
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml      | 2 +-
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml     | 2 +-
       integration-tests/it-exporter/it-exporter-test/pom.xml        | 2 +-
       integration-tests/it-exporter/pom.xml                         | 4 ++--
       integration-tests/pom.xml                                     | 2 +-
       pom.xml                                                       | 4 ++--
       prometheus-metrics-bom/pom.xml                                | 2 +-
       prometheus-metrics-config/pom.xml                             | 2 +-
       prometheus-metrics-core/pom.xml                               | 2 +-
       prometheus-metrics-exporter-common/pom.xml                    | 2 +-
       prometheus-metrics-exporter-httpserver/pom.xml                | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       prometheus-metrics-exporter-servlet-jakarta/pom.xml           | 2 +-
       prometheus-metrics-exporter-servlet-javax/pom.xml             | 2 +-
       prometheus-metrics-exposition-formats/pom.xml                 | 2 +-
       prometheus-metrics-instrumentation-dropwizard5/pom.xml        | 2 +-
       prometheus-metrics-instrumentation-jvm/pom.xml                | 2 +-
       prometheus-metrics-model/pom.xml                              | 2 +-
       prometheus-metrics-shaded-dependencies/pom.xml                | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 2 +-
       .../prometheus-metrics-shaded-protobuf/pom.xml                | 2 +-
       prometheus-metrics-simpleclient-bridge/pom.xml                | 2 +-
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       .../prometheus-metrics-tracer-common/pom.xml                  | 2 +-
       .../prometheus-metrics-tracer-initializer/pom.xml             | 2 +-
       .../prometheus-metrics-tracer-otel-agent/pom.xml              | 2 +-
       .../prometheus-metrics-tracer-otel/pom.xml                    | 2 +-
       41 files changed, 43 insertions(+), 43 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index 153fe35bb..89181cfb9 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           benchmarks
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 4136bcd9d..1b20a0470 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-greeting-service
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index c0cdb2009..5baa99dd8 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               example-exemplars-tail-sampling
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-hello-world-app
      diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml
      index e4c76db5f..9d10957fb 100644
      --- a/examples/example-exemplars-tail-sampling/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-exemplars-tail-sampling
      diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml
      index 4eff2570a..a48c660d2 100644
      --- a/examples/example-exporter-httpserver/pom.xml
      +++ b/examples/example-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-httpserver
      diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml
      index a7d749a7d..25ed35b83 100644
      --- a/examples/example-exporter-multi-target/pom.xml
      +++ b/examples/example-exporter-multi-target/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-multi-target
      diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml
      index 791f29a96..9d5162f0d 100644
      --- a/examples/example-exporter-opentelemetry/pom.xml
      +++ b/examples/example-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-opentelemetry
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 65b9325f6..bf6598e6f 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-exporter-servlet-tomcat
      diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml
      index 459fe67f8..fb86430ef 100644
      --- a/examples/example-native-histogram/pom.xml
      +++ b/examples/example-native-histogram/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-native-histogram
      diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml
      index e55f0ab3f..6566acff3 100644
      --- a/examples/example-prometheus-properties/pom.xml
      +++ b/examples/example-prometheus-properties/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-prometheus-properties
      diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml
      index 8644d8269..73453d437 100644
      --- a/examples/example-simpleclient-bridge/pom.xml
      +++ b/examples/example-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               examples
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           example-simpleclient-bridge
      diff --git a/examples/pom.xml b/examples/pom.xml
      index 9eac97c75..c5ba5bff4 100644
      --- a/examples/pom.xml
      +++ b/examples/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           examples
      diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml
      index 8cd43c2a9..e9fc2d60a 100644
      --- a/integration-tests/it-common/pom.xml
      +++ b/integration-tests/it-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-common
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      index e624ede8f..0d49e17a5 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-httpserver-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 07f1aea24..a17fcb2c7 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-servlet-jetty-sample
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index 00247b3de..016433ec2 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-servlet-tomcat-sample
      diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml
      index 3cdd94910..def7ff0ca 100644
      --- a/integration-tests/it-exporter/it-exporter-test/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               it-exporter
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-exporter-test
      diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml
      index a0292b604..2d012f5dd 100644
      --- a/integration-tests/it-exporter/pom.xml
      +++ b/integration-tests/it-exporter/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               integration-tests
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           it-exporter
      @@ -29,7 +29,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.2.1
      +        HEAD
           
       
           
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 79c644108..7523ab9b6 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           integration-tests
      diff --git a/pom.xml b/pom.xml
      index 1556b6672..38b18b61f 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -5,7 +5,7 @@
       
           io.prometheus
           client_java
      -    1.2.1
      +    1.3.0-SNAPSHOT
       
           Prometheus Metrics Library
           http://github.com/prometheus/client_java
      @@ -30,7 +30,7 @@
               scm:git:git@github.com:prometheus/client_java.git
               scm:git:git@github.com:prometheus/client_java.git
               git@github.com:prometheus/client_java.git
      -        v1.2.1
      +        HEAD
           
       
           
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index 887cfd13b..fce579b40 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-bom
      diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml
      index a8aa1e40f..ec8e44b56 100644
      --- a/prometheus-metrics-config/pom.xml
      +++ b/prometheus-metrics-config/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-config
      diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml
      index 2ecba82b8..283a00a0b 100644
      --- a/prometheus-metrics-core/pom.xml
      +++ b/prometheus-metrics-core/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-core
      diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml
      index 5ac0bb795..d8f89cef0 100644
      --- a/prometheus-metrics-exporter-common/pom.xml
      +++ b/prometheus-metrics-exporter-common/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-common
      diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml
      index 32921708f..34908364e 100644
      --- a/prometheus-metrics-exporter-httpserver/pom.xml
      +++ b/prometheus-metrics-exporter-httpserver/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-httpserver
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index db29f75bf..a54f33dae 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-opentelemetry
      diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      index 9f1d8eaa8..63d05d998 100644
      --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-servlet-jakarta
      diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml
      index be403ae96..41984e48b 100644
      --- a/prometheus-metrics-exporter-servlet-javax/pom.xml
      +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exporter-servlet-javax
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index ee7c7110e..7a0e5784b 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-exposition-formats
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      index 5c96adbd3..92fc3de4c 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-instrumentation-dropwizard5
      diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml
      index 8a7d818dc..2b0208e5a 100644
      --- a/prometheus-metrics-instrumentation-jvm/pom.xml
      +++ b/prometheus-metrics-instrumentation-jvm/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-instrumentation-jvm
      diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml
      index b5feb8533..e6ac36c97 100644
      --- a/prometheus-metrics-model/pom.xml
      +++ b/prometheus-metrics-model/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-model
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      index 7964f3e86..ded184f1a 100644
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-dependencies
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index b68c3afc7..e613da510 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-opentelemetry
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      index 8c51e8a24..cb0ca8ee7 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               prometheus-metrics-shaded-dependencies
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-shaded-protobuf
      diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml
      index c5fbb134b..ed4dd8921 100644
      --- a/prometheus-metrics-simpleclient-bridge/pom.xml
      +++ b/prometheus-metrics-simpleclient-bridge/pom.xml
      @@ -5,7 +5,7 @@
           
               io.prometheus
               client_java
      -        1.2.1
      +        1.3.0-SNAPSHOT
           
       
           prometheus-metrics-simpleclient-bridge
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index 0db442a5f..5a547bfce 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           client_java
      -    1.2.1
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      index 58416dd03..b44735d05 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.1
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-common
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      index 5e9b1a103..3b9aa5e5e 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.1
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-initializer
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      index 9a644e27d..a5ed05f54 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.1
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel-agent
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      index b6b334be4..f10225ae1 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml
      @@ -5,7 +5,7 @@
         
           io.prometheus
           prometheus-metrics-tracer
      -    1.2.1
      +    1.3.0-SNAPSHOT
         
       
         prometheus-metrics-tracer-otel
      
      From 45a1e1adc0fa2b4c4df02d643ad24bb036af29d6 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Thu, 4 Apr 2024 23:20:24 +0200
      Subject: [PATCH 317/980] Exclude shaded dependencies from build
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       pom.xml                                           |  2 +-
       prometheus-metrics-bom/pom.xml                    | 14 +++++++-------
       prometheus-metrics-exporter-opentelemetry/pom.xml |  4 ++--
       prometheus-metrics-exposition-formats/pom.xml     |  4 ++--
       4 files changed, 12 insertions(+), 12 deletions(-)
      
      diff --git a/pom.xml b/pom.xml
      index 38b18b61f..057a36d2b 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -66,7 +66,7 @@
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
      -        prometheus-metrics-shaded-dependencies
      +        
               examples
               benchmarks
               integration-tests
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index fce579b40..d000aac2d 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -17,7 +17,7 @@
           
       
           
      -        1.2.0
      +        1.2.1
           
       
           
      @@ -118,20 +118,20 @@
                   
                       io.prometheus
                       prometheus-metrics-shaded-dependencies
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-protobuf
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
                   
                       io.prometheus
                       prometheus-metrics-shaded-opentelemetry
      -                
      -                ${project.version}
      +                ${prometheus.metrics.shaded.dependencies.version}
      +                
                   
               
           
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index a54f33dae..8d80bda14 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -46,8 +46,8 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-opentelemetry
      -            
      -            ${project.version}
      +            1.2.1
      +            
               
       
               
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 7a0e5784b..88e2b1955 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -50,8 +50,8 @@
               
                   io.prometheus
                   prometheus-metrics-shaded-protobuf
      -            
      -            ${project.version}
      +            1.2.1
      +            
               
       
               
      
      From 1c27e58a26cdf7cbe3751f02fcb9acab600fde64 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 5 Apr 2024 17:59:25 +0200
      Subject: [PATCH 318/980] Fix flaky test
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../bridge/SimpleclientCollectorTest.java        | 16 ++++++++++++----
       1 file changed, 12 insertions(+), 4 deletions(-)
      
      diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      index 8a5e2c018..2681ceed7 100644
      --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      @@ -52,7 +52,7 @@ public void testCounterComplete() throws IOException, InterruptedException {
           }
       
           @Test
      -    public void testCounterMinimal() throws IOException, InterruptedException {
      +    public void testCounterMinimal() throws IOException {
               Counter.build()
                       .name("events")
                       .help("total number of events")
      @@ -222,9 +222,17 @@ private String fixTimestamps(String s) {
               // Example of a "_created" timestamp in new format: 1694464002.939
               // The following regex translates the orig timestamp to the new timestamp
               return s
      -                .replaceAll( "1\\.([0-9]{9})([0-9]{3})E9", "1$1.$2") // Example: 1.694464002939E9
      -                .replaceAll( "1\\.([0-9]{9})([0-9]{2})E9", "1$1.$20") // Example: 1.69460725747E9
      -                .replaceAll( "1\\.([0-9]{9})([0-9])E9", "1$1.$200"); // Example: 1.6946072574E9
      +                .replaceAll("1\\.([0-9]{9})([0-9]{3})E9", "1$1.$2")   // Example: 1.694464002939E9
      +                .replaceAll("1\\.([0-9]{9})([0-9]{2})E9", "1$1.$20")  // Example: 1.69460725747E9
      +                .replaceAll("1\\.([0-9]{9})([0-9])E9", "1$1.$200") // Example: 1.6946072574E9
      +                .replaceAll("1\\.([0-9]{9})E9", "1$1.000")  // Example: 1.712332231E9
      +                .replaceAll("1\\.([0-9]{8})E9", "1$10.000") // Example: 1.71233242E9
      +                .replaceAll("1\\.([0-9]{7})E9", "1$100.000") // Example: 1.7123324E9
      +                .replaceAll("1\\.([0-9]{6})E9", "1$1000.000")
      +                .replaceAll("1\\.([0-9]{5})E9", "1$10000.000")
      +                .replaceAll("1\\.([0-9]{4})E9", "1$100000.000")
      +                .replaceAll("1\\.([0-9]{3})E9", "1$1000000.000")
      +                .replaceAll("1\\.([0-9]{2})E9", "1$10000000.000");
           }
       
           private String fixCounts(String s) {
      
      From 5ae9e247f3f71605b591b80a90e9cb0d8196c5c6 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 5 Apr 2024 23:00:27 +0200
      Subject: [PATCH 319/980] Explicit DuplicateLabelsException when creating
       MetricSnapshot
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../snapshots/DuplicateLabelsException.java   | 25 +++++++++++++++++++
       .../model/snapshots/MetricSnapshot.java       |  2 +-
       2 files changed, 26 insertions(+), 1 deletion(-)
       create mode 100644 prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java
      
      diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java
      new file mode 100644
      index 000000000..4588b344d
      --- /dev/null
      +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java
      @@ -0,0 +1,25 @@
      +package io.prometheus.metrics.model.snapshots;
      +
      +/**
      + * Thrown when a collector tries to create a {@link MetricSnapshot}
      + * where multiple data points have the same labels (same label names and label values).
      + */
      +public class DuplicateLabelsException extends IllegalArgumentException {
      +
      +    private final MetricMetadata metadata;
      +    private final Labels labels;
      +
      +    public DuplicateLabelsException(MetricMetadata metadata, Labels labels) {
      +        super("Duplicate labels for metric \"" + metadata.getName() + "\": " + labels);
      +        this.metadata = metadata;
      +        this.labels = labels;
      +    }
      +
      +    public MetricMetadata getMetadata() {
      +        return metadata;
      +    }
      +
      +    public Labels getLabels() {
      +        return labels;
      +    }
      +}
      \ No newline at end of file
      diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java
      index 273b304eb..2405b9622 100644
      --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java
      +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java
      @@ -43,7 +43,7 @@ protected void validateLabels() {
               // Verify that labels are unique (the same set of names/values must not be used multiple times for the same metric).
               for (int i = 0; i < dataPoints.size() - 1; i++) {
                   if (dataPoints.get(i).getLabels().equals(dataPoints.get(i + 1).getLabels())) {
      -                throw new IllegalArgumentException("Duplicate labels in metric data: " + dataPoints.get(i).getLabels());
      +                throw new DuplicateLabelsException(metadata, dataPoints.get(i).getLabels());
                   }
               }
               // Should we verify that all entries in data have the same label names?
      
      From 96e4d5a6f15af3bed7dc906f6f470c25463a2712 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Sun, 7 Apr 2024 22:58:53 +0200
      Subject: [PATCH 320/980] Fix flaky SlidingWindowTest
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../prometheus/metrics/core/metrics/SlidingWindow.java |  2 +-
       .../metrics/core/metrics/SlidingWindowTest.java        | 10 ++++++----
       2 files changed, 7 insertions(+), 5 deletions(-)
      
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      index 62164a48b..e4e86acdd 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      @@ -43,7 +43,7 @@ public SlidingWindow(Class clazz, Supplier constructor, ObjDoubleConsumer<
                   this.ringBuffer[i] = constructor.get();
               }
               this.currentBucket = 0;
      -        this.lastRotateTimestampMillis = System.currentTimeMillis();
      +        this.lastRotateTimestampMillis = currentTimeMillis.getAsLong();
               this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets;
           }
       
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      index 3b57220f8..3461d959e 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      @@ -10,9 +10,9 @@
       
       public class SlidingWindowTest {
       
      -    static class Observer {
      +    class Observer {
       
      -        List values = new ArrayList<>();
      +        final List values = new ArrayList<>();
       
               public void observe(double value) {
                   values.add(value);
      @@ -23,10 +23,11 @@ void assertValues(double... expectedValues) {
                   for (double expectedValue : expectedValues) {
                       expectedList.add(expectedValue);
                   }
      -            Assert.assertEquals(expectedList, values);
      +            Assert.assertEquals("Start time: " + startTime + ", current time: " + currentTimeMillis.get() + ", elapsed time: " + (currentTimeMillis.get() - startTime), expectedList, values);
               }
           }
       
      +    private long startTime;
           private final AtomicLong currentTimeMillis = new AtomicLong();
           private SlidingWindow ringBuffer;
           private final long maxAgeSeconds = 30;
      @@ -35,7 +36,8 @@ void assertValues(double... expectedValues) {
       
           @Before
           public void setUp() {
      -        currentTimeMillis.set(System.currentTimeMillis());
      +        startTime = System.currentTimeMillis();
      +        currentTimeMillis.set(startTime);
               ringBuffer = new SlidingWindow<>(Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets);
               ringBuffer.currentTimeMillis = currentTimeMillis::get;
           }
      
      From fca49ffc315641c239246ffbb516a36f374fb8dc Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Mon, 8 Apr 2024 12:04:01 +0200
      Subject: [PATCH 321/980] Fix flaky DropWizardExportsTest
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../dropwizard5/DropwizardExportsTest.java    | 67 +++++++++++++++----
       1 file changed, 55 insertions(+), 12 deletions(-)
      
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
      index ae27ce62c..6fbbb68b1 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java
      @@ -2,9 +2,11 @@
       
       import io.dropwizard.metrics5.*;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      -import io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExports;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      +import io.prometheus.metrics.model.snapshots.Quantiles;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      +import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       
      @@ -142,17 +144,58 @@ public void testHistogram() throws IOException {
                   i += 1;
               }
       
      -        String expected = "# TYPE hist summary\n" +
      -                "# HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)\n" +
      -                "hist{quantile=\"0.5\"} 49.0\n" +
      -                "hist{quantile=\"0.75\"} 74.0\n" +
      -                "hist{quantile=\"0.95\"} 94.0\n" +
      -                "hist{quantile=\"0.98\"} 97.0\n" +
      -                "hist{quantile=\"0.99\"} 98.0\n" +
      -                "hist{quantile=\"0.999\"} 99.0\n" +
      -                "hist_count 100\n" +
      -                "# EOF\n";
      -        assertEquals(expected, convertToOpenMetricsFormat(pmRegistry));
      +        // The result should look like this
      +        //
      +        // # TYPE hist summary
      +        // # HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)
      +        // hist{quantile="0.5"} 49.0
      +        // hist{quantile="0.75"} 74.0
      +        // hist{quantile="0.95"} 94.0
      +        // hist{quantile="0.98"} 97.0
      +        // hist{quantile="0.99"} 98.0
      +        // hist{quantile="0.999"} 99.0
      +        // hist_count 100
      +        // # EOF
      +        //
      +        // However, Dropwizard uses a random reservoir sampling algorithm, so the values could as well be off-by-one
      +        //
      +        // # TYPE hist summary
      +        // # HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)
      +        // hist{quantile="0.5"} 50.0
      +        // hist{quantile="0.75"} 75.0
      +        // hist{quantile="0.95"} 95.0
      +        // hist{quantile="0.98"} 98.0
      +        // hist{quantile="0.99"} 99.0
      +        // hist{quantile="0.999"} 99.0
      +        // hist_count 100
      +        // # EOF
      +        //
      +        // The following asserts the values, but allows an error of 1.0 for quantile values.
      +
      +        MetricSnapshots snapshots = pmRegistry.scrape(name -> name.equals("hist"));
      +        Assert.assertEquals(1, snapshots.size());
      +        SummarySnapshot snapshot = (SummarySnapshot) snapshots.get(0);
      +        Assert.assertEquals("hist", snapshot.getMetadata().getName());
      +        Assert.assertEquals("Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)", snapshot.getMetadata().getHelp());
      +        Assert.assertEquals(1, snapshot.getDataPoints().size());
      +        SummarySnapshot.SummaryDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0);
      +        Assert.assertTrue(dataPoint.hasCount());
      +        Assert.assertEquals(100, dataPoint.getCount());
      +        Assert.assertFalse(dataPoint.hasSum());
      +        Quantiles quantiles = dataPoint.getQuantiles();
      +        Assert.assertEquals(6, quantiles.size());
      +        Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0.0);
      +        Assert.assertEquals(49.0, quantiles.get(0).getValue(), 1.0);
      +        Assert.assertEquals(0.75, quantiles.get(1).getQuantile(), 0.0);
      +        Assert.assertEquals(74.0, quantiles.get(1).getValue(), 1.0);
      +        Assert.assertEquals(0.95, quantiles.get(2).getQuantile(), 0.0);
      +        Assert.assertEquals(94.0, quantiles.get(2).getValue(), 1.0);
      +        Assert.assertEquals(0.98, quantiles.get(3).getQuantile(), 0.0);
      +        Assert.assertEquals(97.0, quantiles.get(3).getValue(), 1.0);
      +        Assert.assertEquals(0.99, quantiles.get(4).getQuantile(), 0.0);
      +        Assert.assertEquals(98.0, quantiles.get(4).getValue(), 1.0);
      +        Assert.assertEquals(0.999, quantiles.get(5).getQuantile(), 0.0);
      +        Assert.assertEquals(99.0, quantiles.get(5).getValue(), 1.0);
           }
       
           @Test
      
      From fe02245d54f0f94d5054ca553215cb70b1687233 Mon Sep 17 00:00:00 2001
      From: Kinshuk Bairagi 
      Date: Wed, 10 Apr 2024 19:15:06 +0530
      Subject: [PATCH 322/980] instrumentation-dw5: Fix metric name issue with
       CustomLabelMapper (#949)
      
      * instrumentation-dw5: Fix issue with CustomLabelMapper
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Update CustomLabelMapperTest
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Refactor & Fix tests
      
      Signed-off-by: Kinshuk Bairagi 
      
      ---------
      
      Signed-off-by: Kinshuk Bairagi 
      ---
       .../dropwizard5/DropwizardExports.java        |  8 +--
       .../dropwizard5/labels/CustomLabelMapper.java | 22 +++++++
       .../labels/CustomLabelMapperTest.java         | 57 ++++++++++---------
       3 files changed, 56 insertions(+), 31 deletions(-)
      
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      index 9748504a4..ec2bfa2e4 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      @@ -26,7 +26,7 @@ public class DropwizardExports implements MultiCollector {
            *
            * @param registry a metric registry to export in prometheus.
            */
      -    DropwizardExports(MetricRegistry registry) {
      +    public DropwizardExports(MetricRegistry registry) {
               super();
               this.registry = registry;
               this.metricFilter = MetricFilter.ALL;
      @@ -61,9 +61,9 @@ private static String getHelpMessage(String metricName, Metric metric) {
                       metricName, metric.getClass().getName());
           }
       
      -
      -    private static MetricMetadata getMetricMetaData(String metricName, Metric metric) {
      -        return new MetricMetadata(PrometheusNaming.sanitizeMetricName(metricName), getHelpMessage(metricName, metric));
      +    private MetricMetadata getMetricMetaData(String metricName, Metric metric) {
      +        String name = labelMapper.isPresent() ? labelMapper.get().getName(metricName) : metricName;
      +        return new MetricMetadata(PrometheusNaming.sanitizeMetricName(name), getHelpMessage(metricName, metric));
           }
       
           /**
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      index 1739f6fa6..db5f6a64f 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java
      @@ -25,6 +25,28 @@ public CustomLabelMapper(final List mapperConfigs) {
               }
           }
       
      +    public String getName(final String dropwizardName){
      +        if (dropwizardName == null) {
      +            throw new IllegalArgumentException("Dropwizard metric name cannot be null");
      +        }
      +
      +        CompiledMapperConfig matchingConfig = null;
      +        for (CompiledMapperConfig config : this.compiledMapperConfigs) {
      +            if (config.pattern.matches(dropwizardName)) {
      +                matchingConfig = config;
      +                break;
      +            }
      +        }
      +
      +        if (matchingConfig != null) {
      +            final Map params = matchingConfig.pattern.extractParameters(dropwizardName);
      +            final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params);
      +            return nameAndLabels.name;
      +        }
      +
      +        return dropwizardName;
      +    }
      +
       
           public Labels getLabels(final String dropwizardName, final List additionalLabelNames, final List additionalLabelValues){
               if (dropwizardName == null) {
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
      index e6bbdbed8..d5003332c 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java
      @@ -2,8 +2,10 @@
       
       import io.dropwizard.metrics5.MetricFilter;
       import io.dropwizard.metrics5.MetricRegistry;
      +import io.prometheus.metrics.core.metrics.Counter;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
       import io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExports;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
       import org.junit.Before;
       import org.junit.Test;
      @@ -69,9 +71,9 @@ public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() {
       
               metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1);
       
      -        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      -                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService\"} 1.0\n" +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" +
                       "# EOF\n";
               assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
           }
      @@ -96,9 +98,9 @@ public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() {
               metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1);
       
       
      -        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      -                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService\"} 1.0\n" +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" +
                       "# EOF\n";
               assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
           }
      @@ -113,19 +115,26 @@ public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() {
                       "app.okhttpclient.client.HttpClient",
                       labels
               );
      +
      +        final MapperConfig mapperConfig2 = new MapperConfig(
      +                "app.okhttpclient.client.HttpClient.*.*",
      +                "app.okhttpclient.client.HttpClient2",
      +                labels
      +        );
      +
               final List mapperConfigs = Arrays.asList(
                       new MapperConfig("client-nope.*.*.*"),
                       mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +                mapperConfig2 // this matches as well
               );
       
               final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
               DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper);
               metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1);
       
      -        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 counter\n" +
      -                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400_total{service=\"greatService\",status=\"400\"} 1.0\n" +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_total{service=\"greatService\",status=\"400\"} 1.0\n" +
                       "# EOF\n";
               assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
       
      @@ -144,7 +153,7 @@ public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample
               final List mapperConfigs = Arrays.asList(
                       new MapperConfig("client-nope.*.*.*"),
                       mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +                new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well
               );
       
       
      @@ -154,9 +163,9 @@ public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample
               System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect()));
       
       
      -        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 counter\n" +
      -                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" +
                       "# EOF\n";
               assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
           }
      @@ -167,6 +176,7 @@ public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() {
               final Map labels = new LinkedHashMap();
               labels.put("service", "${0}");
               labels.put("status", "s_${1}");
      +        labels.put("client", "sampleClient");
               final MapperConfig mapperConfig = new MapperConfig(
                       "app.okhttpclient.client.HttpClient.*.*",
                       "app.okhttpclient.client.HttpClient.${0}",
      @@ -174,23 +184,16 @@ public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() {
               );
               final List mapperConfigs = Arrays.asList(
                       new MapperConfig("client-nope.*.*.*"),
      -                mapperConfig,
      -                new MapperConfig("app.okhttpclient.client.HttpClient.*.total") // this matches as well
      +                mapperConfig
               );
       
               final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs);
               DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry,MetricFilter.ALL,  labelMapper);
      -        metricRegistry.histogram("app.okhttpclient.client.HttpClient.greatService.400");
      -
      -        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService_400 summary\n" +
      -                "# HELP app_okhttpclient_client_HttpClient_greatService_400 Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Histogram)\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.5\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.75\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.95\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.98\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.99\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400{service=\"greatService\",status=\"s_400\",quantile=\"0.999\"} 0.0\n" +
      -                "app_okhttpclient_client_HttpClient_greatService_400_count{service=\"greatService\",status=\"s_400\"} 0\n" +
      +        metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1);
      +
      +        String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" +
      +                "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" +
      +                "app_okhttpclient_client_HttpClient_greatService_total{client=\"sampleClient\",service=\"greatService\",status=\"s_400\"} 1.0\n" +
                       "# EOF\n";
               assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect()));
           }
      
      From 4a6495af9c2f7db788ee09f56798958c1e7bc91c Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Wed, 10 Apr 2024 20:31:15 +0200
      Subject: [PATCH 323/980] Allow metric names with only a single character
       (#951)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../io/prometheus/metrics/model/snapshots/PrometheusNaming.java | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      index 58de0c814..34d8251e1 100644
      --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      @@ -13,7 +13,7 @@ public class PrometheusNaming {
           /**
            * Legal characters for metric names, including dot.
            */
      -    private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.:][a-zA-Z0-9_.:]+$");
      +    private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.:][a-zA-Z0-9_.:]*$");
       
           /**
            * Legal characters for label names, including dot.
      
      From 058b39959dff82ef5fcb126834d5c392cc64df37 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Fri, 12 Apr 2024 16:54:00 +0200
      Subject: [PATCH 324/980] Enable integration tests with ./mvnw verify (#952)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       integration-tests/pom.xml | 37 ++++++++++++++++++-------------------
       1 file changed, 18 insertions(+), 19 deletions(-)
      
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 7523ab9b6..9e064fa42 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -1,5 +1,6 @@
       
      -
      +
           4.0.0
       
           
      @@ -31,24 +32,22 @@
           
       
           
      -        
      -            
      -                
      -                    org.apache.maven.plugins
      -                    maven-failsafe-plugin
      -                    
      -                        
      -                            integration-test
      -                            integration-test
      -                            
      -                                integration-test
      -                                verify
      -                            
      -                        
      -                    
      -                
      -            
      -        
      +        
      +            
      +                org.apache.maven.plugins
      +                maven-failsafe-plugin
      +                
      +                    
      +                        integration-test
      +                        integration-test
      +                        
      +                            integration-test
      +                            verify
      +                        
      +                    
      +                
      +            
      +        
           
           
               
      
      From 13315ebcad0fa29f47ada0d03310ba153fdcd9dd Mon Sep 17 00:00:00 2001
      From: Matthias Berndt 
      Date: Tue, 7 May 2024 17:39:30 +0200
      Subject: [PATCH 325/980] Start HTTP server on the provided executor
      
      The metrics HTTP server should run on a daemon JVM
      thread so as to not keep the JVM running even
      though all relevant threads have already exited.
      Unfortunately, the OpenJDK builtin HTTP server
      likes to spawn its own HTTP Dispatcher thread on
      startup.
      https://github.com/openjdk/jdk/blob/02c95a6d7eb77ed17ae64d0f585197e87a67cc4a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java#L190
      This new thread inherits the daemon flag from the
      thread that started it, therefore we need to call
      the start method from the executor service,
      because those threads are daemon threads.
      
      Signed-off-by: Matthias Berndt 
      ---
       .../metrics/exporter/httpserver/HTTPServer.java        | 10 ++++++++--
       1 file changed, 8 insertions(+), 2 deletions(-)
      
      diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      index 81f8871e4..b97d71b5b 100644
      --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      @@ -6,7 +6,6 @@
       import com.sun.net.httpserver.HttpServer;
       import com.sun.net.httpserver.HttpsConfigurator;
       import com.sun.net.httpserver.HttpsServer;
      -import io.prometheus.metrics.config.ExporterHttpServerProperties;
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       
      @@ -14,6 +13,7 @@
       import java.io.IOException;
       import java.net.InetAddress;
       import java.net.InetSocketAddress;
      +import java.util.concurrent.ExecutionException;
       import java.util.concurrent.ExecutorService;
       import java.util.concurrent.RejectedExecutionHandler;
       import java.util.concurrent.SynchronousQueue;
      @@ -55,7 +55,13 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService,
               registerHandler("/", defaultHandler == null ? new DefaultHandler() : defaultHandler, authenticator);
               registerHandler("/metrics", new MetricsHandler(config, registry), authenticator);
               registerHandler("/-/healthy", new HealthyHandler(), authenticator);
      -        this.server.start();
      +        try {
      +            executorService.submit(() -> this.server.start()).get();
      +        } catch (InterruptedException e) {
      +            throw new RuntimeException(e);
      +        } catch (ExecutionException e) {
      +            throw new RuntimeException(e.getCause());
      +        }
           }
       
           private void registerHandler(String path, HttpHandler handler, Authenticator authenticator) {
      
      From a224960e7d9935456dd9860c6e5541825ce6e7b2 Mon Sep 17 00:00:00 2001
      From: Matthias Berndt 
      Date: Tue, 7 May 2024 18:05:23 +0200
      Subject: [PATCH 326/980] does this help to make the tests pass?
      
      Signed-off-by: Matthias Berndt 
      ---
       .../metrics/it/exporter/httpserver/HTTPServerSample.java         | 1 +
       1 file changed, 1 insertion(+)
      
      diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java
      index 9187ecfcb..ccd0b7724 100644
      --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java
      +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java
      @@ -65,6 +65,7 @@ public static void main(String[] args) throws IOException, InterruptedException
                       .buildAndStart();
       
               System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
      +        Thread.sleep(10_000);
           }
       
           private static int parsePortOrExit(String port) {
      
      From b3dd57c8104dc368dd2e166056c55ae761f966c5 Mon Sep 17 00:00:00 2001
      From: Matthias Berndt 
      Date: Wed, 8 May 2024 22:04:48 +0200
      Subject: [PATCH 327/980] change error handling
      
      Signed-off-by: Matthias Berndt 
      ---
       .../io/prometheus/metrics/exporter/httpserver/HTTPServer.java   | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      index b97d71b5b..1b23dfaf0 100644
      --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      @@ -60,7 +60,7 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService,
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               } catch (ExecutionException e) {
      -            throw new RuntimeException(e.getCause());
      +            throw new RuntimeException(e);
               }
           }
       
      
      From bc479bcea63f42f021b3b406cc06a41819278863 Mon Sep 17 00:00:00 2001
      From: Matthias Berndt 
      Date: Wed, 8 May 2024 23:18:27 +0200
      Subject: [PATCH 328/980] add comment
      
      Signed-off-by: Matthias Berndt 
      ---
       .../io/prometheus/metrics/exporter/httpserver/HTTPServer.java    | 1 +
       1 file changed, 1 insertion(+)
      
      diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      index 1b23dfaf0..eb5b5f39d 100644
      --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java
      @@ -57,6 +57,7 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService,
               registerHandler("/-/healthy", new HealthyHandler(), authenticator);
               try {
                   executorService.submit(() -> this.server.start()).get();
      +            // calling .get() on the Future here to avoid silently discarding errors
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               } catch (ExecutionException e) {
      
      From 6b97066ae90248dd9a907213a703db7f73c2dcac Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Tue, 14 May 2024 19:43:03 +0200
      Subject: [PATCH 329/980] Restore Pushgateway from archive
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../pom.xml                                                    | 0
       .../io/prometheus/metrics/exporter/pushgateway}/Base64.java    | 2 +-
       .../exporter/pushgateway}/BasicAuthHttpConnectionFactory.java  | 2 +-
       .../exporter/pushgateway}/DefaultHttpConnectionFactory.java    | 2 +-
       .../metrics/exporter/pushgateway}/HttpConnectionFactory.java   | 2 +-
       .../prometheus/metrics/exporter/pushgateway}/PushGateway.java  | 2 +-
       .../exporter/pushgateway}/BasicAuthPushGatewayTest.java        | 2 +-
       .../metrics/exporter/pushgateway}/ExamplePushGateway.java      | 2 +-
       .../metrics/exporter/pushgateway}/PushGatewayTest.java         | 3 ++-
       .../version-rules.xml                                          | 0
       10 files changed, 9 insertions(+), 8 deletions(-)
       rename {simpleclient-archive/simpleclient_pushgateway => prometheus-metrics-exporter-pushgateway}/pom.xml (100%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway}/Base64.java (96%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway}/BasicAuthHttpConnectionFactory.java (96%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway}/DefaultHttpConnectionFactory.java (86%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway}/HttpConnectionFactory.java (76%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway}/PushGateway.java (99%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway}/BasicAuthPushGatewayTest.java (96%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway}/ExamplePushGateway.java (91%)
       rename {simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter => prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway}/PushGatewayTest.java (99%)
       rename {simpleclient-archive/simpleclient_pushgateway => prometheus-metrics-exporter-pushgateway}/version-rules.xml (100%)
      
      diff --git a/simpleclient-archive/simpleclient_pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml
      similarity index 100%
      rename from simpleclient-archive/simpleclient_pushgateway/pom.xml
      rename to prometheus-metrics-exporter-pushgateway/pom.xml
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
      similarity index 96%
      rename from simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java
      rename to prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
      index 9191f8142..2043bb36f 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/Base64.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import javax.xml.bind.DatatypeConverter;
       
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
      similarity index 96%
      rename from simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java
      rename to prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
      index ead505b1f..8d36b8f11 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/BasicAuthHttpConnectionFactory.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import java.io.IOException;
       import java.io.UnsupportedEncodingException;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      similarity index 86%
      rename from simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java
      rename to prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      index 2987dfafe..44d47de98 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/DefaultHttpConnectionFactory.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import java.io.IOException;
       import java.net.HttpURLConnection;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java
      similarity index 76%
      rename from simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java
      rename to prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java
      index 0b4521afa..94556fa28 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/HttpConnectionFactory.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import java.io.IOException;
       import java.net.HttpURLConnection;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java
      similarity index 99%
      rename from simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java
      rename to prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java
      index 1ab56b6a6..0e00cc19e 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/main/java/io/prometheus/client/exporter/PushGateway.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import java.io.BufferedWriter;
       import java.io.ByteArrayOutputStream;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java
      similarity index 96%
      rename from simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java
      rename to prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java
      index 1d5bfd774..2fca7d9a4 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/BasicAuthPushGatewayTest.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       
       import static org.mockserver.model.HttpRequest.request;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java
      similarity index 91%
      rename from simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java
      rename to prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java
      index 917539445..9b9196b7a 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/ExamplePushGateway.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       import io.prometheus.client.Gauge;
       import io.prometheus.client.CollectorRegistry;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java
      similarity index 99%
      rename from simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
      rename to prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java
      index ced492b8c..c1ac4b797 100644
      --- a/simpleclient-archive/simpleclient_pushgateway/src/test/java/io/prometheus/client/exporter/PushGatewayTest.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java
      @@ -1,4 +1,4 @@
      -package io.prometheus.client.exporter;
      +package io.prometheus.metrics.exporter.pushgateway;
       
       
       import static org.junit.rules.ExpectedException.none;
      @@ -10,6 +10,7 @@
       import java.io.IOException;
       import java.util.TreeMap;
       import java.util.Map;
      +
       import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Rule;
      diff --git a/simpleclient-archive/simpleclient_pushgateway/version-rules.xml b/prometheus-metrics-exporter-pushgateway/version-rules.xml
      similarity index 100%
      rename from simpleclient-archive/simpleclient_pushgateway/version-rules.xml
      rename to prometheus-metrics-exporter-pushgateway/version-rules.xml
      
      From 608592e2bf2fe124c476e804153b3c04317a0919 Mon Sep 17 00:00:00 2001
      From: =?UTF-8?q?Fabian=20St=C3=A4ber?= 
      Date: Tue, 14 May 2024 19:47:49 +0200
      Subject: [PATCH 330/980] Port Pushgateway to client_java 1.x
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Signed-off-by: Fabian Stäber 
      ---
       .../prometheus/client/it/common/Volume.java   |   2 +-
       integration-tests/it-pushgateway/pom.xml      |  98 +++
       .../it/pushgateway/PushGatewayTestApp.java    | 131 ++++
       .../metrics/it/pushgateway/PushGatewayIT.java | 228 ++++++
       .../test/resources/prometheus-basicauth.yaml  |  11 +
       .../src/test/resources/prometheus-ssl.yaml    |  11 +
       .../src/test/resources/prometheus.yaml        |   8 +
       .../test/resources/pushgateway-basicauth.yaml |   4 +
       .../src/test/resources/pushgateway-ssl.yaml   |  86 +++
       .../it-pushgateway/version-rules.xml          |   6 +
       integration-tests/pom.xml                     |   1 +
       pom.xml                                       |   1 +
       .../config/ExporterPushgatewayProperties.java |  59 ++
       .../metrics/config/PrometheusProperties.java  |   7 +
       .../config/PrometheusPropertiesLoader.java    |   3 +-
       .../pom.xml                                   |  29 +-
       .../metrics/exporter/pushgateway/Base64.java  |  48 --
       .../BasicAuthHttpConnectionFactory.java       |  36 -
       .../DefaultHttpConnectionFactory.java         |  10 +-
       .../pushgateway/DefaultJobLabelDetector.java  |  60 ++
       .../metrics/exporter/pushgateway/Format.java  |   6 +
       .../pushgateway/HttpConnectionFactory.java    |   7 +-
       .../exporter/pushgateway/PushGateway.java     | 663 +++++++++++-------
       .../metrics/exporter/pushgateway/Scheme.java  |  29 +
       .../pushgateway/BasicAuthPushGatewayTest.java |  71 +-
       .../pushgateway/ExamplePushGateway.java       |  20 -
       .../exporter/pushgateway/PushGatewayTest.java | 514 ++++++++------
       27 files changed, 1516 insertions(+), 633 deletions(-)
       create mode 100644 integration-tests/it-pushgateway/pom.xml
       create mode 100644 integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
       create mode 100644 integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
       create mode 100644 integration-tests/it-pushgateway/src/test/resources/prometheus-basicauth.yaml
       create mode 100644 integration-tests/it-pushgateway/src/test/resources/prometheus-ssl.yaml
       create mode 100644 integration-tests/it-pushgateway/src/test/resources/prometheus.yaml
       create mode 100644 integration-tests/it-pushgateway/src/test/resources/pushgateway-basicauth.yaml
       create mode 100644 integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml
       create mode 100644 integration-tests/it-pushgateway/version-rules.xml
       create mode 100644 prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java
       delete mode 100644 prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
       delete mode 100644 prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
       create mode 100644 prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java
       create mode 100644 prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java
       create mode 100644 prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java
       delete mode 100644 prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java
      
      diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
      index 6c32ba74b..dc9a32992 100644
      --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
      +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
      @@ -30,7 +30,7 @@ public static Volume create(String prefix) throws IOException, URISyntaxExceptio
       
           /**
            * Copy a file or directory to this volume.
      -     * @param src is reltive to {@code ./target/}
      +     * @param src is relative to {@code ./target/}
            */
           public Volume copy(String src) throws IOException {
               Path srcPath = tmpDir.getParent().resolve(src);
      diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml
      new file mode 100644
      index 000000000..d8b81a303
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/pom.xml
      @@ -0,0 +1,98 @@
      +
      +
      +    4.0.0
      +
      +    
      +        io.prometheus
      +        integration-tests
      +        1.3.0-SNAPSHOT
      +    
      +
      +    it-pushgateway
      +
      +    Integration Test - Pushgateway
      +    http://github.com/prometheus/client_java
      +    
      +        Integration tests for the Pushgateway Exporter
      +    
      +
      +    
      +        
      +            The Apache Software License, Version 2.0
      +            http://www.apache.org/licenses/LICENSE-2.0.txt
      +            repo
      +        
      +    
      +
      +    
      +        
      +            fstab
      +            Fabian Stäber
      +            fabian@fstab.de
      +        
      +    
      +
      +    
      +        
      +            io.prometheus
      +            prometheus-metrics-core
      +            ${project.version}
      +        
      +        
      +            io.prometheus
      +            prometheus-metrics-exporter-pushgateway
      +            ${project.version}
      +        
      +        
      +            org.testcontainers
      +            testcontainers
      +            test
      +        
      +        
      +            io.prometheus
      +            it-common
      +            test-jar
      +            ${project.version}
      +            test
      +        
      +        
      +            com.squareup.okhttp
      +            okhttp
      +            2.7.5
      +            test
      +        
      +        
      +            com.jayway.jsonpath
      +            json-path
      +            2.8.0
      +            test
      +        
      +    
      +
      +    
      +        pushgateway-test-app
      +        
      +            
      +                org.apache.maven.plugins
      +                maven-shade-plugin
      +                
      +                    
      +                        package
      +                        
      +                            shade
      +                        
      +                        
      +                            
      +                                
      +                                    io.prometheus.metrics.it.pushgateway.PushGatewayTestApp
      +                                
      +                            
      +                        
      +                    
      +                
      +            
      +        
      +    
      +
      diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
      new file mode 100644
      index 000000000..279f05d90
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
      @@ -0,0 +1,131 @@
      +package io.prometheus.metrics.it.pushgateway;
      +
      +import io.prometheus.metrics.core.metrics.Gauge;
      +import io.prometheus.metrics.core.metrics.Histogram;
      +import io.prometheus.metrics.exporter.pushgateway.Format;
      +import io.prometheus.metrics.exporter.pushgateway.HttpConnectionFactory;
      +import io.prometheus.metrics.exporter.pushgateway.PushGateway;
      +import io.prometheus.metrics.model.snapshots.Unit;
      +
      +import javax.net.ssl.HttpsURLConnection;
      +import javax.net.ssl.SSLContext;
      +import javax.net.ssl.TrustManager;
      +import javax.net.ssl.X509TrustManager;
      +import java.io.IOException;
      +import java.security.KeyManagementException;
      +import java.security.NoSuchAlgorithmException;
      +import java.security.cert.X509Certificate;
      +
      +import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS;
      +
      +/**
      + * Example application using the {@link PushGateway}.
      + */
      +public class PushGatewayTestApp {
      +
      +    public static void main(String[] args) throws IOException {
      +        if (args.length != 1) {
      +            System.err.println("Usage: java -jar pushgateway-test-app.jar ");
      +            System.exit(-1);
      +        }
      +        switch (args[0]) {
      +            case "simple":
      +                runSimpleTest();
      +                break;
      +            case "textFormat":
      +                runTextFormatTest();
      +                break;
      +            case "basicauth":
      +                runBasicAuthTest();
      +                break;
      +            case "ssl":
      +                runSslTest();
      +                break;
      +            default:
      +                System.err.println(args[0] + ": Not implemented.");
      +                System.exit(-1);
      +        }
      +    }
      +
      +    private static void runSimpleTest() throws IOException {
      +        makeMetrics();
      +        PushGateway pg = PushGateway.builder().build();
      +        System.out.println("Pushing metrics...");
      +        pg.push();
      +        System.out.println("Push successful.");
      +    }
      +
      +    private static void runTextFormatTest() throws IOException {
      +        makeMetrics();
      +        PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build();
      +        System.out.println("Pushing metrics...");
      +        pg.push();
      +        System.out.println("Push successful.");
      +    }
      +
      +    private static void runBasicAuthTest() throws IOException {
      +        makeMetrics();
      +        PushGateway pg = PushGateway.builder()
      +                .basicAuth("my_user", "secret_password")
      +                .build();
      +        System.out.println("Pushing metrics...");
      +        pg.push();
      +        System.out.println("Push successful.");
      +    }
      +
      +    private static void runSslTest() throws IOException {
      +        makeMetrics();
      +        PushGateway pg = PushGateway.builder()
      +                .scheme(HTTPS)
      +                .connectionFactory(insecureConnectionFactory)
      +                .build();
      +        System.out.println("Pushing metrics...");
      +        pg.push();
      +        System.out.println("Push successful.");
      +    }
      +
      +    static TrustManager insecureTrustManager = new X509TrustManager() {
      +        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
      +            return null;
      +        }
      +
      +        @Override
      +        public void checkClientTrusted(X509Certificate[] chain, String authType) {
      +        }
      +
      +        @Override
      +        public void checkServerTrusted(X509Certificate[] chain, String authType) {
      +        }
      +    };
      +
      +    static HttpConnectionFactory insecureConnectionFactory = url -> {
      +        try {
      +            SSLContext sslContext = SSLContext.getInstance("TLS");
      +            sslContext.init(null, new TrustManager[]{insecureTrustManager}, null);
      +            SSLContext.setDefault(sslContext);
      +
      +            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
      +            connection.setHostnameVerifier((hostname, session) -> true);
      +            return connection;
      +        } catch (NoSuchAlgorithmException | KeyManagementException e) {
      +            throw new RuntimeException(e);
      +        }
      +    };
      +
      +    private static void makeMetrics() {
      +        Histogram sizes = Histogram.builder()
      +                .name("file_sizes_bytes")
      +                .classicUpperBounds(256, 512, 1024, 2048)
      +                .unit(Unit.BYTES)
      +                .register();
      +        sizes.observe(513);
      +        sizes.observe(814);
      +        sizes.observe(1553);
      +        Gauge duration = Gauge.builder()
      +                .name("my_batch_job_duration_seconds")
      +                .help("Duration of my batch job in seconds.")
      +                .unit(Unit.SECONDS)
      +                .register();
      +        duration.set(0.5);
      +    }
      +}
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
      new file mode 100644
      index 000000000..6b89a8c58
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
      @@ -0,0 +1,228 @@
      +package io.prometheus.metrics.it.pushgateway;
      +
      +import com.jayway.jsonpath.Criteria;
      +import com.jayway.jsonpath.Filter;
      +import com.jayway.jsonpath.JsonPath;
      +import com.squareup.okhttp.*;
      +import io.prometheus.client.it.common.LogConsumer;
      +import io.prometheus.client.it.common.Volume;
      +import net.minidev.json.JSONArray;
      +import org.junit.After;
      +import org.junit.Assert;
      +import org.junit.Before;
      +import org.junit.Test;
      +import org.testcontainers.containers.BindMode;
      +import org.testcontainers.containers.GenericContainer;
      +import org.testcontainers.containers.Network;
      +import org.testcontainers.containers.wait.strategy.Wait;
      +import org.testcontainers.utility.MountableFile;
      +
      +import java.io.IOException;
      +import java.net.URISyntaxException;
      +import java.util.concurrent.TimeUnit;
      +
      +public class PushGatewayIT {
      +
      +    private GenericContainer sampleAppContainer;
      +    private GenericContainer pushGatewayContainer;
      +    private GenericContainer prometheusContainer;
      +    private Volume sampleAppVolume;
      +
      +    @Before
      +    public void setUp() throws IOException, URISyntaxException {
      +        Network network = Network.newNetwork();
      +        sampleAppVolume = Volume.create("it-pushgateway")
      +                .copy("pushgateway-test-app.jar");
      +        pushGatewayContainer = new GenericContainer<>("prom/pushgateway:v1.8.0")
      +                .withExposedPorts(9091)
      +                .withNetwork(network)
      +                .withNetworkAliases("pushgateway")
      +                .withLogConsumer(LogConsumer.withPrefix("pushgateway"))
      +                .waitingFor(Wait.forListeningPort());
      +        sampleAppContainer = new GenericContainer<>("openjdk:17")
      +                .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY)
      +                .withNetwork(network)
      +                .withWorkingDirectory("/app")
      +                .dependsOn(pushGatewayContainer)
      +                .withLogConsumer(LogConsumer.withPrefix("test-app"));
      +        prometheusContainer = new GenericContainer<>("prom/prometheus:v2.51.2")
      +                .withNetwork(network)
      +                .dependsOn(pushGatewayContainer)
      +                .withExposedPorts(9090)
      +                .withLogConsumer(LogConsumer.withPrefix("prometheus"));
      +    }
      +
      +    @After
      +    public void tearDown() throws IOException {
      +        prometheusContainer.stop();
      +        pushGatewayContainer.stop();
      +        sampleAppContainer.stop();
      +        sampleAppVolume.remove();
      +    }
      +
      +    final OkHttpClient client = new OkHttpClient();
      +
      +    @Test
      +    public void testSimple() throws IOException, InterruptedException {
      +        pushGatewayContainer
      +                .start();
      +        sampleAppContainer
      +                .withCommand("java",
      +                        "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
      +                        "-jar",
      +                        "/app/pushgateway-test-app.jar",
      +                        "simple"
      +                ).start();
      +        prometheusContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
      +                .start();
      +        awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
      +        assertMetrics();
      +    }
      +
      +    @Test
      +    public void testTextFormat() throws IOException, InterruptedException {
      +        pushGatewayContainer
      +                .start();
      +        sampleAppContainer
      +                .withCommand("java",
      +                        "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
      +                        "-jar",
      +                        "/app/pushgateway-test-app.jar",
      +                        "textFormat"
      +                ).start();
      +        prometheusContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
      +                .start();
      +        awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
      +        assertMetrics();
      +    }
      +
      +    @Test
      +    public void testBasicAuth() throws IOException, InterruptedException {
      +        pushGatewayContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-basicauth.yaml"), "/pushgateway/pushgateway-basicauth.yaml")
      +                .withCommand("--web.config.file", "pushgateway-basicauth.yaml")
      +                .start();
      +        sampleAppContainer
      +                .withCommand("java",
      +                        "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
      +                        "-jar",
      +                        "/app/pushgateway-test-app.jar",
      +                        "basicauth"
      +                ).start();
      +        prometheusContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-basicauth.yaml"), "/etc/prometheus/prometheus.yml")
      +                .start();
      +        awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
      +        assertMetrics();
      +    }
      +
      +    @Test
      +    public void testSsl() throws InterruptedException, IOException {
      +        pushGatewayContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-ssl.yaml"), "/pushgateway/pushgateway-ssl.yaml")
      +                .withCommand("--web.config.file", "pushgateway-ssl.yaml")
      +                .start();
      +        sampleAppContainer
      +                .withCommand("java",
      +                        "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
      +                        "-jar",
      +                        "/app/pushgateway-test-app.jar",
      +                        "ssl"
      +                ).start();
      +        prometheusContainer
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-ssl.yaml"), "/etc/prometheus/prometheus.yml")
      +                .start();
      +        awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
      +        assertMetrics();
      +    }
      +
      +    @Test
      +    public void testProtobuf() throws IOException, InterruptedException {
      +        pushGatewayContainer
      +                .start();
      +        sampleAppContainer
      +                .withCommand("java",
      +                        "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
      +                        "-jar",
      +                        "/app/pushgateway-test-app.jar",
      +                        "simple"
      +                ).start();
      +        prometheusContainer
      +                .withCommand("--enable-feature=native-histograms", "--config.file", "/etc/prometheus/prometheus.yml")
      +                .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
      +                .start();
      +        awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
      +        assertNativeHistogram();
      +    }
      +
      +    private void assertMetrics() throws IOException, InterruptedException {
      +        double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app");
      +        Assert.assertEquals(0.5, value, 0.0);
      +        value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512");
      +        Assert.assertEquals(0.0, value, 0.0);
      +        value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024");
      +        Assert.assertEquals(2.0, value, 0.0);
      +        value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf");
      +        Assert.assertEquals(3.0, value, 0.0);
      +    }
      +
      +    private double getValue(String name, String... labels) throws IOException, InterruptedException {
      +        String scrapeResponseJson = scrape(name);
      +        Criteria criteria = Criteria.where("metric.__name__").eq(name);
      +        for (int i = 0; i < labels.length; i += 2) {
      +            criteria = criteria.and("metric." + labels[i]).eq(labels[i + 1]);
      +        }
      +        JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]");
      +        Assert.assertEquals(1, result.size());
      +        return Double.valueOf(result.get(0).toString());
      +    }
      +
      +    private void assertNativeHistogram() throws IOException, InterruptedException {
      +        double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app");
      +        Assert.assertEquals(3, count, 0.0);
      +    }
      +
      +    private double getNativeHistogramCount(String name, String job) throws IOException, InterruptedException {
      +        String scrapeResponseJson = scrape("histogram_count(" + name + ")");
      +        Criteria criteria = Criteria.where("metric.job").eq(job);
      +        JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]");
      +        return Double.valueOf(result.get(0).toString());
      +    }
      +
      +    private String scrape(String query) throws IOException, InterruptedException {
      +        System.out.println("Querying http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090));
      +        HttpUrl baseUrl = HttpUrl.parse("http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090) + "/api/v1/query");
      +        HttpUrl url = baseUrl.newBuilder()
      +                .addQueryParameter("query", query)
      +                .build();
      +        long timeRemaining = TimeUnit.SECONDS.toMillis(15);
      +        while (timeRemaining > 0) {
      +            Request request = new Request.Builder().url(url).build();
      +            Call call = client.newCall(request);
      +            Response response = call.execute();
      +            String body = response.body().string();
      +            if (!body.contains("\"result\":[]")) {
      +                // Result when data is not available yet:
      +                // {"status":"success","data":{"resultType":"vector","result":[]}}
      +                return body;
      +            }
      +            Thread.sleep(250);
      +            timeRemaining -= 250;
      +        }
      +        Assert.fail("timeout while scraping " + url);
      +        return null;
      +    }
      +
      +    private void awaitTermination(GenericContainer container, long timeout, TimeUnit unit) throws InterruptedException {
      +        long waitTimeMillis = 0;
      +        while (container.isRunning()) {
      +            if (waitTimeMillis > unit.toMillis(timeout)) {
      +                Assert.fail(container.getContainerName() + " did not terminate after " + timeout + " " + unit + ".");
      +            }
      +            Thread.sleep(20);
      +            waitTimeMillis += 20;
      +        }
      +    }
      +}
      diff --git a/integration-tests/it-pushgateway/src/test/resources/prometheus-basicauth.yaml b/integration-tests/it-pushgateway/src/test/resources/prometheus-basicauth.yaml
      new file mode 100644
      index 000000000..6f035f9d7
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/resources/prometheus-basicauth.yaml
      @@ -0,0 +1,11 @@
      +global:
      +  scrape_interval: 5s
      +
      +scrape_configs:
      +  - job_name: "push"
      +    honor_labels: true
      +    static_configs:
      +      - targets: ["pushgateway:9091"]
      +    basic_auth:
      +      username: 'my_user'
      +      password: 'secret_password'
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/src/test/resources/prometheus-ssl.yaml b/integration-tests/it-pushgateway/src/test/resources/prometheus-ssl.yaml
      new file mode 100644
      index 000000000..a40bae9b1
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/resources/prometheus-ssl.yaml
      @@ -0,0 +1,11 @@
      +global:
      +  scrape_interval: 5s
      +
      +scrape_configs:
      +  - job_name: "push"
      +    honor_labels: true
      +    scheme: https
      +    static_configs:
      +      - targets: ["pushgateway:9091"]
      +    tls_config:
      +      insecure_skip_verify: true
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/src/test/resources/prometheus.yaml b/integration-tests/it-pushgateway/src/test/resources/prometheus.yaml
      new file mode 100644
      index 000000000..c5ccb68a4
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/resources/prometheus.yaml
      @@ -0,0 +1,8 @@
      +global:
      +  scrape_interval: 5s
      +
      +scrape_configs:
      +  - job_name: "push"
      +    honor_labels: true
      +    static_configs:
      +      - targets: ["pushgateway:9091"]
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/src/test/resources/pushgateway-basicauth.yaml b/integration-tests/it-pushgateway/src/test/resources/pushgateway-basicauth.yaml
      new file mode 100644
      index 000000000..90b470796
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/resources/pushgateway-basicauth.yaml
      @@ -0,0 +1,4 @@
      +basic_auth_users:
      +    # Note: The bcrypt hash of the password was generated with the following command line:
      +    # python -c 'import bcrypt; print(bcrypt.hashpw(b"secret_password", bcrypt.gensalt(rounds=10)).decode("ascii"))'
      +    my_user: $2b$10$kmIxr/4wpcORDXnKLvTMC.WPGqT8nqjBm8AI3MqGkzcSrWJioTfUG
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml b/integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml
      new file mode 100644
      index 000000000..3e4208bbb
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml
      @@ -0,0 +1,86 @@
      +tls_server_config:
      +  # cert and key have been generated with the following command:
      +  # openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 36500 -nodes -subj "/CN=localhost"
      +  cert: |
      +    -----BEGIN CERTIFICATE-----
      +    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
      +    -----END CERTIFICATE-----
      +  key: |
      +    -----BEGIN PRIVATE KEY-----
      +    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
      +    v8yTmHG7BmzLiznu3uPyiEfAPQ3KQ9E=
      +    -----END PRIVATE KEY-----
      \ No newline at end of file
      diff --git a/integration-tests/it-pushgateway/version-rules.xml b/integration-tests/it-pushgateway/version-rules.xml
      new file mode 100644
      index 000000000..76f8da4fd
      --- /dev/null
      +++ b/integration-tests/it-pushgateway/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      \ No newline at end of file
      diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
      index 9e064fa42..9bac492fb 100644
      --- a/integration-tests/pom.xml
      +++ b/integration-tests/pom.xml
      @@ -29,6 +29,7 @@
           
               it-common
               it-exporter
      +        it-pushgateway
           
       
           
      diff --git a/pom.xml b/pom.xml
      index 057a36d2b..b79891eb9 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -63,6 +63,7 @@
               prometheus-metrics-exporter-servlet-javax
               prometheus-metrics-exporter-httpserver
               prometheus-metrics-exporter-opentelemetry
      +        prometheus-metrics-exporter-pushgateway
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
               prometheus-metrics-simpleclient-bridge
      diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java
      new file mode 100644
      index 000000000..f38a7f4af
      --- /dev/null
      +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java
      @@ -0,0 +1,59 @@
      +package io.prometheus.metrics.config;
      +
      +import java.util.Map;
      +
      +public class ExporterPushgatewayProperties {
      +
      +    private static final String ADDRESS = "address";
      +    private static final String JOB = "job";
      +    private static final String SCHEME = "scheme";
      +    private final String scheme;
      +    private final String address;
      +    private final String job;
      +
      +    private ExporterPushgatewayProperties(String address, String job, String scheme) {
      +        this.address = address;
      +        this.job = job;
      +        this.scheme = scheme;
      +    }
      +
      +    /**
      +     * Address of the Pushgateway in the form {@code host:port}.
      +     * Default is {@code localhost:9091}
      +     */
      +    public String getAddress() {
      +        return address;
      +    }
      +
      +    /**
      +     * {@code job} label for metrics being pushed.
      +     * Default is the name of the JAR file that is running.
      +     */
      +    public String getJob() {
      +        return job;
      +    }
      +
      +    /**
      +     * Scheme to be used when pushing metrics to the pushgateway.
      +     * Must be "http" or "https". Default is "http".
      +     */
      +    public String getScheme() {
      +        return scheme;
      +    }
      +
      +    /**
      +     * Note that this will remove entries from {@code properties}.
      +     * This is because we want to know if there are unused properties remaining after all properties have been loaded.
      +     */
      +    static ExporterPushgatewayProperties load(String prefix, Map properties) throws PrometheusPropertiesException {
      +        String address = Util.loadString(prefix + "." + ADDRESS, properties);
      +        String job = Util.loadString(prefix + "." + JOB, properties);
      +        String scheme = Util.loadString(prefix + "." +  SCHEME, properties);
      +        if (scheme != null) {
      +            if (!scheme.equals("http") && !scheme.equals("https")) {
      +                throw new PrometheusPropertiesException(prefix + "." + SCHEME + "=" + scheme + ": Illegal value. Expecting 'http' or 'https'.");
      +            }
      +        }
      +        return new ExporterPushgatewayProperties(address, job, scheme);
      +    }
      +}
      diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java
      index 4707dd862..2e26a4c7b 100644
      --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java
      +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java
      @@ -19,6 +19,7 @@ public class PrometheusProperties {
           private final ExporterFilterProperties exporterFilterProperties;
           private final ExporterHttpServerProperties exporterHttpServerProperties;
           private final ExporterOpenTelemetryProperties exporterOpenTelemetryProperties;
      +    private final ExporterPushgatewayProperties exporterPushgatewayProperties;
       
           /**
            * Get the properties instance. When called for the first time, {@code get()} loads the properties from the following locations:
      @@ -39,6 +40,7 @@ public PrometheusProperties(
                   ExporterProperties exporterProperties,
                   ExporterFilterProperties exporterFilterProperties,
                   ExporterHttpServerProperties httpServerConfig,
      +            ExporterPushgatewayProperties pushgatewayProperties,
                   ExporterOpenTelemetryProperties otelConfig) {
               this.defaultMetricsProperties = defaultMetricsProperties;
               this.metricProperties.putAll(metricProperties);
      @@ -46,6 +48,7 @@ public PrometheusProperties(
               this.exporterProperties = exporterProperties;
               this.exporterFilterProperties = exporterFilterProperties;
               this.exporterHttpServerProperties = httpServerConfig;
      +        this.exporterPushgatewayProperties = pushgatewayProperties;
               this.exporterOpenTelemetryProperties = otelConfig;
           }
       
      @@ -80,6 +83,10 @@ public ExporterHttpServerProperties getExporterHttpServerProperties() {
               return exporterHttpServerProperties;
           }
       
      +    public ExporterPushgatewayProperties getExporterPushgatewayProperties() {
      +        return exporterPushgatewayProperties;
      +    }
      +
           public ExporterOpenTelemetryProperties getExporterOpenTelemetryProperties() {
               return exporterOpenTelemetryProperties;
           }
      diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      index 1cde3a188..bb9b3c2cb 100644
      --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java
      @@ -36,9 +36,10 @@ public static PrometheusProperties load(Map externalProperties)
               ExporterProperties exporterProperties = ExporterProperties.load("io.prometheus.exporter", properties);
               ExporterFilterProperties exporterFilterProperties = ExporterFilterProperties.load("io.prometheus.exporter.filter", properties);
               ExporterHttpServerProperties exporterHttpServerProperties = ExporterHttpServerProperties.load("io.prometheus.exporter.httpServer", properties);
      +        ExporterPushgatewayProperties exporterPushgatewayProperties = ExporterPushgatewayProperties.load("io.prometheus.exporter.pushgateway", properties);
               ExporterOpenTelemetryProperties exporterOpenTelemetryProperties = ExporterOpenTelemetryProperties.load("io.prometheus.exporter.opentelemetry", properties);
               validateAllPropertiesProcessed(properties);
      -        return new PrometheusProperties(defaultMetricsProperties, metricsConfigs, exemplarConfig, exporterProperties, exporterFilterProperties, exporterHttpServerProperties, exporterOpenTelemetryProperties);
      +        return new PrometheusProperties(defaultMetricsProperties, metricsConfigs, exemplarConfig, exporterProperties, exporterFilterProperties, exporterHttpServerProperties, exporterPushgatewayProperties, exporterOpenTelemetryProperties);
           }
       
           // This will remove entries from properties when they are processed.
      diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml
      index 7553c7d29..47dbadf74 100644
      --- a/prometheus-metrics-exporter-pushgateway/pom.xml
      +++ b/prometheus-metrics-exporter-pushgateway/pom.xml
      @@ -5,15 +5,15 @@
           
               io.prometheus
               client_java
      -        1.0.0-beta-2-SNAPSHOT
      +        1.3.0-SNAPSHOT
           
       
      -    simpleclient_pushgateway
      +    prometheus-metrics-exporter-pushgateway
           bundle
       
      -    Prometheus Java Simpleclient Pushgateway
      +    Prometheus Metrics Exporter - Pushgateway
           
      -        Pushgateway exporter for the simpleclient.
      +        Exporter for pushing metrics to a pushgateway.
           
       
           
      @@ -25,10 +25,15 @@
           
       
           
      -        
      +       
                   brian-brazil
                   Brian Brazil
                   brian.brazil@boxever.com
      +       
      +       
      +            fstab
      +            Fabian Stäber
      +            fabian@fstab.de
               
           
       
      @@ -36,12 +41,7 @@
           
               
                   io.prometheus
      -            simpleclient
      -            ${project.version}
      -        
      -        
      -            io.prometheus
      -            simpleclient_common
      +            prometheus-metrics-exporter-common
                   ${project.version}
               
               
      @@ -50,7 +50,6 @@
                   2.4.0-b180830.0359
                   provided
               
      -        
               
                   junit
                   junit
      @@ -69,5 +68,11 @@
                   5.13.2
                   test
               
      +        
      +            io.prometheus
      +            prometheus-metrics-core
      +            ${project.version}
      +            test
      +        
           
       
      diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
      deleted file mode 100644
      index 2043bb36f..000000000
      --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Base64.java
      +++ /dev/null
      @@ -1,48 +0,0 @@
      -package io.prometheus.metrics.exporter.pushgateway;
      -
      -import javax.xml.bind.DatatypeConverter;
      -
      -/**
      - * This class delegates to either javax.xml.bind.DatatypeConverter (for Java < 8) or java.util.Base64 (Java 8+)
      - * to perform Base64 encoding of a String.
      - *
      - * This code requires Java 8+ for compilation.
      - */
      -public class Base64 {
      -
      -    private static final boolean HAS_JAVA_UTIL_BASE64 = hasJavaUtilBase64();
      -
      -    private static boolean hasJavaUtilBase64() {
      -        try {
      -            Class.forName("java.util.Base64");
      -            // Java 8+
      -            return true;
      -        } catch (Throwable t) {
      -            // Java < 8
      -            return false;
      -        }
      -    }
      -
      -    private Base64() {}
      -
      -    /**
      -     * Encodes a byte[] to a String using Base64.
      -     *
      -     * Passing a null argument will cause a NullPointerException to be thrown.
      -     *
      -     * @param src string to be encoded
      -     * @return String in Base64 encoding
      -     */
      -    @SuppressWarnings("all")
      -    public static String encodeToString(byte[] src) {
      -        if (src == null) {
      -            throw new NullPointerException();
      -        }
      -
      -        if (HAS_JAVA_UTIL_BASE64) {
      -            return java.util.Base64.getEncoder().encodeToString(src);
      -        } else {
      -            return DatatypeConverter.printBase64Binary(src);
      -        }
      -    }
      -}
      diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
      deleted file mode 100644
      index 8d36b8f11..000000000
      --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthHttpConnectionFactory.java
      +++ /dev/null
      @@ -1,36 +0,0 @@
      -package io.prometheus.metrics.exporter.pushgateway;
      -
      -import java.io.IOException;
      -import java.io.UnsupportedEncodingException;
      -import java.net.HttpURLConnection;
      -
      -public class BasicAuthHttpConnectionFactory implements HttpConnectionFactory {
      -    private final HttpConnectionFactory originConnectionFactory;
      -    private final String basicAuthHeader;
      -
      -    public BasicAuthHttpConnectionFactory(HttpConnectionFactory connectionFactory, String user, String password) {
      -        this.originConnectionFactory = connectionFactory;
      -        this.basicAuthHeader = encode(user, password);
      -    }
      -
      -    public BasicAuthHttpConnectionFactory(String user, String password) {
      -        this(new DefaultHttpConnectionFactory(), user, password);
      -    }
      -
      -    @Override
      -    public HttpURLConnection create(String url) throws IOException {
      -        HttpURLConnection connection = originConnectionFactory.create(url);
      -        connection.setRequestProperty("Authorization", basicAuthHeader);
      -        return connection;
      -    }
      -
      -    private String encode(String user, String password) {
      -        try {
      -            byte[] credentialsBytes = (user + ":" + password).getBytes("UTF-8");
      -            String encoded = Base64.encodeToString(credentialsBytes);
      -            return String.format("Basic %s", encoded);
      -        } catch (UnsupportedEncodingException e) {
      -            throw new IllegalArgumentException(e);
      -        }
      -    }
      -}
      diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      index 44d47de98..f3223cb53 100644
      --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java
      @@ -4,9 +4,15 @@
       import java.net.HttpURLConnection;
       import java.net.URL;
       
      +/**
      + * This can be used for creating {@link Scheme#HTTP} and {@link Scheme#HTTPS} connections.
      + * 

      + * However, if you want to use it with {@link Scheme#HTTPS} you must make sure that the keychain for verifying the server certificate is set up correctly. + * For an example of how to skip certificate verification see {@code PushGatewayTestApp} in {@code integration-tests/it-pushgateway/}. + */ public class DefaultHttpConnectionFactory implements HttpConnectionFactory { @Override - public HttpURLConnection create(String url) throws IOException { - return (HttpURLConnection) new URL(url).openConnection(); + public HttpURLConnection create(URL url) throws IOException { + return (HttpURLConnection) url.openConnection(); } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java new file mode 100644 index 000000000..8d9afb71e --- /dev/null +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java @@ -0,0 +1,60 @@ +package io.prometheus.metrics.exporter.pushgateway; + +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * The default {@code job} label is the name of the JAR file being executed. + *

      + * This is copy-and-paste from {@code ResourceAttributesFromJarFileName} + * in the {@code prometheus-metrics-exporter-opentelemetry} module. + */ +class DefaultJobLabelDetector { + + static String getDefaultJobLabel() { + Path jarPath = getJarPathFromSunCommandLine(); + if (jarPath == null) { + return "unknown_job"; + } + return getServiceName(jarPath); + } + + private static String getServiceName(Path jarPath) { + String jarName = jarPath.getFileName().toString(); + int dotIndex = jarName.lastIndexOf("."); + return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); + } + + private static Path getJarPathFromSunCommandLine() { + String programArguments = System.getProperty("sun.java.command"); + if (programArguments == null) { + return null; + } + // Take the path until the first space. If the path doesn't exist extend it up to the next + // space. Repeat until a path that exists is found or input runs out. + int next = 0; + while (true) { + int nextSpace = programArguments.indexOf(' ', next); + if (nextSpace == -1) { + return pathIfExists(programArguments); + } + Path path = pathIfExists(programArguments.substring(0, nextSpace)); + next = nextSpace + 1; + if (path != null) { + return path; + } + } + } + + private static Path pathIfExists(String programArguments) { + Path candidate; + try { + candidate = Paths.get(programArguments); + } catch (InvalidPathException e) { + return null; + } + return Files.isRegularFile(candidate) ? candidate : null; + } +} diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java new file mode 100644 index 000000000..90204cff9 --- /dev/null +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java @@ -0,0 +1,6 @@ +package io.prometheus.metrics.exporter.pushgateway; + +public enum Format { + PROMETHEUS_PROTOBUF, + PROMETHEUS_TEXT +} diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java index 94556fa28..c583b144e 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java @@ -2,7 +2,12 @@ import java.io.IOException; import java.net.HttpURLConnection; +import java.net.URL; +/** + * See {@link DefaultHttpConnectionFactory}. + */ +@FunctionalInterface public interface HttpConnectionFactory { - HttpURLConnection create(String url) throws IOException; + HttpURLConnection create(URL url) throws IOException; } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index 0e00cc19e..a2d587675 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -1,300 +1,425 @@ package io.prometheus.metrics.exporter.pushgateway; -import java.io.BufferedWriter; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URL; -import java.net.URLEncoder; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; - -import io.prometheus.client.Collector; -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.exporter.common.TextFormat; +import io.prometheus.metrics.config.ExporterPushgatewayProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.config.PrometheusPropertiesException; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.registry.MultiCollector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; + +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; +import java.util.*; + +import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTP; /** - * Export metrics via the Prometheus Pushgateway. + * Export metrics via the Prometheus Pushgateway *

      * The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. * Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics - * to a Pushgateway. This class allows pushing the contents of a {@link CollectorRegistry} to - * a Pushgateway. + * to a Pushgateway. This Java class allows pushing the contents of a {@link PrometheusRegistry} to a Pushgateway. *

      * Example usage: *

        * {@code
      - *   void executeBatchJob() throws Exception {
      - *     CollectorRegistry registry = new CollectorRegistry();
      - *     Gauge duration = Gauge.build()
      - *         .name("my_batch_job_duration_seconds").help("Duration of my batch job in seconds.").register(registry);
      - *     Gauge.Timer durationTimer = duration.startTimer();
      + * void executeBatchJob() throws Exception {
      + *     PrometheusRegistry registry = new PrometheusRegistry();
      + *     Gauge duration = Gauge.builder()
      + *             .name("my_batch_job_duration_seconds")
      + *             .help("Duration of my batch job in seconds.")
      + *             .register(registry);
      + *     Timer durationTimer = duration.startTimer();
        *     try {
      - *       // Your code here.
      + *         // Your code here.
        *
      - *       // This is only added to the registry after success,
      - *       // so that a previous success in the Pushgateway isn't overwritten on failure.
      - *       Gauge lastSuccess = Gauge.build()
      - *           .name("my_batch_job_last_success").help("Last time my batch job succeeded, in unixtime.").register(registry);
      - *       lastSuccess.setToCurrentTime();
      + *         // This is only added to the registry after success,
      + *         // so that a previous success in the Pushgateway isn't overwritten on failure.
      + *         Gauge lastSuccess = Gauge.builder()
      + *                 .name("my_batch_job_last_success")
      + *                 .help("Last time my batch job succeeded, in unixtime.")
      + *                 .register(registry);
      + *         lastSuccess.set(System.currentTimeMillis());
        *     } finally {
      - *       durationTimer.setDuration();
      - *       PushGateway pg = new PushGateway("127.0.0.1:9091");
      - *       pg.pushAdd(registry, "my_batch_job");
      + *         durationTimer.observeDuration();
      + *         PushGateway pg = PushGateway.builder()
      + *                 .address("127.0.0.1:9091")
      + *                 .job("my_batch_job")
      + *                 .registry(registry)
      + *                 .build();
      + *         pg.pushAdd();
        *     }
      - *   }
      + * }
        * }
        * 
      *

      - * See https://github.com/prometheus/pushgateway + * See https://github.com/prometheus/pushgateway. */ public class PushGateway { - private static final int MILLISECONDS_PER_SECOND = 1000; - - // Visible for testing. - protected final String gatewayBaseURL; - - private HttpConnectionFactory connectionFactory = new DefaultHttpConnectionFactory(); - - /** - * Construct a Pushgateway, with the given address. - *

      - * @param address host:port or ip:port of the Pushgateway. - */ - public PushGateway(String address) { - this(createURLSneakily("http://" + address)); - } - - /** - * Construct a Pushgateway, with the given URL. - *

      - * @param serverBaseURL the base URL and optional context path of the Pushgateway server. - */ - public PushGateway(URL serverBaseURL) { - this.gatewayBaseURL = URI.create(serverBaseURL.toString() + "/metrics/") - .normalize() - .toString(); - } - - public void setConnectionFactory(HttpConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - /** - * Creates a URL instance from a String representation of a URL without throwing a checked exception. - * Required because you can't wrap a call to another constructor in a try statement. - * - * @param urlString the String representation of the URL. - * @return The URL instance. - */ - private static URL createURLSneakily(final String urlString) { - try { - return new URL(urlString); - } catch (MalformedURLException e) { - throw new RuntimeException(e); + private static final int MILLISECONDS_PER_SECOND = 1000; + + private final URL url; + private final Format format; + private final Map requestHeaders; + private final PrometheusRegistry registry; + private final HttpConnectionFactory connectionFactory; + + private PushGateway(PrometheusRegistry registry, Format format, URL url, HttpConnectionFactory connectionFactory, Map requestHeaders) { + this.registry = registry; + this.format = format; + this.url = url; + this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders)); + this.connectionFactory = connectionFactory; } - } - - /** - * Pushes all metrics in a registry, replacing all those with the same job and no grouping key. - *

      - * This uses the PUT HTTP method. - */ - public void push(CollectorRegistry registry, String job) throws IOException { - doRequest(registry, job, null, "PUT"); - } - - /** - * Pushes all metrics in a Collector, replacing all those with the same job and no grouping key. - *

      - * This is useful for pushing a single Gauge. - *

      - * This uses the PUT HTTP method. - */ - public void push(Collector collector, String job) throws IOException { - CollectorRegistry registry = new CollectorRegistry(); - collector.register(registry); - push(registry, job); - } - - /** - * Pushes all metrics in a registry, replacing all those with the same job and grouping key. - *

      - * This uses the PUT HTTP method. - */ - public void push(CollectorRegistry registry, String job, Map groupingKey) throws IOException { - doRequest(registry, job, groupingKey, "PUT"); - } - - /** - * Pushes all metrics in a Collector, replacing all those with the same job and grouping key. - *

      - * This is useful for pushing a single Gauge. - *

      - * This uses the PUT HTTP method. - */ - public void push(Collector collector, String job, Map groupingKey) throws IOException { - CollectorRegistry registry = new CollectorRegistry(); - collector.register(registry); - push(registry, job, groupingKey); - } - - /** - * Pushes all metrics in a registry, replacing only previously pushed metrics of the same name and job and no grouping key. - *

      - * This uses the POST HTTP method. - */ - public void pushAdd(CollectorRegistry registry, String job) throws IOException { - doRequest(registry, job, null, "POST"); - } - - /** - * Pushes all metrics in a Collector, replacing only previously pushed metrics of the same name and job and no grouping key. - *

      - * This is useful for pushing a single Gauge. - *

      - * This uses the POST HTTP method. - */ - public void pushAdd(Collector collector, String job) throws IOException { - CollectorRegistry registry = new CollectorRegistry(); - collector.register(registry); - pushAdd(registry, job); - } - - /** - * Pushes all metrics in a registry, replacing only previously pushed metrics of the same name, job and grouping key. - *

      - * This uses the POST HTTP method. - */ - public void pushAdd(CollectorRegistry registry, String job, Map groupingKey) throws IOException { - doRequest(registry, job, groupingKey, "POST"); - } - - /** - * Pushes all metrics in a Collector, replacing only previously pushed metrics of the same name, job and grouping key. - *

      - * This is useful for pushing a single Gauge. - *

      - * This uses the POST HTTP method. - */ - public void pushAdd(Collector collector, String job, Map groupingKey) throws IOException { - CollectorRegistry registry = new CollectorRegistry(); - collector.register(registry); - pushAdd(registry, job, groupingKey); - } - - - /** - * Deletes metrics from the Pushgateway. - *

      - * Deletes metrics with no grouping key and the provided job. - * This uses the DELETE HTTP method. - */ - public void delete(String job) throws IOException { - doRequest(null, job, null, "DELETE"); - } - - /** - * Deletes metrics from the Pushgateway. - *

      - * Deletes metrics with the provided job and grouping key. - * This uses the DELETE HTTP method. - */ - public void delete(String job, Map groupingKey) throws IOException { - doRequest(null, job, groupingKey, "DELETE"); - } - - void doRequest(CollectorRegistry registry, String job, Map groupingKey, String method) throws IOException { - String url = gatewayBaseURL; - if (job.contains("/")) { - url += "job@base64/" + base64url(job); - } else { - url += "job/" + URLEncoder.encode(job, "UTF-8"); + + /** + * Push all metrics. All metrics with the same job and grouping key are replaced. + *

      + * This uses the PUT HTTP method. + */ + public void push() throws IOException { + doRequest(registry, "PUT"); } - if (groupingKey != null) { - for (Map.Entry entry: groupingKey.entrySet()) { - if (entry.getValue().isEmpty()) { - url += "/" + entry.getKey() + "@base64/="; - } else if (entry.getValue().contains("/")) { - url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue()); - } else { - url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8"); - } - } + /** + * Push a single metric. All metrics with the same job and grouping key are replaced. + *

      + * This is useful for pushing a single Gauge. + *

      + * This uses the PUT HTTP method. + */ + public void push(Collector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "PUT"); + } + + /** + * Push a single collector. All metrics with the same job and grouping key are replaced. + *

      + * This uses the PUT HTTP method. + */ + public void push(MultiCollector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "PUT"); + } + + /** + * Like {@link #push()}, but only metrics with the same name as the newly pushed metrics are replaced. + *

      + * This uses the POST HTTP method. + */ + public void pushAdd() throws IOException { + doRequest(registry, "POST"); + } + + /** + * Like {@link #push(Collector)}, but only the specified metric will be replaced. + *

      + * This uses the POST HTTP method. + */ + public void pushAdd(Collector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "POST"); + } + + /** + * Like {@link #push(MultiCollector)}, but only the metrics from the collector will be replaced. + *

      + * This uses the POST HTTP method. + */ + public void pushAdd(MultiCollector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "POST"); + } + + /** + * Deletes metrics from the Pushgateway. + *

      + * This uses the DELETE HTTP method. + */ + public void delete() throws IOException { + doRequest(null, "DELETE"); } - HttpURLConnection connection = connectionFactory.create(url); - connection.setRequestProperty("Content-Type", TextFormat.CONTENT_TYPE_004); - if (!method.equals("DELETE")) { - connection.setDoOutput(true); + + private void doRequest(PrometheusRegistry registry, String method) throws IOException { + try { + HttpURLConnection connection = connectionFactory.create(url); + requestHeaders.forEach(connection::setRequestProperty); + if (format == Format.PROMETHEUS_TEXT) { + connection.setRequestProperty("Content-Type", PrometheusTextFormatWriter.CONTENT_TYPE); + } else { + connection.setRequestProperty("Content-Type", PrometheusProtobufWriter.CONTENT_TYPE); + } + if (!method.equals("DELETE")) { + connection.setDoOutput(true); + } + connection.setRequestMethod(method); + + connection.setConnectTimeout(10 * MILLISECONDS_PER_SECOND); + connection.setReadTimeout(10 * MILLISECONDS_PER_SECOND); + connection.connect(); + + try { + if (!method.equals("DELETE")) { + OutputStream outputStream = connection.getOutputStream(); + if (format == Format.PROMETHEUS_TEXT) { + new PrometheusTextFormatWriter(false).write(outputStream, registry.scrape()); + } else { + new PrometheusProtobufWriter().write(outputStream, registry.scrape()); + } + outputStream.flush(); + outputStream.close(); + } + + int response = connection.getResponseCode(); + if (response / 100 != 2) { + String errorMessage; + InputStream errorStream = connection.getErrorStream(); + if (errorStream != null) { + String errBody = readFromStream(errorStream); + errorMessage = "Response code from " + url + " was " + response + ", response body: " + errBody; + } else { + errorMessage = "Response code from " + url + " was " + response; + } + throw new IOException(errorMessage); + } + + } finally { + connection.disconnect(); + } + } catch (IOException e) { + String baseUrl = url.getProtocol() + "://" + url.getHost(); + if (url.getPort() != -1) { + baseUrl += ":" + url.getPort(); + } + throw new IOException("Failed to push metrics to the Prometheus Pushgateway on " + baseUrl + ": " + e.getMessage(), e); + } } - connection.setRequestMethod(method); - - connection.setConnectTimeout(10 * MILLISECONDS_PER_SECOND); - connection.setReadTimeout(10 * MILLISECONDS_PER_SECOND); - connection.connect(); - - try { - if (!method.equals("DELETE")) { - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8")); - TextFormat.write004(writer, registry.metricFamilySamples()); - writer.flush(); - writer.close(); - } - - int response = connection.getResponseCode(); - if (response/100 != 2) { - String errorMessage; - InputStream errorStream = connection.getErrorStream(); - if(errorStream != null) { - String errBody = readFromStream(errorStream); - errorMessage = "Response code from " + url + " was " + response + ", response body: " + errBody; - } else { - errorMessage = "Response code from " + url + " was " + response; + + private static String readFromStream(InputStream is) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) != -1) { + result.write(buffer, 0, length); } - throw new IOException(errorMessage); - } - } finally { - connection.disconnect(); + return result.toString("UTF-8"); } - } - - private static String base64url(String v) { - // Per RFC4648 table 2. We support Java 6, and java.util.Base64 was only added in Java 8, - try { - return Base64.encodeToString(v.getBytes("UTF-8")).replace("+", "-").replace("/", "_"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); // Unreachable. + + public static Builder builder() { + return builder(PrometheusProperties.get()); + } + + /** + * The {@link PrometheusProperties} will be used to override what is set in the {@link Builder}. + */ + public static Builder builder(PrometheusProperties config) { + return new Builder(config); } - } - - /** - * Returns a grouping key with the instance label set to the machine's IP address. - *

      - * This is a convenience function, and should only be used where you want to - * push per-instance metrics rather than cluster/job level metrics. - */ - public static Map instanceIPGroupingKey() throws UnknownHostException { - Map groupingKey = new HashMap(); - groupingKey.put("instance", InetAddress.getLocalHost().getHostAddress()); - return groupingKey; - } - - private static String readFromStream(InputStream is) throws IOException { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) != -1) { - result.write(buffer, 0, length); + + public static class Builder { + + private final PrometheusProperties config; + private Format format; + private String address; + private Scheme scheme; + private String job; + private final Map requestHeaders = new HashMap<>(); + private PrometheusRegistry registry = PrometheusRegistry.defaultRegistry; + private HttpConnectionFactory connectionFactory = new DefaultHttpConnectionFactory(); + private Map groupingKey = new TreeMap<>(); + + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Default is {@link Format#PROMETHEUS_PROTOBUF}. + */ + public Builder format(Format format) { + if (format == null) { + throw new NullPointerException(); + } + this.format = format; + return this; + } + + /** + * Address of the Pushgateway in format {@code host:port}. + * Default is {@code localhost:9091}. + * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.address} property. + */ + public Builder address(String address) { + if (address == null) { + throw new NullPointerException(); + } + this.address = address; + return this; + } + + /** + * Username and password for HTTP basic auth when pushing to the Pushgateway. + */ + public Builder basicAuth(String user, String password) { + if (user == null || password == null) { + throw new NullPointerException(); + } + byte[] credentialsBytes = (user + ":" + password).getBytes(StandardCharsets.UTF_8); + String encoded = Base64.getEncoder().encodeToString(credentialsBytes); + requestHeaders.put("Authorization", String.format("Basic %s", encoded)); + return this; + } + + /** + * Specify if metrics should be pushed using HTTP or HTTPS. Default is HTTP. + * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.scheme} property. + */ + public Builder scheme(Scheme scheme) { + if (scheme == null) { + throw new NullPointerException(); + } + this.scheme = scheme; + return this; + } + + /** + * Custom connection factory. Default is {@link DefaultHttpConnectionFactory}. + *

      + * The {@code PushGatewayTestApp} in {@code integration-tests/it-pushgateway/} has an example of a custom + * connection factory that skips SSL certificate validation for HTTPS connections. + */ + public Builder connectionFactory(HttpConnectionFactory connectionFactory) { + if (connectionFactory == null) { + throw new NullPointerException(); + } + this.connectionFactory = connectionFactory; + return this; + } + + /** + * The {@code job} label to be used when pushing metrics. + * If not provided, the name of the JAR file will be used by default. + * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.job} property. + */ + public Builder job(String job) { + if (job == null) { + throw new NullPointerException(); + } + this.job = job; + return this; + } + + /** + * Grouping keys to be used when pushing/deleting metrics. + * Call this method multiple times for adding multiple grouping keys. + */ + public Builder groupingKey(String name, String value) { + if (name == null || value == null) { + throw new NullPointerException(); + } + groupingKey.put(name, value); + return this; + } + + /** + * Convenience method for adding the current IP address as an "instance" label. + */ + public Builder instanceIpGroupingKey() throws UnknownHostException { + return groupingKey("instance", InetAddress.getLocalHost().getHostAddress()); + } + + /** + * Push metrics from this registry instead of {@link PrometheusRegistry#defaultRegistry}. + */ + public Builder registry(PrometheusRegistry registry) { + if (registry == null) { + throw new NullPointerException(); + } + this.registry = registry; + return this; + } + + private Scheme getScheme(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getScheme() != null) { + return Scheme.valueOf(properties.getScheme()); + } else if (this.scheme != null) { + return this.scheme; + } else { + return HTTP; + } + } + + private String getAddress(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getAddress() != null) { + return properties.getAddress(); + } else if (this.address != null) { + return this.address; + } else { + return "localhost:9091"; + } + } + + private String getJob(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getJob() != null) { + return properties.getJob(); + } else if (this.job != null) { + return this.job; + } else { + return DefaultJobLabelDetector.getDefaultJobLabel(); + } + } + + private Format getFormat(ExporterPushgatewayProperties properties) { + // currently not configurable via properties + if (this.format != null) { + return this.format; + } + return Format.PROMETHEUS_PROTOBUF; + } + + private URL makeUrl(ExporterPushgatewayProperties properties) throws UnsupportedEncodingException, MalformedURLException { + String url = getScheme(properties) + "://" + getAddress(properties) + "/metrics/"; + String job = getJob(properties); + if (job.contains("/")) { + url += "job@base64/" + base64url(job); + } else { + url += "job/" + URLEncoder.encode(job, "UTF-8"); + } + if (groupingKey != null) { + for (Map.Entry entry : groupingKey.entrySet()) { + if (entry.getValue().isEmpty()) { + url += "/" + entry.getKey() + "@base64/="; + } else if (entry.getValue().contains("/")) { + url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue()); + } else { + url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8"); + } + } + } + return URI.create(url).normalize().toURL(); + } + + private String base64url(String v) { + return Base64.getEncoder().encodeToString(v.getBytes(StandardCharsets.UTF_8)).replace("+", "-").replace("/", "_"); + } + + public PushGateway build() { + ExporterPushgatewayProperties properties = config == null ? null : config.getExporterPushgatewayProperties(); + try { + return new PushGateway(registry, getFormat(properties), makeUrl(properties), connectionFactory, requestHeaders); + } catch (MalformedURLException e) { + throw new PrometheusPropertiesException(address + ": Invalid address. Expecting :"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // cannot happen, UTF-8 is always supported + } + } } - return result.toString("UTF-8"); - } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java new file mode 100644 index 000000000..adb7ebf07 --- /dev/null +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java @@ -0,0 +1,29 @@ +package io.prometheus.metrics.exporter.pushgateway; + +public enum Scheme { + + HTTP("http"), + HTTPS("https"); + + private final String name; + + Scheme(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public static Scheme fromString(String name) { + switch (name) { + case "http": + return HTTP; + case "https": + return HTTPS; + default: + throw new IllegalArgumentException(name + ": Unsupported scheme. Expecting 'http' or 'https'."); + } + } +} diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java index 2fca7d9a4..78706ee49 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java @@ -1,45 +1,48 @@ package io.prometheus.metrics.exporter.pushgateway; - -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - -import java.io.IOException; - -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Gauge; +import io.prometheus.metrics.core.metrics.Gauge; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockserver.client.MockServerClient; import org.mockserver.junit.MockServerRule; +import java.io.IOException; + +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + public class BasicAuthPushGatewayTest { - @Rule - public MockServerRule mockServerRule = new MockServerRule(this); - private MockServerClient mockServerClient; - - CollectorRegistry registry; - Gauge gauge; - PushGateway pushGateway; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - gauge = Gauge.build().name("g").help("help").create(); - pushGateway = new PushGateway("localhost:" + mockServerRule.getPort()); - pushGateway.setConnectionFactory(new BasicAuthHttpConnectionFactory("testUser", "testPwd")); - } - - @Test - public void testAuthorizedPush() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withHeader("Authorization", "Basic dGVzdFVzZXI6dGVzdFB3ZA==") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pushGateway.push(registry, "j"); - } + @Rule + public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; + + PrometheusRegistry registry; + Gauge gauge; + PushGateway pushGateway; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + pushGateway = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .basicAuth("testUser", "testPwd") + .registry(registry) + .job("j") + .build(); + } + + @Test + public void testAuthorizedPush() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withHeader("Authorization", "Basic dGVzdFVzZXI6dGVzdFB3ZA==") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + pushGateway.push(); + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java deleted file mode 100644 index 9b9196b7a..000000000 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/ExamplePushGateway.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.prometheus.metrics.exporter.pushgateway; - -import io.prometheus.client.Gauge; -import io.prometheus.client.CollectorRegistry; - - -public class ExamplePushGateway { - static final CollectorRegistry pushRegistry = new CollectorRegistry(); - static final Gauge g = (Gauge) Gauge.build().name("gauge").help("blah").register(pushRegistry); - - /** - * Example of how to use the pushgateway, pass in the host:port of a pushgateway. - */ - public static void main(String[] args) throws Exception { - PushGateway pg = new PushGateway(args[0]); - g.set(42); - pg.push(pushRegistry, "job"); - } -} - diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java index c1ac4b797..74ebae7ac 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java @@ -1,223 +1,319 @@ package io.prometheus.metrics.exporter.pushgateway; -import static org.junit.rules.ExpectedException.none; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - -import io.prometheus.client.CollectorRegistry; -import io.prometheus.client.Gauge; -import java.io.IOException; -import java.util.TreeMap; -import java.util.Map; - +import io.prometheus.metrics.core.metrics.Gauge; +import io.prometheus.metrics.model.registry.PrometheusRegistry; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.mockserver.junit.MockServerRule; import org.mockserver.client.MockServerClient; +import org.mockserver.junit.MockServerRule; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URL; + +import static org.junit.rules.ExpectedException.none; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; public class PushGatewayTest { + @Rule + public final ExpectedException thrown = none(); + + @Rule + public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; + + PrometheusRegistry registry; + Gauge gauge; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + } + + @Test(expected = RuntimeException.class) + public void testInvalidURLThrowsRuntimeException() { + PushGateway.builder().address("::").build(); // ":" is interpreted as port number, so parsing fails + } + + @Test + public void testMultipleSlashesAreStrippedFromURL() throws NoSuchFieldException, IllegalAccessException { + final PushGateway pushGateway = PushGateway.builder() + .address("example.com:1234/context///path//") + .job("test") + .build(); + Assert.assertEquals( + "http://example.com:1234/context/path/metrics/job/test", + getUrl(pushGateway).toString() + ); + } + + private URL getUrl(PushGateway pushGateway) throws IllegalAccessException, NoSuchFieldException { + Field field = pushGateway.getClass().getDeclaredField("url"); + field.setAccessible(true); + return (URL) field.get(pushGateway); + } + + @Test + public void testPush() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } + + @Test + public void testPush200Response() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(200)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } + + @Test + public void testNon202ResponseThrows() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(500)); + thrown.expect(IOException.class); + thrown.expectMessage( + "Response code from http://localhost:" + + mockServerRule.getPort() + + "/metrics/job/j was 500"); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } + + @Test + public void testPushCollector() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } + + @Test + public void testPushWithGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .build(); + pg.push(); + } + + @Test + public void testPushWithMultiGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j/l/v/l2/v2") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .groupingKey("l2", "v2") + .build(); + pg.push(); + } + + @Test + public void testPushWithEmptyLabelGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j/l/v/l2@base64/=") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .groupingKey("l2", "") + .build(); + pg.push(); + } + + @Test + public void testPushWithGroupingKeyWithSlashes() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job@base64/YS9i/l/v/l2@base64/75-_Lw==") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("a/b") + .groupingKey("l", "v") + .groupingKey("l2", "\uF7FF/") + .build(); + pg.push(); + } + + @Test + public void testPushCollectorWithGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withPath("/metrics/job/j/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .build(); + pg.push(gauge); + } + + @Test + public void testPushAdd() throws IOException { + mockServerClient.when( + request() + .withMethod("POST") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.pushAdd(); + } + + @Test + public void testPushAddCollector() throws IOException { + mockServerClient.when( + request() + .withMethod("POST") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .build(); + pg.pushAdd(gauge); + } + + @Test + public void testPushAddWithGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("POST") + .withPath("/metrics/job/j/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .groupingKey("l", "v") + .job("j") + .build(); + pg.pushAdd(); + } + + @Test + public void testPushAddCollectorWithGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("POST") + .withPath("/metrics/job/j/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .groupingKey("l", "v") + .job("j") + .build(); + pg.pushAdd(gauge); + } + + @Test + public void testDelete() throws IOException { + mockServerClient.when( + request() + .withMethod("DELETE") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .build(); + pg.delete(); + } + + @Test + public void testDeleteWithGroupingKey() throws IOException { + mockServerClient.when( + request() + .withMethod("DELETE") + .withPath("/metrics/job/j/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .groupingKey("l", "v") + .build(); + pg.delete(); + } - @Rule - public final ExpectedException thrown = none(); - - @Rule - public MockServerRule mockServerRule = new MockServerRule(this); - private MockServerClient mockServerClient; - - CollectorRegistry registry; - Gauge gauge; - PushGateway pg; - Map groupingKey; - - @Before - public void setUp() { - registry = new CollectorRegistry(); - gauge = (Gauge) Gauge.build().name("g").help("help").create(); - pg = new PushGateway("localhost:" + mockServerRule.getPort()); - groupingKey = new TreeMap(); - groupingKey.put("l", "v"); - } - - @Test(expected = RuntimeException.class) - public void testInvalidURLThrowsRuntimeException() { - new PushGateway("::"); // ":" is interpreted as port number, so parsing fails - } - - @Test - public void testMultipleSlashesAreStrippedFromURL() { - final PushGateway pushGateway = new PushGateway("example.com:1234/context///path//"); - Assert.assertEquals( - "http://example.com:1234/context/path/metrics/", - pushGateway.gatewayBaseURL - ); - } - - @Test - public void testPush() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pg.push(registry, "j"); - } - - @Test - public void testPush200Response() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(200)); - pg.push(registry, "j"); - } - - @Test - public void testNon202ResponseThrows() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(500)); - thrown.expect(IOException.class); - thrown.expectMessage( - "Response code from http://localhost:" - + mockServerRule.getPort() - + "/metrics/job/j was 500"); - pg.push(registry, "j"); - } - - @Test - public void testPushCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pg.push(gauge, "j"); - } - - @Test - public void testPushWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - pg.push(registry, "j", groupingKey); - } - - @Test - public void testPushWithMultiGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v/l2/v2") - ).respond(response().withStatusCode(202)); - groupingKey.put("l2", "v2"); - pg.push(registry, "j", groupingKey); - } - - @Test - public void testPushWithEmptyLabelGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v/l2@base64/=") - ).respond(response().withStatusCode(202)); - groupingKey.put("l2", ""); - pg.push(registry, "j", groupingKey); - } - - @Test - public void testPushWithGroupingKeyWithSlashes() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job@base64/YS9i/l/v/l2@base64/75-_Lw==") - ).respond(response().withStatusCode(202)); - groupingKey.put("l2", "\uF7FF/"); - pg.push(registry, "a/b", groupingKey); - } - - @Test - public void testPushCollectorWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - pg.push(gauge, "j", groupingKey); - } - - @Test - public void testPushAdd() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pg.pushAdd(registry, "j"); - } - - @Test - public void testPushAddCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pg.pushAdd(gauge, "j"); - } - - @Test - public void testPushAddWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - pg.pushAdd(registry, "j", groupingKey); - } - - @Test - public void testPushAddCollectorWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - pg.pushAdd(gauge, "j", groupingKey); - } - - @Test - public void testDelete() throws IOException { - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pg.delete("j"); - } - - @Test - public void testDeleteWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - pg.delete("j", groupingKey); - } - - @Test - public void testInstanceIPGroupingKey() throws IOException { - groupingKey = PushGateway.instanceIPGroupingKey(); - Assert.assertTrue(!groupingKey.get("instance").equals("")); - } + @Test + public void testInstanceIpGroupingKey() throws IOException { + String ip = InetAddress.getLocalHost().getHostAddress(); + Assert.assertFalse(ip.isEmpty()); + mockServerClient.when( + request() + .withMethod("DELETE") + .withPath("/metrics/job/j/instance/" + ip + "/l/v") + ).respond(response().withStatusCode(202)); + PushGateway pg = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .groupingKey("l", "v") + .instanceIpGroupingKey() + .build(); + pg.delete(); + } } From dfc559d5d823b746c3c2af7555838a032b418dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 May 2024 14:25:57 +0200 Subject: [PATCH 331/980] Add PushGateway docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- docs/content/config/config.md | 10 +++ docs/content/exporters/pushgateway.md | 103 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 docs/content/exporters/pushgateway.md diff --git a/docs/content/config/config.md b/docs/content/config/config.md index 543ce26e4..a7e57ac0d 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -137,3 +137,13 @@ Exporter OpenTelemetry Properties (3) Format: `key1=value1,key2=value2` Many of these attributes can alternatively be configured via OpenTelemetry environment variables, like `OTEL_EXPORTER_OTLP_ENDPOINT`. The Prometheus metrics library has support for OpenTelemetry environment variables. See Javadoc for details. + +Exporter PushGateway Properties +------------------------------- + +| Name | Javadoc | Note | +|--------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|------| +| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#address(java.lang.String)) | | +| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#scheme(java.lang.String)) | | +| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#job(java.lang.String)) | | + diff --git a/docs/content/exporters/pushgateway.md b/docs/content/exporters/pushgateway.md new file mode 100644 index 000000000..8f002fba9 --- /dev/null +++ b/docs/content/exporters/pushgateway.md @@ -0,0 +1,103 @@ +--- +title: Pushgateway +weight: 5 +--- + +The [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. +Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics to a Pushgateway. +The Pushgateway then exposes these metrics to Prometheus. + +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) Java class allows you to push metrics to a Prometheus Pushgateway. + +Example +------- + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-core:1.3.0' +implementation 'io.prometheus:prometheus-metrics-exporter-pushgateway:1.3.0' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-core + 1.3.0 + + + io.prometheus + prometheus-metrics-exporter-pushgateway + 1.3.0 + +``` +{{< /tab >}} +{{< /tabs >}} + +```java +public class ExampleBatchJob { + + private static PushGateway pushGateway = PushGateway.builder() + .address("localhost:9091") // not needed as localhost:9091 is the default + .job("example") + .build(); + + private static Gauge dataProcessedInBytes = Gauge.builder() + .name("data_processed") + .help("data processed in the last batch job run") + .unit(Unit.BYTES) + .register(); + + public static void main(String[] args) throws Exception { + try { + long bytesProcessed = processData(); + dataProcessedInBytes.set(bytesProcessed); + } finally { + pushGateway.push(); + } + } + + public static long processData() { + // Imagine a batch job here that processes data + // and returns the number of Bytes processed. + return 42; + } +} +``` + +Basic Auth +---------- + +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports basic authentication. + +```java +PushGateway pushGateway = PushGateway.builder() + .job("example") + .basicAuth("my_user", "my_password") + .build(); +``` + +The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. + +SSL +--- + +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports SSL. + +```java +PushGateway pushGateway = PushGateway.builder() + .job("example") + .scheme(Scheme.HTTPS) + .build(); +``` + +However, this requires that the JVM can validate the server certificate. + +If you want to skip certificate verification, you need to provide your own [HttpConnectionFactory](/client_java/api/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.html). +The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. + +Configuration Properties +------------------------ + +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports a couple of properties that can be configured at runtime. See [config](../../config/config). \ No newline at end of file From 2ae979d459b7cd3d9856fc8220eafefeab816fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 May 2024 20:12:37 +0200 Subject: [PATCH 332/980] Add comments to the HTTPServer start() method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../it/exporter/httpserver/HTTPServerSample.java | 2 +- .../metrics/exporter/httpserver/HTTPServer.java | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index ccd0b7724..b8cdc5141 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -65,7 +65,7 @@ public static void main(String[] args) throws IOException, InterruptedException .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - Thread.sleep(10_000); + Thread.currentThread().join(); // wait forever } private static int parsePortOrExit(String port) { diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index eb5b5f39d..de572ba9f 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -56,11 +56,14 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService, registerHandler("/metrics", new MetricsHandler(config, registry), authenticator); registerHandler("/-/healthy", new HealthyHandler(), authenticator); try { - executorService.submit(() -> this.server.start()).get(); + // HttpServer.start() starts the HttpServer in a new background thread. + // If we call HttpServer.start() from a thread of the executorService, + // the background thread will inherit the "daemon" property, + // i.e. the server will run as a Daemon thread. + // See https://github.com/prometheus/client_java/pull/955 + this.executorService.submit(this.server::start).get(); // calling .get() on the Future here to avoid silently discarding errors - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { + } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } } From c82ab1fa65b859c7844e7d9e378aa8b3a954be47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Wed, 15 May 2024 21:27:56 +0200 Subject: [PATCH 333/980] Prevent illegal metric names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../core/metrics/MetricWithFixedMetadata.java | 4 +- .../ExpositionFormatsTest.java | 43 ++++++------------- .../model/snapshots/MetricMetadata.java | 6 +++ .../model/snapshots/PrometheusNaming.java | 14 ++++++ .../model/snapshots/MetricMetadataTest.java | 6 +-- 5 files changed, 39 insertions(+), 34 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 9d39593eb..5b96ea303 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -32,8 +32,8 @@ protected MetricMetadata getMetadata() { private String makeName(String name, Unit unit) { if (unit != null) { - if (!name.endsWith(unit.toString())) { - name = name + "_" + unit; + if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { + name += "_" + unit; } } return name; diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index c86bc6520..09600eafd 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -1,26 +1,11 @@ package io.prometheus.metrics.expositionformats; +import io.prometheus.metrics.model.snapshots.*; import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; -import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; -import io.prometheus.metrics.model.snapshots.Exemplar; -import io.prometheus.metrics.model.snapshots.Exemplars; -import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; -import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; -import io.prometheus.metrics.model.snapshots.HistogramSnapshot; -import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.model.snapshots.MetricSnapshot; -import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; -import io.prometheus.metrics.model.snapshots.Quantiles; -import io.prometheus.metrics.model.snapshots.StateSetSnapshot; -import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; -import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.model.snapshots.UnknownSnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; import org.junit.Assert; import org.junit.Test; @@ -1825,24 +1810,24 @@ public void testUnknownMinimal() throws IOException { @Test public void testUnknownWithDots() throws IOException { String openMetrics = "" + - "# TYPE some_unknown_metric unknown\n" + - "# UNIT some_unknown_metric bytes\n" + - "# HELP some_unknown_metric help message\n" + - "some_unknown_metric{test_env=\"7\"} 0.7\n" + + "# TYPE some_unknown_metric_bytes unknown\n" + + "# UNIT some_unknown_metric_bytes bytes\n" + + "# HELP some_unknown_metric_bytes help message\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n" + "# EOF\n"; String openMetricsWithExemplarsOnAllTimeSeries = "" + - "# TYPE some_unknown_metric unknown\n" + - "# UNIT some_unknown_metric bytes\n" + - "# HELP some_unknown_metric help message\n" + - "some_unknown_metric{test_env=\"7\"} 0.7 # " + exemplarWithDotsString + "\n" + + "# TYPE some_unknown_metric_bytes unknown\n" + + "# UNIT some_unknown_metric_bytes bytes\n" + + "# HELP some_unknown_metric_bytes help message\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7 # " + exemplarWithDotsString + "\n" + "# EOF\n"; String prometheus = "" + - "# HELP some_unknown_metric help message\n" + - "# TYPE some_unknown_metric untyped\n" + - "some_unknown_metric{test_env=\"7\"} 0.7\n"; + "# HELP some_unknown_metric_bytes help message\n" + + "# TYPE some_unknown_metric_bytes untyped\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n"; String prometheusProtobuf = "" + //@formatter:off - "name: \"some_unknown_metric\" " + + "name: \"some_unknown_metric_bytes\" " + "help: \"help message\" " + "type: UNTYPED " + "metric { " + @@ -1851,7 +1836,7 @@ public void testUnknownWithDots() throws IOException { "}"; //@formatter:on UnknownSnapshot unknown = UnknownSnapshot.builder() - .name("some.unknown.metric") + .name(PrometheusNaming.sanitizeMetricName("some.unknown.metric", Unit.BYTES)) .help("help message") .unit(Unit.BYTES) .dataPoint(UnknownDataPointSnapshot.builder() diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java index 366805ddf..b9e577e2c 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java @@ -105,5 +105,11 @@ private void validate() { throw new IllegalArgumentException("'" + name + "': Illegal metric name. " + error + " Call " + PrometheusNaming.class.getSimpleName() + ".sanitizeMetricName(name) to avoid this error."); } + if (hasUnit()) { + if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { + throw new IllegalArgumentException("'" + name + "': Illegal metric name. The name must end with _" + unit + "." + + " Call " + PrometheusNaming.class.getSimpleName() + ".sanitizeMetricName(name, unit) to avoid this error."); + } + } } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java index 34d8251e1..b07e0d07e 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java @@ -121,6 +121,20 @@ public static String sanitizeMetricName(String metricName) { return sanitizedName; } + /** + * Like {@link #sanitizeMetricName(String)}, but also makes sure that the unit is appended + * as a suffix if the unit is not {@code null}. + */ + public static String sanitizeMetricName(String metricName, Unit unit) { + String result = sanitizeLabelName(metricName); + if (unit != null) { + if (!result.endsWith("_" + unit) && !result.endsWith("." + unit)) { + result += "_" + unit; + } + } + return result; + } + /** * Convert an arbitrary string to a name where {@link #isValidLabelName(String) isValidLabelName(name)} is true. */ 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 6e76f724a..77a328873 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 @@ -25,9 +25,9 @@ public void testIllegalName() { @Test public void testSanitizationIllegalCharacters() { - MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("my_namespace/http.server.duration"), "help string", Unit.SECONDS); - Assert.assertEquals("my_namespace_http.server.duration", metadata.getName()); - Assert.assertEquals("my_namespace_http_server_duration", metadata.getPrometheusName()); + 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()); } From bf242dc217fe5a0d87c426d99e7938e45addd201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 21:32:16 +0200 Subject: [PATCH 334/980] Prevent illegal metric names - code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../metrics/model/snapshots/MetricMetadata.java | 2 +- .../model/snapshots/MetricMetadataTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java index b9e577e2c..8a393cf95 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java @@ -107,7 +107,7 @@ private void validate() { } if (hasUnit()) { if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { - throw new IllegalArgumentException("'" + name + "': Illegal metric name. The name must end with _" + unit + "." + throw new IllegalArgumentException("'" + name + "': Illegal metric name. If the unit is non-null, the name must end with the unit: _" + unit + "." + " Call " + PrometheusNaming.class.getSimpleName() + ".sanitizeMetricName(name, unit) to avoid this error."); } } 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 77a328873..f9e9a18d6 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 @@ -54,4 +54,19 @@ public void testSanitizationWeirdCornerCase() { public void testSanitizeEmptyString() { sanitizeMetricName(""); } + + @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 testUnitNotDuplicated() { + Assert.assertEquals("my_counter_bytes", sanitizeMetricName("my_counter_bytes", Unit.BYTES)); + } } From 2a27d6b5154df33405444b717c88296cef7589c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 22:21:44 +0200 Subject: [PATCH 335/980] Update dependencies and temporarily add shaded dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- .../example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter-servlet-jetty-sample/pom.xml | 4 ++-- .../it-exporter-servlet-tomcat-sample/pom.xml | 2 +- .../it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 12 +++++------ .../pom.xml | 8 ++++---- .../opentelemetry/OpenTelemetryExporter.java | 18 ++++++++--------- .../PrometheusInstrumentationScope.java | 2 +- .../PrometheusMetricProducer.java | 14 ++++++------- .../otelmodel/DoublePointDataImpl.java | 6 +++--- .../ExponentialHistogramBucketsImpl.java | 2 +- .../ExponentialHistogramPointDataImpl.java | 8 ++++---- .../otelmodel/HistogramPointDataImpl.java | 6 +++--- .../otelmodel/MetricDataFactory.java | 6 +++--- .../otelmodel/PointDataImpl.java | 7 +++---- .../otelmodel/PrometheusClassicHistogram.java | 8 ++++---- .../otelmodel/PrometheusCounter.java | 8 ++++---- .../otelmodel/PrometheusData.java | 20 +++++++++---------- .../otelmodel/PrometheusGauge.java | 6 +++--- .../otelmodel/PrometheusInfo.java | 8 ++++---- .../otelmodel/PrometheusMetricData.java | 13 ++++++------ .../otelmodel/PrometheusNativeHistogram.java | 10 +++++----- .../otelmodel/PrometheusStateSet.java | 8 ++++---- .../otelmodel/PrometheusSummary.java | 6 +++--- .../otelmodel/PrometheusUnknown.java | 6 +++--- .../otelmodel/SummaryPointDataImpl.java | 8 ++++---- .../otelmodel/ValueAtQuantileImpl.java | 2 +- .../pom.xml | 4 ++-- prometheus-metrics-exposition-formats/pom.xml | 4 ++-- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 4 ++-- prometheus-metrics-tracer/pom.xml | 2 +- 38 files changed, 114 insertions(+), 116 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 1b20a0470..e4c898ef2 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.19 + 10.1.24 diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 5baa99dd8..346417583 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.19 + 10.1.24 diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index bf6598e6f..a78cfd229 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -50,7 +50,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.19 + 10.1.24 diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index a17fcb2c7..28bb7c1d8 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -45,12 +45,12 @@ org.eclipse.jetty jetty-server - 11.0.20 + 11.0.21 org.eclipse.jetty jetty-servlet - 11.0.20 + 11.0.21 diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 016433ec2..78914a7ea 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -45,7 +45,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.19 + 10.1.24 diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index def7ff0ca..9de44493a 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -51,7 +51,7 @@ commons-io commons-io - 2.15.1 + 2.16.1 test diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index d8b81a303..85c49d2b2 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -65,7 +65,7 @@ com.jayway.jsonpath json-path - 2.8.0 + 2.9.0 test diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 9bac492fb..b51829120 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -55,7 +55,7 @@ org.testcontainers testcontainers - 1.19.7 + 1.19.8 test diff --git a/pom.xml b/pom.xml index b79891eb9..f9b64b7e7 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-simpleclient-bridge - + prometheus-metrics-shaded-dependencies examples benchmarks integration-tests diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index d000aac2d..afdd84cf0 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -118,20 +118,20 @@ io.prometheus prometheus-metrics-shaded-dependencies - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} io.prometheus prometheus-metrics-shaded-protobuf - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} io.prometheus prometheus-metrics-shaded-opentelemetry - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 8d80bda14..25f657f31 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -17,7 +17,7 @@ - 1.36.0 + 1.38.0 io.prometheus.metrics.exporter.opentelemetry @@ -46,8 +46,8 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.2.1 - + + ${project.version} @@ -60,7 +60,7 @@ org.wiremock wiremock - 3.4.2 + 3.5.4 test diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index 6cb3b4731..97719d6c3 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -3,15 +3,15 @@ import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.MetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.PeriodicMetricReader; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.ResourceBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.MetricExporter; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.PeriodicMetricReader; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; import java.time.Duration; import java.util.HashMap; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java index acaf0d2a9..de14def11 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; import java.util.Properties; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 63b042ecd..37ee4d1de 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -12,13 +12,13 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.export.CollectionRegistration; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.ResourceBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.CollectionRegistration; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java index b8b850367..8f4a627ff 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java index 664d03cc1..5acacc457 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java index 1756bf63f..799e44712 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java index 9e2eb70dd..af9c1519d 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 24dd549e4..6e723e20a 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -7,9 +7,9 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; public class MetricDataFactory { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java index c9b3713e7..b3795e5dd 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java @@ -1,9 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.PointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index 55eddc9be..0040c7d17 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -2,10 +2,10 @@ import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.HistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java index be0a54a19..4ad04975f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index ef5028871..7d67a22fa 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -1,16 +1,16 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.*; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.SpanContext; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.TraceFlags; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.trace.TraceState; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.Data; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.PointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.AttributesBuilder; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.SpanContext; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.TraceFlags; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.TraceState; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.Data; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import java.util.Collections; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java index 21136b338..73e176bb6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index 88be12ba7..6159e77fb 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -1,10 +1,10 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import java.util.Collection; import java.util.Collections; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java index a12e63f76..348ff535f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -1,14 +1,13 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.MetricMetadata; -import io.prometheus.metrics.model.snapshots.PrometheusNaming; import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.resources.Resource; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; class PrometheusMetricData> implements MetricData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java index c0fcfdf13..83ce1f14a 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -2,11 +2,11 @@ import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ExponentialHistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java index 6631813fb..110919428 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java @@ -2,10 +2,10 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SumData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import java.util.ArrayList; import java.util.Collection; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java index 29f861e2e..11e780018 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java @@ -2,9 +2,9 @@ import io.prometheus.metrics.model.snapshots.Quantile; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java index bcda2e74a..9bb2f8e76 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.MetricDataType; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java index 03a9179c5..83155f05a 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.SummaryPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ValueAtQuantile; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ValueAtQuantile; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java index 09c244534..8117c5a8c 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_36_0.sdk.metrics.data.ValueAtQuantile; +import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ValueAtQuantile; public class ValueAtQuantileImpl implements ValueAtQuantile { diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 47dbadf74..66690e973 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -59,13 +59,13 @@ org.mock-server mockserver-netty - 5.13.2 + 5.15.0 test org.mock-server mockserver-junit-rule-no-dependencies - 5.13.2 + 5.15.0 test diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 88e2b1955..66ec6a427 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -50,8 +50,8 @@ io.prometheus prometheus-metrics-shaded-protobuf - 1.2.1 - + + ${project.version} diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 92fc3de4c..40d04d516 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -70,7 +70,7 @@ org.mockito mockito-core - 5.11.0 + 5.12.0 test diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 2b0208e5a..0e42c50c5 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -58,7 +58,7 @@ org.mockito mockito-core - 5.11.0 + 5.12.0 test diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index e613da510..e48a18808 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -16,8 +16,8 @@ - 1.36.0 - 1_36_0 + 1.38.0 + 1_38_0 diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 5a547bfce..0e08aae71 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -37,7 +37,7 @@ io.opentelemetry opentelemetry-api - 1.36.0 + 1.38.0 From 8f4b89f727ef06894a8bb0b8dad06785955e64d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 23:21:43 +0200 Subject: [PATCH 336/980] Fix module name and dependency in pushgateway pom.xml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- prometheus-metrics-exporter-pushgateway/pom.xml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 66690e973..c217374ba 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -16,6 +16,10 @@ Exporter for pushing metrics to a pushgateway. + + io.prometheus.metrics.exporter.pushgateway + + The Apache Software License, Version 2.0 @@ -37,19 +41,12 @@ - io.prometheus prometheus-metrics-exporter-common ${project.version} - - javax.xml.bind - jaxb-api - 2.4.0-b180830.0359 - provided - junit junit From 87f6d42db7d3b6db30deda840a9970fb9897707a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 23:38:25 +0200 Subject: [PATCH 337/980] Add pushgateway to BOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- prometheus-metrics-bom/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index afdd84cf0..c22de6e13 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -55,6 +55,11 @@ prometheus-metrics-exporter-opentelemetry ${project.version} + + io.prometheus + prometheus-metrics-exporter-pushgateway + ${project.version} + io.prometheus prometheus-metrics-exporter-servlet-jakarta From 5768efe8e829bf88c7af789adb31e2fffa551143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 23:48:37 +0200 Subject: [PATCH 338/980] [maven-release-plugin] prepare release v1.3.0 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/it-pushgateway/pom.xml | 8 +++----- integration-tests/pom.xml | 5 ++--- pom.xml | 4 ++-- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 43 files changed, 48 insertions(+), 51 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 89181cfb9..80f5c594a 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index e4c898ef2..181384a0b 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.0-SNAPSHOT + 1.3.0 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 346417583..c393bfcd6 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.0-SNAPSHOT + 1.3.0 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 9d10957fb..cdf55bd6e 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index a48c660d2..6b6da8ea7 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 25ed35b83..60a6ceeeb 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 9d5162f0d..e775c80c6 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index a78cfd229..3f83002ab 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index fb86430ef..494c777cd 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 6566acff3..f6be3b751 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 73453d437..a256ac54e 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0-SNAPSHOT + 1.3.0 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index c5ba5bff4..3b043e6f5 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index e9fc2d60a..bd0bf5e04 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.0-SNAPSHOT + 1.3.0 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 0d49e17a5..2050a3bf8 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0-SNAPSHOT + 1.3.0 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 28bb7c1d8..7be578a17 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0-SNAPSHOT + 1.3.0 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 78914a7ea..0599f2e53 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0-SNAPSHOT + 1.3.0 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 9de44493a..842c793d8 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0-SNAPSHOT + 1.3.0 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 2d012f5dd..d8636141c 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.0-SNAPSHOT + 1.3.0 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.3.0 diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 85c49d2b2..8d53a7cac 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus integration-tests - 1.3.0-SNAPSHOT + 1.3.0 it-pushgateway @@ -84,8 +83,7 @@ - + io.prometheus.metrics.it.pushgateway.PushGatewayTestApp diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index b51829120..e49ef85fa 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 integration-tests diff --git a/pom.xml b/pom.xml index f9b64b7e7..8fdda21af 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -30,7 +30,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.3.0 diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index c22de6e13..6768f9194 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index ec8e44b56..7463d4eed 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 283a00a0b..94fe8990e 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index d8f89cef0..4dd28da79 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 34908364e..c4861dfae 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 25f657f31..1a107390d 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index c217374ba..fe5da088e 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 63d05d998..4f802d3e6 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index 41984e48b..65e8b8bb9 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 66ec6a427..6e574f04d 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 40d04d516..d87da6b6b 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 0e42c50c5..47f3ba704 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index e6ac36c97..24f3c23e4 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index ded184f1a..70d6f0754 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index e48a18808..878872ca8 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index cb0ca8ee7..5a1b90017 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index ed4dd8921..defa85806 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 0e08aae71..c67dd26bb 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index b44735d05..4791ca998 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 3b9aa5e5e..9a3bd3c6a 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index a5ed05f54..4d6190b34 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index f10225ae1..c7f0d9689 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0-SNAPSHOT + 1.3.0 prometheus-metrics-tracer-otel From 81017d37026fa5f3395058e3c229fad267965d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 16 May 2024 23:48:41 +0200 Subject: [PATCH 339/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 80f5c594a..f9d2f1866 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 181384a0b..72ebcbedd 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.0 + 1.4.0-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index c393bfcd6..ae0b36799 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.0 + 1.4.0-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index cdf55bd6e..ed3cb087f 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 6b6da8ea7..189e74c6c 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 60a6ceeeb..0f1b03cff 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index e775c80c6..29c9ab152 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 3f83002ab..1f9df84c5 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 494c777cd..336a4d05a 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index f6be3b751..62b44cfec 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index a256ac54e..d874aacb9 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.0 + 1.4.0-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 3b043e6f5..a1eb17226 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index bd0bf5e04..195a10caa 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.0 + 1.4.0-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 2050a3bf8..2743b3933 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0 + 1.4.0-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 7be578a17..622f93254 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0 + 1.4.0-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 0599f2e53..bb78e0543 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0 + 1.4.0-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 842c793d8..899a17f10 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.0 + 1.4.0-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index d8636141c..694cee959 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.0 + 1.4.0-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.3.0 + HEAD diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 8d53a7cac..25ce45b12 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.0 + 1.4.0-SNAPSHOT it-pushgateway diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index e49ef85fa..2ed77b95d 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT integration-tests diff --git a/pom.xml b/pom.xml index 8fdda21af..e678cf66d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -30,7 +30,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.3.0 + HEAD diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 6768f9194..f316bb141 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 7463d4eed..2d1e95c88 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 94fe8990e..fd3c9a04f 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 4dd28da79..f65aabf68 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index c4861dfae..45fbfe18f 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 1a107390d..27c8cedbb 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index fe5da088e..8b6e22525 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 4f802d3e6..18559c8e7 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index 65e8b8bb9..b930dd9cf 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 6e574f04d..027faa19b 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index d87da6b6b..085e6de74 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 47f3ba704..c847500db 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 24f3c23e4..8d3051dfe 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 70d6f0754..49b015e49 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 878872ca8..415735290 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 5a1b90017..9f9d46f14 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index defa85806..ba88815f7 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index c67dd26bb..2d10bca44 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 4791ca998..dee1f5a43 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 9a3bd3c6a..4898db46f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 4d6190b34..66a15e397 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index c7f0d9689..2c91242e1 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.0 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel From c0a38270c021e4d63998a98a68bacf2b6f32ace5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Fri, 17 May 2024 00:18:15 +0200 Subject: [PATCH 340/980] Exclude shaded dependencies from build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 14 +++++++------- prometheus-metrics-exporter-opentelemetry/pom.xml | 4 ++-- prometheus-metrics-exposition-formats/pom.xml | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index e678cf66d..6db493f10 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-simpleclient-bridge - prometheus-metrics-shaded-dependencies + examples benchmarks integration-tests diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index f316bb141..02b9ab9e8 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -17,7 +17,7 @@ - 1.2.1 + 1.3.0 @@ -123,20 +123,20 @@ io.prometheus prometheus-metrics-shaded-dependencies - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + io.prometheus prometheus-metrics-shaded-protobuf - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + io.prometheus prometheus-metrics-shaded-opentelemetry - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 27c8cedbb..966f79d7f 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,8 +46,8 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - - ${project.version} + 1.3.0 + diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 027faa19b..d8d150114 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -50,8 +50,8 @@ io.prometheus prometheus-metrics-shaded-protobuf - - ${project.version} + 1.3.0 + From 4a9347202e8fe30f9aab50bc84769e0b1a5b443e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 23 May 2024 12:09:39 +0200 Subject: [PATCH 341/980] Add method for sanitizing Unit names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- .../model/snapshots/PrometheusNaming.java | 88 +++++++++++++++++++ .../metrics/model/snapshots/Unit.java | 8 +- .../model/snapshots/PrometheusNamingTest.java | 48 +++++++++- 3 files changed, 138 insertions(+), 6 deletions(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java index b07e0d07e..06e004398 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java @@ -20,6 +20,11 @@ public class PrometheusNaming { */ private static final Pattern LABEL_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.][a-zA-Z0-9_.]*$"); + /** + * Legal characters for unit names, including dot. + */ + private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$"); + /** * According to OpenMetrics {@code _count} and {@code _sum} (and {@code _gcount}, {@code _gsum}) should also be * reserved metric name suffixes. However, popular instrumentation libraries have Gauges with names @@ -83,6 +88,32 @@ public static boolean isValidLabelName(String name) { !(name.startsWith("__") || name.startsWith("._") || name.startsWith("..") || name.startsWith("_.")); } + /** + * Units may not have illegal characters, and they may not end with a reserved suffix like 'total'. + */ + public static boolean isValidUnitName(String name) { + return validateUnitName(name) == null; + } + + /** + * Same as {@link #isValidUnitName(String)} but returns an error message. + */ + public static String validateUnitName(String name) { + if (name.isEmpty()) { + return "The unit name must not be empty."; + } + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + String suffixName = reservedSuffix.substring(1); + if (name.endsWith(suffixName)) { + return suffixName + " is a reserved suffix in Prometheus"; + } + } + if (!UNIT_NAME_PATTERN.matcher(name).matches()) { + return "The unit name contains unsupported characters"; + } + return null; + } + /** * Get the metric or label name that is used in Prometheus exposition format. * @@ -149,6 +180,42 @@ public static String sanitizeLabelName(String labelName) { return sanitizedName; } + /** + * Convert an arbitrary string to a name where {@link #isValidUnitName(String) isValidUnitName(name)} is true. + * + * @throws IllegalArgumentException if the {@code unitName} cannot be converted, for example if you call {@code sanitizeUnitName("total")} or {@code sanitizeUnitName("")}. + * @throws NullPointerException if {@code unitName} is null. + */ + public static String sanitizeUnitName(String unitName) { + if (unitName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert an empty string to a valid unit name."); + } + String sanitizedName = replaceIllegalCharsInUnitName(unitName); + boolean modified = true; + while (modified) { + modified = false; + while (sanitizedName.startsWith("_") || sanitizedName.startsWith(".")) { + sanitizedName = sanitizedName.substring(1); + modified = true; + } + while (sanitizedName.endsWith(".") || sanitizedName.endsWith("_")) { + sanitizedName = sanitizedName.substring(0, sanitizedName.length()-1); + modified = true; + } + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + String suffixName = reservedSuffix.substring(1); + if (sanitizedName.endsWith(suffixName)) { + sanitizedName = sanitizedName.substring(0, sanitizedName.length() - suffixName.length()); + modified = true; + } + } + } + if (sanitizedName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert '" + unitName + "' into a valid unit name."); + } + return sanitizedName; + } + /** * Returns a string that matches {@link #METRIC_NAME_PATTERN}. */ @@ -189,4 +256,25 @@ private static String replaceIllegalCharsInLabelName(String name) { } return new String(sanitized); } + + /** + * Returns a string that matches {@link #UNIT_NAME_PATTERN}. + */ + private static String replaceIllegalCharsInUnitName(String name) { + int length = name.length(); + char[] sanitized = new char[length]; + for (int i = 0; i < length; i++) { + char ch = name.charAt(i); + if (ch == ':' || + ch == '.' || + (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } + } + return new String(sanitized); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index 94827c64c..16a6c5941 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -28,10 +28,12 @@ public Unit(String name) { if (name == null) { throw new NullPointerException("Unit name cannot be null."); } - if (name.trim().isEmpty()) { - throw new IllegalArgumentException("Unit name cannot be empty."); + name = name.trim(); + String error = PrometheusNaming.validateUnitName(name); + if (error != null) { + throw new IllegalArgumentException(name + ": Illegal unit name: " + error); } - this.name = name.trim(); + this.name = name; } @Override diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java index d9ba9339d..3a7788743 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java @@ -3,9 +3,7 @@ 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.sanitizeLabelName; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.*; public class PrometheusNamingTest { @@ -19,6 +17,8 @@ public void testSanitizeMetricName() { Assert.assertEquals("jvm", sanitizeMetricName("jvm_info")); Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); Assert.assertEquals("a.b", sanitizeMetricName("a.b")); + Assert.assertEquals("total", sanitizeMetricName("_total")); + Assert.assertEquals("total", sanitizeMetricName("total")); } @Test @@ -31,4 +31,46 @@ public void testSanitizeLabelName() { Assert.assertEquals("abc.def", sanitizeLabelName("abc.def")); Assert.assertEquals("abc.def2", sanitizeLabelName("abc.def2")); } + + @Test + public void testValidateUnitName() { + Assert.assertNotNull(validateUnitName("secondstotal")); + Assert.assertNotNull(validateUnitName("total")); + Assert.assertNotNull(validateUnitName("seconds_total")); + Assert.assertNotNull(validateUnitName("_total")); + Assert.assertNotNull(validateUnitName("")); + + Assert.assertNull(validateUnitName("seconds")); + Assert.assertNull(validateUnitName("2")); + } + + @Test + public void testSanitizeUnitName() { + Assert.assertEquals("seconds", sanitizeUnitName("seconds")); + Assert.assertEquals("seconds", sanitizeUnitName("seconds_total")); + Assert.assertEquals("seconds", sanitizeUnitName("seconds_total_total")); + Assert.assertEquals("m_s", sanitizeUnitName("m/s")); + Assert.assertEquals("seconds", sanitizeUnitName("secondstotal")); + Assert.assertEquals("2", sanitizeUnitName("2")); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName1() { + sanitizeUnitName("total"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName2() { + sanitizeUnitName("_total"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName3() { + sanitizeUnitName("%"); + } + + @Test(expected = IllegalArgumentException.class) + public void testEmptyUnitName() { + sanitizeUnitName(""); + } } From 99b933d9f4eaf817b17a9047cfabab6276913d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 23 May 2024 12:57:55 +0200 Subject: [PATCH 342/980] Temporarily add shaded dependencies to prepare for release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 12 ++++++------ prometheus-metrics-exporter-opentelemetry/pom.xml | 4 ++-- prometheus-metrics-exposition-formats/pom.xml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 6db493f10..e678cf66d 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-simpleclient-bridge - + prometheus-metrics-shaded-dependencies examples benchmarks integration-tests diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 02b9ab9e8..9ce68947c 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -123,20 +123,20 @@ io.prometheus prometheus-metrics-shaded-dependencies - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} io.prometheus prometheus-metrics-shaded-protobuf - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} io.prometheus prometheus-metrics-shaded-opentelemetry - ${prometheus.metrics.shaded.dependencies.version} - + + ${project.version} diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 966f79d7f..be9de3f84 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,8 +46,8 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - 1.3.0 - + + ${project.version} diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index d8d150114..209151f65 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -50,8 +50,8 @@ io.prometheus prometheus-metrics-shaded-protobuf - 1.3.0 - + + ${project.version} From 7c964699a6fe9e6a2355ad8a43603e3ea01b92a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 23 May 2024 13:01:51 +0200 Subject: [PATCH 343/980] [maven-release-plugin] prepare release v1.3.1 --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index f9d2f1866..a54b64fbf 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 72ebcbedd..635018986 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.4.0-SNAPSHOT + 1.3.1 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index ae0b36799..2a1b7a881 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.4.0-SNAPSHOT + 1.3.1 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index ed3cb087f..6e83dc254 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 189e74c6c..6a3f18542 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 0f1b03cff..7a3243953 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 29c9ab152..820f4e592 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 1f9df84c5..48fd93e0c 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 336a4d05a..8b690ae08 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 62b44cfec..7c3dbed02 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index d874aacb9..a909a328d 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 1.3.1 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index a1eb17226..210b4a942 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 195a10caa..d6850e2bd 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 1.3.1 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 2743b3933..945db776c 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 1.3.1 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 622f93254..cd1e1796b 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 1.3.1 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index bb78e0543..b4d96d570 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 1.3.1 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 899a17f10..fb04863a6 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 1.3.1 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 694cee959..15c506722 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 1.3.1 it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.3.1 diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 25ce45b12..fef36075e 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 1.3.1 it-pushgateway diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 2ed77b95d..7c1c64054 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 integration-tests diff --git a/pom.xml b/pom.xml index e678cf66d..84f1c21ce 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -30,7 +30,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - HEAD + v1.3.1 diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 9ce68947c..9f92b1c38 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 2d1e95c88..7ee92ad7d 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index fd3c9a04f..678123e85 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index f65aabf68..d09693172 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 45fbfe18f..a1367181c 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index be9de3f84..2b6eb46dd 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 8b6e22525..55ee69618 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 18559c8e7..0d47dee4f 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index b930dd9cf..faeb0c96d 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 209151f65..0cff443c0 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 085e6de74..677210a02 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index c847500db..b2aee1548 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 8d3051dfe..aeaec90f8 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 49b015e49..611334abc 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 415735290..7a7b9f9d2 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 9f9d46f14..2e58cc371 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index ba88815f7..e75ff9ecb 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 2d10bca44..37d7a31ca 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index dee1f5a43..5c71aa55e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 4898db46f..ffca00d8a 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 66a15e397..3f54f084b 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 2c91242e1..0496e6546 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 1.3.1 prometheus-metrics-tracer-otel From eea6c4e196311b35c8adc463e78ab8972a3df2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 23 May 2024 13:01:55 +0200 Subject: [PATCH 344/980] [maven-release-plugin] prepare for next development iteration --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 4 ++-- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 4 ++-- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-shaded-dependencies/pom.xml | 2 +- .../prometheus-metrics-shaded-opentelemetry/pom.xml | 2 +- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 43 files changed, 45 insertions(+), 45 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index a54b64fbf..f9d2f1866 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 635018986..72ebcbedd 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.1 + 1.4.0-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 2a1b7a881..ae0b36799 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.1 + 1.4.0-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 6e83dc254..ed3cb087f 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 6a3f18542..189e74c6c 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 7a3243953..0f1b03cff 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 820f4e592..29c9ab152 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 48fd93e0c..1f9df84c5 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 8b690ae08..336a4d05a 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 7c3dbed02..62b44cfec 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index a909a328d..d874aacb9 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.1 + 1.4.0-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 210b4a942..a1eb17226 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index d6850e2bd..195a10caa 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.1 + 1.4.0-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 945db776c..2743b3933 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.1 + 1.4.0-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index cd1e1796b..622f93254 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.1 + 1.4.0-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index b4d96d570..bb78e0543 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.1 + 1.4.0-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index fb04863a6..899a17f10 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.1 + 1.4.0-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 15c506722..694cee959 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.1 + 1.4.0-SNAPSHOT it-exporter @@ -29,7 +29,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.3.1 + HEAD diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index fef36075e..25ce45b12 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.1 + 1.4.0-SNAPSHOT it-pushgateway diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 7c1c64054..2ed77b95d 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT integration-tests diff --git a/pom.xml b/pom.xml index 84f1c21ce..e678cf66d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java @@ -30,7 +30,7 @@ scm:git:git@github.com:prometheus/client_java.git scm:git:git@github.com:prometheus/client_java.git git@github.com:prometheus/client_java.git - v1.3.1 + HEAD diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 9f92b1c38..9ce68947c 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 7ee92ad7d..2d1e95c88 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 678123e85..fd3c9a04f 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index d09693172..f65aabf68 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index a1367181c..45fbfe18f 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 2b6eb46dd..be9de3f84 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 55ee69618..8b6e22525 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 0d47dee4f..18559c8e7 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index faeb0c96d..b930dd9cf 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 0cff443c0..209151f65 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 677210a02..085e6de74 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index b2aee1548..c847500db 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index aeaec90f8..8d3051dfe 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 611334abc..49b015e49 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-dependencies diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml index 7a7b9f9d2..415735290 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-opentelemetry diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 2e58cc371..9f9d46f14 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-shaded-dependencies - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index e75ff9ecb..ba88815f7 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 37d7a31ca..2d10bca44 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 5c71aa55e..dee1f5a43 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index ffca00d8a..4898db46f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 3f54f084b..66a15e397 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 0496e6546..2c91242e1 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.1 + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel From fa5e057f216908f83a30c86045a2c24037acf710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Thu, 23 May 2024 14:12:27 +0200 Subject: [PATCH 345/980] Exclude shaded dependencies from build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fabian Stäber --- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 14 +++++++------- prometheus-metrics-exporter-opentelemetry/pom.xml | 4 ++-- prometheus-metrics-exposition-formats/pom.xml | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index e678cf66d..6db493f10 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-simpleclient-bridge - prometheus-metrics-shaded-dependencies + examples benchmarks integration-tests diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 9ce68947c..be1d1b1ca 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -17,7 +17,7 @@ - 1.3.0 + 1.3.1 @@ -123,20 +123,20 @@ io.prometheus prometheus-metrics-shaded-dependencies - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + io.prometheus prometheus-metrics-shaded-protobuf - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + io.prometheus prometheus-metrics-shaded-opentelemetry - - ${project.version} + ${prometheus.metrics.shaded.dependencies.version} + diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index be9de3f84..bde4e05f8 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -46,8 +46,8 @@ io.prometheus prometheus-metrics-shaded-opentelemetry - - ${project.version} + 1.3.1 + diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 209151f65..b745e62cc 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -50,8 +50,8 @@ io.prometheus prometheus-metrics-shaded-protobuf - - ${project.version} + 1.3.1 + From 5867b799a735288147bfd9ee680ca588a34490b9 Mon Sep 17 00:00:00 2001 From: dhoard Date: Thu, 23 May 2024 07:58:02 -0400 Subject: [PATCH 346/980] Simple MetricsSnapshot performance change Signed-off-by: dhoard --- .../prometheus/metrics/model/snapshots/MetricSnapshots.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java index 6fcf3fd25..83d932f87 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -79,8 +79,12 @@ private Builder() { } public boolean containsMetricName(String name) { + if (name == null) { + return false; + } + String prometheusName = prometheusName(name); for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getPrometheusName().equals(prometheusName(name))) { + if (snapshot.getMetadata().getPrometheusName().equals(prometheusName)) { return true; } } From 594a9de376cc60625cf35e363807d209ce6dbaa2 Mon Sep 17 00:00:00 2001 From: Martin Chodur Date: Thu, 18 Jul 2024 18:07:08 +0200 Subject: [PATCH 347/980] feat: add bearerToken builder to pushgateway exporter (#968) * feat: add bearerToken builder to pushgateway exporter Signed-off-by: Martin Chodur * feat: add tests and docs Signed-off-by: Martin Chodur * fix: drop integration tests for bearer token Signed-off-by: Martin Chodur --------- Signed-off-by: Martin Chodur --- docs/content/exporters/pushgateway.md | 17 ++++++- .../it/pushgateway/PushGatewayTestApp.java | 2 +- .../exporter/pushgateway/PushGateway.java | 11 +++++ .../BearerTokenPushGatewayTest.java | 48 +++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java diff --git a/docs/content/exporters/pushgateway.md b/docs/content/exporters/pushgateway.md index 8f002fba9..1ca2946b1 100644 --- a/docs/content/exporters/pushgateway.md +++ b/docs/content/exporters/pushgateway.md @@ -80,6 +80,21 @@ PushGateway pushGateway = PushGateway.builder() The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. +Bearer token +---------- + +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports Bearer token authentication. + +```java +PushGateway pushGateway = PushGateway.builder() + .job("example") + .bearerToken("my_token") + .build(); +``` + +The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. + + SSL --- @@ -100,4 +115,4 @@ The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete ex Configuration Properties ------------------------ -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports a couple of properties that can be configured at runtime. See [config](../../config/config). \ No newline at end of file +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports a couple of properties that can be configured at runtime. See [config](../../config/config). diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java index 279f05d90..69ef63081 100644 --- a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java +++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java @@ -128,4 +128,4 @@ private static void makeMetrics() { .register(); duration.set(0.5); } -} \ No newline at end of file +} diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index a2d587675..0e6ab8d54 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -278,6 +278,17 @@ public Builder basicAuth(String user, String password) { return this; } + /** + * Bearer token authorization when pushing to the Pushgateway. + */ + public Builder bearerToken(String token) { + if (token == null) { + throw new NullPointerException(); + } + requestHeaders.put("Authorization", String.format("Bearer %s", token)); + return this; + } + /** * Specify if metrics should be pushed using HTTP or HTTPS. Default is HTTP. * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.scheme} property. diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java new file mode 100644 index 000000000..8687b2d55 --- /dev/null +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java @@ -0,0 +1,48 @@ +package io.prometheus.metrics.exporter.pushgateway; + +import io.prometheus.metrics.core.metrics.Gauge; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockserver.client.MockServerClient; +import org.mockserver.junit.MockServerRule; + +import java.io.IOException; + +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +public class BearerTokenPushGatewayTest { + + @Rule + public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; + + PrometheusRegistry registry; + Gauge gauge; + PushGateway pushGateway; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + pushGateway = PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .bearerToken("xxx") + .registry(registry) + .job("j") + .build(); + } + + @Test + public void testAuthorizedPush() throws IOException { + mockServerClient.when( + request() + .withMethod("PUT") + .withHeader("Authorization", "Bearer xxx") + .withPath("/metrics/job/j") + ).respond(response().withStatusCode(202)); + pushGateway.push(); + } +} From d567081ad4a9b8698c9d412bddd327517ca89f81 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Tue, 30 Jul 2024 18:09:04 +0200 Subject: [PATCH 348/980] Fix UnknownDataPointSnapshot constructor (#977) Signed-off-by: Mickael Maison --- .../metrics/model/snapshots/UnknownSnapshot.java | 2 +- .../model/snapshots/UnknownSnapshotTest.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java index b02228907..60873013a 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -40,7 +40,7 @@ public static final class UnknownDataPointSnapshot extends DataPointSnapshot { * @param exemplar may be null. */ public UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { - this(value, Labels.EMPTY, exemplar, 0); + this(value, labels, exemplar, 0); } /** diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java index dfc2e62a7..a6d7973b5 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java @@ -68,4 +68,20 @@ public void testNameMissing() { public void testValueMissing() { UnknownSnapshot.UnknownDataPointSnapshot.builder().build(); } + + @Test + public void testUnknownDataPointSnapshot() { + Labels labels = Labels.of("k1", "v1"); + Exemplar exemplar = Exemplar.builder().value(2.0).build(); + + UnknownSnapshot.UnknownDataPointSnapshot data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar); + Assert.assertEquals(1.0, data.getValue(), 0.1); + Assert.assertEquals(labels, data.getLabels()); + Assert.assertEquals(exemplar, data.getExemplar()); + + data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar, 0L); + Assert.assertEquals(1.0, data.getValue(), 0.1); + Assert.assertEquals(labels, data.getLabels()); + Assert.assertEquals(exemplar, data.getExemplar()); + } } From ac0a930dd213bc598030af417e58478ba29d669e Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Tue, 30 Jul 2024 12:34:29 -0400 Subject: [PATCH 349/980] Added methods (#978) Signed-off-by: dhoard --- .../metrics/model/snapshots/Label.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java index c31a8b1af..674eafff8 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Objects; + /** * Utility for iterating over {@link Labels}. */ @@ -16,6 +18,7 @@ public Label(String name, String value) { public String getName() { return name; } + public String getValue() { return value; } @@ -25,4 +28,25 @@ public int compareTo(Label other) { int nameCompare = name.compareTo(other.name); return nameCompare != 0 ? nameCompare : value.compareTo(other.value); } + + @Override + public String toString() { + return "Label{" + + "name='" + name + '\'' + + ", value='" + value + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Label label = (Label) o; + return Objects.equals(name, label.name) && Objects.equals(value, label.value); + } + + @Override + public int hashCode() { + return Objects.hash(name, value); + } } From 9f22e9d90f670e167f4f130c81979a27fc48b577 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Wed, 28 Aug 2024 23:26:22 -0400 Subject: [PATCH 350/980] Updated CircleCI image (#982) Signed-off-by: dhoard --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ee84aafe6..55ce02110 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ machine: true jobs: build: machine: - image: ubuntu-2204:2023.07.2 + image: ubuntu-2204:current working_directory: ~/circleci-java steps: - run: From b29d4b85f3a63b5873253beba141659ffa6da40a Mon Sep 17 00:00:00 2001 From: MaBiConti <157379800+MaBiConti@users.noreply.github.com> Date: Thu, 29 Aug 2024 05:31:23 +0200 Subject: [PATCH 351/980] Change links on front page to be relative (#981) When the endpoint of the exporter is mapped to a subpath by a reverse proxy, absolute links would break. Relative links continue to work. Signed-off-by: Martin Bickel Co-authored-by: Karina Calma --- .../metrics/exporter/httpserver/DefaultHandler.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java index 0e6342a34..0bf3b5cc2 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java @@ -21,15 +21,15 @@ public DefaultHandler() { "\n" + "

      Prometheus Java Client

      \n" + "

      Metrics Path

      \n" + - "The metrics path is /metrics.\n" + + "The metrics path is /metrics.\n" + "

      Name Filter

      \n" + "If you want to scrape only specific metrics, use the name[] parameter like this:\n" + "\n" + "You can also use multiple name[] parameters to query multiple metrics:\n" + "\n" + "The name[] parameter can be used by the Prometheus server for scraping. Add the following snippet to your scrape job configuration in prometheus.yaml:\n" + "
      \n" +
      @@ -45,9 +45,9 @@ public DefaultHandler() {
                       "in which case the default is Prometheus protobuf.\n" +
                       "The Prometheus Java metrics library supports a debug query parameter for viewing the different formats in a Web browser:\n" +
                       "\n" +
                       "Note that the debug parameter is only for viewing different formats in a Web browser, it should not be used by the Prometheus server for scraping. The Prometheus server uses the Accept header for indicating which format it accepts.\n" +
                       "\n" +
      
      From c615b0a0c54a06955e365cebedec93934c9004e2 Mon Sep 17 00:00:00 2001
      From: Petar Heyken <48122009+pheyken@users.noreply.github.com>
      Date: Thu, 29 Aug 2024 05:49:39 +0200
      Subject: [PATCH 352/980] add support for guava instrumentation with 1.X.X
       (#979)
      
      * move files out of archive
      * add support for guava instrumentation with 1.X.X
      
      ---------
      
      Signed-off-by: Petar Heyken 
      ---
       pom.xml                                       |   1 +
       .../pom.xml                                   |  33 ++-
       .../guava/CacheMetricsCollector.java          | 203 ++++++++++++++++++
       .../guava/CacheMetricsCollectorTest.java      | 142 ++++++++++++
       .../version-rules.xml                         |   0
       .../guava/cache/CacheMetricsCollector.java    | 142 ------------
       .../cache/CacheMetricsCollectorTest.java      |  85 --------
       7 files changed, 371 insertions(+), 235 deletions(-)
       rename {simpleclient-archive/simpleclient_guava => prometheus-metrics-instrumentation-guava}/pom.xml (64%)
       create mode 100644 prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java
       create mode 100644 prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java
       rename {simpleclient-archive/simpleclient_guava => prometheus-metrics-instrumentation-guava}/version-rules.xml (100%)
       delete mode 100644 simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java
       delete mode 100644 simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java
      
      diff --git a/pom.xml b/pom.xml
      index 6db493f10..033e89331 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -66,6 +66,7 @@
               prometheus-metrics-exporter-pushgateway
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
      +        prometheus-metrics-instrumentation-guava
               prometheus-metrics-simpleclient-bridge
               
               examples
      diff --git a/simpleclient-archive/simpleclient_guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml
      similarity index 64%
      rename from simpleclient-archive/simpleclient_guava/pom.xml
      rename to prometheus-metrics-instrumentation-guava/pom.xml
      index 076491963..a4103e051 100644
      --- a/simpleclient-archive/simpleclient_guava/pom.xml
      +++ b/prometheus-metrics-instrumentation-guava/pom.xml
      @@ -5,17 +5,21 @@
           
               io.prometheus
               client_java
      -        1.0.0-beta-2-SNAPSHOT
      +        1.4.0-SNAPSHOT
           
       
      -    simpleclient_guava
      +    prometheus-metrics-instrumentation-guava
           bundle
       
      -    Prometheus Java Simpleclient guava
      +    Prometheus Metrics Instrumentation - Guava
           
      -        Metrics collector for guava based caches
      +        Instrumentation library guava based caches
           
       
      +    
      +        io.prometheus.metrics.instrumentation.guava
      +    
      +
           
               
                   The Apache Software License, Version 2.0
      @@ -30,18 +34,25 @@
                   Clint Checketts
                   checketts@gmail.com
               
      +
      +        
      +            pheyken
      +            Petar Heyken
      +            mail@petar-heyken.de
      +        
           
       
           
               
                   io.prometheus
      -            simpleclient
      +            prometheus-metrics-core
                   ${project.version}
               
               
                   com.google.guava
                   guava
      -            31.1-jre
      +            33.2.1-jre
      +            provided
               
               
       
      @@ -55,15 +66,21 @@
               
                   org.mockito
                   mockito-core
      -            4.6.1
      +            5.12.0
                   test
               
               
                   org.assertj
                   assertj-core
      -            3.23.1
      +            3.26.3
                   test
               
       
      +        
      +            io.prometheus
      +            prometheus-metrics-exposition-formats
      +            ${project.version}
      +            test
      +        
           
       
      diff --git a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java
      new file mode 100644
      index 000000000..71ffea01c
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java
      @@ -0,0 +1,203 @@
      +package io.prometheus.metrics.instrumentation.guava;
      +
      +import com.google.common.cache.Cache;
      +import com.google.common.cache.CacheStats;
      +import com.google.common.cache.LoadingCache;
      +import io.prometheus.metrics.model.registry.MultiCollector;
      +import io.prometheus.metrics.model.snapshots.CounterSnapshot;
      +import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
      +import io.prometheus.metrics.model.snapshots.Labels;
      +import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      +import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      +
      +import java.util.Arrays;
      +import java.util.List;
      +import java.util.Map;
      +import java.util.concurrent.ConcurrentHashMap;
      +import java.util.concurrent.ConcurrentMap;
      +
      +/**
      + * Collect metrics from Guava's com.google.common.cache.Cache.
      + * 

      + *

      {@code
      + *
      + * // Note that `recordStats()` is required to gather non-zero statistics
      + * Cache cache = CacheBuilder.newBuilder().recordStats().build();
      + * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      + * cacheMetrics.addCache("mycache", cache);
      + *
      + * }
      + * + * Exposed metrics are labeled with the provided cache name. + * + * With the example above, sample metric names would be: + *
      + *     guava_cache_hit_total{cache="mycache"} 10.0
      + *     guava_cache_miss_total{cache="mycache"} 3.0
      + *     guava_cache_requests_total{cache="mycache"} 13.0
      + *     guava_cache_eviction_total{cache="mycache"} 1.0
      + *     guava_cache_size{cache="mycache"} 5.0
      + * 
      + * + * Additionally, if the cache includes a loader, the following metrics would be provided: + *
      + *     guava_cache_load_failure_total{cache="mycache"} 2.0
      + *     guava_cache_loads_total{cache="mycache"} 7.0
      + *     guava_cache_load_duration_seconds_count{cache="mycache"} 7.0
      + *     guava_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
      + * 
      + * + */ +public class CacheMetricsCollector implements MultiCollector { + + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; + + protected final ConcurrentMap children = new ConcurrentHashMap<>(); + + /** + * Add or replace the cache with the given name. + *

      + * Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, Cache cache) { + children.put(cacheName, cache); + } + + /** + * Remove the cache with the given name. + *

      + * Any references to the cache are invalidated. + * + * @param cacheName cache to be removed + */ + public Cache removeCache(String cacheName) { + return children.remove(cacheName); + } + + /** + * Remove all caches. + *

      + * Any references to all caches are invalidated. + */ + public void clear(){ + children.clear(); + } + + @Override + public MetricSnapshots collect() { + final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); + final List labelNames = Arrays.asList("cache"); + + final CounterSnapshot.Builder cacheHitTotal = CounterSnapshot.builder() + .name("guava_cache_hit") + .help("Cache hit totals"); + + final CounterSnapshot.Builder cacheMissTotal = CounterSnapshot.builder() + .name("guava_cache_miss") + .help("Cache miss totals"); + + final CounterSnapshot.Builder cacheRequestsTotal = CounterSnapshot.builder() + .name("guava_cache_requests") + .help("Cache request totals"); + + final CounterSnapshot.Builder cacheEvictionTotal = CounterSnapshot.builder() + .name("guava_cache_eviction") + .help("Cache eviction totals, doesn't include manually removed entries"); + + final CounterSnapshot.Builder cacheLoadFailure = CounterSnapshot.builder() + .name("guava_cache_load_failure") + .help("Cache load failures"); + + final CounterSnapshot.Builder cacheLoadTotal = CounterSnapshot.builder() + .name("guava_cache_loads") + .help("Cache loads: both success and failures"); + + final GaugeSnapshot.Builder cacheSize = GaugeSnapshot.builder() + .name("guava_cache_size") + .help("Cache size"); + + final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() + .name("guava_cache_load_duration_seconds") + .help("Cache load duration: both success and failures"); + + for (final Map.Entry c: children.entrySet()) { + final List cacheName = Arrays.asList(c.getKey()); + final Labels labels = Labels.of(labelNames, cacheName); + + final CacheStats stats = c.getValue().stats(); + + cacheHitTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.hitCount()) + .build() + ); + + cacheMissTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.missCount()) + .build() + ); + + cacheRequestsTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.requestCount()) + .build() + ); + + cacheEvictionTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionCount()) + .build() + ); + + cacheSize.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(c.getValue().size()) + .build() + ); + + if (c.getValue() instanceof LoadingCache) { + cacheLoadFailure.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadExceptionCount()) + .build() + ); + + cacheLoadTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadCount()) + .build() + ); + + cacheLoadSummary.dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(labels) + .count(stats.loadCount()) + .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) + .build() + ); + } + } + + metricSnapshotsBuilder.metricSnapshot(cacheHitTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheMissTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheRequestsTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheEvictionTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadFailure.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheSize.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadSummary.build()); + + return metricSnapshotsBuilder.build(); + } +} diff --git a/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java new file mode 100644 index 000000000..41b3bba8d --- /dev/null +++ b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java @@ -0,0 +1,142 @@ +package io.prometheus.metrics.instrumentation.guava; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CacheMetricsCollectorTest { + + @Test + public void cacheExposesMetricsForHitMissAndEviction() { + final Cache cache = CacheBuilder.newBuilder().maximumSize(2).recordStats().build(); + + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("users", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.getIfPresent("user1"); + cache.getIfPresent("user1"); + cache.put("user1", "First User"); + cache.getIfPresent("user1"); + + // Add to cache to trigger eviction. + cache.put("user2", "Second User"); + cache.put("user3", "Third User"); + cache.put("user4", "Fourth User"); + + assertCounterMetric(registry, "guava_cache_hit", "users", 1.0); + assertCounterMetric(registry, "guava_cache_miss", "users", 2.0); + assertCounterMetric(registry, "guava_cache_requests", "users", 3.0); + assertCounterMetric(registry, "guava_cache_eviction", "users", 2.0); + + final String expected = "# TYPE guava_cache_eviction counter\n" + + "# HELP guava_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + + "guava_cache_eviction_total{cache=\"users\"} 2.0\n" + + "# TYPE guava_cache_hit counter\n" + + "# HELP guava_cache_hit Cache hit totals\n" + + "guava_cache_hit_total{cache=\"users\"} 1.0\n" + + "# TYPE guava_cache_miss counter\n" + + "# HELP guava_cache_miss Cache miss totals\n" + + "guava_cache_miss_total{cache=\"users\"} 2.0\n" + + "# TYPE guava_cache_requests counter\n" + + "# HELP guava_cache_requests Cache request totals\n" + + "guava_cache_requests_total{cache=\"users\"} 3.0\n" + + "# TYPE guava_cache_size gauge\n" + + "# HELP guava_cache_size Cache size\n" + + "guava_cache_size{cache=\"users\"} 2.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat(registry)); + } + + @SuppressWarnings("unchecked") + @Test + public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { + final CacheLoader loader = mock(CacheLoader.class); + when(loader.load(anyString())) + .thenReturn("First User") + .thenThrow(new RuntimeException("Seconds time fails")) + .thenReturn("Third User"); + + final LoadingCache cache = CacheBuilder.newBuilder().recordStats().build(loader); + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("loadingusers", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.get("user1"); + cache.get("user1"); + try { + cache.get("user2"); + } catch (Exception e) { + // ignoring. + } + cache.get("user3"); + + assertCounterMetric(registry, "guava_cache_hit", "loadingusers", 1.0); + assertCounterMetric(registry, "guava_cache_miss", "loadingusers", 3.0); + + assertCounterMetric(registry, "guava_cache_load_failure", "loadingusers", 1.0); + assertCounterMetric(registry, "guava_cache_loads", "loadingusers", 3.0); + + final SummarySnapshot.SummaryDataPointSnapshot loadDuration = (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot( + registry, + "guava_cache_load_duration_seconds", + "loadingusers" + ); + + assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getSum()).isGreaterThan(0); + } + + private void assertCounterMetric(PrometheusRegistry registry, String name, String cacheName, double value) { + final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = + (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); + + assertEquals(value, dataPointSnapshot.getValue(), 0); + } + + private DataPointSnapshot getDataPointSnapshot(PrometheusRegistry registry, String name, String cacheName) + { + final Labels labels = Labels.of(new String[]{"cache"}, new String[]{cacheName}); + + return registry.scrape(name::equals).stream() + .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) + .filter(dataPoint -> dataPoint.getLabels().equals(labels)) + .findFirst() + .get(); + } + + private String convertToOpenMetricsFormat(PrometheusRegistry registry) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, registry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/simpleclient-archive/simpleclient_guava/version-rules.xml b/prometheus-metrics-instrumentation-guava/version-rules.xml similarity index 100% rename from simpleclient-archive/simpleclient_guava/version-rules.xml rename to prometheus-metrics-instrumentation-guava/version-rules.xml diff --git a/simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java b/simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java deleted file mode 100644 index 5ed0276bb..000000000 --- a/simpleclient-archive/simpleclient_guava/src/main/java/io/prometheus/client/guava/cache/CacheMetricsCollector.java +++ /dev/null @@ -1,142 +0,0 @@ -package io.prometheus.client.guava.cache; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheStats; -import com.google.common.cache.LoadingCache; -import io.prometheus.client.Collector; -import io.prometheus.client.CounterMetricFamily; -import io.prometheus.client.GaugeMetricFamily; -import io.prometheus.client.SummaryMetricFamily; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * Collect metrics from Guava's com.google.common.cache.Cache. - *

      - *

      {@code
      - *
      - * // Note that `recordStats()` is required to gather non-zero statistics
      - * Cache cache = CacheBuilder.newBuilder().recordStats().build();
      - * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      - * cacheMetrics.addCache("mycache", cache);
      - *
      - * }
      - * - * Exposed metrics are labeled with the provided cache name. - * - * With the example above, sample metric names would be: - *
      - *     guava_cache_hit_total{cache="mycache"} 10.0
      - *     guava_cache_miss_total{cache="mycache"} 3.0
      - *     guava_cache_requests_total{cache="mycache"} 13.0
      - *     guava_cache_eviction_total{cache="mycache"} 1.0
      - *     guava_cache_size{cache="mycache"} 5.0
      - * 
      - * - * Additionally if the cache includes a loader, the following metrics would be provided: - *
      - *     guava_cache_load_failure_total{cache="mycache"} 2.0
      - *     guava_cache_loads_total{cache="mycache"} 7.0
      - *     guava_cache_load_duration_seconds_count{cache="mycache"} 7.0
      - *     guava_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
      - * 
      - * - */ -public class CacheMetricsCollector extends Collector { - - protected final ConcurrentMap children = new ConcurrentHashMap(); - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, Cache cache) { - children.put(cacheName, cache); - } - - /** - * Remove the cache with the given name. - *

      - * Any references to the cache are invalidated. - * - * @param cacheName cache to be removed - */ - public Cache removeCache(String cacheName) { - return children.remove(cacheName); - } - - /** - * Remove all caches. - *

      - * Any references to all caches are invalidated. - */ - public void clear(){ - children.clear(); - } - - @Override - public List collect() { - List mfs = new ArrayList(); - List labelNames = Arrays.asList("cache"); - - CounterMetricFamily cacheHitTotal = new CounterMetricFamily("guava_cache_hit_total", - "Cache hit totals", labelNames); - mfs.add(cacheHitTotal); - - CounterMetricFamily cacheMissTotal = new CounterMetricFamily("guava_cache_miss_total", - "Cache miss totals", labelNames); - mfs.add(cacheMissTotal); - - CounterMetricFamily cacheRequestsTotal = new CounterMetricFamily("guava_cache_requests_total", - "Cache request totals, hits + misses", labelNames); - mfs.add(cacheRequestsTotal); - - CounterMetricFamily cacheEvictionTotal = new CounterMetricFamily("guava_cache_eviction_total", - "Cache eviction totals, doesn't include manually removed entries", labelNames); - mfs.add(cacheEvictionTotal); - - CounterMetricFamily cacheLoadFailure = new CounterMetricFamily("guava_cache_load_failure_total", - "Cache load failures", labelNames); - mfs.add(cacheLoadFailure); - - CounterMetricFamily cacheLoadTotal = new CounterMetricFamily("guava_cache_loads_total", - "Cache loads: both success and failures", labelNames); - mfs.add(cacheLoadTotal); - - GaugeMetricFamily cacheSize = new GaugeMetricFamily("guava_cache_size", - "Cache size", labelNames); - mfs.add(cacheSize); - - SummaryMetricFamily cacheLoadSummary = new SummaryMetricFamily("guava_cache_load_duration_seconds", - "Cache load duration: both success and failures", labelNames); - mfs.add(cacheLoadSummary); - - for(Map.Entry c: children.entrySet()) { - List cacheName = Arrays.asList(c.getKey()); - CacheStats stats = c.getValue().stats(); - - cacheHitTotal.addMetric(cacheName, stats.hitCount()); - cacheMissTotal.addMetric(cacheName, stats.missCount()); - cacheRequestsTotal.addMetric(cacheName, stats.requestCount()); - cacheEvictionTotal.addMetric(cacheName, stats.evictionCount()); - cacheSize.addMetric(cacheName, c.getValue().size()); - - if(c.getValue() instanceof LoadingCache) { - cacheLoadFailure.addMetric(cacheName, stats.loadExceptionCount()); - cacheLoadTotal.addMetric(cacheName, stats.loadCount()); - - cacheLoadSummary.addMetric(cacheName, stats.loadCount(), stats.totalLoadTime() / Collector.NANOSECONDS_PER_SECOND); - } - } - return mfs; - } -} diff --git a/simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java b/simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java deleted file mode 100644 index dab30b9fb..000000000 --- a/simpleclient-archive/simpleclient_guava/src/test/java/io/prometheus/client/guava/cache/CacheMetricsCollectorTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package io.prometheus.client.guava.cache; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import io.prometheus.client.CollectorRegistry; -import org.junit.Test; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class CacheMetricsCollectorTest { - - @Test - public void cacheExposesMetricsForHitMissAndEviction() throws Exception { - Cache cache = CacheBuilder.newBuilder().maximumSize(2).recordStats().build(); - CollectorRegistry registry = new CollectorRegistry(); - - CacheMetricsCollector collector = new CacheMetricsCollector().register(registry); - collector.addCache("users", cache); - - cache.getIfPresent("user1"); - cache.getIfPresent("user1"); - cache.put("user1", "First User"); - cache.getIfPresent("user1"); - - // Add to cache to trigger eviction. - cache.put("user2", "Second User"); - cache.put("user3", "Third User"); - cache.put("user4", "Fourth User"); - - assertMetric(registry, "guava_cache_hit_total", "users", 1.0); - assertMetric(registry, "guava_cache_miss_total", "users", 2.0); - assertMetric(registry, "guava_cache_requests_total", "users", 3.0); - assertMetric(registry, "guava_cache_eviction_total", "users", 2.0); - } - - @SuppressWarnings("unchecked") - @Test - public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { - CacheLoader loader = mock(CacheLoader.class); - when(loader.load(anyString())) - .thenReturn("First User") - .thenThrow(new RuntimeException("Seconds time fails")) - .thenReturn("Third User"); - - LoadingCache cache = CacheBuilder.newBuilder().recordStats().build(loader); - CollectorRegistry registry = new CollectorRegistry(); - CacheMetricsCollector collector = new CacheMetricsCollector().register(registry); - collector.addCache("loadingusers", cache); - - cache.get("user1"); - cache.get("user1"); - try{ - cache.get("user2"); - } catch (Exception e) { - // ignoring. - } - cache.get("user3"); - - assertMetric(registry, "guava_cache_hit_total", "loadingusers", 1.0); - assertMetric(registry, "guava_cache_miss_total", "loadingusers", 3.0); - - assertMetric(registry, "guava_cache_load_failure_total", "loadingusers", 1.0); - assertMetric(registry, "guava_cache_loads_total", "loadingusers", 3.0); - - assertMetric(registry, "guava_cache_load_duration_seconds_count", "loadingusers", 3.0); - assertMetricGreatThan(registry, "guava_cache_load_duration_seconds_sum", "loadingusers", 0.0); - } - - - private void assertMetric(CollectorRegistry registry, String name, String cacheName, double value) { - assertThat(registry.getSampleValue(name, new String[]{"cache"}, new String[]{cacheName})).isEqualTo(value); - } - - - private void assertMetricGreatThan(CollectorRegistry registry, String name, String cacheName, double value) { - assertThat(registry.getSampleValue(name, new String[]{"cache"}, new String[]{cacheName})).isGreaterThan(value); - } - - -} From ec56b2c43b72f5b998ad11919911686afe49408d Mon Sep 17 00:00:00 2001 From: Petar Heyken <48122009+pheyken@users.noreply.github.com> Date: Sat, 31 Aug 2024 03:14:05 +0200 Subject: [PATCH 353/980] add support for caffeine instrumentation with 1.X.X (#983) * add support for caffeine instrumentation with 1.X.X --------- Signed-off-by: Petar Heyken --- pom.xml | 1 + .../pom.xml | 34 ++- .../caffeine/CacheMetricsCollector.java | 232 ++++++++++++++++++ .../caffeine/CacheMetricsCollectorTest.java | 153 ++++++++++++ .../version-rules.xml | 0 .../cache/caffeine/CacheMetricsCollector.java | 165 ------------- .../caffeine/CacheMetricsCollectorTest.java | 93 ------- 7 files changed, 412 insertions(+), 266 deletions(-) rename {simpleclient-archive/simpleclient_caffeine => prometheus-metrics-instrumentation-caffeine}/pom.xml (64%) create mode 100644 prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java create mode 100644 prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java rename {simpleclient-archive/simpleclient_caffeine => prometheus-metrics-instrumentation-caffeine}/version-rules.xml (100%) delete mode 100644 simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java delete mode 100644 simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java diff --git a/pom.xml b/pom.xml index 033e89331..52953fbc9 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry prometheus-metrics-exporter-pushgateway + prometheus-metrics-instrumentation-caffeine prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-instrumentation-guava diff --git a/simpleclient-archive/simpleclient_caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml similarity index 64% rename from simpleclient-archive/simpleclient_caffeine/pom.xml rename to prometheus-metrics-instrumentation-caffeine/pom.xml index 73529822b..a1b560251 100644 --- a/simpleclient-archive/simpleclient_caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -5,17 +5,21 @@ io.prometheus client_java - 1.0.0-beta-2-SNAPSHOT + 1.4.0-SNAPSHOT - simpleclient_caffeine + prometheus-metrics-instrumentation-caffeine bundle - Prometheus Java Simpleclient Caffeine + Prometheus Metrics Instrumentation - Caffeine - Metrics collector for caffeine based caches + Instrumentation library for caffeine based caches + + io.prometheus.metrics.instrumentation.caffeine + + The Apache Software License, Version 2.0 @@ -30,18 +34,25 @@ Clint Checketts checketts@gmail.com + + + pheyken + Petar Heyken + mail@petar-heyken.de + io.prometheus - simpleclient + prometheus-metrics-core ${project.version} com.github.ben-manes.caffeine caffeine - 3.1.1 + 3.1.8 + provided @@ -55,13 +66,20 @@ org.mockito mockito-core - 4.6.1 + 5.12.0 test org.assertj assertj-core - 3.23.1 + 3.26.3 + test + + + + io.prometheus + prometheus-metrics-exposition-formats + ${project.version} test diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java new file mode 100644 index 000000000..985a15711 --- /dev/null +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java @@ -0,0 +1,232 @@ +package io.prometheus.metrics.instrumentation.caffeine; + +import com.github.benmanes.caffeine.cache.AsyncCache; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.stats.CacheStats; +import io.prometheus.metrics.model.registry.MultiCollector; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + + +/** + * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache. + *

      + *

      {@code
      + *
      + * // Note that `recordStats()` is required to gather non-zero statistics
      + * Cache cache = Caffeine.newBuilder().recordStats().build();
      + * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      + * cacheMetrics.addCache("mycache", cache);
      + *
      + * }
      + * + * Exposed metrics are labeled with the provided cache name. + * + * With the example above, sample metric names would be: + *
      + *     caffeine_cache_hit_total{cache="mycache"} 10.0
      + *     caffeine_cache_miss_total{cache="mycache"} 3.0
      + *     caffeine_cache_requests_total{cache="mycache"} 13.0
      + *     caffeine_cache_eviction_total{cache="mycache"} 1.0
      + *     caffeine_cache_estimated_size{cache="mycache"} 5.0
      + * 
      + * + * Additionally, if the cache includes a loader, the following metrics would be provided: + *
      + *     caffeine_cache_load_failure_total{cache="mycache"} 2.0
      + *     caffeine_cache_loads_total{cache="mycache"} 7.0
      + *     caffeine_cache_load_duration_seconds_count{cache="mycache"} 7.0
      + *     caffeine_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
      + * 
      + * + */ +public class CacheMetricsCollector implements MultiCollector { + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; + + protected final ConcurrentMap children = new ConcurrentHashMap(); + + /** + * Add or replace the cache with the given name. + *

      + * Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, Cache cache) { + children.put(cacheName, cache); + } + + /** + * Add or replace the cache with the given name. + *

      + * Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, AsyncCache cache) { + children.put(cacheName, cache.synchronous()); + } + + /** + * Remove the cache with the given name. + *

      + * Any references to the cache are invalidated. + * + * @param cacheName cache to be removed + */ + public Cache removeCache(String cacheName) { + return children.remove(cacheName); + } + + /** + * Remove all caches. + *

      + * Any references to all caches are invalidated. + */ + public void clear(){ + children.clear(); + } + + @Override + public MetricSnapshots collect() { + final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); + final List labelNames = Arrays.asList("cache"); + + final CounterSnapshot.Builder cacheHitTotal = CounterSnapshot.builder() + .name("caffeine_cache_hit") + .help("Cache hit totals"); + + final CounterSnapshot.Builder cacheMissTotal = CounterSnapshot.builder() + .name("caffeine_cache_miss") + .help("Cache miss totals"); + + final CounterSnapshot.Builder cacheRequestsTotal = CounterSnapshot.builder() + .name("caffeine_cache_requests") + .help("Cache request totals, hits + misses"); + + final CounterSnapshot.Builder cacheEvictionTotal = CounterSnapshot.builder() + .name("caffeine_cache_eviction") + .help("Cache eviction totals, doesn't include manually removed entries"); + + final GaugeSnapshot.Builder cacheEvictionWeight = GaugeSnapshot.builder() + .name("caffeine_cache_eviction_weight") + .help("Cache eviction weight"); + + final CounterSnapshot.Builder cacheLoadFailure = CounterSnapshot.builder() + .name("caffeine_cache_load_failure") + .help("Cache load failures"); + + final CounterSnapshot.Builder cacheLoadTotal = CounterSnapshot.builder() + .name("caffeine_cache_loads") + .help("Cache loads: both success and failures"); + + final GaugeSnapshot.Builder cacheSize = GaugeSnapshot.builder() + .name("caffeine_cache_estimated_size") + .help("Estimated cache size"); + + final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() + .name("caffeine_cache_load_duration_seconds") + .help("Cache load duration: both success and failures"); + + for (final Map.Entry c: children.entrySet()) { + final List cacheName = Arrays.asList(c.getKey()); + final Labels labels = Labels.of(labelNames, cacheName); + + final CacheStats stats = c.getValue().stats(); + + try { + cacheEvictionWeight.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionWeight()) + .build() + ); + } catch (Exception e) { + // EvictionWeight metric is unavailable, newer version of Caffeine is needed. + } + + cacheHitTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.hitCount()) + .build() + ); + + cacheMissTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.missCount()) + .build() + ); + + cacheRequestsTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.requestCount()) + .build() + ); + + cacheEvictionTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionCount()) + .build() + ); + + cacheSize.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(c.getValue().estimatedSize()) + .build() + ); + + if (c.getValue() instanceof LoadingCache) { + cacheLoadFailure.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadFailureCount()) + .build() + ); + + cacheLoadTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadCount()) + .build() + ); + + cacheLoadSummary.dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(labels) + .count(stats.loadCount()) + .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) + .build() + ); + } + } + + return metricSnapshotsBuilder + .metricSnapshot(cacheHitTotal.build()) + .metricSnapshot(cacheMissTotal.build()) + .metricSnapshot(cacheRequestsTotal.build()) + .metricSnapshot(cacheEvictionTotal.build()) + .metricSnapshot(cacheEvictionWeight.build()) + .metricSnapshot(cacheLoadFailure.build()) + .metricSnapshot(cacheLoadTotal.build()) + .metricSnapshot(cacheSize.build()) + .metricSnapshot(cacheLoadSummary.build()) + .build(); + } +} diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java new file mode 100644 index 000000000..86f7ed185 --- /dev/null +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -0,0 +1,153 @@ +package io.prometheus.metrics.instrumentation.caffeine; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.CacheLoader; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.Executor; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class CacheMetricsCollectorTest { + + @Test + public void cacheExposesMetricsForHitMissAndEviction() { + final Cache cache = Caffeine.newBuilder().maximumSize(2).recordStats().executor(new Executor() { + @Override + public void execute(Runnable command) { + // Run cleanup in same thread, to remove async behavior with evictions + command.run(); + } + }).build(); + + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("users", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.getIfPresent("user1"); + cache.getIfPresent("user1"); + cache.put("user1", "First User"); + cache.getIfPresent("user1"); + + // Add to cache to trigger eviction. + cache.put("user2", "Second User"); + cache.put("user3", "Third User"); + cache.put("user4", "Fourth User"); + + assertCounterMetric(registry, "caffeine_cache_hit", "users", 1.0); + assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0); + assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0); + assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0); + + final String expected = "# TYPE caffeine_cache_estimated_size gauge\n" + + "# HELP caffeine_cache_estimated_size Estimated cache size\n" + + "caffeine_cache_estimated_size{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_eviction counter\n" + + "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_eviction_weight gauge\n" + + "# HELP caffeine_cache_eviction_weight Cache eviction weight\n" + + "caffeine_cache_eviction_weight{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_hit counter\n" + + "# HELP caffeine_cache_hit Cache hit totals\n" + + "caffeine_cache_hit_total{cache=\"users\"} 1.0\n" + + "# TYPE caffeine_cache_miss counter\n" + + "# HELP caffeine_cache_miss Cache miss totals\n" + + "caffeine_cache_miss_total{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_requests counter\n" + + "# HELP caffeine_cache_requests Cache request totals, hits + misses\n" + + "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat(registry)); + } + + @SuppressWarnings("unchecked") + @Test + public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { + final CacheLoader loader = mock(CacheLoader.class); + when(loader.load(anyString())) + .thenReturn("First User") + .thenThrow(new RuntimeException("Seconds time fails")) + .thenReturn("Third User"); + + final LoadingCache cache = Caffeine.newBuilder().recordStats().build(loader); + final CacheMetricsCollector collector = new CacheMetricsCollector(); + + collector.addCache("loadingusers", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.get("user1"); + cache.get("user1"); + try { + cache.get("user2"); + } catch (Exception e) { + // ignoring. + } + cache.get("user3"); + + assertCounterMetric(registry, "caffeine_cache_hit", "loadingusers", 1.0); + assertCounterMetric(registry, "caffeine_cache_miss", "loadingusers", 3.0); + + assertCounterMetric(registry, "caffeine_cache_load_failure", "loadingusers", 1.0); + assertCounterMetric(registry, "caffeine_cache_loads", "loadingusers", 3.0); + + final SummarySnapshot.SummaryDataPointSnapshot loadDuration = (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot( + registry, + "caffeine_cache_load_duration_seconds", + "loadingusers" + ); + + assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getSum()).isGreaterThan(0); + } + + private void assertCounterMetric(PrometheusRegistry registry, String name, String cacheName, double value) { + final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = + (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); + + assertEquals(value, dataPointSnapshot.getValue(), 0); + } + + private DataPointSnapshot getDataPointSnapshot(PrometheusRegistry registry, String name, String cacheName) + { + final Labels labels = Labels.of(new String[]{"cache"}, new String[]{cacheName}); + + return registry.scrape(name::equals).stream() + .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) + .filter(dataPoint -> dataPoint.getLabels().equals(labels)) + .findFirst() + .get(); + } + + private String convertToOpenMetricsFormat(PrometheusRegistry registry) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, registry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/simpleclient-archive/simpleclient_caffeine/version-rules.xml b/prometheus-metrics-instrumentation-caffeine/version-rules.xml similarity index 100% rename from simpleclient-archive/simpleclient_caffeine/version-rules.xml rename to prometheus-metrics-instrumentation-caffeine/version-rules.xml diff --git a/simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java b/simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java deleted file mode 100644 index bc48dd86f..000000000 --- a/simpleclient-archive/simpleclient_caffeine/src/main/java/io/prometheus/client/cache/caffeine/CacheMetricsCollector.java +++ /dev/null @@ -1,165 +0,0 @@ -package io.prometheus.client.cache.caffeine; - -import com.github.benmanes.caffeine.cache.AsyncCache; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.LoadingCache; -import com.github.benmanes.caffeine.cache.stats.CacheStats; -import io.prometheus.client.Collector; -import io.prometheus.client.CounterMetricFamily; -import io.prometheus.client.GaugeMetricFamily; -import io.prometheus.client.SummaryMetricFamily; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - - -/** - * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache. - *

      - *

      {@code
      - *
      - * // Note that `recordStats()` is required to gather non-zero statistics
      - * Cache cache = Caffeine.newBuilder().recordStats().build();
      - * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      - * cacheMetrics.addCache("mycache", cache);
      - *
      - * }
      - * - * Exposed metrics are labeled with the provided cache name. - * - * With the example above, sample metric names would be: - *
      - *     caffeine_cache_hit_total{cache="mycache"} 10.0
      - *     caffeine_cache_miss_total{cache="mycache"} 3.0
      - *     caffeine_cache_requests_total{cache="mycache"} 13.0
      - *     caffeine_cache_eviction_total{cache="mycache"} 1.0
      - *     caffeine_cache_estimated_size{cache="mycache"} 5.0
      - * 
      - * - * Additionally if the cache includes a loader, the following metrics would be provided: - *
      - *     caffeine_cache_load_failure_total{cache="mycache"} 2.0
      - *     caffeine_cache_loads_total{cache="mycache"} 7.0
      - *     caffeine_cache_load_duration_seconds_count{cache="mycache"} 7.0
      - *     caffeine_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
      - * 
      - * - */ -public class CacheMetricsCollector extends Collector { - protected final ConcurrentMap children = new ConcurrentHashMap(); - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, Cache cache) { - children.put(cacheName, cache); - } - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, AsyncCache cache) { - children.put(cacheName, cache.synchronous()); - } - - /** - * Remove the cache with the given name. - *

      - * Any references to the cache are invalidated. - * - * @param cacheName cache to be removed - */ - public Cache removeCache(String cacheName) { - return children.remove(cacheName); - } - - /** - * Remove all caches. - *

      - * Any references to all caches are invalidated. - */ - public void clear(){ - children.clear(); - } - - @Override - public List collect() { - List mfs = new ArrayList(); - List labelNames = Arrays.asList("cache"); - - CounterMetricFamily cacheHitTotal = new CounterMetricFamily("caffeine_cache_hit_total", - "Cache hit totals", labelNames); - mfs.add(cacheHitTotal); - - CounterMetricFamily cacheMissTotal = new CounterMetricFamily("caffeine_cache_miss_total", - "Cache miss totals", labelNames); - mfs.add(cacheMissTotal); - - CounterMetricFamily cacheRequestsTotal = new CounterMetricFamily("caffeine_cache_requests_total", - "Cache request totals, hits + misses", labelNames); - mfs.add(cacheRequestsTotal); - - CounterMetricFamily cacheEvictionTotal = new CounterMetricFamily("caffeine_cache_eviction_total", - "Cache eviction totals, doesn't include manually removed entries", labelNames); - mfs.add(cacheEvictionTotal); - - GaugeMetricFamily cacheEvictionWeight = new GaugeMetricFamily("caffeine_cache_eviction_weight", - "Cache eviction weight", labelNames); - mfs.add(cacheEvictionWeight); - - CounterMetricFamily cacheLoadFailure = new CounterMetricFamily("caffeine_cache_load_failure_total", - "Cache load failures", labelNames); - mfs.add(cacheLoadFailure); - - CounterMetricFamily cacheLoadTotal = new CounterMetricFamily("caffeine_cache_loads_total", - "Cache loads: both success and failures", labelNames); - mfs.add(cacheLoadTotal); - - GaugeMetricFamily cacheSize = new GaugeMetricFamily("caffeine_cache_estimated_size", - "Estimated cache size", labelNames); - mfs.add(cacheSize); - - SummaryMetricFamily cacheLoadSummary = new SummaryMetricFamily("caffeine_cache_load_duration_seconds", - "Cache load duration: both success and failures", labelNames); - mfs.add(cacheLoadSummary); - - for(Map.Entry c: children.entrySet()) { - List cacheName = Arrays.asList(c.getKey()); - CacheStats stats = c.getValue().stats(); - - try{ - cacheEvictionWeight.addMetric(cacheName, stats.evictionWeight()); - } catch (Exception e) { - // EvictionWeight metric is unavailable, newer version of Caffeine is needed. - } - - cacheHitTotal.addMetric(cacheName, stats.hitCount()); - cacheMissTotal.addMetric(cacheName, stats.missCount()); - cacheRequestsTotal.addMetric(cacheName, stats.requestCount()); - cacheEvictionTotal.addMetric(cacheName, stats.evictionCount()); - cacheSize.addMetric(cacheName, c.getValue().estimatedSize()); - - if(c.getValue() instanceof LoadingCache) { - cacheLoadFailure.addMetric(cacheName, stats.loadFailureCount()); - cacheLoadTotal.addMetric(cacheName, stats.loadCount()); - - cacheLoadSummary.addMetric(cacheName, stats.loadCount(), stats.totalLoadTime() / Collector.NANOSECONDS_PER_SECOND); - } - } - return mfs; - } -} diff --git a/simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java b/simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java deleted file mode 100644 index 65429f337..000000000 --- a/simpleclient-archive/simpleclient_caffeine/src/test/java/io/prometheus/client/cache/caffeine/CacheMetricsCollectorTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package io.prometheus.client.cache.caffeine; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.CacheLoader; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; -import io.prometheus.client.CollectorRegistry; -import org.junit.Test; - -import java.util.concurrent.Executor; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class CacheMetricsCollectorTest { - - @Test - public void cacheExposesMetricsForHitMissAndEviction() throws Exception { - Cache cache = Caffeine.newBuilder().maximumSize(2).recordStats().executor(new Executor() { - @Override - public void execute(Runnable command) { - // Run cleanup in same thread, to remove async behavior with evictions - command.run(); - } - }).build(); - CollectorRegistry registry = new CollectorRegistry(); - - CacheMetricsCollector collector = new CacheMetricsCollector().register(registry); - collector.addCache("users", cache); - - cache.getIfPresent("user1"); - cache.getIfPresent("user1"); - cache.put("user1", "First User"); - cache.getIfPresent("user1"); - - // Add to cache to trigger eviction. - cache.put("user2", "Second User"); - cache.put("user3", "Third User"); - cache.put("user4", "Fourth User"); - - assertMetric(registry, "caffeine_cache_hit_total", "users", 1.0); - assertMetric(registry, "caffeine_cache_miss_total", "users", 2.0); - assertMetric(registry, "caffeine_cache_requests_total", "users", 3.0); - assertMetric(registry, "caffeine_cache_eviction_total", "users", 2.0); - } - - - @SuppressWarnings("unchecked") - @Test - public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { - CacheLoader loader = mock(CacheLoader.class); - when(loader.load(anyString())) - .thenReturn("First User") - .thenThrow(new RuntimeException("Seconds time fails")) - .thenReturn("Third User"); - - LoadingCache cache = Caffeine.newBuilder().recordStats().build(loader); - CollectorRegistry registry = new CollectorRegistry(); - CacheMetricsCollector collector = new CacheMetricsCollector().register(registry); - collector.addCache("loadingusers", cache); - - cache.get("user1"); - cache.get("user1"); - try { - cache.get("user2"); - } catch (Exception e) { - // ignoring. - } - cache.get("user3"); - - assertMetric(registry, "caffeine_cache_hit_total", "loadingusers", 1.0); - assertMetric(registry, "caffeine_cache_miss_total", "loadingusers", 3.0); - - assertMetric(registry, "caffeine_cache_load_failure_total", "loadingusers", 1.0); - assertMetric(registry, "caffeine_cache_loads_total", "loadingusers", 3.0); - - assertMetric(registry, "caffeine_cache_load_duration_seconds_count", "loadingusers", 3.0); - assertMetricGreatThan(registry, "caffeine_cache_load_duration_seconds_sum", "loadingusers", 0.0); - } - - private void assertMetric(CollectorRegistry registry, String name, String cacheName, double value) { - assertThat(registry.getSampleValue(name, new String[]{"cache"}, new String[]{cacheName})).isEqualTo(value); - } - - - private void assertMetricGreatThan(CollectorRegistry registry, String name, String cacheName, double value) { - assertThat(registry.getSampleValue(name, new String[]{"cache"}, new String[]{cacheName})).isGreaterThan(value); - } - - -} From b2db7094ce276bc534e60a843baf473c56003b03 Mon Sep 17 00:00:00 2001 From: Iacopo Date: Fri, 6 Sep 2024 20:42:25 -0700 Subject: [PATCH 354/980] Nullify noLabels in StatefulMetric during clear() to prevent no-labels increase to stop working (#972) Signed-off-by: Iacopo Pace Co-authored-by: Iacopo Pace --- .../io/prometheus/metrics/core/metrics/StatefulMetric.java | 1 + .../prometheus/metrics/core/metrics/StatefulMetricTest.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 43555167a..44f6cc57a 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -114,6 +114,7 @@ public void remove(String... labelValues) { */ public void clear() { data.clear(); + noLabels = null; } protected abstract T newDataPoint(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index b1c45fa80..dd2c4355a 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -60,5 +60,10 @@ public void testClearNoLabels() { // No labels is always present, but as no value has been observed after clear() the value should be 0.0 Assert.assertEquals(1, counter.collect().getDataPoints().size()); Assert.assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + + // Making inc() works correctly after clear() + counter.inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); } } From 8a24bdea2eef88c7655cb9173db9d058fbc780a8 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Sat, 7 Sep 2024 05:48:56 +0200 Subject: [PATCH 355/980] Add abstract build method to MetricSnapshot.Builder (#969) Signed-off-by: Mickael Maison --- .../io/prometheus/metrics/model/snapshots/CounterSnapshot.java | 1 + .../io/prometheus/metrics/model/snapshots/GaugeSnapshot.java | 3 ++- .../prometheus/metrics/model/snapshots/HistogramSnapshot.java | 1 + .../io/prometheus/metrics/model/snapshots/InfoSnapshot.java | 1 + .../io/prometheus/metrics/model/snapshots/MetricSnapshot.java | 2 ++ .../prometheus/metrics/model/snapshots/StateSetSnapshot.java | 1 + .../io/prometheus/metrics/model/snapshots/SummarySnapshot.java | 1 + .../io/prometheus/metrics/model/snapshots/UnknownSnapshot.java | 1 + 8 files changed, 10 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java index e62aeb9f8..4aceea6bd 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -139,6 +139,7 @@ public Builder dataPoint(CounterDataPointSnapshot dataPoint) { return this; } + @Override public CounterSnapshot build() { return new CounterSnapshot(buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java index f69b8d2a6..2600214aa 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java @@ -118,13 +118,14 @@ private Builder() { } /** - * Add a data point. This can be alled multiple times to add multiple data points. + * Add a data point. This can be called multiple times to add multiple data points. */ public Builder dataPoint(GaugeDataPointSnapshot dataPoint) { dataPoints.add(dataPoint); return this; } + @Override public GaugeSnapshot build() { return new GaugeSnapshot(buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index 2e66c1a25..0737f7368 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -389,6 +389,7 @@ public Builder gaugeHistogram(boolean isGaugeHistogram) { return this; } + @Override public HistogramSnapshot build() { return new HistogramSnapshot(isGaugeHistogram, buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java index e24747181..5d3890c0e 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -95,6 +95,7 @@ public Builder unit(Unit unit) { throw new IllegalArgumentException("Info metric cannot have a unit."); } + @Override public InfoSnapshot build() { return new InfoSnapshot(buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java index 2405b9622..dcf41bc09 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -76,6 +76,8 @@ public T unit(Unit unit) { return self(); } + public abstract MetricSnapshot build(); + protected MetricMetadata buildMetadata() { return new MetricMetadata(name, help, unit); } 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 2a6094354..ddcc94bc2 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 @@ -219,6 +219,7 @@ public Builder unit(Unit unit) { throw new IllegalArgumentException("StateSet metric cannot have a unit."); } + @Override public StateSetSnapshot build() { return new StateSetSnapshot(buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java index 16682dbae..40a31f85a 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java @@ -127,6 +127,7 @@ public Builder dataPoint(SummaryDataPointSnapshot data) { return this; } + @Override public SummarySnapshot build() { return new SummarySnapshot(buildMetadata(), dataPoints); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java index 60873013a..70cf07326 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -126,6 +126,7 @@ public Builder dataPoint(UnknownDataPointSnapshot data) { return this; } + @Override public UnknownSnapshot build() { return new UnknownSnapshot(buildMetadata(), dataPoints); } From 72b79d4aea750d14b018ae278be71bbcae884129 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Mon, 9 Sep 2024 15:25:38 +0200 Subject: [PATCH 356/980] Fix PrometheusNaming.sanitizeMetricName() methods (#975) Signed-off-by: Mickael Maison --- .../model/snapshots/PrometheusNaming.java | 5 ++--- .../model/snapshots/PrometheusNamingTest.java | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java index 06e004398..21c162632 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java @@ -157,7 +157,7 @@ public static String sanitizeMetricName(String metricName) { * as a suffix if the unit is not {@code null}. */ public static String sanitizeMetricName(String metricName, Unit unit) { - String result = sanitizeLabelName(metricName); + String result = sanitizeMetricName(metricName); if (unit != null) { if (!result.endsWith("_" + unit) && !result.endsWith("." + unit)) { result += "_" + unit; @@ -224,8 +224,7 @@ private static String replaceIllegalCharsInMetricName(String name) { char[] sanitized = new char[length]; for (int i = 0; i < length; i++) { char ch = name.charAt(i); - if (ch == ':' || - ch == '.' || + if (ch == '.' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (i > 0 && ch >= '0' && ch <= '9')) { diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java index 3a7788743..9631f9df3 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java @@ -10,7 +10,7 @@ public class PrometheusNamingTest { @Test public void testSanitizeMetricName() { Assert.assertEquals("_abc_def", prometheusName(sanitizeMetricName("0abc.def"))); - Assert.assertEquals("___ab_:c0", prometheusName(sanitizeMetricName("___ab.:c0"))); + Assert.assertEquals("___ab__c0", prometheusName(sanitizeMetricName("___ab.:c0"))); Assert.assertEquals("my_prefix_my_metric", sanitizeMetricName("my_prefix/my_metric")); Assert.assertEquals("my_counter", prometheusName(sanitizeMetricName("my_counter_total"))); Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); @@ -21,6 +21,20 @@ public void testSanitizeMetricName() { Assert.assertEquals("total", sanitizeMetricName("total")); } + @Test + public void testSanitizeMetricNameWithUnit() { + Assert.assertEquals("_abc_def_" + Unit.RATIO, prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO))); + Assert.assertEquals("___ab__c0_" + Unit.RATIO, prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO))); + Assert.assertEquals("my_prefix_my_metric_" + Unit.RATIO, sanitizeMetricName("my_prefix/my_metric", Unit.RATIO)); + Assert.assertEquals("my_counter_" + Unit.RATIO, prometheusName(sanitizeMetricName("my_counter_total", Unit.RATIO))); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm_info", Unit.RATIO)); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); + Assert.assertEquals("a.b_" + Unit.RATIO, sanitizeMetricName("a.b", Unit.RATIO)); + Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("_total", Unit.RATIO)); + Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("total", Unit.RATIO)); + } + @Test public void testSanitizeLabelName() { Assert.assertEquals("_abc_def", prometheusName(sanitizeLabelName("0abc.def"))); From 4ce0d1513b7b211285478e77b11375da2aecd09d Mon Sep 17 00:00:00 2001 From: Andrey Burov <31802895+burov4j@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:00:36 +0300 Subject: [PATCH 357/980] additional improve MetricSnapshots.Builder performance (#985) Signed-off-by: Andrey Burov --- .../metrics/model/snapshots/MetricSnapshots.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java index 83d932f87..a4865acb9 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -3,8 +3,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.stream.Stream; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; @@ -74,6 +76,7 @@ public static Builder builder() { public static class Builder { private final List snapshots = new ArrayList<>(); + private final Set prometheusNames = new HashSet<>(); private Builder() { } @@ -83,12 +86,7 @@ public boolean containsMetricName(String name) { return false; } String prometheusName = prometheusName(name); - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getPrometheusName().equals(prometheusName)) { - return true; - } - } - return false; + return prometheusNames.contains(prometheusName); } /** @@ -96,6 +94,7 @@ public boolean containsMetricName(String name) { */ public Builder metricSnapshot(MetricSnapshot snapshot) { snapshots.add(snapshot); + prometheusNames.add(snapshot.getMetadata().getPrometheusName()); return this; } From 14c09083e75b807837d5b1da80688c01d0ff1b73 Mon Sep 17 00:00:00 2001 From: Mickael Maison Date: Mon, 30 Sep 2024 16:37:07 +0200 Subject: [PATCH 358/980] Make JvmMetrics.register idempotent with the default registry (#987) * Make JvmMetrics.register idempotent with the default registry Signed-off-by: Mickael Maison * Make JvmMetrics.register() methods idempotent Signed-off-by: Mickael Maison --------- Signed-off-by: Mickael Maison --- .../instrumentation/jvm/JvmMetrics.java | 42 +++++++++---------- .../instrumentation/jvm/JvmMetricsTest.java | 19 +++++++++ 2 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java index fa909f629..54d937688 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java @@ -3,7 +3,8 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Registers all JVM metrics. Example usage: @@ -13,15 +14,14 @@ */ public class JvmMetrics { - private static AtomicBoolean registeredWithTheDefaultRegistry = new AtomicBoolean(false); - + private static final Set REGISTERED = ConcurrentHashMap.newKeySet(); public static Builder builder() { return new Builder(PrometheusProperties.get()); } // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you pass a config or not. // However, we will add config options in the future, like whether you want to use Prometheus naming conventions - //'or OpenTelemetry semantic conventions for JVM metrics. + // or OpenTelemetry semantic conventions for JVM metrics. public static Builder builder(PrometheusProperties config) { return new Builder(config); } @@ -37,32 +37,32 @@ private Builder(PrometheusProperties config) { /** * Register all JVM metrics with the default registry. *

      - * It's safe to call this multiple times: - * Only the first call will register the metrics, all subsequent calls will be ignored. + * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls + * will be ignored. */ public void register() { - if (!registeredWithTheDefaultRegistry.getAndSet(true)) { - register(PrometheusRegistry.defaultRegistry); - } + register(PrometheusRegistry.defaultRegistry); } /** * Register all JVM metrics with the {@code registry}. *

      - * You must make sure to call this only once per {@code registry}, otherwise it will - * throw an Exception because you are trying to register duplicate metrics. + * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls + * will be ignored. */ public void register(PrometheusRegistry registry) { - JvmThreadsMetrics.builder(config).register(registry); - JvmBufferPoolMetrics.builder(config).register(registry); - JvmClassLoadingMetrics.builder(config).register(registry); - JvmCompilationMetrics.builder(config).register(registry); - JvmGarbageCollectorMetrics.builder(config).register(registry); - JvmMemoryPoolAllocationMetrics.builder(config).register(registry); - JvmMemoryMetrics.builder(config).register(registry); - JvmNativeMemoryMetrics.builder(config).register(registry); - JvmRuntimeInfoMetric.builder(config).register(registry); - ProcessMetrics.builder(config).register(registry); + if (REGISTERED.add(registry)) { + JvmThreadsMetrics.builder(config).register(registry); + JvmBufferPoolMetrics.builder(config).register(registry); + JvmClassLoadingMetrics.builder(config).register(registry); + JvmCompilationMetrics.builder(config).register(registry); + JvmGarbageCollectorMetrics.builder(config).register(registry); + JvmMemoryPoolAllocationMetrics.builder(config).register(registry); + JvmMemoryMetrics.builder(config).register(registry); + JvmNativeMemoryMetrics.builder(config).register(registry); + JvmRuntimeInfoMetric.builder(config).register(registry); + ProcessMetrics.builder(config).register(registry); + } } } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java new file mode 100644 index 000000000..d93b1682d --- /dev/null +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java @@ -0,0 +1,19 @@ +package io.prometheus.metrics.instrumentation.jvm; + +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class JvmMetricsTest { + + @Test + public void testRegisterIdempotent() { + PrometheusRegistry registry = new PrometheusRegistry(); + assertEquals(0, registry.scrape().size()); + JvmMetrics.builder().register(registry); + assertTrue(registry.scrape().size() > 0); + JvmMetrics.builder().register(registry); + } +} From bddcb487947375c6980f34fb7fce91ac62ee39d9 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 1 Oct 2024 13:26:27 +0200 Subject: [PATCH 359/980] move to github actions / require google java format for changed files (#988) * move to github actions Signed-off-by: Gregor Zeitlinger * apply spotless for all changed files Signed-off-by: Gregor Zeitlinger * apply spotless for all changed files Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .circleci/config.yml | 27 --------------------------- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ pom.xml | 30 ++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 29 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/build.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 55ce02110..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 2 -machine: true -jobs: - build: - machine: - image: ubuntu-2204:current - working_directory: ~/circleci-java - steps: - - run: - name: Install OpenJDK 17 - command: | - sudo apt-get update && sudo apt-get install -y openjdk-17-jdk - sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java - sudo update-alternatives --set javac /usr/lib/jvm/java-17-openjdk-amd64/bin/javac - java -version - - checkout - - restore_cache: - key: maven-dependencies-{{ checksum "pom.xml" }} - - run: cd prometheus-metrics-shaded-dependencies && ../mvnw clean install && cd .. - - run: ./mvnw clean install - - run: ./mvnw javadoc:jar - - save_cache: - paths: - - ~/.m2 - key: maven-dependencies-{{ checksum "pom.xml" }} -orbs: - prometheus: prometheus/prometheus@0.16.0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..ed5d2605f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: Build + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: 'maven' + - name: Shaded dependencies + run: | + cd prometheus-metrics-shaded-dependencies + ../mvnw clean install + - name: Run the Maven verify phase + run: | + ./mvnw clean install + ./mvnw javadoc:jar diff --git a/pom.xml b/pom.xml index 52953fbc9..0f0e27d08 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + pom 4.0.0 @@ -156,9 +157,32 @@ maven-enforcer-plugin 1.4.1 + + com.diffplug.spotless + spotless-maven-plugin + 2.43.0 + + + com.diffplug.spotless + spotless-maven-plugin + + origin/main + + + + + + + verify + + check + + + + org.apache.maven.plugins maven-enforcer-plugin @@ -217,7 +241,9 @@ true all public - benchmarks,examples,integration-tests,integration_tests,,simpleclient,simpleclient_bom,simpleclient_caffeine,simpleclient_common,simpleclient_dropwizard,simpleclient_graphite_bridge,simpleclient_guava,simpleclient_hibernate,simpleclient_hotspot,simpleclient_httpserver,simpleclient_jetty,simpleclient_jetty_jdk8,simpleclient_log4j,simpleclient_log4j2,simpleclient_logback,simpleclient_pushgateway,simpleclient_servlet,simpleclient_servlet_common,simpleclient_servlet_jakarta,simpleclient_spring_boot,simpleclient_spring_web,simpleclient_tracer,simpleclient_vertx,simpleclient_vertx4 + + benchmarks,examples,integration-tests,integration_tests,,simpleclient,simpleclient_bom,simpleclient_caffeine,simpleclient_common,simpleclient_dropwizard,simpleclient_graphite_bridge,simpleclient_guava,simpleclient_hibernate,simpleclient_hotspot,simpleclient_httpserver,simpleclient_jetty,simpleclient_jetty_jdk8,simpleclient_log4j,simpleclient_log4j2,simpleclient_logback,simpleclient_pushgateway,simpleclient_servlet,simpleclient_servlet_common,simpleclient_servlet_jakarta,simpleclient_spring_boot,simpleclient_spring_web,simpleclient_tracer,simpleclient_vertx,simpleclient_vertx4 + io.prometheus.metrics.expositionformats.generated.* From 5a8ae85e63fc99e6cb992819e29de89e378873fb Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 1 Oct 2024 13:32:27 +0200 Subject: [PATCH 360/980] add Gregor Zeitlinger to MAINTAINERS.md (#990) Signed-off-by: Gregor Zeitlinger --- MAINTAINERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index c79384366..dae5c71de 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,3 +1,4 @@ * Fabian Stäber @fstab * Doug Hoard @dhoard * Tom Wilkie @tomwilkie +* Gregor Zeitlinger @zeitlinger From a6815dc33634c7f780f37afa82d412ddb2411fba Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 1 Oct 2024 13:59:00 +0200 Subject: [PATCH 361/980] Various cleanups in prometheus-metrics-model (#993) * Various cleanups in prometheus-metrics-model Signed-off-by: Mickael Maison * format Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Mickael Maison Signed-off-by: Gregor Zeitlinger Co-authored-by: Mickael Maison --- CONTRIBUTING.md | 6 + .../metrics/model/registry/Collector.java | 123 +-- .../model/registry/PrometheusRegistry.java | 229 ++--- .../metrics/model/snapshots/Exemplars.java | 228 +++-- .../metrics/model/snapshots/Labels.java | 836 +++++++++--------- .../metrics/model/snapshots/Quantile.java | 48 +- .../metrics/model/snapshots/Quantiles.java | 149 ++-- .../model/snapshots/StateSetSnapshot.java | 358 ++++---- .../model/registry/MetricNameFilterTest.java | 95 +- .../MultiCollectorNameFilterTest.java | 142 +-- .../registry/PrometheusRegistryTest.java | 153 ++-- .../snapshots/HistogramSnapshotTest.java | 535 +++++------ .../metrics/model/snapshots/LabelsTest.java | 243 +++-- .../model/snapshots/MetricMetadataTest.java | 112 +-- .../model/snapshots/SnapshotTestUtil.java | 18 +- .../model/snapshots/StateSetSnapshotTest.java | 258 +++--- .../metrics/model/snapshots/UnitTest.java | 79 +- 17 files changed, 1837 insertions(+), 1775 deletions(-) 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: - *

        - *
      1. During registration to check if a metric with that name already exists.
      2. - *
      3. During scrape to check if this collector can be skipped because a name filter is present and the metric name is excluded.
      4. - *
      - * 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: + * + *

        + *
      1. During registration to check if a metric with that name already exists. + *
      2. 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

      - * 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

      - * 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

      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

      - * 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

      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); + } } From e17ac02ee092dda726c019f3b31556e12ce3db9e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 1 Oct 2024 14:44:56 +0200 Subject: [PATCH 362/980] add dependabot (#994) Signed-off-by: Gregor Zeitlinger --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b3a1dddd8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + - package-ecosystem: maven + directory: "/" + schedule: + interval: daily From f28106bd03e2b0a00fddb40eb32b3de7ed112f48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:03:22 +0200 Subject: [PATCH 363/980] Bump org.apache.maven.plugins:maven-failsafe-plugin from 2.22.2 to 3.5.0 (#1003) Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 2.22.2 to 3.5.0. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.2...surefire-3.5.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f0e27d08..08257eaca 100644 --- a/pom.xml +++ b/pom.xml @@ -131,7 +131,7 @@ maven-failsafe-plugin - 2.22.2 + 3.5.0 maven-release-plugin From 1844d511f368f45d0b07530a1af1e606ef2707b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:09:30 +0200 Subject: [PATCH 364/980] Bump actions/upload-pages-artifact from 1 to 3 (#1002) Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 1 to 3. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v1...v3) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/github-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 6edc0639a..cd88f043d 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -85,7 +85,7 @@ jobs: - name: ls ./docs/public/api run: echo 'ls ./docs/public/api' && ls ./docs/public/api - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: path: ./docs/public From c9be1fd7505243c7a2f1a6fc5dd966532512db72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:21:19 +0200 Subject: [PATCH 365/980] Bump com.google.protobuf:protobuf-java (#1008) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 3.25.3 to 3.25.5. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.25.3...v3.25.5) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../prometheus-metrics-shaded-protobuf/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml index 9f9d46f14..eba000e1c 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml @@ -20,7 +20,7 @@ - 3.25.3 + 3.25.5 3_25_3 From b2f4ba74ae9d3042bf1f731d22683f037963de0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:27:18 +0200 Subject: [PATCH 366/980] Bump actions/deploy-pages from 2 to 4 (#1000) Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 4. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/github-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index cd88f043d..f51be93eb 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -99,4 +99,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v4 From 8c2b5c56e653d85e2a7bfdd74f073dcbf3c80375 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:32:01 +0200 Subject: [PATCH 367/980] Bump org.awaitility:awaitility from 4.2.1 to 4.2.2 (#1009) Bumps [org.awaitility:awaitility](https://github.com/awaitility/awaitility) from 4.2.1 to 4.2.2. - [Changelog](https://github.com/awaitility/awaitility/blob/master/changelog.txt) - [Commits](https://github.com/awaitility/awaitility/compare/awaitility-4.2.1...awaitility-4.2.2) --- updated-dependencies: - dependency-name: org.awaitility:awaitility dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index bde4e05f8..6c576eae6 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -66,7 +66,7 @@ org.awaitility awaitility - 4.2.1 + 4.2.2 test From addfb9f01770372729d8569271108354e9e7d316 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:36:38 +0200 Subject: [PATCH 368/980] Bump ch.qos.logback:logback-classic (#1007) Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.2.11 to 1.2.13. - [Commits](https://github.com/qos-ch/logback/compare/v_1.2.11...v_1.2.13) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- simpleclient-archive/simpleclient_logback/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient-archive/simpleclient_logback/pom.xml b/simpleclient-archive/simpleclient_logback/pom.xml index 96f4fb34d..a92b408b4 100644 --- a/simpleclient-archive/simpleclient_logback/pom.xml +++ b/simpleclient-archive/simpleclient_logback/pom.xml @@ -41,7 +41,7 @@ ch.qos.logback logback-classic - 1.2.11 + 1.2.13 From f8046ae6bf262e6799ee5c0f6bf25aeeda5a2416 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:46:29 +0200 Subject: [PATCH 369/980] Bump actions/configure-pages from 3 to 5 (#999) Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 3 to 5. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v3...v5) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/github-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index f51be93eb..27479c2a1 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -67,7 +67,7 @@ jobs: run: mv ./target/site/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api - name: Setup Pages id: pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v5 - name: Install Node.js dependencies run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" working-directory: ./docs From 2b74c2089c703b48f59b8e1356e7f968dfeb9a26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:54:32 +0200 Subject: [PATCH 370/980] Bump ch.qos.logback:logback-classic (#1010) Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.2.11 to 1.2.13. - [Commits](https://github.com/qos-ch/logback/compare/v_1.2.11...v_1.2.13) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../it_servlet_jakarta_exporter_webxml/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml index 71e8c536a..061733553 100644 --- a/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml +++ b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml @@ -45,7 +45,7 @@ ch.qos.logback logback-classic - 1.2.11 + 1.2.13 jakarta.servlet From 05dd98274b9d93136e660d501d80b49d1ba92296 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:09:46 +0200 Subject: [PATCH 371/980] Bump ch.qos.logback:logback-classic (#1011) Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.2.11 to 1.2.13. - [Commits](https://github.com/qos-ch/logback/compare/v_1.2.11...v_1.2.13) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- simpleclient-archive/integration_tests/it_pushgateway/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient-archive/integration_tests/it_pushgateway/pom.xml b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml index 2eba31efa..5fd8c8a5a 100644 --- a/simpleclient-archive/integration_tests/it_pushgateway/pom.xml +++ b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml @@ -36,7 +36,7 @@ ch.qos.logback logback-classic - 1.2.11 + 1.2.13 test From 08a1aeb302a7c86edf204f629dcbec44c4012d31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:16:46 +0200 Subject: [PATCH 372/980] Bump actions/checkout from 3 to 4 (#998) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/github-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 27479c2a1..6b2639ffd 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -55,7 +55,7 @@ jobs: #- name: Install Dart Sass # run: sudo snap install dart-sass - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 From 50d9950197110df8fa563e4a171b3cf3e2402ade Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:31:34 +0200 Subject: [PATCH 373/980] Bump org.apache.maven.plugins:maven-resources-plugin from 2.6 to 3.3.1 (#997) Bumps [org.apache.maven.plugins:maven-resources-plugin](https://github.com/apache/maven-resources-plugin) from 2.6 to 3.3.1. - [Release notes](https://github.com/apache/maven-resources-plugin/releases) - [Commits](https://github.com/apache/maven-resources-plugin/compare/maven-resources-plugin-2.6...maven-resources-plugin-3.3.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-resources-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 08257eaca..44eadc391 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ maven-resources-plugin - 2.6 + 3.3.1 maven-compiler-plugin From 397738e33bf00f0219bbed92f7a8a5e78b949cb0 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 1 Oct 2024 16:55:49 +0200 Subject: [PATCH 374/980] reformat all files with spotless (#1015) * reformat all files with spotless Signed-off-by: Gregor Zeitlinger * reformat all files with spotless Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/workflows/build.yml | 2 - .../metrics/benchmarks/BenchmarkRunner.java | 6 +- .../metrics/benchmarks/CounterBenchmark.java | 305 +- .../benchmarks/HistogramBenchmark.java | 279 +- .../metrics/benchmarks/RandomNumbers.java | 15 +- .../greeting/GreetingServlet.java | 50 +- .../otel_exemplars/greeting/Main.java | 33 +- .../otel_exemplars/app/HelloWorldServlet.java | 87 +- .../examples/otel_exemplars/app/Main.java | 33 +- .../metrics/examples/httpserver/Main.java | 47 +- .../metrics/examples/multitarget/Main.java | 22 +- .../multitarget/SampleMultiCollector.java | 123 +- .../metrics/examples/opentelemetry/Main.java | 51 +- .../ManualCompleteMetricsTest.java | 247 +- .../tomcat_servlet/HelloWorldServlet.java | 83 +- .../metrics/examples/tomcat_servlet/Main.java | 39 +- .../examples/nativehistogram/Main.java | 39 +- .../examples/prometheus_properties/Main.java | 50 +- .../metrics/examples/simpleclient/Main.java | 39 +- .../client/it/common/LogConsumer.java | 47 +- .../prometheus/client/it/common/Volume.java | 150 +- .../exporter/httpserver/HTTPServerSample.java | 138 +- .../jetty/ExporterServletJettySample.java | 166 +- .../tomcat/ExporterServletTomcatSample.java | 163 +- .../metrics/it/exporter/test/ExporterIT.java | 645 +-- .../it/pushgateway/PushGatewayTestApp.java | 189 +- .../metrics/it/pushgateway/PushGatewayIT.java | 420 +- pom.xml | 1 - .../metrics/config/ExemplarsProperties.java | 214 +- .../config/ExporterFilterProperties.java | 206 +- .../config/ExporterHttpServerProperties.java | 65 +- .../ExporterOpenTelemetryProperties.java | 358 +- .../metrics/config/ExporterProperties.java | 110 +- .../config/ExporterPushgatewayProperties.java | 101 +- .../metrics/config/MetricsProperties.java | 789 +-- .../metrics/config/PrometheusProperties.java | 147 +- .../config/PrometheusPropertiesException.java | 12 +- .../config/PrometheusPropertiesLoader.java | 188 +- .../io/prometheus/metrics/config/Util.java | 222 +- .../PrometheusPropertiesLoaderTests.java | 57 +- .../config/PrometheusPropertiesTest.java | 44 +- .../core/datapoints/CounterDataPoint.java | 110 +- .../metrics/core/datapoints/DataPoint.java | 3 +- .../datapoints/DistributionDataPoint.java | 44 +- .../core/datapoints/GaugeDataPoint.java | 108 +- .../core/datapoints/StateSetDataPoint.java | 49 +- .../metrics/core/datapoints/Timer.java | 53 +- .../metrics/core/datapoints/TimerApi.java | 119 +- .../core/exemplars/ExemplarSampler.java | 575 ++- .../core/exemplars/ExemplarSamplerConfig.java | 251 +- .../metrics/core/metrics/Buffer.java | 122 +- .../metrics/core/metrics/CKMSQuantiles.java | 446 +- .../metrics/core/metrics/CallbackMetric.java | 61 +- .../metrics/core/metrics/Counter.java | 399 +- .../core/metrics/CounterWithCallback.java | 133 +- .../metrics/core/metrics/Gauge.java | 304 +- .../core/metrics/GaugeWithCallback.java | 87 +- .../metrics/core/metrics/Histogram.java | 1679 +++--- .../prometheus/metrics/core/metrics/Info.java | 227 +- .../metrics/core/metrics/Metric.java | 84 +- .../core/metrics/MetricWithFixedMetadata.java | 152 +- .../metrics/core/metrics/SlidingWindow.java | 121 +- .../metrics/core/metrics/StateSet.java | 238 +- .../metrics/core/metrics/StatefulMetric.java | 332 +- .../metrics/core/metrics/Summary.java | 571 +- .../core/metrics/SummaryWithCallback.java | 88 +- .../metrics/core/util/Scheduler.java | 38 +- .../metrics/core/datapoints/TimerApiTest.java | 2 +- .../ExemplarSamplerConfigTestUtil.java | 42 +- .../core/exemplars/ExemplarSamplerTest.java | 403 +- .../exemplars/SpanContextSupplierTest.java | 184 +- .../core/metrics/CKMSQuantilesTest.java | 641 +-- .../metrics/core/metrics/CounterTest.java | 552 +- .../metrics/core/metrics/GaugeTest.java | 367 +- .../metrics/core/metrics/HistogramTest.java | 2671 +++++----- .../metrics/core/metrics/InfoTest.java | 167 +- .../core/metrics/SlidingWindowTest.java | 132 +- .../metrics/core/metrics/StateSetTest.java | 117 +- .../core/metrics/StatefulMetricTest.java | 102 +- .../core/metrics/SummaryWithCallbackTest.java | 2 +- .../metrics/core/metrics/TestUtil.java | 10 +- .../metrics/core/metrics/TodoTest.java | 15 +- .../common/PrometheusHttpExchange.java | 15 +- .../common/PrometheusHttpRequest.java | 105 +- .../common/PrometheusHttpResponse.java | 17 +- .../common/PrometheusScrapeHandler.java | 288 +- .../exporter/httpserver/DefaultHandler.java | 112 +- .../exporter/httpserver/HTTPServer.java | 403 +- .../exporter/httpserver/HealthyHandler.java | 39 +- .../httpserver/HttpExchangeAdapter.java | 197 +- .../exporter/httpserver/MetricsHandler.java | 48 +- .../httpserver/NamedDaemonThreadFactory.java | 38 +- .../opentelemetry/OpenTelemetryExporter.java | 842 +-- .../PrometheusInstrumentationScope.java | 61 +- .../PrometheusMetricProducer.java | 175 +- .../opentelemetry/ResourceAttributes.java | 48 +- .../ResourceAttributesDefaults.java | 10 +- .../ResourceAttributesFromJarFileName.java | 84 +- .../ResourceAttributesFromOtelAgent.java | 155 +- .../otelmodel/DoublePointDataImpl.java | 24 +- .../ExponentialHistogramBucketsImpl.java | 71 +- .../ExponentialHistogramPointDataImpl.java | 162 +- .../otelmodel/HistogramPointDataImpl.java | 106 +- .../otelmodel/MetricDataFactory.java | 109 +- .../otelmodel/PointDataImpl.java | 67 +- .../otelmodel/PrometheusClassicHistogram.java | 109 +- .../otelmodel/PrometheusCounter.java | 75 +- .../otelmodel/PrometheusData.java | 126 +- .../otelmodel/PrometheusGauge.java | 45 +- .../otelmodel/PrometheusInfo.java | 73 +- .../otelmodel/PrometheusMetricData.java | 240 +- .../otelmodel/PrometheusNativeHistogram.java | 125 +- .../otelmodel/PrometheusStateSet.java | 77 +- .../otelmodel/PrometheusSummary.java | 51 +- .../otelmodel/PrometheusUnknown.java | 45 +- .../otelmodel/SummaryPointDataImpl.java | 65 +- .../otelmodel/ValueAtQuantileImpl.java | 28 +- .../exporter/opentelemetry/ExemplarTest.java | 222 +- .../DefaultHttpConnectionFactory.java | 16 +- .../pushgateway/DefaultJobLabelDetector.java | 82 +- .../metrics/exporter/pushgateway/Format.java | 4 +- .../pushgateway/HttpConnectionFactory.java | 6 +- .../exporter/pushgateway/PushGateway.java | 708 +-- .../metrics/exporter/pushgateway/Scheme.java | 40 +- .../pushgateway/BasicAuthPushGatewayTest.java | 70 +- .../BearerTokenPushGatewayTest.java | 70 +- .../exporter/pushgateway/PushGatewayTest.java | 536 +- .../servlet/jakarta/HttpExchangeAdapter.java | 155 +- .../jakarta/PrometheusMetricsServlet.java | 41 +- .../servlet/javax/HttpExchangeAdapter.java | 222 +- .../javax/PrometheusMetricsServlet.java | 97 +- .../ExpositionFormatWriter.java | 12 +- .../expositionformats/ExpositionFormats.java | 81 +- .../OpenMetricsTextFormatWriter.java | 569 +- .../PrometheusProtobufWriter.java | 605 +-- .../PrometheusTextFormatWriter.java | 586 ++- .../expositionformats/ProtobufUtil.java | 12 +- .../expositionformats/TextFormatUtil.java | 130 +- .../ExpositionFormatsTest.java | 4572 ++++++++++------- .../caffeine/CacheMetricsCollector.java | 322 +- .../caffeine/CacheMetricsCollectorTest.java | 265 +- .../dropwizard5/DropwizardExports.java | 405 +- .../dropwizard5/labels/CustomLabelMapper.java | 181 +- .../labels/GraphiteNamePattern.java | 143 +- .../dropwizard5/labels/MapperConfig.java | 280 +- .../dropwizard5/DropwizardExportsTest.java | 547 +- .../labels/CustomLabelMapperTest.java | 397 +- .../labels/GraphiteNamePatternTest.java | 261 +- .../dropwizard5/labels/MapperConfigTest.java | 97 +- .../guava/CacheMetricsCollector.java | 275 +- .../guava/CacheMetricsCollectorTest.java | 241 +- .../jvm/JvmBufferPoolMetrics.java | 169 +- .../jvm/JvmClassLoadingMetrics.java | 126 +- .../jvm/JvmCompilationMetrics.java | 108 +- .../jvm/JvmGarbageCollectorMetrics.java | 124 +- .../instrumentation/jvm/JvmMemoryMetrics.java | 367 +- .../jvm/JvmMemoryPoolAllocationMetrics.java | 253 +- .../instrumentation/jvm/JvmMetrics.java | 95 +- .../jvm/JvmNativeMemoryMetrics.java | 70 +- .../jvm/JvmRuntimeInfoMetric.java | 145 +- .../jvm/JvmThreadsMetrics.java | 302 +- .../jvm/NativeImageChecker.java | 14 +- .../instrumentation/jvm/ProcessMetrics.java | 422 +- .../jvm/ExampleExporterForManualTesting.java | 21 +- .../jvm/JvmBufferPoolMetricsTest.java | 123 +- .../jvm/JvmClassLoadingMetricsTest.java | 105 +- .../jvm/JvmCompilationMetricsTest.java | 95 +- .../jvm/JvmGarbageCollectorMetricsTest.java | 106 +- .../jvm/JvmMemoryMetricsTest.java | 326 +- .../JvmMemoryPoolAllocationMetricsTest.java | 83 +- .../instrumentation/jvm/JvmMetricsTest.java | 22 +- .../jvm/JvmNativeMemoryMetricsTest.java | 319 +- .../jvm/JvmRuntimeInfoMetricTest.java | 40 +- .../jvm/JvmThreadsMetricsTest.java | 335 +- .../jvm/ProcessMetricsTest.java | 190 +- .../metrics/instrumentation/jvm/TestUtil.java | 13 +- .../model/registry/MetricNameFilter.java | 367 +- .../model/registry/MultiCollector.java | 111 +- .../registry/PrometheusScrapeRequest.java | 16 +- .../snapshots/ClassicHistogramBucket.java | 60 +- .../snapshots/ClassicHistogramBuckets.java | 382 +- .../model/snapshots/CounterSnapshot.java | 237 +- .../model/snapshots/DataPointSnapshot.java | 131 +- .../DistributionDataPointSnapshot.java | 135 +- .../snapshots/DuplicateLabelsException.java | 32 +- .../metrics/model/snapshots/Exemplar.java | 216 +- .../model/snapshots/GaugeSnapshot.java | 203 +- .../model/snapshots/HistogramSnapshot.java | 788 +-- .../metrics/model/snapshots/InfoSnapshot.java | 155 +- .../metrics/model/snapshots/Label.java | 85 +- .../model/snapshots/MetricMetadata.java | 199 +- .../model/snapshots/MetricSnapshot.java | 130 +- .../model/snapshots/MetricSnapshots.java | 155 +- .../snapshots/NativeHistogramBucket.java | 32 +- .../snapshots/NativeHistogramBuckets.java | 261 +- .../model/snapshots/PrometheusNaming.java | 486 +- .../model/snapshots/SummarySnapshot.java | 234 +- .../metrics/model/snapshots/Unit.java | 100 +- .../model/snapshots/UnknownSnapshot.java | 205 +- .../ClassicHistogramBucketsTest.java | 166 +- .../model/snapshots/CounterSnapshotTest.java | 195 +- .../metrics/model/snapshots/ExemplarTest.java | 128 +- .../model/snapshots/ExemplarsTest.java | 86 +- .../model/snapshots/GaugeSnapshotTest.java | 194 +- .../model/snapshots/InfoSnapshotTest.java | 102 +- .../model/snapshots/MetricSnapshotTest.java | 57 +- .../model/snapshots/MetricSnapshotsTest.java | 158 +- .../snapshots/NativeHistogramBucketsTest.java | 101 +- .../model/snapshots/PrometheusNamingTest.java | 151 +- .../model/snapshots/QuantilesTest.java | 69 +- .../model/snapshots/SummarySnapshotTest.java | 192 +- .../model/snapshots/UnknownSnapshotTest.java | 144 +- .../PrometheusMetricsShadedOpenTelemetry.java | 10 +- .../PrometheusMetricsShadedProtobuf.java | 10 +- .../bridge/SimpleclientCollector.java | 649 +-- .../bridge/SimpleclientCollectorTest.java | 473 +- .../metrics/tracer/common/SpanContext.java | 15 +- .../initializer/SpanContextSupplier.java | 66 +- .../OpenTelemetryAgentSpanContext.java | 12 +- .../tracer/otel/OpenTelemetrySpanContext.java | 44 +- 220 files changed, 23898 insertions(+), 22085 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ed5d2605f..835d4dcde 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,8 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - fetch-depth: 0 - name: Set up JDK uses: actions/setup-java@v4 with: diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java index 6503c0d60..9d5d242ae 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/BenchmarkRunner.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.benchmarks; public class BenchmarkRunner { - public static void main(String[] args) throws Exception { - org.openjdk.jmh.Main.main(args); - } + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } } diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index 31678ad10..6730e1bab 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -19,6 +19,7 @@ /** * Results on a machine with dedicated 8 vCPU cores: + * *

        * Benchmark                                                                  Mode  Cnt      Score     Error  Units
        * i.p.metrics.benchmarks.CounterBenchmark.codahaleIncNoLabels               thrpt   25  30978.055 ± 424.088  ops/s
      @@ -32,182 +33,174 @@
        * i.p.metrics.benchmarks.CounterBenchmark.simpleclientInc                   thrpt   25   9057.637 ±  67.761  ops/s
        * i.p.metrics.benchmarks.CounterBenchmark.simpleclientNoLabelsInc           thrpt   25   8993.471 ±  49.581  ops/s
        * 
      - * Prometheus counters are faster than counters of other libraries. For example, incrementing a single counter - * without labels is more than 2 times faster (34752 ops / second) than doing the same with an OpenTelemetry - * counter (16634 ops / sec). + * + * Prometheus counters are faster than counters of other libraries. For example, incrementing a + * single counter without labels is more than 2 times faster (34752 ops / second) than doing the + * same with an OpenTelemetry counter (16634 ops / sec). */ public class CounterBenchmark { - @State(Scope.Benchmark) - public static class PrometheusCounter { - - final Counter noLabels; - final CounterDataPoint dataPoint; - - public PrometheusCounter() { - noLabels = Counter.builder() - .name("test") - .help("help") - .build(); - - Counter labels = Counter.builder() - .name("test") - .help("help") - .labelNames("path", "status") - .build(); - this.dataPoint = labels.labelValues("/", "200"); - } - } + @State(Scope.Benchmark) + public static class PrometheusCounter { - @State(Scope.Benchmark) - public static class SimpleclientCounter { + final Counter noLabels; + final CounterDataPoint dataPoint; - final io.prometheus.client.Counter noLabels; - final io.prometheus.client.Counter.Child dataPoint; + public PrometheusCounter() { + noLabels = Counter.builder().name("test").help("help").build(); - public SimpleclientCounter() { - noLabels = io.prometheus.client.Counter.build() - .name("name") - .help("help") - .create(); + Counter labels = + Counter.builder().name("test").help("help").labelNames("path", "status").build(); + this.dataPoint = labels.labelValues("/", "200"); + } + } - io.prometheus.client.Counter counter = io.prometheus.client.Counter.build() - .name("name") - .help("help") - .labelNames("path", "status") - .create(); + @State(Scope.Benchmark) + public static class SimpleclientCounter { - this.dataPoint = counter.labels("/", "200"); - } - } + final io.prometheus.client.Counter noLabels; + final io.prometheus.client.Counter.Child dataPoint; - @State(Scope.Benchmark) - public static class CodahaleCounterNoLabels { - final com.codahale.metrics.Counter counter = new com.codahale.metrics.MetricRegistry().counter("test"); - } + public SimpleclientCounter() { + noLabels = io.prometheus.client.Counter.build().name("name").help("help").create(); - @State(Scope.Benchmark) - public static class OpenTelemetryCounter { - - final LongCounter longCounter; - final DoubleCounter doubleCounter; - final Attributes attributes; - - public OpenTelemetryCounter() { - - SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder() - .registerMetricReader(InMemoryMetricReader.create()) - .setResource(Resource.getDefault()) - .build(); - OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setMeterProvider(sdkMeterProvider) - .build(); - Meter meter = openTelemetry - .meterBuilder("instrumentation-library-name") - .setInstrumentationVersion("1.0.0") - .build(); - this.longCounter = meter - .counterBuilder("test1") - .setDescription("test") - .build(); - this.doubleCounter = meter - .counterBuilder("test2") - .ofDoubles() - .setDescription("test") - .build(); - this.attributes = Attributes.of( - AttributeKey.stringKey("path"), "/", - AttributeKey.stringKey("status"), "200"); - } - } + io.prometheus.client.Counter counter = + io.prometheus.client.Counter.build() + .name("name") + .help("help") + .labelNames("path", "status") + .create(); - @Benchmark - @Threads(4) - public CounterDataPoint prometheusAdd(RandomNumbers randomNumbers, PrometheusCounter counter) { - for (int i=0; i * Benchmark Mode Cnt Score Error Units * i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryClassic thrpt 25 1908.715 ± 114.050 ops/s @@ -27,164 +27,159 @@ * i.p.metrics.benchmarks.HistogramBenchmark.prometheusNative thrpt 25 3372.789 ± 339.328 ops/s * i.p.metrics.benchmarks.HistogramBenchmark.simpleclient thrpt 25 6488.252 ± 96.737 ops/s *
      + * * The simpleclient (i.e. client_java version 0.16.0 and older) histograms perform about the same as * the classic histogram of the current 1.0.0 version. - *

      - * Compared to OpenTelemetry histograms the Prometheus Java client histograms perform more than 3 times better - * (OpenTelemetry has 1908 ops / sec for classic histograms, while Prometheus has 6451 ops / sec). + * + *

      Compared to OpenTelemetry histograms the Prometheus Java client histograms perform more than 3 + * times better (OpenTelemetry has 1908 ops / sec for classic histograms, while Prometheus has 6451 + * ops / sec). */ - public class HistogramBenchmark { - @State(Scope.Benchmark) - public static class PrometheusClassicHistogram { + @State(Scope.Benchmark) + public static class PrometheusClassicHistogram { - final Histogram noLabels; + final Histogram noLabels; - public PrometheusClassicHistogram() { - noLabels = Histogram.builder() - .name("test") - .help("help") - .classicOnly() - .build(); - } + public PrometheusClassicHistogram() { + noLabels = Histogram.builder().name("test").help("help").classicOnly().build(); } - - @State(Scope.Benchmark) - public static class PrometheusNativeHistogram { - - final Histogram noLabels; - - public PrometheusNativeHistogram() { - noLabels = Histogram.builder() - .name("test") - .help("help") - .nativeOnly() - .nativeInitialSchema(5) - .nativeMaxNumberOfBuckets(0) - .build(); - } + } + + @State(Scope.Benchmark) + public static class PrometheusNativeHistogram { + + final Histogram noLabels; + + public PrometheusNativeHistogram() { + noLabels = + Histogram.builder() + .name("test") + .help("help") + .nativeOnly() + .nativeInitialSchema(5) + .nativeMaxNumberOfBuckets(0) + .build(); } + } - @State(Scope.Benchmark) - public static class SimpleclientHistogram { + @State(Scope.Benchmark) + public static class SimpleclientHistogram { - final io.prometheus.client.Histogram noLabels; + final io.prometheus.client.Histogram noLabels; - public SimpleclientHistogram() { - noLabels = io.prometheus.client.Histogram.build() - .name("name") - .help("help") - .create(); - } + public SimpleclientHistogram() { + noLabels = io.prometheus.client.Histogram.build().name("name").help("help").create(); } - - @State(Scope.Benchmark) - public static class OpenTelemetryClassicHistogram { - - final io.opentelemetry.api.metrics.DoubleHistogram histogram; - - public OpenTelemetryClassicHistogram() { - - SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder() - .registerMetricReader(InMemoryMetricReader.create()) - .setResource(Resource.getDefault()) - .registerView(InstrumentSelector.builder() - .setName("test") - .build(), - View.builder() - .setAggregation(Aggregation.explicitBucketHistogram(Arrays.asList(.005, .01, .025, .05, .1, .25, .5, 1.0, 2.5, 5.0, 10.0))) - .build() - ) - .build(); - OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setMeterProvider(sdkMeterProvider) - .build(); - Meter meter = openTelemetry - .meterBuilder("instrumentation-library-name") - .setInstrumentationVersion("1.0.0") - .build(); - this.histogram = meter - .histogramBuilder("test") - .setDescription("test") - .build(); - } + } + + @State(Scope.Benchmark) + public static class OpenTelemetryClassicHistogram { + + final io.opentelemetry.api.metrics.DoubleHistogram histogram; + + public OpenTelemetryClassicHistogram() { + + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .registerView( + InstrumentSelector.builder().setName("test").build(), + View.builder() + .setAggregation( + Aggregation.explicitBucketHistogram( + Arrays.asList( + .005, .01, .025, .05, .1, .25, .5, 1.0, 2.5, 5.0, 10.0))) + .build()) + .build(); + OpenTelemetry openTelemetry = + OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Meter meter = + openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + this.histogram = meter.histogramBuilder("test").setDescription("test").build(); } - - @State(Scope.Benchmark) - public static class OpenTelemetryExponentialHistogram { - - final io.opentelemetry.api.metrics.DoubleHistogram histogram; - - public OpenTelemetryExponentialHistogram() { - - SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder() - .registerMetricReader(InMemoryMetricReader.create()) - .setResource(Resource.getDefault()) - .registerView(InstrumentSelector.builder() - .setName("test") - .build(), - View.builder() - .setAggregation(Aggregation.base2ExponentialBucketHistogram(10_000, 5)) - .build() - ) - .build(); - OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setMeterProvider(sdkMeterProvider) - .build(); - Meter meter = openTelemetry - .meterBuilder("instrumentation-library-name") - .setInstrumentationVersion("1.0.0") - .build(); - this.histogram = meter - .histogramBuilder("test") - .setDescription("test") - .build(); - } + } + + @State(Scope.Benchmark) + public static class OpenTelemetryExponentialHistogram { + + final io.opentelemetry.api.metrics.DoubleHistogram histogram; + + public OpenTelemetryExponentialHistogram() { + + SdkMeterProvider sdkMeterProvider = + SdkMeterProvider.builder() + .registerMetricReader(InMemoryMetricReader.create()) + .setResource(Resource.getDefault()) + .registerView( + InstrumentSelector.builder().setName("test").build(), + View.builder() + .setAggregation(Aggregation.base2ExponentialBucketHistogram(10_000, 5)) + .build()) + .build(); + OpenTelemetry openTelemetry = + OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); + Meter meter = + openTelemetry + .meterBuilder("instrumentation-library-name") + .setInstrumentationVersion("1.0.0") + .build(); + this.histogram = meter.histogramBuilder("test").setDescription("test").build(); } - - @Benchmark - @Threads(4) - public Histogram prometheusClassic(RandomNumbers randomNumbers, PrometheusClassicHistogram histogram) { - for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { - histogram.noLabels.observe(randomNumbers.randomNumbers[i]); - } - return histogram.noLabels; + } + + @Benchmark + @Threads(4) + public Histogram prometheusClassic( + RandomNumbers randomNumbers, PrometheusClassicHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.noLabels.observe(randomNumbers.randomNumbers[i]); } - - @Benchmark - @Threads(4) - public Histogram prometheusNative(RandomNumbers randomNumbers, PrometheusNativeHistogram histogram) { - for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { - histogram.noLabels.observe(randomNumbers.randomNumbers[i]); - } - return histogram.noLabels; + return histogram.noLabels; + } + + @Benchmark + @Threads(4) + public Histogram prometheusNative( + RandomNumbers randomNumbers, PrometheusNativeHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.noLabels.observe(randomNumbers.randomNumbers[i]); } - - @Benchmark - @Threads(4) - public io.prometheus.client.Histogram simpleclient(RandomNumbers randomNumbers, SimpleclientHistogram histogram) { - for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { - histogram.noLabels.observe(randomNumbers.randomNumbers[i]); - } - return histogram.noLabels; + return histogram.noLabels; + } + + @Benchmark + @Threads(4) + public io.prometheus.client.Histogram simpleclient( + RandomNumbers randomNumbers, SimpleclientHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.noLabels.observe(randomNumbers.randomNumbers[i]); } - - @Benchmark - @Threads(4) - public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryClassic(RandomNumbers randomNumbers, OpenTelemetryClassicHistogram histogram) { - for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { - histogram.histogram.record(randomNumbers.randomNumbers[i]); - } - return histogram.histogram; + return histogram.noLabels; + } + + @Benchmark + @Threads(4) + public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryClassic( + RandomNumbers randomNumbers, OpenTelemetryClassicHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.histogram.record(randomNumbers.randomNumbers[i]); } - - @Benchmark - @Threads(4) - public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryExponential(RandomNumbers randomNumbers, OpenTelemetryExponentialHistogram histogram) { - for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { - histogram.histogram.record(randomNumbers.randomNumbers[i]); - } - return histogram.histogram; + return histogram.histogram; + } + + @Benchmark + @Threads(4) + public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryExponential( + RandomNumbers randomNumbers, OpenTelemetryExponentialHistogram histogram) { + for (int i = 0; i < randomNumbers.randomNumbers.length; i++) { + histogram.histogram.record(randomNumbers.randomNumbers[i]); } + return histogram.histogram; + } } diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java index d7002d909..6778c4ea1 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java @@ -1,19 +1,18 @@ package io.prometheus.metrics.benchmarks; +import java.util.Random; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; -import java.util.Random; - @State(Scope.Thread) public class RandomNumbers { - final double[] randomNumbers = new double[10*1024]; + final double[] randomNumbers = new double[10 * 1024]; - public RandomNumbers() { - Random rand = new Random(0); - for (int i = 0; i < randomNumbers.length; i++) { - randomNumbers[i] = Math.abs(rand.nextGaussian()); - } + public RandomNumbers() { + Random rand = new Random(0); + for (int i = 0; i < randomNumbers.length; i++) { + randomNumbers[i] = Math.abs(rand.nextGaussian()); } + } } diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java index 7a0870bf3..af1652f76 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -1,47 +1,45 @@ package io.prometheus.metrics.examples.otel_exemplars.greeting; +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; + import io.prometheus.metrics.core.metrics.Histogram; import io.prometheus.metrics.model.snapshots.Unit; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.io.IOException; import java.util.Random; -import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; - -/** - * Hello World REST servlet, with an example counter and an example histogram. - */ +/** Hello World REST servlet, with an example counter and an example histogram. */ public class GreetingServlet extends HttpServlet { - private final Random random = new Random(0); + private final Random random = new Random(0); - private final Histogram histogram; + private final Histogram histogram; - public GreetingServlet() { - histogram = Histogram.builder() + public GreetingServlet() { + histogram = + Histogram.builder() .name("request_duration_seconds") .help("request duration in seconds") .unit(Unit.SECONDS) .labelNames("http_status") .register(); - histogram.initLabelValues("200"); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - long start = System.nanoTime(); - try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); - resp.setStatus(200); - resp.setContentType("text/plain"); - resp.getWriter().println("Hello, World!"); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } finally { - histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); - } + histogram.initLabelValues("200"); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("Hello, World!"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } + } } diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java index 731e05cf9..c0cf09830 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java @@ -2,34 +2,31 @@ import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import java.io.File; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; -import java.io.File; - -/** - * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. - */ +/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */ public class Main { - public static void main(String[] args) throws LifecycleException { + public static void main(String[] args) throws LifecycleException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - Tomcat tomcat = new Tomcat(); - tomcat.setPort(8081); + Tomcat tomcat = new Tomcat(); + tomcat.setPort(8081); - Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); - Tomcat.addServlet(ctx, "hello", new GreetingServlet()); - ctx.addServletMappingDecoded("/*", "hello"); + Tomcat.addServlet(ctx, "hello", new GreetingServlet()); + ctx.addServletMappingDecoded("/*", "hello"); - Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); - ctx.addServletMappingDecoded("/metrics", "metrics"); + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); - tomcat.getConnector(); - tomcat.start(); - tomcat.getServer().await(); - } + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } } diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java index 11c048d68..fbe293d50 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -1,12 +1,14 @@ package io.prometheus.metrics.examples.otel_exemplars.app; +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; +import static java.net.http.HttpResponse.BodyHandlers.ofString; + import io.prometheus.metrics.core.metrics.Histogram; import io.prometheus.metrics.model.snapshots.Unit; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -15,51 +17,46 @@ import java.net.http.HttpResponse; import java.util.Random; -import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; -import static java.net.http.HttpResponse.BodyHandlers.ofString; - -/** - * Hello World REST servlet, with an example counter and an example histogram. - */ +/** Hello World REST servlet, with an example counter and an example histogram. */ public class HelloWorldServlet extends HttpServlet { - private final Random random = new Random(0); - - private final Histogram histogram; - - public HelloWorldServlet() { - histogram = Histogram.builder() - .name("request_duration_seconds") - .help("request duration in seconds") - .unit(Unit.SECONDS) - .labelNames("http_status") - .register(); - histogram.initLabelValues("200"); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { - long start = System.nanoTime(); - try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); - String greeting = executeGreetingServiceRequest(); - resp.setStatus(200); - resp.setContentType("text/plain"); - resp.getWriter().print(greeting); - } catch (Exception e) { - throw new ServletException(e); - } finally { - histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); - } - } - - private String executeGreetingServiceRequest() throws URISyntaxException, IOException, InterruptedException { - HttpRequest request = HttpRequest.newBuilder() - .GET() - .uri(new URI("http://localhost:8081/")) - .build(); - HttpClient httpClient = HttpClient.newHttpClient(); - HttpResponse response = httpClient.send(request, ofString()); - return response.body(); + private final Random random = new Random(0); + + private final Histogram histogram; + + public HelloWorldServlet() { + histogram = + Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .labelNames("http_status") + .register(); + histogram.initLabelValues("200"); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + String greeting = executeGreetingServiceRequest(); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().print(greeting); + } catch (Exception e) { + throw new ServletException(e); + } finally { + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } + } + + private String executeGreetingServiceRequest() + throws URISyntaxException, IOException, InterruptedException { + HttpRequest request = + HttpRequest.newBuilder().GET().uri(new URI("http://localhost:8081/")).build(); + HttpClient httpClient = HttpClient.newHttpClient(); + HttpResponse response = httpClient.send(request, ofString()); + return response.body(); + } } diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java index 5fb5114bb..dc58256cb 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java @@ -2,34 +2,31 @@ import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; +import java.io.File; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; -import java.io.File; - -/** - * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. - */ +/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */ public class Main { - public static void main(String[] args) throws LifecycleException { + public static void main(String[] args) throws LifecycleException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - Tomcat tomcat = new Tomcat(); - tomcat.setPort(8080); + Tomcat tomcat = new Tomcat(); + tomcat.setPort(8080); - Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); - Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); - ctx.addServletMappingDecoded("/*", "hello"); + Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); + ctx.addServletMappingDecoded("/*", "hello"); - Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); - ctx.addServletMappingDecoded("/metrics", "metrics"); + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); - tomcat.getConnector(); - tomcat.start(); - tomcat.getServer().await(); - } + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } } diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java index f01874ef8..3b0976778 100644 --- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java +++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java @@ -4,39 +4,36 @@ import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.IOException; -/** - * Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. - */ +/** Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. */ public class Main { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - // Note: uptime_seconds_total is not a great example: - // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds - // with the start timestamp in seconds, so if you want to know the uptime you can simply - // run the Prometheus query - // time() - process_start_time_seconds - // rather than creating a custom uptime metric. - Counter counter = Counter.builder() - .name("uptime_seconds_total") - .help("total number of seconds since this application was started") - .unit(Unit.SECONDS) - .register(); + // Note: uptime_seconds_total is not a great example: + // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds + // with the start timestamp in seconds, so if you want to know the uptime you can simply + // run the Prometheus query + // time() - process_start_time_seconds + // rather than creating a custom uptime metric. + Counter counter = + Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) + .register(); - HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + HTTPServer server = HTTPServer.builder().port(9400).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - while (true) { - Thread.sleep(1000); - counter.inc(); - } + while (true) { + Thread.sleep(1000); + counter.inc(); } + } } diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java index da36346b9..0fac9a0d3 100644 --- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java @@ -1,23 +1,19 @@ package io.prometheus.metrics.examples.multitarget; -import java.io.IOException; - import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import java.io.IOException; -/** - * Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. - */ +/** Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. */ public class Main { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - SampleMultiCollector xmc = new SampleMultiCollector(); - PrometheusRegistry.defaultRegistry.register(xmc); - HTTPServer server = HTTPServer.builder() - .port(9401) - .buildAndStart(); + SampleMultiCollector xmc = new SampleMultiCollector(); + PrometheusRegistry.defaultRegistry.register(xmc); + HTTPServer server = HTTPServer.builder().port(9401).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - } + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + } } diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java index 819bb3028..7a05f0a8b 100644 --- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java @@ -1,9 +1,5 @@ package io.prometheus.metrics.examples.multitarget; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; import io.prometheus.metrics.model.snapshots.CounterSnapshot; @@ -13,76 +9,79 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.PrometheusNaming; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; public class SampleMultiCollector implements MultiCollector { - public SampleMultiCollector() { - super(); - } - - @Override - public MetricSnapshots collect() { - return new MetricSnapshots(); - } + public SampleMultiCollector() { + super(); + } - @Override - public MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { - return collectMetricSnapshots(scrapeRequest); - } + @Override + public MetricSnapshots collect() { + return new MetricSnapshots(); + } - protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { + @Override + public MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { + return collectMetricSnapshots(scrapeRequest); + } - GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); - gaugeBuilder.name("x_load").help("process load"); + protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { - CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); - counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); + GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); + gaugeBuilder.name("x_load").help("process load"); - String[] targetNames = scrapeRequest.getParameterValues("target"); - String targetName; - String[] procs = scrapeRequest.getParameterValues("proc"); - if (targetNames == null || targetNames.length == 0) { - targetName = "defaultTarget"; - procs = null; //ignore procs param - } else { - targetName = targetNames[0]; - } - Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); - io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); - Labels lbls = Labels.of("target", targetName); + CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); + counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); - if (procs == null || procs.length == 0) { - counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); - gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); - counterDataPointBuilder.value(70); - gaugeDataPointBuilder.value(Math.random()); + String[] targetNames = scrapeRequest.getParameterValues("target"); + String targetName; + String[] procs = scrapeRequest.getParameterValues("proc"); + if (targetNames == null || targetNames.length == 0) { + targetName = "defaultTarget"; + procs = null; // ignore procs param + } else { + targetName = targetNames[0]; + } + Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); + io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder + gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); + Labels lbls = Labels.of("target", targetName); - counterBuilder.dataPoint(counterDataPointBuilder.build()); - gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + if (procs == null || procs.length == 0) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + counterDataPointBuilder.value(70); + gaugeDataPointBuilder.value(Math.random()); - } else { - for (int i = 0; i < procs.length; i++) { - counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); - gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); - counterDataPointBuilder.value(Math.random()); - gaugeDataPointBuilder.value(Math.random()); + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); - counterBuilder.dataPoint(counterDataPointBuilder.build()); - gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); - } - } - Collection snaps = new ArrayList(); - snaps.add(counterBuilder.build()); - snaps.add(gaugeBuilder.build()); - MetricSnapshots msnaps = new MetricSnapshots(snaps); - return msnaps; - } + } else { + for (int i = 0; i < procs.length; i++) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + counterDataPointBuilder.value(Math.random()); + gaugeDataPointBuilder.value(Math.random()); - public List getPrometheusNames() { - List names = new ArrayList(); - names.add("x_calls_total"); - names.add("x_load"); - return names; - } + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + } + } + Collection snaps = new ArrayList(); + snaps.add(counterBuilder.build()); + snaps.add(gaugeBuilder.build()); + MetricSnapshots msnaps = new MetricSnapshots(snaps); + return msnaps; + } + public List getPrometheusNames() { + List names = new ArrayList(); + names.add("x_calls_total"); + names.add("x_load"); + return names; + } } diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java index 966b16d92..defe85074 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java @@ -5,37 +5,36 @@ import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; -/** - * Simple example of an application exposing metrics pushing metrics via OTLP. - */ +/** Simple example of an application exposing metrics pushing metrics via OTLP. */ public class Main { - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Exception { - // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions. - // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry - // naming conventions rather than the Prometheus names. - JvmMetrics.builder().register(); + // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions. + // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry + // naming conventions rather than the Prometheus names. + JvmMetrics.builder().register(); - // Note: uptime_seconds_total is not a great example: - // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds - // with the start timestamp in seconds, so if you want to know the uptime you can simply - // run the Prometheus query - // time() - process_start_time_seconds - // rather than creating a custom uptime metric. - Counter counter = Counter.builder() - .name("uptime_seconds_total") - .help("total number of seconds since this application was started") - .unit(Unit.SECONDS) - .register(); + // Note: uptime_seconds_total is not a great example: + // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds + // with the start timestamp in seconds, so if you want to know the uptime you can simply + // run the Prometheus query + // time() - process_start_time_seconds + // rather than creating a custom uptime metric. + Counter counter = + Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) + .register(); - OpenTelemetryExporter.builder() - .intervalSeconds(5) // ridiculously short interval for demo purposes - .buildAndStart(); + OpenTelemetryExporter.builder() + .intervalSeconds(5) // ridiculously short interval for demo purposes + .buildAndStart(); - while (true) { - Thread.sleep(1000); - counter.inc(); - } + while (true) { + Thread.sleep(1000); + counter.inc(); } + } } diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java index 72e8dd107..b8b8ef98b 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java @@ -19,127 +19,128 @@ public class ManualCompleteMetricsTest { - // This contains a complete set of all metric types, and target_info and otel_scope_info. - // I used this to expose in Prometheus format and OTLP format at the same time and compare the results. - // I'm keeping this as a backup for now, but this should be converted to an integration test. - // - // To run it, add prometheus-metrics-exporter-httpserver as a dependency and configure Prometheus - // to scrape from port 9400 in addition to receiving metrics via remote write. - - /* - public static void main(String[] args) throws Exception { - - Counter counter = Counter.newBuilder() - .withName("uptime_seconds_total") - .withHelp("total number of seconds since this application was started") - .withUnit(Unit.SECONDS) - .register(); - - Gauge gauge = Gauge.newBuilder() - .withName("temperature_celsius") - .withHelp("temperature in celsius") - .withUnit(Unit.CELSIUS) - .withLabelNames("location") - .register(); - - gauge.labelValues("inside").set(23.4); - gauge.labelValues("outside").set(9.3); - - // By default, the histogram will be exported as an exponential histogram in OpenTelemetry. - Histogram histogram = Histogram.newBuilder() - .withName("request_latency_seconds") - .withHelp("Request duration in seconds") - .withUnit(Unit.SECONDS) - .withLabelNames("http_status") - .register(); - - Random random = new Random(0); - for (int i = 0; i < 1000; i++) { - histogram.labelValues("200").observe(random.nextGaussian()); - } - - // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry - Histogram classicHistogram = Histogram.newBuilder() - .withName("request_size_bytes") - .withHelp("Request size in Bytes") - .withUnit(Unit.BYTES) - .withLabelNames("path") - .classicOnly() - .withClassicBuckets(128, 256, 512, 1024, 2048) - .register(); - - for (int i = 0; i < 15; i++) { - classicHistogram.labelValues("200").observe(random.nextInt(3000)); - } - - Summary summary = Summary.newBuilder() - .withName("response_latency_seconds") - .withHelp("Response latency seconds") - .withUnit(Unit.BYTES) - .withQuantile(0.95) - .withQuantile(0.99) - .register(); - - for (int i = 0; i < 1000; i++) { - summary.observe(random.nextGaussian()); - } - - Info targetInfo = Info.newBuilder() - .withName("target_info") - .withHelp("OTel resource") - .withLabelNames("service.version") - .register(); - targetInfo.setLabelValues("1.0.0"); - - Info scopeInfo = Info.newBuilder() - .withName("otel_scope_info") - .withLabelNames("otel.scope.name", "otel.scope.version", "library_mascot") - .register(); - - scopeInfo.setLabelValues("my.instrumentation.lib", "100.3", "bear"); - - Info info = Info.newBuilder() - .withName("java_runtime_info") - .withHelp("Java runtime info") - .withLabelNames("version", "vendor", "runtime") - .register(); - - String version = System.getProperty("java.runtime.version", "unknown"); - String vendor = System.getProperty("java.vm.vendor", "unknown"); - String runtime = System.getProperty("java.runtime.name", "unknown"); - - info.setLabelValues(version, vendor, runtime); - - StateSet stateSet = StateSet.newBuilder() - .withName("feature_flags") - .withLabelNames("env") - .withStates("feature1", "feature2") - .register(); - - stateSet.labelValues("dev").setFalse("feature1"); - stateSet.labelValues("dev").setTrue("feature2"); - - PrometheusRegistry.defaultRegistry.register(() -> UnknownSnapshot.newBuilder() - .withName("my_unknown_metric") - .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() - .withLabels(Labels.of("a", "1", "b", "2")) - .withValue(3.0) - .build()) - .build()); - - HTTPServer server = HTTPServer.newBuilder() - .withPort(9400) - .buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - - OpenTelemetryExporter.newBuilder() - .withIntervalSeconds(5) - .buildAndStart(); - - while (true) { - Thread.sleep(1000); - counter.inc(); - } - } - */ + // This contains a complete set of all metric types, and target_info and otel_scope_info. + // I used this to expose in Prometheus format and OTLP format at the same time and compare the + // results. + // I'm keeping this as a backup for now, but this should be converted to an integration test. + // + // To run it, add prometheus-metrics-exporter-httpserver as a dependency and configure Prometheus + // to scrape from port 9400 in addition to receiving metrics via remote write. + + /* + public static void main(String[] args) throws Exception { + + Counter counter = Counter.newBuilder() + .withName("uptime_seconds_total") + .withHelp("total number of seconds since this application was started") + .withUnit(Unit.SECONDS) + .register(); + + Gauge gauge = Gauge.newBuilder() + .withName("temperature_celsius") + .withHelp("temperature in celsius") + .withUnit(Unit.CELSIUS) + .withLabelNames("location") + .register(); + + gauge.labelValues("inside").set(23.4); + gauge.labelValues("outside").set(9.3); + + // By default, the histogram will be exported as an exponential histogram in OpenTelemetry. + Histogram histogram = Histogram.newBuilder() + .withName("request_latency_seconds") + .withHelp("Request duration in seconds") + .withUnit(Unit.SECONDS) + .withLabelNames("http_status") + .register(); + + Random random = new Random(0); + for (int i = 0; i < 1000; i++) { + histogram.labelValues("200").observe(random.nextGaussian()); + } + + // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry + Histogram classicHistogram = Histogram.newBuilder() + .withName("request_size_bytes") + .withHelp("Request size in Bytes") + .withUnit(Unit.BYTES) + .withLabelNames("path") + .classicOnly() + .withClassicBuckets(128, 256, 512, 1024, 2048) + .register(); + + for (int i = 0; i < 15; i++) { + classicHistogram.labelValues("200").observe(random.nextInt(3000)); + } + + Summary summary = Summary.newBuilder() + .withName("response_latency_seconds") + .withHelp("Response latency seconds") + .withUnit(Unit.BYTES) + .withQuantile(0.95) + .withQuantile(0.99) + .register(); + + for (int i = 0; i < 1000; i++) { + summary.observe(random.nextGaussian()); + } + + Info targetInfo = Info.newBuilder() + .withName("target_info") + .withHelp("OTel resource") + .withLabelNames("service.version") + .register(); + targetInfo.setLabelValues("1.0.0"); + + Info scopeInfo = Info.newBuilder() + .withName("otel_scope_info") + .withLabelNames("otel.scope.name", "otel.scope.version", "library_mascot") + .register(); + + scopeInfo.setLabelValues("my.instrumentation.lib", "100.3", "bear"); + + Info info = Info.newBuilder() + .withName("java_runtime_info") + .withHelp("Java runtime info") + .withLabelNames("version", "vendor", "runtime") + .register(); + + String version = System.getProperty("java.runtime.version", "unknown"); + String vendor = System.getProperty("java.vm.vendor", "unknown"); + String runtime = System.getProperty("java.runtime.name", "unknown"); + + info.setLabelValues(version, vendor, runtime); + + StateSet stateSet = StateSet.newBuilder() + .withName("feature_flags") + .withLabelNames("env") + .withStates("feature1", "feature2") + .register(); + + stateSet.labelValues("dev").setFalse("feature1"); + stateSet.labelValues("dev").setTrue("feature2"); + + PrometheusRegistry.defaultRegistry.register(() -> UnknownSnapshot.newBuilder() + .withName("my_unknown_metric") + .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder() + .withLabels(Labels.of("a", "1", "b", "2")) + .withValue(3.0) + .build()) + .build()); + + HTTPServer server = HTTPServer.newBuilder() + .withPort(9400) + .buildAndStart(); + System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + + OpenTelemetryExporter.newBuilder() + .withIntervalSeconds(5) + .buildAndStart(); + + while (true) { + Thread.sleep(1000); + counter.inc(); + } + } + */ } diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index d3d8f37e5..eb2fa4f19 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -1,57 +1,56 @@ package io.prometheus.metrics.examples.tomcat_servlet; +import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; + import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.core.metrics.Histogram; import io.prometheus.metrics.model.snapshots.Unit; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.io.IOException; import java.util.Random; -import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; - -/** - * Hello World REST servlet, with an example counter and an example histogram. - */ +/** Hello World REST servlet, with an example counter and an example histogram. */ public class HelloWorldServlet extends HttpServlet { - private final Random random = new Random(0); - - // Note: The requests_total counter is not a great example, because the - // request_duration_seconds histogram below also has a count with the number of requests. - private final Counter counter = Counter.builder() - .name("requests_total") - .help("total number of requests") - .labelNames("http_status") - .register(); - - private final Histogram histogram = Histogram.builder() - .name("request_duration_seconds") - .help("request duration in seconds") - .unit(Unit.SECONDS) - .labelNames("http_status") - .register(); - - public HelloWorldServlet() { - counter.initLabelValues("200"); - histogram.initLabelValues("200"); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - long start = System.nanoTime(); - try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); - resp.setStatus(200); - resp.setContentType("text/plain"); - resp.getWriter().println("Hello, World!"); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } finally { - counter.labelValues("200").inc(); - histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); - } + private final Random random = new Random(0); + + // Note: The requests_total counter is not a great example, because the + // request_duration_seconds histogram below also has a count with the number of requests. + private final Counter counter = + Counter.builder() + .name("requests_total") + .help("total number of requests") + .labelNames("http_status") + .register(); + + private final Histogram histogram = + Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .labelNames("http_status") + .register(); + + public HelloWorldServlet() { + counter.initLabelValues("200"); + histogram.initLabelValues("200"); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + long start = System.nanoTime(); + try { + Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("Hello, World!"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + counter.labelValues("200").inc(); + histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start)); } + } } diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java index 4ce6353db..81bc2ac19 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java @@ -2,38 +2,35 @@ import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; -import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.startup.Tomcat; - import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; -/** - * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. - */ +/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */ public class Main { - public static void main(String[] args) throws LifecycleException, IOException { + public static void main(String[] args) throws LifecycleException, IOException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - Tomcat tomcat = new Tomcat(); - Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-"); - tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath()); + Tomcat tomcat = new Tomcat(); + Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-"); + tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath()); - Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); - Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); - ctx.addServletMappingDecoded("/*", "hello"); + Tomcat.addServlet(ctx, "hello", new HelloWorldServlet()); + ctx.addServletMappingDecoded("/*", "hello"); - Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); - ctx.addServletMappingDecoded("/metrics", "metrics"); + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); - tomcat.getConnector(); - tomcat.start(); - tomcat.getServer().await(); - } + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } } diff --git a/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java index 591216fb7..b23fd054d 100644 --- a/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java +++ b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java @@ -4,36 +4,35 @@ import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.IOException; import java.util.Random; public class Main { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - Histogram histogram = Histogram.builder() - .name("request_latency_seconds") - .help("request latency in seconds") - .unit(Unit.SECONDS) - .labelNames("path", "status") - .register(); + Histogram histogram = + Histogram.builder() + .name("request_latency_seconds") + .help("request latency in seconds") + .unit(Unit.SECONDS) + .labelNames("path", "status") + .register(); - HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + HTTPServer server = HTTPServer.builder().port(9400).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - Random random = new Random(0); + Random random = new Random(0); - while (true) { - double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); - String status = random.nextInt(100) < 20 ? "500" : "200"; - histogram.labelValues("/", status).observe(duration); - Thread.sleep(1000); - } + while (true) { + double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); + String status = random.nextInt(100) < 20 ? "500" : "200"; + histogram.labelValues("/", status).observe(duration); + Thread.sleep(1000); } + } } diff --git a/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java index 97611fe7b..e1f5954bc 100644 --- a/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java +++ b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java @@ -4,42 +4,42 @@ import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.IOException; import java.util.Random; public class Main { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - Histogram requestDuration = Histogram.builder() - .name("request_duration_seconds") - .help("request duration in seconds") - .unit(Unit.SECONDS) - .register(); + Histogram requestDuration = + Histogram.builder() + .name("request_duration_seconds") + .help("request duration in seconds") + .unit(Unit.SECONDS) + .register(); - Histogram requestSize = Histogram.builder() - .name("request_size_bytes") - .help("request size in bytes") - .unit(Unit.BYTES) - .register(); + Histogram requestSize = + Histogram.builder() + .name("request_size_bytes") + .help("request size in bytes") + .unit(Unit.BYTES) + .register(); - HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + HTTPServer server = HTTPServer.builder().port(9400).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - Random random = new Random(0); + Random random = new Random(0); - while (true) { - double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); - double size = random.nextInt(1000) + 256; - requestDuration.observe(duration); - requestSize.observe(size); - Thread.sleep(1000); - } + while (true) { + double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2); + double size = random.nextInt(1000) + 256; + requestDuration.observe(duration); + requestSize.observe(size); + Thread.sleep(1000); } + } } diff --git a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java index cb0488d57..dd9dbcdcb 100644 --- a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java +++ b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java @@ -3,39 +3,34 @@ import io.prometheus.client.Counter; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.simpleclient.bridge.SimpleclientCollector; - import java.io.IOException; -/** - * Simple example of the simpleclient backwards compatibility module. - */ +/** Simple example of the simpleclient backwards compatibility module. */ public class Main { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - // The following call will register all metrics from the old CollectorRegistry.defaultRegistry - // with the new PrometheusRegistry.defaultRegistry. + // The following call will register all metrics from the old CollectorRegistry.defaultRegistry + // with the new PrometheusRegistry.defaultRegistry. - SimpleclientCollector.builder().register(); + SimpleclientCollector.builder().register(); - // Register a counter with the old CollectorRegistry. - // It doesn't matter whether the counter is registered before or after bridging with PrometheusRegistry. + // Register a counter with the old CollectorRegistry. + // It doesn't matter whether the counter is registered before or after bridging with + // PrometheusRegistry. - Counter simpleclientCounter = Counter.build() - .name("events_total") - .help("total number of events") - .register(); + Counter simpleclientCounter = + Counter.build().name("events_total").help("total number of events").register(); - simpleclientCounter.inc(); + simpleclientCounter.inc(); - // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric. + // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric. - HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + HTTPServer server = HTTPServer.builder().port(9400).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - Thread.currentThread().join(); - } + Thread.currentThread().join(); + } } diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java index d60e53979..0e6cfbcc6 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java @@ -1,36 +1,33 @@ package io.prometheus.client.it.common; -import org.testcontainers.containers.output.OutputFrame; - import java.util.function.Consumer; +import org.testcontainers.containers.output.OutputFrame; -/** - * Print Docker logs from TestContainers to stdout or stderr. - */ +/** Print Docker logs from TestContainers to stdout or stderr. */ public class LogConsumer implements Consumer { - private final String prefix; + private final String prefix; - private LogConsumer(String prefix) { - this.prefix = prefix; - } + private LogConsumer(String prefix) { + this.prefix = prefix; + } - public static LogConsumer withPrefix(String prefix) { - return new LogConsumer(prefix); - } + public static LogConsumer withPrefix(String prefix) { + return new LogConsumer(prefix); + } - @Override - public void accept(OutputFrame outputFrame) { - switch (outputFrame.getType()) { - case STDOUT: - System.out.print(prefix + " - " + outputFrame.getUtf8String()); - break; - case END: - System.out.println(prefix + " - END"); - break; - default: // STDERR or unexpected - System.err.print(prefix + " - " + outputFrame.getUtf8String()); - break; - } + @Override + public void accept(OutputFrame outputFrame) { + switch (outputFrame.getType()) { + case STDOUT: + System.out.print(prefix + " - " + outputFrame.getUtf8String()); + break; + case END: + System.out.println(prefix + " - END"); + break; + default: // STDERR or unexpected + System.err.print(prefix + " - " + outputFrame.getUtf8String()); + break; } + } } diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java index dc9a32992..783ccb7a5 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java @@ -1,6 +1,6 @@ package io.prometheus.client.it.common; -import org.junit.Assert; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import java.io.File; import java.io.IOException; @@ -8,94 +8,96 @@ import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.function.Predicate; +import org.junit.Assert; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; - -/** - * Temporary directory in ./target/ to be mounted as a volume in Docker containers. - */ +/** Temporary directory in ./target/ to be mounted as a volume in Docker containers. */ public class Volume { - private final Path tmpDir; // will be created in the ./target/ directory + private final Path tmpDir; // will be created in the ./target/ directory - private Volume(Path tmpDir) { - this.tmpDir = tmpDir; - } + private Volume(Path tmpDir) { + this.tmpDir = tmpDir; + } - public static Volume create(String prefix) throws IOException, URISyntaxException { - Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent(); - Assert.assertEquals("failed to locate target/ directory", "target", targetDir.getFileName().toString()); - return new Volume(Files.createTempDirectory(targetDir, prefix + "-")); - } + public static Volume create(String prefix) throws IOException, URISyntaxException { + Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent(); + Assert.assertEquals( + "failed to locate target/ directory", "target", targetDir.getFileName().toString()); + return new Volume(Files.createTempDirectory(targetDir, prefix + "-")); + } - /** - * Copy a file or directory to this volume. - * @param src is relative to {@code ./target/} - */ - public Volume copy(String src) throws IOException { - Path srcPath = tmpDir.getParent().resolve(src); - if (Files.isRegularFile(srcPath)) { - Files.copy(srcPath, tmpDir.resolve(srcPath.getFileName()), REPLACE_EXISTING); - } else if (Files.isDirectory(srcPath)) { - Path dest = tmpDir.resolve(srcPath.getFileName()); - Files.createDirectories(dest); - Files.walkFileTree(srcPath, new SimpleFileVisitor() { + /** + * Copy a file or directory to this volume. + * + * @param src is relative to {@code ./target/} + */ + public Volume copy(String src) throws IOException { + Path srcPath = tmpDir.getParent().resolve(src); + if (Files.isRegularFile(srcPath)) { + Files.copy(srcPath, tmpDir.resolve(srcPath.getFileName()), REPLACE_EXISTING); + } else if (Files.isDirectory(srcPath)) { + Path dest = tmpDir.resolve(srcPath.getFileName()); + Files.createDirectories(dest); + Files.walkFileTree( + srcPath, + new SimpleFileVisitor() { - // create parent directories - @Override - public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { - Files.createDirectories(dest.resolve(srcPath.relativize(dir))); - return FileVisitResult.CONTINUE; - } + // create parent directories + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException { + Files.createDirectories(dest.resolve(srcPath.relativize(dir))); + return FileVisitResult.CONTINUE; + } - // copy file - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.copy(file, dest.resolve(srcPath.relativize(file)), REPLACE_EXISTING); - return FileVisitResult.CONTINUE; - } - }); - } else { - Assert.fail(src + ": No such file or directory"); - } - return this; + // copy file + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + Files.copy(file, dest.resolve(srcPath.relativize(file)), REPLACE_EXISTING); + return FileVisitResult.CONTINUE; + } + }); + } else { + Assert.fail(src + ": No such file or directory"); } + return this; + } - /** - * Remove files in tmpDir if they match the predicate. - */ - public void rm(Predicate predicate) throws IOException { - Files.walkFileTree(tmpDir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (predicate.test(file)) { - Files.delete(file); - } - return FileVisitResult.CONTINUE; + /** Remove files in tmpDir if they match the predicate. */ + public void rm(Predicate predicate) throws IOException { + Files.walkFileTree( + tmpDir, + new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException { + if (predicate.test(file)) { + Files.delete(file); } + return FileVisitResult.CONTINUE; + } }); - } + } - public String getHostPath() { - return tmpDir.toString(); - } + public String getHostPath() { + return tmpDir.toString(); + } - /** - * Recursively remove tmpDir and its contents. - */ - public void remove() throws IOException { - if (!deleteRecursively(tmpDir.toFile())) { - throw new IOException(tmpDir + ": Failed to remove temporary test directory."); - } + /** Recursively remove tmpDir and its contents. */ + public void remove() throws IOException { + if (!deleteRecursively(tmpDir.toFile())) { + throw new IOException(tmpDir + ": Failed to remove temporary test directory."); } + } - private boolean deleteRecursively(File file) { - File[] allContents = file.listFiles(); - if (allContents != null) { - for (File child : allContents) { - deleteRecursively(child); - } - } - return file.delete(); + private boolean deleteRecursively(File file) { + File[] allContents = file.listFiles(); + if (allContents != null) { + for (File child : allContents) { + deleteRecursively(child); + } } + return file.delete(); + } } diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index b8cdc5141..4c665dd81 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -6,85 +6,87 @@ import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.IOException; public class HTTPServerSample { - enum Mode { - success, - error - } - - public static void main(String[] args) throws IOException, InterruptedException { - - if (args.length != 2) { - System.err.println("Usage: java -jar exporter-httpserver-sample.jar "); - System.err.println("Where mode is \"success\" or \"error\"."); - System.exit(1); - } - - int port = parsePortOrExit(args[0]); - Mode mode = parseModeOrExit(args[1]); - - Counter counter = Counter.builder() - .name("uptime_seconds_total") - .help("total number of seconds since this application was started") - .unit(Unit.SECONDS) - .register(); - counter.inc(17); + enum Mode { + success, + error + } - Info info = Info.builder() - .name("integration_test_info") - .help("Info metric on this integration test") - .labelNames("test_name") - .register(); - info.addLabelValues("exporter-httpserver-sample"); + public static void main(String[] args) throws IOException, InterruptedException { - Gauge gauge = Gauge.builder() - .name("temperature_celsius") - .help("Temperature in Celsius") - .unit(Unit.CELSIUS) - .labelNames("location") - .register(); - gauge.labelValues("inside").set(23.0); - gauge.labelValues("outside").set(27.0); + if (args.length != 2) { + System.err.println("Usage: java -jar exporter-httpserver-sample.jar "); + System.err.println("Where mode is \"success\" or \"error\"."); + System.exit(1); + } - if (mode == Mode.error) { - Collector failingCollector = () -> { - throw new RuntimeException("Simulating an error."); - }; + int port = parsePortOrExit(args[0]); + Mode mode = parseModeOrExit(args[1]); + + Counter counter = + Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) + .register(); + counter.inc(17); + + Info info = + Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") + .register(); + info.addLabelValues("exporter-httpserver-sample"); + + Gauge gauge = + Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") + .register(); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); + + if (mode == Mode.error) { + Collector failingCollector = + () -> { + throw new RuntimeException("Simulating an error."); + }; + + PrometheusRegistry.defaultRegistry.register(failingCollector); + } - PrometheusRegistry.defaultRegistry.register(failingCollector); - } + HTTPServer server = HTTPServer.builder().port(port).buildAndStart(); - HTTPServer server = HTTPServer.builder() - .port(port) - .buildAndStart(); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + Thread.currentThread().join(); // wait forever + } - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - Thread.currentThread().join(); // wait forever + private static int parsePortOrExit(String port) { + try { + return Integer.parseInt(port); + } catch (NumberFormatException e) { + System.err.println("\"" + port + "\": Invalid port number."); + System.exit(1); } - - private static int parsePortOrExit(String port) { - try { - return Integer.parseInt(port); - } catch (NumberFormatException e) { - System.err.println("\"" + port + "\": Invalid port number."); - System.exit(1); - } - return 0; // this won't happen - } - - private static Mode parseModeOrExit(String mode) { - try { - return Mode.valueOf(mode); - } catch (IllegalArgumentException e) { - System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); - System.exit(1); - } - return null; // this won't happen + return 0; // this won't happen + } + + private static Mode parseModeOrExit(String mode) { + try { + return Mode.valueOf(mode); + } catch (IllegalArgumentException e) { + System.err.println( + "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); + System.exit(1); } + return null; // this won't happen + } } diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java index 9e1a22487..1cc16ee4b 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java @@ -6,99 +6,101 @@ import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.Unit; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.ServletHandler; -/** - * Sample application using the {@link PrometheusMetricsServlet} in Jetty. - */ +/** Sample application using the {@link PrometheusMetricsServlet} in Jetty. */ public class ExporterServletJettySample { - enum Mode { - success, - error - } + enum Mode { + success, + error + } + + public static void main(String[] args) throws Exception { - public static void main(String[] args) throws Exception { - - if (args.length != 2) { - System.err.println("Usage: java -jar exporter-servlet-jetty-sample.jar "); - System.err.println("Where mode is \"success\" or \"error\"."); - System.exit(1); - } - - int port = parsePortOrExit(args[0]); - Mode mode = parseModeOrExit(args[1]); - - Counter counter = Counter.builder() - .name("uptime_seconds_total") - .help("total number of seconds since this application was started") - .unit(Unit.SECONDS) - .register(); - counter.inc(17); - - Info info = Info.builder() - .name("integration_test_info") - .help("Info metric on this integration test") - .labelNames("test_name") - .register(); - info.addLabelValues("exporter-servlet-jetty-sample"); - - Gauge gauge = Gauge.builder() - .name("temperature_celsius") - .help("Temperature in Celsius") - .unit(Unit.CELSIUS) - .labelNames("location") - .register(); - gauge.labelValues("inside").set(23.0); - gauge.labelValues("outside").set(27.0); - - if (mode == Mode.error) { - Collector failingCollector = () -> { - throw new RuntimeException("Simulating an error."); - }; - - PrometheusRegistry.defaultRegistry.register(failingCollector); - } - - Server server = new Server(); - - // set port - ServerConnector connector = new ServerConnector(server); - connector.setPort(port); - server.setConnectors(new Connector[] {connector}); - - // register servlet - ServletHandler servletHandler = new ServletHandler(); - servletHandler.addServletWithMapping(PrometheusMetricsServlet.class, "/metrics"); - server.setHandler(servletHandler); - - System.out.println("Running on http://localhost:" + port + "/metrics"); - - // run - server.start(); + if (args.length != 2) { + System.err.println("Usage: java -jar exporter-servlet-jetty-sample.jar "); + System.err.println("Where mode is \"success\" or \"error\"."); + System.exit(1); } - private static int parsePortOrExit(String port) { - try { - return Integer.parseInt(port); - } catch (NumberFormatException e) { - System.err.println("\"" + port + "\": Invalid port number."); - System.exit(1); - } - return 0; // this won't happen + int port = parsePortOrExit(args[0]); + Mode mode = parseModeOrExit(args[1]); + + Counter counter = + Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) + .register(); + counter.inc(17); + + Info info = + Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") + .register(); + info.addLabelValues("exporter-servlet-jetty-sample"); + + Gauge gauge = + Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") + .register(); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); + + if (mode == Mode.error) { + Collector failingCollector = + () -> { + throw new RuntimeException("Simulating an error."); + }; + + PrometheusRegistry.defaultRegistry.register(failingCollector); } - private static Mode parseModeOrExit(String mode) { - try { - return Mode.valueOf(mode); - } catch (IllegalArgumentException e) { - System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); - System.exit(1); - } - return null; // this won't happen + Server server = new Server(); + + // set port + ServerConnector connector = new ServerConnector(server); + connector.setPort(port); + server.setConnectors(new Connector[] {connector}); + + // register servlet + ServletHandler servletHandler = new ServletHandler(); + servletHandler.addServletWithMapping(PrometheusMetricsServlet.class, "/metrics"); + server.setHandler(servletHandler); + + System.out.println("Running on http://localhost:" + port + "/metrics"); + + // run + server.start(); + } + + private static int parsePortOrExit(String port) { + try { + return Integer.parseInt(port); + } catch (NumberFormatException e) { + System.err.println("\"" + port + "\": Invalid port number."); + System.exit(1); + } + return 0; // this won't happen + } + + private static Mode parseModeOrExit(String mode) { + try { + return Mode.valueOf(mode); + } catch (IllegalArgumentException e) { + System.err.println( + "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); + System.exit(1); } + return null; // this won't happen + } } diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java index 8d13082b7..ead2ee88f 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java @@ -6,99 +6,100 @@ import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.Unit; -import org.apache.catalina.Context; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.startup.Tomcat; - import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; -/** - * Sample application using the {@link PrometheusMetricsServlet} in Tomcat. - */ +/** Sample application using the {@link PrometheusMetricsServlet} in Tomcat. */ public class ExporterServletTomcatSample { - enum Mode { - success, - error - } - - public static void main(String[] args) throws LifecycleException, IOException { + enum Mode { + success, + error + } - if (args.length != 2) { - System.err.println("Usage: java -jar exporter-servlet-tomcat-sample.jar "); - System.err.println("Where mode is \"success\" or \"error\"."); - System.exit(1); - } + public static void main(String[] args) throws LifecycleException, IOException { - int port = parsePortOrExit(args[0]); - Mode mode = parseModeOrExit(args[1]); - - Counter counter = Counter.builder() - .name("uptime_seconds_total") - .help("total number of seconds since this application was started") - .unit(Unit.SECONDS) - .register(); - counter.inc(17); - - Info info = Info.builder() - .name("integration_test_info") - .help("Info metric on this integration test") - .labelNames("test_name") - .register(); - info.addLabelValues("exporter-servlet-tomcat-sample"); - - Gauge gauge = Gauge.builder() - .name("temperature_celsius") - .help("Temperature in Celsius") - .unit(Unit.CELSIUS) - .labelNames("location") - .register(); - gauge.labelValues("inside").set(23.0); - gauge.labelValues("outside").set(27.0); - - if (mode == Mode.error) { - Collector failingCollector = () -> { - throw new RuntimeException("Simulating an error."); - }; - - PrometheusRegistry.defaultRegistry.register(failingCollector); - } - - Tomcat tomcat = new Tomcat(); - tomcat.setPort(port); - - Path tmpDir = Files.createTempDirectory("exporter-servlet-tomcat-sample-"); - tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath()); - Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); - Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); - ctx.addServletMappingDecoded("/metrics", "metrics"); - - tomcat.getConnector(); - tomcat.start(); - tomcat.getServer().await(); + if (args.length != 2) { + System.err.println("Usage: java -jar exporter-servlet-tomcat-sample.jar "); + System.err.println("Where mode is \"success\" or \"error\"."); + System.exit(1); } - private static int parsePortOrExit(String port) { - try { - return Integer.parseInt(port); - } catch (NumberFormatException e) { - System.err.println("\"" + port + "\": Invalid port number."); - System.exit(1); - } - return 0; // this won't happen + int port = parsePortOrExit(args[0]); + Mode mode = parseModeOrExit(args[1]); + + Counter counter = + Counter.builder() + .name("uptime_seconds_total") + .help("total number of seconds since this application was started") + .unit(Unit.SECONDS) + .register(); + counter.inc(17); + + Info info = + Info.builder() + .name("integration_test_info") + .help("Info metric on this integration test") + .labelNames("test_name") + .register(); + info.addLabelValues("exporter-servlet-tomcat-sample"); + + Gauge gauge = + Gauge.builder() + .name("temperature_celsius") + .help("Temperature in Celsius") + .unit(Unit.CELSIUS) + .labelNames("location") + .register(); + gauge.labelValues("inside").set(23.0); + gauge.labelValues("outside").set(27.0); + + if (mode == Mode.error) { + Collector failingCollector = + () -> { + throw new RuntimeException("Simulating an error."); + }; + + PrometheusRegistry.defaultRegistry.register(failingCollector); } - private static Mode parseModeOrExit(String mode) { - try { - return Mode.valueOf(mode); - } catch (IllegalArgumentException e) { - System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); - System.exit(1); - } - return null; // this won't happen + Tomcat tomcat = new Tomcat(); + tomcat.setPort(port); + + Path tmpDir = Files.createTempDirectory("exporter-servlet-tomcat-sample-"); + tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath()); + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet()); + ctx.addServletMappingDecoded("/metrics", "metrics"); + + tomcat.getConnector(); + tomcat.start(); + tomcat.getServer().await(); + } + + private static int parsePortOrExit(String port) { + try { + return Integer.parseInt(port); + } catch (NumberFormatException e) { + System.err.println("\"" + port + "\": Invalid port number."); + System.exit(1); + } + return 0; // this won't happen + } + + private static Mode parseModeOrExit(String mode) { + try { + return Mode.valueOf(mode); + } catch (IllegalArgumentException e) { + System.err.println( + "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\"."); + System.exit(1); } + return null; // this won't happen + } } diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 657b890db..949f71840 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -1,17 +1,10 @@ package io.prometheus.metrics.it.exporter.test; +import static java.nio.charset.StandardCharsets.UTF_8; + import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Volume; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; -import org.apache.commons.io.IOUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.testcontainers.containers.BindMode; -import org.testcontainers.containers.GenericContainer; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -26,317 +19,397 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; - -import static java.nio.charset.StandardCharsets.UTF_8; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.testcontainers.containers.BindMode; +import org.testcontainers.containers.GenericContainer; @RunWith(Parameterized.class) public class ExporterIT { - private final GenericContainer sampleAppContainer; - private final Volume sampleAppVolume; - private final String sampleApp; + private final GenericContainer sampleAppContainer; + private final Volume sampleAppVolume; + private final String sampleApp; - @Parameterized.Parameters(name = "{0}") - public static String[] sampleApps() { - return new String[]{ - "exporter-httpserver-sample", - "exporter-servlet-tomcat-sample", - "exporter-servlet-jetty-sample", - }; - } + @Parameterized.Parameters(name = "{0}") + public static String[] sampleApps() { + return new String[] { + "exporter-httpserver-sample", + "exporter-servlet-tomcat-sample", + "exporter-servlet-jetty-sample", + }; + } - public ExporterIT(String sampleApp) throws IOException, URISyntaxException { - this.sampleApp = sampleApp; - this.sampleAppVolume = Volume.create("it-exporter") - .copy("../../it-" + sampleApp + "/target/" + sampleApp + ".jar"); - this.sampleAppContainer = new GenericContainer<>("openjdk:17") - .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY) - .withWorkingDirectory("/app") - .withLogConsumer(LogConsumer.withPrefix(sampleApp)) - .withExposedPorts(9400); - } + public ExporterIT(String sampleApp) throws IOException, URISyntaxException { + this.sampleApp = sampleApp; + this.sampleAppVolume = + Volume.create("it-exporter") + .copy("../../it-" + sampleApp + "/target/" + sampleApp + ".jar"); + this.sampleAppContainer = + new GenericContainer<>("openjdk:17") + .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY) + .withWorkingDirectory("/app") + .withLogConsumer(LogConsumer.withPrefix(sampleApp)) + .withExposedPorts(9400); + } - @After - public void tearDown() throws IOException { - sampleAppContainer.stop(); - sampleAppVolume.remove(); - } + @After + public void tearDown() throws IOException { + sampleAppContainer.stop(); + sampleAppVolume.remove(); + } - @Test - public void testOpenMetricsTextFormat() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", "", "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); - assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length")); - String bodyString = new String(response.body); - Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - // OpenMetrics text format has a UNIT. - Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); - } + @Test + public void testOpenMetricsTextFormat() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape("GET", "", "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); + Assert.assertEquals(200, response.status); + assertContentType( + "application/openmetrics-text; version=1.0.0; charset=utf-8", + response.getHeader("Content-Type")); + Assert.assertNull(response.getHeader("Content-Encoding")); + Assert.assertNull(response.getHeader("Transfer-Encoding")); + Assert.assertEquals( + Integer.toString(response.body.length), response.getHeader("Content-Length")); + String bodyString = new String(response.body); + Assert.assertTrue( + bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); + Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); + Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); + Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); + // OpenMetrics text format has a UNIT. + Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); + } - @Test - public void testPrometheusTextFormat() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", ""); - Assert.assertEquals(200, response.status); - assertContentType("text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length")); - String bodyString = new String(response.body); - Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - // Prometheus text format does not have a UNIT. - Assert.assertFalse(bodyString.contains("# UNIT uptime_seconds seconds")); - } + @Test + public void testPrometheusTextFormat() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = scrape("GET", ""); + Assert.assertEquals(200, response.status); + assertContentType( + "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); + Assert.assertNull(response.getHeader("Content-Encoding")); + Assert.assertNull(response.getHeader("Transfer-Encoding")); + Assert.assertEquals( + Integer.toString(response.body.length), response.getHeader("Content-Length")); + String bodyString = new String(response.body); + Assert.assertTrue( + bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); + Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); + Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); + Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); + // Prometheus text format does not have a UNIT. + Assert.assertFalse(bodyString.contains("# UNIT uptime_seconds seconds")); + } - @Test - public void testPrometheusProtobufFormat() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", "", "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); - Assert.assertEquals(200, response.status); - assertContentType("application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length")); - List metrics = new ArrayList<>(); - InputStream in = new ByteArrayInputStream(response.body); - while (in.available() > 0) { - metrics.add(Metrics.MetricFamily.parseDelimitedFrom(in)); - } - Assert.assertEquals(3, metrics.size()); - // metrics are sorted by name - Assert.assertEquals("integration_test_info", metrics.get(0).getName()); - Assert.assertEquals("temperature_celsius", metrics.get(1).getName()); - Assert.assertEquals("uptime_seconds_total", metrics.get(2).getName()); + @Test + public void testPrometheusProtobufFormat() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + "", + "Accept", + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); + Assert.assertEquals(200, response.status); + assertContentType( + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", + response.getHeader("Content-Type")); + Assert.assertNull(response.getHeader("Content-Encoding")); + Assert.assertNull(response.getHeader("Transfer-Encoding")); + Assert.assertEquals( + Integer.toString(response.body.length), response.getHeader("Content-Length")); + List metrics = new ArrayList<>(); + InputStream in = new ByteArrayInputStream(response.body); + while (in.available() > 0) { + metrics.add(Metrics.MetricFamily.parseDelimitedFrom(in)); } + Assert.assertEquals(3, metrics.size()); + // metrics are sorted by name + Assert.assertEquals("integration_test_info", metrics.get(0).getName()); + Assert.assertEquals("temperature_celsius", metrics.get(1).getName()); + Assert.assertEquals("uptime_seconds_total", metrics.get(2).getName()); + } - @Test - public void testCompression() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", "", - "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8", - "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); - if (response.getHeader("Content-Length") != null) { - // The servlet container might set a content length as the body is very small. - Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - } else { - // If no content length is set, transfer-encoding chunked must be used. - Assert.assertEquals("chunked", response.getHeader("Transfer-Encoding")); - } - assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertTrue(body.contains("uptime_seconds_total 17.0")); + @Test + public void testCompression() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + "", + "Accept", + "application/openmetrics-text; version=1.0.0; charset=utf-8", + "Accept-Encoding", + "gzip"); + Assert.assertEquals(200, response.status); + Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + if (response.getHeader("Content-Length") != null) { + // The servlet container might set a content length as the body is very small. + Assert.assertEquals( + Integer.toString(response.body.length), response.getHeader("Content-Length")); + Assert.assertNull(response.getHeader("Transfer-Encoding")); + } else { + // If no content length is set, transfer-encoding chunked must be used. + Assert.assertEquals("chunked", response.getHeader("Transfer-Encoding")); } + assertContentType( + "application/openmetrics-text; version=1.0.0; charset=utf-8", + response.getHeader("Content-Type")); + String body = + new String( + IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), + UTF_8); + Assert.assertTrue(body.contains("uptime_seconds_total 17.0")); + } - @Test - public void testErrorHandling() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "error") - .start(); - Response response = scrape("GET", ""); - Assert.assertEquals(500, response.status); - Assert.assertTrue(new String(response.body, UTF_8).contains("Simulating an error.")); - } + @Test + public void testErrorHandling() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "error") + .start(); + Response response = scrape("GET", ""); + Assert.assertEquals(500, response.status); + Assert.assertTrue(new String(response.body, UTF_8).contains("Simulating an error.")); + } - @Test - public void testHeadRequest() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response fullResponse = scrape("GET", ""); - int size = fullResponse.body.length; - Assert.assertTrue(size > 0); - Response headResponse = scrape("HEAD", ""); - Assert.assertEquals(200, headResponse.status); - Assert.assertEquals(Integer.toString(size), headResponse.getHeader("Content-Length")); - Assert.assertEquals(0, headResponse.body.length); - } + @Test + public void testHeadRequest() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response fullResponse = scrape("GET", ""); + int size = fullResponse.body.length; + Assert.assertTrue(size > 0); + Response headResponse = scrape("HEAD", ""); + Assert.assertEquals(200, headResponse.status); + Assert.assertEquals(Integer.toString(size), headResponse.getHeader("Content-Length")); + Assert.assertEquals(0, headResponse.body.length); + } - @Test - public void testDebug() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", "debug=openmetrics"); - Assert.assertEquals(200, response.status); - assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); - String bodyString = new String(response.body, UTF_8); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); - } + @Test + public void testDebug() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = scrape("GET", "debug=openmetrics"); + Assert.assertEquals(200, response.status); + assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); + String bodyString = new String(response.body, UTF_8); + Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); + Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); + } - @Test - public void testNameFilter() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("integration_test_info") + "&" + nameParam("uptime_seconds_total"), - "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); - assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - String bodyString = new String(response.body, UTF_8); - Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - Assert.assertFalse(bodyString.contains("temperature_celsius")); - } + @Test + public void testNameFilter() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + nameParam("integration_test_info") + "&" + nameParam("uptime_seconds_total"), + "Accept", + "application/openmetrics-text; version=1.0.0; charset=utf-8"); + Assert.assertEquals(200, response.status); + assertContentType( + "application/openmetrics-text; version=1.0.0; charset=utf-8", + response.getHeader("Content-Type")); + String bodyString = new String(response.body, UTF_8); + Assert.assertTrue( + bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); + Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); + Assert.assertFalse(bodyString.contains("temperature_celsius")); + } - @Test - public void testEmptyResponseOpenMetrics() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("none_existing"), - "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); - assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length")); - Assert.assertEquals("# EOF\n", new String(response.body, UTF_8)); - } + @Test + public void testEmptyResponseOpenMetrics() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + nameParam("none_existing"), + "Accept", + "application/openmetrics-text; version=1.0.0; charset=utf-8"); + Assert.assertEquals(200, response.status); + assertContentType( + "application/openmetrics-text; version=1.0.0; charset=utf-8", + response.getHeader("Content-Type")); + Assert.assertEquals( + Integer.toString(response.body.length), response.getHeader("Content-Length")); + Assert.assertEquals("# EOF\n", new String(response.body, UTF_8)); + } - @Test - public void testEmptyResponseText() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("none_existing")); - Assert.assertEquals(200, response.status); - assertContentType("text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); - if (response.getHeader("Content-Length") != null) { // HTTPServer does not send a zero content length, which is ok - Assert.assertEquals("0", response.getHeader("Content-Length")); - } - Assert.assertEquals(0, response.body.length); + @Test + public void testEmptyResponseText() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = scrape("GET", nameParam("none_existing")); + Assert.assertEquals(200, response.status); + assertContentType( + "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); + if (response.getHeader("Content-Length") + != null) { // HTTPServer does not send a zero content length, which is ok + Assert.assertEquals("0", response.getHeader("Content-Length")); } + Assert.assertEquals(0, response.body.length); + } - @Test - public void testEmptyResponseProtobuf() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("none_existing"), - "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); - Assert.assertEquals(200, response.status); - assertContentType("application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type")); - Assert.assertEquals(0, response.body.length); - } + @Test + public void testEmptyResponseProtobuf() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + nameParam("none_existing"), + "Accept", + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); + Assert.assertEquals(200, response.status); + assertContentType( + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", + response.getHeader("Content-Type")); + Assert.assertEquals(0, response.body.length); + } - @Test - public void testEmptyResponseGzipOpenMetrics() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("none_existing"), - "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8", - "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); - String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertEquals("# EOF\n", body); - } + @Test + public void testEmptyResponseGzipOpenMetrics() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = + scrape( + "GET", + nameParam("none_existing"), + "Accept", + "application/openmetrics-text; version=1.0.0; charset=utf-8", + "Accept-Encoding", + "gzip"); + Assert.assertEquals(200, response.status); + Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + String body = + new String( + IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), + UTF_8); + Assert.assertEquals("# EOF\n", body); + } - @Test - public void testEmptyResponseGzipText() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", nameParam("none_existing"), - "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); - String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertEquals(0, body.length()); - } + @Test + public void testEmptyResponseGzipText() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = scrape("GET", nameParam("none_existing"), "Accept-Encoding", "gzip"); + Assert.assertEquals(200, response.status); + Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + String body = + new String( + IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), + UTF_8); + Assert.assertEquals(0, body.length()); + } - private String nameParam(String name) throws UnsupportedEncodingException { - return URLEncoder.encode("name[]", UTF_8.name()) + "=" + URLEncoder.encode(name, UTF_8.name()); - } + private String nameParam(String name) throws UnsupportedEncodingException { + return URLEncoder.encode("name[]", UTF_8.name()) + "=" + URLEncoder.encode(name, UTF_8.name()); + } - @Test - public void testDebugUnknown() throws IOException { - sampleAppContainer - .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") - .start(); - Response response = scrape("GET", "debug=unknown"); - Assert.assertEquals(500, response.status); - assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); - } + @Test + public void testDebugUnknown() throws IOException { + sampleAppContainer + .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") + .start(); + Response response = scrape("GET", "debug=unknown"); + Assert.assertEquals(500, response.status); + assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); + } - private void assertContentType(String expected, String actual) { - if (!expected.replace(" ", "").equals(actual)) { - Assert.assertEquals(expected, actual); - } + private void assertContentType(String expected, String actual) { + if (!expected.replace(" ", "").equals(actual)) { + Assert.assertEquals(expected, actual); } + } - private Response scrape(String method, String queryString, String... requestHeaders) throws IOException { - long timeoutMillis = TimeUnit.SECONDS.toMillis(5); - URL url = new URL("http://localhost:" + sampleAppContainer.getMappedPort(9400) + "/metrics?" + queryString); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod(method); - for (int i = 0; i < requestHeaders.length; i += 2) { - con.setRequestProperty(requestHeaders[i], requestHeaders[i + 1]); - } - long start = System.currentTimeMillis(); - Exception exception = null; - while (System.currentTimeMillis() - start < timeoutMillis) { - try { - if (con.getResponseCode() == 200) { - return new Response(con.getResponseCode(), con.getHeaderFields(), IOUtils.toByteArray(con.getInputStream())); - } else { - return new Response(con.getResponseCode(), con.getHeaderFields(), IOUtils.toByteArray(con.getErrorStream())); - } - } catch (Exception e) { - exception = e; - try { - Thread.sleep(100); - } catch (InterruptedException ignored) { - } - } + private Response scrape(String method, String queryString, String... requestHeaders) + throws IOException { + long timeoutMillis = TimeUnit.SECONDS.toMillis(5); + URL url = + new URL( + "http://localhost:" + + sampleAppContainer.getMappedPort(9400) + + "/metrics?" + + queryString); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod(method); + for (int i = 0; i < requestHeaders.length; i += 2) { + con.setRequestProperty(requestHeaders[i], requestHeaders[i + 1]); + } + long start = System.currentTimeMillis(); + Exception exception = null; + while (System.currentTimeMillis() - start < timeoutMillis) { + try { + if (con.getResponseCode() == 200) { + return new Response( + con.getResponseCode(), + con.getHeaderFields(), + IOUtils.toByteArray(con.getInputStream())); + } else { + return new Response( + con.getResponseCode(), + con.getHeaderFields(), + IOUtils.toByteArray(con.getErrorStream())); } - if (exception != null) { - exception.printStackTrace(); + } catch (Exception e) { + exception = e; + try { + Thread.sleep(100); + } catch (InterruptedException ignored) { } - Assert.fail("timeout while getting metrics from " + url); - return null; // will not happen + } + } + if (exception != null) { + exception.printStackTrace(); } + Assert.fail("timeout while getting metrics from " + url); + return null; // will not happen + } - private static class Response { - private final int status; - private final Map headers; - private final byte[] body; + private static class Response { + private final int status; + private final Map headers; + private final byte[] body; - private Response(int status, Map> headers, byte[] body) { - this.status = status; - this.headers = new HashMap<>(headers.size()); - this.body = body; - for (Map.Entry> entry : headers.entrySet()) { - if (entry.getKey() != null) { // HttpUrlConnection uses pseudo key "null" for the status line - this.headers.put(entry.getKey().toLowerCase(), entry.getValue().get(0)); - } - } + private Response(int status, Map> headers, byte[] body) { + this.status = status; + this.headers = new HashMap<>(headers.size()); + this.body = body; + for (Map.Entry> entry : headers.entrySet()) { + if (entry.getKey() + != null) { // HttpUrlConnection uses pseudo key "null" for the status line + this.headers.put(entry.getKey().toLowerCase(), entry.getValue().get(0)); } + } + } - private String getHeader(String name) { - // HTTP headers are case-insensitive - return headers.get(name.toLowerCase()); - } + private String getHeader(String name) { + // HTTP headers are case-insensitive + return headers.get(name.toLowerCase()); } + } } diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java index 69ef63081..6376b03fb 100644 --- a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java +++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java @@ -1,131 +1,126 @@ package io.prometheus.metrics.it.pushgateway; +import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS; + import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.core.metrics.Histogram; import io.prometheus.metrics.exporter.pushgateway.Format; import io.prometheus.metrics.exporter.pushgateway.HttpConnectionFactory; import io.prometheus.metrics.exporter.pushgateway.PushGateway; import io.prometheus.metrics.model.snapshots.Unit; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; -import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS; - -/** - * Example application using the {@link PushGateway}. - */ +/** Example application using the {@link PushGateway}. */ public class PushGatewayTestApp { - public static void main(String[] args) throws IOException { - if (args.length != 1) { - System.err.println("Usage: java -jar pushgateway-test-app.jar "); - System.exit(-1); - } - switch (args[0]) { - case "simple": - runSimpleTest(); - break; - case "textFormat": - runTextFormatTest(); - break; - case "basicauth": - runBasicAuthTest(); - break; - case "ssl": - runSslTest(); - break; - default: - System.err.println(args[0] + ": Not implemented."); - System.exit(-1); - } + public static void main(String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Usage: java -jar pushgateway-test-app.jar "); + System.exit(-1); } - - private static void runSimpleTest() throws IOException { - makeMetrics(); - PushGateway pg = PushGateway.builder().build(); - System.out.println("Pushing metrics..."); - pg.push(); - System.out.println("Push successful."); + switch (args[0]) { + case "simple": + runSimpleTest(); + break; + case "textFormat": + runTextFormatTest(); + break; + case "basicauth": + runBasicAuthTest(); + break; + case "ssl": + runSslTest(); + break; + default: + System.err.println(args[0] + ": Not implemented."); + System.exit(-1); } + } - private static void runTextFormatTest() throws IOException { - makeMetrics(); - PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build(); - System.out.println("Pushing metrics..."); - pg.push(); - System.out.println("Push successful."); - } + private static void runSimpleTest() throws IOException { + makeMetrics(); + PushGateway pg = PushGateway.builder().build(); + System.out.println("Pushing metrics..."); + pg.push(); + System.out.println("Push successful."); + } - private static void runBasicAuthTest() throws IOException { - makeMetrics(); - PushGateway pg = PushGateway.builder() - .basicAuth("my_user", "secret_password") - .build(); - System.out.println("Pushing metrics..."); - pg.push(); - System.out.println("Push successful."); - } + private static void runTextFormatTest() throws IOException { + makeMetrics(); + PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build(); + System.out.println("Pushing metrics..."); + pg.push(); + System.out.println("Push successful."); + } - private static void runSslTest() throws IOException { - makeMetrics(); - PushGateway pg = PushGateway.builder() - .scheme(HTTPS) - .connectionFactory(insecureConnectionFactory) - .build(); - System.out.println("Pushing metrics..."); - pg.push(); - System.out.println("Push successful."); - } + private static void runBasicAuthTest() throws IOException { + makeMetrics(); + PushGateway pg = PushGateway.builder().basicAuth("my_user", "secret_password").build(); + System.out.println("Pushing metrics..."); + pg.push(); + System.out.println("Push successful."); + } + + private static void runSslTest() throws IOException { + makeMetrics(); + PushGateway pg = + PushGateway.builder().scheme(HTTPS).connectionFactory(insecureConnectionFactory).build(); + System.out.println("Pushing metrics..."); + pg.push(); + System.out.println("Push successful."); + } - static TrustManager insecureTrustManager = new X509TrustManager() { + static TrustManager insecureTrustManager = + new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; + return null; } @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) { - } + public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) { - } - }; + public void checkServerTrusted(X509Certificate[] chain, String authType) {} + }; - static HttpConnectionFactory insecureConnectionFactory = url -> { + static HttpConnectionFactory insecureConnectionFactory = + url -> { try { - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, new TrustManager[]{insecureTrustManager}, null); - SSLContext.setDefault(sslContext); + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[] {insecureTrustManager}, null); + SSLContext.setDefault(sslContext); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.setHostnameVerifier((hostname, session) -> true); - return connection; + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setHostnameVerifier((hostname, session) -> true); + return connection; } catch (NoSuchAlgorithmException | KeyManagementException e) { - throw new RuntimeException(e); + throw new RuntimeException(e); } - }; + }; - private static void makeMetrics() { - Histogram sizes = Histogram.builder() - .name("file_sizes_bytes") - .classicUpperBounds(256, 512, 1024, 2048) - .unit(Unit.BYTES) - .register(); - sizes.observe(513); - sizes.observe(814); - sizes.observe(1553); - Gauge duration = Gauge.builder() - .name("my_batch_job_duration_seconds") - .help("Duration of my batch job in seconds.") - .unit(Unit.SECONDS) - .register(); - duration.set(0.5); - } + private static void makeMetrics() { + Histogram sizes = + Histogram.builder() + .name("file_sizes_bytes") + .classicUpperBounds(256, 512, 1024, 2048) + .unit(Unit.BYTES) + .register(); + sizes.observe(513); + sizes.observe(814); + sizes.observe(1553); + Gauge duration = + Gauge.builder() + .name("my_batch_job_duration_seconds") + .help("Duration of my batch job in seconds.") + .unit(Unit.SECONDS) + .register(); + duration.set(0.5); + } } diff --git a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java index 6b89a8c58..7e1198a55 100644 --- a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java +++ b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java @@ -6,6 +6,9 @@ import com.squareup.okhttp.*; import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Volume; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.concurrent.TimeUnit; import net.minidev.json.JSONArray; import org.junit.After; import org.junit.Assert; @@ -17,212 +20,247 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.MountableFile; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.concurrent.TimeUnit; - public class PushGatewayIT { - private GenericContainer sampleAppContainer; - private GenericContainer pushGatewayContainer; - private GenericContainer prometheusContainer; - private Volume sampleAppVolume; - - @Before - public void setUp() throws IOException, URISyntaxException { - Network network = Network.newNetwork(); - sampleAppVolume = Volume.create("it-pushgateway") - .copy("pushgateway-test-app.jar"); - pushGatewayContainer = new GenericContainer<>("prom/pushgateway:v1.8.0") - .withExposedPorts(9091) - .withNetwork(network) - .withNetworkAliases("pushgateway") - .withLogConsumer(LogConsumer.withPrefix("pushgateway")) - .waitingFor(Wait.forListeningPort()); - sampleAppContainer = new GenericContainer<>("openjdk:17") - .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY) - .withNetwork(network) - .withWorkingDirectory("/app") - .dependsOn(pushGatewayContainer) - .withLogConsumer(LogConsumer.withPrefix("test-app")); - prometheusContainer = new GenericContainer<>("prom/prometheus:v2.51.2") - .withNetwork(network) - .dependsOn(pushGatewayContainer) - .withExposedPorts(9090) - .withLogConsumer(LogConsumer.withPrefix("prometheus")); - } + private GenericContainer sampleAppContainer; + private GenericContainer pushGatewayContainer; + private GenericContainer prometheusContainer; + private Volume sampleAppVolume; - @After - public void tearDown() throws IOException { - prometheusContainer.stop(); - pushGatewayContainer.stop(); - sampleAppContainer.stop(); - sampleAppVolume.remove(); - } + @Before + public void setUp() throws IOException, URISyntaxException { + Network network = Network.newNetwork(); + sampleAppVolume = Volume.create("it-pushgateway").copy("pushgateway-test-app.jar"); + pushGatewayContainer = + new GenericContainer<>("prom/pushgateway:v1.8.0") + .withExposedPorts(9091) + .withNetwork(network) + .withNetworkAliases("pushgateway") + .withLogConsumer(LogConsumer.withPrefix("pushgateway")) + .waitingFor(Wait.forListeningPort()); + sampleAppContainer = + new GenericContainer<>("openjdk:17") + .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY) + .withNetwork(network) + .withWorkingDirectory("/app") + .dependsOn(pushGatewayContainer) + .withLogConsumer(LogConsumer.withPrefix("test-app")); + prometheusContainer = + new GenericContainer<>("prom/prometheus:v2.51.2") + .withNetwork(network) + .dependsOn(pushGatewayContainer) + .withExposedPorts(9090) + .withLogConsumer(LogConsumer.withPrefix("prometheus")); + } - final OkHttpClient client = new OkHttpClient(); - - @Test - public void testSimple() throws IOException, InterruptedException { - pushGatewayContainer - .start(); - sampleAppContainer - .withCommand("java", - "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", - "-jar", - "/app/pushgateway-test-app.jar", - "simple" - ).start(); - prometheusContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml") - .start(); - awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); - assertMetrics(); - } + @After + public void tearDown() throws IOException { + prometheusContainer.stop(); + pushGatewayContainer.stop(); + sampleAppContainer.stop(); + sampleAppVolume.remove(); + } - @Test - public void testTextFormat() throws IOException, InterruptedException { - pushGatewayContainer - .start(); - sampleAppContainer - .withCommand("java", - "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", - "-jar", - "/app/pushgateway-test-app.jar", - "textFormat" - ).start(); - prometheusContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml") - .start(); - awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); - assertMetrics(); - } + final OkHttpClient client = new OkHttpClient(); - @Test - public void testBasicAuth() throws IOException, InterruptedException { - pushGatewayContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-basicauth.yaml"), "/pushgateway/pushgateway-basicauth.yaml") - .withCommand("--web.config.file", "pushgateway-basicauth.yaml") - .start(); - sampleAppContainer - .withCommand("java", - "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", - "-jar", - "/app/pushgateway-test-app.jar", - "basicauth" - ).start(); - prometheusContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-basicauth.yaml"), "/etc/prometheus/prometheus.yml") - .start(); - awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); - assertMetrics(); - } + @Test + public void testSimple() throws IOException, InterruptedException { + pushGatewayContainer.start(); + sampleAppContainer + .withCommand( + "java", + "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", + "-jar", + "/app/pushgateway-test-app.jar", + "simple") + .start(); + prometheusContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/prometheus.yaml"), + "/etc/prometheus/prometheus.yml") + .start(); + awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); + assertMetrics(); + } - @Test - public void testSsl() throws InterruptedException, IOException { - pushGatewayContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-ssl.yaml"), "/pushgateway/pushgateway-ssl.yaml") - .withCommand("--web.config.file", "pushgateway-ssl.yaml") - .start(); - sampleAppContainer - .withCommand("java", - "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", - "-jar", - "/app/pushgateway-test-app.jar", - "ssl" - ).start(); - prometheusContainer - .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-ssl.yaml"), "/etc/prometheus/prometheus.yml") - .start(); - awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); - assertMetrics(); - } + @Test + public void testTextFormat() throws IOException, InterruptedException { + pushGatewayContainer.start(); + sampleAppContainer + .withCommand( + "java", + "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", + "-jar", + "/app/pushgateway-test-app.jar", + "textFormat") + .start(); + prometheusContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/prometheus.yaml"), + "/etc/prometheus/prometheus.yml") + .start(); + awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); + assertMetrics(); + } - @Test - public void testProtobuf() throws IOException, InterruptedException { - pushGatewayContainer - .start(); - sampleAppContainer - .withCommand("java", - "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", - "-jar", - "/app/pushgateway-test-app.jar", - "simple" - ).start(); - prometheusContainer - .withCommand("--enable-feature=native-histograms", "--config.file", "/etc/prometheus/prometheus.yml") - .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml") - .start(); - awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); - assertNativeHistogram(); - } + @Test + public void testBasicAuth() throws IOException, InterruptedException { + pushGatewayContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/pushgateway-basicauth.yaml"), + "/pushgateway/pushgateway-basicauth.yaml") + .withCommand("--web.config.file", "pushgateway-basicauth.yaml") + .start(); + sampleAppContainer + .withCommand( + "java", + "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", + "-jar", + "/app/pushgateway-test-app.jar", + "basicauth") + .start(); + prometheusContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/prometheus-basicauth.yaml"), + "/etc/prometheus/prometheus.yml") + .start(); + awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); + assertMetrics(); + } - private void assertMetrics() throws IOException, InterruptedException { - double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app"); - Assert.assertEquals(0.5, value, 0.0); - value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512"); - Assert.assertEquals(0.0, value, 0.0); - value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024"); - Assert.assertEquals(2.0, value, 0.0); - value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf"); - Assert.assertEquals(3.0, value, 0.0); - } + @Test + public void testSsl() throws InterruptedException, IOException { + pushGatewayContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/pushgateway-ssl.yaml"), + "/pushgateway/pushgateway-ssl.yaml") + .withCommand("--web.config.file", "pushgateway-ssl.yaml") + .start(); + sampleAppContainer + .withCommand( + "java", + "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", + "-jar", + "/app/pushgateway-test-app.jar", + "ssl") + .start(); + prometheusContainer + .withCopyFileToContainer( + MountableFile.forClasspathResource("/prometheus-ssl.yaml"), + "/etc/prometheus/prometheus.yml") + .start(); + awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); + assertMetrics(); + } - private double getValue(String name, String... labels) throws IOException, InterruptedException { - String scrapeResponseJson = scrape(name); - Criteria criteria = Criteria.where("metric.__name__").eq(name); - for (int i = 0; i < labels.length; i += 2) { - criteria = criteria.and("metric." + labels[i]).eq(labels[i + 1]); - } - JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]"); - Assert.assertEquals(1, result.size()); - return Double.valueOf(result.get(0).toString()); - } + @Test + public void testProtobuf() throws IOException, InterruptedException { + pushGatewayContainer.start(); + sampleAppContainer + .withCommand( + "java", + "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091", + "-jar", + "/app/pushgateway-test-app.jar", + "simple") + .start(); + prometheusContainer + .withCommand( + "--enable-feature=native-histograms", "--config.file", "/etc/prometheus/prometheus.yml") + .withCopyFileToContainer( + MountableFile.forClasspathResource("/prometheus.yaml"), + "/etc/prometheus/prometheus.yml") + .start(); + awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS); + assertNativeHistogram(); + } - private void assertNativeHistogram() throws IOException, InterruptedException { - double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app"); - Assert.assertEquals(3, count, 0.0); - } + private void assertMetrics() throws IOException, InterruptedException { + double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app"); + Assert.assertEquals(0.5, value, 0.0); + value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512"); + Assert.assertEquals(0.0, value, 0.0); + value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024"); + Assert.assertEquals(2.0, value, 0.0); + value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf"); + Assert.assertEquals(3.0, value, 0.0); + } - private double getNativeHistogramCount(String name, String job) throws IOException, InterruptedException { - String scrapeResponseJson = scrape("histogram_count(" + name + ")"); - Criteria criteria = Criteria.where("metric.job").eq(job); - JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]"); - return Double.valueOf(result.get(0).toString()); + private double getValue(String name, String... labels) throws IOException, InterruptedException { + String scrapeResponseJson = scrape(name); + Criteria criteria = Criteria.where("metric.__name__").eq(name); + for (int i = 0; i < labels.length; i += 2) { + criteria = criteria.and("metric." + labels[i]).eq(labels[i + 1]); } + JSONArray result = + JsonPath.parse(scrapeResponseJson) + .read("$.data.result" + Filter.filter(criteria) + ".value[1]"); + Assert.assertEquals(1, result.size()); + return Double.valueOf(result.get(0).toString()); + } + + private void assertNativeHistogram() throws IOException, InterruptedException { + double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app"); + Assert.assertEquals(3, count, 0.0); + } + + private double getNativeHistogramCount(String name, String job) + throws IOException, InterruptedException { + String scrapeResponseJson = scrape("histogram_count(" + name + ")"); + Criteria criteria = Criteria.where("metric.job").eq(job); + JSONArray result = + JsonPath.parse(scrapeResponseJson) + .read("$.data.result" + Filter.filter(criteria) + ".value[1]"); + return Double.valueOf(result.get(0).toString()); + } - private String scrape(String query) throws IOException, InterruptedException { - System.out.println("Querying http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090)); - HttpUrl baseUrl = HttpUrl.parse("http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090) + "/api/v1/query"); - HttpUrl url = baseUrl.newBuilder() - .addQueryParameter("query", query) - .build(); - long timeRemaining = TimeUnit.SECONDS.toMillis(15); - while (timeRemaining > 0) { - Request request = new Request.Builder().url(url).build(); - Call call = client.newCall(request); - Response response = call.execute(); - String body = response.body().string(); - if (!body.contains("\"result\":[]")) { - // Result when data is not available yet: - // {"status":"success","data":{"resultType":"vector","result":[]}} - return body; - } - Thread.sleep(250); - timeRemaining -= 250; - } - Assert.fail("timeout while scraping " + url); - return null; + private String scrape(String query) throws IOException, InterruptedException { + System.out.println( + "Querying http://" + + prometheusContainer.getHost() + + ":" + + prometheusContainer.getMappedPort(9090)); + HttpUrl baseUrl = + HttpUrl.parse( + "http://" + + prometheusContainer.getHost() + + ":" + + prometheusContainer.getMappedPort(9090) + + "/api/v1/query"); + HttpUrl url = baseUrl.newBuilder().addQueryParameter("query", query).build(); + long timeRemaining = TimeUnit.SECONDS.toMillis(15); + while (timeRemaining > 0) { + Request request = new Request.Builder().url(url).build(); + Call call = client.newCall(request); + Response response = call.execute(); + String body = response.body().string(); + if (!body.contains("\"result\":[]")) { + // Result when data is not available yet: + // {"status":"success","data":{"resultType":"vector","result":[]}} + return body; + } + Thread.sleep(250); + timeRemaining -= 250; } + Assert.fail("timeout while scraping " + url); + return null; + } - private void awaitTermination(GenericContainer container, long timeout, TimeUnit unit) throws InterruptedException { - long waitTimeMillis = 0; - while (container.isRunning()) { - if (waitTimeMillis > unit.toMillis(timeout)) { - Assert.fail(container.getContainerName() + " did not terminate after " + timeout + " " + unit + "."); - } - Thread.sleep(20); - waitTimeMillis += 20; - } + private void awaitTermination(GenericContainer container, long timeout, TimeUnit unit) + throws InterruptedException { + long waitTimeMillis = 0; + while (container.isRunning()) { + if (waitTimeMillis > unit.toMillis(timeout)) { + Assert.fail( + container.getContainerName() + + " did not terminate after " + + timeout + + " " + + unit + + "."); + } + Thread.sleep(20); + waitTimeMillis += 20; } + } } diff --git a/pom.xml b/pom.xml index 44eadc391..5ab8f42e2 100644 --- a/pom.xml +++ b/pom.xml @@ -169,7 +169,6 @@ com.diffplug.spotless spotless-maven-plugin - origin/main diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java index ff955bc50..f660725bf 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java @@ -2,113 +2,135 @@ import java.util.Map; -/** - * Properties starting with io.prometheus.exemplars - */ +/** Properties starting with io.prometheus.exemplars */ public class ExemplarsProperties { - private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds"; - private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds"; - private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds"; - - private final Integer minRetentionPeriodSeconds; - private final Integer maxRetentionPeriodSeconds; - private final Integer sampleIntervalMilliseconds; - - private ExemplarsProperties( - Integer minRetentionPeriodSeconds, - Integer maxRetentionPeriodSeconds, - Integer sampleIntervalMilliseconds) { - this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; - this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; - this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; + private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds"; + private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds"; + private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds"; + + private final Integer minRetentionPeriodSeconds; + private final Integer maxRetentionPeriodSeconds; + private final Integer sampleIntervalMilliseconds; + + private ExemplarsProperties( + Integer minRetentionPeriodSeconds, + Integer maxRetentionPeriodSeconds, + Integer sampleIntervalMilliseconds) { + this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; + this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; + this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; + } + + /** + * Minimum time how long Exemplars are kept before they may be replaced by new Exemplars. + * + *

      Default see {@code ExemplarSamplerConfig.DEFAULT_MIN_RETENTION_PERIOD_SECONDS} + */ + public Integer getMinRetentionPeriodSeconds() { + return minRetentionPeriodSeconds; + } + + /** + * Maximum time how long Exemplars are kept before they are evicted. + * + *

      Default see {@code ExemplarSamplerConfig.DEFAULT_MAX_RETENTION_PERIOD_SECONDS} + */ + public Integer getMaxRetentionPeriodSeconds() { + return maxRetentionPeriodSeconds; + } + + /** + * Time between attempts to sample new Exemplars. This is a performance improvement for + * high-frequency applications, because with the sample interval we make sure that the exemplar + * sampler is not called for every single request. + * + *

      Default see {@code ExemplarSamplerConfig.DEFAULT_SAMPLE_INTERVAL_MILLISECONDS} + */ + public Integer getSampleIntervalMilliseconds() { + return sampleIntervalMilliseconds; + } + + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExemplarsProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + Integer minRetentionPeriodSeconds = + Util.loadInteger(prefix + "." + MIN_RETENTION_PERIOD_SECONDS, properties); + Integer maxRetentionPeriodSeconds = + Util.loadInteger(prefix + "." + MAX_RETENTION_PERIOD_SECONDS, properties); + Integer sampleIntervalMilliseconds = + Util.loadInteger(prefix + "." + SAMPLE_INTERVAL_MILLISECONDS, properties); + + Util.assertValue( + minRetentionPeriodSeconds, + t -> t > 0, + "Expecting value > 0.", + prefix, + MIN_RETENTION_PERIOD_SECONDS); + Util.assertValue( + minRetentionPeriodSeconds, + t -> t > 0, + "Expecting value > 0.", + prefix, + MAX_RETENTION_PERIOD_SECONDS); + Util.assertValue( + sampleIntervalMilliseconds, + t -> t > 0, + "Expecting value > 0.", + prefix, + SAMPLE_INTERVAL_MILLISECONDS); + + if (minRetentionPeriodSeconds != null && maxRetentionPeriodSeconds != null) { + if (minRetentionPeriodSeconds > maxRetentionPeriodSeconds) { + throw new PrometheusPropertiesException( + prefix + + "." + + MIN_RETENTION_PERIOD_SECONDS + + " must not be greater than " + + prefix + + "." + + MAX_RETENTION_PERIOD_SECONDS + + "."); + } } - /** - * Minimum time how long Exemplars are kept before they may be replaced by new Exemplars. - *

      - * Default see {@code ExemplarSamplerConfig.DEFAULT_MIN_RETENTION_PERIOD_SECONDS} - */ - public Integer getMinRetentionPeriodSeconds() { - return minRetentionPeriodSeconds; - } - - /** - * Maximum time how long Exemplars are kept before they are evicted. - *

      - * Default see {@code ExemplarSamplerConfig.DEFAULT_MAX_RETENTION_PERIOD_SECONDS} - */ - public Integer getMaxRetentionPeriodSeconds() { - return maxRetentionPeriodSeconds; - } + return new ExemplarsProperties( + minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds); + } - /** - * Time between attempts to sample new Exemplars. This is a performance improvement for high-frequency - * applications, because with the sample interval we make sure that the exemplar sampler is not called - * for every single request. - *

      - * Default see {@code ExemplarSamplerConfig.DEFAULT_SAMPLE_INTERVAL_MILLISECONDS} - */ - public Integer getSampleIntervalMilliseconds() { - return sampleIntervalMilliseconds; - } + public static Builder builder() { + return new Builder(); + } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExemplarsProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - Integer minRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MIN_RETENTION_PERIOD_SECONDS, properties); - Integer maxRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MAX_RETENTION_PERIOD_SECONDS, properties); - Integer sampleIntervalMilliseconds = Util.loadInteger(prefix + "." + SAMPLE_INTERVAL_MILLISECONDS, properties); - - Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MIN_RETENTION_PERIOD_SECONDS); - Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MAX_RETENTION_PERIOD_SECONDS); - Util.assertValue(sampleIntervalMilliseconds, t -> t > 0, "Expecting value > 0.", prefix, SAMPLE_INTERVAL_MILLISECONDS); - - if (minRetentionPeriodSeconds != null && maxRetentionPeriodSeconds != null) { - if (minRetentionPeriodSeconds > maxRetentionPeriodSeconds) { - throw new PrometheusPropertiesException(prefix + "." + MIN_RETENTION_PERIOD_SECONDS + " must not be greater than " + prefix + "." + MAX_RETENTION_PERIOD_SECONDS + "."); - } - } - - return new ExemplarsProperties( - minRetentionPeriodSeconds, - maxRetentionPeriodSeconds, - sampleIntervalMilliseconds - ); - } + public static class Builder { - public static Builder builder() { - return new Builder(); - } + private Integer minRetentionPeriodSeconds; + private Integer maxRetentionPeriodSeconds; + private Integer sampleIntervalMilliseconds; - public static class Builder { + private Builder() {} - private Integer minRetentionPeriodSeconds; - private Integer maxRetentionPeriodSeconds; - private Integer sampleIntervalMilliseconds; - - private Builder() { - } - - public Builder minRetentionPeriodSeconds(int minRetentionPeriodSeconds) { - this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; - return this; - } + public Builder minRetentionPeriodSeconds(int minRetentionPeriodSeconds) { + this.minRetentionPeriodSeconds = minRetentionPeriodSeconds; + return this; + } - public Builder maxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) { - this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; - return this; - } + public Builder maxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) { + this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds; + return this; + } - public Builder sampleIntervalMilliseconds(int sampleIntervalMilliseconds) { - this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; - return this; - } + public Builder sampleIntervalMilliseconds(int sampleIntervalMilliseconds) { + this.sampleIntervalMilliseconds = sampleIntervalMilliseconds; + return this; + } - public ExemplarsProperties build() { - return new ExemplarsProperties(minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds); - } + public ExemplarsProperties build() { + return new ExemplarsProperties( + minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds); } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java index e9cc46767..4758a48fe 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -6,112 +6,124 @@ import java.util.List; import java.util.Map; -/** - * Properties starting with io.prometheus.exporter.filter - */ +/** Properties starting with io.prometheus.exporter.filter */ public class ExporterFilterProperties { - public static final String METRIC_NAME_MUST_BE_EQUAL_TO = "metricNameMustBeEqualTo"; - public static final String METRIC_NAME_MUST_NOT_BE_EQUAL_TO = "metricNameMustNotBeEqualTo"; - public static final String METRIC_NAME_MUST_START_WITH = "metricNameMustStartWith"; - public static final String METRIC_NAME_MUST_NOT_START_WITH = "metricNameMustNotStartWith"; - - private final List allowedNames; - private final List excludedNames; - private final List allowedPrefixes; - private final List excludedPrefixes; - - private ExporterFilterProperties(List allowedNames, List excludedNames, List allowedPrefixes, List excludedPrefixes) { - this(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, ""); - } - - private ExporterFilterProperties(List allowedNames, List excludedNames, List allowedPrefixes, List excludedPrefixes, String prefix) { - this.allowedNames = allowedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedNames)); - this.excludedNames = excludedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedNames)); - this.allowedPrefixes = allowedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedPrefixes)); - this.excludedPrefixes = excludedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedPrefixes)); - validate(prefix); - } - - public List getAllowedMetricNames() { - return allowedNames; - } - - public List getExcludedMetricNames() { - return excludedNames; - } - - public List getAllowedMetricNamePrefixes() { - return allowedPrefixes; - } - - public List getExcludedMetricNamePrefixes() { - return excludedPrefixes; + public static final String METRIC_NAME_MUST_BE_EQUAL_TO = "metricNameMustBeEqualTo"; + public static final String METRIC_NAME_MUST_NOT_BE_EQUAL_TO = "metricNameMustNotBeEqualTo"; + public static final String METRIC_NAME_MUST_START_WITH = "metricNameMustStartWith"; + public static final String METRIC_NAME_MUST_NOT_START_WITH = "metricNameMustNotStartWith"; + + private final List allowedNames; + private final List excludedNames; + private final List allowedPrefixes; + private final List excludedPrefixes; + + private ExporterFilterProperties( + List allowedNames, + List excludedNames, + List allowedPrefixes, + List excludedPrefixes) { + this(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, ""); + } + + private ExporterFilterProperties( + List allowedNames, + List excludedNames, + List allowedPrefixes, + List excludedPrefixes, + String prefix) { + this.allowedNames = + allowedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedNames)); + this.excludedNames = + excludedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedNames)); + this.allowedPrefixes = + allowedPrefixes == null + ? null + : Collections.unmodifiableList(new ArrayList<>(allowedPrefixes)); + this.excludedPrefixes = + excludedPrefixes == null + ? null + : Collections.unmodifiableList(new ArrayList<>(excludedPrefixes)); + validate(prefix); + } + + public List getAllowedMetricNames() { + return allowedNames; + } + + public List getExcludedMetricNames() { + return excludedNames; + } + + public List getAllowedMetricNamePrefixes() { + return allowedPrefixes; + } + + public List getExcludedMetricNamePrefixes() { + return excludedPrefixes; + } + + private void validate(String prefix) throws PrometheusPropertiesException {} + + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExporterFilterProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + List allowedNames = + Util.loadStringList(prefix + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties); + List excludedNames = + Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties); + List allowedPrefixes = + Util.loadStringList(prefix + "." + METRIC_NAME_MUST_START_WITH, properties); + List excludedPrefixes = + Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); + return new ExporterFilterProperties( + allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private List allowedNames; + private List excludedNames; + private List allowedPrefixes; + private List excludedPrefixes; + + private Builder() {} + + /** Only allowed metric names will be exposed. */ + public Builder allowedNames(String... allowedNames) { + this.allowedNames = Arrays.asList(allowedNames); + return this; } - private void validate(String prefix) throws PrometheusPropertiesException { + /** Excluded metric names will not be exposed. */ + public Builder excludedNames(String... excludedNames) { + this.excludedNames = Arrays.asList(excludedNames); + return this; } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExporterFilterProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - List allowedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties); - List excludedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties); - List allowedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_START_WITH, properties); - List excludedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); - return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); + /** Only metrics with a name starting with an allowed prefix will be exposed. */ + public Builder allowedPrefixes(String... allowedPrefixes) { + this.allowedPrefixes = Arrays.asList(allowedPrefixes); + return this; } - public static Builder builder() { - return new Builder(); + /** Metrics with a name starting with an excluded prefix will not be exposed. */ + public Builder excludedPrefixes(String... excludedPrefixes) { + this.excludedPrefixes = Arrays.asList(excludedPrefixes); + return this; } - public static class Builder { - - private List allowedNames; - private List excludedNames; - private List allowedPrefixes; - private List excludedPrefixes; - - private Builder() { - } - - /** - * Only allowed metric names will be exposed. - */ - public Builder allowedNames(String... allowedNames) { - this.allowedNames = Arrays.asList(allowedNames); - return this; - } - - /** - * Excluded metric names will not be exposed. - */ - public Builder excludedNames(String... excludedNames) { - this.excludedNames = Arrays.asList(excludedNames); - return this; - } - - /** - * Only metrics with a name starting with an allowed prefix will be exposed. - */ - public Builder allowedPrefixes(String... allowedPrefixes) { - this.allowedPrefixes = Arrays.asList(allowedPrefixes); - return this; - } - - /** - * Metrics with a name starting with an excluded prefix will not be exposed. - */ - public Builder excludedPrefixes(String... excludedPrefixes) { - this.excludedPrefixes = Arrays.asList(excludedPrefixes); - return this; - } - - public ExporterFilterProperties build() { - return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes); - } + public ExporterFilterProperties build() { + return new ExporterFilterProperties( + allowedNames, excludedNames, allowedPrefixes, excludedPrefixes); } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java index c458d69d1..fe048ac6b 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java @@ -2,49 +2,48 @@ import java.util.Map; -/** - * Properties starting with io.prometheus.exporter.httpServer - */ +/** Properties starting with io.prometheus.exporter.httpServer */ public class ExporterHttpServerProperties { - private static final String PORT = "port"; - private final Integer port; + private static final String PORT = "port"; + private final Integer port; - private ExporterHttpServerProperties(Integer port) { - this.port = port; - } + private ExporterHttpServerProperties(Integer port) { + this.port = port; + } - public Integer getPort() { - return port; - } + public Integer getPort() { + return port; + } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExporterHttpServerProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - Integer port = Util.loadInteger(prefix + "." + PORT, properties); - Util.assertValue(port, t -> t > 0, "Expecting value > 0", prefix, PORT); - return new ExporterHttpServerProperties(port); - } + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExporterHttpServerProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + Integer port = Util.loadInteger(prefix + "." + PORT, properties); + Util.assertValue(port, t -> t > 0, "Expecting value > 0", prefix, PORT); + return new ExporterHttpServerProperties(port); + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder { + public static class Builder { - private Integer port; + private Integer port; - private Builder() {} + private Builder() {} - public Builder port(int port) { - this.port = port; - return this; - } + public Builder port(int port) { + this.port = port; + return this; + } - public ExporterHttpServerProperties build() { - return new ExporterHttpServerProperties(port); - } + public ExporterHttpServerProperties build() { + return new ExporterHttpServerProperties(port); } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java index 77bcc21cb..b8498d6c5 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java @@ -6,188 +6,222 @@ // TODO: JavaDoc is currently only in OpenTelemetryExporter.Builder. Look there for reference. public class ExporterOpenTelemetryProperties { - // See https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md - private static String PROTOCOL = "protocol"; // otel.exporter.otlp.protocol - private static String ENDPOINT = "endpoint"; // otel.exporter.otlp.endpoint - private static String HEADERS = "headers"; // otel.exporter.otlp.headers - private static String INTERVAL_SECONDS = "intervalSeconds"; // otel.metric.export.interval - private static String TIMEOUT_SECONDS = "timeoutSeconds"; // otel.exporter.otlp.timeout - private static String SERVICE_NAME = "serviceName"; // otel.service.name - private static String SERVICE_NAMESPACE = "serviceNamespace"; - private static String SERVICE_INSTANCE_ID = "serviceInstanceId"; - private static String SERVICE_VERSION = "serviceVersion"; - private static String RESOURCE_ATTRIBUTES = "resourceAttributes"; // otel.resource.attributes - - private final String protocol; - private final String endpoint; - private final Map headers; - private final Integer intervalSeconds; - private final Integer timeoutSeconds; - private final String serviceName; - private final String serviceNamespace; - private final String serviceInstanceId; - private final String serviceVersion; - private final Map resourceAttributes; - - private ExporterOpenTelemetryProperties(String protocol, String endpoint, Map headers, Integer intervalSeconds, Integer timeoutSeconds, String serviceName, String serviceNamespace, String serviceInstanceId, String serviceVersion, Map resourceAttributes) { - this.protocol = protocol; - this.endpoint = endpoint; - this.headers = headers; - this.intervalSeconds = intervalSeconds; - this.timeoutSeconds = timeoutSeconds; - this.serviceName = serviceName; - this.serviceNamespace = serviceNamespace; - this.serviceInstanceId = serviceInstanceId; - this.serviceVersion = serviceVersion; - this.resourceAttributes = resourceAttributes; + // See + // https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md + private static String PROTOCOL = "protocol"; // otel.exporter.otlp.protocol + private static String ENDPOINT = "endpoint"; // otel.exporter.otlp.endpoint + private static String HEADERS = "headers"; // otel.exporter.otlp.headers + private static String INTERVAL_SECONDS = "intervalSeconds"; // otel.metric.export.interval + private static String TIMEOUT_SECONDS = "timeoutSeconds"; // otel.exporter.otlp.timeout + private static String SERVICE_NAME = "serviceName"; // otel.service.name + private static String SERVICE_NAMESPACE = "serviceNamespace"; + private static String SERVICE_INSTANCE_ID = "serviceInstanceId"; + private static String SERVICE_VERSION = "serviceVersion"; + private static String RESOURCE_ATTRIBUTES = "resourceAttributes"; // otel.resource.attributes + + private final String protocol; + private final String endpoint; + private final Map headers; + private final Integer intervalSeconds; + private final Integer timeoutSeconds; + private final String serviceName; + private final String serviceNamespace; + private final String serviceInstanceId; + private final String serviceVersion; + private final Map resourceAttributes; + + private ExporterOpenTelemetryProperties( + String protocol, + String endpoint, + Map headers, + Integer intervalSeconds, + Integer timeoutSeconds, + String serviceName, + String serviceNamespace, + String serviceInstanceId, + String serviceVersion, + Map resourceAttributes) { + this.protocol = protocol; + this.endpoint = endpoint; + this.headers = headers; + this.intervalSeconds = intervalSeconds; + this.timeoutSeconds = timeoutSeconds; + this.serviceName = serviceName; + this.serviceNamespace = serviceNamespace; + this.serviceInstanceId = serviceInstanceId; + this.serviceVersion = serviceVersion; + this.resourceAttributes = resourceAttributes; + } + + public String getProtocol() { + return protocol; + } + + public String getEndpoint() { + return endpoint; + } + + public Map getHeaders() { + return headers; + } + + public Integer getIntervalSeconds() { + return intervalSeconds; + } + + public Integer getTimeoutSeconds() { + return timeoutSeconds; + } + + public String getServiceName() { + return serviceName; + } + + public String getServiceNamespace() { + return serviceNamespace; + } + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public String getServiceVersion() { + return serviceVersion; + } + + public Map getResourceAttributes() { + return resourceAttributes; + } + + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExporterOpenTelemetryProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + String protocol = Util.loadString(prefix + "." + PROTOCOL, properties); + String endpoint = Util.loadString(prefix + "." + ENDPOINT, properties); + Map headers = Util.loadMap(prefix + "." + HEADERS, properties); + Integer intervalSeconds = Util.loadInteger(prefix + "." + INTERVAL_SECONDS, properties); + Integer timeoutSeconds = Util.loadInteger(prefix + "." + TIMEOUT_SECONDS, properties); + String serviceName = Util.loadString(prefix + "." + SERVICE_NAME, properties); + String serviceNamespace = Util.loadString(prefix + "." + SERVICE_NAMESPACE, properties); + String serviceInstanceId = Util.loadString(prefix + "." + SERVICE_INSTANCE_ID, properties); + String serviceVersion = Util.loadString(prefix + "." + SERVICE_VERSION, properties); + Map resourceAttributes = + Util.loadMap(prefix + "." + RESOURCE_ATTRIBUTES, properties); + Util.assertValue(intervalSeconds, t -> t > 0, "Expecting value > 0", prefix, INTERVAL_SECONDS); + Util.assertValue(timeoutSeconds, t -> t > 0, "Expecting value > 0", prefix, TIMEOUT_SECONDS); + if (protocol != null && !protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new PrometheusPropertiesException( + protocol + + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf"); } - - public String getProtocol() { - return protocol; - } - - public String getEndpoint() { - return endpoint; - } - - public Map getHeaders() { - return headers; + return new ExporterOpenTelemetryProperties( + protocol, + endpoint, + headers, + intervalSeconds, + timeoutSeconds, + serviceName, + serviceNamespace, + serviceInstanceId, + serviceVersion, + resourceAttributes); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String protocol; + private String endpoint; + private Map headers = new HashMap<>(); + private Integer intervalSeconds; + private Integer timeoutSeconds; + private String serviceName; + private String serviceNamespace; + private String serviceInstanceId; + private String serviceVersion; + private Map resourceAttributes = new HashMap<>(); + + private Builder() {} + + public Builder protocol(String protocol) { + if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new IllegalArgumentException( + protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); + } + this.protocol = protocol; + return this; } - public Integer getIntervalSeconds() { - return intervalSeconds; + public Builder endpoint(String endpoint) { + this.endpoint = endpoint; + return this; } - public Integer getTimeoutSeconds() { - return timeoutSeconds; + /** Add a request header. Call multiple times to add multiple headers. */ + public Builder header(String name, String value) { + this.headers.put(name, value); + return this; } - public String getServiceName() { - return serviceName; + public Builder intervalSeconds(int intervalSeconds) { + if (intervalSeconds <= 0) { + throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); + } + this.intervalSeconds = intervalSeconds; + return this; } - public String getServiceNamespace() { - return serviceNamespace; + public Builder timeoutSeconds(int timeoutSeconds) { + if (timeoutSeconds <= 0) { + throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); + } + this.timeoutSeconds = timeoutSeconds; + return this; } - public String getServiceInstanceId() { - return serviceInstanceId; + public Builder serviceName(String serviceName) { + this.serviceName = serviceName; + return this; } - public String getServiceVersion() { - return serviceVersion; + public Builder serviceNamespace(String serviceNamespace) { + this.serviceNamespace = serviceNamespace; + return this; } - public Map getResourceAttributes() { - return resourceAttributes; + public Builder serviceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + return this; } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExporterOpenTelemetryProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - String protocol = Util.loadString(prefix + "." + PROTOCOL, properties); - String endpoint = Util.loadString(prefix + "." + ENDPOINT, properties); - Map headers = Util.loadMap(prefix + "." + HEADERS, properties); - Integer intervalSeconds = Util.loadInteger(prefix + "." + INTERVAL_SECONDS, properties); - Integer timeoutSeconds = Util.loadInteger(prefix + "." + TIMEOUT_SECONDS, properties); - String serviceName = Util.loadString(prefix + "." + SERVICE_NAME, properties); - String serviceNamespace = Util.loadString(prefix + "." + SERVICE_NAMESPACE, properties); - String serviceInstanceId = Util.loadString(prefix + "." + SERVICE_INSTANCE_ID, properties); - String serviceVersion = Util.loadString(prefix + "." + SERVICE_VERSION, properties); - Map resourceAttributes = Util.loadMap(prefix + "." + RESOURCE_ATTRIBUTES, properties); - Util.assertValue(intervalSeconds, t -> t > 0, "Expecting value > 0", prefix, INTERVAL_SECONDS); - Util.assertValue(timeoutSeconds, t -> t > 0, "Expecting value > 0", prefix, TIMEOUT_SECONDS); - if (protocol != null && !protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new PrometheusPropertiesException(protocol + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf"); - } - return new ExporterOpenTelemetryProperties(protocol, endpoint, headers, intervalSeconds, timeoutSeconds, serviceName, serviceNamespace, serviceInstanceId, serviceVersion, resourceAttributes); + public Builder serviceVersion(String serviceVersion) { + this.serviceVersion = serviceVersion; + return this; } - public static Builder builder() { - return new Builder(); + public Builder resourceAttribute(String name, String value) { + this.resourceAttributes.put(name, value); + return this; } - public static class Builder { - - private String protocol; - private String endpoint; - private Map headers = new HashMap<>(); - private Integer intervalSeconds; - private Integer timeoutSeconds; - private String serviceName; - private String serviceNamespace; - private String serviceInstanceId; - private String serviceVersion; - private Map resourceAttributes = new HashMap<>(); - - private Builder() {} - - public Builder protocol(String protocol) { - if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new IllegalArgumentException(protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); - } - this.protocol = protocol; - return this; - } - - public Builder endpoint(String endpoint) { - this.endpoint = endpoint; - return this; - } - - /** - * Add a request header. Call multiple times to add multiple headers. - */ - public Builder header(String name, String value) { - this.headers.put(name, value); - return this; - } - - public Builder intervalSeconds(int intervalSeconds) { - if (intervalSeconds <= 0) { - throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); - } - this.intervalSeconds = intervalSeconds; - return this; - } - - public Builder timeoutSeconds(int timeoutSeconds) { - if (timeoutSeconds <= 0) { - throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); - } - this.timeoutSeconds = timeoutSeconds; - return this; - } - - public Builder serviceName(String serviceName) { - this.serviceName = serviceName; - return this; - } - - public Builder serviceNamespace(String serviceNamespace) { - this.serviceNamespace = serviceNamespace; - return this; - } - - public Builder serviceInstanceId(String serviceInstanceId) { - this.serviceInstanceId = serviceInstanceId; - return this; - } - - public Builder serviceVersion(String serviceVersion) { - this.serviceVersion = serviceVersion; - return this; - } - - public Builder resourceAttribute(String name, String value) { - this.resourceAttributes.put(name, value); - return this; - } - - public ExporterOpenTelemetryProperties build() { - return new ExporterOpenTelemetryProperties(protocol, endpoint, headers, intervalSeconds, timeoutSeconds, serviceName, serviceNamespace, serviceInstanceId, serviceVersion, resourceAttributes); - } + public ExporterOpenTelemetryProperties build() { + return new ExporterOpenTelemetryProperties( + protocol, + endpoint, + headers, + intervalSeconds, + timeoutSeconds, + serviceName, + serviceNamespace, + serviceInstanceId, + serviceVersion, + resourceAttributes); } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java index 9493b571c..dd0606e6d 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -2,77 +2,71 @@ import java.util.Map; -/** - * Properties starting with io.prometheus.exporter - */ +/** Properties starting with io.prometheus.exporter */ public class ExporterProperties { - private static final String INCLUDE_CREATED_TIMESTAMPS = "includeCreatedTimestamps"; - private static final String EXEMPLARS_ON_ALL_METRIC_TYPES = "exemplarsOnAllMetricTypes"; + private static final String INCLUDE_CREATED_TIMESTAMPS = "includeCreatedTimestamps"; + private static final String EXEMPLARS_ON_ALL_METRIC_TYPES = "exemplarsOnAllMetricTypes"; - private final Boolean includeCreatedTimestamps; - private final Boolean exemplarsOnAllMetricTypes; + private final Boolean includeCreatedTimestamps; + private final Boolean exemplarsOnAllMetricTypes; - private ExporterProperties(Boolean includeCreatedTimestamps, Boolean exemplarsOnAllMetricTypes) { - this.includeCreatedTimestamps = includeCreatedTimestamps; - this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; - } + private ExporterProperties(Boolean includeCreatedTimestamps, Boolean exemplarsOnAllMetricTypes) { + this.includeCreatedTimestamps = includeCreatedTimestamps; + this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; + } - /** - * Include the {@code _created} timestamps in text format? Default is {@code false}. - */ - public boolean getIncludeCreatedTimestamps() { - return includeCreatedTimestamps != null && includeCreatedTimestamps; - } + /** Include the {@code _created} timestamps in text format? Default is {@code false}. */ + public boolean getIncludeCreatedTimestamps() { + return includeCreatedTimestamps != null && includeCreatedTimestamps; + } - /** - * Allow Exemplars on all metric types in OpenMetrics format? - * Default is {@code false}, which means Exemplars will only be added for Counters and Histogram buckets. - */ - public boolean getExemplarsOnAllMetricTypes() { - return exemplarsOnAllMetricTypes != null && exemplarsOnAllMetricTypes; - } + /** + * Allow Exemplars on all metric types in OpenMetrics format? Default is {@code false}, which + * means Exemplars will only be added for Counters and Histogram buckets. + */ + public boolean getExemplarsOnAllMetricTypes() { + return exemplarsOnAllMetricTypes != null && exemplarsOnAllMetricTypes; + } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExporterProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - Boolean includeCreatedTimestamps = Util.loadBoolean(prefix + "." + INCLUDE_CREATED_TIMESTAMPS, properties); - Boolean exemplarsOnAllMetricTypes = Util.loadBoolean(prefix + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); - return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); - } + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExporterProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + Boolean includeCreatedTimestamps = + Util.loadBoolean(prefix + "." + INCLUDE_CREATED_TIMESTAMPS, properties); + Boolean exemplarsOnAllMetricTypes = + Util.loadBoolean(prefix + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); + return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder { + public static class Builder { - private Boolean includeCreatedTimestamps; - private Boolean exemplarsOnAllMetricTypes; + private Boolean includeCreatedTimestamps; + private Boolean exemplarsOnAllMetricTypes; - private Builder() { - } + private Builder() {} - /** - * See {@link #getIncludeCreatedTimestamps()} - */ - public Builder includeCreatedTimestamps(boolean includeCreatedTimestamps) { - this.includeCreatedTimestamps = includeCreatedTimestamps; - return this; - } + /** See {@link #getIncludeCreatedTimestamps()} */ + public Builder includeCreatedTimestamps(boolean includeCreatedTimestamps) { + this.includeCreatedTimestamps = includeCreatedTimestamps; + return this; + } - /** - * See {@link #getExemplarsOnAllMetricTypes()}. - */ - public Builder exemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { - this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; - return this; - } + /** See {@link #getExemplarsOnAllMetricTypes()}. */ + public Builder exemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { + this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; + return this; + } - public ExporterProperties build() { - return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); - } + public ExporterProperties build() { + return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java index f38a7f4af..4a794eba2 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java @@ -4,56 +4,55 @@ public class ExporterPushgatewayProperties { - private static final String ADDRESS = "address"; - private static final String JOB = "job"; - private static final String SCHEME = "scheme"; - private final String scheme; - private final String address; - private final String job; - - private ExporterPushgatewayProperties(String address, String job, String scheme) { - this.address = address; - this.job = job; - this.scheme = scheme; - } - - /** - * Address of the Pushgateway in the form {@code host:port}. - * Default is {@code localhost:9091} - */ - public String getAddress() { - return address; - } - - /** - * {@code job} label for metrics being pushed. - * Default is the name of the JAR file that is running. - */ - public String getJob() { - return job; - } - - /** - * Scheme to be used when pushing metrics to the pushgateway. - * Must be "http" or "https". Default is "http". - */ - public String getScheme() { - return scheme; - } - - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static ExporterPushgatewayProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - String address = Util.loadString(prefix + "." + ADDRESS, properties); - String job = Util.loadString(prefix + "." + JOB, properties); - String scheme = Util.loadString(prefix + "." + SCHEME, properties); - if (scheme != null) { - if (!scheme.equals("http") && !scheme.equals("https")) { - throw new PrometheusPropertiesException(prefix + "." + SCHEME + "=" + scheme + ": Illegal value. Expecting 'http' or 'https'."); - } - } - return new ExporterPushgatewayProperties(address, job, scheme); + private static final String ADDRESS = "address"; + private static final String JOB = "job"; + private static final String SCHEME = "scheme"; + private final String scheme; + private final String address; + private final String job; + + private ExporterPushgatewayProperties(String address, String job, String scheme) { + this.address = address; + this.job = job; + this.scheme = scheme; + } + + /** Address of the Pushgateway in the form {@code host:port}. Default is {@code localhost:9091} */ + public String getAddress() { + return address; + } + + /** + * {@code job} label for metrics being pushed. Default is the name of the JAR file that is + * running. + */ + public String getJob() { + return job; + } + + /** + * Scheme to be used when pushing metrics to the pushgateway. Must be "http" or "https". Default + * is "http". + */ + public String getScheme() { + return scheme; + } + + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static ExporterPushgatewayProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + String address = Util.loadString(prefix + "." + ADDRESS, properties); + String job = Util.loadString(prefix + "." + JOB, properties); + String scheme = Util.loadString(prefix + "." + SCHEME, properties); + if (scheme != null) { + if (!scheme.equals("http") && !scheme.equals("https")) { + throw new PrometheusPropertiesException( + prefix + "." + SCHEME + "=" + scheme + ": Illegal value. Expecting 'http' or 'https'."); + } } + return new ExporterPushgatewayProperties(address, job, scheme); + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java index 4574d0198..744822005 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java @@ -1,432 +1,455 @@ package io.prometheus.metrics.config; +import static java.util.Collections.unmodifiableList; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import static java.util.Collections.unmodifiableList; - -/** - * Properties starting with io.prometheus.metrics - */ +/** Properties starting with io.prometheus.metrics */ public class MetricsProperties { - private static final String EXEMPLARS_ENABLED = "exemplarsEnabled"; - private static final String HISTOGRAM_NATIVE_ONLY = "histogramNativeOnly"; - private static final String HISTOGRAM_CLASSIC_ONLY = "histogramClassicOnly"; - private static final String HISTOGRAM_CLASSIC_UPPER_BOUNDS = "histogramClassicUpperBounds"; - private static final String HISTOGRAM_NATIVE_INITIAL_SCHEMA = "histogramNativeInitialSchema"; - private static final String HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD = "histogramNativeMinZeroThreshold"; - private static final String HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD = "histogramNativeMaxZeroThreshold"; - private static final String HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS = "histogramNativeMaxNumberOfBuckets"; // 0 means unlimited number of buckets - private static final String HISTOGRAM_NATIVE_RESET_DURATION_SECONDS = "histogramNativeResetDurationSeconds"; // 0 means no reset - private static final String SUMMARY_QUANTILES = "summaryQuantiles"; - private static final String SUMMARY_QUANTILE_ERRORS = "summaryQuantileErrors"; - private static final String SUMMARY_MAX_AGE_SECONDS = "summaryMaxAgeSeconds"; - private static final String SUMMARY_NUMBER_OF_AGE_BUCKETS = "summaryNumberOfAgeBuckets"; - - private final Boolean exemplarsEnabled; - private final Boolean histogramNativeOnly; - private final Boolean histogramClassicOnly; - private final List histogramClassicUpperBounds; - private final Integer histogramNativeInitialSchema; - private final Double histogramNativeMinZeroThreshold; - private final Double histogramNativeMaxZeroThreshold; - private final Integer histogramNativeMaxNumberOfBuckets; - private final Long histogramNativeResetDurationSeconds; - private final List summaryQuantiles; - private final List summaryQuantileErrors; - private final Long summaryMaxAgeSeconds; - private final Integer summaryNumberOfAgeBuckets; - - public MetricsProperties( - Boolean exemplarsEnabled, - Boolean histogramNativeOnly, - Boolean histogramClassicOnly, - List histogramClassicUpperBounds, - Integer histogramNativeInitialSchema, - Double histogramNativeMinZeroThreshold, - Double histogramNativeMaxZeroThreshold, - Integer histogramNativeMaxNumberOfBuckets, - Long histogramNativeResetDurationSeconds, - List summaryQuantiles, - List summaryQuantileErrors, - Long summaryMaxAgeSeconds, - Integer summaryNumberOfAgeBuckets) { - this(exemplarsEnabled, - histogramNativeOnly, - histogramClassicOnly, - histogramClassicUpperBounds, - histogramNativeInitialSchema, - histogramNativeMinZeroThreshold, - histogramNativeMaxZeroThreshold, - histogramNativeMaxNumberOfBuckets, - histogramNativeResetDurationSeconds, - summaryQuantiles, - summaryQuantileErrors, - summaryMaxAgeSeconds, - summaryNumberOfAgeBuckets, - ""); + private static final String EXEMPLARS_ENABLED = "exemplarsEnabled"; + private static final String HISTOGRAM_NATIVE_ONLY = "histogramNativeOnly"; + private static final String HISTOGRAM_CLASSIC_ONLY = "histogramClassicOnly"; + private static final String HISTOGRAM_CLASSIC_UPPER_BOUNDS = "histogramClassicUpperBounds"; + private static final String HISTOGRAM_NATIVE_INITIAL_SCHEMA = "histogramNativeInitialSchema"; + private static final String HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD = + "histogramNativeMinZeroThreshold"; + private static final String HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD = + "histogramNativeMaxZeroThreshold"; + private static final String HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS = + "histogramNativeMaxNumberOfBuckets"; // 0 means unlimited number of buckets + private static final String HISTOGRAM_NATIVE_RESET_DURATION_SECONDS = + "histogramNativeResetDurationSeconds"; // 0 means no reset + private static final String SUMMARY_QUANTILES = "summaryQuantiles"; + private static final String SUMMARY_QUANTILE_ERRORS = "summaryQuantileErrors"; + private static final String SUMMARY_MAX_AGE_SECONDS = "summaryMaxAgeSeconds"; + private static final String SUMMARY_NUMBER_OF_AGE_BUCKETS = "summaryNumberOfAgeBuckets"; + + private final Boolean exemplarsEnabled; + private final Boolean histogramNativeOnly; + private final Boolean histogramClassicOnly; + private final List histogramClassicUpperBounds; + private final Integer histogramNativeInitialSchema; + private final Double histogramNativeMinZeroThreshold; + private final Double histogramNativeMaxZeroThreshold; + private final Integer histogramNativeMaxNumberOfBuckets; + private final Long histogramNativeResetDurationSeconds; + private final List summaryQuantiles; + private final List summaryQuantileErrors; + private final Long summaryMaxAgeSeconds; + private final Integer summaryNumberOfAgeBuckets; + + public MetricsProperties( + Boolean exemplarsEnabled, + Boolean histogramNativeOnly, + Boolean histogramClassicOnly, + List histogramClassicUpperBounds, + Integer histogramNativeInitialSchema, + Double histogramNativeMinZeroThreshold, + Double histogramNativeMaxZeroThreshold, + Integer histogramNativeMaxNumberOfBuckets, + Long histogramNativeResetDurationSeconds, + List summaryQuantiles, + List summaryQuantileErrors, + Long summaryMaxAgeSeconds, + Integer summaryNumberOfAgeBuckets) { + this( + exemplarsEnabled, + histogramNativeOnly, + histogramClassicOnly, + histogramClassicUpperBounds, + histogramNativeInitialSchema, + histogramNativeMinZeroThreshold, + histogramNativeMaxZeroThreshold, + histogramNativeMaxNumberOfBuckets, + histogramNativeResetDurationSeconds, + summaryQuantiles, + summaryQuantileErrors, + summaryMaxAgeSeconds, + summaryNumberOfAgeBuckets, + ""); + } + + private MetricsProperties( + Boolean exemplarsEnabled, + Boolean histogramNativeOnly, + Boolean histogramClassicOnly, + List histogramClassicUpperBounds, + Integer histogramNativeInitialSchema, + Double histogramNativeMinZeroThreshold, + Double histogramNativeMaxZeroThreshold, + Integer histogramNativeMaxNumberOfBuckets, + Long histogramNativeResetDurationSeconds, + List summaryQuantiles, + List summaryQuantileErrors, + Long summaryMaxAgeSeconds, + Integer summaryNumberOfAgeBuckets, + String configPropertyPrefix) { + this.exemplarsEnabled = exemplarsEnabled; + this.histogramNativeOnly = isHistogramNativeOnly(histogramClassicOnly, histogramNativeOnly); + this.histogramClassicOnly = isHistogramClassicOnly(histogramClassicOnly, histogramNativeOnly); + this.histogramClassicUpperBounds = + histogramClassicUpperBounds == null + ? null + : unmodifiableList(new ArrayList<>(histogramClassicUpperBounds)); + this.histogramNativeInitialSchema = histogramNativeInitialSchema; + this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; + this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; + this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; + this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; + this.summaryQuantiles = + summaryQuantiles == null ? null : unmodifiableList(new ArrayList<>(summaryQuantiles)); + this.summaryQuantileErrors = + summaryQuantileErrors == null + ? null + : unmodifiableList(new ArrayList<>(summaryQuantileErrors)); + this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; + this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; + validate(configPropertyPrefix); + } + + private Boolean isHistogramClassicOnly( + Boolean histogramClassicOnly, Boolean histogramNativeOnly) { + if (histogramClassicOnly == null && histogramNativeOnly == null) { + return null; } - - private MetricsProperties( - Boolean exemplarsEnabled, - Boolean histogramNativeOnly, - Boolean histogramClassicOnly, - List histogramClassicUpperBounds, - Integer histogramNativeInitialSchema, - Double histogramNativeMinZeroThreshold, - Double histogramNativeMaxZeroThreshold, - Integer histogramNativeMaxNumberOfBuckets, - Long histogramNativeResetDurationSeconds, - List summaryQuantiles, - List summaryQuantileErrors, - Long summaryMaxAgeSeconds, - Integer summaryNumberOfAgeBuckets, - String configPropertyPrefix) { - this.exemplarsEnabled = exemplarsEnabled; - this.histogramNativeOnly = isHistogramNativeOnly(histogramClassicOnly, histogramNativeOnly); - this.histogramClassicOnly = isHistogramClassicOnly(histogramClassicOnly, histogramNativeOnly); - this.histogramClassicUpperBounds = histogramClassicUpperBounds == null ? null : unmodifiableList(new ArrayList<>(histogramClassicUpperBounds)); - this.histogramNativeInitialSchema = histogramNativeInitialSchema; - this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; - this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; - this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; - this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; - this.summaryQuantiles = summaryQuantiles == null ? null : unmodifiableList(new ArrayList<>(summaryQuantiles)); - this.summaryQuantileErrors = summaryQuantileErrors == null ? null : unmodifiableList(new ArrayList<>(summaryQuantileErrors)); - this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; - this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; - validate(configPropertyPrefix); + if (histogramClassicOnly != null) { + return histogramClassicOnly; } + return !histogramNativeOnly; + } - - private Boolean isHistogramClassicOnly(Boolean histogramClassicOnly, Boolean histogramNativeOnly) { - if (histogramClassicOnly == null && histogramNativeOnly == null) { - return null; - } - if (histogramClassicOnly != null) { - return histogramClassicOnly; - } - return !histogramNativeOnly; + private Boolean isHistogramNativeOnly(Boolean histogramClassicOnly, Boolean histogramNativeOnly) { + if (histogramClassicOnly == null && histogramNativeOnly == null) { + return null; } - - private Boolean isHistogramNativeOnly(Boolean histogramClassicOnly, Boolean histogramNativeOnly) { - if (histogramClassicOnly == null && histogramNativeOnly == null) { - return null; - } - if (histogramNativeOnly != null) { - return histogramNativeOnly; - } - return !histogramClassicOnly; + if (histogramNativeOnly != null) { + return histogramNativeOnly; + } + return !histogramClassicOnly; + } + + private void validate(String prefix) throws PrometheusPropertiesException { + Util.assertValue( + histogramNativeInitialSchema, + s -> s >= -4 && s <= 8, + "Expecting number between -4 and +8.", + prefix, + HISTOGRAM_NATIVE_INITIAL_SCHEMA); + Util.assertValue( + histogramNativeMinZeroThreshold, + t -> t >= 0, + "Expecting value >= 0.", + prefix, + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD); + Util.assertValue( + histogramNativeMaxZeroThreshold, + t -> t >= 0, + "Expecting value >= 0.", + prefix, + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); + Util.assertValue( + histogramNativeMaxNumberOfBuckets, + n -> n >= 0, + "Expecting value >= 0.", + prefix, + HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS); + Util.assertValue( + histogramNativeResetDurationSeconds, + t -> t >= 0, + "Expecting value >= 0.", + prefix, + HISTOGRAM_NATIVE_RESET_DURATION_SECONDS); + Util.assertValue( + summaryMaxAgeSeconds, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_MAX_AGE_SECONDS); + Util.assertValue( + summaryNumberOfAgeBuckets, + t -> t > 0, + "Expecting value > 0", + prefix, + SUMMARY_NUMBER_OF_AGE_BUCKETS); + + if (Boolean.TRUE.equals(histogramNativeOnly) && Boolean.TRUE.equals(histogramClassicOnly)) { + throw new PrometheusPropertiesException( + prefix + + "." + + HISTOGRAM_NATIVE_ONLY + + " and " + + prefix + + "." + + HISTOGRAM_CLASSIC_ONLY + + " cannot both be true"); } - private void validate(String prefix) throws PrometheusPropertiesException { - Util.assertValue(histogramNativeInitialSchema, s -> s >= -4 && s <= 8, "Expecting number between -4 and +8.", prefix, HISTOGRAM_NATIVE_INITIAL_SCHEMA); - Util.assertValue(histogramNativeMinZeroThreshold, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD); - Util.assertValue(histogramNativeMaxZeroThreshold, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); - Util.assertValue(histogramNativeMaxNumberOfBuckets, n -> n >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS); - Util.assertValue(histogramNativeResetDurationSeconds, t -> t >= 0, "Expecting value >= 0.", prefix, HISTOGRAM_NATIVE_RESET_DURATION_SECONDS); - Util.assertValue(summaryMaxAgeSeconds, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_MAX_AGE_SECONDS); - Util.assertValue(summaryNumberOfAgeBuckets, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_NUMBER_OF_AGE_BUCKETS); - - if (Boolean.TRUE.equals(histogramNativeOnly) && Boolean.TRUE.equals(histogramClassicOnly)) { - throw new PrometheusPropertiesException(prefix + "." + HISTOGRAM_NATIVE_ONLY + " and " + prefix + "." + HISTOGRAM_CLASSIC_ONLY + " cannot both be true"); - } - - if (histogramNativeMinZeroThreshold != null && histogramNativeMaxZeroThreshold != null) { - if (histogramNativeMinZeroThreshold > histogramNativeMaxZeroThreshold) { - throw new PrometheusPropertiesException(prefix + "." + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD + " cannot be greater than " + prefix + "." + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); - } - } + if (histogramNativeMinZeroThreshold != null && histogramNativeMaxZeroThreshold != null) { + if (histogramNativeMinZeroThreshold > histogramNativeMaxZeroThreshold) { + throw new PrometheusPropertiesException( + prefix + + "." + + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD + + " cannot be greater than " + + prefix + + "." + + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD); + } + } - if (summaryQuantiles != null) { - for (double quantile : summaryQuantiles) { - if (quantile < 0 || quantile > 1) { - throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILES + ": Expecting 0.0 <= quantile <= 1.0"); - } - } + if (summaryQuantiles != null) { + for (double quantile : summaryQuantiles) { + if (quantile < 0 || quantile > 1) { + throw new PrometheusPropertiesException( + prefix + "." + SUMMARY_QUANTILES + ": Expecting 0.0 <= quantile <= 1.0"); } + } + } - if (summaryQuantileErrors != null) { - if (summaryQuantiles == null) { - throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": Can't configure " + SUMMARY_QUANTILE_ERRORS + " without configuring " + SUMMARY_QUANTILES); - } - if (summaryQuantileErrors.size() != summaryQuantiles.size()) { - throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": must have the same length as " + SUMMARY_QUANTILES); - } - for (double error : summaryQuantileErrors) { - if (error < 0 || error > 1) { - throw new PrometheusPropertiesException(prefix + "." + SUMMARY_QUANTILE_ERRORS + ": Expecting 0.0 <= error <= 1.0"); - } - } + if (summaryQuantileErrors != null) { + if (summaryQuantiles == null) { + throw new PrometheusPropertiesException( + prefix + + "." + + SUMMARY_QUANTILE_ERRORS + + ": Can't configure " + + SUMMARY_QUANTILE_ERRORS + + " without configuring " + + SUMMARY_QUANTILES); + } + if (summaryQuantileErrors.size() != summaryQuantiles.size()) { + throw new PrometheusPropertiesException( + prefix + + "." + + SUMMARY_QUANTILE_ERRORS + + ": must have the same length as " + + SUMMARY_QUANTILES); + } + for (double error : summaryQuantileErrors) { + if (error < 0 || error > 1) { + throw new PrometheusPropertiesException( + prefix + "." + SUMMARY_QUANTILE_ERRORS + ": Expecting 0.0 <= error <= 1.0"); } + } } - - /** - * This is the only configuration property that can be applied to all metric types. - * You can use it to turn Exemplar support off. Default is {@code true}. - */ - public Boolean getExemplarsEnabled() { - return exemplarsEnabled; + } + + /** + * This is the only configuration property that can be applied to all metric types. You can use it + * to turn Exemplar support off. Default is {@code true}. + */ + public Boolean getExemplarsEnabled() { + return exemplarsEnabled; + } + + /** See {@code Histogram.Builder.nativeOnly()} */ + public Boolean getHistogramNativeOnly() { + return histogramNativeOnly; + } + + /** See {@code Histogram.Builder.classicOnly()} */ + public Boolean getHistogramClassicOnly() { + return histogramClassicOnly; + } + + /** See {@code Histogram.Builder.classicBuckets()} */ + public List getHistogramClassicUpperBounds() { + return histogramClassicUpperBounds; + } + + /** See {@code Histogram.Builder.nativeInitialSchema()} */ + public Integer getHistogramNativeInitialSchema() { + return histogramNativeInitialSchema; + } + + /** See {@code Histogram.Builder.nativeMinZeroThreshold()} */ + public Double getHistogramNativeMinZeroThreshold() { + return histogramNativeMinZeroThreshold; + } + + /** See {@code Histogram.Builder.nativeMaxZeroThreshold()} */ + public Double getHistogramNativeMaxZeroThreshold() { + return histogramNativeMaxZeroThreshold; + } + + /** See {@code Histogram.Builder.nativeMaxNumberOfBuckets()} */ + public Integer getHistogramNativeMaxNumberOfBuckets() { + return histogramNativeMaxNumberOfBuckets; + } + + /** See {@code Histogram.Builder.nativeResetDuration()} */ + public Long getHistogramNativeResetDurationSeconds() { + return histogramNativeResetDurationSeconds; + } + + /** See {@code Summary.Builder.quantile()} */ + public List getSummaryQuantiles() { + return summaryQuantiles; + } + + /** + * See {@code Summary.Builder.quantile()} + * + *

      Returns {@code null} only if {@link #getSummaryQuantiles()} is also {@code null}. Returns an + * empty list if {@link #getSummaryQuantiles()} are specified without specifying errors. If the + * list is not empty, it has the same size as {@link #getSummaryQuantiles()}. + */ + public List getSummaryQuantileErrors() { + if (summaryQuantiles != null) { + if (summaryQuantileErrors == null) { + return Collections.emptyList(); + } } - - /** - * See {@code Histogram.Builder.nativeOnly()} - */ - public Boolean getHistogramNativeOnly() { - return histogramNativeOnly; + return summaryQuantileErrors; + } + + /** See {@code Summary.Builder.maxAgeSeconds()} */ + public Long getSummaryMaxAgeSeconds() { + return summaryMaxAgeSeconds; + } + + /** See {@code Summary.Builder.numberOfAgeBuckets()} */ + public Integer getSummaryNumberOfAgeBuckets() { + return summaryNumberOfAgeBuckets; + } + + /** + * Note that this will remove entries from {@code properties}. This is because we want to know if + * there are unused properties remaining after all properties have been loaded. + */ + static MetricsProperties load(String prefix, Map properties) + throws PrometheusPropertiesException { + return new MetricsProperties( + Util.loadBoolean(prefix + "." + EXEMPLARS_ENABLED, properties), + Util.loadBoolean(prefix + "." + HISTOGRAM_NATIVE_ONLY, properties), + Util.loadBoolean(prefix + "." + HISTOGRAM_CLASSIC_ONLY, properties), + Util.loadDoubleList(prefix + "." + HISTOGRAM_CLASSIC_UPPER_BOUNDS, properties), + Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_INITIAL_SCHEMA, properties), + Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD, properties), + Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD, properties), + Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS, properties), + Util.loadLong(prefix + "." + HISTOGRAM_NATIVE_RESET_DURATION_SECONDS, properties), + Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILES, properties), + Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILE_ERRORS, properties), + Util.loadLong(prefix + "." + SUMMARY_MAX_AGE_SECONDS, properties), + Util.loadInteger(prefix + "." + SUMMARY_NUMBER_OF_AGE_BUCKETS, properties), + prefix); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Boolean exemplarsEnabled; + private Boolean histogramNativeOnly; + private Boolean histogramClassicOnly; + private List histogramClassicUpperBounds; + private Integer histogramNativeInitialSchema; + private Double histogramNativeMinZeroThreshold; + private Double histogramNativeMaxZeroThreshold; + private Integer histogramNativeMaxNumberOfBuckets; + private Long histogramNativeResetDurationSeconds; + private List summaryQuantiles; + private List summaryQuantileErrors; + private Long summaryMaxAgeSeconds; + private Integer summaryNumberOfAgeBuckets; + + private Builder() {} + + public MetricsProperties build() { + return new MetricsProperties( + exemplarsEnabled, + histogramNativeOnly, + histogramClassicOnly, + histogramClassicUpperBounds, + histogramNativeInitialSchema, + histogramNativeMinZeroThreshold, + histogramNativeMaxZeroThreshold, + histogramNativeMaxNumberOfBuckets, + histogramNativeResetDurationSeconds, + summaryQuantiles, + summaryQuantileErrors, + summaryMaxAgeSeconds, + summaryNumberOfAgeBuckets); } - /** - * See {@code Histogram.Builder.classicOnly()} - */ - public Boolean getHistogramClassicOnly() { - return histogramClassicOnly; + /** See {@link MetricsProperties#getExemplarsEnabled()} */ + public Builder exemplarsEnabled(Boolean exemplarsEnabled) { + this.exemplarsEnabled = exemplarsEnabled; + return this; } - /** - * See {@code Histogram.Builder.classicBuckets()} - */ - public List getHistogramClassicUpperBounds() { - return histogramClassicUpperBounds; + /** See {@link MetricsProperties#getHistogramNativeOnly()} */ + public Builder histogramNativeOnly(Boolean histogramNativeOnly) { + this.histogramNativeOnly = histogramNativeOnly; + return this; } - /** - * See {@code Histogram.Builder.nativeInitialSchema()} - */ - public Integer getHistogramNativeInitialSchema() { - return histogramNativeInitialSchema; + /** See {@link MetricsProperties#getHistogramClassicOnly()} */ + public Builder histogramClassicOnly(Boolean histogramClassicOnly) { + this.histogramClassicOnly = histogramClassicOnly; + return this; } - /** - * See {@code Histogram.Builder.nativeMinZeroThreshold()} - */ - public Double getHistogramNativeMinZeroThreshold() { - return histogramNativeMinZeroThreshold; + /** See {@link MetricsProperties#getHistogramClassicUpperBounds()} */ + public Builder histogramClassicUpperBounds(double... histogramClassicUpperBounds) { + this.histogramClassicUpperBounds = Util.toList(histogramClassicUpperBounds); + return this; } - /** - * See {@code Histogram.Builder.nativeMaxZeroThreshold()} - */ - public Double getHistogramNativeMaxZeroThreshold() { - return histogramNativeMaxZeroThreshold; + /** See {@link MetricsProperties#getHistogramNativeInitialSchema()} */ + public Builder histogramNativeInitialSchema(Integer histogramNativeInitialSchema) { + this.histogramNativeInitialSchema = histogramNativeInitialSchema; + return this; } - /** - * See {@code Histogram.Builder.nativeMaxNumberOfBuckets()} - */ - public Integer getHistogramNativeMaxNumberOfBuckets() { - return histogramNativeMaxNumberOfBuckets; + /** See {@link MetricsProperties#getHistogramNativeMinZeroThreshold()} */ + public Builder histogramNativeMinZeroThreshold(Double histogramNativeMinZeroThreshold) { + this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; + return this; } - /** - * See {@code Histogram.Builder.nativeResetDuration()} - */ - public Long getHistogramNativeResetDurationSeconds() { - return histogramNativeResetDurationSeconds; + /** See {@link MetricsProperties#getHistogramNativeMaxZeroThreshold()} */ + public Builder histogramNativeMaxZeroThreshold(Double histogramNativeMaxZeroThreshold) { + this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; + return this; } - /** - * See {@code Summary.Builder.quantile()} - */ - public List getSummaryQuantiles() { - return summaryQuantiles; + /** See {@link MetricsProperties#getHistogramNativeMaxNumberOfBuckets()} */ + public Builder histogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxNumberOfBuckets) { + this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; + return this; } - /** - * See {@code Summary.Builder.quantile()} - *

      - * Returns {@code null} only if {@link #getSummaryQuantiles()} is also {@code null}. - * Returns an empty list if {@link #getSummaryQuantiles()} are specified without specifying errors. - * If the list is not empty, it has the same size as {@link #getSummaryQuantiles()}. - */ - public List getSummaryQuantileErrors() { - if (summaryQuantiles != null) { - if (summaryQuantileErrors == null) { - return Collections.emptyList(); - } - } - return summaryQuantileErrors; + /** See {@link MetricsProperties#getHistogramNativeResetDurationSeconds()} */ + public Builder histogramNativeResetDurationSeconds(Long histogramNativeResetDurationSeconds) { + this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; + return this; } - /** - * See {@code Summary.Builder.maxAgeSeconds()} - */ - public Long getSummaryMaxAgeSeconds() { - return summaryMaxAgeSeconds; + /** See {@link MetricsProperties#getSummaryQuantiles()} */ + public Builder summaryQuantiles(double... summaryQuantiles) { + this.summaryQuantiles = Util.toList(summaryQuantiles); + return this; } - /** - * See {@code Summary.Builder.numberOfAgeBuckets()} - */ - public Integer getSummaryNumberOfAgeBuckets() { - return summaryNumberOfAgeBuckets; + /** See {@link MetricsProperties#getSummaryQuantileErrors()} */ + public Builder summaryQuantileErrors(double... summaryQuantileErrors) { + this.summaryQuantileErrors = Util.toList(summaryQuantileErrors); + return this; } - /** - * Note that this will remove entries from {@code properties}. - * This is because we want to know if there are unused properties remaining after all properties have been loaded. - */ - static MetricsProperties load(String prefix, Map properties) throws PrometheusPropertiesException { - return new MetricsProperties( - Util.loadBoolean(prefix + "." + EXEMPLARS_ENABLED, properties), - Util.loadBoolean(prefix + "." + HISTOGRAM_NATIVE_ONLY, properties), - Util.loadBoolean(prefix + "." + HISTOGRAM_CLASSIC_ONLY, properties), - Util.loadDoubleList(prefix + "." + HISTOGRAM_CLASSIC_UPPER_BOUNDS, properties), - Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_INITIAL_SCHEMA, properties), - Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MIN_ZERO_THRESHOLD, properties), - Util.loadDouble(prefix + "." + HISTOGRAM_NATIVE_MAX_ZERO_THRESHOLD, properties), - Util.loadInteger(prefix + "." + HISTOGRAM_NATIVE_MAX_NUMBER_OF_BUCKETS, properties), - Util.loadLong(prefix + "." + HISTOGRAM_NATIVE_RESET_DURATION_SECONDS, properties), - Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILES, properties), - Util.loadDoubleList(prefix + "." + SUMMARY_QUANTILE_ERRORS, properties), - Util.loadLong(prefix + "." + SUMMARY_MAX_AGE_SECONDS, properties), - Util.loadInteger(prefix + "." + SUMMARY_NUMBER_OF_AGE_BUCKETS, properties), - prefix); + /** See {@link MetricsProperties#getSummaryMaxAgeSeconds()} */ + public Builder summaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { + this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; + return this; } - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private Boolean exemplarsEnabled; - private Boolean histogramNativeOnly; - private Boolean histogramClassicOnly; - private List histogramClassicUpperBounds; - private Integer histogramNativeInitialSchema; - private Double histogramNativeMinZeroThreshold; - private Double histogramNativeMaxZeroThreshold; - private Integer histogramNativeMaxNumberOfBuckets; - private Long histogramNativeResetDurationSeconds; - private List summaryQuantiles; - private List summaryQuantileErrors; - private Long summaryMaxAgeSeconds; - private Integer summaryNumberOfAgeBuckets; - - private Builder() { - } - - public MetricsProperties build() { - return new MetricsProperties(exemplarsEnabled, - histogramNativeOnly, - histogramClassicOnly, - histogramClassicUpperBounds, - histogramNativeInitialSchema, - histogramNativeMinZeroThreshold, - histogramNativeMaxZeroThreshold, - histogramNativeMaxNumberOfBuckets, - histogramNativeResetDurationSeconds, - summaryQuantiles, - summaryQuantileErrors, - summaryMaxAgeSeconds, - summaryNumberOfAgeBuckets); - } - - /** - * See {@link MetricsProperties#getExemplarsEnabled()} - */ - public Builder exemplarsEnabled(Boolean exemplarsEnabled) { - this.exemplarsEnabled = exemplarsEnabled; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeOnly()} - */ - public Builder histogramNativeOnly(Boolean histogramNativeOnly) { - this.histogramNativeOnly = histogramNativeOnly; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramClassicOnly()} - */ - public Builder histogramClassicOnly(Boolean histogramClassicOnly) { - this.histogramClassicOnly = histogramClassicOnly; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramClassicUpperBounds()} - */ - public Builder histogramClassicUpperBounds(double... histogramClassicUpperBounds) { - this.histogramClassicUpperBounds = Util.toList(histogramClassicUpperBounds); - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeInitialSchema()} - */ - public Builder histogramNativeInitialSchema(Integer histogramNativeInitialSchema) { - this.histogramNativeInitialSchema = histogramNativeInitialSchema; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeMinZeroThreshold()} - */ - public Builder histogramNativeMinZeroThreshold(Double histogramNativeMinZeroThreshold) { - this.histogramNativeMinZeroThreshold = histogramNativeMinZeroThreshold; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeMaxZeroThreshold()} - */ - public Builder histogramNativeMaxZeroThreshold(Double histogramNativeMaxZeroThreshold) { - this.histogramNativeMaxZeroThreshold = histogramNativeMaxZeroThreshold; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeMaxNumberOfBuckets()} - */ - public Builder histogramNativeMaxNumberOfBuckets(Integer histogramNativeMaxNumberOfBuckets) { - this.histogramNativeMaxNumberOfBuckets = histogramNativeMaxNumberOfBuckets; - return this; - } - - /** - * See {@link MetricsProperties#getHistogramNativeResetDurationSeconds()} - */ - public Builder histogramNativeResetDurationSeconds(Long histogramNativeResetDurationSeconds) { - this.histogramNativeResetDurationSeconds = histogramNativeResetDurationSeconds; - return this; - } - - /** - * See {@link MetricsProperties#getSummaryQuantiles()} - */ - public Builder summaryQuantiles(double... summaryQuantiles) { - this.summaryQuantiles = Util.toList(summaryQuantiles); - return this; - } - - /** - * See {@link MetricsProperties#getSummaryQuantileErrors()} - */ - public Builder summaryQuantileErrors(double... summaryQuantileErrors) { - this.summaryQuantileErrors = Util.toList(summaryQuantileErrors); - return this; - } - - /** - * See {@link MetricsProperties#getSummaryMaxAgeSeconds()} - */ - public Builder summaryMaxAgeSeconds(Long summaryMaxAgeSeconds) { - this.summaryMaxAgeSeconds = summaryMaxAgeSeconds; - return this; - } - - /** - * See {@link MetricsProperties#getSummaryNumberOfAgeBuckets()} - */ - public Builder summaryNumberOfAgeBuckets(Integer summaryNumberOfAgeBuckets) { - this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; - return this; - } + /** See {@link MetricsProperties#getSummaryNumberOfAgeBuckets()} */ + public Builder summaryNumberOfAgeBuckets(Integer summaryNumberOfAgeBuckets) { + this.summaryNumberOfAgeBuckets = summaryNumberOfAgeBuckets; + return this; } + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java index 2e26a4c7b..da31fe8cc 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusProperties.java @@ -5,89 +5,94 @@ /** * The Prometheus Java client library can be configured at runtime (e.g. using a properties file). - *

      - * This class represents the runtime configuration. + * + *

      This class represents the runtime configuration. */ public class PrometheusProperties { - private static final PrometheusProperties instance = PrometheusPropertiesLoader.load(); + private static final PrometheusProperties instance = PrometheusPropertiesLoader.load(); - private final MetricsProperties defaultMetricsProperties; - private final Map metricProperties = new HashMap<>(); - private final ExemplarsProperties exemplarProperties; - private final ExporterProperties exporterProperties; - private final ExporterFilterProperties exporterFilterProperties; - private final ExporterHttpServerProperties exporterHttpServerProperties; - private final ExporterOpenTelemetryProperties exporterOpenTelemetryProperties; - private final ExporterPushgatewayProperties exporterPushgatewayProperties; + private final MetricsProperties defaultMetricsProperties; + private final Map metricProperties = new HashMap<>(); + private final ExemplarsProperties exemplarProperties; + private final ExporterProperties exporterProperties; + private final ExporterFilterProperties exporterFilterProperties; + private final ExporterHttpServerProperties exporterHttpServerProperties; + private final ExporterOpenTelemetryProperties exporterOpenTelemetryProperties; + private final ExporterPushgatewayProperties exporterPushgatewayProperties; - /** - * Get the properties instance. When called for the first time, {@code get()} loads the properties from the following locations: - *

        - *
      • {@code prometheus.properties} file found in the classpath.
      • - *
      • Properties file specified in the {@code PROMETHEUS_CONFIG} environment variable or the {@code prometheus.config} system property.
      • - *
      • Individual properties from system properties.
      • - *
      - */ - public static PrometheusProperties get() throws PrometheusPropertiesException { - return instance; - } + /** + * Get the properties instance. When called for the first time, {@code get()} loads the properties + * from the following locations: + * + *
        + *
      • {@code prometheus.properties} file found in the classpath. + *
      • Properties file specified in the {@code PROMETHEUS_CONFIG} environment variable or the + * {@code prometheus.config} system property. + *
      • Individual properties from system properties. + *
      + */ + public static PrometheusProperties get() throws PrometheusPropertiesException { + return instance; + } - public PrometheusProperties( - MetricsProperties defaultMetricsProperties, - Map metricProperties, - ExemplarsProperties exemplarProperties, - ExporterProperties exporterProperties, - ExporterFilterProperties exporterFilterProperties, - ExporterHttpServerProperties httpServerConfig, - ExporterPushgatewayProperties pushgatewayProperties, - ExporterOpenTelemetryProperties otelConfig) { - this.defaultMetricsProperties = defaultMetricsProperties; - this.metricProperties.putAll(metricProperties); - this.exemplarProperties = exemplarProperties; - this.exporterProperties = exporterProperties; - this.exporterFilterProperties = exporterFilterProperties; - this.exporterHttpServerProperties = httpServerConfig; - this.exporterPushgatewayProperties = pushgatewayProperties; - this.exporterOpenTelemetryProperties = otelConfig; - } + public PrometheusProperties( + MetricsProperties defaultMetricsProperties, + Map metricProperties, + ExemplarsProperties exemplarProperties, + ExporterProperties exporterProperties, + ExporterFilterProperties exporterFilterProperties, + ExporterHttpServerProperties httpServerConfig, + ExporterPushgatewayProperties pushgatewayProperties, + ExporterOpenTelemetryProperties otelConfig) { + this.defaultMetricsProperties = defaultMetricsProperties; + this.metricProperties.putAll(metricProperties); + this.exemplarProperties = exemplarProperties; + this.exporterProperties = exporterProperties; + this.exporterFilterProperties = exporterFilterProperties; + this.exporterHttpServerProperties = httpServerConfig; + this.exporterPushgatewayProperties = pushgatewayProperties; + this.exporterOpenTelemetryProperties = otelConfig; + } - /** - * The default metric properties apply for metrics where {@link #getMetricProperties(String)} is {@code null}. - */ - public MetricsProperties getDefaultMetricProperties() { - return defaultMetricsProperties; - } + /** + * The default metric properties apply for metrics where {@link #getMetricProperties(String)} is + * {@code null}. + */ + public MetricsProperties getDefaultMetricProperties() { + return defaultMetricsProperties; + } - /** - * Properties specific for one metric. Should be merged with {@link #getDefaultMetricProperties()}. - * May return {@code null} if no metric-specific properties are configured for a metric name. - */ - public MetricsProperties getMetricProperties(String metricName) { - return metricProperties.get(metricName.replace(".", "_")); - } + /** + * Properties specific for one metric. Should be merged with {@link + * #getDefaultMetricProperties()}. May return {@code null} if no metric-specific properties are + * configured for a metric name. + */ + public MetricsProperties getMetricProperties(String metricName) { + return metricProperties.get(metricName.replace(".", "_")); + } - public ExemplarsProperties getExemplarProperties() { - return exemplarProperties; - } + public ExemplarsProperties getExemplarProperties() { + return exemplarProperties; + } - public ExporterProperties getExporterProperties() { - return exporterProperties; - } + public ExporterProperties getExporterProperties() { + return exporterProperties; + } - public ExporterFilterProperties getExporterFilterProperties() { - return exporterFilterProperties; - } + public ExporterFilterProperties getExporterFilterProperties() { + return exporterFilterProperties; + } - public ExporterHttpServerProperties getExporterHttpServerProperties() { - return exporterHttpServerProperties; - } + public ExporterHttpServerProperties getExporterHttpServerProperties() { + return exporterHttpServerProperties; + } - public ExporterPushgatewayProperties getExporterPushgatewayProperties() { - return exporterPushgatewayProperties; - } + public ExporterPushgatewayProperties getExporterPushgatewayProperties() { + return exporterPushgatewayProperties; + } - public ExporterOpenTelemetryProperties getExporterOpenTelemetryProperties() { - return exporterOpenTelemetryProperties; - } + public ExporterOpenTelemetryProperties getExporterOpenTelemetryProperties() { + return exporterOpenTelemetryProperties; + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java index e41009ca2..5024cc45a 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java @@ -2,11 +2,11 @@ public class PrometheusPropertiesException extends RuntimeException { - public PrometheusPropertiesException(String msg) { - super(msg); - } + public PrometheusPropertiesException(String msg) { + super(msg); + } - public PrometheusPropertiesException(String msg, Exception cause) { - super(msg, cause); - } + public PrometheusPropertiesException(String msg, Exception cause) { + super(msg, cause); + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java index bb9b3c2cb..9d1fde4ab 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java @@ -14,101 +14,123 @@ /** * The Properties Loader is early stages. - *

      - * It would be great to implement a subset of - * Spring Boot's Externalized Configuration, - * like support for YAML, Properties, and env vars, or support for Spring's naming conventions for properties. + * + *

      It would be great to implement a subset of Spring + * Boot's Externalized Configuration, like support for YAML, Properties, and env vars, or + * support for Spring's naming conventions for properties. */ public class PrometheusPropertiesLoader { - /** - * See {@link PrometheusProperties#get()}. - */ - public static PrometheusProperties load() throws PrometheusPropertiesException { - return load(new Properties()); - } + /** See {@link PrometheusProperties#get()}. */ + public static PrometheusProperties load() throws PrometheusPropertiesException { + return load(new Properties()); + } - public static PrometheusProperties load(Map externalProperties) throws PrometheusPropertiesException { - Map properties = loadProperties(externalProperties); - Map metricsConfigs = loadMetricsConfigs(properties); - MetricsProperties defaultMetricsProperties = MetricsProperties.load("io.prometheus.metrics", properties); - ExemplarsProperties exemplarConfig = ExemplarsProperties.load("io.prometheus.exemplars", properties); - ExporterProperties exporterProperties = ExporterProperties.load("io.prometheus.exporter", properties); - ExporterFilterProperties exporterFilterProperties = ExporterFilterProperties.load("io.prometheus.exporter.filter", properties); - ExporterHttpServerProperties exporterHttpServerProperties = ExporterHttpServerProperties.load("io.prometheus.exporter.httpServer", properties); - ExporterPushgatewayProperties exporterPushgatewayProperties = ExporterPushgatewayProperties.load("io.prometheus.exporter.pushgateway", properties); - ExporterOpenTelemetryProperties exporterOpenTelemetryProperties = ExporterOpenTelemetryProperties.load("io.prometheus.exporter.opentelemetry", properties); - validateAllPropertiesProcessed(properties); - return new PrometheusProperties(defaultMetricsProperties, metricsConfigs, exemplarConfig, exporterProperties, exporterFilterProperties, exporterHttpServerProperties, exporterPushgatewayProperties, exporterOpenTelemetryProperties); - } + public static PrometheusProperties load(Map externalProperties) + throws PrometheusPropertiesException { + Map properties = loadProperties(externalProperties); + Map metricsConfigs = loadMetricsConfigs(properties); + MetricsProperties defaultMetricsProperties = + MetricsProperties.load("io.prometheus.metrics", properties); + ExemplarsProperties exemplarConfig = + ExemplarsProperties.load("io.prometheus.exemplars", properties); + ExporterProperties exporterProperties = + ExporterProperties.load("io.prometheus.exporter", properties); + ExporterFilterProperties exporterFilterProperties = + ExporterFilterProperties.load("io.prometheus.exporter.filter", properties); + ExporterHttpServerProperties exporterHttpServerProperties = + ExporterHttpServerProperties.load("io.prometheus.exporter.httpServer", properties); + ExporterPushgatewayProperties exporterPushgatewayProperties = + ExporterPushgatewayProperties.load("io.prometheus.exporter.pushgateway", properties); + ExporterOpenTelemetryProperties exporterOpenTelemetryProperties = + ExporterOpenTelemetryProperties.load("io.prometheus.exporter.opentelemetry", properties); + validateAllPropertiesProcessed(properties); + return new PrometheusProperties( + defaultMetricsProperties, + metricsConfigs, + exemplarConfig, + exporterProperties, + exporterFilterProperties, + exporterHttpServerProperties, + exporterPushgatewayProperties, + exporterOpenTelemetryProperties); + } - // This will remove entries from properties when they are processed. - private static Map loadMetricsConfigs(Map properties) { - Map result = new HashMap<>(); - // Note that the metric name in the properties file must be as exposed in the Prometheus exposition formats, - // i.e. all dots replaced with underscores. - Pattern pattern = Pattern.compile("io\\.prometheus\\.metrics\\.([^.]+)\\."); - // Create a copy of the keySet() for iterating. We cannot iterate directly over keySet() - // because entries are removed when MetricsConfig.load(...) is called. - Set propertyNames = new HashSet<>(); - for (Object key : properties.keySet()) { - propertyNames.add(key.toString()); - } - for (String propertyName : propertyNames) { - Matcher matcher = pattern.matcher(propertyName); - if (matcher.find()) { - String metricName = matcher.group(1).replace(".", "_"); - if (!result.containsKey(metricName)) { - result.put(metricName, MetricsProperties.load("io.prometheus.metrics." + metricName, properties)); - } - } - } - return result; + // This will remove entries from properties when they are processed. + private static Map loadMetricsConfigs(Map properties) { + Map result = new HashMap<>(); + // Note that the metric name in the properties file must be as exposed in the Prometheus + // exposition formats, + // i.e. all dots replaced with underscores. + Pattern pattern = Pattern.compile("io\\.prometheus\\.metrics\\.([^.]+)\\."); + // Create a copy of the keySet() for iterating. We cannot iterate directly over keySet() + // because entries are removed when MetricsConfig.load(...) is called. + Set propertyNames = new HashSet<>(); + for (Object key : properties.keySet()) { + propertyNames.add(key.toString()); } - - // If there are properties left starting with io.prometheus it's likely a typo, - // because we didn't use that property. - // Throw a config error to let the user know that this property doesn't exist. - private static void validateAllPropertiesProcessed(Map properties) { - for (Object key : properties.keySet()) { - if (key.toString().startsWith("io.prometheus")) { - throw new PrometheusPropertiesException(key + ": Unknown property"); - } + for (String propertyName : propertyNames) { + Matcher matcher = pattern.matcher(propertyName); + if (matcher.find()) { + String metricName = matcher.group(1).replace(".", "_"); + if (!result.containsKey(metricName)) { + result.put( + metricName, + MetricsProperties.load("io.prometheus.metrics." + metricName, properties)); } + } } + return result; + } - private static Map loadProperties(Map externalProperties) { - Map properties = new HashMap<>(); - properties.putAll(loadPropertiesFromClasspath()); - properties.putAll(loadPropertiesFromFile()); // overriding the entries from the classpath file - properties.putAll(System.getProperties()); // overriding the entries from the properties file - properties.putAll(externalProperties); // overriding all the entries above - // TODO: Add environment variables like EXEMPLARS_ENABLED. - return properties; + // If there are properties left starting with io.prometheus it's likely a typo, + // because we didn't use that property. + // Throw a config error to let the user know that this property doesn't exist. + private static void validateAllPropertiesProcessed(Map properties) { + for (Object key : properties.keySet()) { + if (key.toString().startsWith("io.prometheus")) { + throw new PrometheusPropertiesException(key + ": Unknown property"); + } } + } - private static Properties loadPropertiesFromClasspath() { - Properties properties = new Properties(); - try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("prometheus.properties")) { - properties.load(stream); - } catch (Exception ignored) { - } - return properties; + private static Map loadProperties(Map externalProperties) { + Map properties = new HashMap<>(); + properties.putAll(loadPropertiesFromClasspath()); + properties.putAll(loadPropertiesFromFile()); // overriding the entries from the classpath file + properties.putAll(System.getProperties()); // overriding the entries from the properties file + properties.putAll(externalProperties); // overriding all the entries above + // TODO: Add environment variables like EXEMPLARS_ENABLED. + return properties; + } + + private static Properties loadPropertiesFromClasspath() { + Properties properties = new Properties(); + try (InputStream stream = + Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream("prometheus.properties")) { + properties.load(stream); + } catch (Exception ignored) { } + return properties; + } - private static Properties loadPropertiesFromFile() throws PrometheusPropertiesException { - Properties properties = new Properties(); - String path = System.getProperty("prometheus.config"); - if (System.getenv("PROMETHEUS_CONFIG") != null) { - path = System.getenv("PROMETHEUS_CONFIG"); - } - if (path != null) { - try (InputStream stream = Files.newInputStream(Paths.get(path))) { - properties.load(stream); - } catch (IOException e) { - throw new PrometheusPropertiesException("Failed to read Prometheus properties from " + path + ": " + e.getMessage(), e); - } - } - return properties; + private static Properties loadPropertiesFromFile() throws PrometheusPropertiesException { + Properties properties = new Properties(); + String path = System.getProperty("prometheus.config"); + if (System.getenv("PROMETHEUS_CONFIG") != null) { + path = System.getenv("PROMETHEUS_CONFIG"); + } + if (path != null) { + try (InputStream stream = Files.newInputStream(Paths.get(path))) { + properties.load(stream); + } catch (IOException e) { + throw new PrometheusPropertiesException( + "Failed to read Prometheus properties from " + path + ": " + e.getMessage(), e); + } } + return properties; + } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java index 5b3f97252..66d6b2d92 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java @@ -9,131 +9,145 @@ class Util { - private static String getProperty(String name, Map properties) { - Object object = properties.remove(name); - if (object != null) { - return object.toString(); - } - return null; + private static String getProperty(String name, Map properties) { + Object object = properties.remove(name); + if (object != null) { + return object.toString(); } + return null; + } - static Boolean loadBoolean(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - if (!"true".equalsIgnoreCase(property) && !"false".equalsIgnoreCase(property)) { - throw new PrometheusPropertiesException(name + "=" + property + ": Expecting 'true' or 'false'"); - } - return Boolean.parseBoolean(property); - } - return null; + static Boolean loadBoolean(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + if (!"true".equalsIgnoreCase(property) && !"false".equalsIgnoreCase(property)) { + throw new PrometheusPropertiesException( + name + "=" + property + ": Expecting 'true' or 'false'"); + } + return Boolean.parseBoolean(property); } + return null; + } - static List toList(double... values) { - if (values == null) { - return null; - } - List result = new ArrayList<>(values.length); - for (double value : values) { - result.add(value); - } - return result; + static List toList(double... values) { + if (values == null) { + return null; } - - static String loadString(String name, Map properties) throws PrometheusPropertiesException { - return getProperty(name, properties); + List result = new ArrayList<>(values.length); + for (double value : values) { + result.add(value); } + return result; + } - static List loadStringList(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - return Arrays.asList(property.split("\\s*,\\s*")); - } - return null; + static String loadString(String name, Map properties) + throws PrometheusPropertiesException { + return getProperty(name, properties); + } + + static List loadStringList(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + return Arrays.asList(property.split("\\s*,\\s*")); } + return null; + } - static List loadDoubleList(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - String[] numbers = property.split("\\s*,\\s*"); - Double[] result = new Double[numbers.length]; - for (int i = 0; i < numbers.length; i++) { - try { - if ("+Inf".equals(numbers[i].trim())) { - result[i] = Double.POSITIVE_INFINITY; - } else { - result[i] = Double.parseDouble(numbers[i]); - } - } catch (NumberFormatException e) { - throw new PrometheusPropertiesException(name + "=" + property + ": Expecting comma separated list of double values"); - } - } - return Arrays.asList(result); + static List loadDoubleList(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + String[] numbers = property.split("\\s*,\\s*"); + Double[] result = new Double[numbers.length]; + for (int i = 0; i < numbers.length; i++) { + try { + if ("+Inf".equals(numbers[i].trim())) { + result[i] = Double.POSITIVE_INFINITY; + } else { + result[i] = Double.parseDouble(numbers[i]); + } + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException( + name + "=" + property + ": Expecting comma separated list of double values"); } - return null; + } + return Arrays.asList(result); } + return null; + } - // Map is represented as "key1=value1,key2=value2" - static Map loadMap(String name, Map properties) throws PrometheusPropertiesException { - Map result = new HashMap<>(); - String property = getProperty(name, properties); - if (property != null) { - String[] pairs = property.split(","); - for (String pair : pairs) { - if (pair.contains("=")) { - String[] keyValue = pair.split("=", 1); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - if (key.length() > 0 && value.length() > 0) { - result.putIfAbsent(key, value); - } - } - } + // Map is represented as "key1=value1,key2=value2" + static Map loadMap(String name, Map properties) + throws PrometheusPropertiesException { + Map result = new HashMap<>(); + String property = getProperty(name, properties); + if (property != null) { + String[] pairs = property.split(","); + for (String pair : pairs) { + if (pair.contains("=")) { + String[] keyValue = pair.split("=", 1); + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + if (key.length() > 0 && value.length() > 0) { + result.putIfAbsent(key, value); } + } } - return result; + } } + return result; + } - static Integer loadInteger(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - try { - return Integer.parseInt(property); - } catch (NumberFormatException e) { - throw new PrometheusPropertiesException(name + "=" + property + ": Expecting integer value"); - } - } - return null; + static Integer loadInteger(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException( + name + "=" + property + ": Expecting integer value"); + } } + return null; + } - static Double loadDouble(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - try { - return Double.parseDouble(property); - } catch (NumberFormatException e) { - throw new PrometheusPropertiesException(name + "=" + property + ": Expecting double value"); - } - } - return null; + static Double loadDouble(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Double.parseDouble(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting double value"); + } } + return null; + } - static Long loadLong(String name, Map properties) throws PrometheusPropertiesException { - String property = getProperty(name, properties); - if (property != null) { - try { - return Long.parseLong(property); - } catch (NumberFormatException e) { - throw new PrometheusPropertiesException(name + "=" + property + ": Expecting long value"); - } - } - return null; + static Long loadLong(String name, Map properties) + throws PrometheusPropertiesException { + String property = getProperty(name, properties); + if (property != null) { + try { + return Long.parseLong(property); + } catch (NumberFormatException e) { + throw new PrometheusPropertiesException(name + "=" + property + ": Expecting long value"); + } } + return null; + } - static void assertValue(T number, Predicate predicate, String message, String prefix, String name) throws PrometheusPropertiesException { - if (number != null && !predicate.test(number)) { - String fullMessage = prefix == null ? name + ": " + message : prefix + "." + name + ": " + message; - throw new PrometheusPropertiesException(fullMessage); - } + static void assertValue( + T number, Predicate predicate, String message, String prefix, String name) + throws PrometheusPropertiesException { + if (number != null && !predicate.test(number)) { + String fullMessage = + prefix == null ? name + ": " + message : prefix + "." + name + ": " + message; + throw new PrometheusPropertiesException(fullMessage); } + } } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java index 79c20702c..8d16eadb7 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java @@ -1,33 +1,46 @@ package io.prometheus.metrics.config; import java.util.Properties; - import org.junit.Assert; import org.junit.Test; -/** - * Tests for {@link PrometheusPropertiesLoader}. - */ +/** Tests for {@link PrometheusPropertiesLoader}. */ public class PrometheusPropertiesLoaderTests { - @Test - public void propertiesShouldBeLoadedFromPropertiesFile() { - PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(); - Assert.assertEquals(11, prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals(4, prometheusProperties.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size()); - Assert.assertTrue(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); - } + @Test + public void propertiesShouldBeLoadedFromPropertiesFile() { + PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(); + Assert.assertEquals( + 11, + prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); + Assert.assertEquals( + 4, + prometheusProperties + .getMetricProperties("http_duration_seconds") + .getHistogramClassicUpperBounds() + .size()); + Assert.assertTrue(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); + } - @Test - public void externalPropertiesShouldOverridePropertiesFile() { - Properties properties = new Properties(); - properties.setProperty("io.prometheus.metrics.histogramClassicUpperBounds", ".005, .01"); - properties.setProperty("io.prometheus.metrics.http_duration_seconds.histogramClassicUpperBounds", ".005, .01, .015"); - properties.setProperty("io.prometheus.exporter.exemplarsOnAllMetricTypes", "false"); + @Test + public void externalPropertiesShouldOverridePropertiesFile() { + Properties properties = new Properties(); + properties.setProperty("io.prometheus.metrics.histogramClassicUpperBounds", ".005, .01"); + properties.setProperty( + "io.prometheus.metrics.http_duration_seconds.histogramClassicUpperBounds", + ".005, .01, .015"); + properties.setProperty("io.prometheus.exporter.exemplarsOnAllMetricTypes", "false"); - PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(properties); - Assert.assertEquals(2, prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals(3, prometheusProperties.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size()); - Assert.assertFalse(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); - } + PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(properties); + Assert.assertEquals( + 2, + prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); + Assert.assertEquals( + 3, + prometheusProperties + .getMetricProperties("http_duration_seconds") + .getHistogramClassicUpperBounds() + .size()); + Assert.assertFalse(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); + } } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java index 45fec1be0..f9ef25a7a 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java @@ -1,29 +1,37 @@ package io.prometheus.metrics.config; -import org.junit.Assert; -import org.junit.Test; - import java.io.IOException; import java.io.InputStream; import java.util.Properties; +import org.junit.Assert; +import org.junit.Test; public class PrometheusPropertiesTest { - @Test - public void testPrometheusConfig() { - PrometheusProperties result = PrometheusProperties.get(); - Assert.assertEquals(11, result.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals(4, result.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds().size()); - } + @Test + public void testPrometheusConfig() { + PrometheusProperties result = PrometheusProperties.get(); + Assert.assertEquals( + 11, result.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); + Assert.assertEquals( + 4, + result + .getMetricProperties("http_duration_seconds") + .getHistogramClassicUpperBounds() + .size()); + } - @Test - public void testEmptyUpperBounds() throws IOException { - Properties properties = new Properties(); - try (InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("emptyUpperBounds.properties")) { - properties.load(stream); - } - Assert.assertEquals(1, properties.size()); - MetricsProperties.load("io.prometheus.metrics", properties); - Assert.assertEquals(0, properties.size()); + @Test + public void testEmptyUpperBounds() throws IOException { + Properties properties = new Properties(); + try (InputStream stream = + Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream("emptyUpperBounds.properties")) { + properties.load(stream); } + Assert.assertEquals(1, properties.size()); + MetricsProperties.load("io.prometheus.metrics", properties); + Assert.assertEquals(0, properties.size()); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java index 51b45c62a..7055d7565 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/CounterDataPoint.java @@ -3,9 +3,11 @@ import io.prometheus.metrics.model.snapshots.Labels; /** - * Represents a single counter data point, i.e. a single line for a counter metric in Prometheus text format. - *

      - * Example usage: + * Represents a single counter data point, i.e. a single line for a counter metric in Prometheus + * text format. + * + *

      Example usage: + * *

      {@code
        * Counter counter = Counter.builder()
        *     .name("tasks_total")
      @@ -15,84 +17,86 @@
        * CounterDataPoint pendingTasks = counter.labelValues("pending");
        * CounterDataPoint completedTasks = counter.labelValues("completed");
        * }
      - *

      - * Using {@code DataPoint} directly improves performance. If you increment a counter like this: + * + *

      Using {@code DataPoint} directly improves performance. If you increment a counter like this: + * *

      {@code
        * counter.labelValues("pending").inc();
        * }
      - * the label value {@code "pending"} needs to be looked up every single time. - * Using the {@code CounterDataPoint} like this: + * + * the label value {@code "pending"} needs to be looked up every single time. Using the {@code + * CounterDataPoint} like this: + * *
      {@code
        * CounterDataPoint pendingTasks = counter.labelValues("pending");
        * pendingTasks.inc();
        * }
      - * allows you to look up the label value only once, and then use the {@code CounterDataPoint} directly. - * This is a worthwhile performance improvement when instrumenting a performance-critical code path. - *

      - * If you have a counter without labels like this: + * + * allows you to look up the label value only once, and then use the {@code CounterDataPoint} + * directly. This is a worthwhile performance improvement when instrumenting a performance-critical + * code path. + * + *

      If you have a counter without labels like this: + * *

      {@code
        * Counter counterWithoutLabels = Counter.builder()
        *     .name("events_total")
        *     .register();
        * }
      + * * You can use it as a {@code CounterDataPoint} directly. So the following: + * *
      {@code
        * CounterDataPoint counterData = counterWithoutLabels.labelValues(); // empty label values
        * }
      + * * is equivalent to + * *
      {@code
        * CounterDataPoint counterData = counterWithoutLabels;
        * }
      */ public interface CounterDataPoint extends DataPoint { - /** - * Add one. - */ - default void inc() { - inc(1L); - } + /** Add one. */ + default void inc() { + inc(1L); + } - /** - * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. - */ - default void inc(long amount) { - inc((double) amount); - } + /** + * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + default void inc(long amount) { + inc((double) amount); + } - /** - * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. - */ - void inc(double amount); + /** + * Add {@code amount}. Throws an {@link IllegalArgumentException} if {@code amount} is negative. + */ + void inc(double amount); - /** - * Add one, and create a custom exemplar with the given labels. - */ - default void incWithExemplar(Labels labels) { - incWithExemplar(1.0, labels); - } + /** Add one, and create a custom exemplar with the given labels. */ + default void incWithExemplar(Labels labels) { + incWithExemplar(1.0, labels); + } - /** - * Add {@code amount}, and create a custom exemplar with the given labels. - * Throws an {@link IllegalArgumentException} if {@code amount} is negative. - */ - default void incWithExemplar(long amount, Labels labels) { - inc((double) amount); - } + /** + * Add {@code amount}, and create a custom exemplar with the given labels. Throws an {@link + * IllegalArgumentException} if {@code amount} is negative. + */ + default void incWithExemplar(long amount, Labels labels) { + inc((double) amount); + } - /** - * Add {@code amount}, and create a custom exemplar with the given labels. - * Throws an {@link IllegalArgumentException} if {@code amount} is negative. - */ - void incWithExemplar(double amount, Labels labels); + /** + * Add {@code amount}, and create a custom exemplar with the given labels. Throws an {@link + * IllegalArgumentException} if {@code amount} is negative. + */ + void incWithExemplar(double amount, Labels labels); - /** - * Get the current value. - */ - double get(); + /** Get the current value. */ + double get(); - /** - * Get the current value as a {@code long}. Decimal places will be discarded. - */ - long getLongValue(); + /** Get the current value as a {@code long}. Decimal places will be discarded. */ + long getLongValue(); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java index 8dd277d81..5b6017ddf 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DataPoint.java @@ -1,4 +1,3 @@ package io.prometheus.metrics.core.datapoints; -public interface DataPoint { -} +public interface DataPoint {} diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java index f08ccae9c..57e7a3e86 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java @@ -4,33 +4,29 @@ /** * Represents a single data point of a histogram or a summary metric. - *

      - * Single data point means identified label values like {@code {method="GET", path="/", status_code="200"}}, - * ignoring the {@code "le"} label for histograms or the {@code "quantile"} label for summaries. - *

      - * This interface is named DistributionDataPoint because both histograms and summaries are used to observe - * distributions, like latency distributions or distributions of request sizes. Therefore - * DistributionDataPoint is a good name for a common interface implemented by histogram data points - * and summary data points. - *

      - * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + * + *

      Single data point means identified label values like {@code {method="GET", path="/", + * status_code="200"}}, ignoring the {@code "le"} label for histograms or the {@code "quantile"} + * label for summaries. + * + *

      This interface is named DistributionDataPoint because both histograms and summaries are + * used to observe distributions, like latency distributions or distributions of request sizes. + * Therefore DistributionDataPoint is a good name for a common interface implemented by + * histogram data points and summary data points. + * + *

      See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve + * performance. */ public interface DistributionDataPoint extends DataPoint, TimerApi { - /** - * Observe {@code value}. - */ - void observe(double value); + /** Observe {@code value}. */ + void observe(double value); - /** - * Observe {@code value}, and create a custom exemplar with the given labels. - */ - void observeWithExemplar(double value, Labels labels); + /** Observe {@code value}, and create a custom exemplar with the given labels. */ + void observeWithExemplar(double value, Labels labels); - /** - * {@inheritDoc} - */ - default Timer startTimer() { - return new Timer(this::observe); - } + /** {@inheritDoc} */ + default Timer startTimer() { + return new Timer(this::observe); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java index c208d5414..003e3e5e8 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java @@ -3,83 +3,61 @@ import io.prometheus.metrics.model.snapshots.Labels; /** - * Represents a single gauge data point, i.e. a single line for a gauge metric in Prometheus text format. - *

      - * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + * Represents a single gauge data point, i.e. a single line for a gauge metric in Prometheus text + * format. + * + *

      See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve + * performance. */ public interface GaugeDataPoint extends DataPoint, TimerApi { - /** - * Add one. - */ - default void inc() { - inc(1.0); - } + /** Add one. */ + default void inc() { + inc(1.0); + } - /** - * Add {@code amount}. - */ - void inc(double amount); + /** Add {@code amount}. */ + void inc(double amount); - /** - * Add one, and create a custom exemplar with the given labels. - */ - default void incWithExemplar(Labels labels) { - incWithExemplar(1.0, labels); - } + /** Add one, and create a custom exemplar with the given labels. */ + default void incWithExemplar(Labels labels) { + incWithExemplar(1.0, labels); + } - /** - * Add {@code amount}, and create a custom exemplar with the given labels. - */ - void incWithExemplar(double amount, Labels labels); + /** Add {@code amount}, and create a custom exemplar with the given labels. */ + void incWithExemplar(double amount, Labels labels); - /** - * Subtract one. - */ - default void dec() { - inc(-1.0); - } + /** Subtract one. */ + default void dec() { + inc(-1.0); + } - /** - * Subtract {@code amount}. - */ - default void dec(double amount) { - inc(-amount); - } + /** Subtract {@code amount}. */ + default void dec(double amount) { + inc(-amount); + } - /** - * Subtract one, and create a custom exemplar with the given labels. - */ - default void decWithExemplar(Labels labels) { - incWithExemplar(-1.0, labels); - } + /** Subtract one, and create a custom exemplar with the given labels. */ + default void decWithExemplar(Labels labels) { + incWithExemplar(-1.0, labels); + } - /** - * Subtract {@code amount}, and create a custom exemplar with the given labels. - */ - default void decWithExemplar(double amount, Labels labels) { - incWithExemplar(-amount, labels); - } + /** Subtract {@code amount}, and create a custom exemplar with the given labels. */ + default void decWithExemplar(double amount, Labels labels) { + incWithExemplar(-amount, labels); + } - /** - * Set the gauge to {@code value}. - */ - void set(double value); + /** Set the gauge to {@code value}. */ + void set(double value); - /** - * Get the current value. - */ - double get(); + /** Get the current value. */ + double get(); - /** - * Set the gauge to {@code value}, and create a custom exemplar with the given labels. - */ - void setWithExemplar(double value, Labels labels); + /** Set the gauge to {@code value}, and create a custom exemplar with the given labels. */ + void setWithExemplar(double value, Labels labels); - /** - * {@inheritDoc} - */ - default Timer startTimer() { - return new Timer(this::set); - } + /** {@inheritDoc} */ + default Timer startTimer() { + return new Timer(this::set); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java index 7dd8f68a4..61b458ba8 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java @@ -2,32 +2,37 @@ /** * Represents a single StateSet data point. - *

      - * See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve performance. + * + *

      See JavaDoc of {@link CounterDataPoint} on how using data points directly can improve + * performance. */ public interface StateSetDataPoint extends DataPoint { - /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. - */ - void setTrue(String state); + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link + * io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. + */ + void setTrue(String state); - /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. - */ - void setFalse(String state); + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link + * io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. + */ + void setFalse(String state); - /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. - */ - default void setTrue(Enum state) { - setTrue(state.toString()); - } + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link + * io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. + */ + default void setTrue(Enum state) { + setTrue(state.toString()); + } - /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. - */ - default void setFalse(Enum state) { - setFalse(state.toString()); - } + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link + * io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. + */ + default void setFalse(Enum state) { + setFalse(state.toString()); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java index fd6461869..d860bfa08 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/Timer.java @@ -1,40 +1,37 @@ package io.prometheus.metrics.core.datapoints; import io.prometheus.metrics.model.snapshots.Unit; - import java.io.Closeable; import java.util.function.DoubleConsumer; -/** - * Helper class for observing durations. - */ +/** Helper class for observing durations. */ public class Timer implements Closeable { - private final DoubleConsumer observeFunction; - private final long startTimeNanos = System.nanoTime(); + private final DoubleConsumer observeFunction; + private final long startTimeNanos = System.nanoTime(); - /** - * Constructor is package private. Use the {@link TimerApi} provided by the implementation of the {@link DataPoint}. - */ - Timer(DoubleConsumer observeFunction) { - this.observeFunction = observeFunction; - } + /** + * Constructor is package private. Use the {@link TimerApi} provided by the implementation of the + * {@link DataPoint}. + */ + Timer(DoubleConsumer observeFunction) { + this.observeFunction = observeFunction; + } - /** - * Records the observed duration in seconds since this {@code Timer} instance was created. - * @return the observed duration in seconds. - */ - public double observeDuration() { - double elapsed = Unit.nanosToSeconds(System.nanoTime() - startTimeNanos); - observeFunction.accept(elapsed); - return elapsed; - } + /** + * Records the observed duration in seconds since this {@code Timer} instance was created. + * + * @return the observed duration in seconds. + */ + public double observeDuration() { + double elapsed = Unit.nanosToSeconds(System.nanoTime() - startTimeNanos); + observeFunction.accept(elapsed); + return elapsed; + } - /** - * Same as {@link #observeDuration()}. - */ - @Override - public void close() { - observeDuration(); - } + /** Same as {@link #observeDuration()}. */ + @Override + public void close() { + observeDuration(); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java index 27245bbcb..d4266c04c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java @@ -5,70 +5,75 @@ /** * Convenience API for timing durations. - *

      - * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: - * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". + * + *

      Durations are recorded in seconds. The Prometheus instrumentation guidelines say: "Metrics + * must use base units (e.g. seconds, bytes) and leave converting them to something more readable to + * graphing tools". */ public interface TimerApi { - /** - * Start a {@code Timer}. Example: - *

      {@code
      -     * Histogram histogram = Histogram.builder()
      -     *         .name("http_request_duration_seconds")
      -     *         .help("HTTP request service time in seconds")
      -     *         .unit(SECONDS)
      -     *         .labelNames("method", "path")
      -     *         .register();
      -     *
      -     * try (Timer timer = histogram.labelValues("GET", "/").startTimer()) {
      -     *     // duration of this code block will be observed.
      -     * }
      -     * }
      - * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: - * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". - */ - Timer startTimer(); + /** + * Start a {@code Timer}. Example: + * + *
      {@code
      +   * Histogram histogram = Histogram.builder()
      +   *         .name("http_request_duration_seconds")
      +   *         .help("HTTP request service time in seconds")
      +   *         .unit(SECONDS)
      +   *         .labelNames("method", "path")
      +   *         .register();
      +   *
      +   * try (Timer timer = histogram.labelValues("GET", "/").startTimer()) {
      +   *     // duration of this code block will be observed.
      +   * }
      +   * }
      + * + * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: "Metrics + * must use base units (e.g. seconds, bytes) and leave converting them to something more readable + * to graphing tools". + */ + Timer startTimer(); - /** - * Observe the duration of the {@code func} call. Example: - *
      {@code
      -     * Histogram histogram = Histogram.builder()
      -     *         .name("request_duration_seconds")
      -     *         .help("HTTP request service time in seconds")
      -     *         .unit(SECONDS)
      -     *         .labelNames("method", "path")
      -     *         .register();
      -     *
      -     * histogram2.labelValues("GET", "/").time(() -> {
      -     *     // duration of this code block will be observed.
      -     * });
      -     * }
      - *

      - * Durations are recorded in seconds. The Prometheus instrumentation guidelines say: - * "Metrics must use base units (e.g. seconds, bytes) and leave converting them to something more readable to graphing tools". - */ - default void time(Runnable func) { - try (Timer timer = startTimer()) { - func.run(); - } + /** + * Observe the duration of the {@code func} call. Example: + * + *

      {@code
      +   * Histogram histogram = Histogram.builder()
      +   *         .name("request_duration_seconds")
      +   *         .help("HTTP request service time in seconds")
      +   *         .unit(SECONDS)
      +   *         .labelNames("method", "path")
      +   *         .register();
      +   *
      +   * histogram2.labelValues("GET", "/").time(() -> {
      +   *     // duration of this code block will be observed.
      +   * });
      +   * }
      + * + *

      Durations are recorded in seconds. The Prometheus instrumentation guidelines say: "Metrics + * must use base units (e.g. seconds, bytes) and leave converting them to something more readable + * to graphing tools". + */ + default void time(Runnable func) { + try (Timer timer = startTimer()) { + func.run(); } + } - /** - * Like {@link #time(Runnable)}, but returns the return value of {@code func}. - */ - default T time(Supplier func) { - try (Timer timer = startTimer()) { - return func.get(); - } + /** Like {@link #time(Runnable)}, but returns the return value of {@code func}. */ + default T time(Supplier func) { + try (Timer timer = startTimer()) { + return func.get(); } + } - /** - * Like {@link #time(Supplier)}, but {@code func} may throw a checked {@code Exception}. - */ - default T timeChecked(Callable func) throws Exception { - try (Timer timer = startTimer()) { - return func.call(); - } + /** Like {@link #time(Supplier)}, but {@code func} may throw a checked {@code Exception}. */ + default T timeChecked(Callable func) throws Exception { + try (Timer timer = startTimer()) { + return func.call(); } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java index 7c46c244d..b606d5239 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -1,11 +1,10 @@ package io.prometheus.metrics.core.exemplars; -import io.prometheus.metrics.tracer.common.SpanContext; +import io.prometheus.metrics.core.util.Scheduler; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.core.util.Scheduler; - +import io.prometheus.metrics.tracer.common.SpanContext; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -14,330 +13,346 @@ /** * The ExemplarSampler selects Spans as exemplars. - *

      - * There are two types of Exemplars: Regular exemplars are sampled implicitly if a supported tracing - * library is detected. Custom exemplars are provided explicitly in code, for example if a developer - * wants to make sure an Exemplar is created for a specific code path. - *

      - * Spans will be marked as being an Exemplar by calling {@link SpanContext#markCurrentSpanAsExemplar()}. - * The tracer implementation should set a Span attribute to mark the current Span as an Exemplar. - * This attribute can be used by a trace sampling algorithm to make sure traces with Exemplars are sampled. - *

      - * The ExemplarSample is rate-limited, so only a small fraction of Spans will be marked as Exemplars in - * an application with a large number of requests. - *

      - * See {@link ExemplarSamplerConfig} for configuration options. + * + *

      There are two types of Exemplars: Regular exemplars are sampled implicitly if a supported + * tracing library is detected. Custom exemplars are provided explicitly in code, for example if a + * developer wants to make sure an Exemplar is created for a specific code path. + * + *

      Spans will be marked as being an Exemplar by calling {@link + * SpanContext#markCurrentSpanAsExemplar()}. The tracer implementation should set a Span attribute + * to mark the current Span as an Exemplar. This attribute can be used by a trace sampling algorithm + * to make sure traces with Exemplars are sampled. + * + *

      The ExemplarSample is rate-limited, so only a small fraction of Spans will be marked as + * Exemplars in an application with a large number of requests. + * + *

      See {@link ExemplarSamplerConfig} for configuration options. */ public class ExemplarSampler { - private final ExemplarSamplerConfig config; - private final Exemplar[] exemplars; - private final Exemplar[] customExemplars; // Separate from exemplars, because we don't want custom exemplars - // to be overwritten by automatic exemplar sampling. exemplars.lengt == customExemplars.length - private final AtomicBoolean acceptingNewExemplars = new AtomicBoolean(true); - private final AtomicBoolean acceptingNewCustomExemplars = new AtomicBoolean(true); - private final SpanContext spanContext; // may be null, in that case SpanContextSupplier.getSpanContext() is used. + private final ExemplarSamplerConfig config; + private final Exemplar[] exemplars; + private final Exemplar[] + customExemplars; // Separate from exemplars, because we don't want custom exemplars + // to be overwritten by automatic exemplar sampling. exemplars.lengt == customExemplars.length + private final AtomicBoolean acceptingNewExemplars = new AtomicBoolean(true); + private final AtomicBoolean acceptingNewCustomExemplars = new AtomicBoolean(true); + private final SpanContext + spanContext; // may be null, in that case SpanContextSupplier.getSpanContext() is used. - public ExemplarSampler(ExemplarSamplerConfig config) { - this(config, null); - } + public ExemplarSampler(ExemplarSamplerConfig config) { + this(config, null); + } - /** - * Constructor with an additional {code spanContext} argument. - * This is useful for testing, but may also be useful in some production scenarios. - * If {@code spanContext != null} that spanContext is used and - * {@link io.prometheus.metrics.tracer.initializer.SpanContextSupplier SpanContextSupplier} is not used. - * If {@code spanContext == null} - * {@link io.prometheus.metrics.tracer.initializer.SpanContextSupplier#getSpanContext() SpanContextSupplier.getSpanContext()} - * is called to find a span context. - */ - public ExemplarSampler(ExemplarSamplerConfig config, SpanContext spanContext) { - this.config = config; - this.exemplars = new Exemplar[config.getNumberOfExemplars()]; - this.customExemplars = new Exemplar[exemplars.length]; - this.spanContext = spanContext; - } + /** + * Constructor with an additional {code spanContext} argument. This is useful for testing, but may + * also be useful in some production scenarios. If {@code spanContext != null} that spanContext is + * used and {@link io.prometheus.metrics.tracer.initializer.SpanContextSupplier + * SpanContextSupplier} is not used. If {@code spanContext == null} {@link + * io.prometheus.metrics.tracer.initializer.SpanContextSupplier#getSpanContext() + * SpanContextSupplier.getSpanContext()} is called to find a span context. + */ + public ExemplarSampler(ExemplarSamplerConfig config, SpanContext spanContext) { + this.config = config; + this.exemplars = new Exemplar[config.getNumberOfExemplars()]; + this.customExemplars = new Exemplar[exemplars.length]; + this.spanContext = spanContext; + } - public Exemplars collect() { - // this may run in parallel with observe() - long now = System.currentTimeMillis(); - List result = new ArrayList<>(exemplars.length); - for (int i = 0; i < customExemplars.length; i++) { - Exemplar exemplar = customExemplars[i]; - if (exemplar != null) { - if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { - customExemplars[i] = null; - } else { - result.add(exemplar); - } - } + public Exemplars collect() { + // this may run in parallel with observe() + long now = System.currentTimeMillis(); + List result = new ArrayList<>(exemplars.length); + for (int i = 0; i < customExemplars.length; i++) { + Exemplar exemplar = customExemplars[i]; + if (exemplar != null) { + if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + customExemplars[i] = null; + } else { + result.add(exemplar); } - for (int i = 0; i < exemplars.length && result.size() < exemplars.length; i++) { - Exemplar exemplar = exemplars[i]; - if (exemplar != null) { - if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { - exemplars[i] = null; - } else { - result.add(exemplar); - } - } + } + } + for (int i = 0; i < exemplars.length && result.size() < exemplars.length; i++) { + Exemplar exemplar = exemplars[i]; + if (exemplar != null) { + if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + exemplars[i] = null; + } else { + result.add(exemplar); } - return Exemplars.of(result); + } } + return Exemplars.of(result); + } - public void reset() { - for (int i = 0; i < exemplars.length; i++) { - exemplars[i] = null; - customExemplars[i] = null; - } + public void reset() { + for (int i = 0; i < exemplars.length; i++) { + exemplars[i] = null; + customExemplars[i] = null; } + } - public void observe(double value) { - if (!acceptingNewExemplars.get()) { - return; // This is the hot path in a high-throughput application and should be as efficient as possible. - } - rateLimitedObserve(acceptingNewExemplars, value, exemplars, () -> doObserve(value)); + public void observe(double value) { + if (!acceptingNewExemplars.get()) { + return; // This is the hot path in a high-throughput application and should be as efficient as + // possible. } + rateLimitedObserve(acceptingNewExemplars, value, exemplars, () -> doObserve(value)); + } - public void observeWithExemplar(double value, Labels labels) { - if (!acceptingNewCustomExemplars.get()) { - return; // This is the hot path in a high-throughput application and should be as efficient as possible. - } - rateLimitedObserve(acceptingNewCustomExemplars, value, customExemplars, () -> doObserveWithExemplar(value, labels)); + public void observeWithExemplar(double value, Labels labels) { + if (!acceptingNewCustomExemplars.get()) { + return; // This is the hot path in a high-throughput application and should be as efficient as + // possible. } + rateLimitedObserve( + acceptingNewCustomExemplars, + value, + customExemplars, + () -> doObserveWithExemplar(value, labels)); + } - private long doObserve(double value) { - if (exemplars.length == 1) { - return doObserveSingleExemplar(value); - } else if (config.getHistogramClassicUpperBounds() != null) { - return doObserveWithUpperBounds(value); - } else { - return doObserveWithoutUpperBounds(value); - } + private long doObserve(double value) { + if (exemplars.length == 1) { + return doObserveSingleExemplar(value); + } else if (config.getHistogramClassicUpperBounds() != null) { + return doObserveWithUpperBounds(value); + } else { + return doObserveWithoutUpperBounds(value); } + } - private long doObserveSingleExemplar(double value) { - long now = System.currentTimeMillis(); - Exemplar current = exemplars[0]; - if (current == null || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateExemplar(0, value, now); - } - return 0; + private long doObserveSingleExemplar(double value) { + long now = System.currentTimeMillis(); + Exemplar current = exemplars[0]; + if (current == null + || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateExemplar(0, value, now); } + return 0; + } - private long doObserveWithUpperBounds(double value) { - long now = System.currentTimeMillis(); - double[] upperBounds = config.getHistogramClassicUpperBounds(); - for (int i = 0; i < upperBounds.length; i++) { - if (value <= upperBounds[i]) { - Exemplar previous = exemplars[i]; - if (previous == null || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateExemplar(i, value, now); - } else { - return 0; - } - } + private long doObserveWithUpperBounds(double value) { + long now = System.currentTimeMillis(); + double[] upperBounds = config.getHistogramClassicUpperBounds(); + for (int i = 0; i < upperBounds.length; i++) { + if (value <= upperBounds[i]) { + Exemplar previous = exemplars[i]; + if (previous == null + || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateExemplar(i, value, now); + } else { + return 0; } - return 0; // will never happen, as upperBounds contains +Inf + } } + return 0; // will never happen, as upperBounds contains +Inf + } - private long doObserveWithoutUpperBounds(double value) { - final long now = System.currentTimeMillis(); - Exemplar smallest = null; - int smallestIndex = -1; - Exemplar largest = null; - int largestIndex = -1; - int nullIndex = -1; - for (int i = exemplars.length - 1; i >= 0; i--) { - Exemplar exemplar = exemplars[i]; - if (exemplar == null) { - nullIndex = i; - } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { - exemplars[i] = null; - nullIndex = i; - } else { - if (smallest == null || exemplar.getValue() < smallest.getValue()) { - smallest = exemplar; - smallestIndex = i; - } - if (largest == null || exemplar.getValue() > largest.getValue()) { - largest = exemplar; - largestIndex = i; - } - } - } - if (nullIndex >= 0) { - return updateExemplar(nullIndex, value, now); - } - if (now - smallest.getTimestampMillis() > config.getMinRetentionPeriodMillis() && value < smallest.getValue()) { - return updateExemplar(smallestIndex, value, now); - } - if (now - largest.getTimestampMillis() > config.getMinRetentionPeriodMillis() && value > largest.getValue()) { - return updateExemplar(largestIndex, value, now); - } - long oldestTimestamp = 0; - int oldestIndex = -1; - for (int i = 0; i < exemplars.length; i++) { - Exemplar exemplar = exemplars[i]; - if (exemplar != null && exemplar != smallest && exemplar != largest) { - if (oldestTimestamp == 0 || exemplar.getTimestampMillis() < oldestTimestamp) { - oldestTimestamp = exemplar.getTimestampMillis(); - oldestIndex = i; - } - } + private long doObserveWithoutUpperBounds(double value) { + final long now = System.currentTimeMillis(); + Exemplar smallest = null; + int smallestIndex = -1; + Exemplar largest = null; + int largestIndex = -1; + int nullIndex = -1; + for (int i = exemplars.length - 1; i >= 0; i--) { + Exemplar exemplar = exemplars[i]; + if (exemplar == null) { + nullIndex = i; + } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + exemplars[i] = null; + nullIndex = i; + } else { + if (smallest == null || exemplar.getValue() < smallest.getValue()) { + smallest = exemplar; + smallestIndex = i; } - if (oldestIndex != -1 && now - oldestTimestamp > config.getMinRetentionPeriodMillis()) { - return updateExemplar(oldestIndex, value, now); + if (largest == null || exemplar.getValue() > largest.getValue()) { + largest = exemplar; + largestIndex = i; } - return 0; + } } - - // Returns the timestamp of the newly added Exemplar (which is System.currentTimeMillis()) - // or 0 if no Exemplar was added. - private long doObserveWithExemplar(double amount, Labels labels) { - if (customExemplars.length == 1) { - return doObserveSingleExemplar(amount, labels); - } else if (config.getHistogramClassicUpperBounds() != null) { - return doObserveWithExemplarWithUpperBounds(amount, labels); - } else { - return doObserveWithExemplarWithoutUpperBounds(amount, labels); + if (nullIndex >= 0) { + return updateExemplar(nullIndex, value, now); + } + if (now - smallest.getTimestampMillis() > config.getMinRetentionPeriodMillis() + && value < smallest.getValue()) { + return updateExemplar(smallestIndex, value, now); + } + if (now - largest.getTimestampMillis() > config.getMinRetentionPeriodMillis() + && value > largest.getValue()) { + return updateExemplar(largestIndex, value, now); + } + long oldestTimestamp = 0; + int oldestIndex = -1; + for (int i = 0; i < exemplars.length; i++) { + Exemplar exemplar = exemplars[i]; + if (exemplar != null && exemplar != smallest && exemplar != largest) { + if (oldestTimestamp == 0 || exemplar.getTimestampMillis() < oldestTimestamp) { + oldestTimestamp = exemplar.getTimestampMillis(); + oldestIndex = i; } + } } + if (oldestIndex != -1 && now - oldestTimestamp > config.getMinRetentionPeriodMillis()) { + return updateExemplar(oldestIndex, value, now); + } + return 0; + } - private long doObserveSingleExemplar(double amount, Labels labels) { - long now = System.currentTimeMillis(); - Exemplar current = customExemplars[0]; - if (current == null || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateCustomExemplar(0, amount, labels, now); - } - return 0; + // Returns the timestamp of the newly added Exemplar (which is System.currentTimeMillis()) + // or 0 if no Exemplar was added. + private long doObserveWithExemplar(double amount, Labels labels) { + if (customExemplars.length == 1) { + return doObserveSingleExemplar(amount, labels); + } else if (config.getHistogramClassicUpperBounds() != null) { + return doObserveWithExemplarWithUpperBounds(amount, labels); + } else { + return doObserveWithExemplarWithoutUpperBounds(amount, labels); } + } - private long doObserveWithExemplarWithUpperBounds(double value, Labels labels) { - long now = System.currentTimeMillis(); - double[] upperBounds = config.getHistogramClassicUpperBounds(); - for (int i = 0; i < upperBounds.length; i++) { - if (value <= upperBounds[i]) { - Exemplar previous = customExemplars[i]; - if (previous == null || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateCustomExemplar(i, value, labels, now); - } else { - return 0; - } - } - } - return 0; // will never happen, as upperBounds contains +Inf + private long doObserveSingleExemplar(double amount, Labels labels) { + long now = System.currentTimeMillis(); + Exemplar current = customExemplars[0]; + if (current == null + || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(0, amount, labels, now); } + return 0; + } - private long doObserveWithExemplarWithoutUpperBounds(double amount, Labels labels) { - final long now = System.currentTimeMillis(); - int nullPos = -1; - int oldestPos = -1; - Exemplar oldest = null; - for (int i = customExemplars.length - 1; i >= 0; i--) { - Exemplar exemplar = customExemplars[i]; - if (exemplar == null) { - nullPos = i; - } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { - customExemplars[i] = null; - nullPos = i; - } else { - if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { - oldest = exemplar; - oldestPos = i; - } - } - } - if (nullPos != -1) { - return updateCustomExemplar(nullPos, amount, labels, now); - } else if (now - oldest.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateCustomExemplar(oldestPos, amount, labels, now); + private long doObserveWithExemplarWithUpperBounds(double value, Labels labels) { + long now = System.currentTimeMillis(); + double[] upperBounds = config.getHistogramClassicUpperBounds(); + for (int i = 0; i < upperBounds.length; i++) { + if (value <= upperBounds[i]) { + Exemplar previous = customExemplars[i]; + if (previous == null + || now - previous.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(i, value, labels, now); } else { - return 0; + return 0; } + } } + return 0; // will never happen, as upperBounds contains +Inf + } - /** - * Observing requires a system call to {@link System#currentTimeMillis()}, - * and it requires iterating over the existing exemplars to check if one of the existing - * exemplars can be replaced. - *

      - * To avoid performance issues, we rate limit observing exemplars to - * {@link ExemplarSamplerConfig#getSampleIntervalMillis()} milliseconds. - */ - private void rateLimitedObserve(AtomicBoolean accepting, double value, Exemplar[] exemplars, LongSupplier observeFunc) { - if (Double.isNaN(value)) { - return; - } - if (!accepting.compareAndSet(true, false)) { - return; + private long doObserveWithExemplarWithoutUpperBounds(double amount, Labels labels) { + final long now = System.currentTimeMillis(); + int nullPos = -1; + int oldestPos = -1; + Exemplar oldest = null; + for (int i = customExemplars.length - 1; i >= 0; i--) { + Exemplar exemplar = customExemplars[i]; + if (exemplar == null) { + nullPos = i; + } else if (now - exemplar.getTimestampMillis() > config.getMaxRetentionPeriodMillis()) { + customExemplars[i] = null; + nullPos = i; + } else { + if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { + oldest = exemplar; + oldestPos = i; } - // observeFunc returns the current timestamp or 0 if no Exemplar was added. - long now = observeFunc.getAsLong(); - long sleepTime = now == 0 ? config.getSampleIntervalMillis() : durationUntilNextExemplarExpires(now); - Scheduler.schedule(() -> accepting.compareAndSet(false, true), sleepTime, TimeUnit.MILLISECONDS); + } } + if (nullPos != -1) { + return updateCustomExemplar(nullPos, amount, labels, now); + } else if (now - oldest.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(oldestPos, amount, labels, now); + } else { + return 0; + } + } - private long durationUntilNextExemplarExpires(long now) { - long oldestTimestamp = now; - for (Exemplar exemplar : exemplars) { - if (exemplar == null) { - return config.getSampleIntervalMillis(); - } else if (exemplar.getTimestampMillis() < oldestTimestamp) { - oldestTimestamp = exemplar.getTimestampMillis(); - } - } - long oldestAge = now - oldestTimestamp; - if (oldestAge < config.getMinRetentionPeriodMillis()) { - return config.getMinRetentionPeriodMillis() - oldestAge; - } + /** + * Observing requires a system call to {@link System#currentTimeMillis()}, and it requires + * iterating over the existing exemplars to check if one of the existing exemplars can be + * replaced. + * + *

      To avoid performance issues, we rate limit observing exemplars to {@link + * ExemplarSamplerConfig#getSampleIntervalMillis()} milliseconds. + */ + private void rateLimitedObserve( + AtomicBoolean accepting, double value, Exemplar[] exemplars, LongSupplier observeFunc) { + if (Double.isNaN(value)) { + return; + } + if (!accepting.compareAndSet(true, false)) { + return; + } + // observeFunc returns the current timestamp or 0 if no Exemplar was added. + long now = observeFunc.getAsLong(); + long sleepTime = + now == 0 ? config.getSampleIntervalMillis() : durationUntilNextExemplarExpires(now); + Scheduler.schedule( + () -> accepting.compareAndSet(false, true), sleepTime, TimeUnit.MILLISECONDS); + } + + private long durationUntilNextExemplarExpires(long now) { + long oldestTimestamp = now; + for (Exemplar exemplar : exemplars) { + if (exemplar == null) { return config.getSampleIntervalMillis(); + } else if (exemplar.getTimestampMillis() < oldestTimestamp) { + oldestTimestamp = exemplar.getTimestampMillis(); + } + } + long oldestAge = now - oldestTimestamp; + if (oldestAge < config.getMinRetentionPeriodMillis()) { + return config.getMinRetentionPeriodMillis() - oldestAge; } + return config.getSampleIntervalMillis(); + } - private long updateCustomExemplar(int index, double value, Labels labels, long now) { - if (!labels.contains(Exemplar.TRACE_ID) && !labels.contains(Exemplar.SPAN_ID)) { - labels = labels.merge(doSampleExemplar()); - } - customExemplars[index] = Exemplar.builder() - .value(value) - .labels(labels) - .timestampMillis(now) - .build(); - return now; + private long updateCustomExemplar(int index, double value, Labels labels, long now) { + if (!labels.contains(Exemplar.TRACE_ID) && !labels.contains(Exemplar.SPAN_ID)) { + labels = labels.merge(doSampleExemplar()); } + customExemplars[index] = + Exemplar.builder().value(value).labels(labels).timestampMillis(now).build(); + return now; + } - private long updateExemplar(int index, double value, long now) { - Labels traceLabels = doSampleExemplar(); - if (!traceLabels.isEmpty()) { - exemplars[index] = Exemplar.builder() - .value(value) - .labels(traceLabels) - .timestampMillis(now) - .build(); - return now; - } else { - return 0; - } + private long updateExemplar(int index, double value, long now) { + Labels traceLabels = doSampleExemplar(); + if (!traceLabels.isEmpty()) { + exemplars[index] = + Exemplar.builder().value(value).labels(traceLabels).timestampMillis(now).build(); + return now; + } else { + return 0; } + } - private Labels doSampleExemplar() { - // Using the qualified name so that Micrometer can exclude the dependency on prometheus-metrics-tracer-initializer - // as they provide their own implementation of SpanContextSupplier. - // If we had an import statement for SpanContextSupplier the dependency would be needed in any case. - SpanContext spanContext = this.spanContext != null ? this.spanContext : io.prometheus.metrics.tracer.initializer.SpanContextSupplier.getSpanContext(); - try { - if (spanContext != null) { - if (spanContext.isCurrentSpanSampled()) { - String spanId = spanContext.getCurrentSpanId(); - String traceId = spanContext.getCurrentTraceId(); - if (spanId != null && traceId != null) { - spanContext.markCurrentSpanAsExemplar(); - return Labels.of(Exemplar.TRACE_ID, traceId, Exemplar.SPAN_ID, spanId); - } - } - } - } catch (NoClassDefFoundError ignored) { + private Labels doSampleExemplar() { + // Using the qualified name so that Micrometer can exclude the dependency on + // prometheus-metrics-tracer-initializer + // as they provide their own implementation of SpanContextSupplier. + // If we had an import statement for SpanContextSupplier the dependency would be needed in any + // case. + SpanContext spanContext = + this.spanContext != null + ? this.spanContext + : io.prometheus.metrics.tracer.initializer.SpanContextSupplier.getSpanContext(); + try { + if (spanContext != null) { + if (spanContext.isCurrentSpanSampled()) { + String spanId = spanContext.getCurrentSpanId(); + String traceId = spanContext.getCurrentTraceId(); + if (spanId != null && traceId != null) { + spanContext.markCurrentSpanAsExemplar(); + return Labels.of(Exemplar.TRACE_ID, traceId, Exemplar.SPAN_ID, spanId); + } } - return Labels.EMPTY; + } + } catch (NoClassDefFoundError ignored) { } + return Labels.EMPTY; + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java index 9712f29df..7acfbec22 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfig.java @@ -2,134 +2,143 @@ import io.prometheus.metrics.config.ExemplarsProperties; import io.prometheus.metrics.config.PrometheusProperties; - import java.util.concurrent.TimeUnit; public class ExemplarSamplerConfig { - /** - * See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} - */ - public static final int DEFAULT_MIN_RETENTION_PERIOD_SECONDS = 7; - - /** - * See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} - */ - public static final int DEFAULT_MAX_RETENTION_PERIOD_SECONDS = 70; - - /** - * See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} - */ - private static final int DEFAULT_SAMPLE_INTERVAL_MILLISECONDS = 90; - - private final long minRetentionPeriodMillis; - private final long maxRetentionPeriodMillis; - private final long sampleIntervalMillis; - private final double[] histogramClassicUpperBounds; // null unless it's a classic histogram - private final int numberOfExemplars; // if histogramClassicUpperBounds != null, then numberOfExemplars == histogramClassicUpperBounds.length - - /** - * Constructor for all metric types except classic histograms. - * - * @param properties See {@link PrometheusProperties#getExemplarProperties()}. - * @param numberOfExemplars Counters have 1 Exemplar, native histograms and summaries have 4 Exemplars by default. - * For classic histogram use {@link #ExemplarSamplerConfig(ExemplarsProperties, double[])}. - */ - public ExemplarSamplerConfig(ExemplarsProperties properties, int numberOfExemplars) { - this(properties, numberOfExemplars, null); - } - - /** - * Constructor for classic histogram metrics. - * - * @param properties See {@link PrometheusProperties#getExemplarProperties()}. - * @param histogramClassicUpperBounds the ExemplarSampler will provide one Exemplar per histogram bucket. - * Must be sorted, and must include the +Inf bucket. - */ - public ExemplarSamplerConfig(ExemplarsProperties properties, double[] histogramClassicUpperBounds) { - this(properties, histogramClassicUpperBounds.length, histogramClassicUpperBounds); + /** See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} */ + public static final int DEFAULT_MIN_RETENTION_PERIOD_SECONDS = 7; + + /** See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} */ + public static final int DEFAULT_MAX_RETENTION_PERIOD_SECONDS = 70; + + /** See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} */ + private static final int DEFAULT_SAMPLE_INTERVAL_MILLISECONDS = 90; + + private final long minRetentionPeriodMillis; + private final long maxRetentionPeriodMillis; + private final long sampleIntervalMillis; + private final double[] histogramClassicUpperBounds; // null unless it's a classic histogram + private final int + numberOfExemplars; // if histogramClassicUpperBounds != null, then numberOfExemplars == + + // histogramClassicUpperBounds.length + + /** + * Constructor for all metric types except classic histograms. + * + * @param properties See {@link PrometheusProperties#getExemplarProperties()}. + * @param numberOfExemplars Counters have 1 Exemplar, native histograms and summaries have 4 + * Exemplars by default. For classic histogram use {@link + * #ExemplarSamplerConfig(ExemplarsProperties, double[])}. + */ + public ExemplarSamplerConfig(ExemplarsProperties properties, int numberOfExemplars) { + this(properties, numberOfExemplars, null); + } + + /** + * Constructor for classic histogram metrics. + * + * @param properties See {@link PrometheusProperties#getExemplarProperties()}. + * @param histogramClassicUpperBounds the ExemplarSampler will provide one Exemplar per histogram + * bucket. Must be sorted, and must include the +Inf bucket. + */ + public ExemplarSamplerConfig( + ExemplarsProperties properties, double[] histogramClassicUpperBounds) { + this(properties, histogramClassicUpperBounds.length, histogramClassicUpperBounds); + } + + private ExemplarSamplerConfig( + ExemplarsProperties properties, int numberOfExemplars, double[] histogramClassicUpperBounds) { + this( + TimeUnit.SECONDS.toMillis( + getOrDefault( + properties.getMinRetentionPeriodSeconds(), DEFAULT_MIN_RETENTION_PERIOD_SECONDS)), + TimeUnit.SECONDS.toMillis( + getOrDefault( + properties.getMaxRetentionPeriodSeconds(), DEFAULT_MAX_RETENTION_PERIOD_SECONDS)), + getOrDefault( + properties.getSampleIntervalMilliseconds(), DEFAULT_SAMPLE_INTERVAL_MILLISECONDS), + numberOfExemplars, + histogramClassicUpperBounds); + } + + ExemplarSamplerConfig( + long minRetentionPeriodMillis, + long maxRetentionPeriodMillis, + long sampleIntervalMillis, + int numberOfExemplars, + double[] histogramClassicUpperBounds) { + this.minRetentionPeriodMillis = minRetentionPeriodMillis; + this.maxRetentionPeriodMillis = maxRetentionPeriodMillis; + this.sampleIntervalMillis = sampleIntervalMillis; + this.numberOfExemplars = numberOfExemplars; + this.histogramClassicUpperBounds = histogramClassicUpperBounds; + validate(); + } + + private void validate() { + if (minRetentionPeriodMillis <= 0) { + throw new IllegalArgumentException( + minRetentionPeriodMillis + ": minRetentionPeriod must be > 0."); } - - private ExemplarSamplerConfig(ExemplarsProperties properties, int numberOfExemplars, double[] histogramClassicUpperBounds) { - this( - TimeUnit.SECONDS.toMillis(getOrDefault(properties.getMinRetentionPeriodSeconds(), DEFAULT_MIN_RETENTION_PERIOD_SECONDS)), - TimeUnit.SECONDS.toMillis(getOrDefault(properties.getMaxRetentionPeriodSeconds(), DEFAULT_MAX_RETENTION_PERIOD_SECONDS)), - getOrDefault(properties.getSampleIntervalMilliseconds(), DEFAULT_SAMPLE_INTERVAL_MILLISECONDS), - numberOfExemplars, - histogramClassicUpperBounds); - } - - ExemplarSamplerConfig(long minRetentionPeriodMillis, long maxRetentionPeriodMillis, long sampleIntervalMillis, int numberOfExemplars, double[] histogramClassicUpperBounds) { - this.minRetentionPeriodMillis = minRetentionPeriodMillis; - this.maxRetentionPeriodMillis = maxRetentionPeriodMillis; - this.sampleIntervalMillis = sampleIntervalMillis; - this.numberOfExemplars = numberOfExemplars; - this.histogramClassicUpperBounds = histogramClassicUpperBounds; - validate(); + if (maxRetentionPeriodMillis <= 0) { + throw new IllegalArgumentException( + maxRetentionPeriodMillis + ": maxRetentionPeriod must be > 0."); } - - private void validate() { - if (minRetentionPeriodMillis <= 0) { - throw new IllegalArgumentException(minRetentionPeriodMillis + ": minRetentionPeriod must be > 0."); - } - if (maxRetentionPeriodMillis <= 0) { - throw new IllegalArgumentException(maxRetentionPeriodMillis + ": maxRetentionPeriod must be > 0."); - } - if (histogramClassicUpperBounds != null) { - if (histogramClassicUpperBounds.length == 0 || histogramClassicUpperBounds[histogramClassicUpperBounds.length - 1] != Double.POSITIVE_INFINITY) { - throw new IllegalArgumentException("histogramClassicUpperBounds must contain the +Inf bucket."); - } - if (histogramClassicUpperBounds.length != numberOfExemplars) { - throw new IllegalArgumentException("histogramClassicUpperBounds.length must be equal to numberOfExemplars."); - } - double bound = histogramClassicUpperBounds[0]; - for (int i = 1; i < histogramClassicUpperBounds.length; i++) { - if (bound >= histogramClassicUpperBounds[i]) { - throw new IllegalArgumentException("histogramClassicUpperBounds must be sorted and must not contain duplicates."); - } - } - } - if (numberOfExemplars <= 0) { - throw new IllegalArgumentException(numberOfExemplars + ": numberOfExemplars must be > 0."); + if (histogramClassicUpperBounds != null) { + if (histogramClassicUpperBounds.length == 0 + || histogramClassicUpperBounds[histogramClassicUpperBounds.length - 1] + != Double.POSITIVE_INFINITY) { + throw new IllegalArgumentException( + "histogramClassicUpperBounds must contain the +Inf bucket."); + } + if (histogramClassicUpperBounds.length != numberOfExemplars) { + throw new IllegalArgumentException( + "histogramClassicUpperBounds.length must be equal to numberOfExemplars."); + } + double bound = histogramClassicUpperBounds[0]; + for (int i = 1; i < histogramClassicUpperBounds.length; i++) { + if (bound >= histogramClassicUpperBounds[i]) { + throw new IllegalArgumentException( + "histogramClassicUpperBounds must be sorted and must not contain duplicates."); } + } } - - private static T getOrDefault(T result, T defaultValue) { - return result != null ? result : defaultValue; - } - - /** - * May be {@code null}. - */ - public double[] getHistogramClassicUpperBounds() { - return histogramClassicUpperBounds; - } - - /** - * See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} - */ - public long getMinRetentionPeriodMillis() { - return minRetentionPeriodMillis; - } - - /** - * See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} - */ - public long getMaxRetentionPeriodMillis() { - return maxRetentionPeriodMillis; - } - - /** - * See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} - */ - public long getSampleIntervalMillis() { - return sampleIntervalMillis; - } - - /** - * Defaults: Counters have one Exemplar, native histograms and summaries have 4 Exemplars, classic histograms have one Exemplar per bucket. - */ - public int getNumberOfExemplars() { - return numberOfExemplars; + if (numberOfExemplars <= 0) { + throw new IllegalArgumentException(numberOfExemplars + ": numberOfExemplars must be > 0."); } + } + + private static T getOrDefault(T result, T defaultValue) { + return result != null ? result : defaultValue; + } + + /** May be {@code null}. */ + public double[] getHistogramClassicUpperBounds() { + return histogramClassicUpperBounds; + } + + /** See {@link ExemplarsProperties#getMinRetentionPeriodSeconds()} */ + public long getMinRetentionPeriodMillis() { + return minRetentionPeriodMillis; + } + + /** See {@link ExemplarsProperties#getMaxRetentionPeriodSeconds()} */ + public long getMaxRetentionPeriodMillis() { + return maxRetentionPeriodMillis; + } + + /** See {@link ExemplarsProperties#getSampleIntervalMilliseconds()} */ + public long getSampleIntervalMillis() { + return sampleIntervalMillis; + } + + /** + * Defaults: Counters have one Exemplar, native histograms and summaries have 4 Exemplars, classic + * histograms have one Exemplar per bucket. + */ + public int getNumberOfExemplars() { + return numberOfExemplars; + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java index 390a2bc2b..113a85d55 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -1,7 +1,6 @@ package io.prometheus.metrics.core.metrics; import io.prometheus.metrics.model.snapshots.DataPointSnapshot; - import java.util.Arrays; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; @@ -10,75 +9,74 @@ /** * Metrics support concurrent write and scrape operations. - *

      - * This is implemented by switching to a Buffer when the scrape starts, - * and applying the values from the buffer after the scrape ends. + * + *

      This is implemented by switching to a Buffer when the scrape starts, and applying the values + * from the buffer after the scrape ends. */ class Buffer { - private static final long signBit = 1L << 63; - private final AtomicLong observationCount = new AtomicLong(0); - private double[] observationBuffer = new double[0]; - private int bufferPos = 0; - private boolean reset = false; - private final Object appendLock = new Object(); - private final Object runLock = new Object(); + private static final long signBit = 1L << 63; + private final AtomicLong observationCount = new AtomicLong(0); + private double[] observationBuffer = new double[0]; + private int bufferPos = 0; + private boolean reset = false; + private final Object appendLock = new Object(); + private final Object runLock = new Object(); - boolean append(double value) { - long count = observationCount.incrementAndGet(); - if ((count & signBit) == 0) { - return false; // sign bit not set -> buffer not active. - } else { - doAppend(value); - return true; - } + boolean append(double value) { + long count = observationCount.incrementAndGet(); + if ((count & signBit) == 0) { + return false; // sign bit not set -> buffer not active. + } else { + doAppend(value); + return true; } + } - private void doAppend(double amount) { - synchronized (appendLock) { - if (bufferPos >= observationBuffer.length) { - observationBuffer = Arrays.copyOf(observationBuffer, observationBuffer.length + 128); - } - observationBuffer[bufferPos] = amount; - bufferPos++; - } + private void doAppend(double amount) { + synchronized (appendLock) { + if (bufferPos >= observationBuffer.length) { + observationBuffer = Arrays.copyOf(observationBuffer, observationBuffer.length + 128); + } + observationBuffer[bufferPos] = amount; + bufferPos++; } + } - /** - * Must be called by the runnable in the run() method. - */ - void reset() { - reset = true; - } + /** Must be called by the runnable in the run() method. */ + void reset() { + reset = true; + } - T run(Function complete, Supplier runnable, Consumer observeFunction) { - double[] buffer; - int bufferSize; - T result; - synchronized (runLock) { - Long count = observationCount.getAndAdd(signBit); - while (!complete.apply(count)) { - Thread.yield(); - } - result = runnable.get(); - int expectedBufferSize; - if (reset) { - expectedBufferSize = (int) ((observationCount.getAndSet(0) & ~signBit) - count); - reset = false; - } else { - expectedBufferSize = (int) (observationCount.addAndGet(signBit) - count); - } - while (bufferPos != expectedBufferSize) { - Thread.yield(); - } - buffer = observationBuffer; - bufferSize = bufferPos; - observationBuffer = new double[0]; - bufferPos = 0; - } - for (int i = 0; i < bufferSize; i++) { - observeFunction.accept(buffer[i]); - } - return result; + T run( + Function complete, Supplier runnable, Consumer observeFunction) { + double[] buffer; + int bufferSize; + T result; + synchronized (runLock) { + Long count = observationCount.getAndAdd(signBit); + while (!complete.apply(count)) { + Thread.yield(); + } + result = runnable.get(); + int expectedBufferSize; + if (reset) { + expectedBufferSize = (int) ((observationCount.getAndSet(0) & ~signBit) - count); + reset = false; + } else { + expectedBufferSize = (int) (observationCount.addAndGet(signBit) - count); + } + while (bufferPos != expectedBufferSize) { + Thread.yield(); + } + buffer = observationBuffer; + bufferSize = bufferPos; + observationBuffer = new double[0]; + bufferPos = 0; + } + for (int i = 0; i < bufferSize; i++) { + observeFunction.accept(buffer[i]); } + return result; + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java index 22662c62e..c86f17c21 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java @@ -6,20 +6,20 @@ // However, it has been heavily refactored in the meantime. /* - Copyright 2012 Andrew Wang (andrew@umbrant.com) +Copyright 2012 Andrew Wang (andrew@umbrant.com) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 +http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ import java.util.Arrays; import java.util.Iterator; @@ -27,270 +27,248 @@ import java.util.ListIterator; /** - * Algorithm solving the "Targeted Quantile Problem" as described in - * "Effective Computation of Biased Quantiles over Data Streams" - * by Cormode, Korn, Muthukrishnan, and Srivastava. - * + * Algorithm solving the "Targeted Quantile Problem" as described in "Effective Computation of + * Biased Quantiles over Data Streams" by Cormode, Korn, Muthukrishnan, and Srivastava. */ final class CKMSQuantiles { - final Quantile[] quantiles; + final Quantile[] quantiles; - /** - * Total number of observations (not including those that are still in the buffer). - */ - int n = 0; + /** Total number of observations (not including those that are still in the buffer). */ + int n = 0; - /** - * List of sampled observations, ordered by Sample.value. - */ - final LinkedList samples = new LinkedList(); - - /** - * Compress is called every compressInterval inserts. - * Note that the buffer is flushed whenever get() is called, so we - * cannot just wait until the buffer is full before we call compress. - */ - private final int compressInterval = 128; - private int insertsSinceLastCompress = 0; + /** List of sampled observations, ordered by Sample.value. */ + final LinkedList samples = new LinkedList(); - /** - * Note that the buffer size could as well be less than the compressInterval. - * However, the buffer size should not be greater than the compressInterval, - * because the compressInterval is not respected in flush(), so if you want - * to compress more often than calling flush() that won't work. - */ - private final double[] buffer = new double[compressInterval]; - private int bufferPos = 0; + /** + * Compress is called every compressInterval inserts. Note that the buffer is flushed whenever + * get() is called, so we cannot just wait until the buffer is full before we call compress. + */ + private final int compressInterval = 128; - public CKMSQuantiles(Quantile... quantiles) { - if (quantiles.length == 0) { - throw new IllegalArgumentException("quantiles cannot be empty"); - } - this.quantiles = quantiles; - } + private int insertsSinceLastCompress = 0; - /** - * Add an observed value - */ - public void insert(double value) { - buffer[bufferPos++] = value; + /** + * Note that the buffer size could as well be less than the compressInterval. However, the buffer + * size should not be greater than the compressInterval, because the compressInterval is not + * respected in flush(), so if you want to compress more often than calling flush() that won't + * work. + */ + private final double[] buffer = new double[compressInterval]; - if (bufferPos == buffer.length) { - flush(); - } + private int bufferPos = 0; - if (++insertsSinceLastCompress == compressInterval) { - compress(); - insertsSinceLastCompress = 0; - } + public CKMSQuantiles(Quantile... quantiles) { + if (quantiles.length == 0) { + throw new IllegalArgumentException("quantiles cannot be empty"); } + this.quantiles = quantiles; + } - private void flush() { - Arrays.sort(buffer, 0, bufferPos); - insertBatch(buffer, bufferPos); - bufferPos = 0; - } + /** Add an observed value */ + public void insert(double value) { + buffer[bufferPos++] = value; - /** - * Inserts the elements from index 0 to index toIndex from the sortedBuffer. - */ - void insertBatch(double[] sortedBuffer, int toIndex) { - if (toIndex == 0) { - return; - } - ListIterator iterator = samples.listIterator(); - int i = 0; // position in buffer - int r = 0; // sum of g's left of the current sample - while (iterator.hasNext() && i < toIndex) { - Sample item = iterator.next(); - while (i < toIndex) { - if (sortedBuffer[i] > item.value) { - break; - } - insertBefore(iterator, sortedBuffer[i], r); - r++; // new item with g=1 was inserted before, so increment r - i++; - n++; - } - r += item.g; - } - while (i < toIndex) { - samples.add(new Sample(sortedBuffer[i], 0)); - i++; - n++; - } + if (bufferPos == buffer.length) { + flush(); } - private void insertBefore(ListIterator iterator, double value, int r) { - if (!iterator.hasPrevious()) { - samples.addFirst(new Sample(value, 0)); - } else { - iterator.previous(); - iterator.add(new Sample(value, f(r) - 1)); - iterator.next(); + if (++insertsSinceLastCompress == compressInterval) { + compress(); + insertsSinceLastCompress = 0; + } + } + + private void flush() { + Arrays.sort(buffer, 0, bufferPos); + insertBatch(buffer, bufferPos); + bufferPos = 0; + } + + /** Inserts the elements from index 0 to index toIndex from the sortedBuffer. */ + void insertBatch(double[] sortedBuffer, int toIndex) { + if (toIndex == 0) { + return; + } + ListIterator iterator = samples.listIterator(); + int i = 0; // position in buffer + int r = 0; // sum of g's left of the current sample + while (iterator.hasNext() && i < toIndex) { + Sample item = iterator.next(); + while (i < toIndex) { + if (sortedBuffer[i] > item.value) { + break; } + insertBefore(iterator, sortedBuffer[i], r); + r++; // new item with g=1 was inserted before, so increment r + i++; + n++; + } + r += item.g; } + while (i < toIndex) { + samples.add(new Sample(sortedBuffer[i], 0)); + i++; + n++; + } + } + + private void insertBefore(ListIterator iterator, double value, int r) { + if (!iterator.hasPrevious()) { + samples.addFirst(new Sample(value, 0)); + } else { + iterator.previous(); + iterator.add(new Sample(value, f(r) - 1)); + iterator.next(); + } + } - /** - * Get the estimated value at the specified quantile. - */ - public double get(double q) { - flush(); - - if (samples.size() == 0) { - return Double.NaN; - } + /** Get the estimated value at the specified quantile. */ + public double get(double q) { + flush(); - if (q == 0.0) { - return samples.getFirst().value; - } + if (samples.size() == 0) { + return Double.NaN; + } - if (q == 1.0) { - return samples.getLast().value; - } + if (q == 0.0) { + return samples.getFirst().value; + } - int r = 0; // sum of g's left of the current sample - int desiredRank = (int) Math.ceil(q * n); - int upperBound = desiredRank + f(desiredRank) / 2; - - ListIterator iterator = samples.listIterator(); - while (iterator.hasNext()) { - Sample sample = iterator.next(); - if (r + sample.g + sample.delta > upperBound) { - iterator.previous(); // roll back the item.next() above - if (iterator.hasPrevious()) { - Sample result = iterator.previous(); - return result.value; - } else { - return sample.value; - } - } - r += sample.g; - } - return samples.getLast().value; + if (q == 1.0) { + return samples.getLast().value; } - /** - * Error function, as in definition 5 of the paper. - */ - int f(int r) { - int minResult = Integer.MAX_VALUE; - for (Quantile q : quantiles) { - if (q.quantile == 0 || q.quantile == 1) { - continue; - } - int result; - // We had a numerical error here with the following example: - // quantile = 0.95, epsilon = 0.01, (n-r) = 30. - // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. - // To avoid running into these types of error we add 0.00000000001 before rounding down. - if (r >= q.quantile * n) { - result = (int) (q.v * r + 0.00000000001); - } else { - result = (int) (q.u * (n - r) + 0.00000000001); - } - if (result < minResult) { - minResult = result; - } + int r = 0; // sum of g's left of the current sample + int desiredRank = (int) Math.ceil(q * n); + int upperBound = desiredRank + f(desiredRank) / 2; + + ListIterator iterator = samples.listIterator(); + while (iterator.hasNext()) { + Sample sample = iterator.next(); + if (r + sample.g + sample.delta > upperBound) { + iterator.previous(); // roll back the item.next() above + if (iterator.hasPrevious()) { + Sample result = iterator.previous(); + return result.value; + } else { + return sample.value; } - return Math.max(minResult, 1); + } + r += sample.g; } + return samples.getLast().value; + } + + /** Error function, as in definition 5 of the paper. */ + int f(int r) { + int minResult = Integer.MAX_VALUE; + for (Quantile q : quantiles) { + if (q.quantile == 0 || q.quantile == 1) { + continue; + } + int result; + // We had a numerical error here with the following example: + // quantile = 0.95, epsilon = 0.01, (n-r) = 30. + // The expected result of (2*0.01*30)/(1-0.95) is 12. The actual result is 11.99999999999999. + // To avoid running into these types of error we add 0.00000000001 before rounding down. + if (r >= q.quantile * n) { + result = (int) (q.v * r + 0.00000000001); + } else { + result = (int) (q.u * (n - r) + 0.00000000001); + } + if (result < minResult) { + minResult = result; + } + } + return Math.max(minResult, 1); + } - /** - * Merge pairs of consecutive samples if this doesn't violate the error function. - */ - void compress() { - if (samples.size() < 3) { - return; - } - Iterator descendingIterator = samples.descendingIterator(); - int r = n; // n is equal to the sum of the g's of all samples - - Sample right; - Sample left = descendingIterator.next(); - r -= left.g; - - while (descendingIterator.hasNext()) { - right = left; - left = descendingIterator.next(); - r = r - left.g; - if (left == samples.getFirst()) { - // The min sample must never be merged. - break; - } - if (left.g + right.g + right.delta < f(r)) { - right.g += left.g; - descendingIterator.remove(); - left = right; - } - } + /** Merge pairs of consecutive samples if this doesn't violate the error function. */ + void compress() { + if (samples.size() < 3) { + return; } + Iterator descendingIterator = samples.descendingIterator(); + int r = n; // n is equal to the sum of the g's of all samples + + Sample right; + Sample left = descendingIterator.next(); + r -= left.g; + + while (descendingIterator.hasNext()) { + right = left; + left = descendingIterator.next(); + r = r - left.g; + if (left == samples.getFirst()) { + // The min sample must never be merged. + break; + } + if (left.g + right.g + right.delta < f(r)) { + right.g += left.g; + descendingIterator.remove(); + left = right; + } + } + } - static class Sample { + static class Sample { - /** - * Observed value. - */ - final double value; + /** Observed value. */ + final double value; - /** - * Difference between the lowest possible rank of this sample and its predecessor. - * This always starts with 1, but will be updated when compress() merges Samples. - */ - int g = 1; + /** + * Difference between the lowest possible rank of this sample and its predecessor. This always + * starts with 1, but will be updated when compress() merges Samples. + */ + int g = 1; - /** - * Difference between the greatest possible rank of this sample and the lowest possible rank of this sample. - */ - final int delta; + /** + * Difference between the greatest possible rank of this sample and the lowest possible rank of + * this sample. + */ + final int delta; - Sample(double value, int delta) { - this.value = value; - this.delta = delta; - } + Sample(double value, int delta) { + this.value = value; + this.delta = delta; + } - @Override - public String toString() { - return String.format("Sample{val=%.3f, g=%d, delta=%d}", value, g, delta); - } + @Override + public String toString() { + return String.format("Sample{val=%.3f, g=%d, delta=%d}", value, g, delta); } + } - static class Quantile { + static class Quantile { - /** - * Quantile. Must be between 0 and 1. - */ - final double quantile; + /** Quantile. Must be between 0 and 1. */ + final double quantile; - /** - * Allowed error. Must be between 0 and 1. - */ - final double epsilon; + /** Allowed error. Must be between 0 and 1. */ + final double epsilon; - /** - * Helper used in the error function f(), see definition 5 in the paper. - */ - final double u; + /** Helper used in the error function f(), see definition 5 in the paper. */ + final double u; - /** - * Helper used in the error function f(), see definition 5 in the paper. - */ - final double v; + /** Helper used in the error function f(), see definition 5 in the paper. */ + final double v; - Quantile(double quantile, double epsilon) { - if (quantile < 0.0 || quantile > 1.0) throw new IllegalArgumentException("Quantile must be between 0 and 1"); - if (epsilon < 0.0 || epsilon > 1.0) throw new IllegalArgumentException("Epsilon must be between 0 and 1"); + Quantile(double quantile, double epsilon) { + if (quantile < 0.0 || quantile > 1.0) + throw new IllegalArgumentException("Quantile must be between 0 and 1"); + if (epsilon < 0.0 || epsilon > 1.0) + throw new IllegalArgumentException("Epsilon must be between 0 and 1"); - this.quantile = quantile; - this.epsilon = epsilon; - u = 2.0 * epsilon / (1.0 - quantile); // if quantile == 1 this will be Double.NaN - v = 2.0 * epsilon / quantile; // if quantile == 0 this will be Double.NaN - } + this.quantile = quantile; + this.epsilon = epsilon; + u = 2.0 * epsilon / (1.0 - quantile); // if quantile == 1 this will be Double.NaN + v = 2.0 * epsilon / quantile; // if quantile == 0 this will be Double.NaN + } - @Override - public String toString() { - return String.format("Quantile{q=%.3f, epsilon=%.3f}", quantile, epsilon); - } + @Override + public String toString() { + return String.format("Quantile{q=%.3f, epsilon=%.3f}", quantile, epsilon); } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java index 2d9eb0b54..cf25e6527 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java @@ -2,41 +2,52 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.Labels; - import java.util.List; /** * There are two kinds of metrics: {@code StatefulMetric} and {@code CallbackMetric}. - *

      - * See JavaDoc on {@link StatefulMetric} for more info. + * + *

      See JavaDoc on {@link StatefulMetric} for more info. */ abstract class CallbackMetric extends MetricWithFixedMetadata { - protected CallbackMetric(Builder builder) { - super(builder); - } + protected CallbackMetric(Builder builder) { + super(builder); + } - protected Labels makeLabels(String... labelValues) { - if (labelNames.length == 0) { - if (labelValues != null && labelValues.length > 0) { - throw new IllegalArgumentException("Cannot pass label values to a " + this.getClass().getSimpleName() + " that was created without label names."); - } - return constLabels; - } else { - if (labelValues == null) { - throw new IllegalArgumentException(this.getClass().getSimpleName() + " was created with label names, but the callback was called without label values."); - } - if (labelValues.length != labelNames.length) { - throw new IllegalArgumentException(this.getClass().getSimpleName() + " was created with " + labelNames.length + " label names, but the callback was called with " + labelValues.length + " label values."); - } - return constLabels.merge(Labels.of(labelNames, labelValues)); - } + protected Labels makeLabels(String... labelValues) { + if (labelNames.length == 0) { + if (labelValues != null && labelValues.length > 0) { + throw new IllegalArgumentException( + "Cannot pass label values to a " + + this.getClass().getSimpleName() + + " that was created without label names."); + } + return constLabels; + } else { + if (labelValues == null) { + throw new IllegalArgumentException( + this.getClass().getSimpleName() + + " was created with label names, but the callback was called without label values."); + } + if (labelValues.length != labelNames.length) { + throw new IllegalArgumentException( + this.getClass().getSimpleName() + + " was created with " + + labelNames.length + + " label names, but the callback was called with " + + labelValues.length + + " label values."); + } + return constLabels.merge(Labels.of(labelNames, labelValues)); } + } - static abstract class Builder, M extends CallbackMetric> extends MetricWithFixedMetadata.Builder { + abstract static class Builder, M extends CallbackMetric> + extends MetricWithFixedMetadata.Builder { - protected Builder(List illegalLabelNames, PrometheusProperties properties) { - super(illegalLabelNames, properties); - } + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + super(illegalLabelNames, properties); } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index c5a55ca78..5e435f695 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -8,7 +8,6 @@ import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Labels; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -17,8 +16,9 @@ /** * Counter metric. - *

      - * Example usage: + * + *

      Example usage: + * *

      {@code
        * Counter requestCount = Counter.builder()
        *     .name("requests_total")
      @@ -29,251 +29,234 @@
        * requestCount.labelValues("/hello-world", "500").inc();
        * }
      */ -public class Counter extends StatefulMetric implements CounterDataPoint { - - private final boolean exemplarsEnabled; - private final ExemplarSamplerConfig exemplarSamplerConfig; - - private Counter(Builder builder, PrometheusProperties prometheusProperties) { - super(builder); - MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); - exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); - if (exemplarsEnabled) { - exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); - } else { - exemplarSamplerConfig = null; - } +public class Counter extends StatefulMetric + implements CounterDataPoint { + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Counter(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + if (exemplarsEnabled) { + exemplarSamplerConfig = + new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); + } else { + exemplarSamplerConfig = null; } - - /** - * {@inheritDoc} - */ - @Override - public void inc(long amount) { - getNoLabels().inc(amount); + } + + /** {@inheritDoc} */ + @Override + public void inc(long amount) { + getNoLabels().inc(amount); + } + + /** {@inheritDoc} */ + @Override + public void inc(double amount) { + getNoLabels().inc(amount); + } + + /** {@inheritDoc} */ + @Override + public void incWithExemplar(long amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** {@inheritDoc} */ + @Override + public void incWithExemplar(double amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** {@inheritDoc} */ + public double get() { + return getNoLabels().get(); + } + + /** {@inheritDoc} */ + public long getLongValue() { + return getNoLabels().getLongValue(); + } + + /** {@inheritDoc} */ + @Override + public CounterSnapshot collect() { + return (CounterSnapshot) super.collect(); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + @Override + protected DataPoint newDataPoint() { + if (isExemplarsEnabled()) { + return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); + } else { + return new DataPoint(null); } + } - /** - * {@inheritDoc} - */ - @Override - public void inc(double amount) { - getNoLabels().inc(amount); + @Override + protected CounterSnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); } + return new CounterSnapshot(getMetadata(), data); + } - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(long amount, Labels labels) { - getNoLabels().incWithExemplar(amount, labels); + static String stripTotalSuffix(String name) { + if (name != null && (name.endsWith("_total") || name.endsWith(".total"))) { + name = name.substring(0, name.length() - 6); } + return name; + } - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(double amount, Labels labels) { - getNoLabels().incWithExemplar(amount, labels); + class DataPoint implements CounterDataPoint { + + private final DoubleAdder doubleValue = new DoubleAdder(); + // LongAdder is 20% faster than DoubleAdder. So let's use the LongAdder for long observations, + // and DoubleAdder for double observations. If the user doesn't observe any double at all, + // we will be using the LongAdder and get the best performance. + private final LongAdder longValue = new LongAdder(); + private final long createdTimeMillis = System.currentTimeMillis(); + private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false + + private DataPoint(ExemplarSampler exemplarSampler) { + this.exemplarSampler = exemplarSampler; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public double get() { - return getNoLabels().get(); + return longValue.sum() + doubleValue.sum(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public long getLongValue() { - return getNoLabels().getLongValue(); + return longValue.sum() + (long) doubleValue.sum(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public CounterSnapshot collect() { - return (CounterSnapshot) super.collect(); + public void inc(long amount) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observe(amount); + } } + /** {@inheritDoc} */ @Override - protected boolean isExemplarsEnabled() { - return exemplarsEnabled; + public void inc(double amount) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observe(amount); + } } + /** {@inheritDoc} */ @Override - protected DataPoint newDataPoint() { - if (isExemplarsEnabled()) { - return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); - } else { - return new DataPoint(null); - } + public void incWithExemplar(long amount, Labels labels) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(amount, labels); + } } + /** {@inheritDoc} */ @Override - protected CounterSnapshot collect(List labels, List metricData) { - List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(metricData.get(i).collect(labels.get(i))); - } - return new CounterSnapshot(getMetadata(), data); + public void incWithExemplar(double amount, Labels labels) { + validateAndAdd(amount); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(amount, labels); + } } - static String stripTotalSuffix(String name) { - if (name != null && (name.endsWith("_total") || name.endsWith(".total"))) { - name = name.substring(0, name.length() - 6); - } - return name; + private void validateAndAdd(long amount) { + if (amount < 0) { + throw new IllegalArgumentException( + "Negative increment " + amount + " is illegal for Counter metrics."); + } + longValue.add(amount); } - class DataPoint implements CounterDataPoint { - - private final DoubleAdder doubleValue = new DoubleAdder(); - // LongAdder is 20% faster than DoubleAdder. So let's use the LongAdder for long observations, - // and DoubleAdder for double observations. If the user doesn't observe any double at all, - // we will be using the LongAdder and get the best performance. - private final LongAdder longValue = new LongAdder(); - private final long createdTimeMillis = System.currentTimeMillis(); - private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false - - private DataPoint(ExemplarSampler exemplarSampler) { - this.exemplarSampler = exemplarSampler; - } - - /** - * {@inheritDoc} - */ - public double get() { - return longValue.sum() + doubleValue.sum(); - } - - /** - * {@inheritDoc} - */ - public long getLongValue() { - return longValue.sum() + (long) doubleValue.sum(); - } - - /** - * {@inheritDoc} - */ - @Override - public void inc(long amount) { - validateAndAdd(amount); - if (isExemplarsEnabled()) { - exemplarSampler.observe(amount); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void inc(double amount) { - validateAndAdd(amount); - if (isExemplarsEnabled()) { - exemplarSampler.observe(amount); - } - } + private void validateAndAdd(double amount) { + if (amount < 0) { + throw new IllegalArgumentException( + "Negative increment " + amount + " is illegal for Counter metrics."); + } + doubleValue.add(amount); + } - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(long amount, Labels labels) { - validateAndAdd(amount); - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(amount, labels); - } + private CounterSnapshot.CounterDataPointSnapshot collect(Labels labels) { + // Read the exemplar first. Otherwise, there is a race condition where you might + // see an Exemplar for a value that's not counted yet. + // If there are multiple Exemplars (by default it's just one), use the newest. + Exemplar latestExemplar = null; + if (exemplarSampler != null) { + for (Exemplar exemplar : exemplarSampler.collect()) { + if (latestExemplar == null + || exemplar.getTimestampMillis() > latestExemplar.getTimestampMillis()) { + latestExemplar = exemplar; + } } + } + return new CounterSnapshot.CounterDataPointSnapshot( + get(), labels, latestExemplar, createdTimeMillis); + } + } - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(double amount, Labels labels) { - validateAndAdd(amount); - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(amount, labels); - } - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - private void validateAndAdd(long amount) { - if (amount < 0) { - throw new IllegalArgumentException("Negative increment " + amount + " is illegal for Counter metrics."); - } - longValue.add(amount); - } + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - private void validateAndAdd(double amount) { - if (amount < 0) { - throw new IllegalArgumentException("Negative increment " + amount + " is illegal for Counter metrics."); - } - doubleValue.add(amount); - } + public static class Builder extends StatefulMetric.Builder { - private CounterSnapshot.CounterDataPointSnapshot collect(Labels labels) { - // Read the exemplar first. Otherwise, there is a race condition where you might - // see an Exemplar for a value that's not counted yet. - // If there are multiple Exemplars (by default it's just one), use the newest. - Exemplar latestExemplar = null; - if (exemplarSampler != null) { - for (Exemplar exemplar : exemplarSampler.collect()) { - if (latestExemplar == null || exemplar.getTimestampMillis() > latestExemplar.getTimestampMillis()) { - latestExemplar = exemplar; - } - } - } - return new CounterSnapshot.CounterDataPointSnapshot(get(), labels, latestExemplar, createdTimeMillis); - } + private Builder(PrometheusProperties properties) { + super(Collections.emptyList(), properties); } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + /** + * The {@code _total} suffix will automatically be appended if it's missing. + * + *
      {@code
      +     * Counter c1 = Counter.builder()
      +     *     .name("events_total")
      +     *     .build();
      +     * Counter c2 = Counter.builder()
      +     *     .name("events")
      +     *     .build();
      +     * }
      + * + * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in + * Prometheus. + * + *

      Throws an {@link IllegalArgumentException} if {@link + * io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) + * MetricMetadata.isValidMetricName(name)} is {@code false}. + */ + @Override + public Builder name(String name) { + return super.name(stripTotalSuffix(name)); } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + @Override + public Counter build() { + return new Counter(this, properties); } - public static class Builder extends StatefulMetric.Builder { - - private Builder(PrometheusProperties properties) { - super(Collections.emptyList(), properties); - } - - /** - * The {@code _total} suffix will automatically be appended if it's missing. - *

      {@code
      -         * Counter c1 = Counter.builder()
      -         *     .name("events_total")
      -         *     .build();
      -         * Counter c2 = Counter.builder()
      -         *     .name("events")
      -         *     .build();
      -         * }
      - * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. - *

      - * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} - * is {@code false}. - */ - @Override - public Builder name(String name) { - return super.name(stripTotalSuffix(name)); - } - - @Override - public Counter build() { - return new Counter(this, properties); - } - - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java index 76ce68f23..5dc533d58 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java @@ -2,7 +2,6 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.CounterSnapshot; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -10,6 +9,7 @@ /** * Example: + * *

      {@code
        * ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
        *
      @@ -22,80 +22,87 @@
        */
       public class CounterWithCallback extends CallbackMetric {
       
      -    @FunctionalInterface
      -    public interface Callback {
      -        void call(double value, String... labelValues);
      -    }
      +  @FunctionalInterface
      +  public interface Callback {
      +    void call(double value, String... labelValues);
      +  }
       
      -    private final Consumer callback;
      +  private final Consumer callback;
       
      -    private CounterWithCallback(Builder builder) {
      -        super(builder);
      -        this.callback = builder.callback;
      -        if (callback == null) {
      -            throw new IllegalArgumentException("callback cannot be null");
      -        }
      +  private CounterWithCallback(Builder builder) {
      +    super(builder);
      +    this.callback = builder.callback;
      +    if (callback == null) {
      +      throw new IllegalArgumentException("callback cannot be null");
           }
      -
      -    @Override
      -    public CounterSnapshot collect() {
      -        List dataPoints = new ArrayList<>();
      -        callback.accept((value, labelValues) -> {
      -            dataPoints.add(new CounterSnapshot.CounterDataPointSnapshot(value, makeLabels(labelValues), null, 0L));
      +  }
      +
      +  @Override
      +  public CounterSnapshot collect() {
      +    List dataPoints = new ArrayList<>();
      +    callback.accept(
      +        (value, labelValues) -> {
      +          dataPoints.add(
      +              new CounterSnapshot.CounterDataPointSnapshot(
      +                  value, makeLabels(labelValues), null, 0L));
               });
      -        return new CounterSnapshot(getMetadata(), dataPoints);
      -    }
      +    return new CounterSnapshot(getMetadata(), dataPoints);
      +  }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -    public static Builder builder(PrometheusProperties properties) {
      -        return new Builder(properties);
      -    }
      +  public static Builder builder(PrometheusProperties properties) {
      +    return new Builder(properties);
      +  }
       
      -    public static class Builder extends CallbackMetric.Builder {
      +  public static class Builder
      +      extends CallbackMetric.Builder {
       
      -        private Consumer callback;
      +    private Consumer callback;
       
      -        public Builder callback(Consumer callback) {
      -            this.callback = callback;
      -            return self();
      -        }
      +    public Builder callback(Consumer callback) {
      +      this.callback = callback;
      +      return self();
      +    }
       
      -        private Builder(PrometheusProperties properties) {
      -            super(Collections.emptyList(), properties);
      -        }
      +    private Builder(PrometheusProperties properties) {
      +      super(Collections.emptyList(), properties);
      +    }
       
      -        /**
      -         * The {@code _total} suffix will automatically be appended if it's missing.
      -         * 
      {@code
      -         * CounterWithCallback c1 = CounterWithCallback.builder()
      -         *     .name("events_total")
      -         *     .build();
      -         * CounterWithCallback c2 = CounterWithCallback.builder()
      -         *     .name("events")
      -         *     .build();
      -         * }
      - * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in Prometheus. - *

      - * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} - * is {@code false}. - */ - @Override - public Builder name(String name) { - return super.name(Counter.stripTotalSuffix(name)); - } + /** + * The {@code _total} suffix will automatically be appended if it's missing. + * + *

      {@code
      +     * CounterWithCallback c1 = CounterWithCallback.builder()
      +     *     .name("events_total")
      +     *     .build();
      +     * CounterWithCallback c2 = CounterWithCallback.builder()
      +     *     .name("events")
      +     *     .build();
      +     * }
      + * + * In the example above both {@code c1} and {@code c2} would be named {@code "events_total"} in + * Prometheus. + * + *

      Throws an {@link IllegalArgumentException} if {@link + * io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) + * MetricMetadata.isValidMetricName(name)} is {@code false}. + */ + @Override + public Builder name(String name) { + return super.name(Counter.stripTotalSuffix(name)); + } - @Override - public CounterWithCallback build() { - return new CounterWithCallback(this); - } + @Override + public CounterWithCallback build() { + return new CounterWithCallback(this); + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java index 1c46435f6..a3f7e290d 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java @@ -8,7 +8,6 @@ import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.Labels; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -16,8 +15,9 @@ /** * Gauge metric. - *

      - * Example usage: + * + *

      Example usage: + * *

      {@code
        * Gauge currentActiveUsers = Gauge.builder()
        *     .name("current_active_users")
      @@ -36,194 +36,176 @@
        * }
        * }
      */ -public class Gauge extends StatefulMetric implements GaugeDataPoint { - - private final boolean exemplarsEnabled; - private final ExemplarSamplerConfig exemplarSamplerConfig; - - private Gauge(Builder builder, PrometheusProperties prometheusProperties) { - super(builder); - MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); - exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); - if (exemplarsEnabled) { - exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); - } else { - exemplarSamplerConfig = null; - } +public class Gauge extends StatefulMetric + implements GaugeDataPoint { + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Gauge(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + if (exemplarsEnabled) { + exemplarSamplerConfig = + new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 1); + } else { + exemplarSamplerConfig = null; } - - /** - * {@inheritDoc} - */ - @Override - public void inc(double amount) { - getNoLabels().inc(amount); + } + + /** {@inheritDoc} */ + @Override + public void inc(double amount) { + getNoLabels().inc(amount); + } + + /** {@inheritDoc} */ + @Override + public double get() { + return getNoLabels().get(); + } + + /** {@inheritDoc} */ + @Override + public void incWithExemplar(double amount, Labels labels) { + getNoLabels().incWithExemplar(amount, labels); + } + + /** {@inheritDoc} */ + @Override + public void set(double value) { + getNoLabels().set(value); + } + + /** {@inheritDoc} */ + @Override + public void setWithExemplar(double value, Labels labels) { + getNoLabels().setWithExemplar(value, labels); + } + + /** {@inheritDoc} */ + @Override + public GaugeSnapshot collect() { + return (GaugeSnapshot) super.collect(); + } + + @Override + protected GaugeSnapshot collect(List labels, List metricData) { + List dataPointSnapshots = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + dataPointSnapshots.add(metricData.get(i).collect(labels.get(i))); } - - /** - * {@inheritDoc} - */ - @Override - public double get() { - return getNoLabels().get(); + return new GaugeSnapshot(getMetadata(), dataPointSnapshots); + } + + @Override + protected DataPoint newDataPoint() { + if (isExemplarsEnabled()) { + return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); + } else { + return new DataPoint(null); } + } - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(double amount, Labels labels) { - getNoLabels().incWithExemplar(amount, labels); - } + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } - /** - * {@inheritDoc} - */ - @Override - public void set(double value) { - getNoLabels().set(value); + class DataPoint implements GaugeDataPoint { + + private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false + + private DataPoint(ExemplarSampler exemplarSampler) { + this.exemplarSampler = exemplarSampler; } - /** - * {@inheritDoc} - */ + private final AtomicLong value = new AtomicLong(Double.doubleToRawLongBits(0)); + + /** {@inheritDoc} */ @Override - public void setWithExemplar(double value, Labels labels) { - getNoLabels().setWithExemplar(value, labels); + public void inc(double amount) { + long next = + value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); + if (isExemplarsEnabled()) { + exemplarSampler.observe(Double.longBitsToDouble(next)); + } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public GaugeSnapshot collect() { - return (GaugeSnapshot) super.collect(); + public void incWithExemplar(double amount, Labels labels) { + long next = + value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(Double.longBitsToDouble(next), labels); + } } + /** {@inheritDoc} */ @Override - protected GaugeSnapshot collect(List labels, List metricData) { - List dataPointSnapshots = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - dataPointSnapshots.add(metricData.get(i).collect(labels.get(i))); - } - return new GaugeSnapshot(getMetadata(), dataPointSnapshots); + public void set(double value) { + this.value.set(Double.doubleToRawLongBits(value)); + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } } + /** {@inheritDoc} */ @Override - protected DataPoint newDataPoint() { - if (isExemplarsEnabled()) { - return new DataPoint(new ExemplarSampler(exemplarSamplerConfig)); - } else { - return new DataPoint(null); - } + public double get() { + return Double.longBitsToDouble(value.get()); } + /** {@inheritDoc} */ @Override - protected boolean isExemplarsEnabled() { - return exemplarsEnabled; + public void setWithExemplar(double value, Labels labels) { + this.value.set(Double.doubleToRawLongBits(value)); + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } } - class DataPoint implements GaugeDataPoint { - - private final ExemplarSampler exemplarSampler; // null if isExemplarsEnabled() is false - - private DataPoint(ExemplarSampler exemplarSampler) { - this.exemplarSampler = exemplarSampler; - } - - private final AtomicLong value = new AtomicLong(Double.doubleToRawLongBits(0)); - - /** - * {@inheritDoc} - */ - @Override - public void inc(double amount) { - long next = value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); - if (isExemplarsEnabled()) { - exemplarSampler.observe(Double.longBitsToDouble(next)); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void incWithExemplar(double amount, Labels labels) { - long next = value.updateAndGet(l -> Double.doubleToRawLongBits(Double.longBitsToDouble(l) + amount)); - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(Double.longBitsToDouble(next), labels); - } + private GaugeSnapshot.GaugeDataPointSnapshot collect(Labels labels) { + // Read the exemplar first. Otherwise, there is a race condition where you might + // see an Exemplar for a value that's not represented in getValue() yet. + // If there are multiple Exemplars (by default it's just one), use the oldest + // so that we don't violate min age. + Exemplar oldest = null; + if (isExemplarsEnabled()) { + for (Exemplar exemplar : exemplarSampler.collect()) { + if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { + oldest = exemplar; + } } + } + return new GaugeSnapshot.GaugeDataPointSnapshot(get(), labels, oldest); + } + } - /** - * {@inheritDoc} - */ - @Override - public void set(double value) { - this.value.set(Double.doubleToRawLongBits(value)); - if (isExemplarsEnabled()) { - exemplarSampler.observe(value); - } - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - /** - * {@inheritDoc} - */ - @Override - public double get() { - return Double.longBitsToDouble(value.get()); - } + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - /** - * {@inheritDoc} - */ - @Override - public void setWithExemplar(double value, Labels labels) { - this.value.set(Double.doubleToRawLongBits(value)); - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(value, labels); - } - } + public static class Builder extends StatefulMetric.Builder { - private GaugeSnapshot.GaugeDataPointSnapshot collect(Labels labels) { - // Read the exemplar first. Otherwise, there is a race condition where you might - // see an Exemplar for a value that's not represented in getValue() yet. - // If there are multiple Exemplars (by default it's just one), use the oldest - // so that we don't violate min age. - Exemplar oldest = null; - if (isExemplarsEnabled()) { - for (Exemplar exemplar : exemplarSampler.collect()) { - if (oldest == null || exemplar.getTimestampMillis() < oldest.getTimestampMillis()) { - oldest = exemplar; - } - } - } - return new GaugeSnapshot.GaugeDataPointSnapshot(get(), labels, oldest); - } - } - - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + private Builder(PrometheusProperties config) { + super(Collections.emptyList(), config); } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + @Override + public Gauge build() { + return new Gauge(this, properties); } - public static class Builder extends StatefulMetric.Builder { - - private Builder(PrometheusProperties config) { - super(Collections.emptyList(), config); - } - - @Override - public Gauge build() { - return new Gauge(this, properties); - } - - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java index a88a9acca..8b2d7a0ba 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/GaugeWithCallback.java @@ -2,7 +2,6 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -10,6 +9,7 @@ /** * Example: + * *
      {@code
        * MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        *
      @@ -27,59 +27,62 @@
        */
       public class GaugeWithCallback extends CallbackMetric {
       
      -    @FunctionalInterface
      -    public interface Callback {
      -        void call(double value, String... labelValues);
      -    }
      +  @FunctionalInterface
      +  public interface Callback {
      +    void call(double value, String... labelValues);
      +  }
       
      -    private final Consumer callback;
      +  private final Consumer callback;
       
      -    private GaugeWithCallback(Builder builder) {
      -        super(builder);
      -        this.callback = builder.callback;
      -        if (callback == null) {
      -            throw new IllegalArgumentException("callback cannot be null");
      -        }
      +  private GaugeWithCallback(Builder builder) {
      +    super(builder);
      +    this.callback = builder.callback;
      +    if (callback == null) {
      +      throw new IllegalArgumentException("callback cannot be null");
           }
      +  }
       
      -    @Override
      -    public GaugeSnapshot collect() {
      -        List dataPoints = new ArrayList<>();
      -        callback.accept((value, labelValues) -> {
      -            dataPoints.add(new GaugeSnapshot.GaugeDataPointSnapshot(value, makeLabels(labelValues), null, 0L));
      +  @Override
      +  public GaugeSnapshot collect() {
      +    List dataPoints = new ArrayList<>();
      +    callback.accept(
      +        (value, labelValues) -> {
      +          dataPoints.add(
      +              new GaugeSnapshot.GaugeDataPointSnapshot(value, makeLabels(labelValues), null, 0L));
               });
      -        return new GaugeSnapshot(getMetadata(), dataPoints);
      -    }
      +    return new GaugeSnapshot(getMetadata(), dataPoints);
      +  }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -    public static Builder builder(PrometheusProperties properties) {
      -        return new Builder(properties);
      -    }
      +  public static Builder builder(PrometheusProperties properties) {
      +    return new Builder(properties);
      +  }
       
      -    public static class Builder extends CallbackMetric.Builder {
      +  public static class Builder
      +      extends CallbackMetric.Builder {
       
      -        private Consumer callback;
      +    private Consumer callback;
       
      -        public Builder callback(Consumer callback) {
      -            this.callback = callback;
      -            return self();
      -        }
      +    public Builder callback(Consumer callback) {
      +      this.callback = callback;
      +      return self();
      +    }
       
      -        private Builder(PrometheusProperties properties) {
      -            super(Collections.emptyList(), properties);
      -        }
      +    private Builder(PrometheusProperties properties) {
      +      super(Collections.emptyList(), properties);
      +    }
       
      -        @Override
      -        public GaugeWithCallback build() {
      -            return new GaugeWithCallback(this);
      -        }
      +    @Override
      +    public GaugeWithCallback build() {
      +      return new GaugeWithCallback(this);
      +    }
       
      -        @Override
      -        protected Builder self() {
      -            return this;
      -        }
      +    @Override
      +    protected Builder self() {
      +      return this;
           }
      +  }
       }
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      index 0cad6376c..494f7fded 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      @@ -3,16 +3,15 @@
       import io.prometheus.metrics.config.ExemplarsProperties;
       import io.prometheus.metrics.config.MetricsProperties;
       import io.prometheus.metrics.config.PrometheusProperties;
      +import io.prometheus.metrics.core.datapoints.DistributionDataPoint;
       import io.prometheus.metrics.core.exemplars.ExemplarSampler;
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig;
      +import io.prometheus.metrics.core.util.Scheduler;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.Exemplars;
       import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
       import io.prometheus.metrics.model.snapshots.Labels;
       import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets;
      -import io.prometheus.metrics.core.datapoints.DistributionDataPoint;
      -import io.prometheus.metrics.core.util.Scheduler;
      -
       import java.math.BigDecimal;
       import java.util.ArrayList;
       import java.util.Collections;
      @@ -28,6 +27,7 @@
       
       /**
        * Histogram metric. Example usage:
      + *
        * 
      {@code
        * Histogram histogram = Histogram.builder()
        *         .name("http_request_duration_seconds")
      @@ -40,888 +40,921 @@
        * // do something
        * histogram.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
        * }
      + * * Prometheus supports two internal representations of histograms: + * *
        - *
      1. Classic Histograms have a fixed number of buckets with fixed bucket boundaries.
      2. - *
      3. Native Histograms have an infinite number of buckets with a dynamic resolution. - * Prometheus native histograms are the same as OpenTelemetry's exponential histograms.
      4. + *
      5. Classic Histograms have a fixed number of buckets with fixed bucket boundaries. + *
      6. Native Histograms have an infinite number of buckets with a dynamic resolution. + * Prometheus native histograms are the same as OpenTelemetry's exponential histograms. *
      - * By default, a histogram maintains both representations, i.e. the example above will maintain a classic - * histogram representation with Prometheus' default bucket boundaries as well as native histogram representation. - * Which representation is used depends on the exposition format, i.e. which content type the Prometheus server - * accepts when scraping. Exposition format "Text" exposes the classic histogram, exposition format "Protobuf" - * exposes both representations. This is great for migrating from classic histograms to native histograms. - *

      - * If you want the classic representation only, use {@link Histogram.Builder#classicOnly}. - * If you want the native representation only, use {@link Histogram.Builder#nativeOnly}. + * + * By default, a histogram maintains both representations, i.e. the example above will maintain a + * classic histogram representation with Prometheus' default bucket boundaries as well as native + * histogram representation. Which representation is used depends on the exposition format, i.e. + * which content type the Prometheus server accepts when scraping. Exposition format "Text" exposes + * the classic histogram, exposition format "Protobuf" exposes both representations. This is great + * for migrating from classic histograms to native histograms. + * + *

      If you want the classic representation only, use {@link Histogram.Builder#classicOnly}. If you + * want the native representation only, use {@link Histogram.Builder#nativeOnly}. */ -public class Histogram extends StatefulMetric implements DistributionDataPoint { - - // nativeSchema == CLASSIC_HISTOGRAM indicates that this is a classic histogram only. - private final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; - - // NATIVE_BOUNDS is used to look up the native bucket index depending on the current schema. - private static final double[][] NATIVE_BOUNDS; - - private final boolean exemplarsEnabled; - private final ExemplarSamplerConfig exemplarSamplerConfig; - - // Upper bounds for the classic histogram buckets. Contains at least +Inf. - // An empty array indicates that this is a native histogram only. - private final double[] classicUpperBounds; - - // The schema defines the resolution of the native histogram. - // Schema is Prometheus terminology, in OpenTelemetry it's named "scale". - // The formula for the bucket boundaries at position "index" is: - // - // base := base = (2^(2^-scale)) - // lowerBound := base^(index-1) - // upperBound := base^(index) - // - // Note that this is off-by-one compared to OpenTelemetry. - // - // Example: With schema 0 the bucket boundaries are ... 1/16, 1/8, 1/4, 1/2, 1, 2, 4, 8, 16, ... - // Each increment in schema doubles the number of buckets. - // - // The initialNativeSchema is the schema we start with. The histogram will automatically scale down - // if the number of native histogram buckets exceeds nativeMaxBuckets. - private final int nativeInitialSchema; // integer in [-4, 8] - - // Native histogram buckets get smaller and smaller the closer they get to zero. - // To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all - // values in [-zeroThreshold, +zeroThreshold] to be equal to zero. - // - // The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if - // the number of native histogram buckets exceeds nativeMaxBuckets. - private final double nativeMinZeroThreshold; - private final double nativeMaxZeroThreshold; - - // When the number of native histogram buckets becomes larger than nativeMaxBuckets, - // an attempt is made to reduce the number of buckets: - // (1) Reset if the last reset is longer than the reset duration ago - // (2) Increase the zero bucket width if it's smaller than nativeMaxZeroThreshold - // (3) Decrease the nativeSchema, i.e. merge pairs of neighboring buckets into one - private final int nativeMaxBuckets; - - // If the number of native histogram buckets exceeds nativeMaxBuckets, - // the histogram may reset (all values set to zero) after nativeResetDurationSeconds is expired. - private final long nativeResetDurationSeconds; // 0 indicates no reset - - private Histogram(Histogram.Builder builder, PrometheusProperties prometheusProperties) { - super(builder); - MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); - exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); - nativeInitialSchema = getConfigProperty(properties, props -> { - if (Boolean.TRUE.equals(props.getHistogramClassicOnly())) { +public class Histogram extends StatefulMetric + implements DistributionDataPoint { + + // nativeSchema == CLASSIC_HISTOGRAM indicates that this is a classic histogram only. + private final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; + + // NATIVE_BOUNDS is used to look up the native bucket index depending on the current schema. + private static final double[][] NATIVE_BOUNDS; + + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + // Upper bounds for the classic histogram buckets. Contains at least +Inf. + // An empty array indicates that this is a native histogram only. + private final double[] classicUpperBounds; + + // The schema defines the resolution of the native histogram. + // Schema is Prometheus terminology, in OpenTelemetry it's named "scale". + // The formula for the bucket boundaries at position "index" is: + // + // base := base = (2^(2^-scale)) + // lowerBound := base^(index-1) + // upperBound := base^(index) + // + // Note that this is off-by-one compared to OpenTelemetry. + // + // Example: With schema 0 the bucket boundaries are ... 1/16, 1/8, 1/4, 1/2, 1, 2, 4, 8, 16, ... + // Each increment in schema doubles the number of buckets. + // + // The initialNativeSchema is the schema we start with. The histogram will automatically scale + // down + // if the number of native histogram buckets exceeds nativeMaxBuckets. + private final int nativeInitialSchema; // integer in [-4, 8] + + // Native histogram buckets get smaller and smaller the closer they get to zero. + // To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all + // values in [-zeroThreshold, +zeroThreshold] to be equal to zero. + // + // The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if + // the number of native histogram buckets exceeds nativeMaxBuckets. + private final double nativeMinZeroThreshold; + private final double nativeMaxZeroThreshold; + + // When the number of native histogram buckets becomes larger than nativeMaxBuckets, + // an attempt is made to reduce the number of buckets: + // (1) Reset if the last reset is longer than the reset duration ago + // (2) Increase the zero bucket width if it's smaller than nativeMaxZeroThreshold + // (3) Decrease the nativeSchema, i.e. merge pairs of neighboring buckets into one + private final int nativeMaxBuckets; + + // If the number of native histogram buckets exceeds nativeMaxBuckets, + // the histogram may reset (all values set to zero) after nativeResetDurationSeconds is expired. + private final long nativeResetDurationSeconds; // 0 indicates no reset + + private Histogram(Histogram.Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + nativeInitialSchema = + getConfigProperty( + properties, + props -> { + if (Boolean.TRUE.equals(props.getHistogramClassicOnly())) { return CLASSIC_HISTOGRAM; - } else { + } else { return props.getHistogramNativeInitialSchema(); - } - }); - classicUpperBounds = getConfigProperty(properties, props -> { - if (Boolean.TRUE.equals(props.getHistogramNativeOnly())) { - return new double[]{}; - } else if (props.getHistogramClassicUpperBounds() != null) { - SortedSet upperBounds = new TreeSet<>(props.getHistogramClassicUpperBounds()); + } + }); + classicUpperBounds = + getConfigProperty( + properties, + props -> { + if (Boolean.TRUE.equals(props.getHistogramNativeOnly())) { + return new double[] {}; + } else if (props.getHistogramClassicUpperBounds() != null) { + SortedSet upperBounds = + new TreeSet<>(props.getHistogramClassicUpperBounds()); upperBounds.add(Double.POSITIVE_INFINITY); double[] result = new double[upperBounds.size()]; int i = 0; for (double upperBound : upperBounds) { - result[i++] = upperBound; + result[i++] = upperBound; } return result; - } else { + } else { return null; - } - }); - double max = getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxZeroThreshold); - double min = getConfigProperty(properties, MetricsProperties::getHistogramNativeMinZeroThreshold); - nativeMaxZeroThreshold = max == builder.DEFAULT_NATIVE_MAX_ZERO_THRESHOLD && min > max ? min : max; - nativeMinZeroThreshold = Math.min(min, nativeMaxZeroThreshold); - nativeMaxBuckets = getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxNumberOfBuckets); - nativeResetDurationSeconds = getConfigProperty(properties, MetricsProperties::getHistogramNativeResetDurationSeconds); - ExemplarsProperties exemplarsProperties = prometheusProperties.getExemplarProperties(); - exemplarSamplerConfig = classicUpperBounds.length == 0 ? - new ExemplarSamplerConfig(exemplarsProperties, 4) : - new ExemplarSamplerConfig(exemplarsProperties, classicUpperBounds); + } + }); + double max = + getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxZeroThreshold); + double min = + getConfigProperty(properties, MetricsProperties::getHistogramNativeMinZeroThreshold); + nativeMaxZeroThreshold = + max == builder.DEFAULT_NATIVE_MAX_ZERO_THRESHOLD && min > max ? min : max; + nativeMinZeroThreshold = Math.min(min, nativeMaxZeroThreshold); + nativeMaxBuckets = + getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxNumberOfBuckets); + nativeResetDurationSeconds = + getConfigProperty(properties, MetricsProperties::getHistogramNativeResetDurationSeconds); + ExemplarsProperties exemplarsProperties = prometheusProperties.getExemplarProperties(); + exemplarSamplerConfig = + classicUpperBounds.length == 0 + ? new ExemplarSamplerConfig(exemplarsProperties, 4) + : new ExemplarSamplerConfig(exemplarsProperties, classicUpperBounds); + } + + /** {@inheritDoc} */ + @Override + public void observe(double amount) { + getNoLabels().observe(amount); + } + + /** {@inheritDoc} */ + @Override + public void observeWithExemplar(double amount, Labels labels) { + getNoLabels().observeWithExemplar(amount, labels); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + public class DataPoint implements DistributionDataPoint { + private final LongAdder[] classicBuckets; + private final ConcurrentHashMap nativeBucketsForPositiveValues = + new ConcurrentHashMap<>(); + private final ConcurrentHashMap nativeBucketsForNegativeValues = + new ConcurrentHashMap<>(); + private final LongAdder nativeZeroCount = new LongAdder(); + private final LongAdder count = new LongAdder(); + private final DoubleAdder sum = new DoubleAdder(); + private volatile int nativeSchema = + nativeInitialSchema; // integer in [-4, 8] or CLASSIC_HISTOGRAM + private volatile double nativeZeroThreshold = Histogram.this.nativeMinZeroThreshold; + private volatile long createdTimeMillis = System.currentTimeMillis(); + private final Buffer buffer = new Buffer(); + private volatile boolean resetDurationExpired = false; + private final ExemplarSampler exemplarSampler; + + private DataPoint() { + if (exemplarsEnabled) { + exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); + } else { + exemplarSampler = null; + } + classicBuckets = new LongAdder[classicUpperBounds.length]; + for (int i = 0; i < classicUpperBounds.length; i++) { + classicBuckets[i] = new LongAdder(); + } + maybeScheduleNextReset(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public void observe(double amount) { - getNoLabels().observe(amount); + public void observe(double value) { + if (Double.isNaN(value)) { + // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. + return; + } + if (!buffer.append(value)) { + doObserve(value, false); + } + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public void observeWithExemplar(double amount, Labels labels) { - getNoLabels().observeWithExemplar(amount, labels); + public void observeWithExemplar(double value, Labels labels) { + if (Double.isNaN(value)) { + // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. + return; + } + if (!buffer.append(value)) { + doObserve(value, false); + } + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } } - @Override - protected boolean isExemplarsEnabled() { - return exemplarsEnabled; - } - - public class DataPoint implements DistributionDataPoint { - private final LongAdder[] classicBuckets; - private final ConcurrentHashMap nativeBucketsForPositiveValues = new ConcurrentHashMap<>(); - private final ConcurrentHashMap nativeBucketsForNegativeValues = new ConcurrentHashMap<>(); - private final LongAdder nativeZeroCount = new LongAdder(); - private final LongAdder count = new LongAdder(); - private final DoubleAdder sum = new DoubleAdder(); - private volatile int nativeSchema = nativeInitialSchema; // integer in [-4, 8] or CLASSIC_HISTOGRAM - private volatile double nativeZeroThreshold = Histogram.this.nativeMinZeroThreshold; - private volatile long createdTimeMillis = System.currentTimeMillis(); - private final Buffer buffer = new Buffer(); - private volatile boolean resetDurationExpired = false; - private final ExemplarSampler exemplarSampler; - - private DataPoint() { - if (exemplarsEnabled) { - exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); - } else { - exemplarSampler = null; - } - classicBuckets = new LongAdder[classicUpperBounds.length]; - for (int i = 0; i < classicUpperBounds.length; i++) { - classicBuckets[i] = new LongAdder(); - } - maybeScheduleNextReset(); - } - - /** - * {@inheritDoc} - */ - @Override - public void observe(double value) { - if (Double.isNaN(value)) { - // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. - return; - } - if (!buffer.append(value)) { - doObserve(value, false); - } - if (isExemplarsEnabled()) { - exemplarSampler.observe(value); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void observeWithExemplar(double value, Labels labels) { - if (Double.isNaN(value)) { - // See https://github.com/prometheus/client_golang/issues/1275 on ignoring NaN observations. - return; - } - if (!buffer.append(value)) { - doObserve(value, false); - } - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(value, labels); - } - } - - private void doObserve(double value, boolean fromBuffer) { - // classicUpperBounds is an empty array if this is a native histogram only. - for (int i = 0; i < classicUpperBounds.length; ++i) { - // The last bucket is +Inf, so we always increment. - if (value <= classicUpperBounds[i]) { - classicBuckets[i].add(1); - break; - } - } - boolean nativeBucketCreated = false; - if (Histogram.this.nativeInitialSchema != CLASSIC_HISTOGRAM) { - if (value > nativeZeroThreshold) { - nativeBucketCreated = addToNativeBucket(value, nativeBucketsForPositiveValues); - } else if (value < -nativeZeroThreshold) { - nativeBucketCreated = addToNativeBucket(-value, nativeBucketsForNegativeValues); - } else { - nativeZeroCount.add(1); - } - } - sum.add(value); - count.increment(); // must be the last step, because count is used to signal that the operation is complete. - if (!fromBuffer) { - // maybeResetOrScaleDown will switch to the buffer, - // which won't work if we are currently still processing observations from the buffer. - // The reason is that before switching to the buffer we wait for all pending observations to be counted. - // If we do this while still applying observations from the buffer, the pending observations from - // the buffer will never be counted, and the buffer.run() method will wait forever. - maybeResetOrScaleDown(value, nativeBucketCreated); - } - } - - private HistogramSnapshot.HistogramDataPointSnapshot collect(Labels labels) { - Exemplars exemplars = exemplarSampler != null ? exemplarSampler.collect() : Exemplars.EMPTY; - return buffer.run( - expectedCount -> count.sum() == expectedCount, - () -> { - if (classicUpperBounds.length == 0) { - // native only - return new HistogramSnapshot.HistogramDataPointSnapshot( - nativeSchema, - nativeZeroCount.sum(), - nativeZeroThreshold, - toBucketList(nativeBucketsForPositiveValues), - toBucketList(nativeBucketsForNegativeValues), - sum.sum(), - labels, - exemplars, - createdTimeMillis); - } else if (Histogram.this.nativeInitialSchema == CLASSIC_HISTOGRAM) { - // classic only - return new HistogramSnapshot.HistogramDataPointSnapshot( - ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), - sum.sum(), - labels, - exemplars, - createdTimeMillis); - } else { - // hybrid: classic and native - return new HistogramSnapshot.HistogramDataPointSnapshot( - ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), - nativeSchema, - nativeZeroCount.sum(), - nativeZeroThreshold, - toBucketList(nativeBucketsForPositiveValues), - toBucketList(nativeBucketsForNegativeValues), - sum.sum(), - labels, - exemplars, - createdTimeMillis); - } - }, - v -> doObserve(v, true) - ); - } + private void doObserve(double value, boolean fromBuffer) { + // classicUpperBounds is an empty array if this is a native histogram only. + for (int i = 0; i < classicUpperBounds.length; ++i) { + // The last bucket is +Inf, so we always increment. + if (value <= classicUpperBounds[i]) { + classicBuckets[i].add(1); + break; + } + } + boolean nativeBucketCreated = false; + if (Histogram.this.nativeInitialSchema != CLASSIC_HISTOGRAM) { + if (value > nativeZeroThreshold) { + nativeBucketCreated = addToNativeBucket(value, nativeBucketsForPositiveValues); + } else if (value < -nativeZeroThreshold) { + nativeBucketCreated = addToNativeBucket(-value, nativeBucketsForNegativeValues); + } else { + nativeZeroCount.add(1); + } + } + sum.add(value); + count + .increment(); // must be the last step, because count is used to signal that the operation + // is complete. + if (!fromBuffer) { + // maybeResetOrScaleDown will switch to the buffer, + // which won't work if we are currently still processing observations from the buffer. + // The reason is that before switching to the buffer we wait for all pending observations to + // be counted. + // If we do this while still applying observations from the buffer, the pending observations + // from + // the buffer will never be counted, and the buffer.run() method will wait forever. + maybeResetOrScaleDown(value, nativeBucketCreated); + } + } - private boolean addToNativeBucket(double value, ConcurrentHashMap buckets) { - boolean newBucketCreated = false; - int bucketIndex; - if (Double.isInfinite(value)) { - bucketIndex = findBucketIndex(Double.MAX_VALUE) + 1; + private HistogramSnapshot.HistogramDataPointSnapshot collect(Labels labels) { + Exemplars exemplars = exemplarSampler != null ? exemplarSampler.collect() : Exemplars.EMPTY; + return buffer.run( + expectedCount -> count.sum() == expectedCount, + () -> { + if (classicUpperBounds.length == 0) { + // native only + return new HistogramSnapshot.HistogramDataPointSnapshot( + nativeSchema, + nativeZeroCount.sum(), + nativeZeroThreshold, + toBucketList(nativeBucketsForPositiveValues), + toBucketList(nativeBucketsForNegativeValues), + sum.sum(), + labels, + exemplars, + createdTimeMillis); + } else if (Histogram.this.nativeInitialSchema == CLASSIC_HISTOGRAM) { + // classic only + return new HistogramSnapshot.HistogramDataPointSnapshot( + ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), + sum.sum(), + labels, + exemplars, + createdTimeMillis); } else { - bucketIndex = findBucketIndex(value); - } - LongAdder bucketCount = buckets.get(bucketIndex); - if (bucketCount == null) { - LongAdder newBucketCount = new LongAdder(); - LongAdder existingBucketCount = buckets.putIfAbsent(bucketIndex, newBucketCount); - if (existingBucketCount == null) { - newBucketCreated = true; - bucketCount = newBucketCount; - } else { - bucketCount = existingBucketCount; - } - } - bucketCount.increment(); - return newBucketCreated; - } + // hybrid: classic and native + return new HistogramSnapshot.HistogramDataPointSnapshot( + ClassicHistogramBuckets.of(classicUpperBounds, classicBuckets), + nativeSchema, + nativeZeroCount.sum(), + nativeZeroThreshold, + toBucketList(nativeBucketsForPositiveValues), + toBucketList(nativeBucketsForNegativeValues), + sum.sum(), + labels, + exemplars, + createdTimeMillis); + } + }, + v -> doObserve(v, true)); + } - private int findBucketIndex(double value) { - // Preconditions: - // Double.isNan(value) is false; - // Double.isInfinite(value) is false; - // value > 0 - // --- - // The following is a naive implementation of C's frexp() function. - // Performance can be improved by using the internal Bit representation of floating point numbers. - // More info on the Bit representation of floating point numbers: - // https://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number - // Result: value == frac * 2^exp where frac in [0.5, 1). - double frac = value; - int exp = 0; - while (frac < 0.5) { - frac *= 2.0; - exp--; - } - while (frac >= 1.0) { - frac /= 2.0; - exp++; - } - // end of frexp() + private boolean addToNativeBucket(double value, ConcurrentHashMap buckets) { + boolean newBucketCreated = false; + int bucketIndex; + if (Double.isInfinite(value)) { + bucketIndex = findBucketIndex(Double.MAX_VALUE) + 1; + } else { + bucketIndex = findBucketIndex(value); + } + LongAdder bucketCount = buckets.get(bucketIndex); + if (bucketCount == null) { + LongAdder newBucketCount = new LongAdder(); + LongAdder existingBucketCount = buckets.putIfAbsent(bucketIndex, newBucketCount); + if (existingBucketCount == null) { + newBucketCreated = true; + bucketCount = newBucketCount; + } else { + bucketCount = existingBucketCount; + } + } + bucketCount.increment(); + return newBucketCreated; + } - if (nativeSchema >= 1) { - return findIndex(NATIVE_BOUNDS[nativeSchema - 1], frac) + (exp - 1) * NATIVE_BOUNDS[nativeSchema - 1].length; - } else { - int bucketIndex = exp; - if (frac == 0.5) { - bucketIndex--; - } - int offset = (1 << -nativeSchema) - 1; - bucketIndex = (bucketIndex + offset) >> -nativeSchema; - return bucketIndex; - } - } + private int findBucketIndex(double value) { + // Preconditions: + // Double.isNan(value) is false; + // Double.isInfinite(value) is false; + // value > 0 + // --- + // The following is a naive implementation of C's frexp() function. + // Performance can be improved by using the internal Bit representation of floating point + // numbers. + // More info on the Bit representation of floating point numbers: + // https://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number + // Result: value == frac * 2^exp where frac in [0.5, 1). + double frac = value; + int exp = 0; + while (frac < 0.5) { + frac *= 2.0; + exp--; + } + while (frac >= 1.0) { + frac /= 2.0; + exp++; + } + // end of frexp() + + if (nativeSchema >= 1) { + return findIndex(NATIVE_BOUNDS[nativeSchema - 1], frac) + + (exp - 1) * NATIVE_BOUNDS[nativeSchema - 1].length; + } else { + int bucketIndex = exp; + if (frac == 0.5) { + bucketIndex--; + } + int offset = (1 << -nativeSchema) - 1; + bucketIndex = (bucketIndex + offset) >> -nativeSchema; + return bucketIndex; + } + } - private int findIndex(double[] bounds, double frac) { - // The following is the equivalent of golang's sort.SearchFloat64s(bounds, frac) - // See https://pkg.go.dev/sort#SearchFloat64s - int first = 0; - int last = bounds.length - 1; - while (first <= last) { - int mid = (first + last) / 2; - if (bounds[mid] == frac) { - return mid; - } else if (bounds[mid] < frac) { - first = mid + 1; - } else { - last = mid - 1; - } - } - return last + 1; - } + private int findIndex(double[] bounds, double frac) { + // The following is the equivalent of golang's sort.SearchFloat64s(bounds, frac) + // See https://pkg.go.dev/sort#SearchFloat64s + int first = 0; + int last = bounds.length - 1; + while (first <= last) { + int mid = (first + last) / 2; + if (bounds[mid] == frac) { + return mid; + } else if (bounds[mid] < frac) { + first = mid + 1; + } else { + last = mid - 1; + } + } + return last + 1; + } - /** - * Makes sure that the number of native buckets does not exceed nativeMaxBuckets. - *

        - *
      • If the histogram has already been scaled down (nativeSchema < initialSchema) - * reset after resetIntervalExpired to get back to the original schema.
      • - *
      • If a new bucket was created and we now exceed nativeMaxBuckets - * run maybeScaleDown() to scale down
      • - *
      - */ - private void maybeResetOrScaleDown(double value, boolean nativeBucketCreated) { - AtomicBoolean wasReset = new AtomicBoolean(false); - if (resetDurationExpired && nativeSchema < nativeInitialSchema) { - // If nativeSchema < initialNativeSchema the histogram has been scaled down. - // So if resetDurationExpired we will reset it to restore the original native schema. - buffer.run(expectedCount -> count.sum() == expectedCount, - () -> { - if (maybeReset()) { - wasReset.set(true); - } - return null; - }, - v -> doObserve(v, true)); - } else if (nativeBucketCreated) { - // If a new bucket was created we need to check if nativeMaxBuckets is exceeded - // and scale down if so. - maybeScaleDown(wasReset); - } - if (wasReset.get()) { - // We just discarded the newly observed value. Observe it again. - if (!buffer.append(value)) { - doObserve(value, true); - } - } - } + /** + * Makes sure that the number of native buckets does not exceed nativeMaxBuckets. + * + *
        + *
      • If the histogram has already been scaled down (nativeSchema < initialSchema) reset + * after resetIntervalExpired to get back to the original schema. + *
      • If a new bucket was created and we now exceed nativeMaxBuckets run maybeScaleDown() to + * scale down + *
      + */ + private void maybeResetOrScaleDown(double value, boolean nativeBucketCreated) { + AtomicBoolean wasReset = new AtomicBoolean(false); + if (resetDurationExpired && nativeSchema < nativeInitialSchema) { + // If nativeSchema < initialNativeSchema the histogram has been scaled down. + // So if resetDurationExpired we will reset it to restore the original native schema. + buffer.run( + expectedCount -> count.sum() == expectedCount, + () -> { + if (maybeReset()) { + wasReset.set(true); + } + return null; + }, + v -> doObserve(v, true)); + } else if (nativeBucketCreated) { + // If a new bucket was created we need to check if nativeMaxBuckets is exceeded + // and scale down if so. + maybeScaleDown(wasReset); + } + if (wasReset.get()) { + // We just discarded the newly observed value. Observe it again. + if (!buffer.append(value)) { + doObserve(value, true); + } + } + } - private void maybeScaleDown(AtomicBoolean wasReset) { - if (nativeMaxBuckets == 0 || nativeSchema == -4) { - return; - } - int numberOfBuckets = nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); - if (numberOfBuckets <= nativeMaxBuckets) { - return; - } - buffer.run( - expectedCount -> count.sum() == expectedCount, - () -> { - // Now we are in the synchronized block while new observations go into the buffer. - // Check again if we need to limit the bucket size, because another thread might - // have limited it in the meantime. - int nBuckets = nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); - if (nBuckets <= nativeMaxBuckets || nativeSchema == -4) { - return null; - } - if (maybeReset()) { - wasReset.set(true); - return null; - } - if (maybeWidenZeroBucket()) { - return null; - } - doubleBucketWidth(); - return null; - }, - v -> doObserve(v, true) - ); - } + private void maybeScaleDown(AtomicBoolean wasReset) { + if (nativeMaxBuckets == 0 || nativeSchema == -4) { + return; + } + int numberOfBuckets = + nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); + if (numberOfBuckets <= nativeMaxBuckets) { + return; + } + buffer.run( + expectedCount -> count.sum() == expectedCount, + () -> { + // Now we are in the synchronized block while new observations go into the buffer. + // Check again if we need to limit the bucket size, because another thread might + // have limited it in the meantime. + int nBuckets = + nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); + if (nBuckets <= nativeMaxBuckets || nativeSchema == -4) { + return null; + } + if (maybeReset()) { + wasReset.set(true); + return null; + } + if (maybeWidenZeroBucket()) { + return null; + } + doubleBucketWidth(); + return null; + }, + v -> doObserve(v, true)); + } - // maybeReset is called in the synchronized block while new observations go into the buffer. - private boolean maybeReset() { - if (!resetDurationExpired) { - return false; - } - resetDurationExpired = false; - buffer.reset(); - nativeBucketsForPositiveValues.clear(); - nativeBucketsForNegativeValues.clear(); - nativeZeroCount.reset(); - count.reset(); - sum.reset(); - for (int i = 0; i < classicBuckets.length; i++) { - classicBuckets[i].reset(); - } - nativeZeroThreshold = nativeMinZeroThreshold; - nativeSchema = Histogram.this.nativeInitialSchema; - createdTimeMillis = System.currentTimeMillis(); - if (exemplarSampler != null) { - exemplarSampler.reset(); - } - maybeScheduleNextReset(); - return true; - } + // maybeReset is called in the synchronized block while new observations go into the buffer. + private boolean maybeReset() { + if (!resetDurationExpired) { + return false; + } + resetDurationExpired = false; + buffer.reset(); + nativeBucketsForPositiveValues.clear(); + nativeBucketsForNegativeValues.clear(); + nativeZeroCount.reset(); + count.reset(); + sum.reset(); + for (int i = 0; i < classicBuckets.length; i++) { + classicBuckets[i].reset(); + } + nativeZeroThreshold = nativeMinZeroThreshold; + nativeSchema = Histogram.this.nativeInitialSchema; + createdTimeMillis = System.currentTimeMillis(); + if (exemplarSampler != null) { + exemplarSampler.reset(); + } + maybeScheduleNextReset(); + return true; + } - // maybeWidenZeroBucket is called in the synchronized block while new observations go into the buffer. - private boolean maybeWidenZeroBucket() { - if (nativeZeroThreshold >= nativeMaxZeroThreshold) { - return false; - } - int smallestIndex = findSmallestIndex(nativeBucketsForPositiveValues); - int smallestNegativeIndex = findSmallestIndex(nativeBucketsForNegativeValues); - if (smallestNegativeIndex < smallestIndex) { - smallestIndex = smallestNegativeIndex; - } - if (smallestIndex == Integer.MAX_VALUE) { - return false; - } - double newZeroThreshold = nativeBucketIndexToUpperBound(nativeSchema, smallestIndex); - if (newZeroThreshold > nativeMaxZeroThreshold) { - return false; - } - mergeWithZeroBucket(smallestIndex, nativeBucketsForPositiveValues); - mergeWithZeroBucket(smallestIndex, nativeBucketsForNegativeValues); - nativeZeroThreshold = newZeroThreshold; - return true; - } + // maybeWidenZeroBucket is called in the synchronized block while new observations go into the + // buffer. + private boolean maybeWidenZeroBucket() { + if (nativeZeroThreshold >= nativeMaxZeroThreshold) { + return false; + } + int smallestIndex = findSmallestIndex(nativeBucketsForPositiveValues); + int smallestNegativeIndex = findSmallestIndex(nativeBucketsForNegativeValues); + if (smallestNegativeIndex < smallestIndex) { + smallestIndex = smallestNegativeIndex; + } + if (smallestIndex == Integer.MAX_VALUE) { + return false; + } + double newZeroThreshold = nativeBucketIndexToUpperBound(nativeSchema, smallestIndex); + if (newZeroThreshold > nativeMaxZeroThreshold) { + return false; + } + mergeWithZeroBucket(smallestIndex, nativeBucketsForPositiveValues); + mergeWithZeroBucket(smallestIndex, nativeBucketsForNegativeValues); + nativeZeroThreshold = newZeroThreshold; + return true; + } - private void mergeWithZeroBucket(int index, Map buckets) { - LongAdder count = buckets.remove(index); - if (count != null) { - nativeZeroCount.add(count.sum()); - } - } + private void mergeWithZeroBucket(int index, Map buckets) { + LongAdder count = buckets.remove(index); + if (count != null) { + nativeZeroCount.add(count.sum()); + } + } - private double nativeBucketIndexToUpperBound(int schema, int index) { - double result = calcUpperBound(schema, index); - if (Double.isInfinite(result)) { - // The last bucket boundary should always be MAX_VALUE, so that the +Inf bucket counts only - // actual +Inf observations. - // However, MAX_VALUE is not a natural bucket boundary, so we introduce MAX_VALUE - // as an artificial boundary before +Inf. - double previousBucketBoundary = calcUpperBound(schema, index - 1); - if (Double.isFinite(previousBucketBoundary) && previousBucketBoundary < Double.MAX_VALUE) { - return Double.MAX_VALUE; - } - } - return result; - } + private double nativeBucketIndexToUpperBound(int schema, int index) { + double result = calcUpperBound(schema, index); + if (Double.isInfinite(result)) { + // The last bucket boundary should always be MAX_VALUE, so that the +Inf bucket counts only + // actual +Inf observations. + // However, MAX_VALUE is not a natural bucket boundary, so we introduce MAX_VALUE + // as an artificial boundary before +Inf. + double previousBucketBoundary = calcUpperBound(schema, index - 1); + if (Double.isFinite(previousBucketBoundary) && previousBucketBoundary < Double.MAX_VALUE) { + return Double.MAX_VALUE; + } + } + return result; + } - private double calcUpperBound(int schema, int index) { - // The actual formula is: - // --- - // base := 2^(2^-schema); - // upperBound := base^index; - // --- - // The following implementation reduces the numerical error for index > 0. - // It's not very efficient. We should refactor and use an algorithm as in client_golang's getLe() - double factor = 1.0; - while (index > 0) { - if (index % 2 == 0) { - index /= 2; - schema -= 1; - } else { - index -= 1; - factor *= Math.pow(2, Math.pow(2, -schema)); - } - } - return factor * Math.pow(2, index * Math.pow(2, -schema)); - } + private double calcUpperBound(int schema, int index) { + // The actual formula is: + // --- + // base := 2^(2^-schema); + // upperBound := base^index; + // --- + // The following implementation reduces the numerical error for index > 0. + // It's not very efficient. We should refactor and use an algorithm as in client_golang's + // getLe() + double factor = 1.0; + while (index > 0) { + if (index % 2 == 0) { + index /= 2; + schema -= 1; + } else { + index -= 1; + factor *= Math.pow(2, Math.pow(2, -schema)); + } + } + return factor * Math.pow(2, index * Math.pow(2, -schema)); + } - private int findSmallestIndex(Map nativeBuckets) { - int result = Integer.MAX_VALUE; - for (int key : nativeBuckets.keySet()) { - if (key < result) { - result = key; - } - } - return result; + private int findSmallestIndex(Map nativeBuckets) { + int result = Integer.MAX_VALUE; + for (int key : nativeBuckets.keySet()) { + if (key < result) { + result = key; } + } + return result; + } - // doubleBucketWidth is called in the synchronized block while new observations go into the buffer. - private void doubleBucketWidth() { - doubleBucketWidth(nativeBucketsForPositiveValues); - doubleBucketWidth(nativeBucketsForNegativeValues); - nativeSchema--; - } + // doubleBucketWidth is called in the synchronized block while new observations go into the + // buffer. + private void doubleBucketWidth() { + doubleBucketWidth(nativeBucketsForPositiveValues); + doubleBucketWidth(nativeBucketsForNegativeValues); + nativeSchema--; + } - private void doubleBucketWidth(Map buckets) { - int[] keys = new int[buckets.size()]; - long[] values = new long[keys.length]; - int i = 0; - for (Map.Entry entry : buckets.entrySet()) { - keys[i] = entry.getKey(); - values[i] = entry.getValue().sum(); - i++; - } - buckets.clear(); - for (i = 0; i < keys.length; i++) { - int index = (keys[i] + 1) / 2; - LongAdder count = buckets.get(index); - if (count == null) { - count = new LongAdder(); - buckets.put(index, count); - } - count.add(values[i]); - } - } + private void doubleBucketWidth(Map buckets) { + int[] keys = new int[buckets.size()]; + long[] values = new long[keys.length]; + int i = 0; + for (Map.Entry entry : buckets.entrySet()) { + keys[i] = entry.getKey(); + values[i] = entry.getValue().sum(); + i++; + } + buckets.clear(); + for (i = 0; i < keys.length; i++) { + int index = (keys[i] + 1) / 2; + LongAdder count = buckets.get(index); + if (count == null) { + count = new LongAdder(); + buckets.put(index, count); + } + count.add(values[i]); + } + } - private NativeHistogramBuckets toBucketList(ConcurrentHashMap map) { - int[] bucketIndexes = new int[map.size()]; - long[] counts = new long[map.size()]; - int i = 0; - for (Map.Entry entry : map.entrySet()) { - bucketIndexes[i] = entry.getKey(); - counts[i] = entry.getValue().sum(); - i++; - } - return NativeHistogramBuckets.of(bucketIndexes, counts); - } + private NativeHistogramBuckets toBucketList(ConcurrentHashMap map) { + int[] bucketIndexes = new int[map.size()]; + long[] counts = new long[map.size()]; + int i = 0; + for (Map.Entry entry : map.entrySet()) { + bucketIndexes[i] = entry.getKey(); + counts[i] = entry.getValue().sum(); + i++; + } + return NativeHistogramBuckets.of(bucketIndexes, counts); + } - private void maybeScheduleNextReset() { - if (nativeResetDurationSeconds > 0) { - Scheduler.schedule(() -> resetDurationExpired = true, nativeResetDurationSeconds, TimeUnit.SECONDS); - } - } + private void maybeScheduleNextReset() { + if (nativeResetDurationSeconds > 0) { + Scheduler.schedule( + () -> resetDurationExpired = true, nativeResetDurationSeconds, TimeUnit.SECONDS); + } } + } + + /** {@inheritDoc} */ + @Override + public HistogramSnapshot collect() { + return (HistogramSnapshot) super.collect(); + } + + @Override + protected HistogramSnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new HistogramSnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + static { + // See bounds in client_golang's histogram implementation. + NATIVE_BOUNDS = new double[8][]; + for (int schema = 1; schema <= 8; schema++) { + NATIVE_BOUNDS[schema - 1] = new double[1 << schema]; + NATIVE_BOUNDS[schema - 1][0] = 0.5; + // https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto#L501 + double base = Math.pow(2, Math.pow(2, -schema)); + for (int i = 1; i < NATIVE_BOUNDS[schema - 1].length; i++) { + if (i % 2 == 0 && schema > 1) { + // Use previously calculated value for increased precision, see comment in client_golang's + // implementation. + NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 2][i / 2]; + } else { + NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 1][i - 1] * base; + } + } + } + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder extends StatefulMetric.Builder { + + public static final double[] DEFAULT_CLASSIC_UPPER_BOUNDS = + new double[] {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}; + private final double DEFAULT_NATIVE_MIN_ZERO_THRESHOLD = Math.pow(2.0, -128); + private final double DEFAULT_NATIVE_MAX_ZERO_THRESHOLD = Math.pow(2.0, -128); + private final int DEFAULT_NATIVE_INITIAL_SCHEMA = 5; + private final int DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS = 160; + private final long DEFAULT_NATIVE_RESET_DURATION_SECONDS = 0; // 0 means no reset + + private Boolean nativeOnly; + private Boolean classicOnly; + private double[] classicUpperBounds; + private Integer nativeInitialSchema; + private Double nativeMaxZeroThreshold; + private Double nativeMinZeroThreshold; + private Integer nativeMaxNumberOfBuckets; + private Long nativeResetDurationSeconds; - /** - * {@inheritDoc} - */ @Override - public HistogramSnapshot collect() { - return (HistogramSnapshot) super.collect(); + public Histogram build() { + return new Histogram(this, properties); } @Override - protected HistogramSnapshot collect(List labels, List metricData) { - List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(metricData.get(i).collect(labels.get(i))); - } - return new HistogramSnapshot(getMetadata(), data); + protected MetricsProperties toProperties() { + return MetricsProperties.builder() + .exemplarsEnabled(exemplarsEnabled) + .histogramNativeOnly(nativeOnly) + .histogramClassicOnly(classicOnly) + .histogramClassicUpperBounds(classicUpperBounds) + .histogramNativeInitialSchema(nativeInitialSchema) + .histogramNativeMinZeroThreshold(nativeMinZeroThreshold) + .histogramNativeMaxZeroThreshold(nativeMaxZeroThreshold) + .histogramNativeMaxNumberOfBuckets(nativeMaxNumberOfBuckets) + .histogramNativeResetDurationSeconds(nativeResetDurationSeconds) + .build(); } + /** Default properties for histogram metrics. */ @Override - protected DataPoint newDataPoint() { - return new DataPoint(); - } - - static { - // See bounds in client_golang's histogram implementation. - NATIVE_BOUNDS = new double[8][]; - for (int schema = 1; schema <= 8; schema++) { - NATIVE_BOUNDS[schema - 1] = new double[1 << schema]; - NATIVE_BOUNDS[schema - 1][0] = 0.5; - // https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto#L501 - double base = Math.pow(2, Math.pow(2, -schema)); - for (int i = 1; i < NATIVE_BOUNDS[schema - 1].length; i++) { - if (i % 2 == 0 && schema > 1) { - // Use previously calculated value for increased precision, see comment in client_golang's implementation. - NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 2][i / 2]; - } else { - NATIVE_BOUNDS[schema - 1][i] = NATIVE_BOUNDS[schema - 1][i - 1] * base; - } - } - } + public MetricsProperties getDefaultProperties() { + return MetricsProperties.builder() + .exemplarsEnabled(true) + .histogramNativeOnly(false) + .histogramClassicOnly(false) + .histogramClassicUpperBounds(DEFAULT_CLASSIC_UPPER_BOUNDS) + .histogramNativeInitialSchema(DEFAULT_NATIVE_INITIAL_SCHEMA) + .histogramNativeMinZeroThreshold(DEFAULT_NATIVE_MIN_ZERO_THRESHOLD) + .histogramNativeMaxZeroThreshold(DEFAULT_NATIVE_MAX_ZERO_THRESHOLD) + .histogramNativeMaxNumberOfBuckets(DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS) + .histogramNativeResetDurationSeconds(DEFAULT_NATIVE_RESET_DURATION_SECONDS) + .build(); } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + private Builder(PrometheusProperties config) { + super(Collections.singletonList("le"), config); } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + /** + * Use the native histogram representation only, i.e. don't maintain classic histogram buckets. + * See {@link Histogram} for more info. + */ + public Builder nativeOnly() { + if (Boolean.TRUE.equals(classicOnly)) { + throw new IllegalArgumentException("Cannot call nativeOnly() after calling classicOnly()."); + } + nativeOnly = true; + return this; } - public static class Builder extends StatefulMetric.Builder { - - public static final double[] DEFAULT_CLASSIC_UPPER_BOUNDS = new double[]{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}; - private final double DEFAULT_NATIVE_MIN_ZERO_THRESHOLD = Math.pow(2.0, -128); - private final double DEFAULT_NATIVE_MAX_ZERO_THRESHOLD = Math.pow(2.0, -128); - private final int DEFAULT_NATIVE_INITIAL_SCHEMA = 5; - private final int DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS = 160; - private final long DEFAULT_NATIVE_RESET_DURATION_SECONDS = 0; // 0 means no reset - - private Boolean nativeOnly; - private Boolean classicOnly; - private double[] classicUpperBounds; - private Integer nativeInitialSchema; - private Double nativeMaxZeroThreshold; - private Double nativeMinZeroThreshold; - private Integer nativeMaxNumberOfBuckets; - private Long nativeResetDurationSeconds; - - @Override - public Histogram build() { - return new Histogram(this, properties); - } - - @Override - protected MetricsProperties toProperties() { - return MetricsProperties.builder() - .exemplarsEnabled(exemplarsEnabled) - .histogramNativeOnly(nativeOnly) - .histogramClassicOnly(classicOnly) - .histogramClassicUpperBounds(classicUpperBounds) - .histogramNativeInitialSchema(nativeInitialSchema) - .histogramNativeMinZeroThreshold(nativeMinZeroThreshold) - .histogramNativeMaxZeroThreshold(nativeMaxZeroThreshold) - .histogramNativeMaxNumberOfBuckets(nativeMaxNumberOfBuckets) - .histogramNativeResetDurationSeconds(nativeResetDurationSeconds) - .build(); - } - - /** - * Default properties for histogram metrics. - */ - @Override - public MetricsProperties getDefaultProperties() { - return MetricsProperties.builder() - .exemplarsEnabled(true) - .histogramNativeOnly(false) - .histogramClassicOnly(false) - .histogramClassicUpperBounds(DEFAULT_CLASSIC_UPPER_BOUNDS) - .histogramNativeInitialSchema(DEFAULT_NATIVE_INITIAL_SCHEMA) - .histogramNativeMinZeroThreshold(DEFAULT_NATIVE_MIN_ZERO_THRESHOLD) - .histogramNativeMaxZeroThreshold(DEFAULT_NATIVE_MAX_ZERO_THRESHOLD) - .histogramNativeMaxNumberOfBuckets(DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS) - .histogramNativeResetDurationSeconds(DEFAULT_NATIVE_RESET_DURATION_SECONDS) - .build(); - } - - private Builder(PrometheusProperties config) { - super(Collections.singletonList("le"), config); - } - - /** - * Use the native histogram representation only, i.e. don't maintain classic histogram buckets. - * See {@link Histogram} for more info. - */ - public Builder nativeOnly() { - if (Boolean.TRUE.equals(classicOnly)) { - throw new IllegalArgumentException("Cannot call nativeOnly() after calling classicOnly()."); - } - nativeOnly = true; - return this; - } - - /** - * Use the classic histogram representation only, i.e. don't maintain native histogram buckets. - * See {@link Histogram} for more info. - */ - public Builder classicOnly() { - if (Boolean.TRUE.equals(nativeOnly)) { - throw new IllegalArgumentException("Cannot call classicOnly() after calling nativeOnly()."); - } - classicOnly = true; - return this; - } - + /** + * Use the classic histogram representation only, i.e. don't maintain native histogram buckets. + * See {@link Histogram} for more info. + */ + public Builder classicOnly() { + if (Boolean.TRUE.equals(nativeOnly)) { + throw new IllegalArgumentException("Cannot call classicOnly() after calling nativeOnly()."); + } + classicOnly = true; + return this; + } - /** - * Set the upper bounds for the classic histogram buckets. - * Default is {@link Builder#DEFAULT_CLASSIC_UPPER_BOUNDS}. - * If the +Inf bucket is missing it will be added. - * If upperBounds contains duplicates the duplicates will be removed. - */ - public Builder classicUpperBounds(double... upperBounds) { - this.classicUpperBounds = upperBounds; - for (double bound : upperBounds) { - if (Double.isNaN(bound)) { - throw new IllegalArgumentException("Cannot use NaN as upper bound for a histogram"); - } - } - return this; - } + /** + * Set the upper bounds for the classic histogram buckets. Default is {@link + * Builder#DEFAULT_CLASSIC_UPPER_BOUNDS}. If the +Inf bucket is missing it will be added. If + * upperBounds contains duplicates the duplicates will be removed. + */ + public Builder classicUpperBounds(double... upperBounds) { + this.classicUpperBounds = upperBounds; + for (double bound : upperBounds) { + if (Double.isNaN(bound)) { + throw new IllegalArgumentException("Cannot use NaN as upper bound for a histogram"); + } + } + return this; + } - /** - * Create classic histogram buckets with linear bucket boundaries. - *

      - * Example: {@code withClassicLinearBuckets(1.0, 0.5, 10)} creates bucket boundaries - * {@code [[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5]}. - * - * @param start is the first bucket boundary - * @param width is the width of each bucket - * @param count is the total number of buckets, including start - */ - public Builder classicLinearUpperBounds(double start, double width, int count) { - this.classicUpperBounds = new double[count]; - // Use BigDecimal to avoid weird bucket boundaries like 0.7000000000000001. - BigDecimal s = new BigDecimal(Double.toString(start)); - BigDecimal w = new BigDecimal(Double.toString(width)); - for (int i = 0; i < count; i++) { - classicUpperBounds[i] = s.add(w.multiply(new BigDecimal(i))).doubleValue(); - } - return this; - } + /** + * Create classic histogram buckets with linear bucket boundaries. + * + *

      Example: {@code withClassicLinearBuckets(1.0, 0.5, 10)} creates bucket boundaries {@code + * [[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5]}. + * + * @param start is the first bucket boundary + * @param width is the width of each bucket + * @param count is the total number of buckets, including start + */ + public Builder classicLinearUpperBounds(double start, double width, int count) { + this.classicUpperBounds = new double[count]; + // Use BigDecimal to avoid weird bucket boundaries like 0.7000000000000001. + BigDecimal s = new BigDecimal(Double.toString(start)); + BigDecimal w = new BigDecimal(Double.toString(width)); + for (int i = 0; i < count; i++) { + classicUpperBounds[i] = s.add(w.multiply(new BigDecimal(i))).doubleValue(); + } + return this; + } - /** - * Create classic histogram bucxkets with exponential boundaries. - *

      - * Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket bounaries - * {@code [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]} - * - * @param start is the first bucket boundary - * @param factor growth factor - * @param count total number of buckets, including start - */ - public Builder classicExponentialUpperBounds(double start, double factor, int count) { - classicUpperBounds = new double[count]; - for (int i = 0; i < count; i++) { - classicUpperBounds[i] = start * Math.pow(factor, i); - } - return this; - } + /** + * Create classic histogram bucxkets with exponential boundaries. + * + *

      Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket bounaries + * {@code [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]} + * + * @param start is the first bucket boundary + * @param factor growth factor + * @param count total number of buckets, including start + */ + public Builder classicExponentialUpperBounds(double start, double factor, int count) { + classicUpperBounds = new double[count]; + for (int i = 0; i < count; i++) { + classicUpperBounds[i] = start * Math.pow(factor, i); + } + return this; + } - /** - * The schema is a number in [-4, 8] defining the resolution of the native histogram. - * Default is {@link Builder#DEFAULT_NATIVE_INITIAL_SCHEMA}. - *

      - * The higher the schema, the finer the resolution. - * Schema is Prometheus terminology. In OpenTelemetry it's called "scale". - *

      - * Note that the schema for a histogram may be automatically decreased at runtime if the number - * of native histogram buckets exceeds {@link #nativeMaxNumberOfBuckets(int)}. - *

      - * The following table shows: - *

        - *
      • factor: The growth factor for bucket boundaries, i.e. next bucket boundary = growth factor * previous bucket boundary. - *
      • max quantile error: The maximum error for quantiles calculated using the Prometheus histogram_quantile() function, relative to the observed value, assuming harmonic mean. - *
      - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      max quantile errors for different growth factors
      schemafactormax quantile error
      -465.53699%
      -325699%
      -21688%
      -1460%
      0233%
      11.4142...17%
      21.1892...9%
      31.1090...4%
      41.0442...2%
      51.0218...1%
      61.0108...0.5%
      71.0054...0.3%
      81.0027...0.1%
      - */ - public Builder nativeInitialSchema(int nativeSchema) { - if (nativeSchema < -4 || nativeSchema > 8) { - throw new IllegalArgumentException("Unsupported native histogram schema " + nativeSchema + ": expecting -4 <= schema <= 8."); - } - this.nativeInitialSchema = nativeSchema; - return this; - } + /** + * The schema is a number in [-4, 8] defining the resolution of the native histogram. Default is + * {@link Builder#DEFAULT_NATIVE_INITIAL_SCHEMA}. + * + *

      The higher the schema, the finer the resolution. Schema is Prometheus terminology. In + * OpenTelemetry it's called "scale". + * + *

      Note that the schema for a histogram may be automatically decreased at runtime if the + * number of native histogram buckets exceeds {@link #nativeMaxNumberOfBuckets(int)}. + * + *

      The following table shows: + * + *

        + *
      • factor: The growth factor for bucket boundaries, i.e. next bucket boundary = growth + * factor * previous bucket boundary. + *
      • max quantile error: The maximum error for quantiles calculated using the Prometheus + * histogram_quantile() function, relative to the observed value, assuming harmonic mean. + *
      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      max quantile errors for different growth factors
      schemafactormax quantile error
      -465.53699%
      -325699%
      -21688%
      -1460%
      0233%
      11.4142...17%
      21.1892...9%
      31.1090...4%
      41.0442...2%
      51.0218...1%
      61.0108...0.5%
      71.0054...0.3%
      81.0027...0.1%
      + */ + public Builder nativeInitialSchema(int nativeSchema) { + if (nativeSchema < -4 || nativeSchema > 8) { + throw new IllegalArgumentException( + "Unsupported native histogram schema " + + nativeSchema + + ": expecting -4 <= schema <= 8."); + } + this.nativeInitialSchema = nativeSchema; + return this; + } - /** - * Native histogram buckets get smaller and smaller the closer they get to zero. - * To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all - * values in [-zeroThreshold, +zeroThreshold] to be equal to zero. - *

      - * The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if - * the number of native histogram buckets exceeds nativeMaxBuckets. - *

      - * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. - */ - public Builder nativeMaxZeroThreshold(double nativeMaxZeroThreshold) { - if (nativeMaxZeroThreshold < 0) { - throw new IllegalArgumentException("Illegal native max zero threshold " + nativeMaxZeroThreshold + ": must be >= 0"); - } - this.nativeMaxZeroThreshold = nativeMaxZeroThreshold; - return this; - } + /** + * Native histogram buckets get smaller and smaller the closer they get to zero. To avoid + * wasting a lot of buckets for observations fluctuating around zero, we consider all values in + * [-zeroThreshold, +zeroThreshold] to be equal to zero. + * + *

      The zeroThreshold is initialized with minZeroThreshold, and will grow up to + * maxZeroThreshold if the number of native histogram buckets exceeds nativeMaxBuckets. + * + *

      Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. + */ + public Builder nativeMaxZeroThreshold(double nativeMaxZeroThreshold) { + if (nativeMaxZeroThreshold < 0) { + throw new IllegalArgumentException( + "Illegal native max zero threshold " + nativeMaxZeroThreshold + ": must be >= 0"); + } + this.nativeMaxZeroThreshold = nativeMaxZeroThreshold; + return this; + } - /** - * Native histogram buckets get smaller and smaller the closer they get to zero. - * To avoid wasting a lot of buckets for observations fluctuating around zero, we consider all - * values in [-zeroThreshold, +zeroThreshold] to be equal to zero. - *

      - * The zeroThreshold is initialized with minZeroThreshold, and will grow up to maxZeroThreshold if - * the number of native histogram buckets exceeds nativeMaxBuckets. - *

      - * Default is {@link Builder#DEFAULT_NATIVE_MIN_ZERO_THRESHOLD}. - */ - public Builder nativeMinZeroThreshold(double nativeMinZeroThreshold) { - if (nativeMinZeroThreshold < 0) { - throw new IllegalArgumentException("Illegal native min zero threshold " + nativeMinZeroThreshold + ": must be >= 0"); - } - this.nativeMinZeroThreshold = nativeMinZeroThreshold; - return this; - } + /** + * Native histogram buckets get smaller and smaller the closer they get to zero. To avoid + * wasting a lot of buckets for observations fluctuating around zero, we consider all values in + * [-zeroThreshold, +zeroThreshold] to be equal to zero. + * + *

      The zeroThreshold is initialized with minZeroThreshold, and will grow up to + * maxZeroThreshold if the number of native histogram buckets exceeds nativeMaxBuckets. + * + *

      Default is {@link Builder#DEFAULT_NATIVE_MIN_ZERO_THRESHOLD}. + */ + public Builder nativeMinZeroThreshold(double nativeMinZeroThreshold) { + if (nativeMinZeroThreshold < 0) { + throw new IllegalArgumentException( + "Illegal native min zero threshold " + nativeMinZeroThreshold + ": must be >= 0"); + } + this.nativeMinZeroThreshold = nativeMinZeroThreshold; + return this; + } - /** - * Limit the number of native buckets. - *

      - * If the number of native buckets exceeds the maximum, the {@link #nativeInitialSchema(int)} is decreased, - * i.e. the resolution of the histogram is decreased to reduce the number of buckets. - *

      - * Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. - */ - public Builder nativeMaxNumberOfBuckets(int nativeMaxBuckets) { - this.nativeMaxNumberOfBuckets = nativeMaxBuckets; - return this; - } + /** + * Limit the number of native buckets. + * + *

      If the number of native buckets exceeds the maximum, the {@link #nativeInitialSchema(int)} + * is decreased, i.e. the resolution of the histogram is decreased to reduce the number of + * buckets. + * + *

      Default is {@link Builder#DEFAULT_NATIVE_MAX_NUMBER_OF_BUCKETS}. + */ + public Builder nativeMaxNumberOfBuckets(int nativeMaxBuckets) { + this.nativeMaxNumberOfBuckets = nativeMaxBuckets; + return this; + } - /** - * If the histogram needed to be scaled down because {@link #nativeMaxNumberOfBuckets(int)} was exceeded, - * reset the histogram after a certain time interval to go back to the original {@link #nativeInitialSchema(int)}. - *

      - * Reset means all values are set to zero. A good value might be 24h or 7d. - *

      - * Default is no reset. - */ - public Builder nativeResetDuration(long duration, TimeUnit unit) { - // TODO: reset interval isn't tested yet - if (duration <= 0) { - throw new IllegalArgumentException(duration + ": value > 0 expected"); - } - nativeResetDurationSeconds = unit.toSeconds(duration); - return this; - } + /** + * If the histogram needed to be scaled down because {@link #nativeMaxNumberOfBuckets(int)} was + * exceeded, reset the histogram after a certain time interval to go back to the original {@link + * #nativeInitialSchema(int)}. + * + *

      Reset means all values are set to zero. A good value might be 24h or 7d. + * + *

      Default is no reset. + */ + public Builder nativeResetDuration(long duration, TimeUnit unit) { + // TODO: reset interval isn't tested yet + if (duration <= 0) { + throw new IllegalArgumentException(duration + ": value > 0 expected"); + } + nativeResetDurationSeconds = unit.toSeconds(duration); + return this; + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java index 373e7a98b..49f8a1eb5 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java @@ -4,7 +4,6 @@ import io.prometheus.metrics.model.snapshots.InfoSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.Unit; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -13,6 +12,7 @@ /** * Info metric. Example: + * *

      {@code
        * Info info = Info.builder()
        *         .name("java_runtime_info")
      @@ -30,124 +30,143 @@
        */
       public class Info extends MetricWithFixedMetadata {
       
      -    private final Set labels = new CopyOnWriteArraySet<>();
      -
      -    private Info(Builder builder) {
      -        super(builder);
      +  private final Set labels = new CopyOnWriteArraySet<>();
      +
      +  private Info(Builder builder) {
      +    super(builder);
      +  }
      +
      +  /**
      +   * Set the info label values. This will replace any previous values, i.e. the info metric will
      +   * only have one data point after calling setLabelValues(). This is good for a metric like {@code
      +   * target_info} where you want only one single data point.
      +   */
      +  public void setLabelValues(String... labelValues) {
      +    if (labelValues.length != labelNames.length) {
      +      throw new IllegalArgumentException(
      +          getClass().getSimpleName()
      +              + " "
      +              + getMetadata().getName()
      +              + " was created with "
      +              + labelNames.length
      +              + " label names, but you called setLabelValues() with "
      +              + labelValues.length
      +              + " label values.");
           }
      -
      -    /**
      -     * Set the info label values. This will replace any previous values,
      -     * i.e. the info metric will only have one data point after calling setLabelValues().
      -     * This is good for a metric like {@code target_info} where you want only one single data point.
      -     */
      -    public void setLabelValues(String... labelValues) {
      -        if (labelValues.length != labelNames.length) {
      -            throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called setLabelValues() with " + labelValues.length + " label values.");
      -        }
      -        Labels newLabels = Labels.of(labelNames, labelValues);
      -        labels.add(newLabels);
      -        labels.retainAll(Collections.singletonList(newLabels));
      +    Labels newLabels = Labels.of(labelNames, labelValues);
      +    labels.add(newLabels);
      +    labels.retainAll(Collections.singletonList(newLabels));
      +  }
      +
      +  /** Create an info data point with the given label values. */
      +  public void addLabelValues(String... labelValues) {
      +    if (labelValues.length != labelNames.length) {
      +      throw new IllegalArgumentException(
      +          getClass().getSimpleName()
      +              + " "
      +              + getMetadata().getName()
      +              + " was created with "
      +              + labelNames.length
      +              + " label names, but you called addLabelValues() with "
      +              + labelValues.length
      +              + " label values.");
      +    }
      +    labels.add(Labels.of(labelNames, labelValues));
      +  }
      +
      +  /** Remove the data point with the specified label values. */
      +  public void remove(String... labelValues) {
      +    if (labelValues.length != labelNames.length) {
      +      throw new IllegalArgumentException(
      +          getClass().getSimpleName()
      +              + " "
      +              + getMetadata().getName()
      +              + " was created with "
      +              + labelNames.length
      +              + " label names, but you called remove() with "
      +              + labelValues.length
      +              + " label values.");
           }
      +    Labels toBeRemoved = Labels.of(labelNames, labelValues);
      +    labels.remove(toBeRemoved);
      +  }
      +
      +  /** {@inheritDoc} */
      +  @Override
      +  public InfoSnapshot collect() {
      +    List data = new ArrayList<>(labels.size());
      +    if (labelNames.length == 0) {
      +      data.add(new InfoSnapshot.InfoDataPointSnapshot(constLabels));
      +    } else {
      +      for (Labels label : labels) {
      +        data.add(new InfoSnapshot.InfoDataPointSnapshot(label.merge(constLabels)));
      +      }
      +    }
      +    return new InfoSnapshot(getMetadata(), data);
      +  }
       
      -    /**
      -     * Create an info data point with the given label values.
      -     */
      -    public void addLabelValues(String... labelValues) {
      -        if (labelValues.length != labelNames.length) {
      -            throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called addLabelValues() with " + labelValues.length + " label values.");
      -        }
      -        labels.add(Labels.of(labelNames, labelValues));
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder extends MetricWithFixedMetadata.Builder {
      +
      +    private Builder(PrometheusProperties config) {
      +      super(Collections.emptyList(), config);
           }
       
           /**
      -     * Remove the data point with the specified label values.
      +     * The {@code _info} suffix will automatically be appended if it's missing.
      +     *
      +     * 
      {@code
      +     * Info info1 = Info.builder()
      +     *     .name("runtime_info")
      +     *     .build();
      +     * Info info2 = Info.builder()
      +     *     .name("runtime")
      +     *     .build();
      +     * }
      + * + * In the example above both {@code info1} and {@code info2} will be named {@code + * "runtime_info"} in Prometheus. + * + *

      Throws an {@link IllegalArgumentException} if {@link + * io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) + * MetricMetadata.isValidMetricName(name)} is {@code false}. */ - public void remove(String... labelValues) { - if (labelValues.length != labelNames.length) { - throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with " + labelNames.length + " label names, but you called remove() with " + labelValues.length + " label values."); - } - Labels toBeRemoved = Labels.of(labelNames, labelValues); - labels.remove(toBeRemoved); + @Override + public Builder name(String name) { + return super.name(stripInfoSuffix(name)); } - /** - * {@inheritDoc} - */ + /** Throws an {@link UnsupportedOperationException} because Info metrics cannot have a unit. */ @Override - public InfoSnapshot collect() { - List data = new ArrayList<>(labels.size()); - if (labelNames.length == 0) { - data.add(new InfoSnapshot.InfoDataPointSnapshot(constLabels)); - } else { - for (Labels label : labels) { - data.add(new InfoSnapshot.InfoDataPointSnapshot(label.merge(constLabels))); - } - } - return new InfoSnapshot(getMetadata(), data); + public Builder unit(Unit unit) { + if (unit != null) { + throw new UnsupportedOperationException("Info metrics cannot have a unit."); + } + return this; } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + private static String stripInfoSuffix(String name) { + if (name != null && (name.endsWith("_info") || name.endsWith(".info"))) { + name = name.substring(0, name.length() - 5); + } + return name; } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + @Override + public Info build() { + return new Info(this); } - public static class Builder extends MetricWithFixedMetadata.Builder { - - private Builder(PrometheusProperties config) { - super(Collections.emptyList(), config); - } - - /** - * The {@code _info} suffix will automatically be appended if it's missing. - *

      {@code
      -         * Info info1 = Info.builder()
      -         *     .name("runtime_info")
      -         *     .build();
      -         * Info info2 = Info.builder()
      -         *     .name("runtime")
      -         *     .build();
      -         * }
      - * In the example above both {@code info1} and {@code info2} will be named {@code "runtime_info"} in Prometheus. - *

      - * Throws an {@link IllegalArgumentException} if - * {@link io.prometheus.metrics.model.snapshots.PrometheusNaming#isValidMetricName(String) MetricMetadata.isValidMetricName(name)} - * is {@code false}. - */ - @Override - public Builder name(String name) { - return super.name(stripInfoSuffix(name)); - } - - /** - * Throws an {@link UnsupportedOperationException} because Info metrics cannot have a unit. - */ - @Override - public Builder unit(Unit unit) { - if (unit != null) { - throw new UnsupportedOperationException("Info metrics cannot have a unit."); - } - return this; - } - - private static String stripInfoSuffix(String name) { - if (name != null && (name.endsWith("_info") || name.endsWith(".info"))) { - name = name.substring(0, name.length() - 5); - } - return name; - } - - @Override - public Info build() { - return new Info(this); - } - - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java index b7db83208..d3c00eca0 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java @@ -6,63 +6,61 @@ import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshot; - import java.util.ArrayList; import java.util.List; -/** - * Common base class for all metrics. - */ +/** Common base class for all metrics. */ public abstract class Metric implements Collector { - protected final Labels constLabels; + protected final Labels constLabels; - protected Metric(Builder builder) { - this.constLabels = builder.constLabels; - } + protected Metric(Builder builder) { + this.constLabels = builder.constLabels; + } - @Override - public abstract MetricSnapshot collect(); + @Override + public abstract MetricSnapshot collect(); - protected static abstract class Builder, M extends Metric> { + protected abstract static class Builder, M extends Metric> { - protected final List illegalLabelNames; - protected final PrometheusProperties properties; - protected Labels constLabels = Labels.EMPTY; + protected final List illegalLabelNames; + protected final PrometheusProperties properties; + protected Labels constLabels = Labels.EMPTY; - protected Builder(List illegalLabelNames, PrometheusProperties properties) { - this.illegalLabelNames = new ArrayList<>(illegalLabelNames); - this.properties = properties; - } + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + this.illegalLabelNames = new ArrayList<>(illegalLabelNames); + this.properties = properties; + } - // ConstLabels are only used rarely. In particular, do not use them to - // attach the same labels to all your metrics. Those use cases are - // better covered by target labels set by the scraping Prometheus - // server, or by one specific metric (e.g. a build_info or a - // machine_role metric). See also - // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels - public B constLabels(Labels constLabels) { - for (Label label : constLabels) { // NPE if constLabels is null - if (illegalLabelNames.contains(label.getName())) { - throw new IllegalArgumentException(label.getName() + ": illegal label name for this metric type"); - } - } - this.constLabels = constLabels; - return self(); + // ConstLabels are only used rarely. In particular, do not use them to + // attach the same labels to all your metrics. Those use cases are + // better covered by target labels set by the scraping Prometheus + // server, or by one specific metric (e.g. a build_info or a + // machine_role metric). See also + // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels + public B constLabels(Labels constLabels) { + for (Label label : constLabels) { // NPE if constLabels is null + if (illegalLabelNames.contains(label.getName())) { + throw new IllegalArgumentException( + label.getName() + ": illegal label name for this metric type"); } + } + this.constLabels = constLabels; + return self(); + } - public M register() { - return register(PrometheusRegistry.defaultRegistry); - } + public M register() { + return register(PrometheusRegistry.defaultRegistry); + } - public M register(PrometheusRegistry registry) { - M metric = build(); - registry.register(metric); - return metric; - } + public M register(PrometheusRegistry registry) { + M metric = build(); + registry.register(metric); + return metric; + } - public abstract M build(); + public abstract M build(); - protected abstract B self(); - } + protected abstract B self(); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 5b96ea303..c121d0c56 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -5,103 +5,105 @@ import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.PrometheusNaming; import io.prometheus.metrics.model.snapshots.Unit; - import java.util.Arrays; import java.util.List; /** * Almost all metrics have fixed metadata, i.e. the metric name is known when the metric is created. - *

      - * An exception would be a metric that is a bridge to a 3rd party metric library, where the metric name - * has to be retrieved from the 3rd party metric library at scrape time. + * + *

      An exception would be a metric that is a bridge to a 3rd party metric library, where the + * metric name has to be retrieved from the 3rd party metric library at scrape time. */ public abstract class MetricWithFixedMetadata extends Metric { - private final MetricMetadata metadata; - protected final String[] labelNames; - - protected MetricWithFixedMetadata(Builder builder) { - super(builder); - this.metadata = new MetricMetadata(makeName(builder.name, builder.unit), builder.help, builder.unit); - this.labelNames = Arrays.copyOf(builder.labelNames, builder.labelNames.length); + private final MetricMetadata metadata; + protected final String[] labelNames; + + protected MetricWithFixedMetadata(Builder builder) { + super(builder); + this.metadata = + new MetricMetadata(makeName(builder.name, builder.unit), builder.help, builder.unit); + this.labelNames = Arrays.copyOf(builder.labelNames, builder.labelNames.length); + } + + protected MetricMetadata getMetadata() { + return metadata; + } + + private String makeName(String name, Unit unit) { + if (unit != null) { + if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { + name += "_" + unit; + } } + return name; + } - protected MetricMetadata getMetadata() { - return metadata; - } + @Override + public String getPrometheusName() { + return metadata.getPrometheusName(); + } - private String makeName(String name, Unit unit) { - if (unit != null) { - if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { - name += "_" + unit; - } - } - return name; - } + public abstract static class Builder, M extends MetricWithFixedMetadata> + extends Metric.Builder { - @Override - public String getPrometheusName() { - return metadata.getPrometheusName(); - } + protected String name; + private Unit unit; + private String help; + private String[] labelNames = new String[0]; - public static abstract class Builder, M extends MetricWithFixedMetadata> extends Metric.Builder { + protected Builder(List illegalLabelNames, PrometheusProperties properties) { + super(illegalLabelNames, properties); + } - protected String name; - private Unit unit; - private String help; - private String[] labelNames = new String[0]; + public B name(String name) { + if (!PrometheusNaming.isValidMetricName(name)) { + throw new IllegalArgumentException("'" + name + "': Illegal metric name."); + } + this.name = name; + return self(); + } - protected Builder(List illegalLabelNames, PrometheusProperties properties) { - super(illegalLabelNames, properties); - } + public B unit(Unit unit) { + this.unit = unit; + return self(); + } - public B name(String name) { - if (!PrometheusNaming.isValidMetricName(name)) { - throw new IllegalArgumentException("'" + name + "': Illegal metric name."); - } - this.name = name; - return self(); - } + public B help(String help) { + this.help = help; + return self(); + } - public B unit(Unit unit) { - this.unit = unit; - return self(); + public B labelNames(String... labelNames) { + for (String labelName : labelNames) { + if (!PrometheusNaming.isValidLabelName(labelName)) { + throw new IllegalArgumentException(labelName + ": illegal label name"); } - - public B help(String help) { - this.help = help; - return self(); + if (illegalLabelNames.contains(labelName)) { + throw new IllegalArgumentException( + labelName + ": illegal label name for this metric type"); } - - public B labelNames(String... labelNames) { - for (String labelName : labelNames) { - if (!PrometheusNaming.isValidLabelName(labelName)) { - throw new IllegalArgumentException(labelName + ": illegal label name"); - } - if (illegalLabelNames.contains(labelName)) { - throw new IllegalArgumentException(labelName + ": illegal label name for this metric type"); - } - if (constLabels.contains(labelName)) { - throw new IllegalArgumentException(labelName + ": duplicate label name"); - } - } - this.labelNames = labelNames; - return self(); + if (constLabels.contains(labelName)) { + throw new IllegalArgumentException(labelName + ": duplicate label name"); } + } + this.labelNames = labelNames; + return self(); + } - public B constLabels(Labels constLabels) { - for (String labelName : labelNames) { - if (constLabels.contains(labelName)) { // Labels.contains() treats dots like underscores - throw new IllegalArgumentException(labelName + ": duplicate label name"); - } - } - return super.constLabels(constLabels); + public B constLabels(Labels constLabels) { + for (String labelName : labelNames) { + if (constLabels.contains(labelName)) { // Labels.contains() treats dots like underscores + throw new IllegalArgumentException(labelName + ": duplicate label name"); } + } + return super.constLabels(constLabels); + } - @Override - public abstract M build(); + @Override + public abstract M build(); - @Override - protected abstract B self(); - } + @Override + protected abstract B self(); + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java index e4e86acdd..93fa20d0e 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -8,72 +8,77 @@ /** * Maintains a ring buffer of T to implement a sliding time window. - *

      - * This is used to maintain a sliding window of {@link CKMSQuantiles} for {@link Summary} metrics. - *

      - * It is implemented in a generic way so that 3rd party libraries can use it for implementing sliding windows. - *

      - * TODO: The current implementation is {@code synchronized}. There is likely room for optimization. + * + *

      This is used to maintain a sliding window of {@link CKMSQuantiles} for {@link Summary} + * metrics. + * + *

      It is implemented in a generic way so that 3rd party libraries can use it for implementing + * sliding windows. + * + *

      TODO: The current implementation is {@code synchronized}. There is likely room for + * optimization. */ public class SlidingWindow { - private final Supplier constructor; - private final ObjDoubleConsumer observeFunction; - private final T[] ringBuffer; - private int currentBucket; - private long lastRotateTimestampMillis; - private final long durationBetweenRotatesMillis; - LongSupplier currentTimeMillis = System::currentTimeMillis; // to be replaced in unit tests + private final Supplier constructor; + private final ObjDoubleConsumer observeFunction; + private final T[] ringBuffer; + private int currentBucket; + private long lastRotateTimestampMillis; + private final long durationBetweenRotatesMillis; + LongSupplier currentTimeMillis = System::currentTimeMillis; // to be replaced in unit tests - /** - * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of {@code T} - * are maintained and the sliding window moves to the next instance of T every 20 seconds. - * - * @param clazz type of T - * @param constructor for creating a new instance of T as the old one gets evicted - * @param observeFunction for observing a value (e.g. calling {@code t.observe(value)} - * @param maxAgeSeconds after this amount of time an instance of T gets evicted. - * @param ageBuckets number of age buckets. - */ - public SlidingWindow(Class clazz, Supplier constructor, ObjDoubleConsumer observeFunction, long maxAgeSeconds, int ageBuckets) { - this.constructor = constructor; - this.observeFunction = observeFunction; - this.ringBuffer = (T[]) Array.newInstance(clazz, ageBuckets); - for (int i = 0; i < ringBuffer.length; i++) { - this.ringBuffer[i] = constructor.get(); - } - this.currentBucket = 0; - this.lastRotateTimestampMillis = currentTimeMillis.getAsLong(); - this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets; + /** + * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of + * {@code T} are maintained and the sliding window moves to the next instance of T every 20 + * seconds. + * + * @param clazz type of T + * @param constructor for creating a new instance of T as the old one gets evicted + * @param observeFunction for observing a value (e.g. calling {@code t.observe(value)} + * @param maxAgeSeconds after this amount of time an instance of T gets evicted. + * @param ageBuckets number of age buckets. + */ + public SlidingWindow( + Class clazz, + Supplier constructor, + ObjDoubleConsumer observeFunction, + long maxAgeSeconds, + int ageBuckets) { + this.constructor = constructor; + this.observeFunction = observeFunction; + this.ringBuffer = (T[]) Array.newInstance(clazz, ageBuckets); + for (int i = 0; i < ringBuffer.length; i++) { + this.ringBuffer[i] = constructor.get(); } + this.currentBucket = 0; + this.lastRotateTimestampMillis = currentTimeMillis.getAsLong(); + this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets; + } - /** - * Get the currently active instance of {@code T}. - */ - public synchronized T current() { - return rotate(); - } + /** Get the currently active instance of {@code T}. */ + public synchronized T current() { + return rotate(); + } - /** - * Observe a value. - */ - public synchronized void observe(double value) { - rotate(); - for (T t : ringBuffer) { - observeFunction.accept(t, value); - } + /** Observe a value. */ + public synchronized void observe(double value) { + rotate(); + for (T t : ringBuffer) { + observeFunction.accept(t, value); } + } - private T rotate() { - long timeSinceLastRotateMillis = currentTimeMillis.getAsLong() - lastRotateTimestampMillis; - while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { - ringBuffer[currentBucket] = constructor.get(); - if (++currentBucket >= ringBuffer.length) { - currentBucket = 0; - } - timeSinceLastRotateMillis -= durationBetweenRotatesMillis; - lastRotateTimestampMillis += durationBetweenRotatesMillis; - } - return ringBuffer[currentBucket]; + private T rotate() { + long timeSinceLastRotateMillis = currentTimeMillis.getAsLong() - lastRotateTimestampMillis; + while (timeSinceLastRotateMillis > durationBetweenRotatesMillis) { + ringBuffer[currentBucket] = constructor.get(); + if (++currentBucket >= ringBuffer.length) { + currentBucket = 0; + } + timeSinceLastRotateMillis -= durationBetweenRotatesMillis; + lastRotateTimestampMillis += durationBetweenRotatesMillis; } + return ringBuffer[currentBucket]; + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java index 532cfa506..e4d9eff88 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -1,20 +1,20 @@ package io.prometheus.metrics.core.metrics; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; + import io.prometheus.metrics.config.MetricsProperties; import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.datapoints.StateSetDataPoint; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; -import io.prometheus.metrics.core.datapoints.StateSetDataPoint; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Stream; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; - /** * StateSet metric. Example: + * *

      {@code
        * public enum Feature {
        *
      @@ -46,151 +46,141 @@
        *     stateSet.labelValues("dev").setTrue(FEATURE_2);
        * }
        * }
      - * The example above shows how to use a StateSet with an enum. - * You don't have to use enum, you can use regular strings as well. + * + * The example above shows how to use a StateSet with an enum. You don't have to use enum, you can + * use regular strings as well. */ -public class StateSet extends StatefulMetric implements StateSetDataPoint { - - private final boolean exemplarsEnabled; - private final String[] names; - - private StateSet(Builder builder, PrometheusProperties prometheusProperties) { - super(builder); - MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); - exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); - this.names = builder.names; // builder.names is already a validated copy - for (String name : names) { - if (this.getMetadata().getPrometheusName().equals(prometheusName(name))) { - throw new IllegalArgumentException("Label name " + name + " is illegal (can't use the metric name as label name in state set metrics)"); - } - } +public class StateSet extends StatefulMetric + implements StateSetDataPoint { + + private final boolean exemplarsEnabled; + private final String[] names; + + private StateSet(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + this.names = builder.names; // builder.names is already a validated copy + for (String name : names) { + if (this.getMetadata().getPrometheusName().equals(prometheusName(name))) { + throw new IllegalArgumentException( + "Label name " + + name + + " is illegal (can't use the metric name as label name in state set metrics)"); + } } - - /** - * {@inheritDoc} - */ - @Override - public StateSetSnapshot collect() { - return (StateSetSnapshot) super.collect(); + } + + /** {@inheritDoc} */ + @Override + public StateSetSnapshot collect() { + return (StateSetSnapshot) super.collect(); + } + + /** {@inheritDoc} */ + @Override + public void setTrue(String state) { + getNoLabels().setTrue(state); + } + + /** {@inheritDoc} */ + @Override + public void setFalse(String state) { + getNoLabels().setFalse(state); + } + + @Override + protected StateSetSnapshot collect(List labels, List metricDataList) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add( + new StateSetSnapshot.StateSetDataPointSnapshot( + names, metricDataList.get(i).values, labels.get(i))); } + return new StateSetSnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + class DataPoint implements StateSetDataPoint { + + private final boolean[] values = new boolean[names.length]; - /** - * {@inheritDoc} - */ + private DataPoint() {} + + /** {@inheritDoc} */ @Override public void setTrue(String state) { - getNoLabels().setTrue(state); + set(state, true); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public void setFalse(String state) { - getNoLabels().setFalse(state); + set(state, false); } - @Override - protected StateSetSnapshot collect(List labels, List metricDataList) { - List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(new StateSetSnapshot.StateSetDataPointSnapshot(names, metricDataList.get(i).values, labels.get(i))); + private void set(String name, boolean value) { + for (int i = 0; i < names.length; i++) { + if (names[i].equals(name)) { + values[i] = value; + return; } - return new StateSetSnapshot(getMetadata(), data); - } - - @Override - protected DataPoint newDataPoint() { - return new DataPoint(); + } + throw new IllegalArgumentException(name + ": unknown state"); } + } - @Override - protected boolean isExemplarsEnabled() { - return exemplarsEnabled; - } - - class DataPoint implements StateSetDataPoint { + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - private final boolean[] values = new boolean[names.length]; + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - private DataPoint() { - } + public static class Builder extends StatefulMetric.Builder { - /** - * {@inheritDoc} - */ - @Override - public void setTrue(String state) { - set(state, true); - } + private String[] names; - /** - * {@inheritDoc} - */ - @Override - public void setFalse(String state) { - set(state, false); - } - - private void set(String name, boolean value) { - for (int i = 0; i < names.length; i++) { - if (names[i].equals(name)) { - values[i] = value; - return; - } - } - throw new IllegalArgumentException(name + ": unknown state"); - } + private Builder(PrometheusProperties config) { + super(Collections.emptyList(), config); } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + /** Declare the states that should be represented by this StateSet. */ + public Builder states(Class> enumClass) { + return states( + Stream.of(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new)); } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + /** Declare the states that should be represented by this StateSet. */ + public Builder states(String... stateNames) { + if (stateNames.length == 0) { + throw new IllegalArgumentException("states cannot be empty"); + } + this.names = Stream.of(stateNames).distinct().sorted().toArray(String[]::new); + return this; } - public static class Builder extends StatefulMetric.Builder { - - private String[] names; - - private Builder(PrometheusProperties config) { - super(Collections.emptyList(), config); - } - - /** - * Declare the states that should be represented by this StateSet. - */ - public Builder states(Class> enumClass) { - return states(Stream.of(enumClass.getEnumConstants()).map(Enum::toString).toArray(String[]::new)); - } - - /** - * Declare the states that should be represented by this StateSet. - */ - public Builder states(String... stateNames) { - if (stateNames.length == 0) { - throw new IllegalArgumentException("states cannot be empty"); - } - this.names = Stream.of(stateNames) - .distinct() - .sorted() - .toArray(String[]::new); - return this; - } - - @Override - public StateSet build() { - if (names == null) { - throw new IllegalStateException("State names are required when building a StateSet."); - } - return new StateSet(this, properties); - } + @Override + public StateSet build() { + if (names == null) { + throw new IllegalStateException("State names are required when building a StateSet."); + } + return new StateSet(this, properties); + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 44f6cc57a..188a0c15f 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -1,11 +1,13 @@ package io.prometheus.metrics.core.metrics; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + import io.prometheus.metrics.config.MetricsProperties; import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.datapoints.DataPoint; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshot; -import io.prometheus.metrics.core.datapoints.DataPoint; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -13,191 +15,191 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - /** * There are two kinds of metrics: + * *
        - *
      • A {@code StatefulMetric} actively maintains its current values, e.g. a stateful counter actively stores its current count.
      • - *
      • A {@code CallbackMetric} gets its values on demand when it is collected, e.g. a callback gauge representing the current heap size.
      • + *
      • A {@code StatefulMetric} actively maintains its current values, e.g. a stateful counter + * actively stores its current count. + *
      • A {@code CallbackMetric} gets its values on demand when it is collected, e.g. a callback + * gauge representing the current heap size. *
      - * The OpenTelemetry terminology for stateful is synchronous and the OpenTelemetry terminology for callback is asynchronous. - * We are using our own terminology here because in Java synchronous and asynchronous usually refers to multi-threading, - * but this has nothing to do with multi-threading. + * + * The OpenTelemetry terminology for stateful is synchronous and the OpenTelemetry + * terminology for callback is asynchronous. We are using our own terminology here + * because in Java synchronous and asynchronous usually refers to multi-threading, but + * this has nothing to do with multi-threading. */ abstract class StatefulMetric extends MetricWithFixedMetadata { - /** - * Map label values to data points. - */ - private final ConcurrentHashMap, T> data = new ConcurrentHashMap<>(); + /** Map label values to data points. */ + private final ConcurrentHashMap, T> data = new ConcurrentHashMap<>(); - /** - * Shortcut for data.get(Collections.emptyList()) - */ - private volatile T noLabels; + /** Shortcut for data.get(Collections.emptyList()) */ + private volatile T noLabels; - protected StatefulMetric(Builder builder) { - super(builder); - } + protected StatefulMetric(Builder builder) { + super(builder); + } - /** - * labels and metricData have the same size. labels.get(i) are the labels for metricData.get(i). - */ - protected abstract MetricSnapshot collect(List labels, List metricData); - - public MetricSnapshot collect() { - if (labelNames.length == 0 && data.size() == 0) { - // This is a metric without labels that has not been used yet. Initialize the data on the fly. - labelValues(); - } - List labels = new ArrayList<>(data.size()); - List metricData = new ArrayList<>(data.size()); - for (Map.Entry, T> entry : data.entrySet()) { - String[] labelValues = entry.getKey().toArray(new String[labelNames.length]); - labels.add(constLabels.merge(labelNames, labelValues)); - metricData.add(entry.getValue()); - } - return collect(labels, metricData); - } + /** + * labels and metricData have the same size. labels.get(i) are the labels for metricData.get(i). + */ + protected abstract MetricSnapshot collect(List labels, List metricData); - /** - * Initialize label values. - *

      - * Example: Imagine you have a counter for payments as follows - *

      -     * payment_transactions_total{payment_type="credit card"} 7.0
      -     * payment_transactions_total{payment_type="paypal"} 3.0
      -     * 
      - * Now, the data points for the {@code payment_type} label values get initialized when they are - * first used, i.e. the first time you call - *
      {@code
      -     * counter.labelValues("paypal").inc();
      -     * }
      - * the data point with label {@code payment_type="paypal"} will go from non-existent to having value {@code 1.0}. - *

      - * In some cases this is confusing, and you want to have data points initialized on application start - * with an initial value of {@code 0.0}: - *

      -     * payment_transactions_total{payment_type="credit card"} 0.0
      -     * payment_transactions_total{payment_type="paypal"} 0.0
      -     * 
      - * {@code initLabelValues(...)} can be used to initialize label value, so that the data points - * show up in the exposition format with an initial value of zero. - */ - public void initLabelValues(String... labelValues) { - labelValues(labelValues); + public MetricSnapshot collect() { + if (labelNames.length == 0 && data.size() == 0) { + // This is a metric without labels that has not been used yet. Initialize the data on the fly. + labelValues(); } - - public D labelValues(String... labelValues) { - if (labelValues.length != labelNames.length) { - if (labelValues.length == 0) { - throw new IllegalArgumentException(getClass().getSimpleName() + " " + getMetadata().getName() + " was created with label names, so you must call labelValues(...) when using it."); - } else { - throw new IllegalArgumentException("Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); - } - } - return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); + List labels = new ArrayList<>(data.size()); + List metricData = new ArrayList<>(data.size()); + for (Map.Entry, T> entry : data.entrySet()) { + String[] labelValues = entry.getKey().toArray(new String[labelNames.length]); + labels.add(constLabels.merge(labelNames, labelValues)); + metricData.add(entry.getValue()); } - - /** - * Remove the data point with the given label values. - * See https://prometheus.io/docs/instrumenting/writing_clientlibs/#labels. - */ - public void remove(String... labelValues) { - data.remove(Arrays.asList(labelValues)); + return collect(labels, metricData); + } + + /** + * Initialize label values. + * + *

      Example: Imagine you have a counter for payments as follows + * + *

      +   * payment_transactions_total{payment_type="credit card"} 7.0
      +   * payment_transactions_total{payment_type="paypal"} 3.0
      +   * 
      + * + * Now, the data points for the {@code payment_type} label values get initialized when they are + * first used, i.e. the first time you call + * + *
      {@code
      +   * counter.labelValues("paypal").inc();
      +   * }
      + * + * the data point with label {@code payment_type="paypal"} will go from non-existent to having + * value {@code 1.0}. + * + *

      In some cases this is confusing, and you want to have data points initialized on application + * start with an initial value of {@code 0.0}: + * + *

      +   * payment_transactions_total{payment_type="credit card"} 0.0
      +   * payment_transactions_total{payment_type="paypal"} 0.0
      +   * 
      + * + * {@code initLabelValues(...)} can be used to initialize label value, so that the data points + * show up in the exposition format with an initial value of zero. + */ + public void initLabelValues(String... labelValues) { + labelValues(labelValues); + } + + public D labelValues(String... labelValues) { + if (labelValues.length != labelNames.length) { + if (labelValues.length == 0) { + throw new IllegalArgumentException( + getClass().getSimpleName() + + " " + + getMetadata().getName() + + " was created with label names, so you must call labelValues(...) when using it."); + } else { + throw new IllegalArgumentException( + "Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); + } } - - /** - * Reset the metric (remove all data points). - */ - public void clear() { - data.clear(); - noLabels = null; + return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); + } + + /** + * Remove the data point with the given label values. See https://prometheus.io/docs/instrumenting/writing_clientlibs/#labels. + */ + public void remove(String... labelValues) { + data.remove(Arrays.asList(labelValues)); + } + + /** Reset the metric (remove all data points). */ + public void clear() { + data.clear(); + noLabels = null; + } + + protected abstract T newDataPoint(); + + protected T getNoLabels() { + if (noLabels == null) { + // Note that this will throw an IllegalArgumentException if labelNames is not empty. + noLabels = (T) labelValues(); + } + return noLabels; + } + + protected MetricsProperties[] getMetricProperties( + Builder builder, PrometheusProperties prometheusProperties) { + String metricName = getMetadata().getName(); + if (prometheusProperties.getMetricProperties(metricName) != null) { + return new MetricsProperties[] { + prometheusProperties.getMetricProperties(metricName), // highest precedence + builder.toProperties(), // second-highest precedence + prometheusProperties.getDefaultMetricProperties(), // third-highest precedence + builder.getDefaultProperties() // fallback + }; + } else { + return new MetricsProperties[] { + builder.toProperties(), // highest precedence + prometheusProperties.getDefaultMetricProperties(), // second-highest precedence + builder.getDefaultProperties() // fallback + }; } + } + + protected T getConfigProperty( + MetricsProperties[] properties, Function getter) { + T result; + for (MetricsProperties props : properties) { + result = getter.apply(props); + if (result != null) { + return result; + } + } + throw new IllegalStateException( + "Missing default config. This is a bug in the Prometheus metrics core library."); + } + + protected abstract boolean isExemplarsEnabled(); + + abstract static class Builder, M extends StatefulMetric> + extends MetricWithFixedMetadata.Builder { - protected abstract T newDataPoint(); + protected Boolean exemplarsEnabled; + + protected Builder(List illegalLabelNames, PrometheusProperties config) { + super(illegalLabelNames, config); + } - protected T getNoLabels() { - if (noLabels == null) { - // Note that this will throw an IllegalArgumentException if labelNames is not empty. - noLabels = (T) labelValues(); - } - return noLabels; + /** Allow Exemplars for this metric. */ + public B withExemplars() { + this.exemplarsEnabled = TRUE; + return self(); } - protected MetricsProperties[] getMetricProperties(Builder builder, PrometheusProperties prometheusProperties) { - String metricName = getMetadata().getName(); - if (prometheusProperties.getMetricProperties(metricName) != null) { - return new MetricsProperties[]{ - prometheusProperties.getMetricProperties(metricName), // highest precedence - builder.toProperties(), // second-highest precedence - prometheusProperties.getDefaultMetricProperties(), // third-highest precedence - builder.getDefaultProperties() // fallback - }; - } else { - return new MetricsProperties[]{ - builder.toProperties(), // highest precedence - prometheusProperties.getDefaultMetricProperties(), // second-highest precedence - builder.getDefaultProperties() // fallback - }; - } + /** Turn off Exemplars for this metric. */ + public B withoutExemplars() { + this.exemplarsEnabled = FALSE; + return self(); } - protected T getConfigProperty(MetricsProperties[] properties, Function getter) { - T result; - for (MetricsProperties props : properties) { - result = getter.apply(props); - if (result != null) { - return result; - } - } - throw new IllegalStateException("Missing default config. This is a bug in the Prometheus metrics core library."); + /** Override if there are more properties than just exemplars enabled. */ + protected MetricsProperties toProperties() { + return MetricsProperties.builder().exemplarsEnabled(exemplarsEnabled).build(); } - protected abstract boolean isExemplarsEnabled(); - - static abstract class Builder, M extends StatefulMetric> extends MetricWithFixedMetadata.Builder { - - protected Boolean exemplarsEnabled; - - protected Builder(List illegalLabelNames, PrometheusProperties config) { - super(illegalLabelNames, config); - } - - /** - * Allow Exemplars for this metric. - */ - public B withExemplars() { - this.exemplarsEnabled = TRUE; - return self(); - } - - /** - * Turn off Exemplars for this metric. - */ - public B withoutExemplars() { - this.exemplarsEnabled = FALSE; - return self(); - } - - /** - * Override if there are more properties than just exemplars enabled. - */ - protected MetricsProperties toProperties() { - return MetricsProperties.builder() - .exemplarsEnabled(exemplarsEnabled) - .build(); - } - - /** - * Override if there are more properties than just exemplars enabled. - */ - public MetricsProperties getDefaultProperties() { - return MetricsProperties.builder() - .exemplarsEnabled(true) - .build(); - } + /** Override if there are more properties than just exemplars enabled. */ + public MetricsProperties getDefaultProperties() { + return MetricsProperties.builder().exemplarsEnabled(true).build(); } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java index 090922686..126626799 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java @@ -2,6 +2,7 @@ import io.prometheus.metrics.config.MetricsProperties; import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSampler; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig; import io.prometheus.metrics.model.snapshots.Exemplars; @@ -9,8 +10,6 @@ import io.prometheus.metrics.model.snapshots.Quantile; import io.prometheus.metrics.model.snapshots.Quantiles; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import io.prometheus.metrics.core.datapoints.DistributionDataPoint; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -20,6 +19,7 @@ /** * Summary metric. Example: + * *
      {@code
        * Summary summary = Summary.builder()
        *         .name("http_request_duration_seconds_hi")
      @@ -35,323 +35,330 @@
        * // process a request, duration will be observed
        * summary.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start));
        * }
      + * * See {@link Summary.Builder} for configuration options. */ -public class Summary extends StatefulMetric implements DistributionDataPoint { - - private final List quantiles; // May be empty, but cannot be null. - private final long maxAgeSeconds; - private final int ageBuckets; - private final boolean exemplarsEnabled; - private final ExemplarSamplerConfig exemplarSamplerConfig; - - private Summary(Builder builder, PrometheusProperties prometheusProperties) { - super(builder); - MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); - this.exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); - this.quantiles = Collections.unmodifiableList(makeQuantiles(properties)); - this.maxAgeSeconds = getConfigProperty(properties, MetricsProperties::getSummaryMaxAgeSeconds); - this.ageBuckets = getConfigProperty(properties, MetricsProperties::getSummaryNumberOfAgeBuckets); - this.exemplarSamplerConfig = new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 4); - } - - private List makeQuantiles(MetricsProperties[] properties) { - List result = new ArrayList<>(); - List quantiles = getConfigProperty(properties, MetricsProperties::getSummaryQuantiles); - List quantileErrors = getConfigProperty(properties, MetricsProperties::getSummaryQuantileErrors); - if (quantiles != null) { - for (int i = 0; i < quantiles.size(); i++) { - if (quantileErrors.size() > 0) { - result.add(new CKMSQuantiles.Quantile(quantiles.get(i), quantileErrors.get(i))); - } else { - result.add(new CKMSQuantiles.Quantile(quantiles.get(i), Builder.defaultError(quantiles.get(i)))); - } - } +public class Summary extends StatefulMetric + implements DistributionDataPoint { + + private final List quantiles; // May be empty, but cannot be null. + private final long maxAgeSeconds; + private final int ageBuckets; + private final boolean exemplarsEnabled; + private final ExemplarSamplerConfig exemplarSamplerConfig; + + private Summary(Builder builder, PrometheusProperties prometheusProperties) { + super(builder); + MetricsProperties[] properties = getMetricProperties(builder, prometheusProperties); + this.exemplarsEnabled = getConfigProperty(properties, MetricsProperties::getExemplarsEnabled); + this.quantiles = Collections.unmodifiableList(makeQuantiles(properties)); + this.maxAgeSeconds = getConfigProperty(properties, MetricsProperties::getSummaryMaxAgeSeconds); + this.ageBuckets = + getConfigProperty(properties, MetricsProperties::getSummaryNumberOfAgeBuckets); + this.exemplarSamplerConfig = + new ExemplarSamplerConfig(prometheusProperties.getExemplarProperties(), 4); + } + + private List makeQuantiles(MetricsProperties[] properties) { + List result = new ArrayList<>(); + List quantiles = getConfigProperty(properties, MetricsProperties::getSummaryQuantiles); + List quantileErrors = + getConfigProperty(properties, MetricsProperties::getSummaryQuantileErrors); + if (quantiles != null) { + for (int i = 0; i < quantiles.size(); i++) { + if (quantileErrors.size() > 0) { + result.add(new CKMSQuantiles.Quantile(quantiles.get(i), quantileErrors.get(i))); + } else { + result.add( + new CKMSQuantiles.Quantile(quantiles.get(i), Builder.defaultError(quantiles.get(i)))); } - return result; + } } - - @Override - protected boolean isExemplarsEnabled() { - return exemplarsEnabled; + return result; + } + + @Override + protected boolean isExemplarsEnabled() { + return exemplarsEnabled; + } + + /** {@inheritDoc} */ + @Override + public void observe(double amount) { + getNoLabels().observe(amount); + } + + /** {@inheritDoc} */ + @Override + public void observeWithExemplar(double amount, Labels labels) { + getNoLabels().observeWithExemplar(amount, labels); + } + + /** {@inheritDoc} */ + @Override + public SummarySnapshot collect() { + return (SummarySnapshot) super.collect(); + } + + @Override + protected SummarySnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new SummarySnapshot(getMetadata(), data); + } + + @Override + protected DataPoint newDataPoint() { + return new DataPoint(); + } + + public class DataPoint implements DistributionDataPoint { + + private final LongAdder count = new LongAdder(); + private final DoubleAdder sum = new DoubleAdder(); + private final SlidingWindow quantileValues; + private final Buffer buffer = new Buffer(); + private final ExemplarSampler exemplarSampler; + + private final long createdTimeMillis = System.currentTimeMillis(); + + private DataPoint() { + if (quantiles.size() > 0) { + CKMSQuantiles.Quantile[] quantilesArray = quantiles.toArray(new CKMSQuantiles.Quantile[0]); + quantileValues = + new SlidingWindow<>( + CKMSQuantiles.class, + () -> new CKMSQuantiles(quantilesArray), + CKMSQuantiles::insert, + maxAgeSeconds, + ageBuckets); + } else { + quantileValues = null; + } + if (exemplarsEnabled) { + exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); + } else { + exemplarSampler = null; + } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public void observe(double amount) { - getNoLabels().observe(amount); + public void observe(double value) { + if (Double.isNaN(value)) { + return; + } + if (!buffer.append(value)) { + doObserve(value); + } + if (isExemplarsEnabled()) { + exemplarSampler.observe(value); + } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override - public void observeWithExemplar(double amount, Labels labels) { - getNoLabels().observeWithExemplar(amount, labels); + public void observeWithExemplar(double value, Labels labels) { + if (Double.isNaN(value)) { + return; + } + if (!buffer.append(value)) { + doObserve(value); + } + if (isExemplarsEnabled()) { + exemplarSampler.observeWithExemplar(value, labels); + } } - /** - * {@inheritDoc} - */ - @Override - public SummarySnapshot collect() { - return (SummarySnapshot) super.collect(); + private void doObserve(double amount) { + sum.add(amount); + if (quantileValues != null) { + quantileValues.observe(amount); + } + // count must be incremented last, because in collect() the count + // indicates the number of completed observations. + count.increment(); } - @Override - protected SummarySnapshot collect(List labels, List metricData) { - List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(metricData.get(i).collect(labels.get(i))); - } - return new SummarySnapshot(getMetadata(), data); + private SummarySnapshot.SummaryDataPointSnapshot collect(Labels labels) { + return buffer.run( + expectedCount -> count.sum() == expectedCount, + // TODO Exemplars (are hard-coded as empty in the line below) + () -> + new SummarySnapshot.SummaryDataPointSnapshot( + count.sum(), + sum.sum(), + makeQuantiles(), + labels, + Exemplars.EMPTY, + createdTimeMillis), + this::doObserve); } - @Override - protected DataPoint newDataPoint() { - return new DataPoint(); + private List getQuantiles() { + return quantiles; } + private Quantiles makeQuantiles() { + Quantile[] quantiles = new Quantile[getQuantiles().size()]; + for (int i = 0; i < getQuantiles().size(); i++) { + CKMSQuantiles.Quantile quantile = getQuantiles().get(i); + quantiles[i] = + new Quantile(quantile.quantile, quantileValues.current().get(quantile.quantile)); + } + return Quantiles.of(quantiles); + } + } - public class DataPoint implements DistributionDataPoint { - - private final LongAdder count = new LongAdder(); - private final DoubleAdder sum = new DoubleAdder(); - private final SlidingWindow quantileValues; - private final Buffer buffer = new Buffer(); - private final ExemplarSampler exemplarSampler; - - private final long createdTimeMillis = System.currentTimeMillis(); - - private DataPoint() { - if (quantiles.size() > 0) { - CKMSQuantiles.Quantile[] quantilesArray = quantiles.toArray(new CKMSQuantiles.Quantile[0]); - quantileValues = new SlidingWindow<>(CKMSQuantiles.class, () -> new CKMSQuantiles(quantilesArray), CKMSQuantiles::insert, maxAgeSeconds, ageBuckets); - } else { - quantileValues = null; - } - if (exemplarsEnabled) { - exemplarSampler = new ExemplarSampler(exemplarSamplerConfig); - } else { - exemplarSampler = null; - } - } + public static Summary.Builder builder() { + return new Builder(PrometheusProperties.get()); + } - /** - * {@inheritDoc} - */ - @Override - public void observe(double value) { - if (Double.isNaN(value)) { - return; - } - if (!buffer.append(value)) { - doObserve(value); - } - if (isExemplarsEnabled()) { - exemplarSampler.observe(value); - } - } + public static Summary.Builder builder(PrometheusProperties config) { + return new Builder(config); + } - /** - * {@inheritDoc} - */ - @Override - public void observeWithExemplar(double value, Labels labels) { - if (Double.isNaN(value)) { - return; - } - if (!buffer.append(value)) { - doObserve(value); - } - if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(value, labels); - } - } + public static class Builder extends StatefulMetric.Builder { - private void doObserve(double amount) { - sum.add(amount); - if (quantileValues != null) { - quantileValues.observe(amount); - } - // count must be incremented last, because in collect() the count - // indicates the number of completed observations. - count.increment(); - } + /** 5 minutes. See {@link #maxAgeSeconds(long)}. */ + public static final long DEFAULT_MAX_AGE_SECONDS = TimeUnit.MINUTES.toSeconds(5); - private SummarySnapshot.SummaryDataPointSnapshot collect(Labels labels) { - return buffer.run( - expectedCount -> count.sum() == expectedCount, - // TODO Exemplars (are hard-coded as empty in the line below) - () -> new SummarySnapshot.SummaryDataPointSnapshot(count.sum(), sum.sum(), makeQuantiles(), labels, Exemplars.EMPTY, createdTimeMillis), - this::doObserve - ); - } + /** 5. See {@link #numberOfAgeBuckets(int)} */ + public static final int DEFAULT_NUMBER_OF_AGE_BUCKETS = 5; - private List getQuantiles() { - return quantiles; - } + private final List quantiles = new ArrayList<>(); + private Long maxAgeSeconds; + private Integer ageBuckets; - private Quantiles makeQuantiles() { - Quantile[] quantiles = new Quantile[getQuantiles().size()]; - for (int i = 0; i < getQuantiles().size(); i++) { - CKMSQuantiles.Quantile quantile = getQuantiles().get(i); - quantiles[i] = new Quantile(quantile.quantile, quantileValues.current().get(quantile.quantile)); - } - return Quantiles.of(quantiles); - } + private Builder(PrometheusProperties properties) { + super(Collections.singletonList("quantile"), properties); } - public static Summary.Builder builder() { - return new Builder(PrometheusProperties.get()); + private static double defaultError(double quantile) { + if (quantile <= 0.01 || quantile >= 0.99) { + return 0.001; + } else if (quantile <= 0.02 || quantile >= 0.98) { + return 0.005; + } else { + return 0.01; + } } - public static Summary.Builder builder(PrometheusProperties config) { - return new Builder(config); + /** + * Add a quantile. See {@link #quantile(double, double)}. + * + *

      Default errors are: + * + *

        + *
      • error = 0.001 if quantile <= 0.01 or quantile >= 0.99 + *
      • error = 0.005 if quantile <= 0.02 or quantile >= 0.98 + *
      • error = 0.01 else. + *
      + */ + public Builder quantile(double quantile) { + return quantile(quantile, defaultError(quantile)); } - public static class Builder extends StatefulMetric.Builder { - - /** - * 5 minutes. See {@link #maxAgeSeconds(long)}. - */ - public static final long DEFAULT_MAX_AGE_SECONDS = TimeUnit.MINUTES.toSeconds(5); - - /** - * 5. See {@link #numberOfAgeBuckets(int)} - */ - public static final int DEFAULT_NUMBER_OF_AGE_BUCKETS = 5; - private final List quantiles = new ArrayList<>(); - private Long maxAgeSeconds; - private Integer ageBuckets; - - private Builder(PrometheusProperties properties) { - super(Collections.singletonList("quantile"), properties); - } - - private static double defaultError(double quantile) { - if (quantile <= 0.01 || quantile >= 0.99) { - return 0.001; - } else if (quantile <= 0.02 || quantile >= 0.98) { - return 0.005; - } else { - return 0.01; - } - } - - /** - * Add a quantile. See {@link #quantile(double, double)}. - *

      - * Default errors are: - *

        - *
      • error = 0.001 if quantile <= 0.01 or quantile >= 0.99
      • - *
      • error = 0.005 if quantile <= 0.02 or quantile >= 0.98
      • - *
      • error = 0.01 else. - *
      - */ - public Builder quantile(double quantile) { - return quantile(quantile, defaultError(quantile)); - } - - /** - * Add a quantile. Call multiple times to add multiple quantiles. - *

      - * Example: The following will track the 0.95 quantile: - *

      {@code
      -         * .quantile(0.95, 0.001)
      -         * }
      - * The second argument is the acceptable error margin, i.e. with the code above the quantile - * will not be exactly the 0.95 quantile but something between 0.949 and 0.951. - *

      - * There are two special cases: - *

        - *
      • {@code .quantile(0.0, 0.0)} gives you the minimum observed value
      • - *
      • {@code .quantile(1.0, 0.0)} gives you the maximum observed value
      • - *
      - */ - public Builder quantile(double quantile, double error) { - if (quantile < 0.0 || quantile > 1.0) { - throw new IllegalArgumentException("Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); - } - if (error < 0.0 || error > 1.0) { - throw new IllegalArgumentException("Error " + error + " invalid: Expected number between 0.0 and 1.0."); - } - quantiles.add(new CKMSQuantiles.Quantile(quantile, error)); - return this; - } + /** + * Add a quantile. Call multiple times to add multiple quantiles. + * + *

      Example: The following will track the 0.95 quantile: + * + *

      {@code
      +     * .quantile(0.95, 0.001)
      +     * }
      + * + * The second argument is the acceptable error margin, i.e. with the code above the quantile + * will not be exactly the 0.95 quantile but something between 0.949 and 0.951. + * + *

      There are two special cases: + * + *

        + *
      • {@code .quantile(0.0, 0.0)} gives you the minimum observed value + *
      • {@code .quantile(1.0, 0.0)} gives you the maximum observed value + *
      + */ + public Builder quantile(double quantile, double error) { + if (quantile < 0.0 || quantile > 1.0) { + throw new IllegalArgumentException( + "Quantile " + quantile + " invalid: Expected number between 0.0 and 1.0."); + } + if (error < 0.0 || error > 1.0) { + throw new IllegalArgumentException( + "Error " + error + " invalid: Expected number between 0.0 and 1.0."); + } + quantiles.add(new CKMSQuantiles.Quantile(quantile, error)); + return this; + } - /** - * The quantiles are relative to a moving time window. - * {@code maxAgeSeconds} is the size of that time window. - * Default is {@link #DEFAULT_MAX_AGE_SECONDS}. - */ - public Builder maxAgeSeconds(long maxAgeSeconds) { - if (maxAgeSeconds <= 0) { - throw new IllegalArgumentException("maxAgeSeconds cannot be " + maxAgeSeconds); - } - this.maxAgeSeconds = maxAgeSeconds; - return this; - } + /** + * The quantiles are relative to a moving time window. {@code maxAgeSeconds} is the size of that + * time window. Default is {@link #DEFAULT_MAX_AGE_SECONDS}. + */ + public Builder maxAgeSeconds(long maxAgeSeconds) { + if (maxAgeSeconds <= 0) { + throw new IllegalArgumentException("maxAgeSeconds cannot be " + maxAgeSeconds); + } + this.maxAgeSeconds = maxAgeSeconds; + return this; + } - /** - * The quantiles are relative to a moving time window. - * The {@code numberOfAgeBuckets} defines how smoothly the time window moves forward. - * For example, if the time window is 5 minutes and has 5 age buckets, - * then it is moving forward every minute by one minute. - * Default is {@link #DEFAULT_NUMBER_OF_AGE_BUCKETS}. - */ - public Builder numberOfAgeBuckets(int ageBuckets) { - if (ageBuckets <= 0) { - throw new IllegalArgumentException("ageBuckets cannot be " + ageBuckets); - } - this.ageBuckets = ageBuckets; - return this; - } + /** + * The quantiles are relative to a moving time window. The {@code numberOfAgeBuckets} defines + * how smoothly the time window moves forward. For example, if the time window is 5 minutes and + * has 5 age buckets, then it is moving forward every minute by one minute. Default is {@link + * #DEFAULT_NUMBER_OF_AGE_BUCKETS}. + */ + public Builder numberOfAgeBuckets(int ageBuckets) { + if (ageBuckets <= 0) { + throw new IllegalArgumentException("ageBuckets cannot be " + ageBuckets); + } + this.ageBuckets = ageBuckets; + return this; + } - @Override - protected MetricsProperties toProperties() { - double[] quantiles = null; - double[] quantileErrors = null; - if (!this.quantiles.isEmpty()) { - quantiles = new double[this.quantiles.size()]; - quantileErrors = new double[this.quantiles.size()]; - for (int i = 0; i < this.quantiles.size(); i++) { - quantiles[i] = this.quantiles.get(i).quantile; - quantileErrors[i] = this.quantiles.get(i).epsilon; - } - } - return MetricsProperties.builder() - .exemplarsEnabled(exemplarsEnabled) - .summaryQuantiles(quantiles) - .summaryQuantileErrors(quantileErrors) - .summaryNumberOfAgeBuckets(ageBuckets) - .summaryMaxAgeSeconds(maxAgeSeconds) - .build(); + @Override + protected MetricsProperties toProperties() { + double[] quantiles = null; + double[] quantileErrors = null; + if (!this.quantiles.isEmpty()) { + quantiles = new double[this.quantiles.size()]; + quantileErrors = new double[this.quantiles.size()]; + for (int i = 0; i < this.quantiles.size(); i++) { + quantiles[i] = this.quantiles.get(i).quantile; + quantileErrors[i] = this.quantiles.get(i).epsilon; } + } + return MetricsProperties.builder() + .exemplarsEnabled(exemplarsEnabled) + .summaryQuantiles(quantiles) + .summaryQuantileErrors(quantileErrors) + .summaryNumberOfAgeBuckets(ageBuckets) + .summaryMaxAgeSeconds(maxAgeSeconds) + .build(); + } - /** - * Default properties for summary metrics. - */ - @Override - public MetricsProperties getDefaultProperties() { - return MetricsProperties.builder() - .exemplarsEnabled(true) - .summaryQuantiles() - .summaryNumberOfAgeBuckets(DEFAULT_NUMBER_OF_AGE_BUCKETS) - .summaryMaxAgeSeconds(DEFAULT_MAX_AGE_SECONDS) - .build(); - } + /** Default properties for summary metrics. */ + @Override + public MetricsProperties getDefaultProperties() { + return MetricsProperties.builder() + .exemplarsEnabled(true) + .summaryQuantiles() + .summaryNumberOfAgeBuckets(DEFAULT_NUMBER_OF_AGE_BUCKETS) + .summaryMaxAgeSeconds(DEFAULT_MAX_AGE_SECONDS) + .build(); + } - @Override - public Summary build() { - return new Summary(this, properties); - } + @Override + public Summary build() { + return new Summary(this, properties); + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java index c55211636..dbe61b2ce 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SummaryWithCallback.java @@ -4,7 +4,6 @@ import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.Quantiles; import io.prometheus.metrics.model.snapshots.SummarySnapshot; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -12,6 +11,7 @@ /** * Example: + * *
      {@code
        * double MILLISECONDS_PER_SECOND = 1E3;
        *
      @@ -35,59 +35,63 @@
        */
       public class SummaryWithCallback extends CallbackMetric {
       
      -    @FunctionalInterface
      -    public interface Callback {
      -        void call(long count, double sum, Quantiles quantiles, String... labelValues);
      -    }
      +  @FunctionalInterface
      +  public interface Callback {
      +    void call(long count, double sum, Quantiles quantiles, String... labelValues);
      +  }
       
      -    private final Consumer callback;
      +  private final Consumer callback;
       
      -    private SummaryWithCallback(Builder builder) {
      -        super(builder);
      -        this.callback = builder.callback;
      -        if (callback == null) {
      -            throw new IllegalArgumentException("callback cannot be null");
      -        }
      +  private SummaryWithCallback(Builder builder) {
      +    super(builder);
      +    this.callback = builder.callback;
      +    if (callback == null) {
      +      throw new IllegalArgumentException("callback cannot be null");
           }
      +  }
       
      -    @Override
      -    public SummarySnapshot collect() {
      -        List dataPoints = new ArrayList<>();
      -        callback.accept((count, sum, quantiles, labelValues) -> {
      -            dataPoints.add(new SummarySnapshot.SummaryDataPointSnapshot(count, sum, quantiles, makeLabels(labelValues), Exemplars.EMPTY, 0L));
      +  @Override
      +  public SummarySnapshot collect() {
      +    List dataPoints = new ArrayList<>();
      +    callback.accept(
      +        (count, sum, quantiles, labelValues) -> {
      +          dataPoints.add(
      +              new SummarySnapshot.SummaryDataPointSnapshot(
      +                  count, sum, quantiles, makeLabels(labelValues), Exemplars.EMPTY, 0L));
               });
      -        return new SummarySnapshot(getMetadata(), dataPoints);
      -    }
      +    return new SummarySnapshot(getMetadata(), dataPoints);
      +  }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -    public static Builder builder(PrometheusProperties properties) {
      -        return new Builder(properties);
      -    }
      +  public static Builder builder(PrometheusProperties properties) {
      +    return new Builder(properties);
      +  }
       
      -    public static class Builder extends CallbackMetric.Builder {
      +  public static class Builder
      +      extends CallbackMetric.Builder {
       
      -        private Consumer callback;
      +    private Consumer callback;
       
      -        public Builder callback(Consumer callback) {
      -            this.callback = callback;
      -            return self();
      -        }
      +    public Builder callback(Consumer callback) {
      +      this.callback = callback;
      +      return self();
      +    }
       
      -        private Builder(PrometheusProperties properties) {
      -            super(Collections.singletonList("quantile"), properties);
      -        }
      +    private Builder(PrometheusProperties properties) {
      +      super(Collections.singletonList("quantile"), properties);
      +    }
       
      -        @Override
      -        public SummaryWithCallback build() {
      -            return new SummaryWithCallback(this);
      -        }
      +    @Override
      +    public SummaryWithCallback build() {
      +      return new SummaryWithCallback(this);
      +    }
       
      -        @Override
      -        protected Builder self() {
      -            return this;
      -        }
      +    @Override
      +    protected Builder self() {
      +      return this;
           }
      +  }
       }
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java
      index 22780819e..6af7fa54a 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java
      @@ -8,30 +8,30 @@
       import java.util.concurrent.TimeUnit;
       
       /**
      - * Used for scheduling maintenance tasks like purging outdated Exemplars or resetting native histograms.
      + * Used for scheduling maintenance tasks like purging outdated Exemplars or resetting native
      + * histograms.
        */
       public class Scheduler {
       
      -    private static class DaemonThreadFactory implements ThreadFactory {
      -        public Thread newThread(Runnable runnable) {
      -            Thread thread = new Thread(runnable);
      -            thread.setDaemon(true);
      -            return thread;
      -        }
      +  private static class DaemonThreadFactory implements ThreadFactory {
      +    public Thread newThread(Runnable runnable) {
      +      Thread thread = new Thread(runnable);
      +      thread.setDaemon(true);
      +      return thread;
           }
      +  }
       
      -    private static final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
      +  private static final ScheduledExecutorService executor =
      +      Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory());
       
      -    public static ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) {
      -        return executor.schedule(command, delay, unit);
      -    }
      +  public static ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) {
      +    return executor.schedule(command, delay, unit);
      +  }
       
      -    /**
      -     * For unit test. Wait until the executor Thread is running.
      -     */
      -    public static void awaitInitialization() throws InterruptedException {
      -        CountDownLatch latch = new CountDownLatch(1);
      -        Scheduler.schedule(latch::countDown, 0, TimeUnit.MILLISECONDS);
      -        latch.await();
      -    }
      +  /** For unit test. Wait until the executor Thread is running. */
      +  public static void awaitInitialization() throws InterruptedException {
      +    CountDownLatch latch = new CountDownLatch(1);
      +    Scheduler.schedule(latch::countDown, 0, TimeUnit.MILLISECONDS);
      +    latch.await();
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java
      index 4ae0cd0bb..8c015f591 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java
      @@ -2,5 +2,5 @@
       
       public class TimerApiTest {
       
      -    // TODO: Port this from the simpleclient SimpleTimerTest
      +  // TODO: Port this from the simpleclient SimpleTimerTest
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java
      index c20482e44..e22e9d6c6 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerConfigTestUtil.java
      @@ -1,30 +1,32 @@
       package io.prometheus.metrics.core.exemplars;
       
      -import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfig;
      -
       import java.lang.reflect.Field;
       
       public class ExemplarSamplerConfigTestUtil {
       
      -    private static ExemplarSamplerConfig getConfig(Object metric, String fieldName) throws NoSuchFieldException, IllegalAccessException {
      -        Field configField = metric.getClass().getDeclaredField(fieldName);
      -        configField.setAccessible(true);
      -        return (ExemplarSamplerConfig) configField.get(metric);
      -    }
      +  private static ExemplarSamplerConfig getConfig(Object metric, String fieldName)
      +      throws NoSuchFieldException, IllegalAccessException {
      +    Field configField = metric.getClass().getDeclaredField(fieldName);
      +    configField.setAccessible(true);
      +    return (ExemplarSamplerConfig) configField.get(metric);
      +  }
       
      -    private static void setRetentionPeriod(ExemplarSamplerConfig config, String name, long value) throws IllegalAccessException, NoSuchFieldException {
      -        Field field = config.getClass().getDeclaredField(name);
      -        field.setAccessible(true);
      -        field.set(config, value);
      -    }
      +  private static void setRetentionPeriod(ExemplarSamplerConfig config, String name, long value)
      +      throws IllegalAccessException, NoSuchFieldException {
      +    Field field = config.getClass().getDeclaredField(name);
      +    field.setAccessible(true);
      +    field.set(config, value);
      +  }
       
      -    public static void setMinRetentionPeriodMillis(Object metric, long value) throws NoSuchFieldException, IllegalAccessException {
      -        ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig");
      -        setRetentionPeriod(config, "minRetentionPeriodMillis", value);
      -    }
      +  public static void setMinRetentionPeriodMillis(Object metric, long value)
      +      throws NoSuchFieldException, IllegalAccessException {
      +    ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig");
      +    setRetentionPeriod(config, "minRetentionPeriodMillis", value);
      +  }
       
      -    public static void setSampleIntervalMillis(Object metric, long value) throws NoSuchFieldException, IllegalAccessException {
      -        ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig");
      -        setRetentionPeriod(config, "sampleIntervalMillis", value);
      -    }
      +  public static void setSampleIntervalMillis(Object metric, long value)
      +      throws NoSuchFieldException, IllegalAccessException {
      +    ExemplarSamplerConfig config = getConfig(metric, "exemplarSamplerConfig");
      +    setRetentionPeriod(config, "sampleIntervalMillis", value);
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java
      index 1af5da42b..9d51ae17b 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java
      @@ -1,10 +1,10 @@
       package io.prometheus.metrics.core.exemplars;
       
      -import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
      +import io.prometheus.metrics.core.util.Scheduler;
       import io.prometheus.metrics.model.snapshots.Exemplar;
       import io.prometheus.metrics.model.snapshots.Exemplars;
       import io.prometheus.metrics.model.snapshots.Label;
      -import io.prometheus.metrics.core.util.Scheduler;
      +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import org.junit.After;
       import org.junit.Assert;
       import org.junit.Before;
      @@ -12,214 +12,215 @@
       
       public class ExemplarSamplerTest {
       
      -    private final int tick = 10; // Time step in milliseconds. Make this larger if the test is flaky.
      -    private final int sampleInterval = 10 * tick; // do not change this
      -    private final int minAge = 50 * tick; // do not change this
      -    private final int maxAge = 200 * tick; // do not change this
      -
      -    private ExemplarSamplerConfig makeConfig(double... buckets) {
      -        return new ExemplarSamplerConfig(
      -                minAge,
      -                maxAge,
      -                sampleInterval,
      -                buckets.length == 0 ? 4 : buckets.length, // number of exemplars
      -                buckets.length == 0 ? null : buckets
      -        );
      +  private final int tick = 10; // Time step in milliseconds. Make this larger if the test is flaky.
      +  private final int sampleInterval = 10 * tick; // do not change this
      +  private final int minAge = 50 * tick; // do not change this
      +  private final int maxAge = 200 * tick; // do not change this
      +
      +  private ExemplarSamplerConfig makeConfig(double... buckets) {
      +    return new ExemplarSamplerConfig(
      +        minAge,
      +        maxAge,
      +        sampleInterval,
      +        buckets.length == 0 ? 4 : buckets.length, // number of exemplars
      +        buckets.length == 0 ? null : buckets);
      +  }
      +
      +  private static class SpanContext implements io.prometheus.metrics.tracer.common.SpanContext {
      +
      +    int callCount = 0;
      +    boolean isSampled = true;
      +    boolean isExemplar = false;
      +
      +    @Override
      +    public String getCurrentTraceId() {
      +      return "" + (callCount++);
           }
       
      -
      -    private static class SpanContext implements io.prometheus.metrics.tracer.common.SpanContext {
      -
      -        int callCount = 0;
      -        boolean isSampled = true;
      -        boolean isExemplar = false;
      -
      -        @Override
      -        public String getCurrentTraceId() {
      -            return "" + (callCount++);
      -        }
      -
      -        @Override
      -        public String getCurrentSpanId() {
      -            return "" + callCount;
      -        }
      -
      -        @Override
      -        public boolean isCurrentSpanSampled() {
      -            return isSampled;
      -        }
      -
      -        @Override
      -        public void markCurrentSpanAsExemplar() {
      -            isExemplar = true;
      -        }
      +    @Override
      +    public String getCurrentSpanId() {
      +      return "" + callCount;
           }
       
      -    @Test
      -    public void testCustomExemplarsBuckets() throws Exception {
      -        // TODO
      +    @Override
      +    public boolean isCurrentSpanSampled() {
      +      return isSampled;
           }
       
      -    private io.prometheus.metrics.tracer.common.SpanContext origContext;
      -
      -    @Before
      -    public void setUp() {
      -        origContext = SpanContextSupplier.getSpanContext();
      +    @Override
      +    public void markCurrentSpanAsExemplar() {
      +      isExemplar = true;
           }
      -
      -    @After
      -    public void tearDown() {
      -        SpanContextSupplier.setSpanContext(origContext);
      -    }
      -
      -    @Test
      -    public void testIsSampled() throws Exception {
      -        SpanContext context = new SpanContext();
      -        context.isSampled = false;
      -        ExemplarSampler sampler = new ExemplarSampler(makeConfig(), context);
      -        Thread.sleep(tick); // t = 1 tick
      -        sampler.observe(0.3); // no sampled, because isSampled() returns false
      -        assertExemplars(sampler); // empty
      -    }
      -
      -    @Test
      -    public void testDefaultConfigHasFourExemplars() throws Exception {
      -        ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext());
      -        Thread.sleep(tick); // t = 1 tick
      -        sampler.observe(0.3);
      -        Thread.sleep(sampleInterval + tick); // t = 12 tick
      -        sampler.observe(0.8);
      -        Thread.sleep(sampleInterval + tick); // t = 23 tick
      -        sampler.observe(0.4);
      -        Thread.sleep(sampleInterval + tick); // t = 34 tick
      -        sampler.observe(0.6);
      -        Thread.sleep(sampleInterval + tick); // t = 45 tick
      -        sampler.observe(0.2); // not observed, we got 4 Exemplars already and non reached min age
      -        assertExemplars(sampler, 0.3, 0.8, 0.4, 0.6);
      -        print(sampler.collect());
      -    }
      -
      -    @Test
      -    public void testEmptyBuckets() throws Exception {
      -        ExemplarSampler sampler = new ExemplarSampler(makeConfig(Double.POSITIVE_INFINITY), new SpanContext());
      -        Thread.sleep(tick); // t = 1 tick
      -        sampler.observe(0.8); // observed in the +Inf bucket
      -        Thread.sleep(sampleInterval + tick); // t = 12 tick
      -        sampler.observe(0.5); // not observed, because +Inf is the only bucket
      -        assertExemplars(sampler, 0.8);
      -        print(sampler.collect());
      -    }
      -
      -    @Test
      -    public void testDefaultExemplarsBuckets() throws Exception {
      -        ExemplarSampler sampler = new ExemplarSampler(makeConfig(0.2, 0.4, 0.6, 0.8, 1.0, Double.POSITIVE_INFINITY), new SpanContext());
      -        Scheduler.awaitInitialization();
      -        Thread.sleep(tick); // t = 1 tick
      -        sampler.observe(0.3);
      -        sampler.observe(0.5); // not observed, previous observation is less than sample interval ms ago
      -        assertExemplars(sampler, 0.3);
      -        Thread.sleep(sampleInterval + tick); // t = 12 ticks
      -        sampler.observe(0.5); // observed
      -        assertExemplars(sampler, 0.3, 0.5);
      -        Thread.sleep(sampleInterval + tick); // t = 23 ticks
      -        sampler.observe(0.4); // not observed, because 0.3 hasn't reached min age yet
      -        assertExemplars(sampler, 0.3, 0.5);
      -        Thread.sleep(sampleInterval + tick); // t = 34 ticks
      -        sampler.observe(1.1); // observed
      -        assertExemplars(sampler, 0.3, 0.5, 1.1);
      -        Thread.sleep(20 * tick); // t = 54 ticks
      -        assertExemplars(sampler, 0.3, 0.5, 1.1);
      -        sampler.observe(0.4); // observed
      -        assertExemplars(sampler, 0.4, 0.5, 1.1);
      -        Thread.sleep(159 * tick); // t = 213 ticks
      -        assertExemplars(sampler, 0.4, 1.1); // 0.5 evicted because it has reached max age
      -        print(sampler.collect());
      -    }
      -
      -    @Test
      -    public void testCustomExemplarsNoBuckets() throws Exception {
      -        // TODO
      -    }
      -
      -    @Test
      -    public void testDefaultExemplarsNoBuckets() throws Exception {
      -        ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext());
      -        Scheduler.awaitInitialization();
      -        Thread.sleep(tick);           // t = 1 tick
      -        sampler.observe(1);    // observed
      -        assertExemplars(sampler, 1);
      -        sampler.observe(2);    // not observed, previous observation is less than sample interval ms ago
      -        Thread.sleep(sampleInterval + tick); // t = 12 ticks
      -        sampler.observe(3);    // observed
      -        assertExemplars(sampler, 1, 3);
      -        Thread.sleep(2 * tick);    // t = 14 ticks
      -        sampler.observe(4);    // not observed, previous observation is less than sample interval ms ago
      -        Thread.sleep(sampleInterval + tick); // t = 25 ticks
      -        sampler.observe(5);    // observed
      -        assertExemplars(sampler, 1, 3, 5);
      -        Thread.sleep(sampleInterval + tick); // t = 36 ticks
      -        sampler.observe(6);    // observed
      -        assertExemplars(sampler, 1, 3, 5, 6);
      -        Thread.sleep(sampleInterval + tick);  // t = 47 ticks
      -        sampler.observe(7);    // not observed, because no Exemplar has reached the minimum age yet
      -        Thread.sleep(5 * tick); // t = 52 ticks
      -        sampler.observe(2); // not observed. 1 is older than min age, but kept because it's the minimum
      -        assertExemplars(sampler, 1, 3, 5, 6);
      -        Thread.sleep(sampleInterval + tick); // t = 63 ticks
      -        sampler.observe(2); // observed
      -        assertExemplars(sampler, 1, 2, 5, 6);
      -        Thread.sleep(27 * tick); // t = 90 ticks
      -        sampler.observe(7); // observed, replaces 6 because 7 > 6 even though 5 is older
      -        assertExemplars(sampler, 1, 2, 5, 7);
      -        sampler.observe(8); // not observed, sample interval not done
      -        assertExemplars(sampler, 1, 2, 5, 7);
      -        Thread.sleep(sampleInterval + tick); // t = 101 ticks
      -        sampler.observe(8); // observed
      -        assertExemplars(sampler, 1, 2, 8, 7);
      -        Thread.sleep(101 * tick); // t = 202 ticks
      -        sampler.observe(5); // observed, replaces 1 because 1 reached the max age
      -        assertExemplars(sampler, 5, 2, 8, 7);
      -        print(sampler.collect());
      -    }
      -
      -    private void assertExemplars(ExemplarSampler sampler, double... values) {
      -        Exemplars exemplars = sampler.collect();
      -        Assert.assertEquals(values.length, exemplars.size());
      -        for (double value : values) {
      -            boolean found = false;
      -            for (Exemplar exemplar : exemplars) {
      -                if (exemplar.getValue() == value) {
      -                    found = true;
      -                    break;
      -                }
      -            }
      -            Assert.assertTrue(value + " not found", found);
      +  }
      +
      +  @Test
      +  public void testCustomExemplarsBuckets() throws Exception {
      +    // TODO
      +  }
      +
      +  private io.prometheus.metrics.tracer.common.SpanContext origContext;
      +
      +  @Before
      +  public void setUp() {
      +    origContext = SpanContextSupplier.getSpanContext();
      +  }
      +
      +  @After
      +  public void tearDown() {
      +    SpanContextSupplier.setSpanContext(origContext);
      +  }
      +
      +  @Test
      +  public void testIsSampled() throws Exception {
      +    SpanContext context = new SpanContext();
      +    context.isSampled = false;
      +    ExemplarSampler sampler = new ExemplarSampler(makeConfig(), context);
      +    Thread.sleep(tick); // t = 1 tick
      +    sampler.observe(0.3); // no sampled, because isSampled() returns false
      +    assertExemplars(sampler); // empty
      +  }
      +
      +  @Test
      +  public void testDefaultConfigHasFourExemplars() throws Exception {
      +    ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext());
      +    Thread.sleep(tick); // t = 1 tick
      +    sampler.observe(0.3);
      +    Thread.sleep(sampleInterval + tick); // t = 12 tick
      +    sampler.observe(0.8);
      +    Thread.sleep(sampleInterval + tick); // t = 23 tick
      +    sampler.observe(0.4);
      +    Thread.sleep(sampleInterval + tick); // t = 34 tick
      +    sampler.observe(0.6);
      +    Thread.sleep(sampleInterval + tick); // t = 45 tick
      +    sampler.observe(0.2); // not observed, we got 4 Exemplars already and non reached min age
      +    assertExemplars(sampler, 0.3, 0.8, 0.4, 0.6);
      +    print(sampler.collect());
      +  }
      +
      +  @Test
      +  public void testEmptyBuckets() throws Exception {
      +    ExemplarSampler sampler =
      +        new ExemplarSampler(makeConfig(Double.POSITIVE_INFINITY), new SpanContext());
      +    Thread.sleep(tick); // t = 1 tick
      +    sampler.observe(0.8); // observed in the +Inf bucket
      +    Thread.sleep(sampleInterval + tick); // t = 12 tick
      +    sampler.observe(0.5); // not observed, because +Inf is the only bucket
      +    assertExemplars(sampler, 0.8);
      +    print(sampler.collect());
      +  }
      +
      +  @Test
      +  public void testDefaultExemplarsBuckets() throws Exception {
      +    ExemplarSampler sampler =
      +        new ExemplarSampler(
      +            makeConfig(0.2, 0.4, 0.6, 0.8, 1.0, Double.POSITIVE_INFINITY), new SpanContext());
      +    Scheduler.awaitInitialization();
      +    Thread.sleep(tick); // t = 1 tick
      +    sampler.observe(0.3);
      +    sampler.observe(0.5); // not observed, previous observation is less than sample interval ms ago
      +    assertExemplars(sampler, 0.3);
      +    Thread.sleep(sampleInterval + tick); // t = 12 ticks
      +    sampler.observe(0.5); // observed
      +    assertExemplars(sampler, 0.3, 0.5);
      +    Thread.sleep(sampleInterval + tick); // t = 23 ticks
      +    sampler.observe(0.4); // not observed, because 0.3 hasn't reached min age yet
      +    assertExemplars(sampler, 0.3, 0.5);
      +    Thread.sleep(sampleInterval + tick); // t = 34 ticks
      +    sampler.observe(1.1); // observed
      +    assertExemplars(sampler, 0.3, 0.5, 1.1);
      +    Thread.sleep(20 * tick); // t = 54 ticks
      +    assertExemplars(sampler, 0.3, 0.5, 1.1);
      +    sampler.observe(0.4); // observed
      +    assertExemplars(sampler, 0.4, 0.5, 1.1);
      +    Thread.sleep(159 * tick); // t = 213 ticks
      +    assertExemplars(sampler, 0.4, 1.1); // 0.5 evicted because it has reached max age
      +    print(sampler.collect());
      +  }
      +
      +  @Test
      +  public void testCustomExemplarsNoBuckets() throws Exception {
      +    // TODO
      +  }
      +
      +  @Test
      +  public void testDefaultExemplarsNoBuckets() throws Exception {
      +    ExemplarSampler sampler = new ExemplarSampler(makeConfig(), new SpanContext());
      +    Scheduler.awaitInitialization();
      +    Thread.sleep(tick); // t = 1 tick
      +    sampler.observe(1); // observed
      +    assertExemplars(sampler, 1);
      +    sampler.observe(2); // not observed, previous observation is less than sample interval ms ago
      +    Thread.sleep(sampleInterval + tick); // t = 12 ticks
      +    sampler.observe(3); // observed
      +    assertExemplars(sampler, 1, 3);
      +    Thread.sleep(2 * tick); // t = 14 ticks
      +    sampler.observe(4); // not observed, previous observation is less than sample interval ms ago
      +    Thread.sleep(sampleInterval + tick); // t = 25 ticks
      +    sampler.observe(5); // observed
      +    assertExemplars(sampler, 1, 3, 5);
      +    Thread.sleep(sampleInterval + tick); // t = 36 ticks
      +    sampler.observe(6); // observed
      +    assertExemplars(sampler, 1, 3, 5, 6);
      +    Thread.sleep(sampleInterval + tick); // t = 47 ticks
      +    sampler.observe(7); // not observed, because no Exemplar has reached the minimum age yet
      +    Thread.sleep(5 * tick); // t = 52 ticks
      +    sampler.observe(2); // not observed. 1 is older than min age, but kept because it's the minimum
      +    assertExemplars(sampler, 1, 3, 5, 6);
      +    Thread.sleep(sampleInterval + tick); // t = 63 ticks
      +    sampler.observe(2); // observed
      +    assertExemplars(sampler, 1, 2, 5, 6);
      +    Thread.sleep(27 * tick); // t = 90 ticks
      +    sampler.observe(7); // observed, replaces 6 because 7 > 6 even though 5 is older
      +    assertExemplars(sampler, 1, 2, 5, 7);
      +    sampler.observe(8); // not observed, sample interval not done
      +    assertExemplars(sampler, 1, 2, 5, 7);
      +    Thread.sleep(sampleInterval + tick); // t = 101 ticks
      +    sampler.observe(8); // observed
      +    assertExemplars(sampler, 1, 2, 8, 7);
      +    Thread.sleep(101 * tick); // t = 202 ticks
      +    sampler.observe(5); // observed, replaces 1 because 1 reached the max age
      +    assertExemplars(sampler, 5, 2, 8, 7);
      +    print(sampler.collect());
      +  }
      +
      +  private void assertExemplars(ExemplarSampler sampler, double... values) {
      +    Exemplars exemplars = sampler.collect();
      +    Assert.assertEquals(values.length, exemplars.size());
      +    for (double value : values) {
      +      boolean found = false;
      +      for (Exemplar exemplar : exemplars) {
      +        if (exemplar.getValue() == value) {
      +          found = true;
      +          break;
               }
      +      }
      +      Assert.assertTrue(value + " not found", found);
           }
      -
      -    private void print(Exemplars exemplars) {
      -        System.out.print("[");
      -        boolean farst = true;
      -        for (Exemplar exemplar : exemplars) {
      -            if (!farst) {
      -                System.out.print(",");
      -            }
      -            farst = false;
      -            System.out.print(exemplar.getValue() + "{");
      -            boolean first = true;
      -            for (Label label : exemplar.getLabels()) {
      -                if (!first) {
      -                    System.out.print(",");
      -                }
      -                System.out.print(label.getName() + "=" + label.getValue());
      -                first = false;
      -            }
      -            if (!first) {
      -                System.out.print(",");
      -            }
      -            System.out.print("age=" + (System.currentTimeMillis() - exemplar.getTimestampMillis()));
      -            System.out.print("}");
      +  }
      +
      +  private void print(Exemplars exemplars) {
      +    System.out.print("[");
      +    boolean farst = true;
      +    for (Exemplar exemplar : exemplars) {
      +      if (!farst) {
      +        System.out.print(",");
      +      }
      +      farst = false;
      +      System.out.print(exemplar.getValue() + "{");
      +      boolean first = true;
      +      for (Label label : exemplar.getLabels()) {
      +        if (!first) {
      +          System.out.print(",");
               }
      -        System.out.println("]");
      +        System.out.print(label.getName() + "=" + label.getValue());
      +        first = false;
      +      }
      +      if (!first) {
      +        System.out.print(",");
      +      }
      +      System.out.print("age=" + (System.currentTimeMillis() - exemplar.getTimestampMillis()));
      +      System.out.print("}");
           }
      +    System.out.println("]");
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java
      index 033420950..b1409b142 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java
      @@ -1,5 +1,7 @@
       package io.prometheus.metrics.core.exemplars;
       
      +import static io.prometheus.metrics.model.snapshots.Exemplar.TRACE_ID;
      +
       import io.prometheus.metrics.config.ExemplarsProperties;
       import io.prometheus.metrics.model.snapshots.Exemplar;
       import io.prometheus.metrics.model.snapshots.Exemplars;
      @@ -7,97 +9,97 @@
       import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import org.junit.*;
       
      -import static io.prometheus.metrics.model.snapshots.Exemplar.TRACE_ID;
      -
       public class SpanContextSupplierTest {
       
      -    public SpanContext makeSpanContext(String traceId, String spanId) {
      -
      -        return new SpanContext() {
      -            @Override
      -            public String getCurrentTraceId() {
      -                return traceId;
      -            }
      -
      -            @Override
      -            public String getCurrentSpanId() {
      -                return spanId;
      -            }
      -
      -            @Override
      -            public boolean isCurrentSpanSampled() {
      -                return true;
      -            }
      -
      -            @Override
      -            public void markCurrentSpanAsExemplar() {
      -            }
      -        };
      -    }
      -
      -    SpanContext spanContextA = makeSpanContext("A", "a");
      -    SpanContext spanContextB = makeSpanContext("B", "b");
      -    SpanContext origSpanContext;
      -
      -    ExemplarSamplerConfig config = new ExemplarSamplerConfig(
      -            10, // min retention period in milliseconds
      -            20, // max retention period in milliseconds
      -            5, // sample interval in millisecnods
      -            1, // number of exemplars
      -            null // histogram upper bounds
      -    );
      -
      -    @Before
      -    public void setUp() {
      -        origSpanContext = SpanContextSupplier.getSpanContext();
      -    }
      -
      -    @After
      -    public void tearDown() {
      -        SpanContextSupplier.setSpanContext(origSpanContext);
      -    }
      -
      -    /**
      -     * Test: When a {@link SpanContext} is provided as a constructor argument to the {@link ExemplarSampler},
      -     * then that {@link SpanContext} is used, not the one from the {@link SpanContextSupplier}.
      -     */
      -    @Test
      -    public void testConstructorInjection() {
      -        ExemplarsProperties properties = ExemplarsProperties.builder().build();
      -        ExemplarSamplerConfig config = new ExemplarSamplerConfig(properties, 1);
      -        ExemplarSampler exemplarSampler = new ExemplarSampler(config, spanContextA);
      -
      -        SpanContextSupplier.setSpanContext(spanContextB);
      -        exemplarSampler.observe(1.0);
      -        Exemplars exemplars = exemplarSampler.collect();
      -        Assert.assertEquals(1, exemplars.size());
      -        Exemplar exemplar = exemplars.get(0);
      -        Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID));
      -    }
      -
      -    /**
      -     * When the global {@link SpanContext} is updated via {@link SpanContextSupplier#setSpanContext(SpanContext)},
      -     * the {@link ExemplarSampler} recognizes the update (unless a {@link ExemplarSampler} was provided as
      -     * constructor argument to {@link ExemplarSampler}).
      -     */
      -    @Test
      -    public void testUpdateSpanContext() throws InterruptedException {
      -        ExemplarSampler exemplarSampler = new ExemplarSampler(config);
      -
      -        SpanContextSupplier.setSpanContext(spanContextB);
      -        exemplarSampler.observe(1.0);
      -        Exemplars exemplars = exemplarSampler.collect();
      -        Assert.assertEquals(1, exemplars.size());
      -        Exemplar exemplar = exemplars.get(0);
      -        Assert.assertEquals("B", exemplar.getLabels().get(TRACE_ID));
      -
      -        Thread.sleep(15); // more than the minimum retention period defined in config above.
      -
      -        SpanContextSupplier.setSpanContext(spanContextA);
      -        exemplarSampler.observe(1.0);
      -        exemplars = exemplarSampler.collect();
      -        Assert.assertEquals(1, exemplars.size());
      -        exemplar = exemplars.get(0);
      -        Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID));
      -    }
      +  public SpanContext makeSpanContext(String traceId, String spanId) {
      +
      +    return new SpanContext() {
      +      @Override
      +      public String getCurrentTraceId() {
      +        return traceId;
      +      }
      +
      +      @Override
      +      public String getCurrentSpanId() {
      +        return spanId;
      +      }
      +
      +      @Override
      +      public boolean isCurrentSpanSampled() {
      +        return true;
      +      }
      +
      +      @Override
      +      public void markCurrentSpanAsExemplar() {}
      +    };
      +  }
      +
      +  SpanContext spanContextA = makeSpanContext("A", "a");
      +  SpanContext spanContextB = makeSpanContext("B", "b");
      +  SpanContext origSpanContext;
      +
      +  ExemplarSamplerConfig config =
      +      new ExemplarSamplerConfig(
      +          10, // min retention period in milliseconds
      +          20, // max retention period in milliseconds
      +          5, // sample interval in millisecnods
      +          1, // number of exemplars
      +          null // histogram upper bounds
      +          );
      +
      +  @Before
      +  public void setUp() {
      +    origSpanContext = SpanContextSupplier.getSpanContext();
      +  }
      +
      +  @After
      +  public void tearDown() {
      +    SpanContextSupplier.setSpanContext(origSpanContext);
      +  }
      +
      +  /**
      +   * Test: When a {@link SpanContext} is provided as a constructor argument to the {@link
      +   * ExemplarSampler}, then that {@link SpanContext} is used, not the one from the {@link
      +   * SpanContextSupplier}.
      +   */
      +  @Test
      +  public void testConstructorInjection() {
      +    ExemplarsProperties properties = ExemplarsProperties.builder().build();
      +    ExemplarSamplerConfig config = new ExemplarSamplerConfig(properties, 1);
      +    ExemplarSampler exemplarSampler = new ExemplarSampler(config, spanContextA);
      +
      +    SpanContextSupplier.setSpanContext(spanContextB);
      +    exemplarSampler.observe(1.0);
      +    Exemplars exemplars = exemplarSampler.collect();
      +    Assert.assertEquals(1, exemplars.size());
      +    Exemplar exemplar = exemplars.get(0);
      +    Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID));
      +  }
      +
      +  /**
      +   * When the global {@link SpanContext} is updated via {@link
      +   * SpanContextSupplier#setSpanContext(SpanContext)}, the {@link ExemplarSampler} recognizes the
      +   * update (unless a {@link ExemplarSampler} was provided as constructor argument to {@link
      +   * ExemplarSampler}).
      +   */
      +  @Test
      +  public void testUpdateSpanContext() throws InterruptedException {
      +    ExemplarSampler exemplarSampler = new ExemplarSampler(config);
      +
      +    SpanContextSupplier.setSpanContext(spanContextB);
      +    exemplarSampler.observe(1.0);
      +    Exemplars exemplars = exemplarSampler.collect();
      +    Assert.assertEquals(1, exemplars.size());
      +    Exemplar exemplar = exemplars.get(0);
      +    Assert.assertEquals("B", exemplar.getLabels().get(TRACE_ID));
      +
      +    Thread.sleep(15); // more than the minimum retention period defined in config above.
      +
      +    SpanContextSupplier.setSpanContext(spanContextA);
      +    exemplarSampler.observe(1.0);
      +    exemplars = exemplarSampler.collect();
      +    Assert.assertEquals(1, exemplars.size());
      +    exemplar = exemplars.get(0);
      +    Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID));
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java
      index ef90f85cf..e8adc42fe 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java
      @@ -1,340 +1,369 @@
       package io.prometheus.metrics.core.metrics;
       
      +import static org.junit.Assert.*;
      +
       import io.prometheus.metrics.core.metrics.CKMSQuantiles.Quantile;
      +import java.util.*;
       import org.apache.commons.math3.distribution.NormalDistribution;
       import org.apache.commons.math3.random.JDKRandomGenerator;
       import org.apache.commons.math3.random.RandomGenerator;
       import org.junit.Test;
       
      -import java.util.*;
      -
      -import static org.junit.Assert.*;
      -
       public class CKMSQuantilesTest {
       
      -    private final Quantile qMin = new Quantile(0.0, 0.00);
      -    private final Quantile q50 = new Quantile(0.5, 0.01);
      -    private final Quantile q95 = new Quantile(0.95, 0.005);
      -    private final Quantile q99 = new Quantile(0.99, 0.001);
      -    private final Quantile qMax = new Quantile(1.0, 0.00);
      -
      -    @Test
      -    public void testGetOnEmptyValues() {
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      -        assertTrue(Double.isNaN(ckms.get(q95.quantile)));
      -    }
      -
      -    @Test
      -    public void testGet() {
      -        Random random = new Random(0);
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      -        List input = shuffledValues(100, random);
      -        for (double value : input) {
      -            ckms.insert(value);
      -        }
      -        validateResults(ckms);
      +  private final Quantile qMin = new Quantile(0.0, 0.00);
      +  private final Quantile q50 = new Quantile(0.5, 0.01);
      +  private final Quantile q95 = new Quantile(0.95, 0.005);
      +  private final Quantile q99 = new Quantile(0.99, 0.001);
      +  private final Quantile qMax = new Quantile(1.0, 0.00);
      +
      +  @Test
      +  public void testGetOnEmptyValues() {
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      +    assertTrue(Double.isNaN(ckms.get(q95.quantile)));
      +  }
      +
      +  @Test
      +  public void testGet() {
      +    Random random = new Random(0);
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      +    List input = shuffledValues(100, random);
      +    for (double value : input) {
      +      ckms.insert(value);
           }
      -
      -    @Test
      -    public void testBatchInsert() {
      -        Random random = new Random(1);
      -        testInsertBatch(1, 1, 100, random);
      -        testInsertBatch(1, 10, 100, random);
      -        testInsertBatch(2, 10, 100, random);
      -        testInsertBatch(2, 110, 100, random); // compress never called, because compress interval > number of inserts
      -        testInsertBatch(3, 10, 100, random);
      -        testInsertBatch(10, 10, 100, random);
      -        testInsertBatch(128, 128, 1, random);
      -        testInsertBatch(128, 128, 1000, random);
      -        testInsertBatch(128, 128, 10*1000, random);
      -        testInsertBatch(128, 128, 100*1000, random);
      -        testInsertBatch(128, 128, 1000*1000, random);
      +    validateResults(ckms);
      +  }
      +
      +  @Test
      +  public void testBatchInsert() {
      +    Random random = new Random(1);
      +    testInsertBatch(1, 1, 100, random);
      +    testInsertBatch(1, 10, 100, random);
      +    testInsertBatch(2, 10, 100, random);
      +    testInsertBatch(
      +        2, 110, 100,
      +        random); // compress never called, because compress interval > number of inserts
      +    testInsertBatch(3, 10, 100, random);
      +    testInsertBatch(10, 10, 100, random);
      +    testInsertBatch(128, 128, 1, random);
      +    testInsertBatch(128, 128, 1000, random);
      +    testInsertBatch(128, 128, 10 * 1000, random);
      +    testInsertBatch(128, 128, 100 * 1000, random);
      +    testInsertBatch(128, 128, 1000 * 1000, random);
      +  }
      +
      +  private void testInsertBatch(
      +      int batchSize, int compressInterval, int totalNumber, Random random) {
      +    System.out.println(
      +        "testInsertBatch(batchSize="
      +            + batchSize
      +            + ", compressInterval="
      +            + compressInterval
      +            + ", totalNumber="
      +            + totalNumber
      +            + ")");
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, q95);
      +    int insertsSinceCompress = 0;
      +    List input = shuffledValues(totalNumber, random);
      +    for (int i = 0; i < input.size(); i += batchSize) {
      +      double[] batch = new double[batchSize];
      +      int j;
      +      for (j = 0; j < batchSize && i + j < input.size(); j++) {
      +        batch[j] = input.get(i + j);
      +      }
      +      Arrays.sort(batch, 0, j);
      +      ckms.insertBatch(batch, j);
      +      validateSamples(ckms); // after each insert the samples should still be valid
      +      insertsSinceCompress += j;
      +      if (insertsSinceCompress >= compressInterval) {
      +        ckms.compress();
      +        validateSamples(ckms); // after each compress the samples should still be valid
      +        insertsSinceCompress = 0;
      +      }
           }
      -
      -    private void testInsertBatch(int batchSize, int compressInterval, int totalNumber, Random random) {
      -        System.out.println("testInsertBatch(batchSize=" + batchSize + ", compressInterval=" + compressInterval + ", totalNumber=" + totalNumber + ")");
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, q95);
      -        int insertsSinceCompress = 0;
      -        List input = shuffledValues(totalNumber, random);
      -        for (int i=0; i= compressInterval) {
      -                ckms.compress();
      -                validateSamples(ckms); // after each compress the samples should still be valid
      -                insertsSinceCompress=0;
      -            }
      -        }
      -        validateResults(ckms);
      +    validateResults(ckms);
      +  }
      +
      +  @Test
      +  public void testGetWithAMillionElements() {
      +    Random random = new Random(2);
      +    List input = shuffledValues(1000 * 1000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testGetWithAMillionElements() {
      -        Random random = new Random(2);
      -        List input = shuffledValues(1000*1000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000);
      +    validateResults(ckms);
      +    assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000);
      +  }
      +
      +  @Test
      +  public void testMin() {
      +    Random random = new Random(3);
      +    List input = shuffledValues(1000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(qMin);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMin() {
      -        Random random = new Random(3);
      -        List input = shuffledValues(1000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(qMin);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        ckms.compress();
      -        assertEquals(2, ckms.samples.size());
      +    validateResults(ckms);
      +    ckms.compress();
      +    assertEquals(2, ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testMax() {
      +    Random random = new Random(4);
      +    List input = shuffledValues(1000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(qMax);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMax() {
      -        Random random = new Random(4);
      -        List input = shuffledValues(1000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(qMax);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        ckms.compress();
      -        assertEquals(2, ckms.samples.size());
      +    validateResults(ckms);
      +    ckms.compress();
      +    assertEquals(2, ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testMinMax() {
      +    Random random = new Random(5);
      +    List input = shuffledValues(1000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(qMin, qMax);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMinMax() {
      -        Random random = new Random(5);
      -        List input = shuffledValues(1000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(qMin, qMax);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        ckms.compress();
      -        assertEquals(2, ckms.samples.size());
      +    validateResults(ckms);
      +    ckms.compress();
      +    assertEquals(2, ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testMinAndOthers() {
      +    Random random = new Random(6);
      +    List input = shuffledValues(1000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(q95, qMin);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMinAndOthers() {
      -        Random random = new Random(6);
      -        List input = shuffledValues(1000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(q95, qMin);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +    validateResults(ckms);
      +    assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +  }
      +
      +  @Test
      +  public void testMaxAndOthers() {
      +    Random random = new Random(7);
      +    List input = shuffledValues(10000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, qMax);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMaxAndOthers() {
      -        Random random = new Random(7);
      -        List input = shuffledValues(10000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, qMax);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +    validateResults(ckms);
      +    assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +  }
      +
      +  @Test
      +  public void testMinMaxAndOthers() {
      +    Random random = new Random(8);
      +    List input = shuffledValues(10000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, q95, q99, qMax);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMinMaxAndOthers() {
      -        Random random = new Random(8);
      -        List input = shuffledValues(10000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, q95, q99, qMax);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +    validateResults(ckms);
      +    assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size()
      +  }
      +
      +  @Test
      +  public void testExactQuantile() {
      +    Random random = new Random(9);
      +    List input = shuffledValues(10000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 0));
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testExactQuantile() {
      -        Random random = new Random(9);
      -        List input = shuffledValues(10000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 0));
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        // With epsilon == 0 we need to keep all inputs in samples.
      -        assertEquals(input.size(), ckms.samples.size());
      +    validateResults(ckms);
      +    // With epsilon == 0 we need to keep all inputs in samples.
      +    assertEquals(input.size(), ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testExactAndOthers() {
      +    Random random = new Random(10);
      +    List input = shuffledValues(10000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(q50, new Quantile(0.95, 0), q99);
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testExactAndOthers() {
      -        Random random = new Random(10);
      -        List input = shuffledValues(10000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(q50, new Quantile(0.95, 0), q99);
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        // With epsilon == 0 we need to keep all inputs in samples.
      -        assertEquals(input.size(), ckms.samples.size());
      +    validateResults(ckms);
      +    // With epsilon == 0 we need to keep all inputs in samples.
      +    assertEquals(input.size(), ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testExactAndMin() {
      +    Random random = new Random(11);
      +    List input = shuffledValues(10000, random);
      +    CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, new Quantile(0.95, 0));
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testExactAndMin() {
      -        Random random = new Random(11);
      -        List input = shuffledValues(10000, random);
      -        CKMSQuantiles ckms = new CKMSQuantiles(qMin, q50, new Quantile(0.95, 0));
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      -        // With epsilon == 0 we need to keep all inputs in samples.
      -        assertEquals(input.size(), ckms.samples.size());
      +    validateResults(ckms);
      +    // With epsilon == 0 we need to keep all inputs in samples.
      +    assertEquals(input.size(), ckms.samples.size());
      +  }
      +
      +  @Test
      +  public void testMaxEpsilon() {
      +    Random random = new Random(12);
      +    List input = shuffledValues(10000, random);
      +    // epsilon == 1 basically gives you random results, but it should still not throw an exception.
      +    CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 1));
      +    for (double v : input) {
      +      ckms.insert(v);
           }
      -
      -    @Test
      -    public void testMaxEpsilon() {
      -        Random random = new Random(12);
      -        List input = shuffledValues(10000, random);
      -        // epsilon == 1 basically gives you random results, but it should still not throw an exception.
      -        CKMSQuantiles ckms = new CKMSQuantiles(new Quantile(0.95, 1));
      -        for (double v : input) {
      -            ckms.insert(v);
      -        }
      -        validateResults(ckms);
      +    validateResults(ckms);
      +  }
      +
      +  @Test
      +  public void testGetGaussian() {
      +    RandomGenerator rand = new JDKRandomGenerator();
      +    rand.setSeed(0);
      +
      +    double mean = 0.0;
      +    double stddev = 1.0;
      +    NormalDistribution normalDistribution =
      +        new NormalDistribution(
      +            rand, mean, stddev, NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
      +
      +    List quantiles = new ArrayList();
      +    quantiles.add(new Quantile(0.10, 0.001));
      +    quantiles.add(new Quantile(0.50, 0.01));
      +    quantiles.add(new Quantile(0.90, 0.001));
      +    quantiles.add(new Quantile(0.95, 0.001));
      +    quantiles.add(new Quantile(0.99, 0.001));
      +
      +    CKMSQuantiles ckms = new CKMSQuantiles(quantiles.toArray(new Quantile[] {}));
      +
      +    final int elemCount = 1000 * 1000;
      +    double[] shuffle = normalDistribution.sample(elemCount);
      +
      +    // insert a million samples
      +    for (double v : shuffle) {
      +      ckms.insert(v);
           }
       
      -    @Test
      -    public void testGetGaussian() {
      -        RandomGenerator rand = new JDKRandomGenerator();
      -        rand.setSeed(0);
      -
      -        double mean = 0.0;
      -        double stddev = 1.0;
      -        NormalDistribution normalDistribution = new NormalDistribution(rand, mean, stddev, NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
      -
      -        List quantiles = new ArrayList();
      -        quantiles.add(new Quantile(0.10, 0.001));
      -        quantiles.add(new Quantile(0.50, 0.01));
      -        quantiles.add(new Quantile(0.90, 0.001));
      -        quantiles.add(new Quantile(0.95, 0.001));
      -        quantiles.add(new Quantile(0.99, 0.001));
      -
      -        CKMSQuantiles ckms = new CKMSQuantiles(quantiles.toArray(new Quantile[]{}));
      -
      -        final int elemCount = 1000*1000;
      -        double[] shuffle = normalDistribution.sample(elemCount);
      -
      -        // insert a million samples
      -        for (double v : shuffle) {
      -            ckms.insert(v);
      -        }
      -
      -        // give the actual values for the quantiles we test
      -        double p10 = normalDistribution.inverseCumulativeProbability(0.1);
      -        double p90 = normalDistribution.inverseCumulativeProbability(0.9);
      -        double p95 = normalDistribution.inverseCumulativeProbability(0.95);
      -        double p99 = normalDistribution.inverseCumulativeProbability(0.99);
      -
      -        //ε-approximate quantiles relaxes the requirement
      -        //to finding an item with rank between (φ−ε)n and (φ+ε)n.
      -        assertEquals(p10, ckms.get(0.1), errorBoundsNormalDistribution(0.1, 0.001, normalDistribution));
      -        assertEquals(mean, ckms.get(0.5), errorBoundsNormalDistribution(0.5, 0.01, normalDistribution));
      -        assertEquals(p90, ckms.get(0.9), errorBoundsNormalDistribution(0.9, 0.001, normalDistribution));
      -        assertEquals(p95, ckms.get(0.95), errorBoundsNormalDistribution(0.95, 0.001, normalDistribution));
      -        assertEquals(p99, ckms.get(0.99), errorBoundsNormalDistribution(0.99, 0.001, normalDistribution));
      -
      -        assertTrue("sample size should be below 1000", ckms.samples.size() < 1000);
      +    // give the actual values for the quantiles we test
      +    double p10 = normalDistribution.inverseCumulativeProbability(0.1);
      +    double p90 = normalDistribution.inverseCumulativeProbability(0.9);
      +    double p95 = normalDistribution.inverseCumulativeProbability(0.95);
      +    double p99 = normalDistribution.inverseCumulativeProbability(0.99);
      +
      +    // ε-approximate quantiles relaxes the requirement
      +    // to finding an item with rank between (φ−ε)n and (φ+ε)n.
      +    assertEquals(p10, ckms.get(0.1), errorBoundsNormalDistribution(0.1, 0.001, normalDistribution));
      +    assertEquals(mean, ckms.get(0.5), errorBoundsNormalDistribution(0.5, 0.01, normalDistribution));
      +    assertEquals(p90, ckms.get(0.9), errorBoundsNormalDistribution(0.9, 0.001, normalDistribution));
      +    assertEquals(
      +        p95, ckms.get(0.95), errorBoundsNormalDistribution(0.95, 0.001, normalDistribution));
      +    assertEquals(
      +        p99, ckms.get(0.99), errorBoundsNormalDistribution(0.99, 0.001, normalDistribution));
      +
      +    assertTrue("sample size should be below 1000", ckms.samples.size() < 1000);
      +  }
      +
      +  double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) {
      +    // (φ+ε)n
      +    double upperBound = nd.inverseCumulativeProbability(p + epsilon);
      +    // (φ−ε)n
      +    double lowerBound = nd.inverseCumulativeProbability(p - epsilon);
      +    // subtract and divide by 2, assuming that the increase is linear in this small epsilon.
      +    return Math.abs(upperBound - lowerBound) / 2;
      +  }
      +
      +  @Test
      +  public void testIllegalArgumentException() {
      +    try {
      +      new Quantile(-1, 0);
      +    } catch (IllegalArgumentException e) {
      +      assertEquals("Quantile must be between 0 and 1", e.getMessage());
      +    } catch (Exception e) {
      +      fail("Wrong exception thrown" + e);
           }
      -
      -    double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) {
      -        //(φ+ε)n
      -        double upperBound = nd.inverseCumulativeProbability(p + epsilon);
      -        //(φ−ε)n
      -        double lowerBound = nd.inverseCumulativeProbability(p - epsilon);
      -        // subtract and divide by 2, assuming that the increase is linear in this small epsilon.
      -        return Math.abs(upperBound - lowerBound) / 2;
      +    try {
      +      new Quantile(0.95, 2);
      +    } catch (IllegalArgumentException e) {
      +      assertEquals("Epsilon must be between 0 and 1", e.getMessage());
      +    } catch (Exception e) {
      +      fail("Wrong exception thrown" + e);
           }
      +  }
       
      -    @Test
      -    public void testIllegalArgumentException() {
      -        try {
      -            new Quantile(-1, 0);
      -        } catch (IllegalArgumentException e) {
      -            assertEquals("Quantile must be between 0 and 1", e.getMessage());
      -        } catch (Exception e) {
      -            fail("Wrong exception thrown" + e);
      -        }
      -        try {
      -            new Quantile(0.95, 2);
      -        } catch (IllegalArgumentException e) {
      -            assertEquals("Epsilon must be between 0 and 1", e.getMessage());
      -        } catch (Exception e) {
      -            fail("Wrong exception thrown" + e);
      -        }
      +  private List shuffledValues(int n, Random random) {
      +    List result = new ArrayList(n);
      +    for (int i = 0; i < n; i++) {
      +      result.add(i + 1.0);
           }
      -
      -    private List shuffledValues(int n, Random random) {
      -        List result = new ArrayList(n);
      -        for (int i=0; i= lowerBound && actual <= upperBound;
      +      if (!ok) {
               for (CKMSQuantiles.Sample sample : ckms.samples) {
      -            String msg = "invalid sample " + sample + ": count=" + ckms.n + " r=" + r + " f(r)=" + ckms.f(r);
      -            assertTrue(msg, sample.g + sample.delta <= ckms.f(r));
      -            assertTrue("Samples not ordered. Keep in mind that insertBatch() takes a sorted array as parameter.", prev <= sample.value);
      -            prev = sample.value;
      -            r += sample.g;
      -        }
      -        assertEquals("the sum of all g's must be the total number of observations", r, ckms.n);
      -    }
      -
      -    /**
      -     * The values that we insert in these tests are always the numbers from 1 to n, in random order.
      -     * So we can trivially calculate the range of acceptable results for each quantile.
      -     * We check if the value returned by get() is within the range of acceptable results.
      -     */
      -    private void validateResults(CKMSQuantiles ckms) {
      -        for (Quantile q : ckms.quantiles) {
      -            double actual = ckms.get(q.quantile);
      -            double lowerBound, upperBound;
      -            if (q.quantile == 0) {
      -                lowerBound = 1;
      -                upperBound = 1;
      -            } else if (q.quantile == 1) {
      -                lowerBound = ckms.n;
      -                upperBound = ckms.n;
      -            } else {
      -                lowerBound = Math.floor(ckms.n * (q.quantile - 2 * q.epsilon));
      -                upperBound = Math.ceil(ckms.n * (q.quantile + 2 * q.epsilon));
      -            }
      -            boolean ok = actual >= lowerBound && actual <= upperBound;
      -            if (!ok) {
      -                for (CKMSQuantiles.Sample sample : ckms.samples) {
      -                    System.err.println(sample);
      -                }
      -            }
      -            String errorMessage = q + ": " + actual + " not in [" + lowerBound + ", " + upperBound + "], n=" + ckms.n + ", " +  q.quantile + "*" + ckms.n + "=" + (q.quantile*ckms.n);
      -            assertTrue(errorMessage, ok);
      +          System.err.println(sample);
               }
      +      }
      +      String errorMessage =
      +          q
      +              + ": "
      +              + actual
      +              + " not in ["
      +              + lowerBound
      +              + ", "
      +              + upperBound
      +              + "], n="
      +              + ckms.n
      +              + ", "
      +              + q.quantile
      +              + "*"
      +              + ckms.n
      +              + "="
      +              + (q.quantile * ckms.n);
      +      assertTrue(errorMessage, ok);
           }
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      index 7be2a3869..435c5b8fe 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      @@ -1,15 +1,20 @@
       package io.prometheus.metrics.core.metrics;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
      +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      +import static org.junit.Assert.assertEquals;
      +import static org.junit.rules.ExpectedException.none;
      +
      +import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
       import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter;
       import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
      -import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
      -import io.prometheus.metrics.tracer.common.SpanContext;
      -import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.Exemplar;
       import io.prometheus.metrics.model.snapshots.Labels;
       import io.prometheus.metrics.model.snapshots.Unit;
      +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
      +import io.prometheus.metrics.tracer.common.SpanContext;
      +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
      +import java.util.Iterator;
       import org.junit.After;
       import org.junit.Assert;
       import org.junit.Before;
      @@ -17,302 +22,293 @@
       import org.junit.Test;
       import org.junit.rules.ExpectedException;
       
      -import java.util.Iterator;
      -
      -import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      -import static org.junit.Assert.assertEquals;
      -import static org.junit.rules.ExpectedException.none;
      -
       public class CounterTest {
       
      -    Counter noLabels;
      -    Counter labels;
      -    private static final long exemplarSampleIntervalMillis = 10;
      -    private static final long exemplarMinAgeMillis = 100;
      -    SpanContext origSpanContext;
      -
      -    @Rule
      -    public final ExpectedException thrown = none();
      -
      -    @Before
      -    public void setUp() throws NoSuchFieldException, IllegalAccessException {
      -        noLabels = Counter.builder().name("nolabels").build();
      -        labels = Counter.builder().name("labels")
      -                .help("help")
      -                .unit(Unit.SECONDS)
      -                .labelNames("l")
      -                .build();
      -        origSpanContext = SpanContextSupplier.getSpanContext();
      -        ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(noLabels, exemplarSampleIntervalMillis);
      -        ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(noLabels, exemplarMinAgeMillis);
      -        ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(labels, exemplarSampleIntervalMillis);
      -        ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(labels, exemplarMinAgeMillis);
      -    }
      -
      -    @After
      -    public void tearDown() {
      -        SpanContextSupplier.setSpanContext(origSpanContext);
      -    }
      -
      -    private CounterSnapshot.CounterDataPointSnapshot getData(Counter counter, String... labels) {
      -        return counter.collect().getDataPoints().stream()
      -                .filter(d -> d.getLabels().equals(Labels.of(labels)))
      -                .findAny()
      -                .orElseThrow(() -> new RuntimeException("counter with labels " + labels + " not found"));
      -    }
      -
      -    private double getValue(Counter counter, String... labels) {
      -        return getData(counter, labels).getValue();
      -    }
      -
      -
      -    private int getNumberOfLabels(Counter counter) {
      -        return ((CounterSnapshot) counter.collect()).getDataPoints().size();
      -    }
      -
      -    @Test
      -    public void testIncrement() {
      -        noLabels.inc();
      -        assertEquals(1.0, getValue(noLabels), .001);
      -        noLabels.inc(2);
      -        assertEquals(3.0, getValue(noLabels), .001);
      -        noLabels.labelValues().inc(4);
      -        assertEquals(7.0, getValue(noLabels), .001);
      -        noLabels.labelValues().inc();
      -        assertEquals(8.0, getValue(noLabels), .001);
      -    }
      -
      -    @Test
      -    public void testNegativeIncrementFails() {
      -        thrown.expect(IllegalArgumentException.class);
      -        thrown.expectMessage("Negative increment -1 is illegal for Counter metrics.");
      -        noLabels.inc(-1);
      -    }
      -
      -    @Test
      -    public void testEmptyCountersHaveNoLabels() {
      -        assertEquals(1, getNumberOfLabels(noLabels));
      -        assertEquals(0, getNumberOfLabels(labels));
      -    }
      -
      -    @Test
      -    public void testLabels() {
      -        assertEquals(0, getNumberOfLabels(labels));
      -        labels.labelValues("a").inc();
      -        assertEquals(1, getNumberOfLabels(labels));
      -        assertEquals(1.0, getValue(labels, "l", "a"), .001);
      -        labels.labelValues("b").inc(3);
      -        assertEquals(2, getNumberOfLabels(labels));
      -        assertEquals(1.0, getValue(labels, "l", "a"), .001);
      -        assertEquals(3.0, getValue(labels, "l", "b"), .001);
      +  Counter noLabels;
      +  Counter labels;
      +  private static final long exemplarSampleIntervalMillis = 10;
      +  private static final long exemplarMinAgeMillis = 100;
      +  SpanContext origSpanContext;
      +
      +  @Rule public final ExpectedException thrown = none();
      +
      +  @Before
      +  public void setUp() throws NoSuchFieldException, IllegalAccessException {
      +    noLabels = Counter.builder().name("nolabels").build();
      +    labels =
      +        Counter.builder().name("labels").help("help").unit(Unit.SECONDS).labelNames("l").build();
      +    origSpanContext = SpanContextSupplier.getSpanContext();
      +    ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(noLabels, exemplarSampleIntervalMillis);
      +    ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(noLabels, exemplarMinAgeMillis);
      +    ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(labels, exemplarSampleIntervalMillis);
      +    ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(labels, exemplarMinAgeMillis);
      +  }
      +
      +  @After
      +  public void tearDown() {
      +    SpanContextSupplier.setSpanContext(origSpanContext);
      +  }
      +
      +  private CounterSnapshot.CounterDataPointSnapshot getData(Counter counter, String... labels) {
      +    return counter.collect().getDataPoints().stream()
      +        .filter(d -> d.getLabels().equals(Labels.of(labels)))
      +        .findAny()
      +        .orElseThrow(() -> new RuntimeException("counter with labels " + labels + " not found"));
      +  }
      +
      +  private double getValue(Counter counter, String... labels) {
      +    return getData(counter, labels).getValue();
      +  }
      +
      +  private int getNumberOfLabels(Counter counter) {
      +    return ((CounterSnapshot) counter.collect()).getDataPoints().size();
      +  }
      +
      +  @Test
      +  public void testIncrement() {
      +    noLabels.inc();
      +    assertEquals(1.0, getValue(noLabels), .001);
      +    noLabels.inc(2);
      +    assertEquals(3.0, getValue(noLabels), .001);
      +    noLabels.labelValues().inc(4);
      +    assertEquals(7.0, getValue(noLabels), .001);
      +    noLabels.labelValues().inc();
      +    assertEquals(8.0, getValue(noLabels), .001);
      +  }
      +
      +  @Test
      +  public void testNegativeIncrementFails() {
      +    thrown.expect(IllegalArgumentException.class);
      +    thrown.expectMessage("Negative increment -1 is illegal for Counter metrics.");
      +    noLabels.inc(-1);
      +  }
      +
      +  @Test
      +  public void testEmptyCountersHaveNoLabels() {
      +    assertEquals(1, getNumberOfLabels(noLabels));
      +    assertEquals(0, getNumberOfLabels(labels));
      +  }
      +
      +  @Test
      +  public void testLabels() {
      +    assertEquals(0, getNumberOfLabels(labels));
      +    labels.labelValues("a").inc();
      +    assertEquals(1, getNumberOfLabels(labels));
      +    assertEquals(1.0, getValue(labels, "l", "a"), .001);
      +    labels.labelValues("b").inc(3);
      +    assertEquals(2, getNumberOfLabels(labels));
      +    assertEquals(1.0, getValue(labels, "l", "a"), .001);
      +    assertEquals(3.0, getValue(labels, "l", "b"), .001);
      +  }
      +
      +  @Test
      +  public void testTotalStrippedFromName() {
      +    for (String name :
      +        new String[] {
      +          "my_counter_total", "my.counter.total",
      +          "my_counter_seconds_total", "my.counter.seconds.total",
      +          "my_counter", "my.counter",
      +          "my_counter_seconds", "my.counter.seconds"
      +        }) {
      +      Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build();
      +      Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect());
      +      assertEquals(
      +          "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }",
      +          TextFormat.printer().shortDebugString(protobufData));
           }
      +  }
       
      -    @Test
      -    public void testTotalStrippedFromName() {
      -        for (String name : new String[]{
      -                "my_counter_total", "my.counter.total",
      -                "my_counter_seconds_total", "my.counter.seconds.total",
      -                "my_counter", "my.counter",
      -                "my_counter_seconds", "my.counter.seconds"}) {
      -            Counter counter = Counter.builder()
      -                    .name(name)
      -                    .unit(Unit.SECONDS)
      -                    .build();
      -            Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect());
      -            assertEquals("name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", TextFormat.printer().shortDebugString(protobufData));
      -        }
      -    }
      -
      -    @Test
      -    public void testSnapshotComplete() {
      -        long before = System.currentTimeMillis();
      -        Counter counter = Counter.builder()
      -                .name("test_seconds_total")
      -                .unit(Unit.SECONDS)
      -                .help("help message")
      -                .constLabels(Labels.of("const1name", "const1value", "const2name", "const2value"))
      -                .labelNames("path", "status")
      -                .build();
      -        counter.labelValues("/", "200").inc(2);
      -        counter.labelValues("/", "500").inc();
      -        CounterSnapshot snapshot = (CounterSnapshot) counter.collect();
      -        Assert.assertEquals("test_seconds", snapshot.getMetadata().getName());
      -        Assert.assertEquals("seconds", snapshot.getMetadata().getUnit().toString());
      -        Assert.assertEquals("help message", snapshot.getMetadata().getHelp());
      -        Assert.assertEquals(2, snapshot.getDataPoints().size());
      -        Iterator iter = snapshot.getDataPoints().iterator();
      -        // data is ordered by labels, so 200 comes before 500
      -        CounterSnapshot.CounterDataPointSnapshot data = iter.next();
      -        Assert.assertEquals(Labels.of("const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"), data.getLabels());
      -        Assert.assertEquals(2, data.getValue(), 0.0001);
      -        Assert.assertTrue(data.getCreatedTimestampMillis() >= before);
      -        Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis());
      -        // 500
      -        data = iter.next();
      -        Assert.assertEquals(Labels.of("const1name", "const1value", "const2name", "const2value", "path", "/", "status", "500"), data.getLabels());
      -        Assert.assertEquals(1, data.getValue(), 0.0001);
      -        Assert.assertTrue(data.getCreatedTimestampMillis() >= before);
      -        Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis());
      -    }
      -
      -    @Test
      -    public void testIncWithExemplar() throws Exception {
      -        noLabels.incWithExemplar(Labels.of("key", "value"));
      -        assertExemplar(noLabels, 1.0, "key", "value");
      -
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      -
      -        noLabels.incWithExemplar(Labels.EMPTY);
      -        assertExemplar(noLabels, 1.0);
      -
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      -
      -        noLabels.incWithExemplar(3, Labels.of("key1", "value1", "key2", "value2"));
      -        assertExemplar(noLabels, 3, "key1", "value1", "key2", "value2");
      -    }
      -
      -    private void assertExemplar(Counter counter, double value, String... labels) {
      -        Exemplar exemplar = getData(counter).getExemplar();
      -        Assert.assertEquals(value, exemplar.getValue(), 0.0001);
      -        assertEquals(Labels.of(labels), exemplar.getLabels());
      -    }
      -
      -    @Test
      -    public void testExemplarSampler() throws Exception {
      -        final Exemplar exemplar1 = Exemplar.builder()
      -                .value(2.0)
      -                .traceId("abc")
      -                .spanId("123")
      -                .build();
      -        final Exemplar exemplar2 = Exemplar.builder()
      -                .value(1.0)
      -                .traceId("def")
      -                .spanId("456")
      -                .build();
      -        final Exemplar exemplar3 = Exemplar.builder()
      -                .value(1.0)
      -                .traceId("123")
      -                .spanId("abc")
      -                .build();
      -        final Exemplar customExemplar = Exemplar.builder()
      -                .value(1.0)
      -                .traceId("bab")
      -                .spanId("cdc")
      -                .labels(Labels.of("test", "test"))
      -                .build();
      -        SpanContext spanContext = new SpanContext() {
      -            private int callNumber = 0;
      -
      -            @Override
      -            public String getCurrentTraceId() {
      -                switch (callNumber) {
      -                    case 1:
      -                        return "abc";
      -                    case 3:
      -                        return "def";
      -                    case 4:
      -                        return "123";
      -                    case 5:
      -                        return "bab";
      -                    default:
      -                        throw new RuntimeException("unexpected call");
      -                }
      +  @Test
      +  public void testSnapshotComplete() {
      +    long before = System.currentTimeMillis();
      +    Counter counter =
      +        Counter.builder()
      +            .name("test_seconds_total")
      +            .unit(Unit.SECONDS)
      +            .help("help message")
      +            .constLabels(Labels.of("const1name", "const1value", "const2name", "const2value"))
      +            .labelNames("path", "status")
      +            .build();
      +    counter.labelValues("/", "200").inc(2);
      +    counter.labelValues("/", "500").inc();
      +    CounterSnapshot snapshot = (CounterSnapshot) counter.collect();
      +    Assert.assertEquals("test_seconds", snapshot.getMetadata().getName());
      +    Assert.assertEquals("seconds", snapshot.getMetadata().getUnit().toString());
      +    Assert.assertEquals("help message", snapshot.getMetadata().getHelp());
      +    Assert.assertEquals(2, snapshot.getDataPoints().size());
      +    Iterator iter = snapshot.getDataPoints().iterator();
      +    // data is ordered by labels, so 200 comes before 500
      +    CounterSnapshot.CounterDataPointSnapshot data = iter.next();
      +    Assert.assertEquals(
      +        Labels.of(
      +            "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"),
      +        data.getLabels());
      +    Assert.assertEquals(2, data.getValue(), 0.0001);
      +    Assert.assertTrue(data.getCreatedTimestampMillis() >= before);
      +    Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis());
      +    // 500
      +    data = iter.next();
      +    Assert.assertEquals(
      +        Labels.of(
      +            "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "500"),
      +        data.getLabels());
      +    Assert.assertEquals(1, data.getValue(), 0.0001);
      +    Assert.assertTrue(data.getCreatedTimestampMillis() >= before);
      +    Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis());
      +  }
      +
      +  @Test
      +  public void testIncWithExemplar() throws Exception {
      +    noLabels.incWithExemplar(Labels.of("key", "value"));
      +    assertExemplar(noLabels, 1.0, "key", "value");
      +
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +
      +    noLabels.incWithExemplar(Labels.EMPTY);
      +    assertExemplar(noLabels, 1.0);
      +
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +
      +    noLabels.incWithExemplar(3, Labels.of("key1", "value1", "key2", "value2"));
      +    assertExemplar(noLabels, 3, "key1", "value1", "key2", "value2");
      +  }
      +
      +  private void assertExemplar(Counter counter, double value, String... labels) {
      +    Exemplar exemplar = getData(counter).getExemplar();
      +    Assert.assertEquals(value, exemplar.getValue(), 0.0001);
      +    assertEquals(Labels.of(labels), exemplar.getLabels());
      +  }
      +
      +  @Test
      +  public void testExemplarSampler() throws Exception {
      +    final Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build();
      +    final Exemplar exemplar2 = Exemplar.builder().value(1.0).traceId("def").spanId("456").build();
      +    final Exemplar exemplar3 = Exemplar.builder().value(1.0).traceId("123").spanId("abc").build();
      +    final Exemplar customExemplar =
      +        Exemplar.builder()
      +            .value(1.0)
      +            .traceId("bab")
      +            .spanId("cdc")
      +            .labels(Labels.of("test", "test"))
      +            .build();
      +    SpanContext spanContext =
      +        new SpanContext() {
      +          private int callNumber = 0;
      +
      +          @Override
      +          public String getCurrentTraceId() {
      +            switch (callNumber) {
      +              case 1:
      +                return "abc";
      +              case 3:
      +                return "def";
      +              case 4:
      +                return "123";
      +              case 5:
      +                return "bab";
      +              default:
      +                throw new RuntimeException("unexpected call");
                   }
      -
      -            @Override
      -            public String getCurrentSpanId() {
      -                switch (callNumber) {
      -                    case 1:
      -                        return "123";
      -                    case 3:
      -                        return "456";
      -                    case 4:
      -                        return "abc";
      -                    case 5:
      -                        return "cdc";
      -                    default:
      -                        throw new RuntimeException("unexpected call");
      -                }
      +          }
      +
      +          @Override
      +          public String getCurrentSpanId() {
      +            switch (callNumber) {
      +              case 1:
      +                return "123";
      +              case 3:
      +                return "456";
      +              case 4:
      +                return "abc";
      +              case 5:
      +                return "cdc";
      +              default:
      +                throw new RuntimeException("unexpected call");
                   }
      +          }
       
      -            @Override
      -            public boolean isCurrentSpanSampled() {
      -                callNumber++;
      -                if (callNumber == 2) {
      -                    return false;
      -                }
      -                return true;
      +          @Override
      +          public boolean isCurrentSpanSampled() {
      +            callNumber++;
      +            if (callNumber == 2) {
      +              return false;
                   }
      +            return true;
      +          }
       
      -            @Override
      -            public void markCurrentSpanAsExemplar() {
      -            }
      +          @Override
      +          public void markCurrentSpanAsExemplar() {}
               };
      -        Counter counter = Counter.builder()
      -                .name("count_total")
      -                .build();
      +    Counter counter = Counter.builder().name("count_total").build();
       
      -        SpanContextSupplier.setSpanContext(spanContext);
      -        ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(counter, exemplarMinAgeMillis);
      -        ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(counter, exemplarSampleIntervalMillis);
      +    SpanContextSupplier.setSpanContext(spanContext);
      +    ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(counter, exemplarMinAgeMillis);
      +    ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(counter, exemplarSampleIntervalMillis);
       
      -        counter.inc(2.0);
      -        assertExemplarEquals(exemplar1, getData(counter).getExemplar());
      +    counter.inc(2.0);
      +    assertExemplarEquals(exemplar1, getData(counter).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        counter.inc(3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called
      -        assertExemplarEquals(exemplar1, getData(counter).getExemplar());
      +    counter.inc(
      +        3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called
      +    assertExemplarEquals(exemplar1, getData(counter).getExemplar());
       
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
       
      -        counter.inc(2.0); // 2nd call: isSampled() returns false -> not sampled
      -        assertExemplarEquals(exemplar1, getData(counter).getExemplar());
      +    counter.inc(2.0); // 2nd call: isSampled() returns false -> not sampled
      +    assertExemplarEquals(exemplar1, getData(counter).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        counter.inc(1.0); // sampled
      -        assertExemplarEquals(exemplar2, getData(counter).getExemplar());
      +    counter.inc(1.0); // sampled
      +    assertExemplarEquals(exemplar2, getData(counter).getExemplar());
       
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
       
      -        counter.inc(1.0); // sampled
      -        assertExemplarEquals(exemplar3, getData(counter).getExemplar());
      +    counter.inc(1.0); // sampled
      +    assertExemplarEquals(exemplar3, getData(counter).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        counter.incWithExemplar(Labels.of("test", "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached min age yet
      -        assertExemplarEquals(customExemplar, getData(counter).getExemplar());
      -    }
      -
      -    @Test
      -    public void testExemplarSamplerDisabled() {
      -        Counter counter = Counter.builder()
      -                //.withExemplarSampler((inc, prev) -> {throw new RuntimeException("unexpected call to exemplar sampler");})
      -                .name("count_total")
      -                .withoutExemplars()
      -                .build();
      -        counter.incWithExemplar(3.0, Labels.of("a", "b"));
      -        Assert.assertNull(getData(counter).getExemplar());
      -        counter.inc(2.0);
      -        Assert.assertNull(getData(counter).getExemplar());
      -    }
      +    counter.incWithExemplar(
      +        Labels.of(
      +            "test",
      +            "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached
      +    // min age yet
      +    assertExemplarEquals(customExemplar, getData(counter).getExemplar());
      +  }
       
      -    @Test(expected = IllegalArgumentException.class)
      -    public void testConstLabelsFirst() {
      +  @Test
      +  public void testExemplarSamplerDisabled() {
      +    Counter counter =
               Counter.builder()
      -                .name("test_total")
      -                .constLabels(Labels.of("const_a", "const_b"))
      -                .labelNames("const.a")
      -                .build();
      -    }
      -
      -    @Test(expected = IllegalArgumentException.class)
      -    public void testConstLabelsSecond() {
      -        Counter.builder()
      -                .name("test_total")
      -                .labelNames("const.a")
      -                .constLabels(Labels.of("const_a", "const_b"))
      -                .build();
      -    }
      +            // .withExemplarSampler((inc, prev) -> {throw new RuntimeException("unexpected call to
      +            // exemplar sampler");})
      +            .name("count_total")
      +            .withoutExemplars()
      +            .build();
      +    counter.incWithExemplar(3.0, Labels.of("a", "b"));
      +    Assert.assertNull(getData(counter).getExemplar());
      +    counter.inc(2.0);
      +    Assert.assertNull(getData(counter).getExemplar());
      +  }
      +
      +  @Test(expected = IllegalArgumentException.class)
      +  public void testConstLabelsFirst() {
      +    Counter.builder()
      +        .name("test_total")
      +        .constLabels(Labels.of("const_a", "const_b"))
      +        .labelNames("const.a")
      +        .build();
      +  }
      +
      +  @Test(expected = IllegalArgumentException.class)
      +  public void testConstLabelsSecond() {
      +    Counter.builder()
      +        .name("test_total")
      +        .labelNames("const.a")
      +        .constLabels(Labels.of("const_a", "const_b"))
      +        .build();
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
      index 002a44545..678158cbd 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java
      @@ -1,222 +1,213 @@
       package io.prometheus.metrics.core.metrics;
       
      +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      +import static org.junit.Assert.assertEquals;
      +
      +import io.prometheus.metrics.core.datapoints.Timer;
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
      -import io.prometheus.metrics.tracer.common.SpanContext;
      -import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import io.prometheus.metrics.model.snapshots.Exemplar;
       import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
       import io.prometheus.metrics.model.snapshots.Labels;
      -import io.prometheus.metrics.core.datapoints.Timer;
      +import io.prometheus.metrics.tracer.common.SpanContext;
      +import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
       import org.junit.After;
       import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       
      -import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      -import static org.junit.Assert.assertEquals;
      -
       public class GaugeTest {
       
      -    private static final long exemplarSampleIntervalMillis = 10;
      -    private static final long exemplarMinAgeMillis = 100;
      -
      -    private Gauge noLabels, labels;
      -
      -    private SpanContext origSpanContext;
      -
      -    @Before
      -    public void setUp() {
      -        noLabels = Gauge.builder().name("nolabels").build();
      -        labels = Gauge.builder().name("labels").labelNames("l").build();
      -        origSpanContext = SpanContextSupplier.getSpanContext();
      -    }
      -
      -    @After
      -    public void tearDown() {
      -        SpanContextSupplier.setSpanContext(origSpanContext);
      -    }
      -
      -    private GaugeSnapshot.GaugeDataPointSnapshot getData(Gauge gauge, String... labels) {
      -        return ((GaugeSnapshot) gauge.collect()).getDataPoints().stream()
      -                .filter(data -> data.getLabels().equals(Labels.of(labels)))
      -                .findAny()
      -                .orElseThrow(RuntimeException::new);
      +  private static final long exemplarSampleIntervalMillis = 10;
      +  private static final long exemplarMinAgeMillis = 100;
      +
      +  private Gauge noLabels, labels;
      +
      +  private SpanContext origSpanContext;
      +
      +  @Before
      +  public void setUp() {
      +    noLabels = Gauge.builder().name("nolabels").build();
      +    labels = Gauge.builder().name("labels").labelNames("l").build();
      +    origSpanContext = SpanContextSupplier.getSpanContext();
      +  }
      +
      +  @After
      +  public void tearDown() {
      +    SpanContextSupplier.setSpanContext(origSpanContext);
      +  }
      +
      +  private GaugeSnapshot.GaugeDataPointSnapshot getData(Gauge gauge, String... labels) {
      +    return ((GaugeSnapshot) gauge.collect())
      +        .getDataPoints().stream()
      +            .filter(data -> data.getLabels().equals(Labels.of(labels)))
      +            .findAny()
      +            .orElseThrow(RuntimeException::new);
      +  }
      +
      +  private double getValue(Gauge gauge, String... labels) {
      +    return getData(gauge, labels).getValue();
      +  }
      +
      +  @Test
      +  public void testIncrement() {
      +    noLabels.inc();
      +    assertEquals(1.0, getValue(noLabels), .001);
      +    noLabels.inc(2);
      +    assertEquals(3.0, getValue(noLabels), .001);
      +    noLabels.inc(4);
      +    assertEquals(7.0, getValue(noLabels), .001);
      +    noLabels.inc();
      +    assertEquals(8.0, getValue(noLabels), .001);
      +  }
      +
      +  @Test
      +  public void testDecrement() {
      +    noLabels.dec();
      +    assertEquals(-1.0, getValue(noLabels), .001);
      +    noLabels.dec(2);
      +    assertEquals(-3.0, getValue(noLabels), .001);
      +    noLabels.dec(4);
      +    assertEquals(-7.0, getValue(noLabels), .001);
      +    noLabels.dec();
      +    assertEquals(-8.0, getValue(noLabels), .001);
      +  }
      +
      +  @Test
      +  public void testSet() {
      +    noLabels.set(42);
      +    assertEquals(42, getValue(noLabels), .001);
      +    noLabels.set(7);
      +    assertEquals(7.0, getValue(noLabels), .001);
      +  }
      +
      +  @Test
      +  public void testTimer() throws InterruptedException {
      +    try (Timer timer = noLabels.startTimer()) {
      +      Thread.sleep(12);
           }
      -
      -    private double getValue(Gauge gauge, String... labels) {
      -        return getData(gauge, labels).getValue();
      -    }
      -
      -    @Test
      -    public void testIncrement() {
      -        noLabels.inc();
      -        assertEquals(1.0, getValue(noLabels), .001);
      -        noLabels.inc(2);
      -        assertEquals(3.0, getValue(noLabels), .001);
      -        noLabels.inc(4);
      -        assertEquals(7.0, getValue(noLabels), .001);
      -        noLabels.inc();
      -        assertEquals(8.0, getValue(noLabels), .001);
      -    }
      -
      -    @Test
      -    public void testDecrement() {
      -        noLabels.dec();
      -        assertEquals(-1.0, getValue(noLabels), .001);
      -        noLabels.dec(2);
      -        assertEquals(-3.0, getValue(noLabels), .001);
      -        noLabels.dec(4);
      -        assertEquals(-7.0, getValue(noLabels), .001);
      -        noLabels.dec();
      -        assertEquals(-8.0, getValue(noLabels), .001);
      -    }
      -
      -    @Test
      -    public void testSet() {
      -        noLabels.set(42);
      -        assertEquals(42, getValue(noLabels), .001);
      -        noLabels.set(7);
      -        assertEquals(7.0, getValue(noLabels), .001);
      -    }
      -
      -    @Test
      -    public void testTimer() throws InterruptedException {
      -        try (Timer timer = noLabels.startTimer()) {
      -            Thread.sleep(12);
      -        }
      -        assertEquals(0.012, getValue(noLabels), 0.005); // 5ms delta should be enough so this isn't flaky
      -    }
      -
      -    @Test
      -    public void noLabelsDefaultZeroValue() {
      -        assertEquals(0.0, getValue(noLabels), .001);
      -    }
      -
      -    @Test
      -    public void testLabels() {
      -        labels.labelValues("a").inc();
      -        labels.labelValues("b").inc(3);
      -        assertEquals(1.0, getValue(labels, "l", "a"), .001);
      -        assertEquals(3.0, getValue(labels, "l", "b"), .001);
      -    }
      -
      -    @Test
      -    public void testExemplarSampler() throws Exception {
      -        final Exemplar exemplar1 = Exemplar.builder()
      -                .value(2.0)
      -                .traceId("abc")
      -                .spanId("123")
      -                .build();
      -        final Exemplar exemplar2 = Exemplar.builder()
      -                .value(6.5)
      -                .traceId("def")
      -                .spanId("456")
      -                .build();
      -        final Exemplar exemplar3 = Exemplar.builder()
      -                .value(7.0)
      -                .traceId("123")
      -                .spanId("abc")
      -                .build();
      -        final Exemplar customExemplar = Exemplar.builder()
      -                .value(8.0)
      -                .traceId("bab")
      -                .spanId("cdc")
      -                .labels(Labels.of("test", "test"))
      -                .build();
      -        SpanContext spanContext = new SpanContext() {
      -            private int callNumber = 0;
      -
      -            @Override
      -            public String getCurrentTraceId() {
      -                switch (callNumber) {
      -                    case 1:
      -                        return "abc";
      -                    case 3:
      -                        return "def";
      -                    case 4:
      -                        return "123";
      -                    case 5:
      -                        return "bab";
      -                    default:
      -                        throw new RuntimeException("unexpected call");
      -                }
      +    assertEquals(
      +        0.012, getValue(noLabels), 0.005); // 5ms delta should be enough so this isn't flaky
      +  }
      +
      +  @Test
      +  public void noLabelsDefaultZeroValue() {
      +    assertEquals(0.0, getValue(noLabels), .001);
      +  }
      +
      +  @Test
      +  public void testLabels() {
      +    labels.labelValues("a").inc();
      +    labels.labelValues("b").inc(3);
      +    assertEquals(1.0, getValue(labels, "l", "a"), .001);
      +    assertEquals(3.0, getValue(labels, "l", "b"), .001);
      +  }
      +
      +  @Test
      +  public void testExemplarSampler() throws Exception {
      +    final Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build();
      +    final Exemplar exemplar2 = Exemplar.builder().value(6.5).traceId("def").spanId("456").build();
      +    final Exemplar exemplar3 = Exemplar.builder().value(7.0).traceId("123").spanId("abc").build();
      +    final Exemplar customExemplar =
      +        Exemplar.builder()
      +            .value(8.0)
      +            .traceId("bab")
      +            .spanId("cdc")
      +            .labels(Labels.of("test", "test"))
      +            .build();
      +    SpanContext spanContext =
      +        new SpanContext() {
      +          private int callNumber = 0;
      +
      +          @Override
      +          public String getCurrentTraceId() {
      +            switch (callNumber) {
      +              case 1:
      +                return "abc";
      +              case 3:
      +                return "def";
      +              case 4:
      +                return "123";
      +              case 5:
      +                return "bab";
      +              default:
      +                throw new RuntimeException("unexpected call");
                   }
      -
      -            @Override
      -            public String getCurrentSpanId() {
      -                switch (callNumber) {
      -                    case 1:
      -                        return "123";
      -                    case 3:
      -                        return "456";
      -                    case 4:
      -                        return "abc";
      -                    case 5:
      -                        return "cdc";
      -                    default:
      -                        throw new RuntimeException("unexpected call");
      -                }
      +          }
      +
      +          @Override
      +          public String getCurrentSpanId() {
      +            switch (callNumber) {
      +              case 1:
      +                return "123";
      +              case 3:
      +                return "456";
      +              case 4:
      +                return "abc";
      +              case 5:
      +                return "cdc";
      +              default:
      +                throw new RuntimeException("unexpected call");
                   }
      +          }
       
      -            @Override
      -            public boolean isCurrentSpanSampled() {
      -                callNumber++;
      -                if (callNumber == 2) {
      -                    return false;
      -                }
      -                return true;
      +          @Override
      +          public boolean isCurrentSpanSampled() {
      +            callNumber++;
      +            if (callNumber == 2) {
      +              return false;
                   }
      +            return true;
      +          }
       
      -            @Override
      -            public void markCurrentSpanAsExemplar() {
      -            }
      +          @Override
      +          public void markCurrentSpanAsExemplar() {}
               };
      -        Gauge gauge = Gauge.builder()
      -                .name("my_gauge")
      -                .build();
      +    Gauge gauge = Gauge.builder().name("my_gauge").build();
       
      -        ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(gauge, exemplarMinAgeMillis);
      -        ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(gauge, exemplarSampleIntervalMillis);
      -        SpanContextSupplier.setSpanContext(spanContext);
      +    ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(gauge, exemplarMinAgeMillis);
      +    ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(gauge, exemplarSampleIntervalMillis);
      +    SpanContextSupplier.setSpanContext(spanContext);
       
      -        gauge.inc(2.0);
      -        assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
      +    gauge.inc(2.0);
      +    assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        gauge.inc(3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called
      -        assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
      +    gauge.inc(
      +        3.0); // min age not reached -> keep the previous exemplar, exemplar sampler not called
      +    assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
       
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
       
      -        gauge.inc(2.0); // 2nd call: isSampled() returns false -> not sampled
      -        assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
      +    gauge.inc(2.0); // 2nd call: isSampled() returns false -> not sampled
      +    assertExemplarEquals(exemplar1, getData(gauge).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        gauge.dec(0.5); // sampled
      -        assertExemplarEquals(exemplar2, getData(gauge).getExemplar());
      +    gauge.dec(0.5); // sampled
      +    assertExemplarEquals(exemplar2, getData(gauge).getExemplar());
       
      -        Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(exemplarMinAgeMillis + 2 * exemplarSampleIntervalMillis);
       
      -        gauge.set(7.0); // sampled
      -        assertExemplarEquals(exemplar3, getData(gauge).getExemplar());
      +    gauge.set(7.0); // sampled
      +    assertExemplarEquals(exemplar3, getData(gauge).getExemplar());
       
      -        Thread.sleep(2 * exemplarSampleIntervalMillis);
      +    Thread.sleep(2 * exemplarSampleIntervalMillis);
       
      -        gauge.incWithExemplar(Labels.of("test", "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached min age yet
      -        assertExemplarEquals(customExemplar, getData(gauge).getExemplar());
      -    }
      +    gauge.incWithExemplar(
      +        Labels.of(
      +            "test",
      +            "test")); // custom exemplar sampled even though the automatic exemplar hasn't reached
      +    // min age yet
      +    assertExemplarEquals(customExemplar, getData(gauge).getExemplar());
      +  }
       
      -    @Test
      -    public void testExemplarSamplerDisabled() {
      -        Gauge gauge = Gauge.builder()
      -                .name("test")
      -                .withoutExemplars()
      -                .build();
      -        gauge.setWithExemplar(3.0, Labels.of("a", "b"));
      -        Assert.assertNull(getData(gauge).getExemplar());
      -        gauge.inc(2.0);
      -        Assert.assertNull(getData(gauge).getExemplar());
      -    }
      +  @Test
      +  public void testExemplarSamplerDisabled() {
      +    Gauge gauge = Gauge.builder().name("test").withoutExemplars().build();
      +    gauge.setWithExemplar(3.0, Labels.of("a", "b"));
      +    Assert.assertNull(getData(gauge).getExemplar());
      +    gauge.inc(2.0);
      +    Assert.assertNull(getData(gauge).getExemplar());
      +  }
       }
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      index 8df44b43e..da7da5a89 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      @@ -1,6 +1,9 @@
       package io.prometheus.metrics.core.metrics;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
      +import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      +import static org.junit.Assert.assertEquals;
      +import static org.junit.Assert.assertNull;
      +
       import io.prometheus.metrics.core.datapoints.DistributionDataPoint;
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      @@ -12,13 +15,9 @@
       import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
       import io.prometheus.metrics.model.snapshots.Labels;
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
       import io.prometheus.metrics.tracer.common.SpanContext;
       import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
      -import org.junit.After;
      -import org.junit.Assert;
      -import org.junit.Before;
      -import org.junit.Test;
      -
       import java.io.ByteArrayOutputStream;
       import java.io.IOException;
       import java.lang.reflect.Field;
      @@ -40,1270 +39,1464 @@
       import java.util.concurrent.TimeUnit;
       import java.util.concurrent.TimeoutException;
       import java.util.stream.Collectors;
      -
      -import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
      -import static org.junit.Assert.assertEquals;
      -import static org.junit.Assert.assertNull;
      +import org.junit.After;
      +import org.junit.Assert;
      +import org.junit.Before;
      +import org.junit.Test;
       
       public class HistogramTest {
       
      -    private static final double RESET_DURATION_REACHED = -123.456; // just a random value indicating that we should simulate that the reset duration has been reached
      -
      -    private SpanContext origSpanContext;
      -
      -    @Before
      -    public void setUp() {
      -        origSpanContext = SpanContextSupplier.getSpanContext();
      -    }
      -
      -    @After
      -    public void tearDown() {
      -        SpanContextSupplier.setSpanContext(origSpanContext);
      +  private static final double RESET_DURATION_REACHED =
      +      -123.456; // just a random value indicating that we should simulate that the reset duration
      +  // has been reached
      +
      +  private SpanContext origSpanContext;
      +
      +  @Before
      +  public void setUp() {
      +    origSpanContext = SpanContextSupplier.getSpanContext();
      +  }
      +
      +  @After
      +  public void tearDown() {
      +    SpanContextSupplier.setSpanContext(origSpanContext);
      +  }
      +
      +  /** Mimic the tests in client_golang. */
      +  private static class GolangTestCase {
      +    final String name;
      +    final String expected;
      +    final Histogram histogram;
      +    final double[] observations;
      +
      +    private GolangTestCase(
      +        String name, String expected, Histogram histogram, double... observations) {
      +      this.name = name;
      +      this.expected = expected;
      +      this.histogram = histogram;
      +      this.observations = observations;
           }
       
      -    /**
      -     * Mimic the tests in client_golang.
      -     */
      -    private static class GolangTestCase {
      -        final String name;
      -        final String expected;
      -        final Histogram histogram;
      -        final double[] observations;
      -
      -        private GolangTestCase(String name, String expected, Histogram histogram, double... observations) {
      -            this.name = name;
      -            this.expected = expected;
      -            this.histogram = histogram;
      -            this.observations = observations;
      -        }
      -
      -        private void run() throws NoSuchFieldException, IllegalAccessException {
      -            System.out.println("Running " + name + "...");
      -            for (double observation : observations) {
      -                if (observation == RESET_DURATION_REACHED) {
      -                    Field resetAllowed = Histogram.DataPoint.class.getDeclaredField("resetDurationExpired");
      -                    resetAllowed.setAccessible(true);
      -                    resetAllowed.set(histogram.getNoLabels(), true);
      -                } else {
      -                    histogram.observe(observation);
      -                }
      -            }
      -            Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(histogram.collect());
      -            String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }";
      -            assertEquals("test \"" + name + "\" failed", expectedWithMetadata, TextFormat.printer().shortDebugString(protobufData));
      +    private void run() throws NoSuchFieldException, IllegalAccessException {
      +      System.out.println("Running " + name + "...");
      +      for (double observation : observations) {
      +        if (observation == RESET_DURATION_REACHED) {
      +          Field resetAllowed = Histogram.DataPoint.class.getDeclaredField("resetDurationExpired");
      +          resetAllowed.setAccessible(true);
      +          resetAllowed.set(histogram.getNoLabels(), true);
      +        } else {
      +          histogram.observe(observation);
               }
      +      }
      +      Metrics.MetricFamily protobufData =
      +          new PrometheusProtobufWriter().convert(histogram.collect());
      +      String expectedWithMetadata =
      +          "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }";
      +      assertEquals(
      +          "test \"" + name + "\" failed",
      +          expectedWithMetadata,
      +          TextFormat.printer().shortDebugString(protobufData));
           }
      -
      -    /**
      -     * Test cases copied from histogram_test.go in client_golang.
      -     */
      -    @Test
      -    public void testGolangTests() throws NoSuchFieldException, IllegalAccessException {
      -        GolangTestCase[] testCases = new GolangTestCase[]{
      -                new GolangTestCase("'no sparse buckets' from client_golang",
      -                        "sample_count: 3 " +
      -                                "sample_sum: 6.0 " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.005 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.01 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.025 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.05 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.1 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.25 } " +
      -                                "bucket { cumulative_count: 0 upper_bound: 0.5 } " +
      -                                "bucket { cumulative_count: 1 upper_bound: 1.0 } " +
      -                                "bucket { cumulative_count: 2 upper_bound: 2.5 } " +
      -                                "bucket { cumulative_count: 3 upper_bound: 5.0 } " +
      -                                "bucket { cumulative_count: 3 upper_bound: 10.0 } " +
      -                                "bucket { cumulative_count: 3 upper_bound: Infinity }",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .classicOnly()
      -                                .build(),
      -                        1.0, 2.0, 3.0),
      -                new GolangTestCase("'factor 1.1 results in schema 3' from client_golang",
      -                        "sample_count: 4 " +
      -                                "sample_sum: 6.0 " +
      -                                "schema: 3 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 1 } " +
      -                                "positive_span { offset: 7 length: 1 } " +
      -                                "positive_span { offset: 4 length: 1 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(3)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0.0, 1.0, 2.0, 3.0),
      -                new GolangTestCase("'factor 1.2 results in schema 2' from client_golang",
      -                        "sample_count: 6 " +
      -                                "sample_sum: 7.4 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, 1, 1.2, 1.4, 1.8, 2),
      -                new GolangTestCase("'factor 4 results in schema -1' from client_golang",
      -                        "sample_count: 14 " +
      -                                "sample_sum: 63.2581251 " +
      -                                "schema: -1 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 0 " +
      -                                "positive_span { offset: -2 length: 6 } " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: 0 " +
      -                                "positive_delta: 0 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: -2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(-1)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0.0156251, 0.0625, // Bucket -2: (0.015625, 0.0625)
      -                        0.1, 0.25, // Bucket -1: (0.0625, 0.25]
      -                        0.5, 1, // Bucket 0: (0.25, 1]
      -                        1.5, 2, 3, 3.5, // Bucket 1: (1, 4]
      -                        5, 6, 7, // Bucket 2: (4, 16]
      -                        33.33 // Bucket 3: (16, 64]
      -                ),
      -                new GolangTestCase("'factor 17 results in schema -2' from client_golang",
      -                        "sample_count: 14 " +
      -                                "sample_sum: 63.2581251 " +
      -                                "schema: -2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 0 " +
      -                                "positive_span { offset: -1 length: 4 } " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: 3 " +
      -                                "positive_delta: -6",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(-2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0.0156251, 0.0625, // Bucket -1: (0.015625, 0.0625]
      -                        0.1, 0.25, 0.5, 1, // Bucket 0: (0.0625, 1]
      -                        1.5, 2, 3, 3.5, 5, 6, 7, // Bucket 1: (1, 16]
      -                        33.33 // Bucket 2: (16, 256]
      -                ),
      -                new GolangTestCase("'negative buckets' from client_golang",
      -                        "sample_count: 6 " +
      -                                "sample_sum: -7.4 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "negative_span { offset: 0 length: 5 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: -1 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, -1, -1.2, -1.4, -1.8, -2
      -                ),
      -                new GolangTestCase("'negative and positive buckets' from client_golang",
      -                        "sample_count: 11 " +
      -                                "sample_sum: 0.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "negative_span { offset: 0 length: 5 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: -1 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 2 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2
      -                ),
      -                new GolangTestCase("'wide zero bucket' from client_golang",
      -                        "sample_count: 11 " +
      -                                "sample_sum: 0.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 1.4 " +
      -                                "zero_count: 7 " +
      -                                "negative_span { offset: 4 length: 1 } " +
      -                                "negative_delta: 2 " +
      -                                "positive_span { offset: 4 length: 1 } " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMinZeroThreshold(1.4)
      -                                .build(),
      -                        0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2
      -                ),
      -                /*
      -                // See https://github.com/prometheus/client_golang/issues/1275
      -                new TestCase("'NaN observation' from client_golang",
      -                        "sample_count: 7 " +
      -                                "sample_sum: NaN " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeHistogram()
      -                                .nativeSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, 1, 1.2, 1.4, 1.8, 2, Double.NaN
      -                ),
      -                */
      -                new GolangTestCase("'+Inf observation' from client_golang",
      -                        "sample_count: 7 " +
      -                                "sample_sum: Infinity " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_span { offset: 4092 length: 1 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -1",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, 1, 1.2, 1.4, 1.8, 2, Double.POSITIVE_INFINITY
      -                ),
      -                new GolangTestCase("'-Inf observation' from client_golang",
      -                        "sample_count: 7 " +
      -                                "sample_sum: -Infinity " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "negative_span { offset: 4097 length: 1 } " +
      -                                "negative_delta: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0, 1, 1.2, 1.4, 1.8, 2, Double.NEGATIVE_INFINITY
      -                ),
      -                new GolangTestCase("'limited buckets but nothing triggered' from client_golang",
      -                        "sample_count: 6 " +
      -                                "sample_sum: 7.4 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.2, 1.4, 1.8, 2
      -                ),
      -                new GolangTestCase("'buckets limited by halving resolution' from client_golang",
      -                        "sample_count: 8 " +
      -                                "sample_sum: 11.5 " +
      -                                "schema: 1 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: 0 length: 5 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -1 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 1",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3
      -                ),
      -                new GolangTestCase("'buckets limited by widening the zero bucket' from client_golang",
      -                        "sample_count: 8 " +
      -                                "sample_sum: 11.5 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 1.0 " +
      -                                "zero_count: 2 " +
      -                                "positive_span { offset: 1 length: 7 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 0 " +
      -                                "positive_delta: 1",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3
      -                ),
      -                new GolangTestCase("'buckets limited by widening the zero bucket twice' from client_golang",
      -                        "sample_count: 9 " +
      -                                "sample_sum: 15.5 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 1.189207115002721 " +
      -                                "zero_count: 3 " +
      -                                "positive_span { offset: 2 length: 7 } " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 2 " +
      -                                "positive_delta: -2 " +
      -                                "positive_delta: 0 " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, 3, 4),
      -                new GolangTestCase("'buckets limited by reset' from client_golang",
      -                        "sample_count: 2 " +
      -                                "sample_sum: 7.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 0 " +
      -                                "positive_span { offset: 7 length: 2 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMinZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, RESET_DURATION_REACHED, 3, 4),
      -                new GolangTestCase("'limited buckets but nothing triggered, negative observations' from client_golang",
      -                        "sample_count: 6 " +
      -                                "sample_sum: -7.4 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "negative_span { offset: 0 length: 5 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: -1 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 2",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, -1, -1.2, -1.4, -1.8, -2),
      -                new GolangTestCase("'buckets limited by halving resolution, negative observations' from client_golang",
      -                        "sample_count: 8 " +
      -                                "sample_sum: -11.5 " +
      -                                "schema: 1 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "negative_span { offset: 0 length: 5 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -1 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 1",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3),
      -                new GolangTestCase("'buckets limited by widening the zero bucket, negative observations' from client_golang",
      -                        "sample_count: 8 " +
      -                                "sample_sum: -11.5 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 1.0 " +
      -                                "zero_count: 2 " +
      -                                "negative_span { offset: 1 length: 7 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 0 " +
      -                                "negative_delta: 1",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3),
      -                new GolangTestCase("'buckets limited by widening the zero bucket twice, negative observations' from client_golang",
      -                        "sample_count: 9 " +
      -                                "sample_sum: -15.5 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 1.189207115002721 " +
      -                                "zero_count: 3 " +
      -                                "negative_span { offset: 2 length: 7 } " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 2 " +
      -                                "negative_delta: -2 " +
      -                                "negative_delta: 0 " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, -1, -1.1, -1.2, -1.4, -1.8, -2, -3, -4),
      -                new GolangTestCase("'buckets limited by reset, negative observations' from client_golang",
      -                        "sample_count: 2 " +
      -                                "sample_sum: -7.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: " + Math.pow(2.0, -128.0) + " " +
      -                                "zero_count: 0 " +
      -                                "negative_span { offset: 7 length: 2 } " +
      -                                "negative_delta: 1 " +
      -                                "negative_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, -1, -1.1, -1.2, -1.4, -1.8, -2, RESET_DURATION_REACHED, -3, -4),
      -                new GolangTestCase("'buckets limited by halving resolution, then reset' from client_golang",
      -                        "sample_count: 2 " +
      -                                "sample_sum: 7.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 0 " +
      -                                "positive_span { offset: 7 length: 2 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(0)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4),
      -                new GolangTestCase("'buckets limited by widening the zero bucket, then reset' from client_golang",
      -                        "sample_count: 2 " +
      -                                "sample_sum: 7.0 " +
      -                                "schema: 2 " +
      -                                "zero_threshold: " + Math.pow(2.0, -128.0) + " " +
      -                                "zero_count: 0 " +
      -                                "positive_span { offset: 7 length: 2 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(2)
      -                                .nativeMaxZeroThreshold(1.2)
      -                                .nativeMaxNumberOfBuckets(4)
      -                                .build(),
      -                        0, 1, 1.1, 1.2, 1.4, 1.8, 2, 5, 5.1, RESET_DURATION_REACHED, 3, 4)
      +  }
      +
      +  /** Test cases copied from histogram_test.go in client_golang. */
      +  @Test
      +  public void testGolangTests() throws NoSuchFieldException, IllegalAccessException {
      +    GolangTestCase[] testCases =
      +        new GolangTestCase[] {
      +          new GolangTestCase(
      +              "'no sparse buckets' from client_golang",
      +              "sample_count: 3 "
      +                  + "sample_sum: 6.0 "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.005 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.01 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.025 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.05 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.1 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.25 } "
      +                  + "bucket { cumulative_count: 0 upper_bound: 0.5 } "
      +                  + "bucket { cumulative_count: 1 upper_bound: 1.0 } "
      +                  + "bucket { cumulative_count: 2 upper_bound: 2.5 } "
      +                  + "bucket { cumulative_count: 3 upper_bound: 5.0 } "
      +                  + "bucket { cumulative_count: 3 upper_bound: 10.0 } "
      +                  + "bucket { cumulative_count: 3 upper_bound: Infinity }",
      +              Histogram.builder().name("test").classicOnly().build(),
      +              1.0,
      +              2.0,
      +              3.0),
      +          new GolangTestCase(
      +              "'factor 1.1 results in schema 3' from client_golang",
      +              "sample_count: 4 "
      +                  + "sample_sum: 6.0 "
      +                  + "schema: 3 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: 0 length: 1 } "
      +                  + "positive_span { offset: 7 length: 1 } "
      +                  + "positive_span { offset: 4 length: 1 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(3)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0.0,
      +              1.0,
      +              2.0,
      +              3.0),
      +          new GolangTestCase(
      +              "'factor 1.2 results in schema 2' from client_golang",
      +              "sample_count: 6 "
      +                  + "sample_sum: 7.4 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2),
      +          new GolangTestCase(
      +              "'factor 4 results in schema -1' from client_golang",
      +              "sample_count: 14 "
      +                  + "sample_sum: 63.2581251 "
      +                  + "schema: -1 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 0 "
      +                  + "positive_span { offset: -2 length: 6 } "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: 0 "
      +                  + "positive_delta: 0 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: -2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(-1)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0.0156251,
      +              0.0625, // Bucket -2: (0.015625, 0.0625)
      +              0.1,
      +              0.25, // Bucket -1: (0.0625, 0.25]
      +              0.5,
      +              1, // Bucket 0: (0.25, 1]
      +              1.5,
      +              2,
      +              3,
      +              3.5, // Bucket 1: (1, 4]
      +              5,
      +              6,
      +              7, // Bucket 2: (4, 16]
      +              33.33 // Bucket 3: (16, 64]
      +              ),
      +          new GolangTestCase(
      +              "'factor 17 results in schema -2' from client_golang",
      +              "sample_count: 14 "
      +                  + "sample_sum: 63.2581251 "
      +                  + "schema: -2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 0 "
      +                  + "positive_span { offset: -1 length: 4 } "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: 3 "
      +                  + "positive_delta: -6",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(-2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0.0156251,
      +              0.0625, // Bucket -1: (0.015625, 0.0625]
      +              0.1,
      +              0.25,
      +              0.5,
      +              1, // Bucket 0: (0.0625, 1]
      +              1.5,
      +              2,
      +              3,
      +              3.5,
      +              5,
      +              6,
      +              7, // Bucket 1: (1, 16]
      +              33.33 // Bucket 2: (16, 256]
      +              ),
      +          new GolangTestCase(
      +              "'negative buckets' from client_golang",
      +              "sample_count: 6 "
      +                  + "sample_sum: -7.4 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "negative_span { offset: 0 length: 5 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: -1 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2),
      +          new GolangTestCase(
      +              "'negative and positive buckets' from client_golang",
      +              "sample_count: 11 "
      +                  + "sample_sum: 0.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "negative_span { offset: 0 length: 5 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: -1 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 2 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2),
      +          new GolangTestCase(
      +              "'wide zero bucket' from client_golang",
      +              "sample_count: 11 "
      +                  + "sample_sum: 0.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 1.4 "
      +                  + "zero_count: 7 "
      +                  + "negative_span { offset: 4 length: 1 } "
      +                  + "negative_delta: 2 "
      +                  + "positive_span { offset: 4 length: 1 } "
      +                  + "positive_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMinZeroThreshold(1.4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2),
      +          /*
      +          // See https://github.com/prometheus/client_golang/issues/1275
      +          new TestCase("'NaN observation' from client_golang",
      +                  "sample_count: 7 " +
      +                          "sample_sum: NaN " +
      +                          "schema: 2 " +
      +                          "zero_threshold: 0.0 " +
      +                          "zero_count: 1 " +
      +                          "positive_span { offset: 0 length: 5 } " +
      +                          "positive_delta: 1 " +
      +                          "positive_delta: -1 " +
      +                          "positive_delta: 2 " +
      +                          "positive_delta: -2 " +
      +                          "positive_delta: 2",
      +                  Histogram.builder()
      +                          .name("test")
      +                          .nativeHistogram()
      +                          .nativeSchema(2)
      +                          .nativeMaxZeroThreshold(0)
      +                          .build(),
      +                  0, 1, 1.2, 1.4, 1.8, 2, Double.NaN
      +          ),
      +          */
      +          new GolangTestCase(
      +              "'+Inf observation' from client_golang",
      +              "sample_count: 7 "
      +                  + "sample_sum: Infinity "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_span { offset: 4092 length: 1 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -1",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              Double.POSITIVE_INFINITY),
      +          new GolangTestCase(
      +              "'-Inf observation' from client_golang",
      +              "sample_count: 7 "
      +                  + "sample_sum: -Infinity "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "negative_span { offset: 4097 length: 1 } "
      +                  + "negative_delta: 1 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              Double.NEGATIVE_INFINITY),
      +          new GolangTestCase(
      +              "'limited buckets but nothing triggered' from client_golang",
      +              "sample_count: 6 "
      +                  + "sample_sum: 7.4 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2),
      +          new GolangTestCase(
      +              "'buckets limited by halving resolution' from client_golang",
      +              "sample_count: 8 "
      +                  + "sample_sum: 11.5 "
      +                  + "schema: 1 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: 0 length: 5 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -1 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 1",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              3),
      +          new GolangTestCase(
      +              "'buckets limited by widening the zero bucket' from client_golang",
      +              "sample_count: 8 "
      +                  + "sample_sum: 11.5 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 1.0 "
      +                  + "zero_count: 2 "
      +                  + "positive_span { offset: 1 length: 7 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 0 "
      +                  + "positive_delta: 1",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              3),
      +          new GolangTestCase(
      +              "'buckets limited by widening the zero bucket twice' from client_golang",
      +              "sample_count: 9 "
      +                  + "sample_sum: 15.5 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 1.189207115002721 "
      +                  + "zero_count: 3 "
      +                  + "positive_span { offset: 2 length: 7 } "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 2 "
      +                  + "positive_delta: -2 "
      +                  + "positive_delta: 0 "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              3,
      +              4),
      +          new GolangTestCase(
      +              "'buckets limited by reset' from client_golang",
      +              "sample_count: 2 "
      +                  + "sample_sum: 7.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 0 "
      +                  + "positive_span { offset: 7 length: 2 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMinZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              RESET_DURATION_REACHED,
      +              3,
      +              4),
      +          new GolangTestCase(
      +              "'limited buckets but nothing triggered, negative observations' from client_golang",
      +              "sample_count: 6 "
      +                  + "sample_sum: -7.4 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "negative_span { offset: 0 length: 5 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: -1 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 2",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2),
      +          new GolangTestCase(
      +              "'buckets limited by halving resolution, negative observations' from client_golang",
      +              "sample_count: 8 "
      +                  + "sample_sum: -11.5 "
      +                  + "schema: 1 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "negative_span { offset: 0 length: 5 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -1 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 1",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              -3),
      +          new GolangTestCase(
      +              "'buckets limited by widening the zero bucket, negative observations' from client_golang",
      +              "sample_count: 8 "
      +                  + "sample_sum: -11.5 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 1.0 "
      +                  + "zero_count: 2 "
      +                  + "negative_span { offset: 1 length: 7 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 0 "
      +                  + "negative_delta: 1",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              -3),
      +          new GolangTestCase(
      +              "'buckets limited by widening the zero bucket twice, negative observations' from client_golang",
      +              "sample_count: 9 "
      +                  + "sample_sum: -15.5 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 1.189207115002721 "
      +                  + "zero_count: 3 "
      +                  + "negative_span { offset: 2 length: 7 } "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 2 "
      +                  + "negative_delta: -2 "
      +                  + "negative_delta: 0 "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              -3,
      +              -4),
      +          new GolangTestCase(
      +              "'buckets limited by reset, negative observations' from client_golang",
      +              "sample_count: 2 "
      +                  + "sample_sum: -7.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: "
      +                  + Math.pow(2.0, -128.0)
      +                  + " "
      +                  + "zero_count: 0 "
      +                  + "negative_span { offset: 7 length: 2 } "
      +                  + "negative_delta: 1 "
      +                  + "negative_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              -1,
      +              -1.1,
      +              -1.2,
      +              -1.4,
      +              -1.8,
      +              -2,
      +              RESET_DURATION_REACHED,
      +              -3,
      +              -4),
      +          new GolangTestCase(
      +              "'buckets limited by halving resolution, then reset' from client_golang",
      +              "sample_count: 2 "
      +                  + "sample_sum: 7.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 0 "
      +                  + "positive_span { offset: 7 length: 2 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(0)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              5,
      +              5.1,
      +              RESET_DURATION_REACHED,
      +              3,
      +              4),
      +          new GolangTestCase(
      +              "'buckets limited by widening the zero bucket, then reset' from client_golang",
      +              "sample_count: 2 "
      +                  + "sample_sum: 7.0 "
      +                  + "schema: 2 "
      +                  + "zero_threshold: "
      +                  + Math.pow(2.0, -128.0)
      +                  + " "
      +                  + "zero_count: 0 "
      +                  + "positive_span { offset: 7 length: 2 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(2)
      +                  .nativeMaxZeroThreshold(1.2)
      +                  .nativeMaxNumberOfBuckets(4)
      +                  .build(),
      +              0,
      +              1,
      +              1.1,
      +              1.2,
      +              1.4,
      +              1.8,
      +              2,
      +              5,
      +              5.1,
      +              RESET_DURATION_REACHED,
      +              3,
      +              4)
               };
      -        for (GolangTestCase testCase : testCases) {
      -            testCase.run();
      -        }
      +    for (GolangTestCase testCase : testCases) {
      +      testCase.run();
           }
      -
      -    /**
      -     * Additional tests that are not part of client_golang's test suite.
      -     */
      -    @Test
      -    public void testAdditional() throws NoSuchFieldException, IllegalAccessException {
      -        GolangTestCase[] testCases = new GolangTestCase[]{
      -                new GolangTestCase("observed values are exactly at bucket boundaries",
      -                        "sample_count: 3 " +
      -                                "sample_sum: 1.5 " +
      -                                "schema: 0 " +
      -                                "zero_threshold: 0.0 " +
      -                                "zero_count: 1 " +
      -                                "positive_span { offset: -1 length: 2 } " +
      -                                "positive_delta: 1 " +
      -                                "positive_delta: 0",
      -                        Histogram.builder()
      -                                .name("test")
      -                                .nativeOnly()
      -                                .nativeInitialSchema(0)
      -                                .nativeMaxZeroThreshold(0)
      -                                .build(),
      -                        0.0, 0.5, 1.0)
      +  }
      +
      +  /** Additional tests that are not part of client_golang's test suite. */
      +  @Test
      +  public void testAdditional() throws NoSuchFieldException, IllegalAccessException {
      +    GolangTestCase[] testCases =
      +        new GolangTestCase[] {
      +          new GolangTestCase(
      +              "observed values are exactly at bucket boundaries",
      +              "sample_count: 3 "
      +                  + "sample_sum: 1.5 "
      +                  + "schema: 0 "
      +                  + "zero_threshold: 0.0 "
      +                  + "zero_count: 1 "
      +                  + "positive_span { offset: -1 length: 2 } "
      +                  + "positive_delta: 1 "
      +                  + "positive_delta: 0",
      +              Histogram.builder()
      +                  .name("test")
      +                  .nativeOnly()
      +                  .nativeInitialSchema(0)
      +                  .nativeMaxZeroThreshold(0)
      +                  .build(),
      +              0.0,
      +              0.5,
      +              1.0)
               };
      -        for (GolangTestCase testCase : testCases) {
      -            testCase.run();
      -        }
      +    for (GolangTestCase testCase : testCases) {
      +      testCase.run();
           }
      -
      -    /**
      -     * Tests HistogramData.nativeBucketIndexToUpperBound(int, int).
      -     * 

      - * This test is ported from client_golang's TestGetLe(). - */ - @Test - public void testNativeBucketIndexToUpperBound() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - int[] indexes = new int[]{-1, 0, 1, 512, 513, -1, 0, 1, 1024, 1025, -1, 0, 1, 4096, 4097}; - int[] schemas = new int[]{-1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}; - double[] expectedUpperBounds = new double[]{0.25, 1, 4, Double.MAX_VALUE, Double.POSITIVE_INFINITY, - 0.5, 1, 2, Double.MAX_VALUE, Double.POSITIVE_INFINITY, - 0.8408964152537144, 1, 1.189207115002721, Double.MAX_VALUE, Double.POSITIVE_INFINITY}; - Method method = Histogram.DataPoint.class.getDeclaredMethod("nativeBucketIndexToUpperBound", int.class, int.class); - method.setAccessible(true); - for (int i = 0; i < indexes.length; i++) { - Histogram histogram = Histogram.builder() - .name("test") - .nativeInitialSchema(schemas[i]) - .build(); - Histogram.DataPoint histogramData = histogram.newDataPoint(); - double result = (double) method.invoke(histogramData, schemas[i], indexes[i]); - Assert.assertEquals("index=" + indexes[i] + ", schema=" + schemas[i], expectedUpperBounds[i], result, 0.0000000000001); - } + } + + /** + * Tests HistogramData.nativeBucketIndexToUpperBound(int, int). + * + *

      This test is ported from client_golang's TestGetLe(). + */ + @Test + public void testNativeBucketIndexToUpperBound() + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + int[] indexes = new int[] {-1, 0, 1, 512, 513, -1, 0, 1, 1024, 1025, -1, 0, 1, 4096, 4097}; + int[] schemas = new int[] {-1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2}; + double[] expectedUpperBounds = + new double[] { + 0.25, + 1, + 4, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + 0.5, + 1, + 2, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + 0.8408964152537144, + 1, + 1.189207115002721, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY + }; + Method method = + Histogram.DataPoint.class.getDeclaredMethod( + "nativeBucketIndexToUpperBound", int.class, int.class); + method.setAccessible(true); + for (int i = 0; i < indexes.length; i++) { + Histogram histogram = + Histogram.builder().name("test").nativeInitialSchema(schemas[i]).build(); + Histogram.DataPoint histogramData = histogram.newDataPoint(); + double result = (double) method.invoke(histogramData, schemas[i], indexes[i]); + Assert.assertEquals( + "index=" + indexes[i] + ", schema=" + schemas[i], + expectedUpperBounds[i], + result, + 0.0000000000001); } - - /** - * Test if lowerBound < value <= upperBound is true for the bucket index returned by findBucketIndex() - */ - @Test - public void testFindBucketIndex() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Random rand = new Random(); - Method findBucketIndex = Histogram.DataPoint.class.getDeclaredMethod("findBucketIndex", double.class); - Method nativeBucketIndexToUpperBound = Histogram.DataPoint.class.getDeclaredMethod("nativeBucketIndexToUpperBound", int.class, int.class); - findBucketIndex.setAccessible(true); - nativeBucketIndexToUpperBound.setAccessible(true); - for (int schema = -4; schema <= 8; schema++) { - Histogram histogram = Histogram.builder() - .nativeOnly() - .name("test") - .nativeInitialSchema(schema) - .build(); - for (int i = 0; i < 10_000; i++) { - for (int zeros = -5; zeros <= 10; zeros++) { - double value = rand.nextDouble() * Math.pow(10, zeros); - int bucketIndex = (int) findBucketIndex.invoke(histogram.getNoLabels(), value); - double lowerBound = (double) nativeBucketIndexToUpperBound.invoke(histogram.getNoLabels(), schema, bucketIndex - 1); - double upperBound = (double) nativeBucketIndexToUpperBound.invoke(histogram.getNoLabels(), schema, bucketIndex); - Assert.assertTrue("Bucket index " + bucketIndex + " with schema " + schema + " has range [" + lowerBound + ", " + upperBound + "]. Value " + value + " is outside of that range.", lowerBound < value && upperBound >= value); - } - } + } + + /** + * Test if lowerBound < value <= upperBound is true for the bucket index returned by + * findBucketIndex() + */ + @Test + public void testFindBucketIndex() + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Random rand = new Random(); + Method findBucketIndex = + Histogram.DataPoint.class.getDeclaredMethod("findBucketIndex", double.class); + Method nativeBucketIndexToUpperBound = + Histogram.DataPoint.class.getDeclaredMethod( + "nativeBucketIndexToUpperBound", int.class, int.class); + findBucketIndex.setAccessible(true); + nativeBucketIndexToUpperBound.setAccessible(true); + for (int schema = -4; schema <= 8; schema++) { + Histogram histogram = + Histogram.builder().nativeOnly().name("test").nativeInitialSchema(schema).build(); + for (int i = 0; i < 10_000; i++) { + for (int zeros = -5; zeros <= 10; zeros++) { + double value = rand.nextDouble() * Math.pow(10, zeros); + int bucketIndex = (int) findBucketIndex.invoke(histogram.getNoLabels(), value); + double lowerBound = + (double) + nativeBucketIndexToUpperBound.invoke( + histogram.getNoLabels(), schema, bucketIndex - 1); + double upperBound = + (double) + nativeBucketIndexToUpperBound.invoke( + histogram.getNoLabels(), schema, bucketIndex); + Assert.assertTrue( + "Bucket index " + + bucketIndex + + " with schema " + + schema + + " has range [" + + lowerBound + + ", " + + upperBound + + "]. Value " + + value + + " is outside of that range.", + lowerBound < value && upperBound >= value); } + } } - - @Test - public void testDefaults() throws IOException { - Histogram histogram = Histogram.builder().name("test").build(); - histogram.observe(0.5); - HistogramSnapshot snapshot = histogram.collect(); - String expectedProtobuf = "" + - "name: \"test\" " + - "type: HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 1 " + - "sample_sum: 0.5 " + - // default has both, native and classic buckets - "bucket { cumulative_count: 0 upper_bound: 0.005 } " + - "bucket { cumulative_count: 0 upper_bound: 0.01 } " + - "bucket { cumulative_count: 0 upper_bound: 0.025 } " + - "bucket { cumulative_count: 0 upper_bound: 0.05 } " + - "bucket { cumulative_count: 0 upper_bound: 0.1 } " + - "bucket { cumulative_count: 0 upper_bound: 0.25 } " + - "bucket { cumulative_count: 1 upper_bound: 0.5 } " + - "bucket { cumulative_count: 1 upper_bound: 1.0 } " + - "bucket { cumulative_count: 1 upper_bound: 2.5 } " + - "bucket { cumulative_count: 1 upper_bound: 5.0 } " + - "bucket { cumulative_count: 1 upper_bound: 10.0 } " + - "bucket { cumulative_count: 1 upper_bound: Infinity } " + - // default native schema is 5 - "schema: 5 " + - // default zero threshold is 2^-128 - "zero_threshold: " + Math.pow(2.0, -128.0) + " " + - "zero_count: 0 " + - "positive_span { offset: -32 length: 1 } " + - "positive_delta: 1 " + - "} }"; - String expectedTextFormat = "" + - // default classic buckets - "# TYPE test histogram\n" + - "test_bucket{le=\"0.005\"} 0\n" + - "test_bucket{le=\"0.01\"} 0\n" + - "test_bucket{le=\"0.025\"} 0\n" + - "test_bucket{le=\"0.05\"} 0\n" + - "test_bucket{le=\"0.1\"} 0\n" + - "test_bucket{le=\"0.25\"} 0\n" + - "test_bucket{le=\"0.5\"} 1\n" + - "test_bucket{le=\"1.0\"} 1\n" + - "test_bucket{le=\"2.5\"} 1\n" + - "test_bucket{le=\"5.0\"} 1\n" + - "test_bucket{le=\"10.0\"} 1\n" + - "test_bucket{le=\"+Inf\"} 1\n" + - "test_count 1\n" + - "test_sum 0.5\n" + - "# EOF\n"; - - // protobuf - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - Assert.assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); - - // text - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expectedTextFormat, out.toString()); - } - - @Test - public void testExemplarsClassicHistogram() throws Exception { - SpanContext spanContext = new SpanContext() { - int callCount = 0; - - @Override - public String getCurrentTraceId() { - return "traceId-" + callCount; - } - - @Override - public String getCurrentSpanId() { - return "spanId-" + callCount; - } - - @Override - public boolean isCurrentSpanSampled() { - callCount++; - return true; - } - - @Override - public void markCurrentSpanAsExemplar() { - } + } + + @Test + public void testDefaults() throws IOException { + Histogram histogram = Histogram.builder().name("test").build(); + histogram.observe(0.5); + HistogramSnapshot snapshot = histogram.collect(); + String expectedProtobuf = + "" + + "name: \"test\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 1 " + + "sample_sum: 0.5 " + + + // default has both, native and classic buckets + "bucket { cumulative_count: 0 upper_bound: 0.005 } " + + "bucket { cumulative_count: 0 upper_bound: 0.01 } " + + "bucket { cumulative_count: 0 upper_bound: 0.025 } " + + "bucket { cumulative_count: 0 upper_bound: 0.05 } " + + "bucket { cumulative_count: 0 upper_bound: 0.1 } " + + "bucket { cumulative_count: 0 upper_bound: 0.25 } " + + "bucket { cumulative_count: 1 upper_bound: 0.5 } " + + "bucket { cumulative_count: 1 upper_bound: 1.0 } " + + "bucket { cumulative_count: 1 upper_bound: 2.5 } " + + "bucket { cumulative_count: 1 upper_bound: 5.0 } " + + "bucket { cumulative_count: 1 upper_bound: 10.0 } " + + "bucket { cumulative_count: 1 upper_bound: Infinity } " + + + // default native schema is 5 + "schema: 5 " + + + // default zero threshold is 2^-128 + "zero_threshold: " + + Math.pow(2.0, -128.0) + + " " + + "zero_count: 0 " + + "positive_span { offset: -32 length: 1 } " + + "positive_delta: 1 " + + "} }"; + String expectedTextFormat = + "" + + + // default classic buckets + "# TYPE test histogram\n" + + "test_bucket{le=\"0.005\"} 0\n" + + "test_bucket{le=\"0.01\"} 0\n" + + "test_bucket{le=\"0.025\"} 0\n" + + "test_bucket{le=\"0.05\"} 0\n" + + "test_bucket{le=\"0.1\"} 0\n" + + "test_bucket{le=\"0.25\"} 0\n" + + "test_bucket{le=\"0.5\"} 1\n" + + "test_bucket{le=\"1.0\"} 1\n" + + "test_bucket{le=\"2.5\"} 1\n" + + "test_bucket{le=\"5.0\"} 1\n" + + "test_bucket{le=\"10.0\"} 1\n" + + "test_bucket{le=\"+Inf\"} 1\n" + + "test_count 1\n" + + "test_sum 0.5\n" + + "# EOF\n"; + + // protobuf + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); + Assert.assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); + + // text + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expectedTextFormat, out.toString()); + } + + @Test + public void testExemplarsClassicHistogram() throws Exception { + SpanContext spanContext = + new SpanContext() { + int callCount = 0; + + @Override + public String getCurrentTraceId() { + return "traceId-" + callCount; + } + + @Override + public String getCurrentSpanId() { + return "spanId-" + callCount; + } + + @Override + public boolean isCurrentSpanSampled() { + callCount++; + return true; + } + + @Override + public void markCurrentSpanAsExemplar() {} }; - Histogram histogram = Histogram.builder() - .name("test") - // The default number of Exemplars is 4. - // Use 5 buckets to verify that the exemplar sample is configured with the buckets. - .classicUpperBounds(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY) - .labelNames("path") - .build(); - - long sampleIntervalMillis = 10; - ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); - SpanContextSupplier.setSpanContext(spanContext); - - Exemplar ex1a = Exemplar.builder() - .value(0.5) - .spanId("spanId-1") - .traceId("traceId-1") - .build(); - Exemplar ex1b = Exemplar.builder() - .value(0.5) - .spanId("spanId-2") - .traceId("traceId-2") - .build(); - Exemplar ex2a = Exemplar.builder() - .value(4.5) - .spanId("spanId-3") - .traceId("traceId-3") - .build(); - Exemplar ex2b = Exemplar.builder() - .value(4.5) - .spanId("spanId-4") - .traceId("traceId-4") - .build(); - Exemplar ex3a = Exemplar.builder() - .value(1.5) - .spanId("spanId-5") - .traceId("traceId-5") - .build(); - Exemplar ex3b = Exemplar.builder() - .value(1.5) - .spanId("spanId-6") - .traceId("traceId-6") - .build(); - Exemplar ex4a = Exemplar.builder() - .value(2.5) - .spanId("spanId-7") - .traceId("traceId-7") - .build(); - Exemplar ex4b = Exemplar.builder() - .value(2.5) - .spanId("spanId-8") - .traceId("traceId-8") - .build(); - Exemplar ex5a = Exemplar.builder() - .value(3.5) - .spanId("spanId-9") - .traceId("traceId-9") - .build(); - Exemplar ex5b = Exemplar.builder() - .value(3.5) - .spanId("spanId-10") - .traceId("traceId-10") - .build(); - histogram.labelValues("/hello").observe(0.5); - histogram.labelValues("/world").observe(0.5); // different labels are tracked independently, i.e. we don't need to wait for sampleIntervalMillis - - HistogramSnapshot snapshot = histogram.collect(); - assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); - assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); - assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 2.0, "path", "/world")); - assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 3.0, "path", "/world")); - assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 4.0, "path", "/world")); - assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); - assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); - - Thread.sleep(sampleIntervalMillis + 1); - histogram.labelValues("/hello").observe(4.5); - histogram.labelValues("/world").observe(4.5); - - snapshot = histogram.collect(); - assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); - assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); - assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 2.0, "path", "/world")); - assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 3.0, "path", "/world")); - assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 4.0, "path", "/world")); - assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); - assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); - - Thread.sleep(sampleIntervalMillis + 1); - histogram.labelValues("/hello").observe(1.5); - histogram.labelValues("/world").observe(1.5); - Thread.sleep(sampleIntervalMillis + 1); - histogram.labelValues("/hello").observe(2.5); - histogram.labelValues("/world").observe(2.5); - Thread.sleep(sampleIntervalMillis + 1); - histogram.labelValues("/hello").observe(3.5); - histogram.labelValues("/world").observe(3.5); - - snapshot = histogram.collect(); - assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); - assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); - assertExemplarEquals(ex3a, getExemplar(snapshot, 2.0, "path", "/hello")); - assertExemplarEquals(ex3b, getExemplar(snapshot, 2.0, "path", "/world")); - assertExemplarEquals(ex4a, getExemplar(snapshot, 3.0, "path", "/hello")); - assertExemplarEquals(ex4b, getExemplar(snapshot, 3.0, "path", "/world")); - assertExemplarEquals(ex5a, getExemplar(snapshot, 4.0, "path", "/hello")); - assertExemplarEquals(ex5b, getExemplar(snapshot, 4.0, "path", "/world")); - assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); - assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); - - Exemplar custom = Exemplar.builder() - .value(3.4) - .labels(Labels.of("key2", "value2", "key1", "value1", "trace_id", "traceId-11", "span_id", "spanId-11")) - .build(); - Thread.sleep(sampleIntervalMillis + 1); - histogram.labelValues("/hello").observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2")); - snapshot = histogram.collect(); - // custom exemplars have preference, so the automatic exemplar is replaced - assertExemplarEquals(custom, getExemplar(snapshot, 4.0, "path", "/hello")); + Histogram histogram = + Histogram.builder() + .name("test") + // The default number of Exemplars is 4. + // Use 5 buckets to verify that the exemplar sample is configured with the buckets. + .classicUpperBounds(1.0, 2.0, 3.0, 4.0, Double.POSITIVE_INFINITY) + .labelNames("path") + .build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + SpanContextSupplier.setSpanContext(spanContext); + + Exemplar ex1a = Exemplar.builder().value(0.5).spanId("spanId-1").traceId("traceId-1").build(); + Exemplar ex1b = Exemplar.builder().value(0.5).spanId("spanId-2").traceId("traceId-2").build(); + Exemplar ex2a = Exemplar.builder().value(4.5).spanId("spanId-3").traceId("traceId-3").build(); + Exemplar ex2b = Exemplar.builder().value(4.5).spanId("spanId-4").traceId("traceId-4").build(); + Exemplar ex3a = Exemplar.builder().value(1.5).spanId("spanId-5").traceId("traceId-5").build(); + Exemplar ex3b = Exemplar.builder().value(1.5).spanId("spanId-6").traceId("traceId-6").build(); + Exemplar ex4a = Exemplar.builder().value(2.5).spanId("spanId-7").traceId("traceId-7").build(); + Exemplar ex4b = Exemplar.builder().value(2.5).spanId("spanId-8").traceId("traceId-8").build(); + Exemplar ex5a = Exemplar.builder().value(3.5).spanId("spanId-9").traceId("traceId-9").build(); + Exemplar ex5b = Exemplar.builder().value(3.5).spanId("spanId-10").traceId("traceId-10").build(); + histogram.labelValues("/hello").observe(0.5); + histogram + .labelValues("/world") + .observe(0.5); // different labels are tracked independently, i.e. we don't need to wait for + // sampleIntervalMillis + + HistogramSnapshot snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 2.0, "path", "/world")); + assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 3.0, "path", "/world")); + assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 4.0, "path", "/world")); + assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Thread.sleep(sampleIntervalMillis + 1); + histogram.labelValues("/hello").observe(4.5); + histogram.labelValues("/world").observe(4.5); + + snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 2.0, "path", "/world")); + assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 3.0, "path", "/world")); + assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); + assertNull(getExemplar(snapshot, 4.0, "path", "/world")); + assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Thread.sleep(sampleIntervalMillis + 1); + histogram.labelValues("/hello").observe(1.5); + histogram.labelValues("/world").observe(1.5); + Thread.sleep(sampleIntervalMillis + 1); + histogram.labelValues("/hello").observe(2.5); + histogram.labelValues("/world").observe(2.5); + Thread.sleep(sampleIntervalMillis + 1); + histogram.labelValues("/hello").observe(3.5); + histogram.labelValues("/world").observe(3.5); + + snapshot = histogram.collect(); + assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); + assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); + assertExemplarEquals(ex3a, getExemplar(snapshot, 2.0, "path", "/hello")); + assertExemplarEquals(ex3b, getExemplar(snapshot, 2.0, "path", "/world")); + assertExemplarEquals(ex4a, getExemplar(snapshot, 3.0, "path", "/hello")); + assertExemplarEquals(ex4b, getExemplar(snapshot, 3.0, "path", "/world")); + assertExemplarEquals(ex5a, getExemplar(snapshot, 4.0, "path", "/hello")); + assertExemplarEquals(ex5b, getExemplar(snapshot, 4.0, "path", "/world")); + assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); + assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + + Exemplar custom = + Exemplar.builder() + .value(3.4) + .labels( + Labels.of( + "key2", + "value2", + "key1", + "value1", + "trace_id", + "traceId-11", + "span_id", + "spanId-11")) + .build(); + Thread.sleep(sampleIntervalMillis + 1); + histogram + .labelValues("/hello") + .observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2")); + snapshot = histogram.collect(); + // custom exemplars have preference, so the automatic exemplar is replaced + assertExemplarEquals(custom, getExemplar(snapshot, 4.0, "path", "/hello")); + } + + private Exemplar getExemplar(HistogramSnapshot snapshot, double le, String... labels) { + HistogramSnapshot.HistogramDataPointSnapshot data = + snapshot.getDataPoints().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findFirst() + .orElseThrow(() -> new RuntimeException("Labels not found")); + double lowerBound = Double.NEGATIVE_INFINITY; + for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { + if (bucket.getUpperBound() == le) { + break; + } else { + lowerBound = bucket.getUpperBound(); + } } - - private Exemplar getExemplar(HistogramSnapshot snapshot, double le, String... labels) { - HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream() - .filter(d -> d.getLabels().equals(Labels.of(labels))) - .findFirst() - .orElseThrow(() -> new RuntimeException("Labels not found")); - double lowerBound = Double.NEGATIVE_INFINITY; - for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { - if (bucket.getUpperBound() == le) { - break; - } else { - lowerBound = bucket.getUpperBound(); - } - } - return data.getExemplars().get(lowerBound, le); + return data.getExemplars().get(lowerBound, le); + } + + @Test + public void testCustomExemplarsClassicHistogram() + throws InterruptedException, NoSuchFieldException, IllegalAccessException { + + // TODO: This was copied from the old simpleclient, can probably be refactored. + + Histogram histogram = Histogram.builder().name("test").withExemplars().build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(histogram, 3 * sampleIntervalMillis); + + Labels labels = Labels.of("mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + histogram.observeWithExemplar(0.5, Labels.of("key", "value")); + assertExemplar(histogram, 0.5, "key", "value"); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.5, Labels.EMPTY); + assertExemplar(histogram, 0.5); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.5, labels); + assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + // default buckets are {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(2.0, Labels.of("key1", "value1", "key2", "value2")); + assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); + assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); + + Thread.sleep(sampleIntervalMillis * 3 + 1); + histogram.observeWithExemplar(0.4, Labels.EMPTY); // same bucket as 0.5 + assertExemplar(histogram, 0.4); + assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); + } + + private void assertExemplar(Histogram histogram, double value, String... labels) { + double lowerBound = Double.NEGATIVE_INFINITY; + double upperBound = Double.POSITIVE_INFINITY; + HistogramSnapshot snapshot = histogram.collect(); + HistogramSnapshot.HistogramDataPointSnapshot data = + snapshot.getDataPoints().stream() + .filter(d -> d.getLabels().isEmpty()) + .findFirst() + .orElseThrow(() -> new RuntimeException("No data without labels found")); + for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { + if (bucket.getUpperBound() >= value) { + upperBound = bucket.getUpperBound(); + break; + } else { + lowerBound = bucket.getUpperBound(); + } } - - @Test - public void testCustomExemplarsClassicHistogram() throws InterruptedException, NoSuchFieldException, IllegalAccessException { - - // TODO: This was copied from the old simpleclient, can probably be refactored. - - Histogram histogram = Histogram.builder() - .name("test") - .withExemplars() - .build(); - - long sampleIntervalMillis = 10; - ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); - ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(histogram, 3 * sampleIntervalMillis); - - Labels labels = Labels.of("mapKey1", "mapValue1", "mapKey2", "mapValue2"); - - histogram.observeWithExemplar(0.5, Labels.of("key", "value")); - assertExemplar(histogram, 0.5, "key", "value"); - - Thread.sleep(sampleIntervalMillis * 3 + 1); - histogram.observeWithExemplar(0.5, Labels.EMPTY); - assertExemplar(histogram, 0.5); - - Thread.sleep(sampleIntervalMillis * 3 + 1); - histogram.observeWithExemplar(0.5, labels); - assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); - - // default buckets are {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - Thread.sleep(sampleIntervalMillis * 3 + 1); - histogram.observeWithExemplar(2.0, Labels.of("key1", "value1", "key2", "value2")); - assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); - assertExemplar(histogram, 0.5, "mapKey1", "mapValue1", "mapKey2", "mapValue2"); - - Thread.sleep(sampleIntervalMillis * 3 + 1); - histogram.observeWithExemplar(0.4, Labels.EMPTY); // same bucket as 0.5 - assertExemplar(histogram, 0.4); - assertExemplar(histogram, 2.0, "key1", "value1", "key2", "value2"); - } - - private void assertExemplar(Histogram histogram, double value, String... labels) { - double lowerBound = Double.NEGATIVE_INFINITY; - double upperBound = Double.POSITIVE_INFINITY; - HistogramSnapshot snapshot = histogram.collect(); - HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream() - .filter(d -> d.getLabels().isEmpty()) - .findFirst() - .orElseThrow(() -> new RuntimeException("No data without labels found")); - for (ClassicHistogramBucket bucket : data.getClassicBuckets()) { - if (bucket.getUpperBound() >= value) { - upperBound = bucket.getUpperBound(); - break; - } else { - lowerBound = bucket.getUpperBound(); - } - } - Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); - Assert.assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); - Assert.assertEquals(value, exemplar.getValue(), 0.0); - Assert.assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); - for (int i = 0; i < labels.length; i += 2) { - Assert.assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); - Assert.assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); - } + Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); + Assert.assertNotNull( + "No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); + Assert.assertEquals(value, exemplar.getValue(), 0.0); + Assert.assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); + for (int i = 0; i < labels.length; i += 2) { + Assert.assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); + Assert.assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); } + } + @Test + public void testExemplarsNativeHistogram() throws NoSuchFieldException, IllegalAccessException { - @Test - public void testExemplarsNativeHistogram() throws NoSuchFieldException, IllegalAccessException { + SpanContext spanContext = + new SpanContext() { + int callCount = 0; - SpanContext spanContext = new SpanContext() { - int callCount = 0; + @Override + public String getCurrentTraceId() { + return "traceId-" + callCount; + } - @Override - public String getCurrentTraceId() { - return "traceId-" + callCount; - } + @Override + public String getCurrentSpanId() { + return "spanId-" + callCount; + } - @Override - public String getCurrentSpanId() { - return "spanId-" + callCount; - } + @Override + public boolean isCurrentSpanSampled() { + callCount++; + return true; + } - @Override - public boolean isCurrentSpanSampled() { - callCount++; - return true; - } - - @Override - public void markCurrentSpanAsExemplar() { - } + @Override + public void markCurrentSpanAsExemplar() {} }; - Histogram histogram = Histogram.builder() - .name("test") - .nativeOnly() - .labelNames("path") - .build(); - - long sampleIntervalMillis = 10; - ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); - SpanContextSupplier.setSpanContext(spanContext); - - Exemplar ex1 = Exemplar.builder() - .value(3.11) - .spanId("spanId-1") - .traceId("traceId-1") - .build(); - Exemplar ex2 = Exemplar.builder() - .value(3.12) - .spanId("spanId-2") - .traceId("traceId-2") - .build(); - Exemplar ex3 = Exemplar.builder() - .value(3.13) - .spanId("spanId-3") - .traceId("traceId-3") - .labels(Labels.of("key1", "value1", "key2", "value2")) - .build(); - - histogram.labelValues("/hello").observe(3.11); - histogram.labelValues("/world").observe(3.12); - assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); - assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); - assertEquals(1, getData(histogram, "path", "/world").getExemplars().size()); - assertExemplarEquals(ex2, getData(histogram, "path", "/world").getExemplars().iterator().next()); - - histogram.labelValues("/world").observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2")); - assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); - assertExemplarEquals(ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); - assertEquals(2, getData(histogram, "path", "/world").getExemplars().size()); - Exemplars exemplars = getData(histogram, "path", "/world").getExemplars(); - List exemplarList = new ArrayList<>(exemplars.size()); - for (Exemplar exemplar : exemplars) { - exemplarList.add(exemplar); - } - exemplarList.sort(Comparator.comparingDouble(Exemplar::getValue)); - assertEquals(2, exemplars.size()); - assertExemplarEquals(ex2, exemplarList.get(0)); - assertExemplarEquals(ex3, exemplarList.get(1)); + Histogram histogram = Histogram.builder().name("test").nativeOnly().labelNames("path").build(); + + long sampleIntervalMillis = 10; + ExemplarSamplerConfigTestUtil.setSampleIntervalMillis(histogram, sampleIntervalMillis); + SpanContextSupplier.setSpanContext(spanContext); + + Exemplar ex1 = Exemplar.builder().value(3.11).spanId("spanId-1").traceId("traceId-1").build(); + Exemplar ex2 = Exemplar.builder().value(3.12).spanId("spanId-2").traceId("traceId-2").build(); + Exemplar ex3 = + Exemplar.builder() + .value(3.13) + .spanId("spanId-3") + .traceId("traceId-3") + .labels(Labels.of("key1", "value1", "key2", "value2")) + .build(); + + histogram.labelValues("/hello").observe(3.11); + histogram.labelValues("/world").observe(3.12); + assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertExemplarEquals( + ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); + assertEquals(1, getData(histogram, "path", "/world").getExemplars().size()); + assertExemplarEquals( + ex2, getData(histogram, "path", "/world").getExemplars().iterator().next()); + + histogram + .labelValues("/world") + .observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2")); + assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertExemplarEquals( + ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); + assertEquals(2, getData(histogram, "path", "/world").getExemplars().size()); + Exemplars exemplars = getData(histogram, "path", "/world").getExemplars(); + List exemplarList = new ArrayList<>(exemplars.size()); + for (Exemplar exemplar : exemplars) { + exemplarList.add(exemplar); } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalLabelName() { + exemplarList.sort(Comparator.comparingDouble(Exemplar::getValue)); + assertEquals(2, exemplars.size()); + assertExemplarEquals(ex2, exemplarList.get(0)); + assertExemplarEquals(ex3, exemplarList.get(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelName() { + Histogram.builder().name("test").labelNames("label", "le"); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelNameConstLabels() { + Histogram.builder().name("test").constLabels(Labels.of("label1", "value1", "le", "0.3")); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalLabelNamePrefix() { + Histogram.builder().name("test").labelNames("__hello"); + } + + @Test(expected = IllegalArgumentException.class) + public void testIllegalName() { + Histogram.builder().name("my_namespace/server.durations"); + } + + @Test(expected = IllegalArgumentException.class) + public void testNoName() { + Histogram.builder().build(); + } + + @Test(expected = NullPointerException.class) + public void testNullName() { + Histogram.builder().name(null); + } + + @Test + public void testDuplicateClassicBuckets() { + Histogram histogram = + Histogram.builder().name("test").classicUpperBounds(0, 3, 17, 3, 21).build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testUnsortedBuckets() { + Histogram histogram = Histogram.builder().name("test").classicUpperBounds(0.2, 0.1).build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testEmptyBuckets() { + Histogram histogram = Histogram.builder().name("test").classicUpperBounds().build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testBucketsIncludePositiveInfinity() { + Histogram histogram = Histogram.builder() - .name("test") - .labelNames("label", "le"); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalLabelNameConstLabels() { + .name("test") + .classicUpperBounds(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY) + .build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test + public void testLinearBuckets() { + Histogram histogram = + Histogram.builder().name("test").classicLinearUpperBounds(0.1, 0.1, 10).build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + Assert.assertEquals( + Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY), + upperBounds); + } + + @Test + public void testExponentialBuckets() { + Histogram histogram = + Histogram.builder().classicExponentialUpperBounds(2, 2.5, 3).name("test").build(); + List upperBounds = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getUpperBound) + .collect(Collectors.toList()); + assertEquals(Arrays.asList(2.0, 5.0, 12.5, Double.POSITIVE_INFINITY), upperBounds); + } + + @Test(expected = RuntimeException.class) + public void testBucketsIncludeNaN() { + Histogram.builder().name("test").classicUpperBounds(0.01, 0.1, 1.0, Double.NaN); + } + + @Test + public void testNoLabelsDefaultZeroValue() { + Histogram noLabels = Histogram.builder().name("test").build(); + assertEquals(0.0, getBucket(noLabels, 0.005).getCount(), 0.0); + assertEquals(0, getData(noLabels).getCount()); + assertEquals(0.0, getData(noLabels).getSum(), 0.0); + } + + private ClassicHistogramBucket getBucket(Histogram histogram, double le, String... labels) { + return getData(histogram, labels).getClassicBuckets().stream() + .filter(b -> b.getUpperBound() == le) + .findAny() + .orElseThrow(() -> new RuntimeException("bucket with le=" + le + " not found.")); + } + + @Test + public void testObserve() { + Histogram noLabels = Histogram.builder().name("test").build(); + noLabels.observe(2); + assertEquals(1, getData(noLabels).getCount()); + assertEquals(2.0, getData(noLabels).getSum(), .0); + assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); + noLabels.observe(4); + assertEquals(2.0, getData(noLabels).getCount(), .0); + assertEquals(6.0, getData(noLabels).getSum(), .0); + assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); + assertEquals(1.0, getBucket(noLabels, 5).getCount(), .0); + assertEquals(0.0, getBucket(noLabels, 10).getCount(), .0); + assertEquals(0.0, getBucket(noLabels, Double.POSITIVE_INFINITY).getCount(), .0); + } + + @Test + // See https://github.com/prometheus/client_java/issues/646 + public void testNegativeAmount() { + Histogram histogram = Histogram.builder() - .name("test") - .constLabels(Labels.of("label1", "value1", "le", "0.3")); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalLabelNamePrefix() { - Histogram.builder() - .name("test") - .labelNames("__hello"); - } - - @Test(expected = IllegalArgumentException.class) - public void testIllegalName() { - Histogram.builder().name("my_namespace/server.durations"); - } - - @Test(expected = IllegalArgumentException.class) - public void testNoName() { - Histogram.builder().build(); - } - - @Test(expected = NullPointerException.class) - public void testNullName() { - Histogram.builder() - .name(null); - } - - @Test - public void testDuplicateClassicBuckets() { - Histogram histogram = Histogram.builder() - .name("test") - .classicUpperBounds(0, 3, 17, 3, 21) - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); - } - - @Test - public void testUnsortedBuckets() { - Histogram histogram = Histogram.builder() - .name("test") - .classicUpperBounds(0.2, 0.1) - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); + .name("histogram") + .help("test histogram for negative values") + .classicUpperBounds(-10, -5, 0, 5, 10) + .build(); + double expectedCount = 0; + double expectedSum = 0; + for (int i = 10; i >= -11; i--) { + histogram.observe(i); + expectedCount++; + expectedSum += i; + assertEquals(expectedSum, getData(histogram).getSum(), .001); + assertEquals(expectedCount, getData(histogram).getCount(), .001); } - - @Test - public void testEmptyBuckets() { - Histogram histogram = Histogram.builder() - .name("test") - .classicUpperBounds() - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - Assert.assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); - } - - @Test - public void testBucketsIncludePositiveInfinity() { - Histogram histogram = Histogram.builder() - .name("test") - .classicUpperBounds(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY) - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); - } - - @Test - public void testLinearBuckets() { - Histogram histogram = Histogram.builder() - .name("test") - .classicLinearUpperBounds(0.1, 0.1, 10) - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY), upperBounds); - } - - @Test - public void testExponentialBuckets() { - Histogram histogram = Histogram.builder() - .classicExponentialUpperBounds(2, 2.5, 3) - .name("test") - .build(); - List upperBounds = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getUpperBound) - .collect(Collectors.toList()); - assertEquals(Arrays.asList(2.0, 5.0, 12.5, Double.POSITIVE_INFINITY), upperBounds); - } - - @Test(expected = RuntimeException.class) - public void testBucketsIncludeNaN() { + List expectedBucketCounts = + Arrays.asList(2L, 5L, 5L, 5L, 5L, 0L); // buckets -10, -5, 0, 5, 10, +Inf + List actualBucketCounts = + getData(histogram).getClassicBuckets().stream() + .map(ClassicHistogramBucket::getCount) + .collect(Collectors.toList()); + assertEquals(expectedBucketCounts, actualBucketCounts); + } + + @Test + public void testBoundaryConditions() { + Histogram histogram = Histogram.builder().name("test").build(); + histogram.observe(2.5); + assertEquals(0, getBucket(histogram, 1).getCount()); + assertEquals(1, getBucket(histogram, 2.5).getCount()); + + histogram.observe(Double.POSITIVE_INFINITY); + assertEquals(0, getBucket(histogram, 1).getCount()); + assertEquals(1, getBucket(histogram, 2.5).getCount()); + assertEquals(0, getBucket(histogram, 5).getCount()); + assertEquals(0, getBucket(histogram, 10).getCount()); + assertEquals(1, getBucket(histogram, Double.POSITIVE_INFINITY).getCount()); + } + + @Test + public void testObserveWithLabels() { + Histogram histogram = Histogram.builder() - .name("test") - .classicUpperBounds(0.01, 0.1, 1.0, Double.NaN); - } - - @Test - public void testNoLabelsDefaultZeroValue() { - Histogram noLabels = Histogram.builder().name("test").build(); - assertEquals(0.0, getBucket(noLabels, 0.005).getCount(), 0.0); - assertEquals(0, getData(noLabels).getCount()); - assertEquals(0.0, getData(noLabels).getSum(), 0.0); - } - - private ClassicHistogramBucket getBucket(Histogram histogram, double le, String... labels) { - return getData(histogram, labels).getClassicBuckets().stream() - .filter(b -> b.getUpperBound() == le) - .findAny() - .orElseThrow(() -> new RuntimeException("bucket with le=" + le + " not found.")); - } - - @Test - public void testObserve() { - Histogram noLabels = Histogram.builder() - .name("test") - .build(); - noLabels.observe(2); - assertEquals(1, getData(noLabels).getCount()); - assertEquals(2.0, getData(noLabels).getSum(), .0); - assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); - noLabels.observe(4); - assertEquals(2.0, getData(noLabels).getCount(), .0); - assertEquals(6.0, getData(noLabels).getSum(), .0); - assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 5).getCount(), .0); - assertEquals(0.0, getBucket(noLabels, 10).getCount(), .0); - assertEquals(0.0, getBucket(noLabels, Double.POSITIVE_INFINITY).getCount(), .0); - } - - @Test - // See https://github.com/prometheus/client_java/issues/646 - public void testNegativeAmount() { - Histogram histogram = Histogram.builder() - .name("histogram") - .help("test histogram for negative values") - .classicUpperBounds(-10, -5, 0, 5, 10) - .build(); - double expectedCount = 0; - double expectedSum = 0; - for (int i = 10; i >= -11; i--) { - histogram.observe(i); - expectedCount++; - expectedSum += i; - assertEquals(expectedSum, getData(histogram).getSum(), .001); - assertEquals(expectedCount, getData(histogram).getCount(), .001); - } - List expectedBucketCounts = Arrays.asList(2L, 5L, 5L, 5L, 5L, 0L); // buckets -10, -5, 0, 5, 10, +Inf - List actualBucketCounts = getData(histogram).getClassicBuckets().stream() - .map(ClassicHistogramBucket::getCount) - .collect(Collectors.toList()); - assertEquals(expectedBucketCounts, actualBucketCounts); - } - - @Test - public void testBoundaryConditions() { - Histogram histogram = Histogram.builder() - .name("test") - .build(); - histogram.observe(2.5); - assertEquals(0, getBucket(histogram, 1).getCount()); - assertEquals(1, getBucket(histogram, 2.5).getCount()); - - histogram.observe(Double.POSITIVE_INFINITY); - assertEquals(0, getBucket(histogram, 1).getCount()); - assertEquals(1, getBucket(histogram, 2.5).getCount()); - assertEquals(0, getBucket(histogram, 5).getCount()); - assertEquals(0, getBucket(histogram, 10).getCount()); - assertEquals(1, getBucket(histogram, Double.POSITIVE_INFINITY).getCount()); - } - - @Test - public void testObserveWithLabels() { - Histogram histogram = Histogram.builder() - .name("test") - .constLabels(Labels.of("env", "prod")) - .labelNames("path", "status") - .build(); - histogram.labelValues("/hello", "200").observe(0.11); - histogram.labelValues("/hello", "200").observe(0.2); - histogram.labelValues("/hello", "500").observe(0.19); - HistogramSnapshot.HistogramDataPointSnapshot data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); - HistogramSnapshot.HistogramDataPointSnapshot data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); - assertEquals(2, data200.getCount()); - assertEquals(0.31, data200.getSum(), 0.0000001); - assertEquals(1, data500.getCount()); - assertEquals(0.19, data500.getSum(), 0.0000001); - histogram.labelValues("/hello", "200").observe(0.13); - data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); - data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); - assertEquals(3, data200.getCount()); - assertEquals(0.44, data200.getSum(), 0.0000001); - assertEquals(1, data500.getCount()); - assertEquals(0.19, data500.getSum(), 0.0000001); - } - - @Test - public void testObserveMultithreaded() throws InterruptedException, ExecutionException, TimeoutException { - // Hard to test concurrency, but let's run a couple of observations in parallel and assert none gets lost. - Histogram histogram = Histogram.builder() - .name("test") - .labelNames("status") - .build(); - int nThreads = 8; - DistributionDataPoint obs = histogram.labelValues("200"); - ExecutorService executor = Executors.newFixedThreadPool(nThreads); - CompletionService> completionService = new ExecutorCompletionService<>(executor); - CountDownLatch startSignal = new CountDownLatch(nThreads); - for (int t = 0; t < nThreads; t++) { - completionService.submit(() -> { - List snapshots = new ArrayList<>(); - startSignal.countDown(); - startSignal.await(); - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 1000; j++) { - obs.observe(1.1); - } - snapshots.add(histogram.collect()); - } - return snapshots; - }); - } - long maxCount = 0; - for (int i = 0; i < nThreads; i++) { - Future> future = completionService.take(); - List snapshots = future.get(5, TimeUnit.SECONDS); - long count = 0; - for (HistogramSnapshot snapshot : snapshots) { - Assert.assertEquals(1, snapshot.getDataPoints().size()); - HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream().findFirst().orElseThrow(RuntimeException::new); - Assert.assertTrue(data.getCount() >= (count + 1000)); // 1000 own observations plus the ones from other threads - count = data.getCount(); - } - if (count > maxCount) { - maxCount = count; + .name("test") + .constLabels(Labels.of("env", "prod")) + .labelNames("path", "status") + .build(); + histogram.labelValues("/hello", "200").observe(0.11); + histogram.labelValues("/hello", "200").observe(0.2); + histogram.labelValues("/hello", "500").observe(0.19); + HistogramSnapshot.HistogramDataPointSnapshot data200 = + getData(histogram, "env", "prod", "path", "/hello", "status", "200"); + HistogramSnapshot.HistogramDataPointSnapshot data500 = + getData(histogram, "env", "prod", "path", "/hello", "status", "500"); + assertEquals(2, data200.getCount()); + assertEquals(0.31, data200.getSum(), 0.0000001); + assertEquals(1, data500.getCount()); + assertEquals(0.19, data500.getSum(), 0.0000001); + histogram.labelValues("/hello", "200").observe(0.13); + data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); + data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); + assertEquals(3, data200.getCount()); + assertEquals(0.44, data200.getSum(), 0.0000001); + assertEquals(1, data500.getCount()); + assertEquals(0.19, data500.getSum(), 0.0000001); + } + + @Test + public void testObserveMultithreaded() + throws InterruptedException, ExecutionException, TimeoutException { + // Hard to test concurrency, but let's run a couple of observations in parallel and assert none + // gets lost. + Histogram histogram = Histogram.builder().name("test").labelNames("status").build(); + int nThreads = 8; + DistributionDataPoint obs = histogram.labelValues("200"); + ExecutorService executor = Executors.newFixedThreadPool(nThreads); + CompletionService> completionService = + new ExecutorCompletionService<>(executor); + CountDownLatch startSignal = new CountDownLatch(nThreads); + for (int t = 0; t < nThreads; t++) { + completionService.submit( + () -> { + List snapshots = new ArrayList<>(); + startSignal.countDown(); + startSignal.await(); + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 1000; j++) { + obs.observe(1.1); + } + snapshots.add(histogram.collect()); } - } - Assert.assertEquals(nThreads * 10_000, maxCount); // the last collect() has seen all observations - Assert.assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); - executor.shutdown(); - Assert.assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); + return snapshots; + }); } - - - private HistogramSnapshot.HistogramDataPointSnapshot getData(Histogram histogram, String... labels) { - return histogram.collect().getDataPoints().stream() - .filter(d -> d.getLabels().equals(Labels.of(labels))) - .findAny() - .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); + long maxCount = 0; + for (int i = 0; i < nThreads; i++) { + Future> future = completionService.take(); + List snapshots = future.get(5, TimeUnit.SECONDS); + long count = 0; + for (HistogramSnapshot snapshot : snapshots) { + Assert.assertEquals(1, snapshot.getDataPoints().size()); + HistogramSnapshot.HistogramDataPointSnapshot data = + snapshot.getDataPoints().stream().findFirst().orElseThrow(RuntimeException::new); + Assert.assertTrue( + data.getCount() + >= (count + 1000)); // 1000 own observations plus the ones from other threads + count = data.getCount(); + } + if (count > maxCount) { + maxCount = count; + } } + Assert.assertEquals( + nThreads * 10_000, maxCount); // the last collect() has seen all observations + Assert.assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); + executor.shutdown(); + Assert.assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); + } + + private HistogramSnapshot.HistogramDataPointSnapshot getData( + Histogram histogram, String... labels) { + return histogram.collect().getDataPoints().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index f2ddbc456..4175ae733 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -1,107 +1,102 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; -import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; -import org.junit.Assert; -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; - -import static org.junit.Assert.assertEquals; +import org.junit.Assert; +import org.junit.Test; public class InfoTest { - @Test - public void testInfoStrippedFromName() { - for (String name : new String[]{ - "jvm.runtime", "jvm_runtime", - "jvm.runtime.info", "jvm_runtime_info"}) { - for (String labelName : new String[]{"my.key", "my_key"}) { - Info info = Info.builder() - .name(name) - .labelNames(labelName) - .build(); - info.addLabelValues("value"); - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertEquals("name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }", TextFormat.printer().shortDebugString(protobufData)); - } - } - } - - @Test - public void testAddAndRemove() throws IOException { - Info info = Info.builder() - .name("test_info") - .labelNames("a", "b") - .build(); - Assert.assertEquals(0, info.collect().getDataPoints().size()); - info.addLabelValues("val1", "val2"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); - info.addLabelValues("val1", "val2"); // already exist, so no change - Assert.assertEquals(1, info.collect().getDataPoints().size()); - info.addLabelValues("val2", "val2"); - Assert.assertEquals(2, info.collect().getDataPoints().size()); - info.remove("val1", "val3"); // does not exist, so no change - Assert.assertEquals(2, info.collect().getDataPoints().size()); - info.remove("val1", "val2"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); - info.remove("val2", "val2"); - Assert.assertEquals(0, info.collect().getDataPoints().size()); + @Test + public void testInfoStrippedFromName() { + for (String name : + new String[] { + "jvm.runtime", "jvm_runtime", + "jvm.runtime.info", "jvm_runtime_info" + }) { + for (String labelName : new String[] {"my.key", "my_key"}) { + Info info = Info.builder().name(name).labelNames(labelName).build(); + info.addLabelValues("value"); + Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); + assertEquals( + "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }", + TextFormat.printer().shortDebugString(protobufData)); + } } + } - @Test - public void testSet() throws IOException { - Info info = Info.builder() - .name("target_info") - .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) - .labelNames("service.version") - .build(); - info.setLabelValues("1.0.0"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); - info.setLabelValues("2.0.0"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); - assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info); - } + @Test + public void testAddAndRemove() throws IOException { + Info info = Info.builder().name("test_info").labelNames("a", "b").build(); + Assert.assertEquals(0, info.collect().getDataPoints().size()); + info.addLabelValues("val1", "val2"); + Assert.assertEquals(1, info.collect().getDataPoints().size()); + info.addLabelValues("val1", "val2"); // already exist, so no change + Assert.assertEquals(1, info.collect().getDataPoints().size()); + info.addLabelValues("val2", "val2"); + Assert.assertEquals(2, info.collect().getDataPoints().size()); + info.remove("val1", "val3"); // does not exist, so no change + Assert.assertEquals(2, info.collect().getDataPoints().size()); + info.remove("val1", "val2"); + Assert.assertEquals(1, info.collect().getDataPoints().size()); + info.remove("val2", "val2"); + Assert.assertEquals(0, info.collect().getDataPoints().size()); + } - @Test - public void testConstLabelsOnly() throws IOException { - Info info = Info.builder() - .name("target_info") - .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) - .build(); - Assert.assertEquals(1, info.collect().getDataPoints().size()); - assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); - } - - @Test(expected = IllegalArgumentException.class) - public void testConstLabelsDuplicate1() { + @Test + public void testSet() throws IOException { + Info info = Info.builder() - .constLabels(Labels.of("a_1", "val1")) - .labelNames("a.1") - .build(); - } + .name("target_info") + .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) + .labelNames("service.version") + .build(); + info.setLabelValues("1.0.0"); + Assert.assertEquals(1, info.collect().getDataPoints().size()); + info.setLabelValues("2.0.0"); + Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertTextFormat( + "target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", + info); + } - @Test(expected = IllegalArgumentException.class) - public void testConstLabelsDuplicate2() { + @Test + public void testConstLabelsOnly() throws IOException { + Info info = Info.builder() - .labelNames("a_1") - .constLabels(Labels.of("a.1", "val1")) - .build(); - } + .name("target_info") + .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) + .build(); + Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsDuplicate1() { + Info.builder().constLabels(Labels.of("a_1", "val1")).labelNames("a.1").build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testConstLabelsDuplicate2() { + Info.builder().labelNames("a_1").constLabels(Labels.of("a.1", "val1")).build(); + } - private void assertTextFormat(String expected, Info info) throws IOException { - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - writer.write(outputStream, MetricSnapshots.of(info.collect())); - String result = outputStream.toString(StandardCharsets.UTF_8.name()); - if (!result.contains(expected)) { - throw new AssertionError(expected + " is not contained in the following output:\n" + result); - } + private void assertTextFormat(String expected, Info info) throws IOException { + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + writer.write(outputStream, MetricSnapshots.of(info.collect())); + String result = outputStream.toString(StandardCharsets.UTF_8.name()); + if (!result.contains(expected)) { + throw new AssertionError(expected + " is not contained in the following output:\n" + result); } + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java index 3461d959e..ce43b141c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java @@ -1,79 +1,89 @@ package io.prometheus.metrics.core.metrics; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; public class SlidingWindowTest { - class Observer { + class Observer { - final List values = new ArrayList<>(); + final List values = new ArrayList<>(); - public void observe(double value) { - values.add(value); - } + public void observe(double value) { + values.add(value); + } - void assertValues(double... expectedValues) { - ArrayList expectedList = new ArrayList<>(); - for (double expectedValue : expectedValues) { - expectedList.add(expectedValue); - } - Assert.assertEquals("Start time: " + startTime + ", current time: " + currentTimeMillis.get() + ", elapsed time: " + (currentTimeMillis.get() - startTime), expectedList, values); - } + void assertValues(double... expectedValues) { + ArrayList expectedList = new ArrayList<>(); + for (double expectedValue : expectedValues) { + expectedList.add(expectedValue); + } + Assert.assertEquals( + "Start time: " + + startTime + + ", current time: " + + currentTimeMillis.get() + + ", elapsed time: " + + (currentTimeMillis.get() - startTime), + expectedList, + values); } + } - private long startTime; - private final AtomicLong currentTimeMillis = new AtomicLong(); - private SlidingWindow ringBuffer; - private final long maxAgeSeconds = 30; - private final int ageBuckets = 5; - private final long timeBetweenRotateMillis = maxAgeSeconds * 1000 / ageBuckets + 2; + private long startTime; + private final AtomicLong currentTimeMillis = new AtomicLong(); + private SlidingWindow ringBuffer; + private final long maxAgeSeconds = 30; + private final int ageBuckets = 5; + private final long timeBetweenRotateMillis = maxAgeSeconds * 1000 / ageBuckets + 2; - @Before - public void setUp() { - startTime = System.currentTimeMillis(); - currentTimeMillis.set(startTime); - ringBuffer = new SlidingWindow<>(Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets); - ringBuffer.currentTimeMillis = currentTimeMillis::get; - } + @Before + public void setUp() { + startTime = System.currentTimeMillis(); + currentTimeMillis.set(startTime); + ringBuffer = + new SlidingWindow<>( + Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets); + ringBuffer.currentTimeMillis = currentTimeMillis::get; + } - @Test - public void testRotate() { - for (int i=0; i first observation evicted - ringBuffer.current().assertValues(2.0); - ringBuffer.observe(3.0); - ringBuffer.current().assertValues(2.0, 3.0); - currentTimeMillis.addAndGet(2 * timeBetweenRotateMillis); // 7/5 of max age - ringBuffer.current().assertValues(3.0); - currentTimeMillis.addAndGet(3 * timeBetweenRotateMillis); // 10/5 of max age - ringBuffer.current().assertValues(); // empty - } + @Test + public void testMultiRotate() { + ringBuffer.observe(1.0); + currentTimeMillis.addAndGet(2 * timeBetweenRotateMillis); // 2/5 of max aqe + ringBuffer.observe(2.0); + ringBuffer.current().assertValues(1.0, 2.0); + currentTimeMillis.addAndGet( + 3 * timeBetweenRotateMillis); // 5/5 of max age -> first observation evicted + ringBuffer.current().assertValues(2.0); + ringBuffer.observe(3.0); + ringBuffer.current().assertValues(2.0, 3.0); + currentTimeMillis.addAndGet(2 * timeBetweenRotateMillis); // 7/5 of max age + ringBuffer.current().assertValues(3.0); + currentTimeMillis.addAndGet(3 * timeBetweenRotateMillis); // 10/5 of max age + ringBuffer.current().assertValues(); // empty + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java index 5a82cdb48..776aeacde 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java @@ -7,69 +7,68 @@ public class StateSetTest { - enum MyFeatureFlag { - EXPERIMENTAL_FEATURE_1 { - @Override - public String toString() { - return "feature1"; - } - }, + enum MyFeatureFlag { + EXPERIMENTAL_FEATURE_1 { + @Override + public String toString() { + return "feature1"; + } + }, - EXPERIMENTAL_FEATURE_2 { - @Override - public String toString() { - return "feature2"; - } - } + EXPERIMENTAL_FEATURE_2 { + @Override + public String toString() { + return "feature2"; + } } + } - @Test - public void testEnumStateSet() { - StateSet stateSet = StateSet.builder() - .name("feature_flags") - .labelNames("environment") - .states(MyFeatureFlag.class) - .build(); - stateSet.labelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); - stateSet.labelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); - StateSetSnapshot snapshot = stateSet.collect(); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - Assert.assertEquals(2, getData(stateSet, "environment", "dev").size()); - Assert.assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); - Assert.assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); - Assert.assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); - Assert.assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); - Assert.assertEquals(2, getData(stateSet, "environment", "prod").size()); - Assert.assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); - Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(0)); - Assert.assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); - Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(1)); - } + @Test + public void testEnumStateSet() { + StateSet stateSet = + StateSet.builder() + .name("feature_flags") + .labelNames("environment") + .states(MyFeatureFlag.class) + .build(); + stateSet.labelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); + stateSet.labelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); + StateSetSnapshot snapshot = stateSet.collect(); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + Assert.assertEquals(2, getData(stateSet, "environment", "dev").size()); + Assert.assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); + Assert.assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); + Assert.assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); + Assert.assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); + Assert.assertEquals(2, getData(stateSet, "environment", "prod").size()); + Assert.assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); + Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(0)); + Assert.assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); + Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(1)); + } - @Test - public void testDefaultFalse() { - StateSet stateSet = StateSet.builder() - .name("test") - .states("state1", "state2", "state3") - .build(); - Assert.assertEquals(3, getData(stateSet).size()); - Assert.assertEquals("state1", getData(stateSet).getName(0)); - Assert.assertFalse(getData(stateSet).isTrue(0)); - Assert.assertEquals("state2", getData(stateSet).getName(1)); - Assert.assertFalse(getData(stateSet).isTrue(1)); - Assert.assertEquals("state3", getData(stateSet).getName(2)); - Assert.assertFalse(getData(stateSet).isTrue(2)); - } + @Test + public void testDefaultFalse() { + StateSet stateSet = + StateSet.builder().name("test").states("state1", "state2", "state3").build(); + Assert.assertEquals(3, getData(stateSet).size()); + Assert.assertEquals("state1", getData(stateSet).getName(0)); + Assert.assertFalse(getData(stateSet).isTrue(0)); + Assert.assertEquals("state2", getData(stateSet).getName(1)); + Assert.assertFalse(getData(stateSet).isTrue(1)); + Assert.assertEquals("state3", getData(stateSet).getName(2)); + Assert.assertFalse(getData(stateSet).isTrue(2)); + } - private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) { - return stateSet.collect().getDataPoints().stream() - .filter(d -> d.getLabels().equals(Labels.of(labels))) - .findAny() - .orElseThrow(() -> new RuntimeException("stateset with labels " + labels + " not found")); - } + private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) { + return stateSet.collect().getDataPoints().stream() + .filter(d -> d.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(() -> new RuntimeException("stateset with labels " + labels + " not found")); + } - @Test(expected = IllegalStateException.class) - public void testStatesCannotBeEmpty() { - StateSet.builder().name("invalid").build(); - } + @Test(expected = IllegalStateException.class) + public void testStatesCannotBeEmpty() { + StateSet.builder().name("invalid").build(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index dd2c4355a..d77ec6e83 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -1,69 +1,69 @@ package io.prometheus.metrics.core.metrics; -import org.junit.Assert; -import org.junit.Test; - import java.lang.reflect.Field; import java.util.Map; +import org.junit.Assert; +import org.junit.Test; public class StatefulMetricTest { - @Test - public void testLabelRemoveWhileCollecting() throws Exception { - Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build(); - Field data = counter.getClass().getSuperclass().getDeclaredField("data"); - data.setAccessible(true); + @Test + public void testLabelRemoveWhileCollecting() throws Exception { + Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build(); + Field data = counter.getClass().getSuperclass().getDeclaredField("data"); + data.setAccessible(true); - counter.labelValues("a", "b").inc(1.0); - counter.labelValues("c", "d").inc(3.0); - counter.labelValues("e", "f").inc(7.0); + counter.labelValues("a", "b").inc(1.0); + counter.labelValues("c", "d").inc(3.0); + counter.labelValues("e", "f").inc(7.0); - // collect() iterates over data.entrySet(). - // remove() removes entries from data. - // Make sure iterating does not yield null while removing. + // collect() iterates over data.entrySet(). + // remove() removes entries from data. + // Make sure iterating does not yield null while removing. - int i = 0; - for (Map.Entry entry : ((Map) data.get(counter)).entrySet()) { - i++; - if (i == 2) { - counter.remove("c", "d"); - counter.remove("e", "f"); - } - Assert.assertNotNull(entry.getKey()); - Assert.assertNotNull(entry.getValue()); - } + int i = 0; + for (Map.Entry entry : ((Map) data.get(counter)).entrySet()) { + i++; + if (i == 2) { + counter.remove("c", "d"); + counter.remove("e", "f"); + } + Assert.assertNotNull(entry.getKey()); + Assert.assertNotNull(entry.getValue()); } + } - @Test - public void testClear() { - Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build(); - counter.labelValues("a", "b").inc(3.0); - counter.labelValues("c", "d").inc(3.0); - counter.labelValues("a", "b").inc(); - Assert.assertEquals(2, counter.collect().getDataPoints().size()); + @Test + public void testClear() { + Counter counter = Counter.builder().name("test").labelNames("label1", "label2").build(); + counter.labelValues("a", "b").inc(3.0); + counter.labelValues("c", "d").inc(3.0); + counter.labelValues("a", "b").inc(); + Assert.assertEquals(2, counter.collect().getDataPoints().size()); - counter.clear(); - Assert.assertEquals(0, counter.collect().getDataPoints().size()); + counter.clear(); + Assert.assertEquals(0, counter.collect().getDataPoints().size()); - counter.labelValues("a", "b").inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - } + counter.labelValues("a", "b").inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + } - @Test - public void testClearNoLabels() { - Counter counter = Counter.builder().name("test").build(); - counter.inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + @Test + public void testClearNoLabels() { + Counter counter = Counter.builder().name("test").build(); + counter.inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); - counter.clear(); - // No labels is always present, but as no value has been observed after clear() the value should be 0.0 - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + counter.clear(); + // No labels is always present, but as no value has been observed after clear() the value should + // be 0.0 + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); - // Making inc() works correctly after clear() - counter.inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); - } + // Making inc() works correctly after clear() + counter.inc(); + Assert.assertEquals(1, counter.collect().getDataPoints().size()); + Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java index cbd9ef53f..8231d86f2 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java @@ -2,5 +2,5 @@ public class SummaryWithCallbackTest { - // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. + // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java index 489bcac33..95a8b90fb 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java @@ -5,9 +5,9 @@ public class TestUtil { - public static void assertExemplarEquals(Exemplar expected, Exemplar actual) { - // ignore timestamp - Assert.assertEquals(expected.getValue(), actual.getValue(), 0.00001); - Assert.assertEquals(expected.getLabels(), actual.getLabels()); - } + public static void assertExemplarEquals(Exemplar expected, Exemplar actual) { + // ignore timestamp + Assert.assertEquals(expected.getValue(), actual.getValue(), 0.00001); + Assert.assertEquals(expected.getLabels(), actual.getLabels()); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java index 996e199db..be6d17784 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java @@ -2,16 +2,17 @@ public class TodoTest { - // if a metric with labels is created but never used it has no data. - // The registry's collect() method should skip those metrics to avoid illegal protobuf or text format. + // if a metric with labels is created but never used it has no data. + // The registry's collect() method should skip those metrics to avoid illegal protobuf or text + // format. - // callback versions of metrics + // callback versions of metrics - // build() called with name == null + // build() called with name == null - // call inc() without labels, but the metric was created with labels + // call inc() without labels, but the metric was created with labels - // call inc() with labels, but the metric was created without labels + // call inc() with labels, but the metric was created without labels - // for performance: Use return value of withLabels() directly + // for performance: Use return value of withLabels() directly } diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpExchange.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpExchange.java index 7a9f5846b..b7ac63b28 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpExchange.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpExchange.java @@ -3,11 +3,14 @@ import java.io.IOException; public interface PrometheusHttpExchange extends AutoCloseable { - PrometheusHttpRequest getRequest(); - PrometheusHttpResponse getResponse(); - void handleException(IOException e) throws IOException; - void handleException(RuntimeException e); + PrometheusHttpRequest getRequest(); - @Override - void close(); + PrometheusHttpResponse getResponse(); + + void handleException(IOException e) throws IOException; + + void handleException(RuntimeException e); + + @Override + void close(); } diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java index f7b5346a5..954facfef 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java @@ -1,78 +1,65 @@ package io.prometheus.metrics.exporter.common; +import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Enumeration; -import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; - public interface PrometheusHttpRequest extends PrometheusScrapeRequest { - /** - * See {@code jakarta.servlet.http.HttpServletRequest.getQueryString()} - */ - String getQueryString(); + /** See {@code jakarta.servlet.http.HttpServletRequest.getQueryString()} */ + String getQueryString(); - /** - * See {@code jakarta.servlet.http.HttpServletRequest.getHeaders(String)} - */ - Enumeration getHeaders(String name); + /** See {@code jakarta.servlet.http.HttpServletRequest.getHeaders(String)} */ + Enumeration getHeaders(String name); - /** - * See {@code jakarta.servlet.http.HttpServletRequest.getMethod()} - */ - String getMethod(); + /** See {@code jakarta.servlet.http.HttpServletRequest.getMethod()} */ + String getMethod(); - /** - * See {@code jakarta.servlet.http.HttpServletRequest.getHeader(String)} - */ - default String getHeader(String name) { - Enumeration headers = getHeaders(name); - if (headers == null || !headers.hasMoreElements()) { - return null; - } else { - return headers.nextElement(); - } + /** See {@code jakarta.servlet.http.HttpServletRequest.getHeader(String)} */ + default String getHeader(String name) { + Enumeration headers = getHeaders(name); + if (headers == null || !headers.hasMoreElements()) { + return null; + } else { + return headers.nextElement(); } + } - /** - * See {@code jakarta.servlet.ServletRequest.getParameter(String)} - */ - default String getParameter(String name) { - String[] values = getParameterValues(name); - if (values == null || values.length == 0) { - return null; - } else { - return values[0]; - } + /** See {@code jakarta.servlet.ServletRequest.getParameter(String)} */ + default String getParameter(String name) { + String[] values = getParameterValues(name); + if (values == null || values.length == 0) { + return null; + } else { + return values[0]; } + } - /** - * See {@code jakarta.servlet.ServletRequest.getParameterValues(String)} - */ - default String[] getParameterValues(String name) { - try { - ArrayList result = new ArrayList<>(); - String queryString = getQueryString(); - if (queryString != null) { - String[] pairs = queryString.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - if (idx != -1 && URLDecoder.decode(pair.substring(0, idx), "UTF-8").equals(name)) { - result.add(URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); - } - } - } - if (result.isEmpty()) { - // Servlet API: getParameterValues() returns null if the parameter does not exist. - return null; - } else { - return result.toArray(new String[0]); - } - } catch (UnsupportedEncodingException e) { - // UTF-8 encoding not supported. - throw new RuntimeException(e); + /** See {@code jakarta.servlet.ServletRequest.getParameterValues(String)} */ + default String[] getParameterValues(String name) { + try { + ArrayList result = new ArrayList<>(); + String queryString = getQueryString(); + if (queryString != null) { + String[] pairs = queryString.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + if (idx != -1 && URLDecoder.decode(pair.substring(0, idx), "UTF-8").equals(name)) { + result.add(URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); + } } + } + if (result.isEmpty()) { + // Servlet API: getParameterValues() returns null if the parameter does not exist. + return null; + } else { + return result.toArray(new String[0]); + } + } catch (UnsupportedEncodingException e) { + // UTF-8 encoding not supported. + throw new RuntimeException(e); } + } } diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpResponse.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpResponse.java index 4e3db6955..b3dd4e2fb 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpResponse.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpResponse.java @@ -5,14 +5,13 @@ public interface PrometheusHttpResponse { - /** - * See {@code jakarta.servlet.http.HttpServletResponse.setHeader(String, String)} - */ - void setHeader(String name, String value); + /** See {@code jakarta.servlet.http.HttpServletResponse.setHeader(String, String)} */ + void setHeader(String name, String value); - /** - * This is equivalent to calling {@link com.sun.net.httpserver.HttpExchange#sendResponseHeaders(int, long)} - * followed by {@link com.sun.net.httpserver.HttpExchange#getResponseBody()}. - */ - OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException; + /** + * This is equivalent to calling {@link + * com.sun.net.httpserver.HttpExchange#sendResponseHeaders(int, long)} followed by {@link + * com.sun.net.httpserver.HttpExchange#getResponseBody()}. + */ + OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException; } diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index 5155457df..dee7098fb 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -7,7 +7,6 @@ import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -18,157 +17,168 @@ import java.util.function.Predicate; import java.util.zip.GZIPOutputStream; -/** - * Prometheus scrape endpoint. - */ +/** Prometheus scrape endpoint. */ public class PrometheusScrapeHandler { - private final PrometheusRegistry registry; - private final ExpositionFormats expositionFormats; - private final Predicate nameFilter; - private AtomicInteger lastResponseSize = new AtomicInteger(2 << 9); // 0.5 MB - - public PrometheusScrapeHandler() { - this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); - } - - public PrometheusScrapeHandler(PrometheusRegistry registry) { - this(PrometheusProperties.get(), registry); - } - - public PrometheusScrapeHandler(PrometheusProperties config) { - this(config, PrometheusRegistry.defaultRegistry); - } - - public PrometheusScrapeHandler(PrometheusProperties config, PrometheusRegistry registry) { - this.expositionFormats = ExpositionFormats.init(config.getExporterProperties()); - this.registry = registry; - this.nameFilter = makeNameFilter(config.getExporterFilterProperties()); - } - - public void handleRequest(PrometheusHttpExchange exchange) throws IOException { - try { - PrometheusHttpRequest request = exchange.getRequest(); - PrometheusHttpResponse response = exchange.getResponse(); - MetricSnapshots snapshots = scrape(request); - if (writeDebugResponse(snapshots, exchange)) { - return; - } - ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream(lastResponseSize.get() + 1024); - String acceptHeader = request.getHeader("Accept"); - ExpositionFormatWriter writer = expositionFormats.findWriter(acceptHeader); - writer.write(responseBuffer, snapshots); - lastResponseSize.set(responseBuffer.size()); - response.setHeader("Content-Type", writer.getContentType()); - - if (shouldUseCompression(request)) { - response.setHeader("Content-Encoding", "gzip"); - try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(response.sendHeadersAndGetBody(200, 0))) { - responseBuffer.writeTo(gzipOutputStream); - } - } else { - int contentLength = responseBuffer.size(); - if (contentLength > 0) { - response.setHeader("Content-Length", String.valueOf(contentLength)); - } - if (request.getMethod().equals("HEAD")) { - // The HTTPServer implementation will throw an Exception if we close the output stream - // without sending a response body, so let's not close the output stream in case of a HEAD response. - response.sendHeadersAndGetBody(200, -1); - } else { - try (OutputStream outputStream = response.sendHeadersAndGetBody(200, contentLength)) { - responseBuffer.writeTo(outputStream); - } - } - } - } catch (IOException e) { - exchange.handleException(e); - } catch (RuntimeException e) { - exchange.handleException(e); - } finally { - exchange.close(); + private final PrometheusRegistry registry; + private final ExpositionFormats expositionFormats; + private final Predicate nameFilter; + private AtomicInteger lastResponseSize = new AtomicInteger(2 << 9); // 0.5 MB + + public PrometheusScrapeHandler() { + this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); + } + + public PrometheusScrapeHandler(PrometheusRegistry registry) { + this(PrometheusProperties.get(), registry); + } + + public PrometheusScrapeHandler(PrometheusProperties config) { + this(config, PrometheusRegistry.defaultRegistry); + } + + public PrometheusScrapeHandler(PrometheusProperties config, PrometheusRegistry registry) { + this.expositionFormats = ExpositionFormats.init(config.getExporterProperties()); + this.registry = registry; + this.nameFilter = makeNameFilter(config.getExporterFilterProperties()); + } + + public void handleRequest(PrometheusHttpExchange exchange) throws IOException { + try { + PrometheusHttpRequest request = exchange.getRequest(); + PrometheusHttpResponse response = exchange.getResponse(); + MetricSnapshots snapshots = scrape(request); + if (writeDebugResponse(snapshots, exchange)) { + return; + } + ByteArrayOutputStream responseBuffer = + new ByteArrayOutputStream(lastResponseSize.get() + 1024); + String acceptHeader = request.getHeader("Accept"); + ExpositionFormatWriter writer = expositionFormats.findWriter(acceptHeader); + writer.write(responseBuffer, snapshots); + lastResponseSize.set(responseBuffer.size()); + response.setHeader("Content-Type", writer.getContentType()); + + if (shouldUseCompression(request)) { + response.setHeader("Content-Encoding", "gzip"); + try (GZIPOutputStream gzipOutputStream = + new GZIPOutputStream(response.sendHeadersAndGetBody(200, 0))) { + responseBuffer.writeTo(gzipOutputStream); } - } - - private Predicate makeNameFilter(ExporterFilterProperties props) { - if (props.getAllowedMetricNames() == null && props.getExcludedMetricNames() == null && props.getAllowedMetricNamePrefixes() == null && props.getExcludedMetricNamePrefixes() == null) { - return null; + } else { + int contentLength = responseBuffer.size(); + if (contentLength > 0) { + response.setHeader("Content-Length", String.valueOf(contentLength)); + } + if (request.getMethod().equals("HEAD")) { + // The HTTPServer implementation will throw an Exception if we close the output stream + // without sending a response body, so let's not close the output stream in case of a HEAD + // response. + response.sendHeadersAndGetBody(200, -1); } else { - return MetricNameFilter.builder() - .nameMustBeEqualTo(props.getAllowedMetricNames()) - .nameMustNotBeEqualTo(props.getExcludedMetricNames()) - .nameMustStartWith(props.getAllowedMetricNamePrefixes()) - .nameMustNotStartWith(props.getExcludedMetricNamePrefixes()) - .build(); + try (OutputStream outputStream = response.sendHeadersAndGetBody(200, contentLength)) { + responseBuffer.writeTo(outputStream); + } } + } + } catch (IOException e) { + exchange.handleException(e); + } catch (RuntimeException e) { + exchange.handleException(e); + } finally { + exchange.close(); + } + } + + private Predicate makeNameFilter(ExporterFilterProperties props) { + if (props.getAllowedMetricNames() == null + && props.getExcludedMetricNames() == null + && props.getAllowedMetricNamePrefixes() == null + && props.getExcludedMetricNamePrefixes() == null) { + return null; + } else { + return MetricNameFilter.builder() + .nameMustBeEqualTo(props.getAllowedMetricNames()) + .nameMustNotBeEqualTo(props.getExcludedMetricNames()) + .nameMustStartWith(props.getAllowedMetricNamePrefixes()) + .nameMustNotStartWith(props.getExcludedMetricNamePrefixes()) + .build(); } + } - private MetricSnapshots scrape(PrometheusHttpRequest request) { + private MetricSnapshots scrape(PrometheusHttpRequest request) { - Predicate filter = makeNameFilter(request.getParameterValues("name[]")); - if (filter != null) { - return registry.scrape(filter, request); - } else { - return registry.scrape(request); - } + Predicate filter = makeNameFilter(request.getParameterValues("name[]")); + if (filter != null) { + return registry.scrape(filter, request); + } else { + return registry.scrape(request); } + } - private Predicate makeNameFilter(String[] includedNames) { - Predicate result = null; - if (includedNames != null && includedNames.length > 0) { - result = MetricNameFilter.builder().nameMustBeEqualTo(includedNames).build(); - } - if (result != null && nameFilter != null) { - result = result.and(nameFilter); - } else if (nameFilter != null) { - result = nameFilter; - } - return result; + private Predicate makeNameFilter(String[] includedNames) { + Predicate result = null; + if (includedNames != null && includedNames.length > 0) { + result = MetricNameFilter.builder().nameMustBeEqualTo(includedNames).build(); } - - private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExchange exchange) throws IOException { - String debugParam = exchange.getRequest().getParameter("debug"); - PrometheusHttpResponse response = exchange.getResponse(); - if (debugParam == null) { - return false; - } else { - response.setHeader("Content-Type", "text/plain; charset=utf-8"); - boolean supportedFormat = Arrays.asList("openmetrics", "text", "prometheus-protobuf").contains(debugParam); - int responseStatus = supportedFormat ? 200 : 500; - OutputStream body = response.sendHeadersAndGetBody(responseStatus, 0); - switch (debugParam) { - case "openmetrics": - expositionFormats.getOpenMetricsTextFormatWriter().write(body, snapshots); - break; - case "text": - expositionFormats.getPrometheusTextFormatWriter().write(body, snapshots); - break; - case "prometheus-protobuf": - String debugString = expositionFormats.getPrometheusProtobufWriter().toDebugString(snapshots); - body.write(debugString.getBytes(StandardCharsets.UTF_8)); - break; - default: - body.write(("debug=" + debugParam + ": Unsupported query parameter. Valid values are 'openmetrics', 'text', and 'prometheus-protobuf'.").getBytes(StandardCharsets.UTF_8)); - break; - } - return true; - } + if (result != null && nameFilter != null) { + result = result.and(nameFilter); + } else if (nameFilter != null) { + result = nameFilter; } + return result; + } + + private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExchange exchange) + throws IOException { + String debugParam = exchange.getRequest().getParameter("debug"); + PrometheusHttpResponse response = exchange.getResponse(); + if (debugParam == null) { + return false; + } else { + response.setHeader("Content-Type", "text/plain; charset=utf-8"); + boolean supportedFormat = + Arrays.asList("openmetrics", "text", "prometheus-protobuf").contains(debugParam); + int responseStatus = supportedFormat ? 200 : 500; + OutputStream body = response.sendHeadersAndGetBody(responseStatus, 0); + switch (debugParam) { + case "openmetrics": + expositionFormats.getOpenMetricsTextFormatWriter().write(body, snapshots); + break; + case "text": + expositionFormats.getPrometheusTextFormatWriter().write(body, snapshots); + break; + case "prometheus-protobuf": + String debugString = + expositionFormats.getPrometheusProtobufWriter().toDebugString(snapshots); + body.write(debugString.getBytes(StandardCharsets.UTF_8)); + break; + default: + body.write( + ("debug=" + + debugParam + + ": Unsupported query parameter. Valid values are 'openmetrics', 'text', and 'prometheus-protobuf'.") + .getBytes(StandardCharsets.UTF_8)); + break; + } + return true; + } + } - private boolean shouldUseCompression(PrometheusHttpRequest request) { - Enumeration encodingHeaders = request.getHeaders("Accept-Encoding"); - if (encodingHeaders == null) { - return false; - } - while (encodingHeaders.hasMoreElements()) { - String encodingHeader = encodingHeaders.nextElement(); - String[] encodings = encodingHeader.split(","); - for (String encoding : encodings) { - if (encoding.trim().equalsIgnoreCase("gzip")) { - return true; - } - } + private boolean shouldUseCompression(PrometheusHttpRequest request) { + Enumeration encodingHeaders = request.getHeaders("Accept-Encoding"); + if (encodingHeaders == null) { + return false; + } + while (encodingHeaders.hasMoreElements()) { + String encodingHeader = encodingHeaders.nextElement(); + String[] encodings = encodingHeader.split(","); + for (String encoding : encodings) { + if (encoding.trim().equalsIgnoreCase("gzip")) { + return true; } - return false; + } } + return false; + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java index 0bf3b5cc2..eeb2f70f6 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java @@ -2,69 +2,67 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; - import java.io.IOException; import java.nio.charset.StandardCharsets; -/** - * Handler for the / endpoint - */ +/** Handler for the / endpoint */ public class DefaultHandler implements HttpHandler { - private final byte[] responseBytes; - private final String contentType; + private final byte[] responseBytes; + private final String contentType; - public DefaultHandler() { - String responseString = "" + - "\n" + - "Prometheus Java Client\n" + - "\n" + - "

      Prometheus Java Client

      \n" + - "

      Metrics Path

      \n" + - "The metrics path is /metrics.\n" + - "

      Name Filter

      \n" + - "If you want to scrape only specific metrics, use the name[] parameter like this:\n" + - "\n" + - "You can also use multiple name[] parameters to query multiple metrics:\n" + - "\n" + - "The name[] parameter can be used by the Prometheus server for scraping. Add the following snippet to your scrape job configuration in prometheus.yaml:\n" + - "
      \n" +
      -                "params:\n" +
      -                "    name[]:\n" +
      -                "        - my_metric_a\n" +
      -                "        - my_metric_b\n" +
      -                "
      \n" + - "

      Debug Parameter

      \n" + - "The Prometheus Java metrics library supports multiple exposition formats.\n" + - "The Prometheus server sends the Accept header to indicate which format it accepts.\n" + - "By default, the Prometheus server accepts OpenMetrics text format, unless the Prometheus server is started with feature flag --enable-feature=native-histograms,\n" + - "in which case the default is Prometheus protobuf.\n" + - "The Prometheus Java metrics library supports a debug query parameter for viewing the different formats in a Web browser:\n" + - "\n" + - "Note that the debug parameter is only for viewing different formats in a Web browser, it should not be used by the Prometheus server for scraping. The Prometheus server uses the Accept header for indicating which format it accepts.\n" + - "\n" + - "\n"; - this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); - this.contentType = "text/html; charset=utf-8"; - } + public DefaultHandler() { + String responseString = + "" + + "\n" + + "Prometheus Java Client\n" + + "\n" + + "

      Prometheus Java Client

      \n" + + "

      Metrics Path

      \n" + + "The metrics path is /metrics.\n" + + "

      Name Filter

      \n" + + "If you want to scrape only specific metrics, use the name[] parameter like this:\n" + + "\n" + + "You can also use multiple name[] parameters to query multiple metrics:\n" + + "\n" + + "The name[] parameter can be used by the Prometheus server for scraping. Add the following snippet to your scrape job configuration in prometheus.yaml:\n" + + "
      \n"
      +            + "params:\n"
      +            + "    name[]:\n"
      +            + "        - my_metric_a\n"
      +            + "        - my_metric_b\n"
      +            + "
      \n" + + "

      Debug Parameter

      \n" + + "The Prometheus Java metrics library supports multiple exposition formats.\n" + + "The Prometheus server sends the Accept header to indicate which format it accepts.\n" + + "By default, the Prometheus server accepts OpenMetrics text format, unless the Prometheus server is started with feature flag --enable-feature=native-histograms,\n" + + "in which case the default is Prometheus protobuf.\n" + + "The Prometheus Java metrics library supports a debug query parameter for viewing the different formats in a Web browser:\n" + + "\n" + + "Note that the debug parameter is only for viewing different formats in a Web browser, it should not be used by the Prometheus server for scraping. The Prometheus server uses the Accept header for indicating which format it accepts.\n" + + "\n" + + "\n"; + this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); + this.contentType = "text/html; charset=utf-8"; + } - @Override - public void handle(HttpExchange exchange) throws IOException { - try { - exchange.getResponseHeaders().set("Content-Type", contentType); - exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); - exchange.sendResponseHeaders(200, responseBytes.length); - exchange.getResponseBody().write(responseBytes); - } finally { - exchange.close(); - } + @Override + public void handle(HttpExchange exchange) throws IOException { + try { + exchange.getResponseHeaders().set("Content-Type", contentType); + exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); + exchange.sendResponseHeaders(200, responseBytes.length); + exchange.getResponseBody().write(responseBytes); + } finally { + exchange.close(); } + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index de572ba9f..ad13d70af 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -8,7 +8,6 @@ import com.sun.net.httpserver.HttpsServer; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; - import java.io.Closeable; import java.io.IOException; import java.net.InetAddress; @@ -22,251 +21,245 @@ /** * Expose Prometheus metrics using a plain Java HttpServer. - *

      - * Example Usage: - *

      - * {@code
      + *
      + * 

      Example Usage: + * + *

      {@code
        * HTTPServer server = HTTPServer.builder()
        *     .port(9090)
        *     .buildAndStart();
        * }
      - * */ + */ public class HTTPServer implements Closeable { - static { - if (!System.getProperties().containsKey("sun.net.httpserver.maxReqTime")) { - System.setProperty("sun.net.httpserver.maxReqTime", "60"); - } + static { + if (!System.getProperties().containsKey("sun.net.httpserver.maxReqTime")) { + System.setProperty("sun.net.httpserver.maxReqTime", "60"); + } - if (!System.getProperties().containsKey("sun.net.httpserver.maxRspTime")) { - System.setProperty("sun.net.httpserver.maxRspTime", "600"); - } + if (!System.getProperties().containsKey("sun.net.httpserver.maxRspTime")) { + System.setProperty("sun.net.httpserver.maxRspTime", "600"); } + } - protected final HttpServer server; - protected final ExecutorService executorService; + protected final HttpServer server; + protected final ExecutorService executorService; - private HTTPServer(PrometheusProperties config, ExecutorService executorService, HttpServer httpServer, PrometheusRegistry registry, Authenticator authenticator, HttpHandler defaultHandler) { - if (httpServer.getAddress() == null) { - throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); - } - this.server = httpServer; - this.executorService = executorService; - registerHandler("/", defaultHandler == null ? new DefaultHandler() : defaultHandler, authenticator); - registerHandler("/metrics", new MetricsHandler(config, registry), authenticator); - registerHandler("/-/healthy", new HealthyHandler(), authenticator); - try { - // HttpServer.start() starts the HttpServer in a new background thread. - // If we call HttpServer.start() from a thread of the executorService, - // the background thread will inherit the "daemon" property, - // i.e. the server will run as a Daemon thread. - // See https://github.com/prometheus/client_java/pull/955 - this.executorService.submit(this.server::start).get(); - // calling .get() on the Future here to avoid silently discarding errors - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } + private HTTPServer( + PrometheusProperties config, + ExecutorService executorService, + HttpServer httpServer, + PrometheusRegistry registry, + Authenticator authenticator, + HttpHandler defaultHandler) { + if (httpServer.getAddress() == null) { + throw new IllegalArgumentException("HttpServer hasn't been bound to an address"); } + this.server = httpServer; + this.executorService = executorService; + registerHandler( + "/", defaultHandler == null ? new DefaultHandler() : defaultHandler, authenticator); + registerHandler("/metrics", new MetricsHandler(config, registry), authenticator); + registerHandler("/-/healthy", new HealthyHandler(), authenticator); + try { + // HttpServer.start() starts the HttpServer in a new background thread. + // If we call HttpServer.start() from a thread of the executorService, + // the background thread will inherit the "daemon" property, + // i.e. the server will run as a Daemon thread. + // See https://github.com/prometheus/client_java/pull/955 + this.executorService.submit(this.server::start).get(); + // calling .get() on the Future here to avoid silently discarding errors + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } - private void registerHandler(String path, HttpHandler handler, Authenticator authenticator) { - HttpContext context = server.createContext(path, handler); - if (authenticator != null) { - context.setAuthenticator(authenticator); - } + private void registerHandler(String path, HttpHandler handler, Authenticator authenticator) { + HttpContext context = server.createContext(path, handler); + if (authenticator != null) { + context.setAuthenticator(authenticator); + } + } + + /** Stop the HTTP server. Same as {@link #close()}. */ + public void stop() { + close(); + } + + /** Stop the HTTPServer. Same as {@link #stop()}. */ + @Override + public void close() { + server.stop(0); + executorService.shutdown(); // Free any (parked/idle) threads in pool + } + + /** + * Gets the port number. This is useful if you did not specify a port and the server picked a free + * port automatically. + */ + public int getPort() { + return server.getAddress().getPort(); + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private Integer port = null; + private String hostname = null; + private InetAddress inetAddress = null; + private ExecutorService executorService = null; + private PrometheusRegistry registry = null; + private Authenticator authenticator = null; + private HttpsConfigurator httpsConfigurator = null; + private HttpHandler defaultHandler = null; + + private Builder(PrometheusProperties config) { + this.config = config; } /** - * Stop the HTTP server. Same as {@link #close()}. + * Port to bind to. Default is 0, indicating that a random port will be selected. You can learn + * the randomly selected port by calling {@link HTTPServer#getPort()}. */ - public void stop() { - close(); + public Builder port(int port) { + this.port = port; + return this; } /** - * Stop the HTTPServer. Same as {@link #stop()}. + * Use this hostname to resolve the IP address to bind to. Must not be called together with + * {@link #inetAddress(InetAddress)}. Default is empty, indicating that the HTTPServer binds to + * the wildcard address. */ - @Override - public void close() { - server.stop(0); - executorService.shutdown(); // Free any (parked/idle) threads in pool + public Builder hostname(String hostname) { + this.hostname = hostname; + return this; } /** - * Gets the port number. - * This is useful if you did not specify a port and the server picked a free port automatically. + * Bind to this IP address. Must not be called together with {@link #hostname(String)}. Default + * is empty, indicating that the HTTPServer binds to the wildcard address. */ - public int getPort() { - return server.getAddress().getPort(); + public Builder inetAddress(InetAddress address) { + this.inetAddress = address; + return this; } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + /** Optional: ExecutorService used by the {@code httpServer}. */ + public Builder executorService(ExecutorService executorService) { + this.executorService = executorService; + return this; } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + /** Optional: Default is {@link PrometheusRegistry#defaultRegistry}. */ + public Builder registry(PrometheusRegistry registry) { + this.registry = registry; + return this; } - public static class Builder { - - private final PrometheusProperties config; - private Integer port = null; - private String hostname = null; - private InetAddress inetAddress = null; - private ExecutorService executorService = null; - private PrometheusRegistry registry = null; - private Authenticator authenticator = null; - private HttpsConfigurator httpsConfigurator = null; - private HttpHandler defaultHandler = null; - - private Builder(PrometheusProperties config) { - this.config = config; - } - - /** - * Port to bind to. Default is 0, indicating that a random port will be selected. - * You can learn the randomly selected port by calling {@link HTTPServer#getPort()}. - */ - public Builder port(int port) { - this.port = port; - return this; - } - - /** - * Use this hostname to resolve the IP address to bind to. - * Must not be called together with {@link #inetAddress(InetAddress)}. - * Default is empty, indicating that the HTTPServer binds to the wildcard address. - */ - public Builder hostname(String hostname) { - this.hostname = hostname; - return this; - } - - /** - * Bind to this IP address. - * Must not be called together with {@link #hostname(String)}. - * Default is empty, indicating that the HTTPServer binds to the wildcard address. - */ - public Builder inetAddress(InetAddress address) { - this.inetAddress = address; - return this; - } - - /** - * Optional: ExecutorService used by the {@code httpServer}. - */ - public Builder executorService(ExecutorService executorService) { - this.executorService = executorService; - return this; - } - - /** - * Optional: Default is {@link PrometheusRegistry#defaultRegistry}. - */ - public Builder registry(PrometheusRegistry registry) { - this.registry = registry; - return this; - } - - /** - * Optional: {@link Authenticator} for authentication. - */ - public Builder authenticator(Authenticator authenticator) { - this.authenticator = authenticator; - return this; - } + /** Optional: {@link Authenticator} for authentication. */ + public Builder authenticator(Authenticator authenticator) { + this.authenticator = authenticator; + return this; + } - /** - * Optional: {@link HttpsConfigurator} for TLS/SSL - */ - public Builder httpsConfigurator(HttpsConfigurator configurator) { - this.httpsConfigurator = configurator; - return this; - } + /** Optional: {@link HttpsConfigurator} for TLS/SSL */ + public Builder httpsConfigurator(HttpsConfigurator configurator) { + this.httpsConfigurator = configurator; + return this; + } - /** - * Optional: Override default handler, i.e. the handler that will be registered for the / endpoint. - */ - public Builder defaultHandler(HttpHandler defaultHandler) { - this.defaultHandler = defaultHandler; - return this; - } + /** + * Optional: Override default handler, i.e. the handler that will be registered for the / + * endpoint. + */ + public Builder defaultHandler(HttpHandler defaultHandler) { + this.defaultHandler = defaultHandler; + return this; + } - /** - * Build and start the HTTPServer. - */ - public HTTPServer buildAndStart() throws IOException { - if (registry == null) { - registry = PrometheusRegistry.defaultRegistry; - } - HttpServer httpServer; - if (httpsConfigurator != null) { - httpServer = HttpsServer.create(makeInetSocketAddress(), 3); - ((HttpsServer)httpServer).setHttpsConfigurator(httpsConfigurator); - } else { - httpServer = HttpServer.create(makeInetSocketAddress(), 3); - } - ExecutorService executorService = makeExecutorService(); - httpServer.setExecutor(executorService); - return new HTTPServer(config, executorService, httpServer, registry, authenticator, defaultHandler); - } + /** Build and start the HTTPServer. */ + public HTTPServer buildAndStart() throws IOException { + if (registry == null) { + registry = PrometheusRegistry.defaultRegistry; + } + HttpServer httpServer; + if (httpsConfigurator != null) { + httpServer = HttpsServer.create(makeInetSocketAddress(), 3); + ((HttpsServer) httpServer).setHttpsConfigurator(httpsConfigurator); + } else { + httpServer = HttpServer.create(makeInetSocketAddress(), 3); + } + ExecutorService executorService = makeExecutorService(); + httpServer.setExecutor(executorService); + return new HTTPServer( + config, executorService, httpServer, registry, authenticator, defaultHandler); + } - private InetSocketAddress makeInetSocketAddress() { - if (inetAddress != null) { - assertNull(hostname, "cannot configure 'inetAddress' and 'hostname' at the same time"); - return new InetSocketAddress(inetAddress, findPort()); - } else if (hostname != null) { - return new InetSocketAddress(hostname, findPort()); - } else { - return new InetSocketAddress(findPort()); - } - } + private InetSocketAddress makeInetSocketAddress() { + if (inetAddress != null) { + assertNull(hostname, "cannot configure 'inetAddress' and 'hostname' at the same time"); + return new InetSocketAddress(inetAddress, findPort()); + } else if (hostname != null) { + return new InetSocketAddress(hostname, findPort()); + } else { + return new InetSocketAddress(findPort()); + } + } - private ExecutorService makeExecutorService() { - if (executorService != null) { - return executorService; - } else { - return new ThreadPoolExecutor( - 1, - 10, - 120, - TimeUnit.SECONDS, - new SynchronousQueue<>(true), - NamedDaemonThreadFactory.defaultThreadFactory(true), - new BlockingRejectedExecutionHandler()); - } - } + private ExecutorService makeExecutorService() { + if (executorService != null) { + return executorService; + } else { + return new ThreadPoolExecutor( + 1, + 10, + 120, + TimeUnit.SECONDS, + new SynchronousQueue<>(true), + NamedDaemonThreadFactory.defaultThreadFactory(true), + new BlockingRejectedExecutionHandler()); + } + } - private int findPort() { - if (config != null && config.getExporterHttpServerProperties() != null) { - Integer port = config.getExporterHttpServerProperties().getPort(); - if (port != null) { - return port; - } - } - if (port != null) { - return port; - } - return 0; // random port will be selected + private int findPort() { + if (config != null && config.getExporterHttpServerProperties() != null) { + Integer port = config.getExporterHttpServerProperties().getPort(); + if (port != null) { + return port; } + } + if (port != null) { + return port; + } + return 0; // random port will be selected + } - private void assertNull(Object o, String msg) { - if (o != null) { - throw new IllegalStateException(msg); - } - } + private void assertNull(Object o, String msg) { + if (o != null) { + throw new IllegalStateException(msg); + } } + } - private static class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { + private static class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { - @Override - public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { - if (!threadPoolExecutor.isShutdown()) { - try { - threadPoolExecutor.getQueue().put(runnable); - } catch (InterruptedException ignored) { - } - } + @Override + public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { + if (!threadPoolExecutor.isShutdown()) { + try { + threadPoolExecutor.getQueue().put(runnable); + } catch (InterruptedException ignored) { } + } } + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java index 4fbdb9426..806b47553 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HealthyHandler.java @@ -2,33 +2,30 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; - import java.io.IOException; import java.nio.charset.StandardCharsets; -/** - * Handler for the /-/healthy endpoint - */ +/** Handler for the /-/healthy endpoint */ public class HealthyHandler implements HttpHandler { - private final byte[] responseBytes; - private final String contentType; + private final byte[] responseBytes; + private final String contentType; - public HealthyHandler() { - String responseString = "Exporter is healthy.\n"; - this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); - this.contentType = "text/plain; charset=utf-8"; - } + public HealthyHandler() { + String responseString = "Exporter is healthy.\n"; + this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); + this.contentType = "text/plain; charset=utf-8"; + } - @Override - public void handle(HttpExchange exchange) throws IOException { - try { - exchange.getResponseHeaders().set("Content-Type", contentType); - exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); - exchange.sendResponseHeaders(200, responseBytes.length); - exchange.getResponseBody().write(responseBytes); - } finally { - exchange.close(); - } + @Override + public void handle(HttpExchange exchange) throws IOException { + try { + exchange.getResponseHeaders().set("Content-Type", contentType); + exchange.getResponseHeaders().set("Content-Length", Integer.toString(responseBytes.length)); + exchange.sendResponseHeaders(200, responseBytes.length); + exchange.getResponseBody().write(responseBytes); + } finally { + exchange.close(); } + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java index 3636acedf..e7d33d310 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java @@ -4,7 +4,6 @@ import io.prometheus.metrics.exporter.common.PrometheusHttpExchange; import io.prometheus.metrics.exporter.common.PrometheusHttpRequest; import io.prometheus.metrics.exporter.common.PrometheusHttpResponse; - import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; @@ -19,113 +18,129 @@ public class HttpExchangeAdapter implements PrometheusHttpExchange { - private final HttpExchange httpExchange; - private final HttpRequest request = new HttpRequest(); - private final HttpResponse response = new HttpResponse(); - private volatile boolean responseSent = false; + private final HttpExchange httpExchange; + private final HttpRequest request = new HttpRequest(); + private final HttpResponse response = new HttpResponse(); + private volatile boolean responseSent = false; - public HttpExchangeAdapter(HttpExchange httpExchange) { - this.httpExchange = httpExchange; - } + public HttpExchangeAdapter(HttpExchange httpExchange) { + this.httpExchange = httpExchange; + } - public class HttpRequest implements PrometheusHttpRequest { - - @Override - public String getQueryString() { - return httpExchange.getRequestURI().getRawQuery(); - } - - @Override - public Enumeration getHeaders(String name) { - List headers = httpExchange.getRequestHeaders().get(name); - if (headers == null) { - return Collections.emptyEnumeration(); - } else { - return Collections.enumeration(headers); - } - } - - @Override - public String getMethod() { - return httpExchange.getRequestMethod(); - } - - @Override - public String getRequestPath() { - URI requestURI = httpExchange.getRequestURI(); - String uri = requestURI.toString(); - int qx = uri.indexOf('?'); - if (qx != -1) { - uri = uri.substring(0, qx); - } - return uri; - } - } - - public class HttpResponse implements PrometheusHttpResponse { - - @Override - public void setHeader(String name, String value) { - httpExchange.getResponseHeaders().set(name, value); - } - - @Override - public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException { - if (responseSent) { - throw new IOException("Cannot send multiple HTTP responses for a single HTTP exchange."); - } - responseSent = true; - httpExchange.sendResponseHeaders(statusCode, contentLength); - return httpExchange.getResponseBody(); - } - } + public class HttpRequest implements PrometheusHttpRequest { @Override - public HttpRequest getRequest() { - return request; + public String getQueryString() { + return httpExchange.getRequestURI().getRawQuery(); } @Override - public HttpResponse getResponse() { - return response; + public Enumeration getHeaders(String name) { + List headers = httpExchange.getRequestHeaders().get(name); + if (headers == null) { + return Collections.emptyEnumeration(); + } else { + return Collections.enumeration(headers); + } } @Override - public void handleException(IOException e) throws IOException { - sendErrorResponseWithStackTrace(e); + public String getMethod() { + return httpExchange.getRequestMethod(); } @Override - public void handleException(RuntimeException e) { - sendErrorResponseWithStackTrace(e); + public String getRequestPath() { + URI requestURI = httpExchange.getRequestURI(); + String uri = requestURI.toString(); + int qx = uri.indexOf('?'); + if (qx != -1) { + uri = uri.substring(0, qx); + } + return uri; } + } - private void sendErrorResponseWithStackTrace(Exception requestHandlerException) { - if (!responseSent) { - responseSent = true; - try { - StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter(stringWriter); - printWriter.write("An Exception occurred while scraping metrics: "); - requestHandlerException.printStackTrace(new PrintWriter(printWriter)); - byte[] stackTrace = stringWriter.toString().getBytes(StandardCharsets.UTF_8); - httpExchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8"); - httpExchange.sendResponseHeaders(500, stackTrace.length); - httpExchange.getResponseBody().write(stackTrace); - } catch (Exception errorWriterException) { - // We want to avoid logging so that we don't mess with application logs when the HTTPServer is used in a Java agent. - // However, if we can't even send an error response to the client there's nothing we can do but logging a message. - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "The Prometheus metrics HTTPServer caught an Exception during scrape and failed to send an error response to the client.", errorWriterException); - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Original Exception that caused the Prometheus scrape error:", requestHandlerException); - } - } else { - // If the exception occurs after response headers have been sent, it's too late to respond with HTTP 500. - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "The Prometheus metrics HTTPServer caught an Exception while trying to send the metrics response.", requestHandlerException); - } + public class HttpResponse implements PrometheusHttpResponse { + + @Override + public void setHeader(String name, String value) { + httpExchange.getResponseHeaders().set(name, value); } @Override - public void close() { - httpExchange.close(); + public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) + throws IOException { + if (responseSent) { + throw new IOException("Cannot send multiple HTTP responses for a single HTTP exchange."); + } + responseSent = true; + httpExchange.sendResponseHeaders(statusCode, contentLength); + return httpExchange.getResponseBody(); } + } + + @Override + public HttpRequest getRequest() { + return request; + } + + @Override + public HttpResponse getResponse() { + return response; + } + + @Override + public void handleException(IOException e) throws IOException { + sendErrorResponseWithStackTrace(e); + } + + @Override + public void handleException(RuntimeException e) { + sendErrorResponseWithStackTrace(e); + } + + private void sendErrorResponseWithStackTrace(Exception requestHandlerException) { + if (!responseSent) { + responseSent = true; + try { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + printWriter.write("An Exception occurred while scraping metrics: "); + requestHandlerException.printStackTrace(new PrintWriter(printWriter)); + byte[] stackTrace = stringWriter.toString().getBytes(StandardCharsets.UTF_8); + httpExchange.getResponseHeaders().set("Content-Type", "text/plain; charset=utf-8"); + httpExchange.sendResponseHeaders(500, stackTrace.length); + httpExchange.getResponseBody().write(stackTrace); + } catch (Exception errorWriterException) { + // We want to avoid logging so that we don't mess with application logs when the HTTPServer + // is used in a Java agent. + // However, if we can't even send an error response to the client there's nothing we can do + // but logging a message. + Logger.getLogger(this.getClass().getName()) + .log( + Level.SEVERE, + "The Prometheus metrics HTTPServer caught an Exception during scrape and failed to send an error response to the client.", + errorWriterException); + Logger.getLogger(this.getClass().getName()) + .log( + Level.SEVERE, + "Original Exception that caused the Prometheus scrape error:", + requestHandlerException); + } + } else { + // If the exception occurs after response headers have been sent, it's too late to respond + // with HTTP 500. + Logger.getLogger(this.getClass().getName()) + .log( + Level.SEVERE, + "The Prometheus metrics HTTPServer caught an Exception while trying to send the metrics response.", + requestHandlerException); + } + } + + @Override + public void close() { + httpExchange.close(); + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/MetricsHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/MetricsHandler.java index 3506ddd4b..4ac4b80d7 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/MetricsHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/MetricsHandler.java @@ -5,41 +5,31 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.exporter.common.PrometheusScrapeHandler; import io.prometheus.metrics.model.registry.PrometheusRegistry; - -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.charset.StandardCharsets; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Handler for the /metrics endpoint - */ + +/** Handler for the /metrics endpoint */ public class MetricsHandler implements HttpHandler { - private final PrometheusScrapeHandler prometheusScrapeHandler; + private final PrometheusScrapeHandler prometheusScrapeHandler; - public MetricsHandler() { - prometheusScrapeHandler = new PrometheusScrapeHandler(); - } + public MetricsHandler() { + prometheusScrapeHandler = new PrometheusScrapeHandler(); + } - public MetricsHandler(PrometheusRegistry registry) { - prometheusScrapeHandler = new PrometheusScrapeHandler(registry); - } + public MetricsHandler(PrometheusRegistry registry) { + prometheusScrapeHandler = new PrometheusScrapeHandler(registry); + } - public MetricsHandler(PrometheusProperties config) { - prometheusScrapeHandler = new PrometheusScrapeHandler(config); - } + public MetricsHandler(PrometheusProperties config) { + prometheusScrapeHandler = new PrometheusScrapeHandler(config); + } - public MetricsHandler(PrometheusProperties config, PrometheusRegistry registry) { - prometheusScrapeHandler = new PrometheusScrapeHandler(config, registry); - } + public MetricsHandler(PrometheusProperties config, PrometheusRegistry registry) { + prometheusScrapeHandler = new PrometheusScrapeHandler(config, registry); + } - @Override - public void handle(HttpExchange t) throws IOException { - prometheusScrapeHandler.handleRequest(new HttpExchangeAdapter(t)); - } + @Override + public void handle(HttpExchange t) throws IOException { + prometheusScrapeHandler.handleRequest(new HttpExchangeAdapter(t)); + } } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/NamedDaemonThreadFactory.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/NamedDaemonThreadFactory.java index 378ac6ddc..b5d2415f7 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/NamedDaemonThreadFactory.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/NamedDaemonThreadFactory.java @@ -6,26 +6,26 @@ class NamedDaemonThreadFactory implements ThreadFactory { - private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); - private final int poolNumber = POOL_NUMBER.getAndIncrement(); - private final AtomicInteger threadNumber = new AtomicInteger(1); - private final ThreadFactory delegate; - private final boolean daemon; + private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); + private final int poolNumber = POOL_NUMBER.getAndIncrement(); + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final ThreadFactory delegate; + private final boolean daemon; - NamedDaemonThreadFactory(ThreadFactory delegate, boolean daemon) { - this.delegate = delegate; - this.daemon = daemon; - } + NamedDaemonThreadFactory(ThreadFactory delegate, boolean daemon) { + this.delegate = delegate; + this.daemon = daemon; + } - @Override - public Thread newThread(Runnable r) { - Thread t = delegate.newThread(r); - t.setName(String.format("prometheus-http-%d-%d", poolNumber, threadNumber.getAndIncrement())); - t.setDaemon(daemon); - return t; - } + @Override + public Thread newThread(Runnable r) { + Thread t = delegate.newThread(r); + t.setName(String.format("prometheus-http-%d-%d", poolNumber, threadNumber.getAndIncrement())); + t.setDaemon(daemon); + return t; + } - static ThreadFactory defaultThreadFactory(boolean daemon) { - return new NamedDaemonThreadFactory(Executors.defaultThreadFactory(), daemon); - } + static ThreadFactory defaultThreadFactory(boolean daemon) { + return new NamedDaemonThreadFactory(Executors.defaultThreadFactory(), daemon); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index 97719d6c3..fb674e351 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -12,444 +12,492 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.PeriodicMetricReader; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; - import java.time.Duration; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; public class OpenTelemetryExporter implements AutoCloseable { - private final PeriodicMetricReader reader; - - private OpenTelemetryExporter(Builder builder, PrometheusProperties config, PrometheusRegistry registry) { - InstrumentationScopeInfo instrumentationScopeInfo = PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); - ExporterOpenTelemetryProperties properties = config.getExporterOpenTelemetryProperties(); - Resource resource = initResourceAttributes(builder, properties, instrumentationScopeInfo); - MetricExporter exporter; - if (ConfigHelper.getProtocol(builder, properties).equals("grpc")) { - OtlpGrpcMetricExporterBuilder exporterBuilder = OtlpGrpcMetricExporter.builder() - .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) - .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); - for (Map.Entry header : ConfigHelper.getHeaders(builder, properties).entrySet()) { - exporterBuilder.addHeader(header.getKey(), header.getValue()); - } - exporter = exporterBuilder.build(); - } else { - OtlpHttpMetricExporterBuilder exporterBuilder = OtlpHttpMetricExporter.builder() - .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) - .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); - for (Map.Entry header : ConfigHelper.getHeaders(builder, properties).entrySet()) { - exporterBuilder.addHeader(header.getKey(), header.getValue()); - } - exporter = exporterBuilder.build(); - } - reader = PeriodicMetricReader.builder(exporter) - .setInterval(Duration.ofSeconds(ConfigHelper.getIntervalSeconds(builder, properties))) - .build(); - - PrometheusMetricProducer prometheusMetricProducer = new PrometheusMetricProducer(registry, instrumentationScopeInfo, resource); - reader.register(prometheusMetricProducer); + private final PeriodicMetricReader reader; + + private OpenTelemetryExporter( + Builder builder, PrometheusProperties config, PrometheusRegistry registry) { + InstrumentationScopeInfo instrumentationScopeInfo = + PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); + ExporterOpenTelemetryProperties properties = config.getExporterOpenTelemetryProperties(); + Resource resource = initResourceAttributes(builder, properties, instrumentationScopeInfo); + MetricExporter exporter; + if (ConfigHelper.getProtocol(builder, properties).equals("grpc")) { + OtlpGrpcMetricExporterBuilder exporterBuilder = + OtlpGrpcMetricExporter.builder() + .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) + .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); + for (Map.Entry header : + ConfigHelper.getHeaders(builder, properties).entrySet()) { + exporterBuilder.addHeader(header.getKey(), header.getValue()); + } + exporter = exporterBuilder.build(); + } else { + OtlpHttpMetricExporterBuilder exporterBuilder = + OtlpHttpMetricExporter.builder() + .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) + .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); + for (Map.Entry header : + ConfigHelper.getHeaders(builder, properties).entrySet()) { + exporterBuilder.addHeader(header.getKey(), header.getValue()); + } + exporter = exporterBuilder.build(); } - - public void close() { - reader.shutdown(); + reader = + PeriodicMetricReader.builder(exporter) + .setInterval(Duration.ofSeconds(ConfigHelper.getIntervalSeconds(builder, properties))) + .build(); + + PrometheusMetricProducer prometheusMetricProducer = + new PrometheusMetricProducer(registry, instrumentationScopeInfo, resource); + reader.register(prometheusMetricProducer); + } + + public void close() { + reader.shutdown(); + } + + private Resource initResourceAttributes( + Builder builder, + ExporterOpenTelemetryProperties properties, + InstrumentationScopeInfo instrumentationScopeInfo) { + String serviceName = ConfigHelper.getServiceName(builder, properties); + String serviceNamespace = ConfigHelper.getServiceNamespace(builder, properties); + String serviceInstanceId = ConfigHelper.getServiceInstanceId(builder, properties); + String serviceVersion = ConfigHelper.getServiceVersion(builder, properties); + Map resourceAttributes = + ResourceAttributes.get( + instrumentationScopeInfo.getName(), + serviceName, + serviceNamespace, + serviceInstanceId, + serviceVersion, + ConfigHelper.getResourceAttributes(builder, properties)); + ResourceBuilder resourceBuilder = Resource.builder(); + for (Map.Entry entry : resourceAttributes.entrySet()) { + resourceBuilder.put(entry.getKey(), entry.getValue()); } - - private Resource initResourceAttributes(Builder builder, ExporterOpenTelemetryProperties properties, InstrumentationScopeInfo instrumentationScopeInfo) { - String serviceName = ConfigHelper.getServiceName(builder, properties); - String serviceNamespace = ConfigHelper.getServiceNamespace(builder, properties); - String serviceInstanceId = ConfigHelper.getServiceInstanceId(builder, properties); - String serviceVersion = ConfigHelper.getServiceVersion(builder, properties); - Map resourceAttributes = ResourceAttributes.get(instrumentationScopeInfo.getName(), serviceName, serviceNamespace, serviceInstanceId, serviceVersion, ConfigHelper.getResourceAttributes(builder, properties)); - ResourceBuilder resourceBuilder = Resource.builder(); - for (Map.Entry entry : resourceAttributes.entrySet()) { - resourceBuilder.put(entry.getKey(), entry.getValue()); - } - return resourceBuilder.build(); + return resourceBuilder.build(); + } + + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } + + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private PrometheusRegistry registry = null; + private String protocol; + private String endpoint; + private final Map headers = new HashMap<>(); + private Integer intervalSeconds; + private Integer timeoutSeconds; + private String serviceName; + private String serviceNamespace; + private String serviceInstanceId; + private String serviceVersion; + private final Map resourceAttributes = new HashMap<>(); + + private Builder(PrometheusProperties config) { + this.config = config; } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); + public Builder registry(PrometheusRegistry registry) { + this.registry = registry; + return this; } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + /** + * Specifies the OTLP transport protocol to be used when exporting metrics. + * + *

      Supported values are {@code "grpc"} and {@code "http/protobuf"}. Default is {@code + * "grpc"}. + * + *

      See OpenTelemetry's OTEL_EXPORTER_OTLP_PROTOCOL. + */ + public Builder protocol(String protocol) { + if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new IllegalArgumentException( + protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); + } + this.protocol = protocol; + return this; } - public static class Builder { - - private final PrometheusProperties config; - private PrometheusRegistry registry = null; - private String protocol; - private String endpoint; - private final Map headers = new HashMap<>(); - private Integer intervalSeconds; - private Integer timeoutSeconds; - private String serviceName; - private String serviceNamespace; - private String serviceInstanceId; - private String serviceVersion; - private final Map resourceAttributes = new HashMap<>(); - - private Builder(PrometheusProperties config) { - this.config = config; - } - - public Builder registry(PrometheusRegistry registry) { - this.registry = registry; - return this; - } - - /** - * Specifies the OTLP transport protocol to be used when exporting metrics. - *

      - * Supported values are {@code "grpc"} and {@code "http/protobuf"}. Default is {@code "grpc"}. - *

      - * See OpenTelemetry's OTEL_EXPORTER_OTLP_PROTOCOL. - */ - public Builder protocol(String protocol) { - if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new IllegalArgumentException(protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); - } - this.protocol = protocol; - return this; - } - - /** - * The OTLP endpoint to send metric data to. - *

      - * The default depends on the protocol: - *

        - *
      • {@code "grpc"}: {@code "http://localhost:4317"}
      • - *
      • {@code "http/protobuf"}: {@code "http://localhost:4318/v1/metrics"}
      • - *
      - * If the protocol is {@code "http/protobuf"} and the endpoint does not have the {@code "/v1/metrics"} suffix, - * the {@code "/v1/metrics"} suffix will automatically be appended. - *

      - * See OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_ENDPOINT. - */ - public Builder endpoint(String endpoint) { - this.endpoint = endpoint; - return this; - } + /** + * The OTLP endpoint to send metric data to. + * + *

      The default depends on the protocol: + * + *

        + *
      • {@code "grpc"}: {@code "http://localhost:4317"} + *
      • {@code "http/protobuf"}: {@code "http://localhost:4318/v1/metrics"} + *
      + * + * If the protocol is {@code "http/protobuf"} and the endpoint does not have the {@code + * "/v1/metrics"} suffix, the {@code "/v1/metrics"} suffix will automatically be appended. + * + *

      See OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_ENDPOINT. + */ + public Builder endpoint(String endpoint) { + this.endpoint = endpoint; + return this; + } - /** - * Add an HTTP header to be applied to outgoing requests. - * Call multiple times to add multiple headers. - *

      - * See OpenTelemetry's OTEL_EXPORTER_OTLP_HEADERS. - */ - public Builder header(String name, String value) { - this.headers.put(name, value); - return this; - } + /** + * Add an HTTP header to be applied to outgoing requests. Call multiple times to add multiple + * headers. + * + *

      See OpenTelemetry's OTEL_EXPORTER_OTLP_HEADERS. + */ + public Builder header(String name, String value) { + this.headers.put(name, value); + return this; + } - /** - * The interval between the start of two export attempts. Default is 60000. - *

      - * Like OpenTelemetry's OTEL_METRIC_EXPORT_INTERVAL, - * but in seconds rather than milliseconds. - */ - public Builder intervalSeconds(int intervalSeconds) { - if (intervalSeconds <= 0) { - throw new IllegalStateException(intervalSeconds + ": expecting a push interval > 0s"); - } - this.intervalSeconds = intervalSeconds; - return this; - } + /** + * The interval between the start of two export attempts. Default is 60000. + * + *

      Like OpenTelemetry's OTEL_METRIC_EXPORT_INTERVAL, + * but in seconds rather than milliseconds. + */ + public Builder intervalSeconds(int intervalSeconds) { + if (intervalSeconds <= 0) { + throw new IllegalStateException(intervalSeconds + ": expecting a push interval > 0s"); + } + this.intervalSeconds = intervalSeconds; + return this; + } - /** - * The timeout for outgoing requests. Default is 10. - *

      - * Like OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, - * but in seconds rather than milliseconds. - */ - public Builder timeoutSeconds(int timeoutSeconds) { - if (timeoutSeconds <= 0) { - throw new IllegalStateException(timeoutSeconds + ": expecting a push interval > 0s"); - } - this.timeoutSeconds = timeoutSeconds; - return this; - } + /** + * The timeout for outgoing requests. Default is 10. + * + *

      Like OpenTelemetry's OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, + * but in seconds rather than milliseconds. + */ + public Builder timeoutSeconds(int timeoutSeconds) { + if (timeoutSeconds <= 0) { + throw new IllegalStateException(timeoutSeconds + ": expecting a push interval > 0s"); + } + this.timeoutSeconds = timeoutSeconds; + return this; + } - /** - * The {@code service.name} resource attribute. - *

      - * If not explicitly specified, {@code client_java} will try to initialize it with a reasonable default, like the JAR file name. - *

      - * See {@code service.name} in OpenTelemetry's Resource Semantic Conventions. - */ - public Builder serviceName(String serviceName) { - this.serviceName = serviceName; - return this; - } + /** + * The {@code service.name} resource attribute. + * + *

      If not explicitly specified, {@code client_java} will try to initialize it with a + * reasonable default, like the JAR file name. + * + *

      See {@code service.name} in OpenTelemetry's Resource + * Semantic Conventions. + */ + public Builder serviceName(String serviceName) { + this.serviceName = serviceName; + return this; + } - /** - * The {@code service.namespace} resource attribute. - *

      - * See {@code service.namespace} in OpenTelemetry's Resource Semantic Conventions. - */ - public Builder serviceNamespace(String serviceNamespace) { - this.serviceNamespace = serviceNamespace; - return this; - } + /** + * The {@code service.namespace} resource attribute. + * + *

      See {@code service.namespace} in OpenTelemetry's Resource + * Semantic Conventions. + */ + public Builder serviceNamespace(String serviceNamespace) { + this.serviceNamespace = serviceNamespace; + return this; + } - /** - * The {@code service.instance.id} resource attribute. - *

      - * See {@code service.instance.id} in OpenTelemetry's Resource Semantic Conventions. - */ - public Builder serviceInstanceId(String serviceInstanceId) { - this.serviceInstanceId = serviceInstanceId; - return this; - } + /** + * The {@code service.instance.id} resource attribute. + * + *

      See {@code service.instance.id} in OpenTelemetry's Resource + * Semantic Conventions. + */ + public Builder serviceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + return this; + } - /** - * The {@code service.version} resource attribute. - *

      - * See {@code service.version} in OpenTelemetry's Resource Semantic Conventions. - */ - public Builder serviceVersion(String serviceVersion) { - this.serviceVersion = serviceVersion; - return this; - } + /** + * The {@code service.version} resource attribute. + * + *

      See {@code service.version} in OpenTelemetry's Resource + * Semantic Conventions. + */ + public Builder serviceVersion(String serviceVersion) { + this.serviceVersion = serviceVersion; + return this; + } - /** - * Add a resource attribute. Call multiple times to add multiple resource attributes. - *

      - * See OpenTelemetry's OTEL_RESOURCE_ATTRIBUTES. - */ - public Builder resourceAttribute(String name, String value) { - this.resourceAttributes.put(name, value); - return this; - } + /** + * Add a resource attribute. Call multiple times to add multiple resource attributes. + * + *

      See OpenTelemetry's OTEL_RESOURCE_ATTRIBUTES. + */ + public Builder resourceAttribute(String name, String value) { + this.resourceAttributes.put(name, value); + return this; + } - public OpenTelemetryExporter buildAndStart() { - if (registry == null) { - registry = PrometheusRegistry.defaultRegistry; - } - return new OpenTelemetryExporter(this, config, registry); + public OpenTelemetryExporter buildAndStart() { + if (registry == null) { + registry = PrometheusRegistry.defaultRegistry; + } + return new OpenTelemetryExporter(this, config, registry); + } + } + + private static class ConfigHelper { + + private static String getProtocol( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String protocol = config.getProtocol(); + if (protocol != null) { + return protocol; + } + protocol = getString("otel.exporter.otlp.protocol"); + if (protocol != null) { + if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { + throw new IllegalStateException( + protocol + + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf."); } + return protocol; + } + if (builder.protocol != null) { + return builder.protocol; + } + return "grpc"; } - private static class ConfigHelper { - - private static String getProtocol(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String protocol = config.getProtocol(); - if (protocol != null) { - return protocol; - } - protocol = getString("otel.exporter.otlp.protocol"); - if (protocol != null) { - if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new IllegalStateException(protocol + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf."); - } - return protocol; - } - if (builder.protocol != null) { - return builder.protocol; - } - return "grpc"; + private static String getEndpoint( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String endpoint = config.getEndpoint(); + if (endpoint == null) { + endpoint = getString("otel.exporter.otlp.metrics.endpoint"); + } + if (endpoint == null) { + endpoint = getString("otel.exporter.otlp.endpoint"); + } + if (endpoint == null) { + endpoint = builder.endpoint; + } + if (endpoint == null) { + if (getProtocol(builder, config).equals("grpc")) { + endpoint = "http://localhost:4317"; + } else { // http/protobuf + endpoint = "http://localhost:4318/v1/metrics"; } - - private static String getEndpoint(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String endpoint = config.getEndpoint(); - if (endpoint == null) { - endpoint = getString("otel.exporter.otlp.metrics.endpoint"); - } - if (endpoint == null) { - endpoint = getString("otel.exporter.otlp.endpoint"); - } - if (endpoint == null) { - endpoint = builder.endpoint; - } - if (endpoint == null) { - if (getProtocol(builder, config).equals("grpc")) { - endpoint = "http://localhost:4317"; - } else { // http/protobuf - endpoint = "http://localhost:4318/v1/metrics"; - } - } - if (getProtocol(builder, config).equals("grpc")) { - return endpoint; - } else { // http/protobuf - if (!endpoint.endsWith("v1/metrics")) { - if (!endpoint.endsWith("/")) { - return endpoint + "/v1/metrics"; - } else { - return endpoint + "v1/metrics"; - } - } else { - return endpoint; - } - } + } + if (getProtocol(builder, config).equals("grpc")) { + return endpoint; + } else { // http/protobuf + if (!endpoint.endsWith("v1/metrics")) { + if (!endpoint.endsWith("/")) { + return endpoint + "/v1/metrics"; + } else { + return endpoint + "v1/metrics"; + } + } else { + return endpoint; } + } + } - private static Map getHeaders(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Map headers = config.getHeaders(); - if (!headers.isEmpty()) { - return headers; - } - headers = getMap("otel.exporter.otlp.headers"); - if (!headers.isEmpty()) { - return headers; - } - if (!builder.headers.isEmpty()) { - return builder.headers; - } - return new HashMap<>(); - } + private static Map getHeaders( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Map headers = config.getHeaders(); + if (!headers.isEmpty()) { + return headers; + } + headers = getMap("otel.exporter.otlp.headers"); + if (!headers.isEmpty()) { + return headers; + } + if (!builder.headers.isEmpty()) { + return builder.headers; + } + return new HashMap<>(); + } - private static int getIntervalSeconds(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Integer intervalSeconds = config.getIntervalSeconds(); - if (intervalSeconds != null) { - return intervalSeconds; - } - intervalSeconds = getPositiveInteger("otel.metric.export.interval"); - if (intervalSeconds != null) { - return (int) TimeUnit.MILLISECONDS.toSeconds(intervalSeconds); - } - if (builder.intervalSeconds != null) { - return builder.intervalSeconds; - } - return 60; - } + private static int getIntervalSeconds( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Integer intervalSeconds = config.getIntervalSeconds(); + if (intervalSeconds != null) { + return intervalSeconds; + } + intervalSeconds = getPositiveInteger("otel.metric.export.interval"); + if (intervalSeconds != null) { + return (int) TimeUnit.MILLISECONDS.toSeconds(intervalSeconds); + } + if (builder.intervalSeconds != null) { + return builder.intervalSeconds; + } + return 60; + } - private static int getTimeoutSeconds(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Integer timeoutSeconds = config.getTimeoutSeconds(); - if (timeoutSeconds != null) { - return timeoutSeconds; - } - Integer timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.metrics.timeout"); - if (timeoutMilliseconds == null) { - timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.timeout"); - } - if (timeoutMilliseconds != null) { - return (int) TimeUnit.MILLISECONDS.toSeconds(timeoutMilliseconds); - } - if (builder.timeoutSeconds != null) { - return builder.timeoutSeconds; - } - return 10; - } + private static int getTimeoutSeconds( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Integer timeoutSeconds = config.getTimeoutSeconds(); + if (timeoutSeconds != null) { + return timeoutSeconds; + } + Integer timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.metrics.timeout"); + if (timeoutMilliseconds == null) { + timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.timeout"); + } + if (timeoutMilliseconds != null) { + return (int) TimeUnit.MILLISECONDS.toSeconds(timeoutMilliseconds); + } + if (builder.timeoutSeconds != null) { + return builder.timeoutSeconds; + } + return 10; + } - private static String getServiceName(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceName = config.getServiceName(); - if (serviceName != null) { - return serviceName; - } - serviceName = getString("otel.service.name"); - if (serviceName != null) { - return serviceName; - } - if (builder.serviceName != null) { - return builder.serviceName; - } - return null; - } + private static String getServiceName( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceName = config.getServiceName(); + if (serviceName != null) { + return serviceName; + } + serviceName = getString("otel.service.name"); + if (serviceName != null) { + return serviceName; + } + if (builder.serviceName != null) { + return builder.serviceName; + } + return null; + } - private static String getServiceNamespace(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceNamespace = config.getServiceNamespace(); - if (serviceNamespace != null) { - return serviceNamespace; - } - if (builder.serviceNamespace != null) { - return builder.serviceNamespace; - } - return null; - } + private static String getServiceNamespace( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceNamespace = config.getServiceNamespace(); + if (serviceNamespace != null) { + return serviceNamespace; + } + if (builder.serviceNamespace != null) { + return builder.serviceNamespace; + } + return null; + } - private static String getServiceInstanceId(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceInstanceId = config.getServiceInstanceId(); - if (serviceInstanceId != null) { - return serviceInstanceId; - } - if (builder.serviceInstanceId != null) { - return builder.serviceInstanceId; - } - return null; - } + private static String getServiceInstanceId( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceInstanceId = config.getServiceInstanceId(); + if (serviceInstanceId != null) { + return serviceInstanceId; + } + if (builder.serviceInstanceId != null) { + return builder.serviceInstanceId; + } + return null; + } - private static String getServiceVersion(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceVersion = config.getServiceVersion(); - if (serviceVersion != null) { - return serviceVersion; - } - if (builder.serviceVersion != null) { - return builder.serviceVersion; - } - return null; - } + private static String getServiceVersion( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + String serviceVersion = config.getServiceVersion(); + if (serviceVersion != null) { + return serviceVersion; + } + if (builder.serviceVersion != null) { + return builder.serviceVersion; + } + return null; + } - private static Map getResourceAttributes(OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Map resourceAttributes = config.getResourceAttributes(); - if (!resourceAttributes.isEmpty()) { - return resourceAttributes; - } - resourceAttributes = getMap("otel.resource.attributes"); - if (!resourceAttributes.isEmpty()) { - return resourceAttributes; - } - if (!builder.resourceAttributes.isEmpty()) { - return builder.resourceAttributes; - } - return new HashMap<>(); - } + private static Map getResourceAttributes( + OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { + Map resourceAttributes = config.getResourceAttributes(); + if (!resourceAttributes.isEmpty()) { + return resourceAttributes; + } + resourceAttributes = getMap("otel.resource.attributes"); + if (!resourceAttributes.isEmpty()) { + return resourceAttributes; + } + if (!builder.resourceAttributes.isEmpty()) { + return builder.resourceAttributes; + } + return new HashMap<>(); + } - private static String getString(String otelPropertyName) { - String otelEnvVarName = otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(); - if (System.getenv(otelEnvVarName) != null) { - return System.getenv(otelEnvVarName); - } - if (System.getProperty(otelPropertyName) != null) { - return System.getProperty(otelPropertyName); - } - return null; - } + private static String getString(String otelPropertyName) { + String otelEnvVarName = otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(); + if (System.getenv(otelEnvVarName) != null) { + return System.getenv(otelEnvVarName); + } + if (System.getProperty(otelPropertyName) != null) { + return System.getProperty(otelPropertyName); + } + return null; + } - private static Integer getInteger(String otelPropertyName) { - String result = getString(otelPropertyName); - if (result == null) { - return null; - } else { - try { - return Integer.parseInt(result); - } catch (NumberFormatException e) { - throw new IllegalStateException(otelPropertyName + "=" + result + " - illegal value."); - } - } + private static Integer getInteger(String otelPropertyName) { + String result = getString(otelPropertyName); + if (result == null) { + return null; + } else { + try { + return Integer.parseInt(result); + } catch (NumberFormatException e) { + throw new IllegalStateException(otelPropertyName + "=" + result + " - illegal value."); } + } + } - private static Integer getPositiveInteger(String otelPropertyName) { - Integer result = getInteger(otelPropertyName); - if (result == null) { - return null; - } - if (result <= 0) { - throw new IllegalStateException(otelPropertyName + "=" + result + ": Expecting value > 0."); - } - return result; - } + private static Integer getPositiveInteger(String otelPropertyName) { + Integer result = getInteger(otelPropertyName); + if (result == null) { + return null; + } + if (result <= 0) { + throw new IllegalStateException(otelPropertyName + "=" + result + ": Expecting value > 0."); + } + return result; + } - private static Map getMap(String otelPropertyName) { - Map result = new HashMap<>(); - String property = getString(otelPropertyName); - if (property != null) { - String[] pairs = property.split(","); - for (String pair : pairs) { - if (pair.contains("=")) { - String[] keyValue = pair.split("=", 1); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - if (key.length() > 0 && value.length() > 0) { - result.putIfAbsent(key, value); - } - } - } - } - } - return result; + private static Map getMap(String otelPropertyName) { + Map result = new HashMap<>(); + String property = getString(otelPropertyName); + if (property != null) { + String[] pairs = property.split(","); + for (String pair : pairs) { + if (pair.contains("=")) { + String[] keyValue = pair.split("=", 1); + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + if (key.length() > 0 && value.length() > 0) { + result.putIfAbsent(key, value); + } + } + } } + } + return result; } + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java index de14def11..fae9a2984 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -1,32 +1,49 @@ package io.prometheus.metrics.exporter.opentelemetry; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; - import java.util.Properties; class PrometheusInstrumentationScope { - private static final String instrumentationScopePropertiesFile = "instrumentationScope.properties"; - private static final String instrumentationScopeNameKey = "instrumentationScope.name"; - private static final String instrumentationScopeVersionKey = "instrumentationScope.version"; + private static final String instrumentationScopePropertiesFile = + "instrumentationScope.properties"; + private static final String instrumentationScopeNameKey = "instrumentationScope.name"; + private static final String instrumentationScopeVersionKey = "instrumentationScope.version"; - public static InstrumentationScopeInfo loadInstrumentationScopeInfo() { - try { - Properties properties = new Properties(); - properties.load(PrometheusInstrumentationScope.class.getClassLoader().getResourceAsStream(instrumentationScopePropertiesFile)); - String instrumentationScopeName = properties.getProperty(instrumentationScopeNameKey); - if (instrumentationScopeName == null) { - throw new IllegalStateException("Prometheus metrics library initialization error: " + instrumentationScopeNameKey + " not found in " + instrumentationScopePropertiesFile + " in classpath."); - } - String instrumentationScopeVersion = properties.getProperty(instrumentationScopeVersionKey); - if (instrumentationScopeVersion == null) { - throw new IllegalStateException("Prometheus metrics library initialization error: " + instrumentationScopeVersionKey + " not found in " + instrumentationScopePropertiesFile + " in classpath."); - } - return InstrumentationScopeInfo.builder(instrumentationScopeName) - .setVersion(instrumentationScopeVersion) - .build(); - } catch (Exception e) { - throw new IllegalStateException("Prometheus metrics library initialization error: Failed to read " + instrumentationScopePropertiesFile + " from classpath.", e); - } + public static InstrumentationScopeInfo loadInstrumentationScopeInfo() { + try { + Properties properties = new Properties(); + properties.load( + PrometheusInstrumentationScope.class + .getClassLoader() + .getResourceAsStream(instrumentationScopePropertiesFile)); + String instrumentationScopeName = properties.getProperty(instrumentationScopeNameKey); + if (instrumentationScopeName == null) { + throw new IllegalStateException( + "Prometheus metrics library initialization error: " + + instrumentationScopeNameKey + + " not found in " + + instrumentationScopePropertiesFile + + " in classpath."); + } + String instrumentationScopeVersion = properties.getProperty(instrumentationScopeVersionKey); + if (instrumentationScopeVersion == null) { + throw new IllegalStateException( + "Prometheus metrics library initialization error: " + + instrumentationScopeVersionKey + + " not found in " + + instrumentationScopePropertiesFile + + " in classpath."); + } + return InstrumentationScopeInfo.builder(instrumentationScopeName) + .setVersion(instrumentationScopeVersion) + .build(); + } catch (Exception e) { + throw new IllegalStateException( + "Prometheus metrics library initialization error: Failed to read " + + instrumentationScopePropertiesFile + + " from classpath.", + e); } + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 37ee4d1de..8d3fb2469 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -19,106 +19,115 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.CollectionRegistration; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; - import java.util.ArrayList; import java.util.Collection; import java.util.List; class PrometheusMetricProducer implements CollectionRegistration { - private final PrometheusRegistry registry; - private final Resource resource; - private final InstrumentationScopeInfo instrumentationScopeInfo; + private final PrometheusRegistry registry; + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; - public PrometheusMetricProducer(PrometheusRegistry registry, InstrumentationScopeInfo instrumentationScopeInfo, Resource resource) { - this.registry = registry; - this.instrumentationScopeInfo = instrumentationScopeInfo; - this.resource = resource; - } + public PrometheusMetricProducer( + PrometheusRegistry registry, + InstrumentationScopeInfo instrumentationScopeInfo, + Resource resource) { + this.registry = registry; + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.resource = resource; + } - @Override - public Collection collectAllMetrics() { - // TODO: We could add a filter configuration for the OpenTelemetry exporter and call registry.scrape(filter) if a filter is configured, like in the Servlet exporter. - MetricSnapshots snapshots = registry.scrape(); - Resource resourceWithTargetInfo = resource.merge(resourceFromTargetInfo(snapshots)); - InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOTelScopeInfo(snapshots); - List result = new ArrayList<>(snapshots.size()); - MetricDataFactory factory = new MetricDataFactory(resourceWithTargetInfo, scopeFromInfo != null ? scopeFromInfo : instrumentationScopeInfo, System.currentTimeMillis()); - for (MetricSnapshot snapshot : snapshots) { - if (snapshot instanceof CounterSnapshot) { - addUnlessNull(result, factory.create((CounterSnapshot) snapshot)); - } else if (snapshot instanceof GaugeSnapshot) { - addUnlessNull(result, factory.create((GaugeSnapshot) snapshot)); - } else if (snapshot instanceof HistogramSnapshot) { - if (!((HistogramSnapshot) snapshot).isGaugeHistogram()) { - addUnlessNull(result, factory.create((HistogramSnapshot) snapshot)); - } - } else if (snapshot instanceof SummarySnapshot) { - addUnlessNull(result, factory.create((SummarySnapshot) snapshot)); - } else if (snapshot instanceof InfoSnapshot) { - String name = snapshot.getMetadata().getPrometheusName(); - if (!name.equals("target") && !name.equals("otel_scope")) { - addUnlessNull(result, factory.create((InfoSnapshot) snapshot)); - } - } else if (snapshot instanceof StateSetSnapshot) { - addUnlessNull(result, factory.create((StateSetSnapshot) snapshot)); - } else if (snapshot instanceof UnknownSnapshot) { - addUnlessNull(result, factory.create((UnknownSnapshot) snapshot)); - } + @Override + public Collection collectAllMetrics() { + // TODO: We could add a filter configuration for the OpenTelemetry exporter and call + // registry.scrape(filter) if a filter is configured, like in the Servlet exporter. + MetricSnapshots snapshots = registry.scrape(); + Resource resourceWithTargetInfo = resource.merge(resourceFromTargetInfo(snapshots)); + InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOTelScopeInfo(snapshots); + List result = new ArrayList<>(snapshots.size()); + MetricDataFactory factory = + new MetricDataFactory( + resourceWithTargetInfo, + scopeFromInfo != null ? scopeFromInfo : instrumentationScopeInfo, + System.currentTimeMillis()); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot instanceof CounterSnapshot) { + addUnlessNull(result, factory.create((CounterSnapshot) snapshot)); + } else if (snapshot instanceof GaugeSnapshot) { + addUnlessNull(result, factory.create((GaugeSnapshot) snapshot)); + } else if (snapshot instanceof HistogramSnapshot) { + if (!((HistogramSnapshot) snapshot).isGaugeHistogram()) { + addUnlessNull(result, factory.create((HistogramSnapshot) snapshot)); } - return result; + } else if (snapshot instanceof SummarySnapshot) { + addUnlessNull(result, factory.create((SummarySnapshot) snapshot)); + } else if (snapshot instanceof InfoSnapshot) { + String name = snapshot.getMetadata().getPrometheusName(); + if (!name.equals("target") && !name.equals("otel_scope")) { + addUnlessNull(result, factory.create((InfoSnapshot) snapshot)); + } + } else if (snapshot instanceof StateSetSnapshot) { + addUnlessNull(result, factory.create((StateSetSnapshot) snapshot)); + } else if (snapshot instanceof UnknownSnapshot) { + addUnlessNull(result, factory.create((UnknownSnapshot) snapshot)); + } } + return result; + } - private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { - ResourceBuilder result = Resource.builder(); - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) { - InfoSnapshot targetInfo = (InfoSnapshot) snapshot; - if (targetInfo.getDataPoints().size() > 0) { - InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getDataPoints().get(0); - Labels labels = data.getLabels(); - for (int i = 0; i < labels.size(); i++) { - result.put(labels.getName(i), labels.getValue(i)); - } - } - } + private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { + ResourceBuilder result = Resource.builder(); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) { + InfoSnapshot targetInfo = (InfoSnapshot) snapshot; + if (targetInfo.getDataPoints().size() > 0) { + InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getDataPoints().get(0); + Labels labels = data.getLabels(); + for (int i = 0; i < labels.size(); i++) { + result.put(labels.getName(i), labels.getValue(i)); + } } - return result.build(); + } } + return result.build(); + } - private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo(MetricSnapshots snapshots) { - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") && snapshot instanceof InfoSnapshot) { - InfoSnapshot scopeInfo = (InfoSnapshot) snapshot; - if (scopeInfo.getDataPoints().size() > 0) { - Labels labels = scopeInfo.getDataPoints().get(0).getLabels(); - String name = null; - String version = null; - AttributesBuilder attributesBuilder = Attributes.builder(); - for (int i = 0; i < labels.size(); i++) { - if (labels.getPrometheusName(i).equals("otel_scope_name")) { - name = labels.getValue(i); - } else if (labels.getPrometheusName(i).equals("otel_scope_version")) { - version = labels.getValue(i); - } else { - attributesBuilder.put(labels.getName(i), labels.getValue(i)); - } - } - if (name != null) { - return InstrumentationScopeInfo.builder(name) - .setVersion(version) - .setAttributes(attributesBuilder.build()) - .build(); - } - } + private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo( + MetricSnapshots snapshots) { + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") + && snapshot instanceof InfoSnapshot) { + InfoSnapshot scopeInfo = (InfoSnapshot) snapshot; + if (scopeInfo.getDataPoints().size() > 0) { + Labels labels = scopeInfo.getDataPoints().get(0).getLabels(); + String name = null; + String version = null; + AttributesBuilder attributesBuilder = Attributes.builder(); + for (int i = 0; i < labels.size(); i++) { + if (labels.getPrometheusName(i).equals("otel_scope_name")) { + name = labels.getValue(i); + } else if (labels.getPrometheusName(i).equals("otel_scope_version")) { + version = labels.getValue(i); + } else { + attributesBuilder.put(labels.getName(i), labels.getValue(i)); } + } + if (name != null) { + return InstrumentationScopeInfo.builder(name) + .setVersion(version) + .setAttributes(attributesBuilder.build()) + .build(); + } } - return null; + } } + return null; + } - private void addUnlessNull(List result, MetricData data) { - if (data != null) { - result.add(data); - } + private void addUnlessNull(List result, MetricData data) { + if (data != null) { + result.add(data); } + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java index c4319b7fc..2c88badfc 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java @@ -5,30 +5,32 @@ public class ResourceAttributes { - // TODO: The OTel Java instrumentation also has a SpringBootServiceNameDetector, we should port this over. - public static Map get(String instrumentationScopeName, - String serviceName, - String serviceNamespace, - String serviceInstanceId, - String serviceVersion, - Map configuredResourceAttributes) { - Map result = new HashMap<>(); - ResourceAttributesFromOtelAgent.addIfAbsent(result, instrumentationScopeName); - putIfAbsent(result, "service.name", serviceName); - putIfAbsent(result, "service.namespace", serviceNamespace); - putIfAbsent(result, "service.instance.id", serviceInstanceId); - putIfAbsent(result, "service.version", serviceVersion); - for (Map.Entry attribute : configuredResourceAttributes.entrySet()) { - putIfAbsent(result, attribute.getKey(), attribute.getValue()); - } - ResourceAttributesFromJarFileName.addIfAbsent(result); - ResourceAttributesDefaults.addIfAbsent(result); - return result; + // TODO: The OTel Java instrumentation also has a SpringBootServiceNameDetector, we should port + // this over. + public static Map get( + String instrumentationScopeName, + String serviceName, + String serviceNamespace, + String serviceInstanceId, + String serviceVersion, + Map configuredResourceAttributes) { + Map result = new HashMap<>(); + ResourceAttributesFromOtelAgent.addIfAbsent(result, instrumentationScopeName); + putIfAbsent(result, "service.name", serviceName); + putIfAbsent(result, "service.namespace", serviceNamespace); + putIfAbsent(result, "service.instance.id", serviceInstanceId); + putIfAbsent(result, "service.version", serviceVersion); + for (Map.Entry attribute : configuredResourceAttributes.entrySet()) { + putIfAbsent(result, attribute.getKey(), attribute.getValue()); } + ResourceAttributesFromJarFileName.addIfAbsent(result); + ResourceAttributesDefaults.addIfAbsent(result); + return result; + } - private static void putIfAbsent(Map result, String key, String value) { - if (value != null) { - result.putIfAbsent(key, value); - } + private static void putIfAbsent(Map result, String key, String value) { + if (value != null) { + result.putIfAbsent(key, value); } + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java index 0e63f4ccb..19328fd73 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java @@ -5,10 +5,10 @@ public class ResourceAttributesDefaults { - private static final String instanceId = UUID.randomUUID().toString(); + private static final String instanceId = UUID.randomUUID().toString(); - public static void addIfAbsent(Map result) { - result.putIfAbsent("service.instance.id", instanceId); - result.putIfAbsent("service.name", "unknown_service:java"); - } + public static void addIfAbsent(Map result) { + result.putIfAbsent("service.instance.id", instanceId); + result.putIfAbsent("service.name", "unknown_service:java"); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java index 093b3b44d..7cf7a51aa 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java @@ -9,52 +9,52 @@ // See io.opentelemetry.instrumentation.resources.JarServiceNameDetector public class ResourceAttributesFromJarFileName { - public static void addIfAbsent(Map result) { - if (result.containsKey("service.name")) { - return; - } - Path jarPath = getJarPathFromSunCommandLine(); - if (jarPath == null) { - return; - } - String serviceName = getServiceName(jarPath); - result.putIfAbsent("service.name", serviceName); + public static void addIfAbsent(Map result) { + if (result.containsKey("service.name")) { + return; } - - private static Path getJarPathFromSunCommandLine() { - String programArguments = System.getProperty("sun.java.command"); - if (programArguments == null) { - return null; - } - // Take the path until the first space. If the path doesn't exist extend it up to the next - // space. Repeat until a path that exists is found or input runs out. - int next = 0; - while (true) { - int nextSpace = programArguments.indexOf(' ', next); - if (nextSpace == -1) { - return pathIfExists(programArguments); - } - Path path = pathIfExists(programArguments.substring(0, nextSpace)); - next = nextSpace + 1; - if (path != null) { - return path; - } - } + Path jarPath = getJarPathFromSunCommandLine(); + if (jarPath == null) { + return; } + String serviceName = getServiceName(jarPath); + result.putIfAbsent("service.name", serviceName); + } - private static Path pathIfExists(String programArguments) { - Path candidate; - try { - candidate = Paths.get(programArguments); - } catch (InvalidPathException e) { - return null; - } - return Files.isRegularFile(candidate) ? candidate : null; + private static Path getJarPathFromSunCommandLine() { + String programArguments = System.getProperty("sun.java.command"); + if (programArguments == null) { + return null; + } + // Take the path until the first space. If the path doesn't exist extend it up to the next + // space. Repeat until a path that exists is found or input runs out. + int next = 0; + while (true) { + int nextSpace = programArguments.indexOf(' ', next); + if (nextSpace == -1) { + return pathIfExists(programArguments); + } + Path path = pathIfExists(programArguments.substring(0, nextSpace)); + next = nextSpace + 1; + if (path != null) { + return path; + } } + } - private static String getServiceName(Path jarPath) { - String jarName = jarPath.getFileName().toString(); - int dotIndex = jarName.lastIndexOf("."); - return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); + private static Path pathIfExists(String programArguments) { + Path candidate; + try { + candidate = Paths.get(programArguments); + } catch (InvalidPathException e) { + return null; } + return Files.isRegularFile(candidate) ? candidate : null; + } + + private static String getServiceName(Path jarPath) { + String jarName = jarPath.getFileName().toString(); + int dotIndex = jarName.lastIndexOf("."); + return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java index a18897fe5..698db602f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.exporter.opentelemetry; +import static java.nio.file.Files.createTempDirectory; + import java.io.File; import java.io.InputStream; import java.lang.reflect.Field; @@ -11,91 +13,98 @@ import java.nio.file.StandardCopyOption; import java.util.Map; -import static java.nio.file.Files.createTempDirectory; - public class ResourceAttributesFromOtelAgent { - private static final String[] OTEL_JARS = new String[]{"opentelemetry-api-1.29.0.jar", "opentelemetry-context-1.29.0.jar"}; + private static final String[] OTEL_JARS = + new String[] {"opentelemetry-api-1.29.0.jar", "opentelemetry-context-1.29.0.jar"}; - /** - * This grabs resource attributes like {@code service.name} and {@code service.instance.id} from - * the OTel Java agent (if present) and adds them to {@code result}. - *

      - * The way this works is as follows: If the OTel Java agent is attached, it modifies the - * {@code GlobalOpenTelemetry.get()} method to return an agent-specific object. - * From that agent-specific object we can get the resource attributes via reflection. - *

      - * So we load the {@code GlobalOpenTelemetry} class (in a separate class loader from the JAR files - * that are bundled with this module), call {@code .get()}, and inspect the returned object. - *

      - * After that we discard the class loader so that all OTel specific classes are unloaded. - * No runtime dependency on any OTel version remains. - */ - public static void addIfAbsent(Map result, String instrumentationScopeName) { - try { - Path tmpDir = createTempDirectory(instrumentationScopeName + "-"); - try { - URL[] otelJars = copyOtelJarsToTempDir(tmpDir, instrumentationScopeName); + /** + * This grabs resource attributes like {@code service.name} and {@code service.instance.id} from + * the OTel Java agent (if present) and adds them to {@code result}. + * + *

      The way this works is as follows: If the OTel Java agent is attached, it modifies the {@code + * GlobalOpenTelemetry.get()} method to return an agent-specific object. From that agent-specific + * object we can get the resource attributes via reflection. + * + *

      So we load the {@code GlobalOpenTelemetry} class (in a separate class loader from the JAR + * files that are bundled with this module), call {@code .get()}, and inspect the returned object. + * + *

      After that we discard the class loader so that all OTel specific classes are unloaded. No + * runtime dependency on any OTel version remains. + */ + public static void addIfAbsent(Map result, String instrumentationScopeName) { + try { + Path tmpDir = createTempDirectory(instrumentationScopeName + "-"); + try { + URL[] otelJars = copyOtelJarsToTempDir(tmpDir, instrumentationScopeName); - try (URLClassLoader classLoader = new URLClassLoader(otelJars)) { - Class globalOpenTelemetryClass = classLoader.loadClass("io.opentelemetry.api.GlobalOpenTelemetry"); - Object globalOpenTelemetry = globalOpenTelemetryClass.getMethod("get").invoke(null); - if (globalOpenTelemetry.getClass().getSimpleName().contains("ApplicationOpenTelemetry")) { - // GlobalOpenTelemetry is injected by the OTel Java aqent - Object applicationMeterProvider = callMethod("getMeterProvider", globalOpenTelemetry); - Object agentMeterProvider = getField("agentMeterProvider", applicationMeterProvider); - Object sdkMeterProvider = getField("delegate", agentMeterProvider); - Object sharedState = getField("sharedState", sdkMeterProvider); - Object resource = callMethod("getResource", sharedState); - Object attributes = callMethod("getAttributes", resource); - Map attributeMap = (Map) callMethod("asMap", attributes); + try (URLClassLoader classLoader = new URLClassLoader(otelJars)) { + Class globalOpenTelemetryClass = + classLoader.loadClass("io.opentelemetry.api.GlobalOpenTelemetry"); + Object globalOpenTelemetry = globalOpenTelemetryClass.getMethod("get").invoke(null); + if (globalOpenTelemetry.getClass().getSimpleName().contains("ApplicationOpenTelemetry")) { + // GlobalOpenTelemetry is injected by the OTel Java aqent + Object applicationMeterProvider = callMethod("getMeterProvider", globalOpenTelemetry); + Object agentMeterProvider = getField("agentMeterProvider", applicationMeterProvider); + Object sdkMeterProvider = getField("delegate", agentMeterProvider); + Object sharedState = getField("sharedState", sdkMeterProvider); + Object resource = callMethod("getResource", sharedState); + Object attributes = callMethod("getAttributes", resource); + Map attributeMap = (Map) callMethod("asMap", attributes); - for (Map.Entry entry : attributeMap.entrySet()) { - if (entry.getKey() != null && entry.getValue() != null) { - result.putIfAbsent(entry.getKey().toString(), entry.getValue().toString()); - } - } - } - } - } finally { - deleteTempDir(tmpDir.toFile()); + for (Map.Entry entry : attributeMap.entrySet()) { + if (entry.getKey() != null && entry.getValue() != null) { + result.putIfAbsent(entry.getKey().toString(), entry.getValue().toString()); + } } - } catch (Exception ignored) { + } } + } finally { + deleteTempDir(tmpDir.toFile()); + } + } catch (Exception ignored) { } + } - private static Object getField(String name, Object obj) throws Exception { - Field field = obj.getClass().getDeclaredField(name); - field.setAccessible(true); - return field.get(obj); - } + private static Object getField(String name, Object obj) throws Exception { + Field field = obj.getClass().getDeclaredField(name); + field.setAccessible(true); + return field.get(obj); + } - private static Object callMethod(String name, Object obj) throws Exception { - Method method = obj.getClass().getMethod(name); - method.setAccessible(true); - return method.invoke(obj); - } + private static Object callMethod(String name, Object obj) throws Exception { + Method method = obj.getClass().getMethod(name); + method.setAccessible(true); + return method.invoke(obj); + } - private static URL[] copyOtelJarsToTempDir(Path tmpDir, String instrumentationScopeName) throws Exception { - URL[] result = new URL[OTEL_JARS.length]; - for (int i = 0; i < OTEL_JARS.length; i++) { - InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("lib/" + OTEL_JARS[i]); - if (inputStream == null) { - throw new IllegalStateException("Error initializing " + instrumentationScopeName + ": lib/" + OTEL_JARS[i] + " not found in classpath."); - } - File outputFile = tmpDir.resolve(OTEL_JARS[i]).toFile(); - Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - inputStream.close(); - result[i] = outputFile.toURI().toURL(); - } - return result; + private static URL[] copyOtelJarsToTempDir(Path tmpDir, String instrumentationScopeName) + throws Exception { + URL[] result = new URL[OTEL_JARS.length]; + for (int i = 0; i < OTEL_JARS.length; i++) { + InputStream inputStream = + Thread.currentThread().getContextClassLoader().getResourceAsStream("lib/" + OTEL_JARS[i]); + if (inputStream == null) { + throw new IllegalStateException( + "Error initializing " + + instrumentationScopeName + + ": lib/" + + OTEL_JARS[i] + + " not found in classpath."); + } + File outputFile = tmpDir.resolve(OTEL_JARS[i]).toFile(); + Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + inputStream.close(); + result[i] = outputFile.toURI().toURL(); } + return result; + } - private static void deleteTempDir(File tmpDir) { - // We don't have subdirectories, so this simple implementation should work. - for (File file : tmpDir.listFiles()) { - file.delete(); - } - tmpDir.delete(); + private static void deleteTempDir(File tmpDir) { + // We don't have subdirectories, so this simple implementation should work. + for (File file : tmpDir.listFiles()) { + file.delete(); } + tmpDir.delete(); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java index 8f4a627ff..12b7c7acd 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java @@ -3,20 +3,24 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; - import java.util.List; class DoublePointDataImpl extends PointDataImpl implements DoublePointData { - private final double value; + private final double value; - public DoublePointDataImpl(double value, long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { - super(startEpochNanos, epochNanos, attributes, exemplars); - this.value = value; - } + public DoublePointDataImpl( + double value, + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.value = value; + } - @Override - public double getValue() { - return value; - } + @Override + public double getValue() { + return value; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java index 5acacc457..798e9b5df 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java @@ -1,46 +1,45 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; - import java.util.ArrayList; import java.util.List; class ExponentialHistogramBucketsImpl implements ExponentialHistogramBuckets { - private final int scale; - private final int offset; - private final List bucketCounts = new ArrayList<>(); - - ExponentialHistogramBucketsImpl(int scale, int offset) { - this.scale = scale; - this.offset = offset; - } - - void addCount(long count) { - bucketCounts.add(count); - } - - @Override - public int getScale() { - return scale; - } - - @Override - public int getOffset() { - return offset; - } - - @Override - public List getBucketCounts() { - return bucketCounts; - } - - @Override - public long getTotalCount() { - long result = 0; - for (Long count : bucketCounts) { - result += count; - } - return result; + private final int scale; + private final int offset; + private final List bucketCounts = new ArrayList<>(); + + ExponentialHistogramBucketsImpl(int scale, int offset) { + this.scale = scale; + this.offset = offset; + } + + void addCount(long count) { + bucketCounts.add(count); + } + + @Override + public int getScale() { + return scale; + } + + @Override + public int getOffset() { + return offset; + } + + @Override + public List getBucketCounts() { + return bucketCounts; + } + + @Override + public long getTotalCount() { + long result = 0; + for (Long count : bucketCounts) { + result += count; } + return result; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java index 799e44712..3c5a893e2 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java @@ -4,82 +4,92 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; - import java.util.List; -public class ExponentialHistogramPointDataImpl extends PointDataImpl implements ExponentialHistogramPointData { - - private final int scale; - private final double sum; - private final long count; - private final long zeroCount; - private final double min; - private final double max; - - private final ExponentialHistogramBuckets positiveBuckets; - private final ExponentialHistogramBuckets negativeBuckets; - - ExponentialHistogramPointDataImpl(int scale, double sum, long count, long zeroCount, double min, double max, - ExponentialHistogramBuckets positiveBuckets, ExponentialHistogramBuckets negativeBuckets, - long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { - super(startEpochNanos, epochNanos, attributes, exemplars); - this.scale = scale; - this.sum = sum; - this.count = count; - this.zeroCount = zeroCount; - this.min = min; - this.max = max; - this.positiveBuckets = positiveBuckets; - this.negativeBuckets = negativeBuckets; - } - - @Override - public int getScale() { - return scale; - } - - @Override - public double getSum() { - return sum; - } - - @Override - public long getCount() { - return count; - } - - @Override - public long getZeroCount() { - return zeroCount; - } - - @Override - public boolean hasMin() { - return !Double.isNaN(min); - } - - @Override - public double getMin() { - return min; - } - - @Override - public boolean hasMax() { - return !Double.isNaN(max); - } - - @Override - public double getMax() { - return max; - } - - @Override - public ExponentialHistogramBuckets getPositiveBuckets() { - return positiveBuckets; - } - - @Override - public ExponentialHistogramBuckets getNegativeBuckets() { - return negativeBuckets; - } +public class ExponentialHistogramPointDataImpl extends PointDataImpl + implements ExponentialHistogramPointData { + + private final int scale; + private final double sum; + private final long count; + private final long zeroCount; + private final double min; + private final double max; + + private final ExponentialHistogramBuckets positiveBuckets; + private final ExponentialHistogramBuckets negativeBuckets; + + ExponentialHistogramPointDataImpl( + int scale, + double sum, + long count, + long zeroCount, + double min, + double max, + ExponentialHistogramBuckets positiveBuckets, + ExponentialHistogramBuckets negativeBuckets, + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.scale = scale; + this.sum = sum; + this.count = count; + this.zeroCount = zeroCount; + this.min = min; + this.max = max; + this.positiveBuckets = positiveBuckets; + this.negativeBuckets = negativeBuckets; + } + + @Override + public int getScale() { + return scale; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public long getCount() { + return count; + } + + @Override + public long getZeroCount() { + return zeroCount; + } + + @Override + public boolean hasMin() { + return !Double.isNaN(min); + } + + @Override + public double getMin() { + return min; + } + + @Override + public boolean hasMax() { + return !Double.isNaN(max); + } + + @Override + public double getMax() { + return max; + } + + @Override + public ExponentialHistogramBuckets getPositiveBuckets() { + return positiveBuckets; + } + + @Override + public ExponentialHistogramBuckets getNegativeBuckets() { + return negativeBuckets; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java index af9c1519d..19b141b04 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java @@ -3,66 +3,74 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; - import java.util.List; public class HistogramPointDataImpl extends PointDataImpl implements HistogramPointData { - private final double sum; - private final long count; - private final double min; - private final double max; - private final List boundaries; - private final List counts; + private final double sum; + private final long count; + private final double min; + private final double max; + private final List boundaries; + private final List counts; - public HistogramPointDataImpl(double sum, long count, double min, double max, List boundaries, List counts, - long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { - super(startEpochNanos, epochNanos, attributes, exemplars); - this.sum = sum; - this.count = count; - this.min = min; - this.max = max; - this.boundaries = boundaries; - this.counts = counts; - } + public HistogramPointDataImpl( + double sum, + long count, + double min, + double max, + List boundaries, + List counts, + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.sum = sum; + this.count = count; + this.min = min; + this.max = max; + this.boundaries = boundaries; + this.counts = counts; + } - @Override - public double getSum() { - return sum; - } + @Override + public double getSum() { + return sum; + } - @Override - public long getCount() { - return count; - } + @Override + public long getCount() { + return count; + } - @Override - public boolean hasMin() { - return !Double.isNaN(min); - } + @Override + public boolean hasMin() { + return !Double.isNaN(min); + } - @Override - public double getMin() { - return min; - } + @Override + public double getMin() { + return min; + } - @Override - public boolean hasMax() { - return !Double.isNaN(max); - } + @Override + public boolean hasMax() { + return !Double.isNaN(max); + } - @Override - public double getMax() { - return max; - } + @Override + public double getMax() { + return max; + } - @Override - public List getBoundaries() { - return boundaries; - } + @Override + public List getBoundaries() { + return boundaries; + } - @Override - public List getCounts() { - return counts; - } + @Override + public List getCounts() { + return counts; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 6e723e20a..95cb59546 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -13,49 +13,84 @@ public class MetricDataFactory { - private final Resource resource; - private final InstrumentationScopeInfo instrumentationScopeInfo; - private final long currentTimeMillis; - - public MetricDataFactory(Resource resource, InstrumentationScopeInfo instrumentationScopeInfo, long currentTimeMillis) { - this.resource = resource; - this.instrumentationScopeInfo = instrumentationScopeInfo; - this.currentTimeMillis = currentTimeMillis; - } + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; + private final long currentTimeMillis; - public MetricData create(CounterSnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusCounter(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } + public MetricDataFactory( + Resource resource, + InstrumentationScopeInfo instrumentationScopeInfo, + long currentTimeMillis) { + this.resource = resource; + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.currentTimeMillis = currentTimeMillis; + } - public MetricData create(GaugeSnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusGauge(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } + public MetricData create(CounterSnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusCounter(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } - public MetricData create(HistogramSnapshot snapshot) { - if (!snapshot.getDataPoints().isEmpty()) { - HistogramSnapshot.HistogramDataPointSnapshot firstDataPoint = snapshot.getDataPoints().get(0); - if (firstDataPoint.hasNativeHistogramData()) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusNativeHistogram(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } else if (firstDataPoint.hasClassicHistogramData()) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusClassicHistogram(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } - } - return null; - } + public MetricData create(GaugeSnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusGauge(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } - public MetricData create(SummarySnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusSummary(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); + public MetricData create(HistogramSnapshot snapshot) { + if (!snapshot.getDataPoints().isEmpty()) { + HistogramSnapshot.HistogramDataPointSnapshot firstDataPoint = snapshot.getDataPoints().get(0); + if (firstDataPoint.hasNativeHistogramData()) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusNativeHistogram(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } else if (firstDataPoint.hasClassicHistogramData()) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusClassicHistogram(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } } + return null; + } - public MetricData create(InfoSnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusInfo(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } + public MetricData create(SummarySnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusSummary(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } - public MetricData create(StateSetSnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusStateSet(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } + public MetricData create(InfoSnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusInfo(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } - public MetricData create(UnknownSnapshot snapshot) { - return new PrometheusMetricData<>(snapshot.getMetadata(), new PrometheusUnknown(snapshot, currentTimeMillis), instrumentationScopeInfo, resource); - } + public MetricData create(StateSetSnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusStateSet(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } + + public MetricData create(UnknownSnapshot snapshot) { + return new PrometheusMetricData<>( + snapshot.getMetadata(), + new PrometheusUnknown(snapshot, currentTimeMillis), + instrumentationScopeInfo, + resource); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java index b3795e5dd..d1ba082e5 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java @@ -3,40 +3,43 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; - import java.util.List; abstract class PointDataImpl implements PointData { - private final long startEpochNanos; - private final long epochNanos; - private final Attributes attributes; - private final List exemplars; - - PointDataImpl(long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { - this.startEpochNanos = startEpochNanos; - this.epochNanos = epochNanos; - this.attributes = attributes; - this.exemplars = exemplars; - } - - @Override - public long getStartEpochNanos() { - return startEpochNanos; - } - - @Override - public long getEpochNanos() { - return epochNanos; - } - - @Override - public Attributes getAttributes() { - return attributes; - } - - @Override - public List getExemplars() { - return exemplars; - } + private final long startEpochNanos; + private final long epochNanos; + private final Attributes attributes; + private final List exemplars; + + PointDataImpl( + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + this.startEpochNanos = startEpochNanos; + this.epochNanos = epochNanos; + this.attributes = attributes; + this.exemplars = exemplars; + } + + @Override + public long getStartEpochNanos() { + return startEpochNanos; + } + + @Override + public long getEpochNanos() { + return epochNanos; + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public List getExemplars() { + return exemplars; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index 0040c7d17..3434dc467 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -6,75 +6,78 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; - import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -class PrometheusClassicHistogram extends PrometheusData implements HistogramData { +class PrometheusClassicHistogram extends PrometheusData + implements HistogramData { - private final List points; + private final List points; - PrometheusClassicHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.HISTOGRAM); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } + PrometheusClassicHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.HISTOGRAM); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } - @Override - public AggregationTemporality getAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } - @Override - public Collection getPoints() { - return points; - } + @Override + public Collection getPoints() { + return points; + } - private HistogramPointData toOtelDataPoint(HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { - if (!dataPoint.hasClassicHistogramData()) { - return null; - } else { - return new HistogramPointDataImpl( - dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, - dataPoint.hasCount() ? dataPoint.getCount() : calculateCount(dataPoint.getClassicBuckets()), - Double.NaN, - Double.NaN, - makeBoundaries(dataPoint.getClassicBuckets()), - makeCounts(dataPoint.getClassicBuckets()), - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplars(dataPoint.getExemplars()) - ); - } + private HistogramPointData toOtelDataPoint( + HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { + if (!dataPoint.hasClassicHistogramData()) { + return null; + } else { + return new HistogramPointDataImpl( + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() + ? dataPoint.getCount() + : calculateCount(dataPoint.getClassicBuckets()), + Double.NaN, + Double.NaN, + makeBoundaries(dataPoint.getClassicBuckets()), + makeCounts(dataPoint.getClassicBuckets()), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars())); } + } - private long calculateCount(ClassicHistogramBuckets buckets) { - int result = 0; - for (int i=0; i makeBoundaries(ClassicHistogramBuckets buckets) { - List result = new ArrayList<>(buckets.size()); - for (int i=0; i makeBoundaries(ClassicHistogramBuckets buckets) { + List result = new ArrayList<>(buckets.size()); + for (int i = 0; i < buckets.size(); i++) { + result.add(buckets.getUpperBound(i)); } + return result; + } - private List makeCounts(ClassicHistogramBuckets buckets) { - List result = new ArrayList<>(buckets.size()); - for (int i=0; i makeCounts(ClassicHistogramBuckets buckets) { + List result = new ArrayList<>(buckets.size()); + for (int i = 0; i < buckets.size(); i++) { + result.add(buckets.getCount(i)); } + return result; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java index 4ad04975f..f730fb97d 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java @@ -1,48 +1,49 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; -import io.prometheus.metrics.model.snapshots.CounterSnapshot; - import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -class PrometheusCounter extends PrometheusData implements SumData { - - private final List points; - - public PrometheusCounter(CounterSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.DOUBLE_SUM); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .collect(Collectors.toList()); - } - - @Override - public boolean isMonotonic() { - return true; - } - - @Override - public AggregationTemporality getAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - - @Override - public Collection getPoints() { - return points; - } - - private DoublePointData toOtelDataPoint(CounterSnapshot.CounterDataPointSnapshot dataPoint, long currentTimeMillis) { - return new DoublePointDataImpl( - dataPoint.getValue(), - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplar(dataPoint.getExemplar()) - ); - } +class PrometheusCounter extends PrometheusData + implements SumData { + + private final List points; + + public PrometheusCounter(CounterSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public boolean isMonotonic() { + return true; + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint( + CounterSnapshot.CounterDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar())); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index 7d67a22fa..7e09a483e 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -11,7 +11,6 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; - import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -20,78 +19,81 @@ abstract class PrometheusData implements Data { - private final MetricDataType type; + private final MetricDataType type; - public PrometheusData(MetricDataType type) { - this.type = type; - } + public PrometheusData(MetricDataType type) { + this.type = type; + } - public MetricDataType getType() { - return type; - } - - protected Attributes labelsToAttributes(Labels labels) { - if (labels.isEmpty()) { - return Attributes.empty(); - } else { - AttributesBuilder builder = Attributes.builder(); - for (int i=0; i convertExemplar(Exemplar exemplar) { - if (exemplar == null) { - return Collections.emptyList(); - } - return convertExemplars(Exemplars.of(exemplar)); + protected Attributes labelsToAttributes(Labels labels) { + if (labels.isEmpty()) { + return Attributes.empty(); + } else { + AttributesBuilder builder = Attributes.builder(); + for (int i = 0; i < labels.size(); i++) { + builder.put(labels.getName(i), labels.getValue(i)); + } + return builder.build(); } + } - protected List convertExemplars(Exemplars exemplars) { - return StreamSupport.stream(exemplars.spliterator(), false) - .map(this::toDoubleExemplarData) - .collect(Collectors.toList()); + protected List convertExemplar(Exemplar exemplar) { + if (exemplar == null) { + return Collections.emptyList(); } + return convertExemplars(Exemplars.of(exemplar)); + } - protected DoubleExemplarData toDoubleExemplarData(Exemplar exemplar) { - if (exemplar == null) { - return null; - } - - AttributesBuilder filteredAttributesBuilder = Attributes.builder(); - String traceId = null; - String spanId = null; - for (Label label : exemplar.getLabels()) { - if (label.getName().equals(Exemplar.TRACE_ID)) { - traceId = label.getValue(); - } - else if (label.getName().equals(Exemplar.SPAN_ID)) { - spanId = label.getValue(); - } else { - filteredAttributesBuilder.put(label.getName(), label.getValue()); - } - } - Attributes filteredAttributes = filteredAttributesBuilder.build(); + protected List convertExemplars(Exemplars exemplars) { + return StreamSupport.stream(exemplars.spliterator(), false) + .map(this::toDoubleExemplarData) + .collect(Collectors.toList()); + } - SpanContext spanContext = (traceId != null && spanId != null) - ? SpanContext.create(traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()) - : SpanContext.getInvalid(); - - return ImmutableDoubleExemplarData.create( - filteredAttributes, - TimeUnit.MILLISECONDS.toNanos(exemplar.getTimestampMillis()), - spanContext, - exemplar.getValue()); + protected DoubleExemplarData toDoubleExemplarData(Exemplar exemplar) { + if (exemplar == null) { + return null; } - protected long getStartEpochNanos(DataPointSnapshot dataPoint) { - return dataPoint.hasCreatedTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getCreatedTimestampMillis()) : 0L; + AttributesBuilder filteredAttributesBuilder = Attributes.builder(); + String traceId = null; + String spanId = null; + for (Label label : exemplar.getLabels()) { + if (label.getName().equals(Exemplar.TRACE_ID)) { + traceId = label.getValue(); + } else if (label.getName().equals(Exemplar.SPAN_ID)) { + spanId = label.getValue(); + } else { + filteredAttributesBuilder.put(label.getName(), label.getValue()); + } } + Attributes filteredAttributes = filteredAttributesBuilder.build(); - protected long getEpochNanos(DataPointSnapshot dataPoint, long currentTimeMillis) { - return dataPoint.hasScrapeTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getScrapeTimestampMillis()) : TimeUnit.MILLISECONDS.toNanos(currentTimeMillis); - } + SpanContext spanContext = + (traceId != null && spanId != null) + ? SpanContext.create(traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()) + : SpanContext.getInvalid(); + + return ImmutableDoubleExemplarData.create( + filteredAttributes, + TimeUnit.MILLISECONDS.toNanos(exemplar.getTimestampMillis()), + spanContext, + exemplar.getValue()); + } + + protected long getStartEpochNanos(DataPointSnapshot dataPoint) { + return dataPoint.hasCreatedTimestamp() + ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getCreatedTimestampMillis()) + : 0L; + } + protected long getEpochNanos(DataPointSnapshot dataPoint, long currentTimeMillis) { + return dataPoint.hasScrapeTimestamp() + ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getScrapeTimestampMillis()) + : TimeUnit.MILLISECONDS.toNanos(currentTimeMillis); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java index 73e176bb6..872d569e6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -4,34 +4,35 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; - import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -class PrometheusGauge extends PrometheusData implements GaugeData { +class PrometheusGauge extends PrometheusData + implements GaugeData { - private final List points; + private final List points; - public PrometheusGauge(GaugeSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.DOUBLE_GAUGE); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .collect(Collectors.toList()); - } + public PrometheusGauge(GaugeSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_GAUGE); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } - @Override - public Collection getPoints() { - return points; - } + @Override + public Collection getPoints() { + return points; + } - private DoublePointData toOtelDataPoint(GaugeSnapshot.GaugeDataPointSnapshot dataPoint, long currentTimeMillis) { - return new DoublePointDataImpl( - dataPoint.getValue(), - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplar(dataPoint.getExemplar()) - ); - } + private DoublePointData toOtelDataPoint( + GaugeSnapshot.GaugeDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar())); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index 6159e77fb..eb5ae48f6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -5,45 +5,46 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; - import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -public class PrometheusInfo extends PrometheusData implements SumData { - - private final List points; - - public PrometheusInfo(InfoSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.DOUBLE_SUM); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .collect(Collectors.toList()); - } - - @Override - public boolean isMonotonic() { - return false; - } - - @Override - public AggregationTemporality getAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - - @Override - public Collection getPoints() { - return points; - } - - private DoublePointData toOtelDataPoint(InfoSnapshot.InfoDataPointSnapshot dataPoint, long currentTimeMillis) { - return new DoublePointDataImpl( - 1.0, - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - Collections.emptyList() - ); - } +public class PrometheusInfo extends PrometheusData + implements SumData { + + private final List points; + + public PrometheusInfo(InfoSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } + + @Override + public boolean isMonotonic() { + return false; + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint( + InfoSnapshot.InfoDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + 1.0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + Collections.emptyList()); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java index 348ff535f..5d86000b8 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -11,124 +11,154 @@ class PrometheusMetricData> implements MetricData { - private final Resource resource; - private final InstrumentationScopeInfo instrumentationScopeInfo; - private final String name; - private final String description; - private final String unit; - T data; + private final Resource resource; + private final InstrumentationScopeInfo instrumentationScopeInfo; + private final String name; + private final String description; + private final String unit; + T data; - PrometheusMetricData(MetricMetadata metricMetadata, T data, InstrumentationScopeInfo instrumentationScopeInfo, Resource resource) { - this.instrumentationScopeInfo = instrumentationScopeInfo; - this.resource = resource; - this.name = getNameWithoutUnit(metricMetadata); - this.description = metricMetadata.getHelp(); - this.unit = convertUnit(metricMetadata.getUnit()); - this.data = data; - } + PrometheusMetricData( + MetricMetadata metricMetadata, + T data, + InstrumentationScopeInfo instrumentationScopeInfo, + Resource resource) { + this.instrumentationScopeInfo = instrumentationScopeInfo; + this.resource = resource; + this.name = getNameWithoutUnit(metricMetadata); + this.description = metricMetadata.getHelp(); + this.unit = convertUnit(metricMetadata.getUnit()); + this.data = data; + } - // In OpenTelemetry the unit should not be part of the metric name. - private String getNameWithoutUnit(MetricMetadata metricMetadata) { - String name = metricMetadata.getName(); - if (metricMetadata.getUnit() != null) { - String unit = metricMetadata.getUnit().toString(); - if (name.endsWith(unit)) { - name = name.substring(0, name.length() - unit.length()); - } - while (name.endsWith("_")) { - name = name.substring(0, name.length()-1); - } - } - return name; + // In OpenTelemetry the unit should not be part of the metric name. + private String getNameWithoutUnit(MetricMetadata metricMetadata) { + String name = metricMetadata.getName(); + if (metricMetadata.getUnit() != null) { + String unit = metricMetadata.getUnit().toString(); + if (name.endsWith(unit)) { + name = name.substring(0, name.length() - unit.length()); + } + while (name.endsWith("_")) { + name = name.substring(0, name.length() - 1); + } } + return name; + } - // See https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/6cf4dec6cb42d87d8840e9f67d4acf66d4eb8fda/pkg/translator/prometheus/normalize_name.go#L19 - private String convertUnit(Unit unit) { - if (unit == null) { - return null; - } - switch (unit.toString()) { - // Time - case "days": return "d"; - case "hours": return "h"; - case "minutes": return "min"; - case "seconds": return "s"; - case "milliseconds": return "ms"; - case "microseconds": return "us"; - case "nanoseconds": return "ns"; - // Bytes - case "bytes": return "By"; - case "kibibytes": return "KiBy"; - case "mebibytes": return "MiBy"; - case "gibibytes": return "GiBy"; - case "tibibytes": return "TiBy"; - case "kilobytes": return "KBy"; - case "megabytes": return "MBy"; - case "gigabytes": return "GBy"; - case "terabytes": return "TBy"; - // SI - case "meters": return "m"; - case "volts": return "V"; - case "amperes": return "A"; - case "joules": return "J"; - case "watts": return "W"; - case "grams": return "g"; - // Misc - case "celsius": return "Cel"; - case "hertz": return "Hz"; - case "percent": return "%"; - // default - default: - return unit.toString(); - } + // See + // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/6cf4dec6cb42d87d8840e9f67d4acf66d4eb8fda/pkg/translator/prometheus/normalize_name.go#L19 + private String convertUnit(Unit unit) { + if (unit == null) { + return null; } - - @Override - public Resource getResource() { - return resource; + switch (unit.toString()) { + // Time + case "days": + return "d"; + case "hours": + return "h"; + case "minutes": + return "min"; + case "seconds": + return "s"; + case "milliseconds": + return "ms"; + case "microseconds": + return "us"; + case "nanoseconds": + return "ns"; + // Bytes + case "bytes": + return "By"; + case "kibibytes": + return "KiBy"; + case "mebibytes": + return "MiBy"; + case "gibibytes": + return "GiBy"; + case "tibibytes": + return "TiBy"; + case "kilobytes": + return "KBy"; + case "megabytes": + return "MBy"; + case "gigabytes": + return "GBy"; + case "terabytes": + return "TBy"; + // SI + case "meters": + return "m"; + case "volts": + return "V"; + case "amperes": + return "A"; + case "joules": + return "J"; + case "watts": + return "W"; + case "grams": + return "g"; + // Misc + case "celsius": + return "Cel"; + case "hertz": + return "Hz"; + case "percent": + return "%"; + // default + default: + return unit.toString(); } + } + + @Override + public Resource getResource() { + return resource; + } - @Override - public InstrumentationScopeInfo getInstrumentationScopeInfo() { + @Override + public InstrumentationScopeInfo getInstrumentationScopeInfo() { return instrumentationScopeInfo; - } + } - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } - @Override - public String getDescription() { - return description; - } + @Override + public String getDescription() { + return description; + } - @Override - public String getUnit() { - return unit; - } + @Override + public String getUnit() { + return unit; + } - @Override - public MetricDataType getType() { - return data.getType(); - } + @Override + public MetricDataType getType() { + return data.getType(); + } - @Override - public T getData() { - return data; - } + @Override + public T getData() { + return data; + } - @Override - public SumData getDoubleSumData() { - if (data instanceof PrometheusCounter) { - return (PrometheusCounter) data; - } - if (data instanceof PrometheusStateSet) { - return (PrometheusStateSet) data; - } - if (data instanceof PrometheusInfo) { - return (PrometheusInfo) data; - } - return MetricData.super.getDoubleSumData(); + @Override + public SumData getDoubleSumData() { + if (data instanceof PrometheusCounter) { + return (PrometheusCounter) data; + } + if (data instanceof PrometheusStateSet) { + return (PrometheusStateSet) data; + } + if (data instanceof PrometheusInfo) { + return (PrometheusInfo) data; } + return MetricData.super.getDoubleSumData(); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java index 83ce1f14a..eb2a6555e 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -7,81 +7,82 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; - import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -class PrometheusNativeHistogram extends PrometheusData implements ExponentialHistogramData { +class PrometheusNativeHistogram extends PrometheusData + implements ExponentialHistogramData { - private final List points; + private final List points; - PrometheusNativeHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.EXPONENTIAL_HISTOGRAM); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } + PrometheusNativeHistogram(HistogramSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.EXPONENTIAL_HISTOGRAM); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } - @Override - public AggregationTemporality getAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } - @Override - public Collection getPoints() { - return points; - } + @Override + public Collection getPoints() { + return points; + } - private ExponentialHistogramPointData toOtelDataPoint(HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { - if (!dataPoint.hasNativeHistogramData()) { - return null; - } - return new ExponentialHistogramPointDataImpl( - dataPoint.getNativeSchema(), - dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, - dataPoint.hasCount() ? dataPoint.getCount() : calculateCount(dataPoint), - dataPoint.getNativeZeroCount(), - Double.NaN, - Double.NaN, - convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForPositiveValues()), - convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForNegativeValues()), - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplars(dataPoint.getExemplars()) - ); + private ExponentialHistogramPointData toOtelDataPoint( + HistogramSnapshot.HistogramDataPointSnapshot dataPoint, long currentTimeMillis) { + if (!dataPoint.hasNativeHistogramData()) { + return null; } + return new ExponentialHistogramPointDataImpl( + dataPoint.getNativeSchema(), + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() ? dataPoint.getCount() : calculateCount(dataPoint), + dataPoint.getNativeZeroCount(), + Double.NaN, + Double.NaN, + convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForPositiveValues()), + convertBuckets(dataPoint.getNativeSchema(), dataPoint.getNativeBucketsForNegativeValues()), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars())); + } - private ExponentialHistogramBuckets convertBuckets(int scale, NativeHistogramBuckets buckets) { - if (buckets.size() == 0) { - return new ExponentialHistogramBucketsImpl(scale, 0); - } - int offset = buckets.getBucketIndex(0); - ExponentialHistogramBucketsImpl result = new ExponentialHistogramBucketsImpl(scale, offset-1); - int currentBucket = 0; - for (int i=offset; i<=buckets.getBucketIndex(buckets.size()-1); i++) { - if (buckets.getBucketIndex(currentBucket) == i) { - result.addCount(buckets.getCount(currentBucket)); - currentBucket++; - } else { - result.addCount(0); - } - } - return result; + private ExponentialHistogramBuckets convertBuckets(int scale, NativeHistogramBuckets buckets) { + if (buckets.size() == 0) { + return new ExponentialHistogramBucketsImpl(scale, 0); + } + int offset = buckets.getBucketIndex(0); + ExponentialHistogramBucketsImpl result = new ExponentialHistogramBucketsImpl(scale, offset - 1); + int currentBucket = 0; + for (int i = offset; i <= buckets.getBucketIndex(buckets.size() - 1); i++) { + if (buckets.getBucketIndex(currentBucket) == i) { + result.addCount(buckets.getCount(currentBucket)); + currentBucket++; + } else { + result.addCount(0); + } } + return result; + } - private long calculateCount(HistogramSnapshot.HistogramDataPointSnapshot dataPoint) { - long result = 0L; - for (int i=0; i implements SumData { - - private final List points; - public PrometheusStateSet(StateSetSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.DOUBLE_SUM); - this.points = new ArrayList<>(); - for (StateSetSnapshot.StateSetDataPointSnapshot dataPoint : snapshot.getDataPoints()) { - for (int i=0; i + implements SumData { - @Override - public AggregationTemporality getAggregationTemporality() { - return AggregationTemporality.CUMULATIVE; - } - - @Override - public Collection getPoints() { - return points; - } + private final List points; - private DoublePointData toOtelDataPoint(StateSetSnapshot snapshot, StateSetSnapshot.StateSetDataPointSnapshot dataPoint, int i, long currentTimeMillis) { - return new DoublePointDataImpl( - dataPoint.isTrue(i) ? 1.0 : 0.0, - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels().merge(Labels.of(snapshot.getMetadata().getName(), dataPoint.getName(i)))), - Collections.emptyList() - ); + public PrometheusStateSet(StateSetSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_SUM); + this.points = new ArrayList<>(); + for (StateSetSnapshot.StateSetDataPointSnapshot dataPoint : snapshot.getDataPoints()) { + for (int i = 0; i < dataPoint.size(); i++) { + this.points.add(toOtelDataPoint(snapshot, dataPoint, i, currentTimeMillis)); + } } + } + + @Override + public boolean isMonotonic() { + return false; + } + + @Override + public AggregationTemporality getAggregationTemporality() { + return AggregationTemporality.CUMULATIVE; + } + + @Override + public Collection getPoints() { + return points; + } + + private DoublePointData toOtelDataPoint( + StateSetSnapshot snapshot, + StateSetSnapshot.StateSetDataPointSnapshot dataPoint, + int i, + long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.isTrue(i) ? 1.0 : 0.0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes( + dataPoint + .getLabels() + .merge(Labels.of(snapshot.getMetadata().getName(), dataPoint.getName(i)))), + Collections.emptyList()); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java index 11e780018..709b819af 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java @@ -5,39 +5,40 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; - import java.util.Collection; import java.util.List; import java.util.stream.Collectors; class PrometheusSummary extends PrometheusData implements SummaryData { - private final List points; + private final List points; - PrometheusSummary(SummarySnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.SUMMARY); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .collect(Collectors.toList()); - } + PrometheusSummary(SummarySnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.SUMMARY); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } - @Override - public Collection getPoints() { - return points; - } + @Override + public Collection getPoints() { + return points; + } - private SummaryPointData toOtelDataPoint(SummarySnapshot.SummaryDataPointSnapshot dataPoint, long currentTimeMillis) { - SummaryPointDataImpl result = new SummaryPointDataImpl( - dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, - dataPoint.hasCount() ? dataPoint.getCount() : 0, - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplars(dataPoint.getExemplars()) - ); - for (Quantile quantile : dataPoint.getQuantiles()) { - result.addValue(quantile.getQuantile(), quantile.getValue()); - } - return result; + private SummaryPointData toOtelDataPoint( + SummarySnapshot.SummaryDataPointSnapshot dataPoint, long currentTimeMillis) { + SummaryPointDataImpl result = + new SummaryPointDataImpl( + dataPoint.hasSum() ? dataPoint.getSum() : Double.NaN, + dataPoint.hasCount() ? dataPoint.getCount() : 0, + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplars(dataPoint.getExemplars())); + for (Quantile quantile : dataPoint.getQuantiles()) { + result.addValue(quantile.getQuantile(), quantile.getValue()); } + return result; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java index 9bb2f8e76..39c8f508f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -4,34 +4,35 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; - import java.util.Collection; import java.util.List; import java.util.stream.Collectors; -class PrometheusUnknown extends PrometheusData implements GaugeData { +class PrometheusUnknown extends PrometheusData + implements GaugeData { - private final List points; + private final List points; - public PrometheusUnknown(UnknownSnapshot snapshot, long currentTimeMillis) { - super(MetricDataType.DOUBLE_GAUGE); - this.points = snapshot.getDataPoints().stream() - .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) - .collect(Collectors.toList()); - } + public PrometheusUnknown(UnknownSnapshot snapshot, long currentTimeMillis) { + super(MetricDataType.DOUBLE_GAUGE); + this.points = + snapshot.getDataPoints().stream() + .map(dataPoint -> toOtelDataPoint(dataPoint, currentTimeMillis)) + .collect(Collectors.toList()); + } - @Override - public Collection getPoints() { - return points; - } + @Override + public Collection getPoints() { + return points; + } - private DoublePointData toOtelDataPoint(UnknownSnapshot.UnknownDataPointSnapshot dataPoint, long currentTimeMillis) { - return new DoublePointDataImpl( - dataPoint.getValue(), - getStartEpochNanos(dataPoint), - getEpochNanos(dataPoint, currentTimeMillis), - labelsToAttributes(dataPoint.getLabels()), - convertExemplar(dataPoint.getExemplar()) - ); - } + private DoublePointData toOtelDataPoint( + UnknownSnapshot.UnknownDataPointSnapshot dataPoint, long currentTimeMillis) { + return new DoublePointDataImpl( + dataPoint.getValue(), + getStartEpochNanos(dataPoint), + getEpochNanos(dataPoint, currentTimeMillis), + labelsToAttributes(dataPoint.getLabels()), + convertExemplar(dataPoint.getExemplar())); + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java index 83155f05a..eab7da588 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java @@ -4,38 +4,43 @@ import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ValueAtQuantile; - import java.util.ArrayList; import java.util.List; public class SummaryPointDataImpl extends PointDataImpl implements SummaryPointData { - private final double sum; - private final long count; - private final List values; - - public SummaryPointDataImpl(double sum, long count, long startEpochNanos, long epochNanos, Attributes attributes, List exemplars) { - super(startEpochNanos, epochNanos, attributes, exemplars); - this.sum = sum; - this.count = count; - this.values = new ArrayList<>(); - } - - void addValue(double quantile, double value) { - values.add(new ValueAtQuantileImpl(quantile, value)); - } - - @Override - public long getCount() { - return count; - } - - @Override - public double getSum() { - return sum; - } - - @Override - public List getValues() { - return values; - } + private final double sum; + private final long count; + private final List values; + + public SummaryPointDataImpl( + double sum, + long count, + long startEpochNanos, + long epochNanos, + Attributes attributes, + List exemplars) { + super(startEpochNanos, epochNanos, attributes, exemplars); + this.sum = sum; + this.count = count; + this.values = new ArrayList<>(); + } + + void addValue(double quantile, double value) { + values.add(new ValueAtQuantileImpl(quantile, value)); + } + + @Override + public long getCount() { + return count; + } + + @Override + public double getSum() { + return sum; + } + + @Override + public List getValues() { + return values; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java index 8117c5a8c..13b39d3aa 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java @@ -4,21 +4,21 @@ public class ValueAtQuantileImpl implements ValueAtQuantile { - private final double quantile; - private final double value; + private final double quantile; + private final double value; - public ValueAtQuantileImpl(double quantile, double value) { - this.quantile = quantile; - this.value = value; - } + public ValueAtQuantileImpl(double quantile, double value) { + this.quantile = quantile; + this.value = value; + } - @Override - public double getQuantile() { - return quantile; - } + @Override + public double getQuantile() { + return quantile; + } - @Override - public double getValue() { - return value; - } + @Override + public double getValue() { + return value; + } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java index 2482d6857..5af5193f6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java @@ -1,5 +1,15 @@ package io.prometheus.metrics.exporter.opentelemetry; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.awaitility.Awaitility.await; + import com.github.tomakehurst.wiremock.http.Request; import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.github.tomakehurst.wiremock.matching.MatchResult; @@ -23,123 +33,113 @@ import org.junit.Rule; import org.junit.Test; -import static com.github.tomakehurst.wiremock.client.WireMock.containing; -import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; -import static com.github.tomakehurst.wiremock.client.WireMock.ok; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.verify; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.awaitility.Awaitility.await; - public class ExemplarTest { - private static final String ENDPOINT_PATH = "/v1/metrics"; - private static final int TIMEOUT = 3; - private static final String INSTRUMENTATION_SCOPE_NAME = "testInstrumentationScope"; - private static final String SPAN_NAME = "test-span"; - public static final String TEST_COUNTER_NAME = "test_counter"; - private Counter testCounter; - private OpenTelemetryExporter openTelemetryExporter; - @Rule - public WireMockRule wireMockRule = new WireMockRule(4317); - - @Before - public void setUp() { - openTelemetryExporter = OpenTelemetryExporter.builder() - .endpoint("http://localhost:4317") - .protocol("http/protobuf") - .intervalSeconds(1) - .buildAndStart(); - - testCounter = Counter.builder() - .name(TEST_COUNTER_NAME) - .withExemplars() - .register(); - - wireMockRule.stubFor(post(ENDPOINT_PATH) - .withHeader("Content-Type", containing("application/x-protobuf")) - .willReturn(ok() - .withHeader("Content-Type", "application/json") - .withBody("{\"partialSuccess\":{}}"))); + private static final String ENDPOINT_PATH = "/v1/metrics"; + private static final int TIMEOUT = 3; + private static final String INSTRUMENTATION_SCOPE_NAME = "testInstrumentationScope"; + private static final String SPAN_NAME = "test-span"; + public static final String TEST_COUNTER_NAME = "test_counter"; + private Counter testCounter; + private OpenTelemetryExporter openTelemetryExporter; + @Rule public WireMockRule wireMockRule = new WireMockRule(4317); + + @Before + public void setUp() { + openTelemetryExporter = + OpenTelemetryExporter.builder() + .endpoint("http://localhost:4317") + .protocol("http/protobuf") + .intervalSeconds(1) + .buildAndStart(); + + testCounter = Counter.builder().name(TEST_COUNTER_NAME).withExemplars().register(); + + wireMockRule.stubFor( + post(ENDPOINT_PATH) + .withHeader("Content-Type", containing("application/x-protobuf")) + .willReturn( + ok().withHeader("Content-Type", "application/json") + .withBody("{\"partialSuccess\":{}}"))); + } + + @After + public void tearDown() { + PrometheusRegistry.defaultRegistry.unregister(testCounter); + openTelemetryExporter.close(); + } + + @Test + public void sampledExemplarIsForwarded() { + try (SdkTracerProvider sdkTracerProvider = + SdkTracerProvider.builder().setSampler(Sampler.alwaysOn()).build()) { + + Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); + Span span = test.spanBuilder(SPAN_NAME).startSpan(); + try (Scope scope = span.makeCurrent()) { + testCounter.inc(2); + } } - @After - public void tearDown() { - PrometheusRegistry.defaultRegistry.unregister(testCounter); - openTelemetryExporter.close(); + await() + .atMost(TIMEOUT, SECONDS) + .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) + .until( + () -> { + verify( + postRequestedFor(urlEqualTo(ENDPOINT_PATH)) + .withHeader("Content-Type", equalTo("application/x-protobuf")) + .andMatching(getExemplarCountMatcher(1))); + return true; + }); + } + + @Test(expected = ConditionTimeoutException.class) + public void notSampledExemplarIsNotForwarded() { + try (SdkTracerProvider sdkTracerProvider = + SdkTracerProvider.builder().setSampler(Sampler.alwaysOff()).build()) { + + Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); + Span span = test.spanBuilder(SPAN_NAME).startSpan(); + try (Scope scope = span.makeCurrent()) { + testCounter.inc(2); + } } - @Test - public void sampledExemplarIsForwarded() { - try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() - .setSampler(Sampler.alwaysOn()) - .build()) { - - Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); - Span span = test.spanBuilder(SPAN_NAME) - .startSpan(); - try (Scope scope = span.makeCurrent()) { - testCounter.inc(2); + await() + .atMost(TIMEOUT, SECONDS) + .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) + .until( + () -> { + verify( + postRequestedFor(urlEqualTo(ENDPOINT_PATH)) + .withHeader("Content-Type", equalTo("application/x-protobuf")) + .andMatching(getExemplarCountMatcher(1))); + return true; + }); + } + + private static ValueMatcher getExemplarCountMatcher(int expectedCount) { + return request -> { + try { + ExportMetricsServiceRequest exportMetricsServiceRequest = + ExportMetricsServiceRequest.parseFrom(request.getBody()); + for (ResourceMetrics resourceMetrics : + exportMetricsServiceRequest.getResourceMetricsList()) { + for (InstrumentationLibraryMetrics instrumentationLibraryMetrics : + resourceMetrics.getInstrumentationLibraryMetricsList()) { + for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) { + for (NumberDataPoint numberDataPoint : metric.getSum().getDataPointsList()) { + if (numberDataPoint.getExemplarsCount() == expectedCount) { + return MatchResult.exactMatch(); } + } } - - - await().atMost(TIMEOUT, SECONDS) - .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) - .until(() -> { - verify(postRequestedFor(urlEqualTo(ENDPOINT_PATH)) - .withHeader("Content-Type", equalTo("application/x-protobuf")) - .andMatching(getExemplarCountMatcher(1))); - return true; - }); - - } - - @Test(expected = ConditionTimeoutException.class) - public void notSampledExemplarIsNotForwarded() { - try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() - .setSampler(Sampler.alwaysOff()) - .build()) { - - Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); - Span span = test.spanBuilder(SPAN_NAME) - .startSpan(); - try (Scope scope = span.makeCurrent()) { - testCounter.inc(2); - } + } } - - await().atMost(TIMEOUT, SECONDS) - .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) - .until(() -> { - verify(postRequestedFor(urlEqualTo(ENDPOINT_PATH)) - .withHeader("Content-Type", equalTo("application/x-protobuf")) - .andMatching(getExemplarCountMatcher(1))); - return true; - }); - - } - - private static ValueMatcher getExemplarCountMatcher(int expectedCount) { - return request -> { - try { - ExportMetricsServiceRequest exportMetricsServiceRequest = ExportMetricsServiceRequest.parseFrom(request.getBody()); - for (ResourceMetrics resourceMetrics : exportMetricsServiceRequest.getResourceMetricsList()) { - for (InstrumentationLibraryMetrics instrumentationLibraryMetrics : resourceMetrics.getInstrumentationLibraryMetricsList()) { - for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) { - for (NumberDataPoint numberDataPoint : metric.getSum().getDataPointsList()) { - if (numberDataPoint.getExemplarsCount() == expectedCount) { - return MatchResult.exactMatch(); - } - } - } - } - } - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(e); - } - return MatchResult.noMatch(); - }; - } + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(e); + } + return MatchResult.noMatch(); + }; + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java index f3223cb53..60c110149 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultHttpConnectionFactory.java @@ -6,13 +6,15 @@ /** * This can be used for creating {@link Scheme#HTTP} and {@link Scheme#HTTPS} connections. - *

      - * However, if you want to use it with {@link Scheme#HTTPS} you must make sure that the keychain for verifying the server certificate is set up correctly. - * For an example of how to skip certificate verification see {@code PushGatewayTestApp} in {@code integration-tests/it-pushgateway/}. + * + *

      However, if you want to use it with {@link Scheme#HTTPS} you must make sure that the keychain + * for verifying the server certificate is set up correctly. For an example of how to skip + * certificate verification see {@code PushGatewayTestApp} in {@code + * integration-tests/it-pushgateway/}. */ public class DefaultHttpConnectionFactory implements HttpConnectionFactory { - @Override - public HttpURLConnection create(URL url) throws IOException { - return (HttpURLConnection) url.openConnection(); - } + @Override + public HttpURLConnection create(URL url) throws IOException { + return (HttpURLConnection) url.openConnection(); + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java index 8d9afb71e..59a11a473 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/DefaultJobLabelDetector.java @@ -7,54 +7,54 @@ /** * The default {@code job} label is the name of the JAR file being executed. - *

      - * This is copy-and-paste from {@code ResourceAttributesFromJarFileName} - * in the {@code prometheus-metrics-exporter-opentelemetry} module. + * + *

      This is copy-and-paste from {@code ResourceAttributesFromJarFileName} in the {@code + * prometheus-metrics-exporter-opentelemetry} module. */ class DefaultJobLabelDetector { - static String getDefaultJobLabel() { - Path jarPath = getJarPathFromSunCommandLine(); - if (jarPath == null) { - return "unknown_job"; - } - return getServiceName(jarPath); + static String getDefaultJobLabel() { + Path jarPath = getJarPathFromSunCommandLine(); + if (jarPath == null) { + return "unknown_job"; } + return getServiceName(jarPath); + } - private static String getServiceName(Path jarPath) { - String jarName = jarPath.getFileName().toString(); - int dotIndex = jarName.lastIndexOf("."); - return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); - } + private static String getServiceName(Path jarPath) { + String jarName = jarPath.getFileName().toString(); + int dotIndex = jarName.lastIndexOf("."); + return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); + } - private static Path getJarPathFromSunCommandLine() { - String programArguments = System.getProperty("sun.java.command"); - if (programArguments == null) { - return null; - } - // Take the path until the first space. If the path doesn't exist extend it up to the next - // space. Repeat until a path that exists is found or input runs out. - int next = 0; - while (true) { - int nextSpace = programArguments.indexOf(' ', next); - if (nextSpace == -1) { - return pathIfExists(programArguments); - } - Path path = pathIfExists(programArguments.substring(0, nextSpace)); - next = nextSpace + 1; - if (path != null) { - return path; - } - } + private static Path getJarPathFromSunCommandLine() { + String programArguments = System.getProperty("sun.java.command"); + if (programArguments == null) { + return null; + } + // Take the path until the first space. If the path doesn't exist extend it up to the next + // space. Repeat until a path that exists is found or input runs out. + int next = 0; + while (true) { + int nextSpace = programArguments.indexOf(' ', next); + if (nextSpace == -1) { + return pathIfExists(programArguments); + } + Path path = pathIfExists(programArguments.substring(0, nextSpace)); + next = nextSpace + 1; + if (path != null) { + return path; + } } + } - private static Path pathIfExists(String programArguments) { - Path candidate; - try { - candidate = Paths.get(programArguments); - } catch (InvalidPathException e) { - return null; - } - return Files.isRegularFile(candidate) ? candidate : null; + private static Path pathIfExists(String programArguments) { + Path candidate; + try { + candidate = Paths.get(programArguments); + } catch (InvalidPathException e) { + return null; } + return Files.isRegularFile(candidate) ? candidate : null; + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java index 90204cff9..3d1b9d2e6 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Format.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.pushgateway; public enum Format { - PROMETHEUS_PROTOBUF, - PROMETHEUS_TEXT + PROMETHEUS_PROTOBUF, + PROMETHEUS_TEXT } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java index c583b144e..f7a039af7 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.java @@ -4,10 +4,8 @@ import java.net.HttpURLConnection; import java.net.URL; -/** - * See {@link DefaultHttpConnectionFactory}. - */ +/** See {@link DefaultHttpConnectionFactory}. */ @FunctionalInterface public interface HttpConnectionFactory { - HttpURLConnection create(URL url) throws IOException; + HttpURLConnection create(URL url) throws IOException; } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index 0e6ab8d54..d879c3105 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.exporter.pushgateway; +import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTP; + import io.prometheus.metrics.config.ExporterPushgatewayProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.config.PrometheusPropertiesException; @@ -8,24 +10,23 @@ import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusRegistry; - import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.util.*; -import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTP; - /** - * Export metrics via the Prometheus Pushgateway - *

      - * The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. - * Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics - * to a Pushgateway. This Java class allows pushing the contents of a {@link PrometheusRegistry} to a Pushgateway. - *

      - * Example usage: - *

      - * {@code
      + * Export metrics via the Prometheus
      + * Pushgateway
      + *
      + * 

      The Prometheus Pushgateway exists to allow ephemeral and batch jobs to expose their metrics to + * Prometheus. Since these kinds of jobs may not exist long enough to be scraped, they can instead + * push their metrics to a Pushgateway. This Java class allows pushing the contents of a {@link + * PrometheusRegistry} to a Pushgateway. + * + *

      Example usage: + * + *

      {@code
        * void executeBatchJob() throws Exception {
        *     PrometheusRegistry registry = new PrometheusRegistry();
        *     Gauge duration = Gauge.builder()
      @@ -53,384 +54,397 @@
        *         pg.pushAdd();
        *     }
        * }
      - * }
      - * 
      - *

      - * See https://github.com/prometheus/pushgateway. + * }

      + * + *

      See https://github.com/prometheus/pushgateway. */ public class PushGateway { - private static final int MILLISECONDS_PER_SECOND = 1000; + private static final int MILLISECONDS_PER_SECOND = 1000; + + private final URL url; + private final Format format; + private final Map requestHeaders; + private final PrometheusRegistry registry; + private final HttpConnectionFactory connectionFactory; + + private PushGateway( + PrometheusRegistry registry, + Format format, + URL url, + HttpConnectionFactory connectionFactory, + Map requestHeaders) { + this.registry = registry; + this.format = format; + this.url = url; + this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders)); + this.connectionFactory = connectionFactory; + } + + /** + * Push all metrics. All metrics with the same job and grouping key are replaced. + * + *

      This uses the PUT HTTP method. + */ + public void push() throws IOException { + doRequest(registry, "PUT"); + } + + /** + * Push a single metric. All metrics with the same job and grouping key are replaced. + * + *

      This is useful for pushing a single Gauge. + * + *

      This uses the PUT HTTP method. + */ + public void push(Collector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "PUT"); + } + + /** + * Push a single collector. All metrics with the same job and grouping key are replaced. + * + *

      This uses the PUT HTTP method. + */ + public void push(MultiCollector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "PUT"); + } + + /** + * Like {@link #push()}, but only metrics with the same name as the newly pushed metrics are + * replaced. + * + *

      This uses the POST HTTP method. + */ + public void pushAdd() throws IOException { + doRequest(registry, "POST"); + } + + /** + * Like {@link #push(Collector)}, but only the specified metric will be replaced. + * + *

      This uses the POST HTTP method. + */ + public void pushAdd(Collector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "POST"); + } + + /** + * Like {@link #push(MultiCollector)}, but only the metrics from the collector will be replaced. + * + *

      This uses the POST HTTP method. + */ + public void pushAdd(MultiCollector collector) throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + doRequest(registry, "POST"); + } + + /** + * Deletes metrics from the Pushgateway. + * + *

      This uses the DELETE HTTP method. + */ + public void delete() throws IOException { + doRequest(null, "DELETE"); + } + + private void doRequest(PrometheusRegistry registry, String method) throws IOException { + try { + HttpURLConnection connection = connectionFactory.create(url); + requestHeaders.forEach(connection::setRequestProperty); + if (format == Format.PROMETHEUS_TEXT) { + connection.setRequestProperty("Content-Type", PrometheusTextFormatWriter.CONTENT_TYPE); + } else { + connection.setRequestProperty("Content-Type", PrometheusProtobufWriter.CONTENT_TYPE); + } + if (!method.equals("DELETE")) { + connection.setDoOutput(true); + } + connection.setRequestMethod(method); + + connection.setConnectTimeout(10 * MILLISECONDS_PER_SECOND); + connection.setReadTimeout(10 * MILLISECONDS_PER_SECOND); + connection.connect(); + + try { + if (!method.equals("DELETE")) { + OutputStream outputStream = connection.getOutputStream(); + if (format == Format.PROMETHEUS_TEXT) { + new PrometheusTextFormatWriter(false).write(outputStream, registry.scrape()); + } else { + new PrometheusProtobufWriter().write(outputStream, registry.scrape()); + } + outputStream.flush(); + outputStream.close(); + } - private final URL url; - private final Format format; - private final Map requestHeaders; - private final PrometheusRegistry registry; - private final HttpConnectionFactory connectionFactory; + int response = connection.getResponseCode(); + if (response / 100 != 2) { + String errorMessage; + InputStream errorStream = connection.getErrorStream(); + if (errorStream != null) { + String errBody = readFromStream(errorStream); + errorMessage = + "Response code from " + url + " was " + response + ", response body: " + errBody; + } else { + errorMessage = "Response code from " + url + " was " + response; + } + throw new IOException(errorMessage); + } - private PushGateway(PrometheusRegistry registry, Format format, URL url, HttpConnectionFactory connectionFactory, Map requestHeaders) { - this.registry = registry; - this.format = format; - this.url = url; - this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders)); - this.connectionFactory = connectionFactory; + } finally { + connection.disconnect(); + } + } catch (IOException e) { + String baseUrl = url.getProtocol() + "://" + url.getHost(); + if (url.getPort() != -1) { + baseUrl += ":" + url.getPort(); + } + throw new IOException( + "Failed to push metrics to the Prometheus Pushgateway on " + + baseUrl + + ": " + + e.getMessage(), + e); + } + } + + private static String readFromStream(InputStream is) throws IOException { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + return result.toString("UTF-8"); + } + + public static Builder builder() { + return builder(PrometheusProperties.get()); + } + + /** + * The {@link PrometheusProperties} will be used to override what is set in the {@link Builder}. + */ + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } + + public static class Builder { + + private final PrometheusProperties config; + private Format format; + private String address; + private Scheme scheme; + private String job; + private final Map requestHeaders = new HashMap<>(); + private PrometheusRegistry registry = PrometheusRegistry.defaultRegistry; + private HttpConnectionFactory connectionFactory = new DefaultHttpConnectionFactory(); + private Map groupingKey = new TreeMap<>(); + + private Builder(PrometheusProperties config) { + this.config = config; } - /** - * Push all metrics. All metrics with the same job and grouping key are replaced. - *

      - * This uses the PUT HTTP method. - */ - public void push() throws IOException { - doRequest(registry, "PUT"); + /** Default is {@link Format#PROMETHEUS_PROTOBUF}. */ + public Builder format(Format format) { + if (format == null) { + throw new NullPointerException(); + } + this.format = format; + return this; } /** - * Push a single metric. All metrics with the same job and grouping key are replaced. - *

      - * This is useful for pushing a single Gauge. - *

      - * This uses the PUT HTTP method. + * Address of the Pushgateway in format {@code host:port}. Default is {@code localhost:9091}. + * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.address} + * property. */ - public void push(Collector collector) throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - doRequest(registry, "PUT"); + public Builder address(String address) { + if (address == null) { + throw new NullPointerException(); + } + this.address = address; + return this; } - /** - * Push a single collector. All metrics with the same job and grouping key are replaced. - *

      - * This uses the PUT HTTP method. - */ - public void push(MultiCollector collector) throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - doRequest(registry, "PUT"); + /** Username and password for HTTP basic auth when pushing to the Pushgateway. */ + public Builder basicAuth(String user, String password) { + if (user == null || password == null) { + throw new NullPointerException(); + } + byte[] credentialsBytes = (user + ":" + password).getBytes(StandardCharsets.UTF_8); + String encoded = Base64.getEncoder().encodeToString(credentialsBytes); + requestHeaders.put("Authorization", String.format("Basic %s", encoded)); + return this; + } + + /** Bearer token authorization when pushing to the Pushgateway. */ + public Builder bearerToken(String token) { + if (token == null) { + throw new NullPointerException(); + } + requestHeaders.put("Authorization", String.format("Bearer %s", token)); + return this; } /** - * Like {@link #push()}, but only metrics with the same name as the newly pushed metrics are replaced. - *

      - * This uses the POST HTTP method. + * Specify if metrics should be pushed using HTTP or HTTPS. Default is HTTP. Can be overwritten + * at runtime with the {@code io.prometheus.exporter.pushgateway.scheme} property. */ - public void pushAdd() throws IOException { - doRequest(registry, "POST"); + public Builder scheme(Scheme scheme) { + if (scheme == null) { + throw new NullPointerException(); + } + this.scheme = scheme; + return this; } /** - * Like {@link #push(Collector)}, but only the specified metric will be replaced. - *

      - * This uses the POST HTTP method. + * Custom connection factory. Default is {@link DefaultHttpConnectionFactory}. + * + *

      The {@code PushGatewayTestApp} in {@code integration-tests/it-pushgateway/} has an example + * of a custom connection factory that skips SSL certificate validation for HTTPS connections. */ - public void pushAdd(Collector collector) throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - doRequest(registry, "POST"); + public Builder connectionFactory(HttpConnectionFactory connectionFactory) { + if (connectionFactory == null) { + throw new NullPointerException(); + } + this.connectionFactory = connectionFactory; + return this; } /** - * Like {@link #push(MultiCollector)}, but only the metrics from the collector will be replaced. - *

      - * This uses the POST HTTP method. + * The {@code job} label to be used when pushing metrics. If not provided, the name of the JAR + * file will be used by default. Can be overwritten at runtime with the {@code + * io.prometheus.exporter.pushgateway.job} property. */ - public void pushAdd(MultiCollector collector) throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - doRequest(registry, "POST"); + public Builder job(String job) { + if (job == null) { + throw new NullPointerException(); + } + this.job = job; + return this; } /** - * Deletes metrics from the Pushgateway. - *

      - * This uses the DELETE HTTP method. + * Grouping keys to be used when pushing/deleting metrics. Call this method multiple times for + * adding multiple grouping keys. */ - public void delete() throws IOException { - doRequest(null, "DELETE"); + public Builder groupingKey(String name, String value) { + if (name == null || value == null) { + throw new NullPointerException(); + } + groupingKey.put(name, value); + return this; } - private void doRequest(PrometheusRegistry registry, String method) throws IOException { - try { - HttpURLConnection connection = connectionFactory.create(url); - requestHeaders.forEach(connection::setRequestProperty); - if (format == Format.PROMETHEUS_TEXT) { - connection.setRequestProperty("Content-Type", PrometheusTextFormatWriter.CONTENT_TYPE); - } else { - connection.setRequestProperty("Content-Type", PrometheusProtobufWriter.CONTENT_TYPE); - } - if (!method.equals("DELETE")) { - connection.setDoOutput(true); - } - connection.setRequestMethod(method); - - connection.setConnectTimeout(10 * MILLISECONDS_PER_SECOND); - connection.setReadTimeout(10 * MILLISECONDS_PER_SECOND); - connection.connect(); - - try { - if (!method.equals("DELETE")) { - OutputStream outputStream = connection.getOutputStream(); - if (format == Format.PROMETHEUS_TEXT) { - new PrometheusTextFormatWriter(false).write(outputStream, registry.scrape()); - } else { - new PrometheusProtobufWriter().write(outputStream, registry.scrape()); - } - outputStream.flush(); - outputStream.close(); - } - - int response = connection.getResponseCode(); - if (response / 100 != 2) { - String errorMessage; - InputStream errorStream = connection.getErrorStream(); - if (errorStream != null) { - String errBody = readFromStream(errorStream); - errorMessage = "Response code from " + url + " was " + response + ", response body: " + errBody; - } else { - errorMessage = "Response code from " + url + " was " + response; - } - throw new IOException(errorMessage); - } - - } finally { - connection.disconnect(); - } - } catch (IOException e) { - String baseUrl = url.getProtocol() + "://" + url.getHost(); - if (url.getPort() != -1) { - baseUrl += ":" + url.getPort(); - } - throw new IOException("Failed to push metrics to the Prometheus Pushgateway on " + baseUrl + ": " + e.getMessage(), e); - } + /** Convenience method for adding the current IP address as an "instance" label. */ + public Builder instanceIpGroupingKey() throws UnknownHostException { + return groupingKey("instance", InetAddress.getLocalHost().getHostAddress()); } - private static String readFromStream(InputStream is) throws IOException { - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = is.read(buffer)) != -1) { - result.write(buffer, 0, length); - } - return result.toString("UTF-8"); + /** Push metrics from this registry instead of {@link PrometheusRegistry#defaultRegistry}. */ + public Builder registry(PrometheusRegistry registry) { + if (registry == null) { + throw new NullPointerException(); + } + this.registry = registry; + return this; } - public static Builder builder() { - return builder(PrometheusProperties.get()); + private Scheme getScheme(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getScheme() != null) { + return Scheme.valueOf(properties.getScheme()); + } else if (this.scheme != null) { + return this.scheme; + } else { + return HTTP; + } } - /** - * The {@link PrometheusProperties} will be used to override what is set in the {@link Builder}. - */ - public static Builder builder(PrometheusProperties config) { - return new Builder(config); + private String getAddress(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getAddress() != null) { + return properties.getAddress(); + } else if (this.address != null) { + return this.address; + } else { + return "localhost:9091"; + } } - public static class Builder { - - private final PrometheusProperties config; - private Format format; - private String address; - private Scheme scheme; - private String job; - private final Map requestHeaders = new HashMap<>(); - private PrometheusRegistry registry = PrometheusRegistry.defaultRegistry; - private HttpConnectionFactory connectionFactory = new DefaultHttpConnectionFactory(); - private Map groupingKey = new TreeMap<>(); - - private Builder(PrometheusProperties config) { - this.config = config; - } - - /** - * Default is {@link Format#PROMETHEUS_PROTOBUF}. - */ - public Builder format(Format format) { - if (format == null) { - throw new NullPointerException(); - } - this.format = format; - return this; - } - - /** - * Address of the Pushgateway in format {@code host:port}. - * Default is {@code localhost:9091}. - * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.address} property. - */ - public Builder address(String address) { - if (address == null) { - throw new NullPointerException(); - } - this.address = address; - return this; - } - - /** - * Username and password for HTTP basic auth when pushing to the Pushgateway. - */ - public Builder basicAuth(String user, String password) { - if (user == null || password == null) { - throw new NullPointerException(); - } - byte[] credentialsBytes = (user + ":" + password).getBytes(StandardCharsets.UTF_8); - String encoded = Base64.getEncoder().encodeToString(credentialsBytes); - requestHeaders.put("Authorization", String.format("Basic %s", encoded)); - return this; - } - - /** - * Bearer token authorization when pushing to the Pushgateway. - */ - public Builder bearerToken(String token) { - if (token == null) { - throw new NullPointerException(); - } - requestHeaders.put("Authorization", String.format("Bearer %s", token)); - return this; - } - - /** - * Specify if metrics should be pushed using HTTP or HTTPS. Default is HTTP. - * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.scheme} property. - */ - public Builder scheme(Scheme scheme) { - if (scheme == null) { - throw new NullPointerException(); - } - this.scheme = scheme; - return this; - } - - /** - * Custom connection factory. Default is {@link DefaultHttpConnectionFactory}. - *

      - * The {@code PushGatewayTestApp} in {@code integration-tests/it-pushgateway/} has an example of a custom - * connection factory that skips SSL certificate validation for HTTPS connections. - */ - public Builder connectionFactory(HttpConnectionFactory connectionFactory) { - if (connectionFactory == null) { - throw new NullPointerException(); - } - this.connectionFactory = connectionFactory; - return this; - } - - /** - * The {@code job} label to be used when pushing metrics. - * If not provided, the name of the JAR file will be used by default. - * Can be overwritten at runtime with the {@code io.prometheus.exporter.pushgateway.job} property. - */ - public Builder job(String job) { - if (job == null) { - throw new NullPointerException(); - } - this.job = job; - return this; - } - - /** - * Grouping keys to be used when pushing/deleting metrics. - * Call this method multiple times for adding multiple grouping keys. - */ - public Builder groupingKey(String name, String value) { - if (name == null || value == null) { - throw new NullPointerException(); - } - groupingKey.put(name, value); - return this; - } - - /** - * Convenience method for adding the current IP address as an "instance" label. - */ - public Builder instanceIpGroupingKey() throws UnknownHostException { - return groupingKey("instance", InetAddress.getLocalHost().getHostAddress()); - } - - /** - * Push metrics from this registry instead of {@link PrometheusRegistry#defaultRegistry}. - */ - public Builder registry(PrometheusRegistry registry) { - if (registry == null) { - throw new NullPointerException(); - } - this.registry = registry; - return this; - } - - private Scheme getScheme(ExporterPushgatewayProperties properties) { - if (properties != null && properties.getScheme() != null) { - return Scheme.valueOf(properties.getScheme()); - } else if (this.scheme != null) { - return this.scheme; - } else { - return HTTP; - } - } - - private String getAddress(ExporterPushgatewayProperties properties) { - if (properties != null && properties.getAddress() != null) { - return properties.getAddress(); - } else if (this.address != null) { - return this.address; - } else { - return "localhost:9091"; - } - } - - private String getJob(ExporterPushgatewayProperties properties) { - if (properties != null && properties.getJob() != null) { - return properties.getJob(); - } else if (this.job != null) { - return this.job; - } else { - return DefaultJobLabelDetector.getDefaultJobLabel(); - } - } + private String getJob(ExporterPushgatewayProperties properties) { + if (properties != null && properties.getJob() != null) { + return properties.getJob(); + } else if (this.job != null) { + return this.job; + } else { + return DefaultJobLabelDetector.getDefaultJobLabel(); + } + } - private Format getFormat(ExporterPushgatewayProperties properties) { - // currently not configurable via properties - if (this.format != null) { - return this.format; - } - return Format.PROMETHEUS_PROTOBUF; - } + private Format getFormat(ExporterPushgatewayProperties properties) { + // currently not configurable via properties + if (this.format != null) { + return this.format; + } + return Format.PROMETHEUS_PROTOBUF; + } - private URL makeUrl(ExporterPushgatewayProperties properties) throws UnsupportedEncodingException, MalformedURLException { - String url = getScheme(properties) + "://" + getAddress(properties) + "/metrics/"; - String job = getJob(properties); - if (job.contains("/")) { - url += "job@base64/" + base64url(job); - } else { - url += "job/" + URLEncoder.encode(job, "UTF-8"); - } - if (groupingKey != null) { - for (Map.Entry entry : groupingKey.entrySet()) { - if (entry.getValue().isEmpty()) { - url += "/" + entry.getKey() + "@base64/="; - } else if (entry.getValue().contains("/")) { - url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue()); - } else { - url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8"); - } - } - } - return URI.create(url).normalize().toURL(); + private URL makeUrl(ExporterPushgatewayProperties properties) + throws UnsupportedEncodingException, MalformedURLException { + String url = getScheme(properties) + "://" + getAddress(properties) + "/metrics/"; + String job = getJob(properties); + if (job.contains("/")) { + url += "job@base64/" + base64url(job); + } else { + url += "job/" + URLEncoder.encode(job, "UTF-8"); + } + if (groupingKey != null) { + for (Map.Entry entry : groupingKey.entrySet()) { + if (entry.getValue().isEmpty()) { + url += "/" + entry.getKey() + "@base64/="; + } else if (entry.getValue().contains("/")) { + url += "/" + entry.getKey() + "@base64/" + base64url(entry.getValue()); + } else { + url += "/" + entry.getKey() + "/" + URLEncoder.encode(entry.getValue(), "UTF-8"); + } } + } + return URI.create(url).normalize().toURL(); + } - private String base64url(String v) { - return Base64.getEncoder().encodeToString(v.getBytes(StandardCharsets.UTF_8)).replace("+", "-").replace("/", "_"); - } + private String base64url(String v) { + return Base64.getEncoder() + .encodeToString(v.getBytes(StandardCharsets.UTF_8)) + .replace("+", "-") + .replace("/", "_"); + } - public PushGateway build() { - ExporterPushgatewayProperties properties = config == null ? null : config.getExporterPushgatewayProperties(); - try { - return new PushGateway(registry, getFormat(properties), makeUrl(properties), connectionFactory, requestHeaders); - } catch (MalformedURLException e) { - throw new PrometheusPropertiesException(address + ": Invalid address. Expecting :"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); // cannot happen, UTF-8 is always supported - } - } + public PushGateway build() { + ExporterPushgatewayProperties properties = + config == null ? null : config.getExporterPushgatewayProperties(); + try { + return new PushGateway( + registry, + getFormat(properties), + makeUrl(properties), + connectionFactory, + requestHeaders); + } catch (MalformedURLException e) { + throw new PrometheusPropertiesException( + address + ": Invalid address. Expecting :"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // cannot happen, UTF-8 is always supported + } } + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java index adb7ebf07..51a2e32dd 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/Scheme.java @@ -1,29 +1,29 @@ package io.prometheus.metrics.exporter.pushgateway; public enum Scheme { + HTTP("http"), + HTTPS("https"); - HTTP("http"), - HTTPS("https"); + private final String name; - private final String name; + Scheme(String name) { + this.name = name; + } - Scheme(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } + @Override + public String toString() { + return name; + } - public static Scheme fromString(String name) { - switch (name) { - case "http": - return HTTP; - case "https": - return HTTPS; - default: - throw new IllegalArgumentException(name + ": Unsupported scheme. Expecting 'http' or 'https'."); - } + public static Scheme fromString(String name) { + switch (name) { + case "http": + return HTTP; + case "https": + return HTTPS; + default: + throw new IllegalArgumentException( + name + ": Unsupported scheme. Expecting 'http' or 'https'."); } + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java index 78706ee49..7fbb32b10 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java @@ -1,48 +1,48 @@ package io.prometheus.metrics.exporter.pushgateway; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import java.io.IOException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockserver.client.MockServerClient; import org.mockserver.junit.MockServerRule; -import java.io.IOException; - -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - public class BasicAuthPushGatewayTest { - @Rule - public MockServerRule mockServerRule = new MockServerRule(this); - private MockServerClient mockServerClient; - - PrometheusRegistry registry; - Gauge gauge; - PushGateway pushGateway; - - @Before - public void setUp() { - registry = new PrometheusRegistry(); - gauge = Gauge.builder().name("g").help("help").build(); - pushGateway = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .basicAuth("testUser", "testPwd") - .registry(registry) - .job("j") - .build(); - } - - @Test - public void testAuthorizedPush() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withHeader("Authorization", "Basic dGVzdFVzZXI6dGVzdFB3ZA==") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pushGateway.push(); - } + @Rule public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; + + PrometheusRegistry registry; + Gauge gauge; + PushGateway pushGateway; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + pushGateway = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .basicAuth("testUser", "testPwd") + .registry(registry) + .job("j") + .build(); + } + + @Test + public void testAuthorizedPush() throws IOException { + mockServerClient + .when( + request() + .withMethod("PUT") + .withHeader("Authorization", "Basic dGVzdFVzZXI6dGVzdFB3ZA==") + .withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + pushGateway.push(); + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java index 8687b2d55..144a0f24f 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java @@ -1,48 +1,48 @@ package io.prometheus.metrics.exporter.pushgateway; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import java.io.IOException; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockserver.client.MockServerClient; import org.mockserver.junit.MockServerRule; -import java.io.IOException; - -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - public class BearerTokenPushGatewayTest { - @Rule - public MockServerRule mockServerRule = new MockServerRule(this); - private MockServerClient mockServerClient; - - PrometheusRegistry registry; - Gauge gauge; - PushGateway pushGateway; - - @Before - public void setUp() { - registry = new PrometheusRegistry(); - gauge = Gauge.builder().name("g").help("help").build(); - pushGateway = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .bearerToken("xxx") - .registry(registry) - .job("j") - .build(); - } - - @Test - public void testAuthorizedPush() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withHeader("Authorization", "Bearer xxx") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - pushGateway.push(); - } + @Rule public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; + + PrometheusRegistry registry; + Gauge gauge; + PushGateway pushGateway; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + pushGateway = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .bearerToken("xxx") + .registry(registry) + .job("j") + .build(); + } + + @Test + public void testAuthorizedPush() throws IOException { + mockServerClient + .when( + request() + .withMethod("PUT") + .withHeader("Authorization", "Bearer xxx") + .withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + pushGateway.push(); + } } diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java index 74ebae7ac..ce88300db 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java @@ -1,8 +1,15 @@ package io.prometheus.metrics.exporter.pushgateway; +import static org.junit.rules.ExpectedException.none; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.InetAddress; +import java.net.URL; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -11,309 +18,276 @@ import org.mockserver.client.MockServerClient; import org.mockserver.junit.MockServerRule; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.InetAddress; -import java.net.URL; - -import static org.junit.rules.ExpectedException.none; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - public class PushGatewayTest { - @Rule - public final ExpectedException thrown = none(); + @Rule public final ExpectedException thrown = none(); - @Rule - public MockServerRule mockServerRule = new MockServerRule(this); - private MockServerClient mockServerClient; + @Rule public MockServerRule mockServerRule = new MockServerRule(this); + private MockServerClient mockServerClient; - PrometheusRegistry registry; - Gauge gauge; + PrometheusRegistry registry; + Gauge gauge; - @Before - public void setUp() { - registry = new PrometheusRegistry(); - gauge = Gauge.builder().name("g").help("help").build(); - } + @Before + public void setUp() { + registry = new PrometheusRegistry(); + gauge = Gauge.builder().name("g").help("help").build(); + } - @Test(expected = RuntimeException.class) - public void testInvalidURLThrowsRuntimeException() { - PushGateway.builder().address("::").build(); // ":" is interpreted as port number, so parsing fails - } + @Test(expected = RuntimeException.class) + public void testInvalidURLThrowsRuntimeException() { + PushGateway.builder() + .address("::") + .build(); // ":" is interpreted as port number, so parsing fails + } - @Test - public void testMultipleSlashesAreStrippedFromURL() throws NoSuchFieldException, IllegalAccessException { - final PushGateway pushGateway = PushGateway.builder() - .address("example.com:1234/context///path//") - .job("test") - .build(); - Assert.assertEquals( - "http://example.com:1234/context/path/metrics/job/test", - getUrl(pushGateway).toString() - ); - } + @Test + public void testMultipleSlashesAreStrippedFromURL() + throws NoSuchFieldException, IllegalAccessException { + final PushGateway pushGateway = + PushGateway.builder().address("example.com:1234/context///path//").job("test").build(); + Assert.assertEquals( + "http://example.com:1234/context/path/metrics/job/test", getUrl(pushGateway).toString()); + } - private URL getUrl(PushGateway pushGateway) throws IllegalAccessException, NoSuchFieldException { - Field field = pushGateway.getClass().getDeclaredField("url"); - field.setAccessible(true); - return (URL) field.get(pushGateway); - } + private URL getUrl(PushGateway pushGateway) throws IllegalAccessException, NoSuchFieldException { + Field field = pushGateway.getClass().getDeclaredField("url"); + field.setAccessible(true); + return (URL) field.get(pushGateway); + } - @Test - public void testPush() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.push(); - } + @Test + public void testPush() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } - @Test - public void testPush200Response() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(200)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.push(); - } + @Test + public void testPush200Response() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j")) + .respond(response().withStatusCode(200)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } - @Test - public void testNon202ResponseThrows() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(500)); - thrown.expect(IOException.class); - thrown.expectMessage( - "Response code from http://localhost:" - + mockServerRule.getPort() - + "/metrics/job/j was 500"); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.push(); - } + @Test + public void testNon202ResponseThrows() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j")) + .respond(response().withStatusCode(500)); + thrown.expect(IOException.class); + thrown.expectMessage( + "Response code from http://localhost:" + + mockServerRule.getPort() + + "/metrics/job/j was 500"); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } - @Test - public void testPushCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.push(); - } + @Test + public void testPushCollector() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + } - @Test - public void testPushWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .groupingKey("l", "v") - .build(); - pg.push(); - } + @Test + public void testPushWithGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .build(); + pg.push(); + } - @Test - public void testPushWithMultiGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v/l2/v2") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .groupingKey("l", "v") - .groupingKey("l2", "v2") - .build(); - pg.push(); - } + @Test + public void testPushWithMultiGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j/l/v/l2/v2")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .groupingKey("l2", "v2") + .build(); + pg.push(); + } - @Test - public void testPushWithEmptyLabelGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v/l2@base64/=") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .groupingKey("l", "v") - .groupingKey("l2", "") - .build(); - pg.push(); - } + @Test + public void testPushWithEmptyLabelGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j/l/v/l2@base64/=")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .groupingKey("l2", "") + .build(); + pg.push(); + } - @Test - public void testPushWithGroupingKeyWithSlashes() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job@base64/YS9i/l/v/l2@base64/75-_Lw==") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("a/b") - .groupingKey("l", "v") - .groupingKey("l2", "\uF7FF/") - .build(); - pg.push(); - } + @Test + public void testPushWithGroupingKeyWithSlashes() throws IOException { + mockServerClient + .when( + request().withMethod("PUT").withPath("/metrics/job@base64/YS9i/l/v/l2@base64/75-_Lw==")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("a/b") + .groupingKey("l", "v") + .groupingKey("l2", "\uF7FF/") + .build(); + pg.push(); + } - @Test - public void testPushCollectorWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("PUT") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .groupingKey("l", "v") - .build(); - pg.push(gauge); - } + @Test + public void testPushCollectorWithGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("PUT").withPath("/metrics/job/j/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .groupingKey("l", "v") + .build(); + pg.push(gauge); + } - @Test - public void testPushAdd() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.pushAdd(); - } + @Test + public void testPushAdd() throws IOException { + mockServerClient + .when(request().withMethod("POST").withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .job("j") + .build(); + pg.pushAdd(); + } - @Test - public void testPushAddCollector() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .job("j") - .build(); - pg.pushAdd(gauge); - } + @Test + public void testPushAddCollector() throws IOException { + mockServerClient + .when(request().withMethod("POST").withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder().address("localhost:" + mockServerRule.getPort()).job("j").build(); + pg.pushAdd(gauge); + } - @Test - public void testPushAddWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .groupingKey("l", "v") - .job("j") - .build(); - pg.pushAdd(); - } + @Test + public void testPushAddWithGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("POST").withPath("/metrics/job/j/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .groupingKey("l", "v") + .job("j") + .build(); + pg.pushAdd(); + } - @Test - public void testPushAddCollectorWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("POST") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .groupingKey("l", "v") - .job("j") - .build(); - pg.pushAdd(gauge); - } + @Test + public void testPushAddCollectorWithGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("POST").withPath("/metrics/job/j/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .registry(registry) + .groupingKey("l", "v") + .job("j") + .build(); + pg.pushAdd(gauge); + } - @Test - public void testDelete() throws IOException { - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .job("j") - .build(); - pg.delete(); - } + @Test + public void testDelete() throws IOException { + mockServerClient + .when(request().withMethod("DELETE").withPath("/metrics/job/j")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder().address("localhost:" + mockServerRule.getPort()).job("j").build(); + pg.delete(); + } - @Test - public void testDeleteWithGroupingKey() throws IOException { - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .job("j") - .groupingKey("l", "v") - .build(); - pg.delete(); - } + @Test + public void testDeleteWithGroupingKey() throws IOException { + mockServerClient + .when(request().withMethod("DELETE").withPath("/metrics/job/j/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .groupingKey("l", "v") + .build(); + pg.delete(); + } - @Test - public void testInstanceIpGroupingKey() throws IOException { - String ip = InetAddress.getLocalHost().getHostAddress(); - Assert.assertFalse(ip.isEmpty()); - mockServerClient.when( - request() - .withMethod("DELETE") - .withPath("/metrics/job/j/instance/" + ip + "/l/v") - ).respond(response().withStatusCode(202)); - PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .job("j") - .groupingKey("l", "v") - .instanceIpGroupingKey() - .build(); - pg.delete(); - } + @Test + public void testInstanceIpGroupingKey() throws IOException { + String ip = InetAddress.getLocalHost().getHostAddress(); + Assert.assertFalse(ip.isEmpty()); + mockServerClient + .when(request().withMethod("DELETE").withPath("/metrics/job/j/instance/" + ip + "/l/v")) + .respond(response().withStatusCode(202)); + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerRule.getPort()) + .job("j") + .groupingKey("l", "v") + .instanceIpGroupingKey() + .build(); + pg.delete(); + } } diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java index afcfb6cbc..6953b1c6d 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/HttpExchangeAdapter.java @@ -5,109 +5,108 @@ import io.prometheus.metrics.exporter.common.PrometheusHttpResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.io.IOException; import java.io.OutputStream; -import java.net.URI; import java.util.Enumeration; public class HttpExchangeAdapter implements PrometheusHttpExchange { - private final Request request; - private final Response response; + private final Request request; + private final Response response; - public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { - this.request = new Request(request); - this.response = new Response(response); - } + public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { + this.request = new Request(request); + this.response = new Response(response); + } - @Override - public PrometheusHttpRequest getRequest() { - return request; - } + @Override + public PrometheusHttpRequest getRequest() { + return request; + } - @Override - public PrometheusHttpResponse getResponse() { - return response; + @Override + public PrometheusHttpResponse getResponse() { + return response; + } + + @Override + public void handleException(IOException e) throws IOException { + throw e; // leave exception handling to the servlet container + } + + @Override + public void handleException(RuntimeException e) { + throw e; // leave exception handling to the servlet container + } + + @Override + public void close() { + // nothing to do for Servlets. + } + + public static class Request implements PrometheusHttpRequest { + + private final HttpServletRequest request; + + public Request(HttpServletRequest request) { + this.request = request; } @Override - public void handleException(IOException e) throws IOException { - throw e; // leave exception handling to the servlet container + public String getQueryString() { + return request.getQueryString(); } @Override - public void handleException(RuntimeException e) { - throw e; // leave exception handling to the servlet container + public Enumeration getHeaders(String name) { + return request.getHeaders(name); } @Override - public void close() { - // nothing to do for Servlets. + public String getMethod() { + return request.getMethod(); } - public static class Request implements PrometheusHttpRequest { - - private final HttpServletRequest request; - - public Request(HttpServletRequest request) { - this.request = request; - } - - @Override - public String getQueryString() { - return request.getQueryString(); - } - - @Override - public Enumeration getHeaders(String name) { - return request.getHeaders(name); - } - - @Override - public String getMethod() { - return request.getMethod(); - } - - @Override - public String getRequestPath() { - StringBuilder uri = new StringBuilder(); - String contextPath = request.getContextPath(); - if (contextPath.startsWith("/")) { - uri.append(contextPath); - } - String servletPath = request.getServletPath(); - if (servletPath.startsWith("/")) { - uri.append(servletPath); - } - String pathInfo = request.getPathInfo(); - if (pathInfo != null) { - uri.append(pathInfo); - } - return uri.toString(); - } + @Override + public String getRequestPath() { + StringBuilder uri = new StringBuilder(); + String contextPath = request.getContextPath(); + if (contextPath.startsWith("/")) { + uri.append(contextPath); + } + String servletPath = request.getServletPath(); + if (servletPath.startsWith("/")) { + uri.append(servletPath); + } + String pathInfo = request.getPathInfo(); + if (pathInfo != null) { + uri.append(pathInfo); + } + return uri.toString(); } + } - public static class Response implements PrometheusHttpResponse { + public static class Response implements PrometheusHttpResponse { - private final HttpServletResponse response; + private final HttpServletResponse response; - public Response(HttpServletResponse response) { - this.response = response; - } + public Response(HttpServletResponse response) { + this.response = response; + } - @Override - public void setHeader(String name, String value) { - response.setHeader(name, value); - } + @Override + public void setHeader(String name, String value) { + response.setHeader(name, value); + } - @Override - public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException { - if (response.getHeader("Content-Length") == null && contentLength > 0) { - response.setContentLength(contentLength); - } - response.setStatus(statusCode); - return response.getOutputStream(); - } + @Override + public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) + throws IOException { + if (response.getHeader("Content-Length") == null && contentLength > 0) { + response.setContentLength(contentLength); + } + response.setStatus(statusCode); + return response.getOutputStream(); } + } } diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java index 94dcf83eb..28728dc94 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java @@ -6,36 +6,37 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; - import java.io.IOException; /** * Initial example exporter so that we can try the new metrics library out. - *

      - * We'll add a Jakarta servlet, the built-in HTTPServer, etc. soon, and likely move common code into a common module. + * + *

      We'll add a Jakarta servlet, the built-in HTTPServer, etc. soon, and likely move common code + * into a common module. */ public class PrometheusMetricsServlet extends HttpServlet { - private final PrometheusScrapeHandler handler; + private final PrometheusScrapeHandler handler; - public PrometheusMetricsServlet() { - this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); - } + public PrometheusMetricsServlet() { + this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); + } - public PrometheusMetricsServlet(PrometheusRegistry registry) { - this(PrometheusProperties.get(), registry); - } + public PrometheusMetricsServlet(PrometheusRegistry registry) { + this(PrometheusProperties.get(), registry); + } - public PrometheusMetricsServlet(PrometheusProperties config) { - this(config, PrometheusRegistry.defaultRegistry); - } + public PrometheusMetricsServlet(PrometheusProperties config) { + this(config, PrometheusRegistry.defaultRegistry); + } - public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) { - this.handler = new PrometheusScrapeHandler(config, registry); - } + public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) { + this.handler = new PrometheusScrapeHandler(config, registry); + } - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - handler.handleRequest(new HttpExchangeAdapter(request, response)); - } + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException { + handler.handleRequest(new HttpExchangeAdapter(request, response)); + } } diff --git a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java index 0073db368..939b4d259 100644 --- a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/HttpExchangeAdapter.java @@ -3,151 +3,143 @@ import io.prometheus.metrics.exporter.common.PrometheusHttpExchange; import io.prometheus.metrics.exporter.common.PrometheusHttpRequest; import io.prometheus.metrics.exporter.common.PrometheusHttpResponse; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * This class is an adapter for HTTP exchanges, implementing the PrometheusHttpExchange interface. - * It wraps HttpServletRequest and HttpServletResponse objects into Request and Response inner classes. + * It wraps HttpServletRequest and HttpServletResponse objects into Request and Response inner + * classes. */ public class HttpExchangeAdapter implements PrometheusHttpExchange { - private final Request request; - private final Response response; + private final Request request; + private final Response response; + + /** + * Constructs a new HttpExchangeAdapter with the given HttpServletRequest and HttpServletResponse. + * + * @param request the HttpServletRequest to be adapted + * @param response the HttpServletResponse to be adapted + */ + public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { + this.request = new Request(request); + this.response = new Response(response); + } + + /** + * Returns the adapted HttpServletRequest. + * + * @return the adapted HttpServletRequest + */ + @Override + public PrometheusHttpRequest getRequest() { + return request; + } + + /** + * Returns the adapted HttpServletResponse. + * + * @return the adapted HttpServletResponse + */ + @Override + public PrometheusHttpResponse getResponse() { + return response; + } + + @Override + public void handleException(IOException e) throws IOException { + throw e; // leave exception handling to the servlet container + } + + @Override + public void handleException(RuntimeException e) { + throw e; // leave exception handling to the servlet container + } + + @Override + public void close() { + // nothing to do for Servlets. + } + + /** This inner class adapts a HttpServletRequest to a PrometheusHttpRequest. */ + public static class Request implements PrometheusHttpRequest { + + private final HttpServletRequest request; /** - * Constructs a new HttpExchangeAdapter with the given HttpServletRequest and HttpServletResponse. + * Constructs a new Request with the given HttpServletRequest. * - * @param request the HttpServletRequest to be adapted - * @param response the HttpServletResponse to be adapted + * @param request the HttpServletRequest to be adapted */ - public HttpExchangeAdapter(HttpServletRequest request, HttpServletResponse response) { - this.request = new Request(request); - this.response = new Response(response); + public Request(HttpServletRequest request) { + this.request = request; } - /** - * Returns the adapted HttpServletRequest. - * - * @return the adapted HttpServletRequest - */ @Override - public PrometheusHttpRequest getRequest() { - return request; + public String getQueryString() { + return request.getQueryString(); } - /** - * Returns the adapted HttpServletResponse. - * - * @return the adapted HttpServletResponse - */ @Override - public PrometheusHttpResponse getResponse() { - return response; + public Enumeration getHeaders(String name) { + return request.getHeaders(name); } @Override - public void handleException(IOException e) throws IOException { - throw e; // leave exception handling to the servlet container + public String getMethod() { + return request.getMethod(); } @Override - public void handleException(RuntimeException e) { - throw e; // leave exception handling to the servlet container + public String getRequestPath() { + StringBuilder uri = new StringBuilder(); + String contextPath = request.getContextPath(); + if (contextPath.startsWith("/")) { + uri.append(contextPath); + } + String servletPath = request.getServletPath(); + if (servletPath.startsWith("/")) { + uri.append(servletPath); + } + String pathInfo = request.getPathInfo(); + if (pathInfo != null) { + uri.append(pathInfo); + } + return uri.toString(); } + } - @Override - public void close() { - // nothing to do for Servlets. - } + /** This inner class adapts a HttpServletResponse to a PrometheusHttpResponse. */ + public static class Response implements PrometheusHttpResponse { + + private final HttpServletResponse response; /** - * This inner class adapts a HttpServletRequest to a PrometheusHttpRequest. + * Constructs a new Response with the given HttpServletResponse. + * + * @param response the HttpServletResponse to be adapted */ - public static class Request implements PrometheusHttpRequest { - - private final HttpServletRequest request; - - /** - * Constructs a new Request with the given HttpServletRequest. - * - * @param request the HttpServletRequest to be adapted - */ - public Request(HttpServletRequest request) { - this.request = request; - } - - @Override - public String getQueryString() { - return request.getQueryString(); - } - - - @Override - public Enumeration getHeaders(String name) { - return request.getHeaders(name); - } - - - @Override - public String getMethod() { - return request.getMethod(); - } - - - @Override - public String getRequestPath() { - StringBuilder uri = new StringBuilder(); - String contextPath = request.getContextPath(); - if (contextPath.startsWith("/")) { - uri.append(contextPath); - } - String servletPath = request.getServletPath(); - if (servletPath.startsWith("/")) { - uri.append(servletPath); - } - String pathInfo = request.getPathInfo(); - if (pathInfo != null) { - uri.append(pathInfo); - } - return uri.toString(); - } + public Response(HttpServletResponse response) { + this.response = response; } - /** - * This inner class adapts a HttpServletResponse to a PrometheusHttpResponse. - */ - public static class Response implements PrometheusHttpResponse { - - private final HttpServletResponse response; - - /** - * Constructs a new Response with the given HttpServletResponse. - * - * @param response the HttpServletResponse to be adapted - */ - public Response(HttpServletResponse response) { - this.response = response; - } - - - @Override - public void setHeader(String name, String value) { - response.setHeader(name, value); - } - - - @Override - public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) throws IOException { - if (response.getHeader("Content-Length") == null && contentLength > 0) { - response.setContentLength(contentLength); - } - response.setStatus(statusCode); - return response.getOutputStream(); - } + @Override + public void setHeader(String name, String value) { + response.setHeader(name, value); + } + + @Override + public OutputStream sendHeadersAndGetBody(int statusCode, int contentLength) + throws IOException { + if (response.getHeader("Content-Length") == null && contentLength > 0) { + response.setContentLength(contentLength); + } + response.setStatus(statusCode); + return response.getOutputStream(); } -} \ No newline at end of file + } +} diff --git a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java index 88564d118..fe81fe96b 100644 --- a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java +++ b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java @@ -3,65 +3,64 @@ import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.exporter.common.PrometheusScrapeHandler; import io.prometheus.metrics.model.registry.PrometheusRegistry; - +import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; /** - * This class extends HttpServlet to create a servlet for exporting Prometheus metrics. - * It uses a PrometheusScrapeHandler to handle HTTP GET requests and export metrics. - * The servlet can be configured with custom PrometheusProperties and a PrometheusRegistry. + * This class extends HttpServlet to create a servlet for exporting Prometheus metrics. It uses a + * PrometheusScrapeHandler to handle HTTP GET requests and export metrics. The servlet can be + * configured with custom PrometheusProperties and a PrometheusRegistry. */ public class PrometheusMetricsServlet extends HttpServlet { - private final PrometheusScrapeHandler handler; + private final PrometheusScrapeHandler handler; - /** - * Default constructor. Uses the default PrometheusProperties and PrometheusRegistry. - */ - public PrometheusMetricsServlet() { - this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); - } + /** Default constructor. Uses the default PrometheusProperties and PrometheusRegistry. */ + public PrometheusMetricsServlet() { + this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); + } - /** - * Constructor with a custom PrometheusRegistry. Uses the default PrometheusProperties. - * - * @param registry the PrometheusRegistry to use - */ - public PrometheusMetricsServlet(PrometheusRegistry registry) { - this(PrometheusProperties.get(), registry); - } + /** + * Constructor with a custom PrometheusRegistry. Uses the default PrometheusProperties. + * + * @param registry the PrometheusRegistry to use + */ + public PrometheusMetricsServlet(PrometheusRegistry registry) { + this(PrometheusProperties.get(), registry); + } - /** - * Constructor with custom PrometheusProperties. Uses the default PrometheusRegistry. - * - * @param config the PrometheusProperties to use - */ - public PrometheusMetricsServlet(PrometheusProperties config) { - this(config, PrometheusRegistry.defaultRegistry); - } + /** + * Constructor with custom PrometheusProperties. Uses the default PrometheusRegistry. + * + * @param config the PrometheusProperties to use + */ + public PrometheusMetricsServlet(PrometheusProperties config) { + this(config, PrometheusRegistry.defaultRegistry); + } - /** - * Constructor with custom PrometheusProperties and PrometheusRegistry. - * - * @param config the PrometheusProperties to use - * @param registry the PrometheusRegistry to use - */ - public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) { - this.handler = new PrometheusScrapeHandler(config, registry); - } + /** + * Constructor with custom PrometheusProperties and PrometheusRegistry. + * + * @param config the PrometheusProperties to use + * @param registry the PrometheusRegistry to use + */ + public PrometheusMetricsServlet(PrometheusProperties config, PrometheusRegistry registry) { + this.handler = new PrometheusScrapeHandler(config, registry); + } - /** - * Handles HTTP GET requests. Exports Prometheus metrics by delegating to the PrometheusScrapeHandler. - * - * @param request the HttpServletRequest - * @param response the HttpServletResponse - * @throws IOException if an I/O error occurs - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - handler.handleRequest(new HttpExchangeAdapter(request, response)); - } -} \ No newline at end of file + /** + * Handles HTTP GET requests. Exports Prometheus metrics by delegating to the + * PrometheusScrapeHandler. + * + * @param request the HttpServletRequest + * @param response the HttpServletResponse + * @throws IOException if an I/O error occurs + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws IOException { + handler.handleRequest(new HttpExchangeAdapter(request, response)); + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java index 3db354c56..e693e0c15 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java @@ -1,16 +1,14 @@ package io.prometheus.metrics.expositionformats; import io.prometheus.metrics.model.snapshots.MetricSnapshots; - import java.io.IOException; import java.io.OutputStream; public interface ExpositionFormatWriter { - boolean accepts(String acceptHeader); + boolean accepts(String acceptHeader); + + /** Text formats use UTF-8 encoding. */ + void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException; - /** - * Text formats use UTF-8 encoding. - */ - void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException; - String getContentType(); + String getContentType(); } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java index f913753cd..01ea9ef40 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java @@ -5,49 +5,50 @@ public class ExpositionFormats { - private final PrometheusProtobufWriter prometheusProtobufWriter; - private final PrometheusTextFormatWriter prometheusTextFormatWriter; - private final OpenMetricsTextFormatWriter openMetricsTextFormatWriter; - - private ExpositionFormats(PrometheusProtobufWriter prometheusProtobufWriter, - PrometheusTextFormatWriter prometheusTextFormatWriter, - OpenMetricsTextFormatWriter openMetricsTextFormatWriter) { - this.prometheusProtobufWriter = prometheusProtobufWriter; - this.prometheusTextFormatWriter = prometheusTextFormatWriter; - this.openMetricsTextFormatWriter = openMetricsTextFormatWriter; + private final PrometheusProtobufWriter prometheusProtobufWriter; + private final PrometheusTextFormatWriter prometheusTextFormatWriter; + private final OpenMetricsTextFormatWriter openMetricsTextFormatWriter; + + private ExpositionFormats( + PrometheusProtobufWriter prometheusProtobufWriter, + PrometheusTextFormatWriter prometheusTextFormatWriter, + OpenMetricsTextFormatWriter openMetricsTextFormatWriter) { + this.prometheusProtobufWriter = prometheusProtobufWriter; + this.prometheusTextFormatWriter = prometheusTextFormatWriter; + this.openMetricsTextFormatWriter = openMetricsTextFormatWriter; + } + + public static ExpositionFormats init() { + return init(PrometheusProperties.get().getExporterProperties()); + } + + public static ExpositionFormats init(ExporterProperties properties) { + return new ExpositionFormats( + new PrometheusProtobufWriter(), + new PrometheusTextFormatWriter(properties.getIncludeCreatedTimestamps()), + new OpenMetricsTextFormatWriter( + properties.getIncludeCreatedTimestamps(), properties.getExemplarsOnAllMetricTypes())); + } + + public ExpositionFormatWriter findWriter(String acceptHeader) { + if (prometheusProtobufWriter.accepts(acceptHeader)) { + return prometheusProtobufWriter; } - - public static ExpositionFormats init() { - return init(PrometheusProperties.get().getExporterProperties()); - } - - public static ExpositionFormats init(ExporterProperties properties) { - return new ExpositionFormats( - new PrometheusProtobufWriter(), - new PrometheusTextFormatWriter(properties.getIncludeCreatedTimestamps()), - new OpenMetricsTextFormatWriter(properties.getIncludeCreatedTimestamps(), properties.getExemplarsOnAllMetricTypes()) - ); - } - - public ExpositionFormatWriter findWriter(String acceptHeader) { - if (prometheusProtobufWriter.accepts(acceptHeader)) { - return prometheusProtobufWriter; - } - if (openMetricsTextFormatWriter.accepts(acceptHeader)) { - return openMetricsTextFormatWriter; - } - return prometheusTextFormatWriter; + if (openMetricsTextFormatWriter.accepts(acceptHeader)) { + return openMetricsTextFormatWriter; } + return prometheusTextFormatWriter; + } - public PrometheusProtobufWriter getPrometheusProtobufWriter() { - return prometheusProtobufWriter; - } + public PrometheusProtobufWriter getPrometheusProtobufWriter() { + return prometheusProtobufWriter; + } - public PrometheusTextFormatWriter getPrometheusTextFormatWriter() { - return prometheusTextFormatWriter; - } + public PrometheusTextFormatWriter getPrometheusTextFormatWriter() { + return prometheusTextFormatWriter; + } - public OpenMetricsTextFormatWriter getOpenMetricsTextFormatWriter() { - return openMetricsTextFormatWriter; - } + public OpenMetricsTextFormatWriter getOpenMetricsTextFormatWriter() { + return openMetricsTextFormatWriter; + } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index dd92391ff..00ac6b9fc 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -1,5 +1,11 @@ package io.prometheus.metrics.expositionformats; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; + import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.DataPointSnapshot; @@ -17,317 +23,356 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; - import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.List; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; - /** - * Write the OpenMetrics text format as defined on https://openmetrics.io. + * Write the OpenMetrics text format as defined on https://openmetrics.io. */ public class OpenMetricsTextFormatWriter implements ExpositionFormatWriter { - public static final String CONTENT_TYPE = "application/openmetrics-text; version=1.0.0; charset=utf-8"; - private final boolean createdTimestampsEnabled; - private final boolean exemplarsOnAllMetricTypesEnabled; + public static final String CONTENT_TYPE = + "application/openmetrics-text; version=1.0.0; charset=utf-8"; + private final boolean createdTimestampsEnabled; + private final boolean exemplarsOnAllMetricTypesEnabled; - /** - * @param createdTimestampsEnabled defines if {@code _created} timestamps should be included in the output or not. - */ - public OpenMetricsTextFormatWriter(boolean createdTimestampsEnabled, boolean exemplarsOnAllMetricTypesEnabled) { - this.createdTimestampsEnabled = createdTimestampsEnabled; - this.exemplarsOnAllMetricTypesEnabled = exemplarsOnAllMetricTypesEnabled; - } + /** + * @param createdTimestampsEnabled defines if {@code _created} timestamps should be included in + * the output or not. + */ + public OpenMetricsTextFormatWriter( + boolean createdTimestampsEnabled, boolean exemplarsOnAllMetricTypesEnabled) { + this.createdTimestampsEnabled = createdTimestampsEnabled; + this.exemplarsOnAllMetricTypesEnabled = exemplarsOnAllMetricTypesEnabled; + } - @Override - public boolean accepts(String acceptHeader) { - if (acceptHeader == null) { - return false; - } - return acceptHeader.contains("application/openmetrics-text"); + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; } + return acceptHeader.contains("application/openmetrics-text"); + } - @Override - public String getContentType() { - return CONTENT_TYPE; - } + @Override + public String getContentType() { + return CONTENT_TYPE; + } - public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { - OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); - for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { - if (snapshot instanceof CounterSnapshot) { - writeCounter(writer, (CounterSnapshot) snapshot); - } else if (snapshot instanceof GaugeSnapshot) { - writeGauge(writer, (GaugeSnapshot) snapshot); - } else if (snapshot instanceof HistogramSnapshot) { - writeHistogram(writer, (HistogramSnapshot) snapshot); - } else if (snapshot instanceof SummarySnapshot) { - writeSummary(writer, (SummarySnapshot) snapshot); - } else if (snapshot instanceof InfoSnapshot) { - writeInfo(writer, (InfoSnapshot) snapshot); - } else if (snapshot instanceof StateSetSnapshot) { - writeStateSet(writer, (StateSetSnapshot) snapshot); - } else if (snapshot instanceof UnknownSnapshot) { - writeUnknown(writer, (UnknownSnapshot) snapshot); - } - } + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getDataPoints().size() > 0) { + if (snapshot instanceof CounterSnapshot) { + writeCounter(writer, (CounterSnapshot) snapshot); + } else if (snapshot instanceof GaugeSnapshot) { + writeGauge(writer, (GaugeSnapshot) snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeHistogram(writer, (HistogramSnapshot) snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeSummary(writer, (SummarySnapshot) snapshot); + } else if (snapshot instanceof InfoSnapshot) { + writeInfo(writer, (InfoSnapshot) snapshot); + } else if (snapshot instanceof StateSetSnapshot) { + writeStateSet(writer, (StateSetSnapshot) snapshot); + } else if (snapshot instanceof UnknownSnapshot) { + writeUnknown(writer, (UnknownSnapshot) snapshot); } - writer.write("# EOF\n"); - writer.flush(); + } } + writer.write("# EOF\n"); + writer.flush(); + } - private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "counter", metadata); - for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); - writeDouble(writer, data.getValue()); - writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); - writeCreated(writer, metadata, data); - } + private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "counter", metadata); + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + writeCreated(writer, metadata, data); } + } - private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "gauge", metadata); - for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); - writeDouble(writer, data.getValue()); - if (exemplarsOnAllMetricTypesEnabled) { - writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); - } else { - writeScrapeTimestampAndExemplar(writer, data, null); - } - } + private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "gauge", metadata); + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } } + } - private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - if (snapshot.isGaugeHistogram()) { - writeMetadata(writer, "gaugehistogram", metadata); - writeClassicHistogramBuckets(writer, metadata, "_gcount", "_gsum", snapshot.getDataPoints()); - } else { - writeMetadata(writer, "histogram", metadata); - writeClassicHistogramBuckets(writer, metadata, "_count", "_sum", snapshot.getDataPoints()); - } - } - - private void writeClassicHistogramBuckets(OutputStreamWriter writer, MetricMetadata metadata, String countSuffix, String sumSuffix, List dataList) throws IOException { - for (HistogramSnapshot.HistogramDataPointSnapshot data : dataList) { - ClassicHistogramBuckets buckets = getClassicBuckets(data); - Exemplars exemplars = data.getExemplars(); - long cumulativeCount = 0; - for (int i = 0; i < buckets.size(); i++) { - cumulativeCount += buckets.getCount(i); - writeNameAndLabels(writer, metadata.getPrometheusName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); - writeLong(writer, cumulativeCount); - Exemplar exemplar; - if (i == 0) { - exemplar = exemplars.get(Double.NEGATIVE_INFINITY, buckets.getUpperBound(i)); - } else { - exemplar = exemplars.get(buckets.getUpperBound(i - 1), buckets.getUpperBound(i)); - } - writeScrapeTimestampAndExemplar(writer, data, exemplar); - } - // In OpenMetrics format, histogram _count and _sum are either both present or both absent. - if (data.hasCount() && data.hasSum()) { - writeCountAndSum(writer, metadata, data, countSuffix, sumSuffix, exemplars); - } - writeCreated(writer, metadata, data); - } + private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + if (snapshot.isGaugeHistogram()) { + writeMetadata(writer, "gaugehistogram", metadata); + writeClassicHistogramBuckets(writer, metadata, "_gcount", "_gsum", snapshot.getDataPoints()); + } else { + writeMetadata(writer, "histogram", metadata); + writeClassicHistogramBuckets(writer, metadata, "_count", "_sum", snapshot.getDataPoints()); } + } - private ClassicHistogramBuckets getClassicBuckets(HistogramSnapshot.HistogramDataPointSnapshot data) { - if (data.getClassicBuckets().isEmpty()) { - return ClassicHistogramBuckets.of( - new double[]{Double.POSITIVE_INFINITY}, - new long[]{data.getCount()} - ); + private void writeClassicHistogramBuckets( + OutputStreamWriter writer, + MetricMetadata metadata, + String countSuffix, + String sumSuffix, + List dataList) + throws IOException { + for (HistogramSnapshot.HistogramDataPointSnapshot data : dataList) { + ClassicHistogramBuckets buckets = getClassicBuckets(data); + Exemplars exemplars = data.getExemplars(); + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + writeNameAndLabels( + writer, + metadata.getPrometheusName(), + "_bucket", + data.getLabels(), + "le", + buckets.getUpperBound(i)); + writeLong(writer, cumulativeCount); + Exemplar exemplar; + if (i == 0) { + exemplar = exemplars.get(Double.NEGATIVE_INFINITY, buckets.getUpperBound(i)); } else { - return data.getClassicBuckets(); + exemplar = exemplars.get(buckets.getUpperBound(i - 1), buckets.getUpperBound(i)); } + writeScrapeTimestampAndExemplar(writer, data, exemplar); + } + // In OpenMetrics format, histogram _count and _sum are either both present or both absent. + if (data.hasCount() && data.hasSum()) { + writeCountAndSum(writer, metadata, data, countSuffix, sumSuffix, exemplars); + } + writeCreated(writer, metadata, data); } + } - private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { - boolean metadataWritten = false; - MetricMetadata metadata = snapshot.getMetadata(); - for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { - if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { - continue; - } - if (!metadataWritten) { - writeMetadata(writer, "summary", metadata); - metadataWritten = true; - } - Exemplars exemplars = data.getExemplars(); - // Exemplars for summaries are new, and there's no best practice yet which Exemplars to choose for which - // time series. We select exemplars[0] for _count, exemplars[1] for _sum, and exemplars[2...] for the - // quantiles, all indexes modulo exemplars.length. - int exemplarIndex = 1; - for (Quantile quantile : data.getQuantiles()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels(), "quantile", quantile.getQuantile()); - writeDouble(writer, quantile.getValue()); - if (exemplars.size() > 0 && exemplarsOnAllMetricTypesEnabled) { - exemplarIndex = (exemplarIndex + 1) % exemplars.size(); - writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); - } else { - writeScrapeTimestampAndExemplar(writer, data, null); - } - } - // Unlike histograms, summaries can have only a count or only a sum according to OpenMetrics. - writeCountAndSum(writer, metadata, data, "_count", "_sum", exemplars); - writeCreated(writer, metadata, data); - } + private ClassicHistogramBuckets getClassicBuckets( + HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.getClassicBuckets().isEmpty()) { + return ClassicHistogramBuckets.of( + new double[] {Double.POSITIVE_INFINITY}, new long[] {data.getCount()}); + } else { + return data.getClassicBuckets(); } + } - private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "info", metadata); - for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); - writer.write("1"); - writeScrapeTimestampAndExemplar(writer, data, null); + private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) + throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { + if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { + continue; + } + if (!metadataWritten) { + writeMetadata(writer, "summary", metadata); + metadataWritten = true; + } + Exemplars exemplars = data.getExemplars(); + // Exemplars for summaries are new, and there's no best practice yet which Exemplars to choose + // for which + // time series. We select exemplars[0] for _count, exemplars[1] for _sum, and exemplars[2...] + // for the + // quantiles, all indexes modulo exemplars.length. + int exemplarIndex = 1; + for (Quantile quantile : data.getQuantiles()) { + writeNameAndLabels( + writer, + metadata.getPrometheusName(), + null, + data.getLabels(), + "quantile", + quantile.getQuantile()); + writeDouble(writer, quantile.getValue()); + if (exemplars.size() > 0 && exemplarsOnAllMetricTypesEnabled) { + exemplarIndex = (exemplarIndex + 1) % exemplars.size(); + writeScrapeTimestampAndExemplar(writer, data, exemplars.get(exemplarIndex)); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); } + } + // Unlike histograms, summaries can have only a count or only a sum according to OpenMetrics. + writeCountAndSum(writer, metadata, data, "_count", "_sum", exemplars); + writeCreated(writer, metadata, data); } + } - private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "stateset", metadata); - for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { - for (int i = 0; i < data.size(); i++) { - writer.write(metadata.getPrometheusName()); - writer.write('{'); - for (int j = 0; j < data.getLabels().size(); j++) { - if (j > 0) { - writer.write(","); - } - writer.write(data.getLabels().getPrometheusName(j)); - writer.write("=\""); - writeEscapedLabelValue(writer, data.getLabels().getValue(j)); - writer.write("\""); - } - if (!data.getLabels().isEmpty()) { - writer.write(","); - } - writer.write(metadata.getPrometheusName()); - writer.write("=\""); - writeEscapedLabelValue(writer, data.getName(i)); - writer.write("\"} "); - if (data.isTrue(i)) { - writer.write("1"); - } else { - writer.write("0"); - } - writeScrapeTimestampAndExemplar(writer, data, null); - } - } + private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "info", metadata); + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); + writer.write("1"); + writeScrapeTimestampAndExemplar(writer, data, null); } + } - private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "unknown", metadata); - for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); - writeDouble(writer, data.getValue()); - if (exemplarsOnAllMetricTypesEnabled) { - writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); - } else { - writeScrapeTimestampAndExemplar(writer, data, null); - } + private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "stateset", metadata); + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { + for (int i = 0; i < data.size(); i++) { + writer.write(metadata.getPrometheusName()); + writer.write('{'); + for (int j = 0; j < data.getLabels().size(); j++) { + if (j > 0) { + writer.write(","); + } + writer.write(data.getLabels().getPrometheusName(j)); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getLabels().getValue(j)); + writer.write("\""); } - } - - private void writeCountAndSum(OutputStreamWriter writer, MetricMetadata metadata, DistributionDataPointSnapshot data, String countSuffix, String sumSuffix, Exemplars exemplars) throws IOException { - if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), countSuffix, data.getLabels()); - writeLong(writer, data.getCount()); - if (exemplarsOnAllMetricTypesEnabled) { - writeScrapeTimestampAndExemplar(writer, data, exemplars.getLatest()); - } else { - writeScrapeTimestampAndExemplar(writer, data, null); - } + if (!data.getLabels().isEmpty()) { + writer.write(","); } - if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), sumSuffix, data.getLabels()); - writeDouble(writer, data.getSum()); - writeScrapeTimestampAndExemplar(writer, data, null); + writer.write(metadata.getPrometheusName()); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getName(i)); + writer.write("\"} "); + if (data.isTrue(i)) { + writer.write("1"); + } else { + writer.write("0"); } + writeScrapeTimestampAndExemplar(writer, data, null); + } } + } - private void writeCreated(OutputStreamWriter writer, MetricMetadata metadata, DataPointSnapshot data) throws IOException { - if (createdTimestampsEnabled && data.hasCreatedTimestamp()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); - writeTimestamp(writer, data.getCreatedTimestampMillis()); - if (data.hasScrapeTimestamp()) { - writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); - } - writer.write('\n'); - } + private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "unknown", metadata); + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, data.getExemplar()); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } } + } - private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { - writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + private void writeCountAndSum( + OutputStreamWriter writer, + MetricMetadata metadata, + DistributionDataPointSnapshot data, + String countSuffix, + String sumSuffix, + Exemplars exemplars) + throws IOException { + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), countSuffix, data.getLabels()); + writeLong(writer, data.getCount()); + if (exemplarsOnAllMetricTypesEnabled) { + writeScrapeTimestampAndExemplar(writer, data, exemplars.getLatest()); + } else { + writeScrapeTimestampAndExemplar(writer, data, null); + } } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), sumSuffix, data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndExemplar(writer, data, null); + } + } - private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels, - String additionalLabelName, double additionalLabelValue) throws IOException { - writer.write(name); - if (suffix != null) { - writer.write(suffix); - } - if (!labels.isEmpty() || additionalLabelName != null) { - writeLabels(writer, labels, additionalLabelName, additionalLabelValue); - } + private void writeCreated( + OutputStreamWriter writer, MetricMetadata metadata, DataPointSnapshot data) + throws IOException { + if (createdTimestampsEnabled && data.hasCreatedTimestamp()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); + writeTimestamp(writer, data.getCreatedTimestampMillis()); + if (data.hasScrapeTimestamp()) { writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); + } + writer.write('\n'); } + } - private void writeScrapeTimestampAndExemplar(OutputStreamWriter writer, DataPointSnapshot data, Exemplar exemplar) throws IOException { - if (data.hasScrapeTimestamp()) { - writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); - } - if (exemplar != null) { - writer.write(" # "); - writeLabels(writer, exemplar.getLabels(), null, 0); - writer.write(' '); - writeDouble(writer, exemplar.getValue()); - if (exemplar.hasTimestamp()) { - writer.write(' '); - writeTimestamp(writer, exemplar.getTimestampMillis()); - } - } - writer.write('\n'); + private void writeNameAndLabels( + OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { + writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + } + + private void writeNameAndLabels( + OutputStreamWriter writer, + String name, + String suffix, + Labels labels, + String additionalLabelName, + double additionalLabelValue) + throws IOException { + writer.write(name); + if (suffix != null) { + writer.write(suffix); } + if (!labels.isEmpty() || additionalLabelName != null) { + writeLabels(writer, labels, additionalLabelName, additionalLabelValue); + } + writer.write(' '); + } - private void writeMetadata(OutputStreamWriter writer, String typeName, MetricMetadata metadata) throws IOException { - writer.write("# TYPE "); - writer.write(metadata.getPrometheusName()); + private void writeScrapeTimestampAndExemplar( + OutputStreamWriter writer, DataPointSnapshot data, Exemplar exemplar) throws IOException { + if (data.hasScrapeTimestamp()) { + writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); + } + if (exemplar != null) { + writer.write(" # "); + writeLabels(writer, exemplar.getLabels(), null, 0); + writer.write(' '); + writeDouble(writer, exemplar.getValue()); + if (exemplar.hasTimestamp()) { writer.write(' '); - writer.write(typeName); - writer.write('\n'); - if (metadata.getUnit() != null) { - writer.write("# UNIT "); - writer.write(metadata.getPrometheusName()); - writer.write(' '); - writeEscapedLabelValue(writer, metadata.getUnit().toString()); - writer.write('\n'); - } - if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { - writer.write("# HELP "); - writer.write(metadata.getPrometheusName()); - writer.write(' '); - writeEscapedLabelValue(writer, metadata.getHelp()); - writer.write('\n'); - } + writeTimestamp(writer, exemplar.getTimestampMillis()); + } + } + writer.write('\n'); + } + + private void writeMetadata(OutputStreamWriter writer, String typeName, MetricMetadata metadata) + throws IOException { + writer.write("# TYPE "); + writer.write(metadata.getPrometheusName()); + writer.write(' '); + writer.write(typeName); + writer.write('\n'); + if (metadata.getUnit() != null) { + writer.write("# UNIT "); + writer.write(metadata.getPrometheusName()); + writer.write(' '); + writeEscapedLabelValue(writer, metadata.getUnit().toString()); + writer.write('\n'); + } + if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { + writer.write("# HELP "); + writer.write(metadata.getPrometheusName()); + writer.write(' '); + writeEscapedLabelValue(writer, metadata.getHelp()); + writer.write('\n'); } + } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index e0103059a..1c1535de3 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -1,16 +1,17 @@ package io.prometheus.metrics.expositionformats; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; +import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; + import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.InfoSnapshot; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; @@ -19,348 +20,362 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; - +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import java.io.IOException; import java.io.OutputStream; -import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; - /** - * Write the Prometheus protobuf format as defined in - * github.com/prometheus/client_model. - *

      - * As of today, this is the only exposition format that supports native histograms. + * Write the Prometheus protobuf format as defined in github.com/prometheus/client_model. + * + *

      As of today, this is the only exposition format that supports native histograms. */ public class PrometheusProtobufWriter implements ExpositionFormatWriter { - public static final String CONTENT_TYPE = "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"; + public static final String CONTENT_TYPE = + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"; - @Override - public boolean accepts(String acceptHeader) { - if (acceptHeader == null) { - return false; - } else { - return acceptHeader.contains("application/vnd.google.protobuf") - && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); - } + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } else { + return acceptHeader.contains("application/vnd.google.protobuf") + && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); } + } - @Override - public String getContentType() { - return CONTENT_TYPE; - } + @Override + public String getContentType() { + return CONTENT_TYPE; + } - public String toDebugString(MetricSnapshots metricSnapshots) { - StringBuilder stringBuilder = new StringBuilder(); - for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { - stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); - } - } - return stringBuilder.toString(); + public String toDebugString(MetricSnapshots metricSnapshots) { + StringBuilder stringBuilder = new StringBuilder(); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getDataPoints().size() > 0) { + stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); + } } + return stringBuilder.toString(); + } - @Override - public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { - for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { - convert(snapshot).writeDelimitedTo(out); - } - } - } - - public Metrics.MetricFamily convert(MetricSnapshot snapshot) { - Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder(); - if (snapshot instanceof CounterSnapshot) { - for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { - builder.addMetric(convert(data)); - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_total", Metrics.MetricType.COUNTER); - } else if (snapshot instanceof GaugeSnapshot) { - for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { - builder.addMetric(convert(data)); - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); - } else if (snapshot instanceof HistogramSnapshot) { - HistogramSnapshot histogram = (HistogramSnapshot) snapshot; - for (HistogramSnapshot.HistogramDataPointSnapshot data : histogram.getDataPoints()) { - builder.addMetric(convert(data)); - } - Metrics.MetricType type = histogram.isGaugeHistogram() ? Metrics.MetricType.GAUGE_HISTOGRAM : Metrics.MetricType.HISTOGRAM; - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, type); - } else if (snapshot instanceof SummarySnapshot) { - for (SummarySnapshot.SummaryDataPointSnapshot data : ((SummarySnapshot) snapshot).getDataPoints()) { - if (data.hasCount() || data.hasSum() || data.getQuantiles().size() > 0) { - builder.addMetric(convert(data)); - } - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.SUMMARY); - } else if (snapshot instanceof InfoSnapshot) { - for (InfoSnapshot.InfoDataPointSnapshot data : ((InfoSnapshot) snapshot).getDataPoints()) { - builder.addMetric(convert(data)); - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_info", Metrics.MetricType.GAUGE); - } else if (snapshot instanceof StateSetSnapshot) { - for (StateSetSnapshot.StateSetDataPointSnapshot data : ((StateSetSnapshot) snapshot).getDataPoints()) { - for (int i = 0; i < data.size(); i++) { - builder.addMetric(convert(data, snapshot.getMetadata().getPrometheusName(), i)); - } - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); - } else if (snapshot instanceof UnknownSnapshot) { - for (UnknownSnapshot.UnknownDataPointSnapshot data : ((UnknownSnapshot) snapshot).getDataPoints()) { - builder.addMetric(convert(data)); - } - setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.UNTYPED); - } - return builder.build(); + @Override + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getDataPoints().size() > 0) { + convert(snapshot).writeDelimitedTo(out); + } } + } - private void setMetadataUnlessEmpty(Metrics.MetricFamily.Builder builder, MetricMetadata metadata, String nameSuffix, Metrics.MetricType type) { - if (builder.getMetricCount() == 0) { - return; + public Metrics.MetricFamily convert(MetricSnapshot snapshot) { + Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder(); + if (snapshot instanceof CounterSnapshot) { + for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_total", Metrics.MetricType.COUNTER); + } else if (snapshot instanceof GaugeSnapshot) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); + } else if (snapshot instanceof HistogramSnapshot) { + HistogramSnapshot histogram = (HistogramSnapshot) snapshot; + for (HistogramSnapshot.HistogramDataPointSnapshot data : histogram.getDataPoints()) { + builder.addMetric(convert(data)); + } + Metrics.MetricType type = + histogram.isGaugeHistogram() + ? Metrics.MetricType.GAUGE_HISTOGRAM + : Metrics.MetricType.HISTOGRAM; + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, type); + } else if (snapshot instanceof SummarySnapshot) { + for (SummarySnapshot.SummaryDataPointSnapshot data : + ((SummarySnapshot) snapshot).getDataPoints()) { + if (data.hasCount() || data.hasSum() || data.getQuantiles().size() > 0) { + builder.addMetric(convert(data)); } - if (nameSuffix == null) { - builder.setName(metadata.getPrometheusName()); - } else { - builder.setName(metadata.getPrometheusName() + nameSuffix); - } - if (metadata.getHelp() != null) { - builder.setHelp(metadata.getHelp()); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.SUMMARY); + } else if (snapshot instanceof InfoSnapshot) { + for (InfoSnapshot.InfoDataPointSnapshot data : ((InfoSnapshot) snapshot).getDataPoints()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), "_info", Metrics.MetricType.GAUGE); + } else if (snapshot instanceof StateSetSnapshot) { + for (StateSetSnapshot.StateSetDataPointSnapshot data : + ((StateSetSnapshot) snapshot).getDataPoints()) { + for (int i = 0; i < data.size(); i++) { + builder.addMetric(convert(data, snapshot.getMetadata().getPrometheusName(), i)); } - builder.setType(type); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.GAUGE); + } else if (snapshot instanceof UnknownSnapshot) { + for (UnknownSnapshot.UnknownDataPointSnapshot data : + ((UnknownSnapshot) snapshot).getDataPoints()) { + builder.addMetric(convert(data)); + } + setMetadataUnlessEmpty(builder, snapshot.getMetadata(), null, Metrics.MetricType.UNTYPED); } + return builder.build(); + } - private Metrics.Metric.Builder convert(CounterDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Counter.Builder counterBuilder = Metrics.Counter.newBuilder(); - counterBuilder.setValue(data.getValue()); - if (data.getExemplar() != null) { - counterBuilder.setExemplar(convert(data.getExemplar())); - } - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setCounter(counterBuilder.build()); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; + private void setMetadataUnlessEmpty( + Metrics.MetricFamily.Builder builder, + MetricMetadata metadata, + String nameSuffix, + Metrics.MetricType type) { + if (builder.getMetricCount() == 0) { + return; } + if (nameSuffix == null) { + builder.setName(metadata.getPrometheusName()); + } else { + builder.setName(metadata.getPrometheusName() + nameSuffix); + } + if (metadata.getHelp() != null) { + builder.setHelp(metadata.getHelp()); + } + builder.setType(type); + } - private Metrics.Metric.Builder convert(GaugeSnapshot.GaugeDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); - gaugeBuilder.setValue(data.getValue()); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setGauge(gaugeBuilder); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; + private Metrics.Metric.Builder convert(CounterDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Counter.Builder counterBuilder = Metrics.Counter.newBuilder(); + counterBuilder.setValue(data.getValue()); + if (data.getExemplar() != null) { + counterBuilder.setExemplar(convert(data.getExemplar())); } + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setCounter(counterBuilder.build()); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } - private Metrics.Metric.Builder convert(HistogramSnapshot.HistogramDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Histogram.Builder histogramBuilder = Metrics.Histogram.newBuilder(); - if (data.hasNativeHistogramData()) { - histogramBuilder.setSchema(data.getNativeSchema()); - histogramBuilder.setZeroCount(data.getNativeZeroCount()); - histogramBuilder.setZeroThreshold(data.getNativeZeroThreshold()); - addBuckets(histogramBuilder, data.getNativeBucketsForPositiveValues(), +1); - addBuckets(histogramBuilder, data.getNativeBucketsForNegativeValues(), -1); + private Metrics.Metric.Builder convert(GaugeSnapshot.GaugeDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + gaugeBuilder.setValue(data.getValue()); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } - if (!data.hasClassicHistogramData()) { // native only - // Add a single +Inf bucket for the exemplar. - Exemplar exemplar = data.getExemplars().getLatest(); - if (exemplar != null) { - Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() - .setCumulativeCount(getNativeCount(data)) - .setUpperBound(Double.POSITIVE_INFINITY); - bucketBuilder.setExemplar(convert(exemplar)); - histogramBuilder.addBucket(bucketBuilder); - } - } - } - if (data.hasClassicHistogramData()) { + private Metrics.Metric.Builder convert(HistogramSnapshot.HistogramDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Histogram.Builder histogramBuilder = Metrics.Histogram.newBuilder(); + if (data.hasNativeHistogramData()) { + histogramBuilder.setSchema(data.getNativeSchema()); + histogramBuilder.setZeroCount(data.getNativeZeroCount()); + histogramBuilder.setZeroThreshold(data.getNativeZeroThreshold()); + addBuckets(histogramBuilder, data.getNativeBucketsForPositiveValues(), +1); + addBuckets(histogramBuilder, data.getNativeBucketsForNegativeValues(), -1); - ClassicHistogramBuckets buckets = data.getClassicBuckets(); - double lowerBound = Double.NEGATIVE_INFINITY; - long cumulativeCount = 0; - for (int i = 0; i < buckets.size(); i++) { - cumulativeCount += buckets.getCount(i); - double upperBound = buckets.getUpperBound(i); - Metrics.Bucket.Builder bucketBuilder = Metrics.Bucket.newBuilder() - .setCumulativeCount(cumulativeCount) - .setUpperBound(upperBound); - Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); - if (exemplar != null) { - bucketBuilder.setExemplar(convert(exemplar)); - } - histogramBuilder.addBucket(bucketBuilder); - lowerBound = upperBound; - } - } - addLabels(metricBuilder, data.getLabels()); - setScrapeTimestamp(metricBuilder, data); - if (data.hasCount()) { - histogramBuilder.setSampleCount(data.getCount()); + if (!data.hasClassicHistogramData()) { // native only + // Add a single +Inf bucket for the exemplar. + Exemplar exemplar = data.getExemplars().getLatest(); + if (exemplar != null) { + Metrics.Bucket.Builder bucketBuilder = + Metrics.Bucket.newBuilder() + .setCumulativeCount(getNativeCount(data)) + .setUpperBound(Double.POSITIVE_INFINITY); + bucketBuilder.setExemplar(convert(exemplar)); + histogramBuilder.addBucket(bucketBuilder); } - if (data.hasSum()) { - histogramBuilder.setSampleSum(data.getSum()); - } - metricBuilder.setHistogram(histogramBuilder.build()); - return metricBuilder; + } } + if (data.hasClassicHistogramData()) { - private long getNativeCount(HistogramSnapshot.HistogramDataPointSnapshot data) { - if (data.hasCount()) { - return data.getCount(); - } else { - long count = data.getNativeZeroCount(); - for (int i = 0; i < data.getNativeBucketsForPositiveValues().size(); i++) { - count += data.getNativeBucketsForPositiveValues().getCount(i); - } - for (int i = 0; i < data.getNativeBucketsForNegativeValues().size(); i++) { - count += data.getNativeBucketsForNegativeValues().getCount(i); - } - return count; + ClassicHistogramBuckets buckets = data.getClassicBuckets(); + double lowerBound = Double.NEGATIVE_INFINITY; + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + double upperBound = buckets.getUpperBound(i); + Metrics.Bucket.Builder bucketBuilder = + Metrics.Bucket.newBuilder() + .setCumulativeCount(cumulativeCount) + .setUpperBound(upperBound); + Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); + if (exemplar != null) { + bucketBuilder.setExemplar(convert(exemplar)); } + histogramBuilder.addBucket(bucketBuilder); + lowerBound = upperBound; + } + } + addLabels(metricBuilder, data.getLabels()); + setScrapeTimestamp(metricBuilder, data); + if (data.hasCount()) { + histogramBuilder.setSampleCount(data.getCount()); + } + if (data.hasSum()) { + histogramBuilder.setSampleSum(data.getSum()); } + metricBuilder.setHistogram(histogramBuilder.build()); + return metricBuilder; + } - private void addBuckets(Metrics.Histogram.Builder histogramBuilder, NativeHistogramBuckets buckets, int sgn) { - if (buckets.size() > 0) { - Metrics.BucketSpan.Builder currentSpan = Metrics.BucketSpan.newBuilder(); - currentSpan.setOffset(buckets.getBucketIndex(0)); - currentSpan.setLength(0); - int previousIndex = currentSpan.getOffset(); - long previousCount = 0; - for (int i = 0; i < buckets.size(); i++) { - if (buckets.getBucketIndex(i) > previousIndex + 1) { - // If the gap between bucketIndex and previousIndex is just 1 or 2, - // we don't start a new span but continue the existing span and add 1 or 2 empty buckets. - if (buckets.getBucketIndex(i) <= previousIndex + 3) { - while (buckets.getBucketIndex(i) > previousIndex + 1) { - currentSpan.setLength(currentSpan.getLength() + 1); - previousIndex++; - if (sgn > 0) { - histogramBuilder.addPositiveDelta(-previousCount); - } else { - histogramBuilder.addNegativeDelta(-previousCount); - } - previousCount = 0; - } - } else { - if (sgn > 0) { - histogramBuilder.addPositiveSpan(currentSpan.build()); - } else { - histogramBuilder.addNegativeSpan(currentSpan.build()); - } - currentSpan = Metrics.BucketSpan.newBuilder(); - currentSpan.setOffset(buckets.getBucketIndex(i) - (previousIndex + 1)); - } - } - currentSpan.setLength(currentSpan.getLength() + 1); - previousIndex = buckets.getBucketIndex(i); - if (sgn > 0) { - histogramBuilder.addPositiveDelta(buckets.getCount(i) - previousCount); - } else { - histogramBuilder.addNegativeDelta(buckets.getCount(i) - previousCount); - } - previousCount = buckets.getCount(i); + private long getNativeCount(HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.hasCount()) { + return data.getCount(); + } else { + long count = data.getNativeZeroCount(); + for (int i = 0; i < data.getNativeBucketsForPositiveValues().size(); i++) { + count += data.getNativeBucketsForPositiveValues().getCount(i); + } + for (int i = 0; i < data.getNativeBucketsForNegativeValues().size(); i++) { + count += data.getNativeBucketsForNegativeValues().getCount(i); + } + return count; + } + } + + private void addBuckets( + Metrics.Histogram.Builder histogramBuilder, NativeHistogramBuckets buckets, int sgn) { + if (buckets.size() > 0) { + Metrics.BucketSpan.Builder currentSpan = Metrics.BucketSpan.newBuilder(); + currentSpan.setOffset(buckets.getBucketIndex(0)); + currentSpan.setLength(0); + int previousIndex = currentSpan.getOffset(); + long previousCount = 0; + for (int i = 0; i < buckets.size(); i++) { + if (buckets.getBucketIndex(i) > previousIndex + 1) { + // If the gap between bucketIndex and previousIndex is just 1 or 2, + // we don't start a new span but continue the existing span and add 1 or 2 empty buckets. + if (buckets.getBucketIndex(i) <= previousIndex + 3) { + while (buckets.getBucketIndex(i) > previousIndex + 1) { + currentSpan.setLength(currentSpan.getLength() + 1); + previousIndex++; + if (sgn > 0) { + histogramBuilder.addPositiveDelta(-previousCount); + } else { + histogramBuilder.addNegativeDelta(-previousCount); + } + previousCount = 0; } + } else { if (sgn > 0) { - histogramBuilder.addPositiveSpan(currentSpan.build()); + histogramBuilder.addPositiveSpan(currentSpan.build()); } else { - histogramBuilder.addNegativeSpan(currentSpan.build()); + histogramBuilder.addNegativeSpan(currentSpan.build()); } + currentSpan = Metrics.BucketSpan.newBuilder(); + currentSpan.setOffset(buckets.getBucketIndex(i) - (previousIndex + 1)); + } } - } - - private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder(); - if (data.hasCount()) { - summaryBuilder.setSampleCount(data.getCount()); - } - if (data.hasSum()) { - summaryBuilder.setSampleSum(data.getSum()); - } - Quantiles quantiles = data.getQuantiles(); - for (int i = 0; i < quantiles.size(); i++) { - summaryBuilder.addQuantile(Metrics.Quantile.newBuilder() - .setQuantile(quantiles.get(i).getQuantile()) - .setValue(quantiles.get(i).getValue()) - .build()); + currentSpan.setLength(currentSpan.getLength() + 1); + previousIndex = buckets.getBucketIndex(i); + if (sgn > 0) { + histogramBuilder.addPositiveDelta(buckets.getCount(i) - previousCount); + } else { + histogramBuilder.addNegativeDelta(buckets.getCount(i) - previousCount); } - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setSummary(summaryBuilder.build()); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; + previousCount = buckets.getCount(i); + } + if (sgn > 0) { + histogramBuilder.addPositiveSpan(currentSpan.build()); + } else { + histogramBuilder.addNegativeSpan(currentSpan.build()); + } } + } - private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); - gaugeBuilder.setValue(1); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setGauge(gaugeBuilder); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; + private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder(); + if (data.hasCount()) { + summaryBuilder.setSampleCount(data.getCount()); } - - private Metrics.Metric.Builder convert(StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.addLabel(Metrics.LabelPair.newBuilder() - .setName(name) - .setValue(data.getName(i)) - .build()); - if (data.isTrue(i)) { - gaugeBuilder.setValue(1); - } else { - gaugeBuilder.setValue(0); - } - metricBuilder.setGauge(gaugeBuilder); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; + if (data.hasSum()) { + summaryBuilder.setSampleSum(data.getSum()); } + Quantiles quantiles = data.getQuantiles(); + for (int i = 0; i < quantiles.size(); i++) { + summaryBuilder.addQuantile( + Metrics.Quantile.newBuilder() + .setQuantile(quantiles.get(i).getQuantile()) + .setValue(quantiles.get(i).getValue()) + .build()); + } + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setSummary(summaryBuilder.build()); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + gaugeBuilder.setValue(1); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } - private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Untyped.Builder untypedBuilder = Metrics.Untyped.newBuilder(); - untypedBuilder.setValue(data.getValue()); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setUntyped(untypedBuilder); - return metricBuilder; + private Metrics.Metric.Builder convert( + StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.addLabel( + Metrics.LabelPair.newBuilder().setName(name).setValue(data.getName(i)).build()); + if (data.isTrue(i)) { + gaugeBuilder.setValue(1); + } else { + gaugeBuilder.setValue(0); } + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } - private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { - for (int i = 0; i < labels.size(); i++) { - metricBuilder.addLabel(Metrics.LabelPair.newBuilder() - .setName(labels.getPrometheusName(i)) - .setValue(labels.getValue(i)) - .build()); - } + private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Untyped.Builder untypedBuilder = Metrics.Untyped.newBuilder(); + untypedBuilder.setValue(data.getValue()); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setUntyped(untypedBuilder); + return metricBuilder; + } + + private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { + for (int i = 0; i < labels.size(); i++) { + metricBuilder.addLabel( + Metrics.LabelPair.newBuilder() + .setName(labels.getPrometheusName(i)) + .setValue(labels.getValue(i)) + .build()); } + } - private void addLabels(Metrics.Exemplar.Builder metricBuilder, Labels labels) { - for (int i = 0; i < labels.size(); i++) { - metricBuilder.addLabel(Metrics.LabelPair.newBuilder() - .setName(labels.getPrometheusName(i)) - .setValue(labels.getValue(i)) - .build()); - } + private void addLabels(Metrics.Exemplar.Builder metricBuilder, Labels labels) { + for (int i = 0; i < labels.size(); i++) { + metricBuilder.addLabel( + Metrics.LabelPair.newBuilder() + .setName(labels.getPrometheusName(i)) + .setValue(labels.getValue(i)) + .build()); } + } - private Metrics.Exemplar.Builder convert(Exemplar exemplar) { - Metrics.Exemplar.Builder builder = Metrics.Exemplar.newBuilder(); - builder.setValue(exemplar.getValue()); - addLabels(builder, exemplar.getLabels()); - if (exemplar.hasTimestamp()) { - builder.setTimestamp(timestampFromMillis(exemplar.getTimestampMillis())); - } - return builder; + private Metrics.Exemplar.Builder convert(Exemplar exemplar) { + Metrics.Exemplar.Builder builder = Metrics.Exemplar.newBuilder(); + builder.setValue(exemplar.getValue()); + addLabels(builder, exemplar.getLabels()); + if (exemplar.hasTimestamp()) { + builder.setTimestamp(timestampFromMillis(exemplar.getTimestampMillis())); } + return builder; + } - private void setScrapeTimestamp(Metrics.Metric.Builder metricBuilder, DataPointSnapshot data) { - if (data.hasScrapeTimestamp()) { - metricBuilder.setTimestampMs(data.getScrapeTimestampMillis()); - } + private void setScrapeTimestamp(Metrics.Metric.Builder metricBuilder, DataPointSnapshot data) { + if (data.hasScrapeTimestamp()) { + metricBuilder.setTimestampMs(data.getScrapeTimestampMillis()); } + } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index cf9bc3d10..28d049f25 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -1,12 +1,18 @@ package io.prometheus.metrics.expositionformats; -import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; + import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.InfoSnapshot; import io.prometheus.metrics.model.snapshots.Labels; -import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; @@ -14,334 +20,356 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; - import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeDouble; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; - /** - * Write the Prometheus text format. This is the default if you view a Prometheus endpoint with your Web browser. + * Write the Prometheus text format. This is the default if you view a Prometheus endpoint with your + * Web browser. */ public class PrometheusTextFormatWriter implements ExpositionFormatWriter { - public static final String CONTENT_TYPE = "text/plain; version=0.0.4; charset=utf-8"; + public static final String CONTENT_TYPE = "text/plain; version=0.0.4; charset=utf-8"; - private final boolean writeCreatedTimestamps; + private final boolean writeCreatedTimestamps; - public PrometheusTextFormatWriter(boolean writeCreatedTimestamps) { - this.writeCreatedTimestamps = writeCreatedTimestamps; - } + public PrometheusTextFormatWriter(boolean writeCreatedTimestamps) { + this.writeCreatedTimestamps = writeCreatedTimestamps; + } - @Override - public boolean accepts(String acceptHeader) { - if (acceptHeader == null) { - return false; - } else { - return acceptHeader.contains("text/plain"); - } + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } else { + return acceptHeader.contains("text/plain"); } + } - @Override - public String getContentType() { - return CONTENT_TYPE; - } + @Override + public String getContentType() { + return CONTENT_TYPE; + } - public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { - // See https://prometheus.io/docs/instrumenting/exposition_formats/ - // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and "summary". - OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); - for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { - if (snapshot instanceof CounterSnapshot) { - writeCounter(writer, (CounterSnapshot) snapshot); - } else if (snapshot instanceof GaugeSnapshot) { - writeGauge(writer, (GaugeSnapshot) snapshot); - } else if (snapshot instanceof HistogramSnapshot) { - writeHistogram(writer, (HistogramSnapshot) snapshot); - } else if (snapshot instanceof SummarySnapshot) { - writeSummary(writer, (SummarySnapshot) snapshot); - } else if (snapshot instanceof InfoSnapshot) { - writeInfo(writer, (InfoSnapshot) snapshot); - } else if (snapshot instanceof StateSetSnapshot) { - writeStateSet(writer, (StateSetSnapshot) snapshot); - } else if (snapshot instanceof UnknownSnapshot) { - writeUnknown(writer, (UnknownSnapshot) snapshot); - } - } - } - if (writeCreatedTimestamps) { - for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { - if (snapshot instanceof CounterSnapshot) { - writeCreated(writer, snapshot); - } else if (snapshot instanceof HistogramSnapshot) { - writeCreated(writer, snapshot); - } else if (snapshot instanceof SummarySnapshot) { - writeCreated(writer, snapshot); - } - } - } + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + // See https://prometheus.io/docs/instrumenting/exposition_formats/ + // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and + // "summary". + OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); + for (MetricSnapshot snapshot : metricSnapshots) { + if (snapshot.getDataPoints().size() > 0) { + if (snapshot instanceof CounterSnapshot) { + writeCounter(writer, (CounterSnapshot) snapshot); + } else if (snapshot instanceof GaugeSnapshot) { + writeGauge(writer, (GaugeSnapshot) snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeHistogram(writer, (HistogramSnapshot) snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeSummary(writer, (SummarySnapshot) snapshot); + } else if (snapshot instanceof InfoSnapshot) { + writeInfo(writer, (InfoSnapshot) snapshot); + } else if (snapshot instanceof StateSetSnapshot) { + writeStateSet(writer, (StateSetSnapshot) snapshot); + } else if (snapshot instanceof UnknownSnapshot) { + writeUnknown(writer, (UnknownSnapshot) snapshot); } - writer.flush(); - } - - public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException { - boolean metadataWritten = false; - MetricMetadata metadata = snapshot.getMetadata(); - for (DataPointSnapshot data : snapshot.getDataPoints()) { - if (data.hasCreatedTimestamp()) { - if (!metadataWritten) { - writeMetadata(writer, "_created", "gauge", metadata); - metadataWritten = true; - } - writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); - writeTimestamp(writer, data.getCreatedTimestampMillis()); - writeScrapeTimestampAndNewline(writer, data); - } - } - + } } - - private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) throws IOException { + if (writeCreatedTimestamps) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "_total", "counter", metadata); - for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); - writeDouble(writer, data.getValue()); - writeScrapeTimestampAndNewline(writer, data); - } + if (snapshot instanceof CounterSnapshot) { + writeCreated(writer, snapshot); + } else if (snapshot instanceof HistogramSnapshot) { + writeCreated(writer, snapshot); + } else if (snapshot instanceof SummarySnapshot) { + writeCreated(writer, snapshot); + } } + } } + writer.flush(); + } - private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "", "gauge", metadata); - for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); - writeDouble(writer, data.getValue()); - writeScrapeTimestampAndNewline(writer, data); + public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (DataPointSnapshot data : snapshot.getDataPoints()) { + if (data.hasCreatedTimestamp()) { + if (!metadataWritten) { + writeMetadata(writer, "_created", "gauge", metadata); + metadataWritten = true; } + writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); + writeTimestamp(writer, data.getCreatedTimestampMillis()); + writeScrapeTimestampAndNewline(writer, data); + } } + } - private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "", "histogram", metadata); - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { - ClassicHistogramBuckets buckets = getClassicBuckets(data); - long cumulativeCount = 0; - for (int i = 0; i < buckets.size(); i++) { - cumulativeCount += buckets.getCount(i); - writeNameAndLabels(writer, metadata.getPrometheusName(), "_bucket", data.getLabels(), "le", buckets.getUpperBound(i)); - writeLong(writer, cumulativeCount); - writeScrapeTimestampAndNewline(writer, data); - } - if (!snapshot.isGaugeHistogram()) { - if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); - writeLong(writer, data.getCount()); - writeScrapeTimestampAndNewline(writer, data); - } - if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); - writeDouble(writer, data.getSum()); - writeScrapeTimestampAndNewline(writer, data); - } - } - } - if (snapshot.isGaugeHistogram()) { - writeGaugeCountSum(writer, snapshot, metadata); - } + private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot) + throws IOException { + if (snapshot.getDataPoints().size() > 0) { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "_total", "counter", metadata); + for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_total", data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } } + } - private ClassicHistogramBuckets getClassicBuckets(HistogramSnapshot.HistogramDataPointSnapshot data) { - if (data.getClassicBuckets().isEmpty()) { - return ClassicHistogramBuckets.of( - new double[]{Double.POSITIVE_INFINITY}, - new long[]{data.getCount()} - ); - } else { - return data.getClassicBuckets(); - } + private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "gauge", metadata); + for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); } + } - private void writeGaugeCountSum(OutputStreamWriter writer, HistogramSnapshot snapshot, MetricMetadata metadata) throws IOException { - // Prometheus text format does not support gaugehistogram's _gcount and _gsum. - // So we append _gcount and _gsum as gauge metrics. - boolean metadataWritten = false; - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { - if (data.hasCount()) { - if (!metadataWritten) { - writeMetadata(writer, "_gcount", "gauge", metadata); - metadataWritten = true; - } - writeNameAndLabels(writer, metadata.getPrometheusName(), "_gcount", data.getLabels()); - writeLong(writer, data.getCount()); - writeScrapeTimestampAndNewline(writer, data); - } + private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "histogram", metadata); + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { + ClassicHistogramBuckets buckets = getClassicBuckets(data); + long cumulativeCount = 0; + for (int i = 0; i < buckets.size(); i++) { + cumulativeCount += buckets.getCount(i); + writeNameAndLabels( + writer, + metadata.getPrometheusName(), + "_bucket", + data.getLabels(), + "le", + buckets.getUpperBound(i)); + writeLong(writer, cumulativeCount); + writeScrapeTimestampAndNewline(writer, data); + } + if (!snapshot.isGaugeHistogram()) { + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); } - metadataWritten = false; - for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { - if (data.hasSum()) { - if (!metadataWritten) { - writeMetadata(writer, "_gsum", "gauge", metadata); - metadataWritten = true; - } - writeNameAndLabels(writer, metadata.getPrometheusName(), "_gsum", data.getLabels()); - writeDouble(writer, data.getSum()); - writeScrapeTimestampAndNewline(writer, data); - } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); } + } } - - private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) throws IOException { - boolean metadataWritten = false; - MetricMetadata metadata = snapshot.getMetadata(); - for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { - if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { - continue; - } - if (!metadataWritten) { - writeMetadata(writer, "", "summary", metadata); - metadataWritten = true; - } - for (Quantile quantile : data.getQuantiles()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels(), "quantile", quantile.getQuantile()); - writeDouble(writer, quantile.getValue()); - writeScrapeTimestampAndNewline(writer, data); - } - if (data.hasCount()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); - writeLong(writer, data.getCount()); - writeScrapeTimestampAndNewline(writer, data); - } - if (data.hasSum()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); - writeDouble(writer, data.getSum()); - writeScrapeTimestampAndNewline(writer, data); - } - } + if (snapshot.isGaugeHistogram()) { + writeGaugeCountSum(writer, snapshot, metadata); } + } - private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "_info", "gauge", metadata); - for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); - writer.write("1"); - writeScrapeTimestampAndNewline(writer, data); - } + private ClassicHistogramBuckets getClassicBuckets( + HistogramSnapshot.HistogramDataPointSnapshot data) { + if (data.getClassicBuckets().isEmpty()) { + return ClassicHistogramBuckets.of( + new double[] {Double.POSITIVE_INFINITY}, new long[] {data.getCount()}); + } else { + return data.getClassicBuckets(); } + } - private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "", "gauge", metadata); - for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { - for (int i = 0; i < data.size(); i++) { - writer.write(metadata.getPrometheusName()); - writer.write('{'); - for (int j = 0; j < data.getLabels().size(); j++) { - if (j > 0) { - writer.write(","); - } - writer.write(data.getLabels().getPrometheusName(j)); - writer.write("=\""); - writeEscapedLabelValue(writer, data.getLabels().getValue(j)); - writer.write("\""); - } - if (!data.getLabels().isEmpty()) { - writer.write(","); - } - writer.write(metadata.getPrometheusName()); - writer.write("=\""); - writeEscapedLabelValue(writer, data.getName(i)); - writer.write("\"} "); - if (data.isTrue(i)) { - writer.write("1"); - } else { - writer.write("0"); - } - writeScrapeTimestampAndNewline(writer, data); - } + private void writeGaugeCountSum( + OutputStreamWriter writer, HistogramSnapshot snapshot, MetricMetadata metadata) + throws IOException { + // Prometheus text format does not support gaugehistogram's _gcount and _gsum. + // So we append _gcount and _gsum as gauge metrics. + boolean metadataWritten = false; + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { + if (data.hasCount()) { + if (!metadataWritten) { + writeMetadata(writer, "_gcount", "gauge", metadata); + metadataWritten = true; } + writeNameAndLabels(writer, metadata.getPrometheusName(), "_gcount", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); + } } - - private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) throws IOException { - MetricMetadata metadata = snapshot.getMetadata(); - writeMetadata(writer, "", "untyped", metadata); - for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { - writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); - writeDouble(writer, data.getValue()); - writeScrapeTimestampAndNewline(writer, data); + metadataWritten = false; + for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) { + if (data.hasSum()) { + if (!metadataWritten) { + writeMetadata(writer, "_gsum", "gauge", metadata); + metadataWritten = true; } + writeNameAndLabels(writer, metadata.getPrometheusName(), "_gsum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); + } } + } - private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { - writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot) + throws IOException { + boolean metadataWritten = false; + MetricMetadata metadata = snapshot.getMetadata(); + for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) { + if (data.getQuantiles().size() == 0 && !data.hasCount() && !data.hasSum()) { + continue; + } + if (!metadataWritten) { + writeMetadata(writer, "", "summary", metadata); + metadataWritten = true; + } + for (Quantile quantile : data.getQuantiles()) { + writeNameAndLabels( + writer, + metadata.getPrometheusName(), + null, + data.getLabels(), + "quantile", + quantile.getQuantile()); + writeDouble(writer, quantile.getValue()); + writeScrapeTimestampAndNewline(writer, data); + } + if (data.hasCount()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_count", data.getLabels()); + writeLong(writer, data.getCount()); + writeScrapeTimestampAndNewline(writer, data); + } + if (data.hasSum()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_sum", data.getLabels()); + writeDouble(writer, data.getSum()); + writeScrapeTimestampAndNewline(writer, data); + } } + } - private void writeNameAndLabels(OutputStreamWriter writer, String name, String suffix, Labels labels, - String additionalLabelName, double additionalLabelValue) throws IOException { - writer.write(name); - if (suffix != null) { - writer.write(suffix); - } - if (!labels.isEmpty() || additionalLabelName != null) { - writeLabels(writer, labels, additionalLabelName, additionalLabelValue); - } - writer.write(' '); + private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "_info", "gauge", metadata); + for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), "_info", data.getLabels()); + writer.write("1"); + writeScrapeTimestampAndNewline(writer, data); } + } - private void writeMetadata(OutputStreamWriter writer, String suffix, String typeString, MetricMetadata metadata) throws IOException { - if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { - writer.write("# HELP "); - writer.write(metadata.getPrometheusName()); - if (suffix != null) { - writer.write(suffix); - } - writer.write(' '); - writeEscapedHelp(writer, metadata.getHelp()); - writer.write('\n'); + private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "gauge", metadata); + for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) { + for (int i = 0; i < data.size(); i++) { + writer.write(metadata.getPrometheusName()); + writer.write('{'); + for (int j = 0; j < data.getLabels().size(); j++) { + if (j > 0) { + writer.write(","); + } + writer.write(data.getLabels().getPrometheusName(j)); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getLabels().getValue(j)); + writer.write("\""); + } + if (!data.getLabels().isEmpty()) { + writer.write(","); } - writer.write("# TYPE "); writer.write(metadata.getPrometheusName()); - if (suffix != null) { - writer.write(suffix); + writer.write("=\""); + writeEscapedLabelValue(writer, data.getName(i)); + writer.write("\"} "); + if (data.isTrue(i)) { + writer.write("1"); + } else { + writer.write("0"); } - writer.write(' '); - writer.write(typeString); - writer.write('\n'); + writeScrapeTimestampAndNewline(writer, data); + } } + } - private void writeEscapedHelp(Writer writer, String s) throws IOException { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '\\': - writer.append("\\\\"); - break; - case '\n': - writer.append("\\n"); - break; - default: - writer.append(c); - } - } + private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot) + throws IOException { + MetricMetadata metadata = snapshot.getMetadata(); + writeMetadata(writer, "", "untyped", metadata); + for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) { + writeNameAndLabels(writer, metadata.getPrometheusName(), null, data.getLabels()); + writeDouble(writer, data.getValue()); + writeScrapeTimestampAndNewline(writer, data); } + } - private void writeScrapeTimestampAndNewline(OutputStreamWriter writer, DataPointSnapshot data) throws IOException { - if (data.hasScrapeTimestamp()) { - writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); - } - writer.write('\n'); + private void writeNameAndLabels( + OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException { + writeNameAndLabels(writer, name, suffix, labels, null, 0.0); + } + + private void writeNameAndLabels( + OutputStreamWriter writer, + String name, + String suffix, + Labels labels, + String additionalLabelName, + double additionalLabelValue) + throws IOException { + writer.write(name); + if (suffix != null) { + writer.write(suffix); + } + if (!labels.isEmpty() || additionalLabelName != null) { + writeLabels(writer, labels, additionalLabelName, additionalLabelValue); + } + writer.write(' '); + } + + private void writeMetadata( + OutputStreamWriter writer, String suffix, String typeString, MetricMetadata metadata) + throws IOException { + if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) { + writer.write("# HELP "); + writer.write(metadata.getPrometheusName()); + if (suffix != null) { + writer.write(suffix); + } + writer.write(' '); + writeEscapedHelp(writer, metadata.getHelp()); + writer.write('\n'); + } + writer.write("# TYPE "); + writer.write(metadata.getPrometheusName()); + if (suffix != null) { + writer.write(suffix); + } + writer.write(' '); + writer.write(typeString); + writer.write('\n'); + } + + private void writeEscapedHelp(Writer writer, String s) throws IOException { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\\': + writer.append("\\\\"); + break; + case '\n': + writer.append("\\n"); + break; + default: + writer.append(c); + } + } + } + + private void writeScrapeTimestampAndNewline(OutputStreamWriter writer, DataPointSnapshot data) + throws IOException { + if (data.hasScrapeTimestamp()) { + writer.write(' '); + writeTimestamp(writer, data.getScrapeTimestampMillis()); } + writer.write('\n'); + } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java index ad3a28828..fee5d8eb1 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java @@ -4,10 +4,10 @@ public class ProtobufUtil { - static Timestamp timestampFromMillis(long timestampMillis) { - return Timestamp.newBuilder() - .setSeconds(timestampMillis / 1000L) - .setNanos((int) (timestampMillis % 1000L * 1000000L)) - .build(); - } + static Timestamp timestampFromMillis(long timestampMillis) { + return Timestamp.newBuilder() + .setSeconds(timestampMillis / 1000L) + .setNanos((int) (timestampMillis % 1000L * 1000000L)) + .build(); + } } diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index 423fa6692..54daaaa3e 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -1,82 +1,84 @@ package io.prometheus.metrics.expositionformats; import io.prometheus.metrics.model.snapshots.Labels; - import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; - public class TextFormatUtil { - static void writeLong(OutputStreamWriter writer, long value) throws IOException { - writer.append(Long.toString(value)); - } + static void writeLong(OutputStreamWriter writer, long value) throws IOException { + writer.append(Long.toString(value)); + } - static void writeDouble(OutputStreamWriter writer, double d) throws IOException { - if (d == Double.POSITIVE_INFINITY) { - writer.write("+Inf"); - } else if (d == Double.NEGATIVE_INFINITY) { - writer.write("-Inf"); - } else { - writer.write(Double.toString(d)); - // FloatingDecimal.getBinaryToASCIIConverter(d).appendTo(writer); - } + static void writeDouble(OutputStreamWriter writer, double d) throws IOException { + if (d == Double.POSITIVE_INFINITY) { + writer.write("+Inf"); + } else if (d == Double.NEGATIVE_INFINITY) { + writer.write("-Inf"); + } else { + writer.write(Double.toString(d)); + // FloatingDecimal.getBinaryToASCIIConverter(d).appendTo(writer); } + } - static void writeTimestamp(OutputStreamWriter writer, long timestampMs) throws IOException { - writer.write(Long.toString(timestampMs / 1000L)); - writer.write("."); - long ms = timestampMs % 1000; - if (ms < 100) { - writer.write("0"); - } - if (ms < 10) { - writer.write("0"); - } - writer.write(Long.toString(ms)); + static void writeTimestamp(OutputStreamWriter writer, long timestampMs) throws IOException { + writer.write(Long.toString(timestampMs / 1000L)); + writer.write("."); + long ms = timestampMs % 1000; + if (ms < 100) { + writer.write("0"); } + if (ms < 10) { + writer.write("0"); + } + writer.write(Long.toString(ms)); + } - static void writeEscapedLabelValue(Writer writer, String s) throws IOException { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - switch (c) { - case '\\': - writer.append("\\\\"); - break; - case '\"': - writer.append("\\\""); - break; - case '\n': - writer.append("\\n"); - break; - default: - writer.append(c); - } - } + static void writeEscapedLabelValue(Writer writer, String s) throws IOException { + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '\\': + writer.append("\\\\"); + break; + case '\"': + writer.append("\\\""); + break; + case '\n': + writer.append("\\n"); + break; + default: + writer.append(c); + } } + } - static void writeLabels(OutputStreamWriter writer, Labels labels, String additionalLabelName, double additionalLabelValue) throws IOException { - writer.write('{'); - for (int i = 0; i < labels.size(); i++) { - if (i > 0) { - writer.write(","); - } - writer.write(labels.getPrometheusName(i)); - writer.write("=\""); - writeEscapedLabelValue(writer, labels.getValue(i)); - writer.write("\""); - } - if (additionalLabelName != null) { - if (!labels.isEmpty()) { - writer.write(","); - } - writer.write(additionalLabelName); - writer.write("=\""); - writeDouble(writer, additionalLabelValue); - writer.write("\""); - } - writer.write('}'); + static void writeLabels( + OutputStreamWriter writer, + Labels labels, + String additionalLabelName, + double additionalLabelValue) + throws IOException { + writer.write('{'); + for (int i = 0; i < labels.size(); i++) { + if (i > 0) { + writer.write(","); + } + writer.write(labels.getPrometheusName(i)); + writer.write("=\""); + writeEscapedLabelValue(writer, labels.getValue(i)); + writer.write("\""); + } + if (additionalLabelName != null) { + if (!labels.isEmpty()) { + writer.write(","); + } + writer.write(additionalLabelName); + writer.write("=\""); + writeDouble(writer, additionalLabelValue); + writer.write("\""); } + writer.write('}'); + } } diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 09600eafd..1ce3f2840 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -1,1938 +1,2766 @@ package io.prometheus.metrics.expositionformats; -import io.prometheus.metrics.model.snapshots.*; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.model.snapshots.*; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; -import org.junit.Assert; -import org.junit.Test; - +import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import java.io.ByteArrayOutputStream; import java.io.IOException; +import org.junit.Assert; +import org.junit.Test; public class ExpositionFormatsTest { - private final String exemplar1String = "{env=\"prod\",span_id=\"12345\",trace_id=\"abcde\"} 1.7 1672850685.829"; - private final String exemplar2String = "{env=\"dev\",span_id=\"23456\",trace_id=\"bcdef\"} 2.4 1672850685.830"; - private final String exemplarWithDotsString = "{some_exemplar_key=\"some value\"} 3.0 1690298864.383"; + private final String exemplar1String = + "{env=\"prod\",span_id=\"12345\",trace_id=\"abcde\"} 1.7 1672850685.829"; + private final String exemplar2String = + "{env=\"dev\",span_id=\"23456\",trace_id=\"bcdef\"} 2.4 1672850685.830"; + private final String exemplarWithDotsString = + "{some_exemplar_key=\"some value\"} 3.0 1690298864.383"; - private final String exemplar1protoString = "exemplar { " + - "label { name: \"env\" value: \"prod\" } " + - "label { name: \"span_id\" value: \"12345\" } " + - "label { name: \"trace_id\" value: \"abcde\" } " + - "value: 1.7 " + - "timestamp { seconds: 1672850685 nanos: 829000000 } }"; + private final String exemplar1protoString = + "exemplar { " + + "label { name: \"env\" value: \"prod\" } " + + "label { name: \"span_id\" value: \"12345\" } " + + "label { name: \"trace_id\" value: \"abcde\" } " + + "value: 1.7 " + + "timestamp { seconds: 1672850685 nanos: 829000000 } }"; - private final String exemplar2protoString = "exemplar { " + - "label { name: \"env\" value: \"dev\" } " + - "label { name: \"span_id\" value: \"23456\" } " + - "label { name: \"trace_id\" value: \"bcdef\" } " + - "value: 2.4 " + - "timestamp { seconds: 1672850685 nanos: 830000000 } }"; + private final String exemplar2protoString = + "exemplar { " + + "label { name: \"env\" value: \"dev\" } " + + "label { name: \"span_id\" value: \"23456\" } " + + "label { name: \"trace_id\" value: \"bcdef\" } " + + "value: 2.4 " + + "timestamp { seconds: 1672850685 nanos: 830000000 } }"; - private final String exemplarWithDotsProtoString = "exemplar { " + - "label { name: \"some_exemplar_key\" value: \"some value\" } " + - "value: 3.0 " + - "timestamp { seconds: 1690298864 nanos: 383000000 } }"; + private final String exemplarWithDotsProtoString = + "exemplar { " + + "label { name: \"some_exemplar_key\" value: \"some value\" } " + + "value: 3.0 " + + "timestamp { seconds: 1690298864 nanos: 383000000 } }"; - private final String createdTimestamp1s = "1672850385.800"; - private final long createdTimestamp1 = (long) (1000 * Double.parseDouble(createdTimestamp1s)); - private final String createdTimestamp2s = "1672850285.000"; - private final long createdTimestamp2 = (long) (1000 * Double.parseDouble(createdTimestamp2s)); - private final String scrapeTimestamp1s = "1672850685.829"; - private final long scrapeTimestamp1 = (long) (1000 * Double.parseDouble(scrapeTimestamp1s)); - private final String scrapeTimestamp2s = "1672850585.820"; - private final long scrapeTimestamp2 = (long) (1000 * Double.parseDouble(scrapeTimestamp2s)); + private final String createdTimestamp1s = "1672850385.800"; + private final long createdTimestamp1 = (long) (1000 * Double.parseDouble(createdTimestamp1s)); + private final String createdTimestamp2s = "1672850285.000"; + private final long createdTimestamp2 = (long) (1000 * Double.parseDouble(createdTimestamp2s)); + private final String scrapeTimestamp1s = "1672850685.829"; + private final long scrapeTimestamp1 = (long) (1000 * Double.parseDouble(scrapeTimestamp1s)); + private final String scrapeTimestamp2s = "1672850585.820"; + private final long scrapeTimestamp2 = (long) (1000 * Double.parseDouble(scrapeTimestamp2s)); - private final Exemplar exemplar1 = Exemplar.builder() - .spanId("12345") - .traceId("abcde") - .labels(Labels.of("env", "prod")) - .value(1.7) - .timestampMillis(1672850685829L) - .build(); + private final Exemplar exemplar1 = + Exemplar.builder() + .spanId("12345") + .traceId("abcde") + .labels(Labels.of("env", "prod")) + .value(1.7) + .timestampMillis(1672850685829L) + .build(); - private final Exemplar exemplar2 = Exemplar.builder() - .spanId("23456") - .traceId("bcdef") - .labels(Labels.of("env", "dev")) - .value(2.4) - .timestampMillis(1672850685830L) - .build(); + private final Exemplar exemplar2 = + Exemplar.builder() + .spanId("23456") + .traceId("bcdef") + .labels(Labels.of("env", "dev")) + .value(2.4) + .timestampMillis(1672850685830L) + .build(); - private final Exemplar exemplarWithDots = Exemplar.builder() - .labels(Labels.of("some.exemplar.key", "some value")) - .value(3.0) - .timestampMillis(1690298864383L) - .build(); + private final Exemplar exemplarWithDots = + Exemplar.builder() + .labels(Labels.of("some.exemplar.key", "some value")) + .value(3.0) + .timestampMillis(1690298864383L) + .build(); - @Test - public void testCounterComplete() throws IOException { - String openMetricsText = "" + - "# TYPE service_time_seconds counter\n" + - "# UNIT service_time_seconds seconds\n" + - "# HELP service_time_seconds total time spent serving\n" + - "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP service_time_seconds_total total time spent serving\n" + - "# TYPE service_time_seconds_total counter\n" + - "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + "\n" + - "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + "\n" + - "# HELP service_time_seconds_created total time spent serving\n" + - "# TYPE service_time_seconds_created gauge\n" + - "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; - String openMetricsTextWithoutCreated = "" + - "# TYPE service_time_seconds counter\n" + - "# UNIT service_time_seconds seconds\n" + - "# HELP service_time_seconds total time spent serving\n" + - "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "# EOF\n"; - String prometheusTextWithoutCreated = "" + - "# HELP service_time_seconds_total total time spent serving\n" + - "# TYPE service_time_seconds_total counter\n" + - "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s + "\n" + - "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"service_time_seconds_total\" " + - "help: \"total time spent serving\" " + - "type: COUNTER " + - "metric { " + - "label { name: \"path\" value: \"/hello\" } " + - "label { name: \"status\" value: \"200\" } " + - "counter { " + - "value: 0.8 " + - exemplar1protoString + " " + - "} " + - "timestamp_ms: 1672850685829 " + - "} " + - "metric { " + - "label { name: \"path\" value: \"/hello\" } " + - "label { name: \"status\" value: \"500\" } " + - "counter { " + - "value: 0.9 " + - exemplar2protoString + " " + - "} " + - "timestamp_ms: 1672850585820 " + - "}"; - //@formatter:on + @Test + public void testCounterComplete() throws IOException { + String openMetricsText = + "" + + "# TYPE service_time_seconds counter\n" + + "# UNIT service_time_seconds seconds\n" + + "# HELP service_time_seconds total time spent serving\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP service_time_seconds_total total time spent serving\n" + + "# TYPE service_time_seconds_total counter\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + + scrapeTimestamp1s + + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + + scrapeTimestamp2s + + "\n" + + "# HELP service_time_seconds_created total time spent serving\n" + + "# TYPE service_time_seconds_created gauge\n" + + "service_time_seconds_created{path=\"/hello\",status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "service_time_seconds_created{path=\"/hello\",status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n"; + String openMetricsTextWithoutCreated = + "" + + "# TYPE service_time_seconds counter\n" + + "# UNIT service_time_seconds seconds\n" + + "# HELP service_time_seconds total time spent serving\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = + "" + + "# HELP service_time_seconds_total total time spent serving\n" + + "# TYPE service_time_seconds_total counter\n" + + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + + scrapeTimestamp1s + + "\n" + + "service_time_seconds_total{path=\"/hello\",status=\"500\"} 0.9 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"service_time_seconds_total\" " + + "help: \"total time spent serving\" " + + "type: COUNTER " + + "metric { " + + "label { name: \"path\" value: \"/hello\" } " + + "label { name: \"status\" value: \"200\" } " + + "counter { " + + "value: 0.8 " + + exemplar1protoString + + " " + + "} " + + "timestamp_ms: 1672850685829 " + + "} " + + "metric { " + + "label { name: \"path\" value: \"/hello\" } " + + "label { name: \"status\" value: \"500\" } " + + "counter { " + + "value: 0.9 " + + exemplar2protoString + + " " + + "} " + + "timestamp_ms: 1672850585820 " + + "}"; + // @formatter:on - CounterSnapshot counter = CounterSnapshot.builder() - .name("service_time_seconds") - .help("total time spent serving") - .unit(Unit.SECONDS) - .dataPoint(CounterDataPointSnapshot.builder() - .value(0.8) - .labels(Labels.builder() - .label("path", "/hello") - .label("status", "200") - .build()) - .exemplar(exemplar1) - .createdTimestampMillis(createdTimestamp1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .dataPoint(CounterDataPointSnapshot.builder() - .value(0.9) - .labels(Labels.builder() - .label("path", "/hello") - .label("status", "500") - .build()) - .exemplar(exemplar2) - .createdTimestampMillis(createdTimestamp2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, counter); - assertPrometheusText(prometheusText, counter); - assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, counter); - assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, counter); - assertPrometheusProtobuf(prometheusProtobuf, counter); - } + CounterSnapshot counter = + CounterSnapshot.builder() + .name("service_time_seconds") + .help("total time spent serving") + .unit(Unit.SECONDS) + .dataPoint( + CounterDataPointSnapshot.builder() + .value(0.8) + .labels(Labels.builder().label("path", "/hello").label("status", "200").build()) + .exemplar(exemplar1) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .dataPoint( + CounterDataPointSnapshot.builder() + .value(0.9) + .labels(Labels.builder().label("path", "/hello").label("status", "500").build()) + .exemplar(exemplar2) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, counter); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } - @Test - public void testCounterMinimal() throws IOException { - String openMetricsText = "" + - "# TYPE my_counter counter\n" + - "my_counter_total 1.1\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE my_counter_total counter\n" + - "my_counter_total 1.1\n"; - String prometheusProtobuf = "" + - "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; - CounterSnapshot counter = CounterSnapshot.builder() - .name("my_counter") - .dataPoint(CounterDataPointSnapshot.builder().value(1.1).build()) - .build(); - assertOpenMetricsText(openMetricsText, counter); - assertPrometheusText(prometheusText, counter); - assertOpenMetricsTextWithoutCreated(openMetricsText, counter); - assertPrometheusTextWithoutCreated(prometheusText, counter); - assertPrometheusProtobuf(prometheusProtobuf, counter); - } + @Test + public void testCounterMinimal() throws IOException { + String openMetricsText = + "" + "# TYPE my_counter counter\n" + "my_counter_total 1.1\n" + "# EOF\n"; + String prometheusText = "" + "# TYPE my_counter_total counter\n" + "my_counter_total 1.1\n"; + String prometheusProtobuf = + "" + "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; + CounterSnapshot counter = + CounterSnapshot.builder() + .name("my_counter") + .dataPoint(CounterDataPointSnapshot.builder().value(1.1).build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertOpenMetricsTextWithoutCreated(openMetricsText, counter); + assertPrometheusTextWithoutCreated(prometheusText, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } - @Test - public void testCounterWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_request_count counter\n" + - "my_request_count_total{http_path=\"/hello\"} 3.0 # " + exemplarWithDotsString + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE my_request_count_total counter\n" + - "my_request_count_total{http_path=\"/hello\"} 3.0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_request_count_total\" " + - "type: COUNTER " + - "metric { " + - "label { name: \"http_path\" value: \"/hello\" } " + - "counter { " + - "value: 3.0 " + exemplarWithDotsProtoString + " " + - "} " + - "}"; - //@formatter:on + @Test + public void testCounterWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_request_count counter\n" + + "my_request_count_total{http_path=\"/hello\"} 3.0 # " + + exemplarWithDotsString + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE my_request_count_total counter\n" + + "my_request_count_total{http_path=\"/hello\"} 3.0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_request_count_total\" " + + "type: COUNTER " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "counter { " + + "value: 3.0 " + + exemplarWithDotsProtoString + + " " + + "} " + + "}"; + // @formatter:on - CounterSnapshot counter = CounterSnapshot.builder() - .name("my.request.count") - .dataPoint(CounterDataPointSnapshot.builder() - .value(3.0) - .labels(Labels.builder() - .label("http.path", "/hello") - .build()) - .exemplar(exemplarWithDots) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, counter); - assertPrometheusText(prometheusText, counter); - assertPrometheusProtobuf(prometheusProtobuf, counter); - } + CounterSnapshot counter = + CounterSnapshot.builder() + .name("my.request.count") + .dataPoint( + CounterDataPointSnapshot.builder() + .value(3.0) + .labels(Labels.builder().label("http.path", "/hello").build()) + .exemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, counter); + assertPrometheusText(prometheusText, counter); + assertPrometheusProtobuf(prometheusProtobuf, counter); + } - @Test - public void testGaugeComplete() throws IOException { - String openMetricsText = "" + - "# TYPE disk_usage_ratio gauge\n" + - "# UNIT disk_usage_ratio ratio\n" + - "# HELP disk_usage_ratio percentage used\n" + - "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + "\n" + - "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE disk_usage_ratio gauge\n" + - "# UNIT disk_usage_ratio ratio\n" + - "# HELP disk_usage_ratio percentage used\n" + - "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP disk_usage_ratio percentage used\n" + - "# TYPE disk_usage_ratio gauge\n" + - "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s + "\n" + - "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"disk_usage_ratio\" " + - "help: \"percentage used\" " + - "type: GAUGE " + - "metric { " + - "label { name: \"device\" value: \"/dev/sda1\" } " + - "gauge { value: 0.2 } " + - "timestamp_ms: 1672850685829 " + - "} metric { " + - "label { name: \"device\" value: \"/dev/sda2\" } " + - "gauge { value: 0.7 } " + - "timestamp_ms: 1672850585820 " + - "}"; - //@formatter:on - GaugeSnapshot gauge = GaugeSnapshot.builder() - .name("disk_usage_ratio") - .help("percentage used") - .unit(new Unit("ratio")) - .dataPoint(GaugeDataPointSnapshot.builder() - .value(0.7) - .labels(Labels.builder() - .label("device", "/dev/sda2") - .build()) - .exemplar(exemplar2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(GaugeDataPointSnapshot.builder() - .value(0.2) - .labels(Labels.builder() - .label("device", "/dev/sda1") - .build()) - .exemplar(exemplar1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gauge); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gauge); - assertPrometheusText(prometheusText, gauge); - assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); - assertPrometheusTextWithoutCreated(prometheusText, gauge); - assertPrometheusProtobuf(prometheusProtobuf, gauge); - } + @Test + public void testGaugeComplete() throws IOException { + String openMetricsText = + "" + + "# TYPE disk_usage_ratio gauge\n" + + "# UNIT disk_usage_ratio ratio\n" + + "# HELP disk_usage_ratio percentage used\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + + scrapeTimestamp1s + + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE disk_usage_ratio gauge\n" + + "# UNIT disk_usage_ratio ratio\n" + + "# HELP disk_usage_ratio percentage used\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP disk_usage_ratio percentage used\n" + + "# TYPE disk_usage_ratio gauge\n" + + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + + scrapeTimestamp1s + + "\n" + + "disk_usage_ratio{device=\"/dev/sda2\"} 0.7 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"disk_usage_ratio\" " + + "help: \"percentage used\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"device\" value: \"/dev/sda1\" } " + + "gauge { value: 0.2 } " + + "timestamp_ms: 1672850685829 " + + "} metric { " + + "label { name: \"device\" value: \"/dev/sda2\" } " + + "gauge { value: 0.7 } " + + "timestamp_ms: 1672850585820 " + + "}"; + // @formatter:on + GaugeSnapshot gauge = + GaugeSnapshot.builder() + .name("disk_usage_ratio") + .help("percentage used") + .unit(new Unit("ratio")) + .dataPoint( + GaugeDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.builder().label("device", "/dev/sda2").build()) + .exemplar(exemplar2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + GaugeDataPointSnapshot.builder() + .value(0.2) + .labels(Labels.builder().label("device", "/dev/sda1").build()) + .exemplar(exemplar1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, gauge); + assertPrometheusText(prometheusText, gauge); + assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); + assertPrometheusTextWithoutCreated(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } - @Test - public void testGaugeMinimal() throws IOException { - String openMetricsText = "" + - "# TYPE temperature_centigrade gauge\n" + - "temperature_centigrade 22.3\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE temperature_centigrade gauge\n" + - "temperature_centigrade 22.3\n"; - String prometheusProtobuf = "" + - "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; - GaugeSnapshot gauge = GaugeSnapshot.builder() - .name("temperature_centigrade") - .dataPoint(GaugeDataPointSnapshot.builder() - .value(22.3) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gauge); - assertPrometheusText(prometheusText, gauge); - assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); - assertPrometheusTextWithoutCreated(prometheusText, gauge); - assertPrometheusProtobuf(prometheusProtobuf, gauge); - } + @Test + public void testGaugeMinimal() throws IOException { + String openMetricsText = + "" + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n" + "# EOF\n"; + String prometheusText = + "" + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n"; + String prometheusProtobuf = + "" + "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; + GaugeSnapshot gauge = + GaugeSnapshot.builder() + .name("temperature_centigrade") + .dataPoint(GaugeDataPointSnapshot.builder().value(22.3).build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertPrometheusText(prometheusText, gauge); + assertOpenMetricsTextWithoutCreated(openMetricsText, gauge); + assertPrometheusTextWithoutCreated(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } - @Test - public void testGaugeWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_temperature_celsius gauge\n" + - "# UNIT my_temperature_celsius celsius\n" + - "# HELP my_temperature_celsius Temperature\n" + - "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE my_temperature_celsius gauge\n" + - "# UNIT my_temperature_celsius celsius\n" + - "# HELP my_temperature_celsius Temperature\n" + - "my_temperature_celsius{location_id=\"data-center-1\"} 23.0 # " + exemplarWithDotsString + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP my_temperature_celsius Temperature\n" + - "# TYPE my_temperature_celsius gauge\n" + - "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_temperature_celsius\" " + - "help: \"Temperature\" " + - "type: GAUGE " + - "metric { " + - "label { name: \"location_id\" value: \"data-center-1\" } " + - "gauge { " + - "value: 23.0 " + - "} " + - "}"; - //@formatter:on + @Test + public void testGaugeWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_temperature_celsius gauge\n" + + "# UNIT my_temperature_celsius celsius\n" + + "# HELP my_temperature_celsius Temperature\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE my_temperature_celsius gauge\n" + + "# UNIT my_temperature_celsius celsius\n" + + "# HELP my_temperature_celsius Temperature\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0 # " + + exemplarWithDotsString + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP my_temperature_celsius Temperature\n" + + "# TYPE my_temperature_celsius gauge\n" + + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_temperature_celsius\" " + + "help: \"Temperature\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"location_id\" value: \"data-center-1\" } " + + "gauge { " + + "value: 23.0 " + + "} " + + "}"; + // @formatter:on - GaugeSnapshot gauge = GaugeSnapshot.builder() - .name("my.temperature.celsius") - .help("Temperature") - .unit(Unit.CELSIUS) - .dataPoint(GaugeDataPointSnapshot.builder() - .value(23.0) - .labels(Labels.builder() - .label("location.id", "data-center-1") - .build()) - .exemplar(exemplarWithDots) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gauge); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gauge); - assertPrometheusText(prometheusText, gauge); - assertPrometheusProtobuf(prometheusProtobuf, gauge); - } + GaugeSnapshot gauge = + GaugeSnapshot.builder() + .name("my.temperature.celsius") + .help("Temperature") + .unit(Unit.CELSIUS) + .dataPoint( + GaugeDataPointSnapshot.builder() + .value(23.0) + .labels(Labels.builder().label("location.id", "data-center-1").build()) + .exemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gauge); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, gauge); + assertPrometheusText(prometheusText, gauge); + assertPrometheusProtobuf(prometheusProtobuf, gauge); + } - @Test - public void testSummaryComplete() throws IOException { - String openMetricsText = "" + - "# TYPE http_request_duration_seconds summary\n" + - "# UNIT http_request_duration_seconds seconds\n" + - "# HELP http_request_duration_seconds request duration\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE http_request_duration_seconds summary\n" + - "# UNIT http_request_duration_seconds seconds\n" + - "# HELP http_request_duration_seconds request duration\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP http_request_duration_seconds request duration\n" + - "# TYPE http_request_duration_seconds summary\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + - "# HELP http_request_duration_seconds_created request duration\n" + - "# TYPE http_request_duration_seconds_created gauge\n" + - "http_request_duration_seconds_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; - String openMetricsTextWithoutCreated = "" + - "# TYPE http_request_duration_seconds summary\n" + - "# UNIT http_request_duration_seconds seconds\n" + - "# HELP http_request_duration_seconds request duration\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusTextWithoutCreated = "" + - "# HELP http_request_duration_seconds request duration\n" + - "# TYPE http_request_duration_seconds summary\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + scrapeTimestamp1s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_count{status=\"500\"} 7 " + scrapeTimestamp2s + "\n" + - "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"http_request_duration_seconds\" " + - "help: \"request duration\" " + - "type: SUMMARY " + - "metric { " + - "label { name: \"status\" value: \"200\" } " + - "summary { " + - "sample_count: 3 " + - "sample_sum: 1.2 " + - "quantile { quantile: 0.5 value: 225.3 } " + - "quantile { quantile: 0.9 value: 240.7 } " + - "quantile { quantile: 0.95 value: 245.1 } " + - "} " + - "timestamp_ms: 1672850685829 " + - "} metric { " + - "label { name: \"status\" value: \"500\" } " + - "summary { " + - "sample_count: 7 " + - "sample_sum: 2.2 " + - "quantile { quantile: 0.5 value: 225.3 } " + - "quantile { quantile: 0.9 value: 240.7 } " + - "quantile { quantile: 0.95 value: 245.1 } " + - "} " + "" + - "timestamp_ms: 1672850585820 " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("http_request_duration_seconds") - .help("request duration") - .unit(Unit.SECONDS) - .dataPoint(SummaryDataPointSnapshot.builder() - .count(7) - .sum(2.2) - .quantiles(Quantiles.builder() - .quantile(0.5, 225.3) - .quantile(0.9, 240.7) - .quantile(0.95, 245.1) - .build()) - .labels(Labels.builder() - .label("status", "500") - .build()) - .exemplars(Exemplars.of(exemplar2)) - .createdTimestampMillis(createdTimestamp2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(SummaryDataPointSnapshot.builder() - .count(3) - .sum(1.2) - .quantiles(Quantiles.builder() - .quantile(0.5, 225.3) - .quantile(0.9, 240.7) - .quantile(0.95, 245.1) - .build()) - .labels(Labels.builder() - .label("status", "200") - .build()) - .exemplars(Exemplars.of(exemplar1)) - .createdTimestampMillis(createdTimestamp1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, summary); - assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryComplete() throws IOException { + String openMetricsText = + "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP http_request_duration_seconds request duration\n" + + "# TYPE http_request_duration_seconds summary\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + + scrapeTimestamp2s + + "\n" + + "# HELP http_request_duration_seconds_created request duration\n" + + "# TYPE http_request_duration_seconds_created gauge\n" + + "http_request_duration_seconds_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n"; + String openMetricsTextWithoutCreated = + "" + + "# TYPE http_request_duration_seconds summary\n" + + "# UNIT http_request_duration_seconds seconds\n" + + "# HELP http_request_duration_seconds request duration\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = + "" + + "# HELP http_request_duration_seconds request duration\n" + + "# TYPE http_request_duration_seconds summary\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"200\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds_sum{status=\"200\"} 1.2 " + + scrapeTimestamp1s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.5\"} 225.3 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.9\"} 240.7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds{status=\"500\",quantile=\"0.95\"} 245.1 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_count{status=\"500\"} 7 " + + scrapeTimestamp2s + + "\n" + + "http_request_duration_seconds_sum{status=\"500\"} 2.2 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"http_request_duration_seconds\" " + + "help: \"request duration\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "summary { " + + "sample_count: 3 " + + "sample_sum: 1.2 " + + "quantile { quantile: 0.5 value: 225.3 } " + + "quantile { quantile: 0.9 value: 240.7 } " + + "quantile { quantile: 0.95 value: 245.1 } " + + "} " + + "timestamp_ms: 1672850685829 " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "summary { " + + "sample_count: 7 " + + "sample_sum: 2.2 " + + "quantile { quantile: 0.5 value: 225.3 } " + + "quantile { quantile: 0.9 value: 240.7 } " + + "quantile { quantile: 0.95 value: 245.1 } " + + "} " + + "" + + "timestamp_ms: 1672850585820 " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("http_request_duration_seconds") + .help("request duration") + .unit(Unit.SECONDS) + .dataPoint( + SummaryDataPointSnapshot.builder() + .count(7) + .sum(2.2) + .quantiles( + Quantiles.builder() + .quantile(0.5, 225.3) + .quantile(0.9, 240.7) + .quantile(0.95, 245.1) + .build()) + .labels(Labels.builder().label("status", "500").build()) + .exemplars(Exemplars.of(exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + SummaryDataPointSnapshot.builder() + .count(3) + .sum(1.2) + .quantiles( + Quantiles.builder() + .quantile(0.5, 225.3) + .quantile(0.9, 240.7) + .quantile(0.95, 245.1) + .build()) + .labels(Labels.builder().label("status", "200").build()) + .exemplars(Exemplars.of(exemplar1)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, summary); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryWithoutQuantiles() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds summary\n" + - "# UNIT latency_seconds seconds\n" + - "# HELP latency_seconds latency\n" + - "latency_seconds_count 3\n" + - "latency_seconds_sum 1.2\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP latency_seconds latency\n" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_count 3\n" + - "latency_seconds_sum 1.2\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "help: \"latency\" " + - "type: SUMMARY " + - "metric { " + - "summary { " + - "sample_count: 3 " + - "sample_sum: 1.2 " + - "} " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .help("latency") - .unit(Unit.SECONDS) - .dataPoint(SummaryDataPointSnapshot.builder() - .count(3) - .sum(1.2) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsText, summary); - assertPrometheusTextWithoutCreated(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryWithoutQuantiles() throws IOException { + String openMetricsText = + "" + + "# TYPE latency_seconds summary\n" + + "# UNIT latency_seconds seconds\n" + + "# HELP latency_seconds latency\n" + + "latency_seconds_count 3\n" + + "latency_seconds_sum 1.2\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP latency_seconds latency\n" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count 3\n" + + "latency_seconds_sum 1.2\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "help: \"latency\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_count: 3 " + + "sample_sum: 1.2 " + + "} " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .help("latency") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder().count(3).sum(1.2).build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryNoCountAndSum() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds{quantile=\"0.95\"} 200.0\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds{quantile=\"0.95\"} 200.0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "type: SUMMARY " + - "metric { " + - "summary { " + - "quantile { quantile: 0.95 value: 200.0 } " + - "} " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .dataPoint(SummaryDataPointSnapshot.builder() - .quantiles(Quantiles.builder().quantile(0.95, 200.0).build()) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsText, summary); - assertPrometheusTextWithoutCreated(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryNoCountAndSum() throws IOException { + String openMetricsText = + "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds{quantile=\"0.95\"} 200.0\n" + + "# EOF\n"; + String prometheusText = + "" + "# TYPE latency_seconds summary\n" + "latency_seconds{quantile=\"0.95\"} 200.0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "quantile { quantile: 0.95 value: 200.0 } " + + "} " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint( + SummaryDataPointSnapshot.builder() + .quantiles(Quantiles.builder().quantile(0.95, 200.0).build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryJustCount() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_count 1\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_count 1\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "type: SUMMARY " + - "metric { " + - "summary { " + - "sample_count: 1 " + - "} " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .dataPoint(SummaryDataPointSnapshot.builder() - .count(1) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsText, summary); - assertPrometheusTextWithoutCreated(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryJustCount() throws IOException { + String openMetricsText = + "" + "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n" + "# EOF\n"; + String prometheusText = "" + "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_count: 1 " + + "} " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder().count(1).build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryJustSum() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_sum 12.3\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_sum 12.3\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "type: SUMMARY " + - "metric { " + - "summary { " + - "sample_sum: 12.3 " + - "} " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .dataPoint(SummaryDataPointSnapshot.builder() - .sum(12.3) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsText, summary); - assertPrometheusTextWithoutCreated(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryJustSum() throws IOException { + String openMetricsText = + "" + "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n" + "# EOF\n"; + String prometheusText = "" + "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "summary { " + + "sample_sum: 12.3 " + + "} " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder().sum(12.3).build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryEmptyData() throws IOException { - // SummaryData can be present but empty (no count, no sum, no quantiles). - // This should be treated like no data is present. - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .help("latency") - .unit(Unit.SECONDS) - .dataPoint(SummaryDataPointSnapshot.builder().build()) - .build(); - assertOpenMetricsText("# EOF\n", summary); - assertPrometheusText("", summary); - assertOpenMetricsTextWithoutCreated("# EOF\n", summary); - assertPrometheusTextWithoutCreated("", summary); - assertPrometheusProtobuf("", summary); - } + @Test + public void testSummaryEmptyData() throws IOException { + // SummaryData can be present but empty (no count, no sum, no quantiles). + // This should be treated like no data is present. + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .help("latency") + .unit(Unit.SECONDS) + .dataPoint(SummaryDataPointSnapshot.builder().build()) + .build(); + assertOpenMetricsText("# EOF\n", summary); + assertPrometheusText("", summary); + assertOpenMetricsTextWithoutCreated("# EOF\n", summary); + assertPrometheusTextWithoutCreated("", summary); + assertPrometheusProtobuf("", summary); + } - @Test - public void testSummaryEmptyAndNonEmpty() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_count{path=\"/v2\"} 2\n" + - "latency_seconds_sum{path=\"/v2\"} 10.7\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE latency_seconds summary\n" + - "latency_seconds_count{path=\"/v2\"} 2\n" + - "latency_seconds_sum{path=\"/v2\"} 10.7\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "type: SUMMARY " + - "metric { " + - "label { name: \"path\" value: \"/v2\" } " + - "summary { " + - "sample_count: 2 " + - "sample_sum: 10.7 " + - "} " + - "}"; - //@formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("latency_seconds") - .dataPoint(SummaryDataPointSnapshot.builder() - .labels(Labels.of("path", "/v1")) - .build()) - .dataPoint(SummaryDataPointSnapshot.builder() - .labels(Labels.of("path", "/v2")) - .count(2) - .sum(10.7) - .build()) - .dataPoint(SummaryDataPointSnapshot.builder() - .labels(Labels.of("path", "/v3")) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertPrometheusText(prometheusText, summary); - assertOpenMetricsTextWithoutCreated(openMetricsText, summary); - assertPrometheusTextWithoutCreated(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + @Test + public void testSummaryEmptyAndNonEmpty() throws IOException { + String openMetricsText = + "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count{path=\"/v2\"} 2\n" + + "latency_seconds_sum{path=\"/v2\"} 10.7\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE latency_seconds summary\n" + + "latency_seconds_count{path=\"/v2\"} 2\n" + + "latency_seconds_sum{path=\"/v2\"} 10.7\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"path\" value: \"/v2\" } " + + "summary { " + + "sample_count: 2 " + + "sample_sum: 10.7 " + + "} " + + "}"; + // @formatter:on + SummarySnapshot summary = + SummarySnapshot.builder() + .name("latency_seconds") + .dataPoint(SummaryDataPointSnapshot.builder().labels(Labels.of("path", "/v1")).build()) + .dataPoint( + SummaryDataPointSnapshot.builder() + .labels(Labels.of("path", "/v2")) + .count(2) + .sum(10.7) + .build()) + .dataPoint(SummaryDataPointSnapshot.builder().labels(Labels.of("path", "/v3")).build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertPrometheusText(prometheusText, summary); + assertOpenMetricsTextWithoutCreated(openMetricsText, summary); + assertPrometheusTextWithoutCreated(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testSummaryWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_request_duration_seconds summary\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE my_request_duration_seconds summary\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 1 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "# TYPE my_request_duration_seconds summary\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_request_duration_seconds\" " + - "help: \"Request duration in seconds\" " + - "type: SUMMARY " + - "metric { " + - "label { name: \"http_path\" value: \"/hello\" } " + - "summary { sample_count: 1 sample_sum: 0.03 } " + - "}"; - //@formatter:on + @Test + public void testSummaryWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_request_duration_seconds summary\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE my_request_duration_seconds summary\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds summary\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: SUMMARY " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "summary { sample_count: 1 sample_sum: 0.03 } " + + "}"; + // @formatter:on - SummarySnapshot summary = SummarySnapshot.builder() - .name("my.request.duration.seconds") - .help("Request duration in seconds") - .unit(Unit.SECONDS) - .dataPoint(SummaryDataPointSnapshot.builder() - .count(1) - .sum(0.03) - .labels(Labels.builder() - .label("http.path", "/hello") - .build()) - .exemplars(Exemplars.of(exemplarWithDots)) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, summary); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, summary); - assertPrometheusText(prometheusText, summary); - assertPrometheusProtobuf(prometheusProtobuf, summary); - } + SummarySnapshot summary = + SummarySnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint( + SummaryDataPointSnapshot.builder() + .count(1) + .sum(0.03) + .labels(Labels.builder().label("http.path", "/hello").build()) + .exemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, summary); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, summary); + assertPrometheusText(prometheusText, summary); + assertPrometheusProtobuf(prometheusProtobuf, summary); + } - @Test - public void testClassicHistogramComplete() throws Exception { - String openMetricsText = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP response_size_bytes help\n" + - "# TYPE response_size_bytes histogram\n" + - "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "# HELP response_size_bytes_created help\n" + - "# TYPE response_size_bytes_created gauge\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; - String openMetricsTextWithoutCreated = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusTextWithoutCreated = "" + - "# HELP response_size_bytes help\n" + - "# TYPE response_size_bytes histogram\n" + - "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_count{status=\"200\"} 3 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.1 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_count{status=\"500\"} 5 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"response_size_bytes\" " + - "help: \"help\" " + - "type: HISTOGRAM " + - "metric { " + - "label { name: \"status\" value: \"200\" } " + - "timestamp_ms: 1672850685829 " + - "histogram { " + - "sample_count: 3 " + - "sample_sum: 4.1 " + - "bucket { " + - "cumulative_count: 2 " + - "upper_bound: 2.2 " + - exemplar1protoString + " " + - "} bucket { " + - "cumulative_count: 3 " + - "upper_bound: Infinity " + - exemplar2protoString + " " + - "} " + - "} " + - "} metric { " + - "label { name: \"status\" value: \"500\" } " + - "timestamp_ms: 1672850585820 " + - "histogram { " + - "sample_count: 5 " + - "sample_sum: 3.2 " + - "bucket { " + - "cumulative_count: 3 " + - "upper_bound: 1.0 " + - "} bucket { " + - "cumulative_count: 5 " + - "upper_bound: 2.2 " + - exemplar1protoString + " " + - "} bucket { " + - "cumulative_count: 5 " + - "upper_bound: Infinity " + - exemplar2protoString + " " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.builder() - .name("response_size_bytes") - .help("help") - .unit(Unit.BYTES) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(3.2) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(1.0, 3) - .bucket(2.2, 2) - .bucket(Double.POSITIVE_INFINITY, 0) - .build()) - .labels(Labels.of("status", "500")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(4.1) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(2.2, 2) - .bucket(Double.POSITIVE_INFINITY, 1) - .build()) - .labels(Labels.of("status", "200")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, histogram); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); - assertPrometheusText(prometheusText, histogram); - assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, histogram); - assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, histogram); - assertPrometheusProtobuf(prometheusProtobuf, histogram); - } + @Test + public void testClassicHistogramComplete() throws Exception { + String openMetricsText = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "# HELP response_size_bytes_created help\n" + + "# TYPE response_size_bytes_created gauge\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n"; + String openMetricsTextWithoutCreated = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = + "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_count{status=\"200\"} 3 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.1 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"1.0\"} 3 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"2.2\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_count{status=\"500\"} 5 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"response_size_bytes\" " + + "help: \"help\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 3 " + + "sample_sum: 4.1 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: 2.2 " + + exemplar1protoString + + " " + + "} bucket { " + + "cumulative_count: 3 " + + "upper_bound: Infinity " + + exemplar2protoString + + " " + + "} " + + "} " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 5 " + + "sample_sum: 3.2 " + + "bucket { " + + "cumulative_count: 3 " + + "upper_bound: 1.0 " + + "} bucket { " + + "cumulative_count: 5 " + + "upper_bound: 2.2 " + + exemplar1protoString + + " " + + "} bucket { " + + "cumulative_count: 5 " + + "upper_bound: Infinity " + + exemplar2protoString + + " " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot histogram = + HistogramSnapshot.builder() + .name("response_size_bytes") + .help("help") + .unit(Unit.BYTES) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(1.0, 3) + .bucket(2.2, 2) + .bucket(Double.POSITIVE_INFINITY, 0) + .build()) + .labels(Labels.of("status", "500")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(4.1) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(2.2, 2) + .bucket(Double.POSITIVE_INFINITY, 1) + .build()) + .labels(Labels.of("status", "200")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, histogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } - @Test - public void testClassicHistogramMinimal() throws Exception { - // In OpenMetrics a histogram can have a _count if and only if it has a _sum. - // In Prometheus format, a histogram can have a _count without a _sum. - String openMetricsText = "" + - "# TYPE request_latency_seconds histogram\n" + - "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE request_latency_seconds histogram\n" + - "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + - "request_latency_seconds_count 2\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"request_latency_seconds\" " + - "type: HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 2 " + - "bucket { " + - "cumulative_count: 2 " + - "upper_bound: Infinity " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.builder() - .name("request_latency_seconds") - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 2) - .build()) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, histogram); - assertPrometheusText(prometheusText, histogram); - assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); - assertPrometheusTextWithoutCreated(prometheusText, histogram); - assertPrometheusProtobuf(prometheusProtobuf, histogram); - } + @Test + public void testClassicHistogramMinimal() throws Exception { + // In OpenMetrics a histogram can have a _count if and only if it has a _sum. + // In Prometheus format, a histogram can have a _count without a _sum. + String openMetricsText = + "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"request_latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 2 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot histogram = + HistogramSnapshot.builder() + .name("request_latency_seconds") + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 2) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); + assertPrometheusTextWithoutCreated(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } - @Test - public void testClassicHistogramCountAndSum() throws Exception { - String openMetricsText = "" + - "# TYPE request_latency_seconds histogram\n" + - "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + - "request_latency_seconds_count 2\n" + - "request_latency_seconds_sum 3.2\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE request_latency_seconds histogram\n" + - "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + - "request_latency_seconds_count 2\n" + - "request_latency_seconds_sum 3.2\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"request_latency_seconds\" " + - "type: HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 2 " + - "sample_sum: 3.2 " + - "bucket { " + - "cumulative_count: 2 " + - "upper_bound: Infinity " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot histogram = HistogramSnapshot.builder() - .name("request_latency_seconds") - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(3.2) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 2) - .build()) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, histogram); - assertPrometheusText(prometheusText, histogram); - assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); - assertPrometheusTextWithoutCreated(prometheusText, histogram); - assertPrometheusProtobuf(prometheusProtobuf, histogram); - } + @Test + public void testClassicHistogramCountAndSum() throws Exception { + String openMetricsText = + "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n" + + "request_latency_seconds_sum 3.2\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE request_latency_seconds histogram\n" + + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + + "request_latency_seconds_count 2\n" + + "request_latency_seconds_sum 3.2\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"request_latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 2 " + + "sample_sum: 3.2 " + + "bucket { " + + "cumulative_count: 2 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot histogram = + HistogramSnapshot.builder() + .name("request_latency_seconds") + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 2) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertPrometheusText(prometheusText, histogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, histogram); + assertPrometheusTextWithoutCreated(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } - @Test - public void testClassicGaugeHistogramComplete() throws IOException { - String openMetricsText = "" + - "# TYPE cache_size_bytes gaugehistogram\n" + - "# UNIT cache_size_bytes bytes\n" + - "# HELP cache_size_bytes number of bytes in the cache\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE cache_size_bytes gaugehistogram\n" + - "# UNIT cache_size_bytes bytes\n" + - "# HELP cache_size_bytes number of bytes in the cache\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP cache_size_bytes number of bytes in the cache\n" + - "# TYPE cache_size_bytes histogram\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + "\n" + - "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + - "# TYPE cache_size_bytes_gcount gauge\n" + - "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + - "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + - "# TYPE cache_size_bytes_gsum gauge\n" + - "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + - "# HELP cache_size_bytes_created number of bytes in the cache\n" + - "# TYPE cache_size_bytes_created gauge\n" + - "cache_size_bytes_created{db=\"items\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_created{db=\"options\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; - String openMetricsTextWithoutCreated = "" + - "# TYPE cache_size_bytes gaugehistogram\n" + - "# UNIT cache_size_bytes bytes\n" + - "# HELP cache_size_bytes number of bytes in the cache\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + " # " + exemplar1String + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusTextWithoutCreated = "" + - "# HELP cache_size_bytes number of bytes in the cache\n" + - "# TYPE cache_size_bytes histogram\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + scrapeTimestamp2s + "\n" + - "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + scrapeTimestamp2s + "\n" + - "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + - "# TYPE cache_size_bytes_gcount gauge\n" + - "cache_size_bytes_gcount{db=\"items\"} 4 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gcount{db=\"options\"} 4 " + scrapeTimestamp2s + "\n" + - "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + - "# TYPE cache_size_bytes_gsum gauge\n" + - "cache_size_bytes_gsum{db=\"items\"} 17.0 " + scrapeTimestamp1s + "\n" + - "cache_size_bytes_gsum{db=\"options\"} 18.0 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"cache_size_bytes\" " + - "help: \"number of bytes in the cache\" " + - "type: GAUGE_HISTOGRAM " + - "metric { " + - "label { name: \"db\" value: \"items\" } " + - "timestamp_ms: 1672850685829 " + - "histogram { " + - "sample_count: 4 " + - "sample_sum: 17.0 " + - "bucket { " + - "cumulative_count: 3 " + - "upper_bound: 2.0 " + - exemplar1protoString + " " + - "} bucket { " + - "cumulative_count: 4 " + - "upper_bound: Infinity " + - exemplar2protoString + " " + - "} " + - "} " + - "} metric { " + - "label { name: \"db\" value: \"options\" } " + - "timestamp_ms: 1672850585820 " + - "histogram { " + - "sample_count: 4 " + - "sample_sum: 18.0 " + - "bucket { " + - "cumulative_count: 4 " + - "upper_bound: 2.0 " + - exemplar1protoString + " " + - "} bucket { " + - "cumulative_count: 4 " + - "upper_bound: Infinity " + - exemplar2protoString + " " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram(true) - .name("cache_size_bytes") - .help("number of bytes in the cache") - .unit(Unit.BYTES) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(17) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(2.0, 3) - .bucket(Double.POSITIVE_INFINITY, 1) - .build()) - .labels(Labels.of("db", "items")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(18) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(2.0, 4) - .bucket(Double.POSITIVE_INFINITY, 0) - .build() - ) - .labels(Labels.of("db", "options")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gaugeHistogram); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, gaugeHistogram); - assertPrometheusText(prometheusText, gaugeHistogram); - assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, gaugeHistogram); - assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, gaugeHistogram); - assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); - } + @Test + public void testClassicGaugeHistogramComplete() throws IOException { + String openMetricsText = + "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_created{db=\"items\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_created{db=\"options\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_created{db=\"items\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_created{db=\"options\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "# TYPE cache_size_bytes histogram\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + + scrapeTimestamp2s + + "\n" + + "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gcount gauge\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + + scrapeTimestamp2s + + "\n" + + "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gsum gauge\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + + scrapeTimestamp2s + + "\n" + + "# HELP cache_size_bytes_created number of bytes in the cache\n" + + "# TYPE cache_size_bytes_created gauge\n" + + "cache_size_bytes_created{db=\"items\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_created{db=\"options\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n"; + String openMetricsTextWithoutCreated = + "" + + "# TYPE cache_size_bytes gaugehistogram\n" + + "# UNIT cache_size_bytes bytes\n" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar1String + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = + "" + + "# HELP cache_size_bytes number of bytes in the cache\n" + + "# TYPE cache_size_bytes histogram\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"items\",le=\"+Inf\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"2.0\"} 4 " + + scrapeTimestamp2s + + "\n" + + "cache_size_bytes_bucket{db=\"options\",le=\"+Inf\"} 4 " + + scrapeTimestamp2s + + "\n" + + "# HELP cache_size_bytes_gcount number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gcount gauge\n" + + "cache_size_bytes_gcount{db=\"items\"} 4 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gcount{db=\"options\"} 4 " + + scrapeTimestamp2s + + "\n" + + "# HELP cache_size_bytes_gsum number of bytes in the cache\n" + + "# TYPE cache_size_bytes_gsum gauge\n" + + "cache_size_bytes_gsum{db=\"items\"} 17.0 " + + scrapeTimestamp1s + + "\n" + + "cache_size_bytes_gsum{db=\"options\"} 18.0 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"cache_size_bytes\" " + + "help: \"number of bytes in the cache\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "label { name: \"db\" value: \"items\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 17.0 " + + "bucket { " + + "cumulative_count: 3 " + + "upper_bound: 2.0 " + + exemplar1protoString + + " " + + "} bucket { " + + "cumulative_count: 4 " + + "upper_bound: Infinity " + + exemplar2protoString + + " " + + "} " + + "} " + + "} metric { " + + "label { name: \"db\" value: \"options\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 18.0 " + + "bucket { " + + "cumulative_count: 4 " + + "upper_bound: 2.0 " + + exemplar1protoString + + " " + + "} bucket { " + + "cumulative_count: 4 " + + "upper_bound: Infinity " + + exemplar2protoString + + " " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot gaugeHistogram = + HistogramSnapshot.builder() + .gaugeHistogram(true) + .name("cache_size_bytes") + .help("number of bytes in the cache") + .unit(Unit.BYTES) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(17) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(2.0, 3) + .bucket(Double.POSITIVE_INFINITY, 1) + .build()) + .labels(Labels.of("db", "items")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(18) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(2.0, 4) + .bucket(Double.POSITIVE_INFINITY, 0) + .build()) + .labels(Labels.of("db", "options")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } - @Test - public void testClassicGaugeHistogramMinimal() throws IOException { - // In OpenMetrics a histogram can have a _count if and only if it has a _sum. - // In Prometheus format, a histogram can have a _count without a _sum. - String openMetricsText = "" + - "# TYPE queue_size_bytes gaugehistogram\n" + - "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE queue_size_bytes histogram\n" + - "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + - "# TYPE queue_size_bytes_gcount gauge\n" + - "queue_size_bytes_gcount 130\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"queue_size_bytes\" " + - "type: GAUGE_HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 130 " + - "bucket { " + - "cumulative_count: 130 " + - "upper_bound: Infinity " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram(true) - .name("queue_size_bytes") - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 130) - .build()) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gaugeHistogram); - assertPrometheusText(prometheusText, gaugeHistogram); - assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); - assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); - assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); - } + @Test + public void testClassicGaugeHistogramMinimal() throws IOException { + // In OpenMetrics a histogram can have a _count if and only if it has a _sum. + // In Prometheus format, a histogram can have a _count without a _sum. + String openMetricsText = + "" + + "# TYPE queue_size_bytes gaugehistogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE queue_size_bytes histogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# TYPE queue_size_bytes_gcount gauge\n" + + "queue_size_bytes_gcount 130\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"queue_size_bytes\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 130 " + + "bucket { " + + "cumulative_count: 130 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot gaugeHistogram = + HistogramSnapshot.builder() + .gaugeHistogram(true) + .name("queue_size_bytes") + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } - @Test - public void testClassicGaugeHistogramCountAndSum() throws IOException { - String openMetricsText = "" + - "# TYPE queue_size_bytes gaugehistogram\n" + - "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + - "queue_size_bytes_gcount 130\n" + - "queue_size_bytes_gsum 27000.0\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE queue_size_bytes histogram\n" + - "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + - "# TYPE queue_size_bytes_gcount gauge\n" + - "queue_size_bytes_gcount 130\n" + - "# TYPE queue_size_bytes_gsum gauge\n" + - "queue_size_bytes_gsum 27000.0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"queue_size_bytes\" " + - "type: GAUGE_HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 130 " + - "sample_sum: 27000.0 " + - "bucket { " + - "cumulative_count: 130 " + - "upper_bound: Infinity " + - "} " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder() - .gaugeHistogram(true) - .name("queue_size_bytes") - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(27000) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 130) - .build()) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, gaugeHistogram); - assertPrometheusText(prometheusText, gaugeHistogram); - assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); - assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); - assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); - } + @Test + public void testClassicGaugeHistogramCountAndSum() throws IOException { + String openMetricsText = + "" + + "# TYPE queue_size_bytes gaugehistogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "queue_size_bytes_gcount 130\n" + + "queue_size_bytes_gsum 27000.0\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE queue_size_bytes histogram\n" + + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + + "# TYPE queue_size_bytes_gcount gauge\n" + + "queue_size_bytes_gcount 130\n" + + "# TYPE queue_size_bytes_gsum gauge\n" + + "queue_size_bytes_gsum 27000.0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"queue_size_bytes\" " + + "type: GAUGE_HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 130 " + + "sample_sum: 27000.0 " + + "bucket { " + + "cumulative_count: 130 " + + "upper_bound: Infinity " + + "} " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot gaugeHistogram = + HistogramSnapshot.builder() + .gaugeHistogram(true) + .name("queue_size_bytes") + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(27000) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) + .build()) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, gaugeHistogram); + assertPrometheusText(prometheusText, gaugeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsText, gaugeHistogram); + assertPrometheusTextWithoutCreated(prometheusText, gaugeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, gaugeHistogram); + } - @Test - public void testClassicHistogramWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_request_duration_seconds histogram\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE my_request_duration_seconds histogram\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 130 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "# TYPE my_request_duration_seconds histogram\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_request_duration_seconds\" " + - "help: \"Request duration in seconds\" " + - "type: HISTOGRAM " + - "metric { " + - "label { name: \"http_path\" value: \"/hello\" } " + - "histogram { " + - "sample_count: 130 " + - "sample_sum: 0.01 " + - "bucket { cumulative_count: 130 upper_bound: Infinity " + exemplarWithDotsProtoString + " } " + - "} " + - "}"; - //@formatter:on + @Test + public void testClassicHistogramWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds histogram\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "histogram { " + + "sample_count: 130 " + + "sample_sum: 0.01 " + + "bucket { cumulative_count: 130 upper_bound: Infinity " + + exemplarWithDotsProtoString + + " } " + + "} " + + "}"; + // @formatter:on - HistogramSnapshot histogram = HistogramSnapshot.builder() - .name("my.request.duration.seconds") - .help("Request duration in seconds") - .unit(Unit.SECONDS) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(0.01) - .labels(Labels.builder() - .label("http.path", "/hello") - .build()) - .classicHistogramBuckets(ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 130) - .build()) - .exemplars(Exemplars.of(exemplarWithDots)) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, histogram); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); - assertPrometheusText(prometheusText, histogram); - assertPrometheusProtobuf(prometheusProtobuf, histogram); - } + HistogramSnapshot histogram = + HistogramSnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(0.01) + .labels(Labels.builder().label("http.path", "/hello").build()) + .classicHistogramBuckets( + ClassicHistogramBuckets.builder() + .bucket(Double.POSITIVE_INFINITY, 130) + .build()) + .exemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, histogram); + assertPrometheusText(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } - @Test - public void testNativeHistogramComplete() throws IOException { - String openMetricsText = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP response_size_bytes help\n" + - "# TYPE response_size_bytes histogram\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "# HELP response_size_bytes_created help\n" + - "# TYPE response_size_bytes_created gauge\n" + - "response_size_bytes_created{status=\"200\"} " + createdTimestamp1s + " " + scrapeTimestamp1s + "\n" + - "response_size_bytes_created{status=\"500\"} " + createdTimestamp2s + " " + scrapeTimestamp2s + "\n"; - String openMetricsTextWithoutCreated = "" + - "# TYPE response_size_bytes histogram\n" + - "# UNIT response_size_bytes bytes\n" + - "# HELP response_size_bytes help\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheusTextWithoutCreated = "" + - "# HELP response_size_bytes help\n" + - "# TYPE response_size_bytes histogram\n" + - "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_count{status=\"200\"} 2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_sum{status=\"200\"} 4.2 " + scrapeTimestamp1s + "\n" + - "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_count{status=\"500\"} 55 " + scrapeTimestamp2s + "\n" + - "response_size_bytes_sum{status=\"500\"} 3.2 " + scrapeTimestamp2s + "\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"response_size_bytes\" " + - "help: \"help\" " + - "type: HISTOGRAM " + - "metric { " + - "label { name: \"status\" value: \"200\" } " + - "timestamp_ms: 1672850685829 " + - "histogram { " + - "sample_count: 2 " + - "sample_sum: 4.2 " + - "bucket { cumulative_count: 2 upper_bound: Infinity " + exemplar2protoString + " } " + - "schema: 5 " + - "zero_threshold: 0.0 " + - "zero_count: 0 " + - "positive_span { offset: 0 length: 1 } " + - "positive_delta: 2 " + - "} " + - "} metric { " + - "label { name: \"status\" value: \"500\" } " + - "timestamp_ms: 1672850585820 " + - "histogram { " + - "sample_count: 55 " + // bucket counts + zero count - "sample_sum: 3.2 " + - "bucket { cumulative_count: 55 upper_bound: Infinity " + exemplar2protoString + " } " + - "schema: 5 " + - "zero_threshold: 0.0 " + - "zero_count: 1 " + - "negative_span { offset: 0 length: 1 } " + - "negative_span { offset: 9 length: 1 } " + - "negative_delta: 1 " + - "negative_delta: -1 " + // span with count 0 - "positive_span { offset: 2 length: 3 } " + // span with 3 buckets (indexes 2-4) - "positive_span { offset: 7 length: 1 } " + // span with 1 bucket (index 12) - "positive_span { offset: 9 length: 4 } " + // span with gap of size 1 (indexes 22-25) - "positive_span { offset: 6 length: 5 } " + // span with gap of size 2 (indexes 32-36) - "positive_span { offset: 4 length: 2 } " + // span with gap of size 3 part 1 (indexes 41-42) - "positive_span { offset: 3 length: 2 } " + // span with gap of size 3 part 2 (indexes 46-47) - "positive_delta: 3 " + // index 2, count 3 - "positive_delta: 2 " + // index 3, count 5 - "positive_delta: -1 " + // index 4, count 4 - "positive_delta: 2 " + // index 12, count 6 - "positive_delta: -4 " + // index 22, count 2 - "positive_delta: -2 " + // index 23, gap - "positive_delta: 1 " + // index 24, count 1 - "positive_delta: 2 " + // index 25, count 3 - "positive_delta: 1 " + // index 32, count 4 - "positive_delta: -1 " + // index 33, count 3 - "positive_delta: -3 " + // index 34, gap - "positive_delta: 0 " + // index 35, gap - "positive_delta: 7 " + // index 36, count 7 - "positive_delta: -4 " + // index 41, count 3 - "positive_delta: 6 " + // index 42, count 9 - "positive_delta: -7 " + // index 46, count 2 - "positive_delta: -1 " + // index 47, count 1 - "} " + - "}"; - //@formatter:on - HistogramSnapshot nativeHistogram = HistogramSnapshot.builder() - .name("response_size_bytes") - .help("help") - .unit(Unit.BYTES) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(3.2) - .nativeSchema(5) - .nativeZeroCount(1) - .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() - // span with 3 buckets - .bucket(2, 3) - .bucket(3, 5) - .bucket(4, 4) - // span with just 1 bucket - .bucket(12, 6) - // span with gap of size 1 - .bucket(22, 2) - .bucket(24, 1) - .bucket(25, 3) - // span with gap of size 2 - .bucket(32, 4) - .bucket(33, 3) - .bucket(36, 7) - // span with gap of size 3 - .bucket(41, 3) - .bucket(42, 9) - .bucket(46, 2) - .bucket(47, 1) - .build()) - .nativeBucketsForNegativeValues(NativeHistogramBuckets.builder() - .bucket(0, 1) - .bucket(10, 0) // bucket with count 0 - .build()) - .labels(Labels.of("status", "500")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .sum(4.2) - .nativeSchema(5) - .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() - .bucket(0, 2) - .build()) - .labels(Labels.of("status", "200")) - .exemplars(Exemplars.of(exemplar1, exemplar2)) - .createdTimestampMillis(createdTimestamp1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, nativeHistogram); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, nativeHistogram); - assertPrometheusText(prometheusText, nativeHistogram); - assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, nativeHistogram); - assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, nativeHistogram); - assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); - } + @Test + public void testNativeHistogramComplete() throws IOException { + String openMetricsText = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "# HELP response_size_bytes_created help\n" + + "# TYPE response_size_bytes_created gauge\n" + + "response_size_bytes_created{status=\"200\"} " + + createdTimestamp1s + + " " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_created{status=\"500\"} " + + createdTimestamp2s + + " " + + scrapeTimestamp2s + + "\n"; + String openMetricsTextWithoutCreated = + "" + + "# TYPE response_size_bytes histogram\n" + + "# UNIT response_size_bytes bytes\n" + + "# HELP response_size_bytes help\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + + scrapeTimestamp1s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheusTextWithoutCreated = + "" + + "# HELP response_size_bytes help\n" + + "# TYPE response_size_bytes histogram\n" + + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_count{status=\"200\"} 2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_sum{status=\"200\"} 4.2 " + + scrapeTimestamp1s + + "\n" + + "response_size_bytes_bucket{status=\"500\",le=\"+Inf\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_count{status=\"500\"} 55 " + + scrapeTimestamp2s + + "\n" + + "response_size_bytes_sum{status=\"500\"} 3.2 " + + scrapeTimestamp2s + + "\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"response_size_bytes\" " + + "help: \"help\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"status\" value: \"200\" } " + + "timestamp_ms: 1672850685829 " + + "histogram { " + + "sample_count: 2 " + + "sample_sum: 4.2 " + + "bucket { cumulative_count: 2 upper_bound: Infinity " + + exemplar2protoString + + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "positive_span { offset: 0 length: 1 } " + + "positive_delta: 2 " + + "} " + + "} metric { " + + "label { name: \"status\" value: \"500\" } " + + "timestamp_ms: 1672850585820 " + + "histogram { " + + "sample_count: 55 " + + // bucket counts + zero count + "sample_sum: 3.2 " + + "bucket { cumulative_count: 55 upper_bound: Infinity " + + exemplar2protoString + + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "negative_span { offset: 0 length: 1 } " + + "negative_span { offset: 9 length: 1 } " + + "negative_delta: 1 " + + "negative_delta: -1 " + + // span with count 0 + "positive_span { offset: 2 length: 3 } " + + // span with 3 buckets (indexes 2-4) + "positive_span { offset: 7 length: 1 } " + + // span with 1 bucket (index 12) + "positive_span { offset: 9 length: 4 } " + + // span with gap of size 1 (indexes 22-25) + "positive_span { offset: 6 length: 5 } " + + // span with gap of size 2 (indexes 32-36) + "positive_span { offset: 4 length: 2 } " + + // span with gap of size 3 part 1 (indexes 41-42) + "positive_span { offset: 3 length: 2 } " + + // span with gap of size 3 part 2 (indexes 46-47) + "positive_delta: 3 " + + // index 2, count 3 + "positive_delta: 2 " + + // index 3, count 5 + "positive_delta: -1 " + + // index 4, count 4 + "positive_delta: 2 " + + // index 12, count 6 + "positive_delta: -4 " + + // index 22, count 2 + "positive_delta: -2 " + + // index 23, gap + "positive_delta: 1 " + + // index 24, count 1 + "positive_delta: 2 " + + // index 25, count 3 + "positive_delta: 1 " + + // index 32, count 4 + "positive_delta: -1 " + + // index 33, count 3 + "positive_delta: -3 " + + // index 34, gap + "positive_delta: 0 " + + // index 35, gap + "positive_delta: 7 " + + // index 36, count 7 + "positive_delta: -4 " + + // index 41, count 3 + "positive_delta: 6 " + + // index 42, count 9 + "positive_delta: -7 " + + // index 46, count 2 + "positive_delta: -1 " + + // index 47, count 1 + "} " + + "}"; + // @formatter:on + HistogramSnapshot nativeHistogram = + HistogramSnapshot.builder() + .name("response_size_bytes") + .help("help") + .unit(Unit.BYTES) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(3.2) + .nativeSchema(5) + .nativeZeroCount(1) + .nativeBucketsForPositiveValues( + NativeHistogramBuckets.builder() + // span with 3 buckets + .bucket(2, 3) + .bucket(3, 5) + .bucket(4, 4) + // span with just 1 bucket + .bucket(12, 6) + // span with gap of size 1 + .bucket(22, 2) + .bucket(24, 1) + .bucket(25, 3) + // span with gap of size 2 + .bucket(32, 4) + .bucket(33, 3) + .bucket(36, 7) + // span with gap of size 3 + .bucket(41, 3) + .bucket(42, 9) + .bucket(46, 2) + .bucket(47, 1) + .build()) + .nativeBucketsForNegativeValues( + NativeHistogramBuckets.builder() + .bucket(0, 1) + .bucket(10, 0) // bucket with count 0 + .build()) + .labels(Labels.of("status", "500")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .sum(4.2) + .nativeSchema(5) + .nativeBucketsForPositiveValues( + NativeHistogramBuckets.builder().bucket(0, 2).build()) + .labels(Labels.of("status", "200")) + .exemplars(Exemplars.of(exemplar1, exemplar2)) + .createdTimestampMillis(createdTimestamp1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, nativeHistogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, nativeHistogram); + assertPrometheusText(prometheusText, nativeHistogram); + assertOpenMetricsTextWithoutCreated(openMetricsTextWithoutCreated, nativeHistogram); + assertPrometheusTextWithoutCreated(prometheusTextWithoutCreated, nativeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); + } - @Test - public void testNativeHistogramMinimal() throws IOException { - String openMetricsText = "" + - "# TYPE latency_seconds histogram\n" + - "latency_seconds_bucket{le=\"+Inf\"} 0\n" + - "# EOF\n"; - String prometheusText = "" + - "# TYPE latency_seconds histogram\n" + - "latency_seconds_bucket{le=\"+Inf\"} 0\n" + - "latency_seconds_count 0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"latency_seconds\" " + - "type: HISTOGRAM " + - "metric { " + - "histogram { " + - "sample_count: 0 " + - "schema: 5 " + - "zero_threshold: 0.0 " + - "zero_count: 0 " + - "} " + - "}"; - //@formatter:on - HistogramSnapshot nativeHistogram = HistogramSnapshot.builder() - .name("latency_seconds") - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .nativeSchema(5) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, nativeHistogram); - assertPrometheusText(prometheusText, nativeHistogram); - assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); - } + @Test + public void testNativeHistogramMinimal() throws IOException { + String openMetricsText = + "" + + "# TYPE latency_seconds histogram\n" + + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + + "# EOF\n"; + String prometheusText = + "" + + "# TYPE latency_seconds histogram\n" + + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + + "latency_seconds_count 0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"latency_seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "histogram { " + + "sample_count: 0 " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 0 " + + "} " + + "}"; + // @formatter:on + HistogramSnapshot nativeHistogram = + HistogramSnapshot.builder() + .name("latency_seconds") + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder().nativeSchema(5).build()) + .build(); + assertOpenMetricsText(openMetricsText, nativeHistogram); + assertPrometheusText(prometheusText, nativeHistogram); + assertPrometheusProtobuf(prometheusProtobuf, nativeHistogram); + } - @Test - public void testNativeHistogramWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_request_duration_seconds histogram\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + - "# EOF\n"; - String openMetricsTextWithExemplarsOnAllTimeSeries = "" + - "# TYPE my_request_duration_seconds histogram\n" + - "# UNIT my_request_duration_seconds seconds\n" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 4 # " + exemplarWithDotsString + "\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP my_request_duration_seconds Request duration in seconds\n" + - "# TYPE my_request_duration_seconds histogram\n" + - "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4\n" + - "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + - "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_request_duration_seconds\" " + - "help: \"Request duration in seconds\" " + - "type: HISTOGRAM " + - "metric { " + - "label { name: \"http_path\" value: \"/hello\" } " + - "histogram { " + - "sample_count: 4 " + - "sample_sum: 3.2 " + - "bucket { cumulative_count: 4 upper_bound: Infinity " + exemplarWithDotsProtoString + " } " + - "schema: 5 " + - "zero_threshold: 0.0 " + - "zero_count: 1 " + - "positive_span { offset: 2 length: 1 } " + - "positive_delta: 3 " + - "} " + - "}"; - //@formatter:on + @Test + public void testNativeHistogramWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + + "# EOF\n"; + String openMetricsTextWithExemplarsOnAllTimeSeries = + "" + + "# TYPE my_request_duration_seconds histogram\n" + + "# UNIT my_request_duration_seconds seconds\n" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4 # " + + exemplarWithDotsString + + "\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP my_request_duration_seconds Request duration in seconds\n" + + "# TYPE my_request_duration_seconds histogram\n" + + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4\n" + + "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_request_duration_seconds\" " + + "help: \"Request duration in seconds\" " + + "type: HISTOGRAM " + + "metric { " + + "label { name: \"http_path\" value: \"/hello\" } " + + "histogram { " + + "sample_count: 4 " + + "sample_sum: 3.2 " + + "bucket { cumulative_count: 4 upper_bound: Infinity " + + exemplarWithDotsProtoString + + " } " + + "schema: 5 " + + "zero_threshold: 0.0 " + + "zero_count: 1 " + + "positive_span { offset: 2 length: 1 } " + + "positive_delta: 3 " + + "} " + + "}"; + // @formatter:on - HistogramSnapshot histogram = HistogramSnapshot.builder() - .name("my.request.duration.seconds") - .help("Request duration in seconds") - .unit(Unit.SECONDS) - .dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder() - .labels(Labels.builder() - .label("http.path", "/hello") - .build()) - .sum(3.2) - .nativeSchema(5) - .nativeZeroCount(1) - .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder() - .bucket(2, 3) - .build() - ) - .exemplars(Exemplars.of(exemplarWithDots)) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, histogram); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsTextWithExemplarsOnAllTimeSeries, histogram); - assertPrometheusText(prometheusText, histogram); - assertPrometheusProtobuf(prometheusProtobuf, histogram); - } - // TODO: Gauge Native Histogram + HistogramSnapshot histogram = + HistogramSnapshot.builder() + .name("my.request.duration.seconds") + .help("Request duration in seconds") + .unit(Unit.SECONDS) + .dataPoint( + HistogramSnapshot.HistogramDataPointSnapshot.builder() + .labels(Labels.builder().label("http.path", "/hello").build()) + .sum(3.2) + .nativeSchema(5) + .nativeZeroCount(1) + .nativeBucketsForPositiveValues( + NativeHistogramBuckets.builder().bucket(2, 3).build()) + .exemplars(Exemplars.of(exemplarWithDots)) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, histogram); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsTextWithExemplarsOnAllTimeSeries, histogram); + assertPrometheusText(prometheusText, histogram); + assertPrometheusProtobuf(prometheusProtobuf, histogram); + } - @Test - public void testInfo() throws IOException { - String openMetrics = "" + - "# TYPE version info\n" + - "# HELP version version information\n" + - "version_info{version=\"1.2.3\"} 1\n" + - "# EOF\n"; - String prometheus = "" + - "# HELP version_info version information\n" + - "# TYPE version_info gauge\n" + - "version_info{version=\"1.2.3\"} 1\n"; - InfoSnapshot info = InfoSnapshot.builder() - .name("version") - .help("version information") - .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() - .labels(Labels.of("version", "1.2.3")) - .build()) - .build(); - assertOpenMetricsText(openMetrics, info); - assertPrometheusText(prometheus, info); - assertOpenMetricsTextWithoutCreated(openMetrics, info); - assertPrometheusTextWithoutCreated(prometheus, info); - } + // TODO: Gauge Native Histogram - @Test - public void testInfoWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE jvm_status info\n" + - "# HELP jvm_status JVM status info\n" + - "jvm_status_info{jvm_version=\"1.2.3\"} 1\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP jvm_status_info JVM status info\n" + - "# TYPE jvm_status_info gauge\n" + - "jvm_status_info{jvm_version=\"1.2.3\"} 1\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"jvm_status_info\" " + - "help: \"JVM status info\" " + - "type: GAUGE " + - "metric { " + "" + - "label { name: \"jvm_version\" value: \"1.2.3\" } " + - "gauge { value: 1.0 } " + - "}"; - //@formatter:on - InfoSnapshot info = InfoSnapshot.builder() - .name("jvm.status") - .help("JVM status info") - .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() - .labels(Labels.of("jvm.version", "1.2.3")) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, info); - assertPrometheusText(prometheusText, info); - assertPrometheusProtobuf(prometheusProtobuf, info); - } + @Test + public void testInfo() throws IOException { + String openMetrics = + "" + + "# TYPE version info\n" + + "# HELP version version information\n" + + "version_info{version=\"1.2.3\"} 1\n" + + "# EOF\n"; + String prometheus = + "" + + "# HELP version_info version information\n" + + "# TYPE version_info gauge\n" + + "version_info{version=\"1.2.3\"} 1\n"; + InfoSnapshot info = + InfoSnapshot.builder() + .name("version") + .help("version information") + .dataPoint( + InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("version", "1.2.3")) + .build()) + .build(); + assertOpenMetricsText(openMetrics, info); + assertPrometheusText(prometheus, info); + assertOpenMetricsTextWithoutCreated(openMetrics, info); + assertPrometheusTextWithoutCreated(prometheus, info); + } - @Test - public void testStateSetComplete() throws IOException { - String openMetrics = "" + - "# TYPE state stateset\n" + - "# HELP state complete state set example\n" + - "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s + "\n" + - "state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" + - "state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" + - "state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String prometheus = "" + - "# HELP state complete state set example\n" + - "# TYPE state gauge\n" + - "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s + "\n" + - "state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" + - "state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" + - "state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n"; - StateSetSnapshot stateSet = StateSetSnapshot.builder() - .name("state") - .help("complete state set example") - .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() - .labels(Labels.of("env", "prod")) - .state("state1", false) - .state("state2", true) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() - .labels(Labels.of("env", "dev")) - .state("state2", false) - .state("state1", true) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetrics, stateSet); - assertPrometheusText(prometheus, stateSet); - assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); - assertPrometheusTextWithoutCreated(prometheus, stateSet); - } + @Test + public void testInfoWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE jvm_status info\n" + + "# HELP jvm_status JVM status info\n" + + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP jvm_status_info JVM status info\n" + + "# TYPE jvm_status_info gauge\n" + + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"jvm_status_info\" " + + "help: \"JVM status info\" " + + "type: GAUGE " + + "metric { " + + "" + + "label { name: \"jvm_version\" value: \"1.2.3\" } " + + "gauge { value: 1.0 } " + + "}"; + // @formatter:on + InfoSnapshot info = + InfoSnapshot.builder() + .name("jvm.status") + .help("JVM status info") + .dataPoint( + InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("jvm.version", "1.2.3")) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, info); + assertPrometheusText(prometheusText, info); + assertPrometheusProtobuf(prometheusProtobuf, info); + } - @Test - public void testStateSetMinimal() throws IOException { - String openMetrics = "" + - "# TYPE state stateset\n" + - "state{state=\"a\"} 1\n" + - "state{state=\"bb\"} 0\n" + - "# EOF\n"; - String prometheus = "" + - "# TYPE state gauge\n" + - "state{state=\"a\"} 1\n" + - "state{state=\"bb\"} 0\n"; - StateSetSnapshot stateSet = StateSetSnapshot.builder() - .name("state") - .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() - .state("a", true) - .state("bb", false) - .build()) - .build(); - assertOpenMetricsText(openMetrics, stateSet); - assertPrometheusText(prometheus, stateSet); - assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); - assertPrometheusTextWithoutCreated(prometheus, stateSet); - } + @Test + public void testStateSetComplete() throws IOException { + String openMetrics = + "" + + "# TYPE state stateset\n" + + "# HELP state complete state set example\n" + + "state{env=\"dev\",state=\"state1\"} 1 " + + scrapeTimestamp1s + + "\n" + + "state{env=\"dev\",state=\"state2\"} 0 " + + scrapeTimestamp1s + + "\n" + + "state{env=\"prod\",state=\"state1\"} 0 " + + scrapeTimestamp2s + + "\n" + + "state{env=\"prod\",state=\"state2\"} 1 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String prometheus = + "" + + "# HELP state complete state set example\n" + + "# TYPE state gauge\n" + + "state{env=\"dev\",state=\"state1\"} 1 " + + scrapeTimestamp1s + + "\n" + + "state{env=\"dev\",state=\"state2\"} 0 " + + scrapeTimestamp1s + + "\n" + + "state{env=\"prod\",state=\"state1\"} 0 " + + scrapeTimestamp2s + + "\n" + + "state{env=\"prod\",state=\"state2\"} 1 " + + scrapeTimestamp2s + + "\n"; + StateSetSnapshot stateSet = + StateSetSnapshot.builder() + .name("state") + .help("complete state set example") + .dataPoint( + StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("env", "prod")) + .state("state1", false) + .state("state2", true) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("env", "dev")) + .state("state2", false) + .state("state1", true) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetrics, stateSet); + assertPrometheusText(prometheus, stateSet); + assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); + assertPrometheusTextWithoutCreated(prometheus, stateSet); + } - @Test - public void testStateSetWithDots() throws IOException { - String openMetricsText = "" + - "# TYPE my_application_state stateset\n" + - "# HELP my_application_state My application state\n" + - "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + - "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n" + - "# EOF\n"; - String prometheusText = "" + - "# HELP my_application_state My application state\n" + - "# TYPE my_application_state gauge\n" + - "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + - "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"my_application_state\" " + - "help: \"My application state\" " + - "type: GAUGE " + - "metric { " + - "label { name: \"data_center\" value: \"us east\" } " + - "label { name: \"my_application_state\" value: \"feature.enabled\" } " + - "gauge { value: 1.0 } " + - "} metric { " + - "label { name: \"data_center\" value: \"us east\" } " + - "label { name: \"my_application_state\" value: \"is.alpha.version\" } " + - "gauge { value: 0.0 } " + - "}"; - //@formatter:on - StateSetSnapshot stateSet = StateSetSnapshot.builder() - .name("my.application.state") - .help("My application state") - .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder() - .labels(Labels.of("data.center", "us east")) - .state("feature.enabled", true) - .state("is.alpha.version", false) - .build()) - .build(); - assertOpenMetricsText(openMetricsText, stateSet); - assertPrometheusText(prometheusText, stateSet); - assertPrometheusProtobuf(prometheusProtobuf, stateSet); - } + @Test + public void testStateSetMinimal() throws IOException { + String openMetrics = + "" + + "# TYPE state stateset\n" + + "state{state=\"a\"} 1\n" + + "state{state=\"bb\"} 0\n" + + "# EOF\n"; + String prometheus = + "" + "# TYPE state gauge\n" + "state{state=\"a\"} 1\n" + "state{state=\"bb\"} 0\n"; + StateSetSnapshot stateSet = + StateSetSnapshot.builder() + .name("state") + .dataPoint( + StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("a", true) + .state("bb", false) + .build()) + .build(); + assertOpenMetricsText(openMetrics, stateSet); + assertPrometheusText(prometheus, stateSet); + assertOpenMetricsTextWithoutCreated(openMetrics, stateSet); + assertPrometheusTextWithoutCreated(prometheus, stateSet); + } - @Test - public void testUnknownComplete() throws IOException { - String openMetrics = "" + - "# TYPE my_special_thing_bytes unknown\n" + - "# UNIT my_special_thing_bytes bytes\n" + - "# HELP my_special_thing_bytes help message\n" + - "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" + - "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n" + - "# EOF\n"; - String openMetricsWithExemplarsOnAllTimeSeries = "" + - "# TYPE my_special_thing_bytes unknown\n" + - "# UNIT my_special_thing_bytes bytes\n" + - "# HELP my_special_thing_bytes help message\n" + - "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + " # " + exemplar1String + "\n" + - "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + " # " + exemplar2String + "\n" + - "# EOF\n"; - String prometheus = "" + - "# HELP my_special_thing_bytes help message\n" + - "# TYPE my_special_thing_bytes untyped\n" + - "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" + - "my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n"; - UnknownSnapshot unknown = UnknownSnapshot.builder() - .name("my_special_thing_bytes") - .help("help message") - .unit(Unit.BYTES) - .dataPoint(UnknownDataPointSnapshot.builder() - .value(0.7) - .labels(Labels.of("env", "prod")) - .exemplar(exemplar2) - .scrapeTimestampMillis(scrapeTimestamp2) - .build()) - .dataPoint(UnknownDataPointSnapshot.builder() - .value(0.2) - .labels(Labels.of("env", "dev")) - .exemplar(exemplar1) - .scrapeTimestampMillis(scrapeTimestamp1) - .build()) - .build(); - assertOpenMetricsText(openMetrics, unknown); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsWithExemplarsOnAllTimeSeries, unknown); - assertPrometheusText(prometheus, unknown); - assertOpenMetricsTextWithoutCreated(openMetrics, unknown); - assertPrometheusTextWithoutCreated(prometheus, unknown); - } + @Test + public void testStateSetWithDots() throws IOException { + String openMetricsText = + "" + + "# TYPE my_application_state stateset\n" + + "# HELP my_application_state My application state\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n" + + "# EOF\n"; + String prometheusText = + "" + + "# HELP my_application_state My application state\n" + + "# TYPE my_application_state gauge\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"my_application_state\" " + + "help: \"My application state\" " + + "type: GAUGE " + + "metric { " + + "label { name: \"data_center\" value: \"us east\" } " + + "label { name: \"my_application_state\" value: \"feature.enabled\" } " + + "gauge { value: 1.0 } " + + "} metric { " + + "label { name: \"data_center\" value: \"us east\" } " + + "label { name: \"my_application_state\" value: \"is.alpha.version\" } " + + "gauge { value: 0.0 } " + + "}"; + // @formatter:on + StateSetSnapshot stateSet = + StateSetSnapshot.builder() + .name("my.application.state") + .help("My application state") + .dataPoint( + StateSetSnapshot.StateSetDataPointSnapshot.builder() + .labels(Labels.of("data.center", "us east")) + .state("feature.enabled", true) + .state("is.alpha.version", false) + .build()) + .build(); + assertOpenMetricsText(openMetricsText, stateSet); + assertPrometheusText(prometheusText, stateSet); + assertPrometheusProtobuf(prometheusProtobuf, stateSet); + } - @Test - public void testUnknownMinimal() throws IOException { - String openMetrics = "" + - "# TYPE other unknown\n" + - "other 22.3\n" + - "# EOF\n"; - String prometheus = "" + - "# TYPE other untyped\n" + - "other 22.3\n"; - UnknownSnapshot unknown = UnknownSnapshot.builder() - .name("other") - .dataPoint(UnknownDataPointSnapshot.builder() - .value(22.3) - .build()) - .build(); - assertOpenMetricsText(openMetrics, unknown); - assertPrometheusText(prometheus, unknown); - assertOpenMetricsTextWithoutCreated(openMetrics, unknown); - assertPrometheusTextWithoutCreated(prometheus, unknown); - } + @Test + public void testUnknownComplete() throws IOException { + String openMetrics = + "" + + "# TYPE my_special_thing_bytes unknown\n" + + "# UNIT my_special_thing_bytes bytes\n" + + "# HELP my_special_thing_bytes help message\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + + scrapeTimestamp1s + + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + + scrapeTimestamp2s + + "\n" + + "# EOF\n"; + String openMetricsWithExemplarsOnAllTimeSeries = + "" + + "# TYPE my_special_thing_bytes unknown\n" + + "# UNIT my_special_thing_bytes bytes\n" + + "# HELP my_special_thing_bytes help message\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + + scrapeTimestamp1s + + " # " + + exemplar1String + + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + + scrapeTimestamp2s + + " # " + + exemplar2String + + "\n" + + "# EOF\n"; + String prometheus = + "" + + "# HELP my_special_thing_bytes help message\n" + + "# TYPE my_special_thing_bytes untyped\n" + + "my_special_thing_bytes{env=\"dev\"} 0.2 " + + scrapeTimestamp1s + + "\n" + + "my_special_thing_bytes{env=\"prod\"} 0.7 " + + scrapeTimestamp2s + + "\n"; + UnknownSnapshot unknown = + UnknownSnapshot.builder() + .name("my_special_thing_bytes") + .help("help message") + .unit(Unit.BYTES) + .dataPoint( + UnknownDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.of("env", "prod")) + .exemplar(exemplar2) + .scrapeTimestampMillis(scrapeTimestamp2) + .build()) + .dataPoint( + UnknownDataPointSnapshot.builder() + .value(0.2) + .labels(Labels.of("env", "dev")) + .exemplar(exemplar1) + .scrapeTimestampMillis(scrapeTimestamp1) + .build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsWithExemplarsOnAllTimeSeries, unknown); + assertPrometheusText(prometheus, unknown); + assertOpenMetricsTextWithoutCreated(openMetrics, unknown); + assertPrometheusTextWithoutCreated(prometheus, unknown); + } - @Test - public void testUnknownWithDots() throws IOException { - String openMetrics = "" + - "# TYPE some_unknown_metric_bytes unknown\n" + - "# UNIT some_unknown_metric_bytes bytes\n" + - "# HELP some_unknown_metric_bytes help message\n" + - "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n" + - "# EOF\n"; - String openMetricsWithExemplarsOnAllTimeSeries = "" + - "# TYPE some_unknown_metric_bytes unknown\n" + - "# UNIT some_unknown_metric_bytes bytes\n" + - "# HELP some_unknown_metric_bytes help message\n" + - "some_unknown_metric_bytes{test_env=\"7\"} 0.7 # " + exemplarWithDotsString + "\n" + - "# EOF\n"; - String prometheus = "" + - "# HELP some_unknown_metric_bytes help message\n" + - "# TYPE some_unknown_metric_bytes untyped\n" + - "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n"; - String prometheusProtobuf = "" + - //@formatter:off - "name: \"some_unknown_metric_bytes\" " + - "help: \"help message\" " + - "type: UNTYPED " + - "metric { " + - "label { name: \"test_env\" value: \"7\" } " + - "untyped { value: 0.7 } " + - "}"; - //@formatter:on - UnknownSnapshot unknown = UnknownSnapshot.builder() - .name(PrometheusNaming.sanitizeMetricName("some.unknown.metric", Unit.BYTES)) - .help("help message") - .unit(Unit.BYTES) - .dataPoint(UnknownDataPointSnapshot.builder() - .value(0.7) - .labels(Labels.of("test.env", "7")) - .exemplar(exemplarWithDots) - .build()) - .build(); - assertOpenMetricsText(openMetrics, unknown); - assertOpenMetricsTextWithExemplarsOnAllTimeSeries(openMetricsWithExemplarsOnAllTimeSeries, unknown); - assertPrometheusText(prometheus, unknown); - assertPrometheusProtobuf(prometheusProtobuf, unknown); - } + @Test + public void testUnknownMinimal() throws IOException { + String openMetrics = "" + "# TYPE other unknown\n" + "other 22.3\n" + "# EOF\n"; + String prometheus = "" + "# TYPE other untyped\n" + "other 22.3\n"; + UnknownSnapshot unknown = + UnknownSnapshot.builder() + .name("other") + .dataPoint(UnknownDataPointSnapshot.builder().value(22.3).build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertPrometheusText(prometheus, unknown); + assertOpenMetricsTextWithoutCreated(openMetrics, unknown); + assertPrometheusTextWithoutCreated(prometheus, unknown); + } - @Test - public void testHelpEscape() throws IOException { - String openMetrics = "" + - "# TYPE test counter\n" + - "# HELP test Some text and \\n some \\\" escaping\n" + - "test_total 1.0\n" + - "# EOF\n"; - String prometheus = "" + - "# HELP test_total Some text and \\n some \" escaping\n" + - "# TYPE test_total counter\n" + - "test_total 1.0\n"; - CounterSnapshot counter = CounterSnapshot.builder() - .name("test") - .help("Some text and \n some \" escaping") // example from https://openMetrics.io - .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - assertOpenMetricsText(openMetrics, counter); - assertPrometheusText(prometheus, counter); - assertOpenMetricsTextWithoutCreated(openMetrics, counter); - assertPrometheusTextWithoutCreated(prometheus, counter); - } + @Test + public void testUnknownWithDots() throws IOException { + String openMetrics = + "" + + "# TYPE some_unknown_metric_bytes unknown\n" + + "# UNIT some_unknown_metric_bytes bytes\n" + + "# HELP some_unknown_metric_bytes help message\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n" + + "# EOF\n"; + String openMetricsWithExemplarsOnAllTimeSeries = + "" + + "# TYPE some_unknown_metric_bytes unknown\n" + + "# UNIT some_unknown_metric_bytes bytes\n" + + "# HELP some_unknown_metric_bytes help message\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7 # " + + exemplarWithDotsString + + "\n" + + "# EOF\n"; + String prometheus = + "" + + "# HELP some_unknown_metric_bytes help message\n" + + "# TYPE some_unknown_metric_bytes untyped\n" + + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n"; + String prometheusProtobuf = + "" + + + // @formatter:off + "name: \"some_unknown_metric_bytes\" " + + "help: \"help message\" " + + "type: UNTYPED " + + "metric { " + + "label { name: \"test_env\" value: \"7\" } " + + "untyped { value: 0.7 } " + + "}"; + // @formatter:on + UnknownSnapshot unknown = + UnknownSnapshot.builder() + .name(PrometheusNaming.sanitizeMetricName("some.unknown.metric", Unit.BYTES)) + .help("help message") + .unit(Unit.BYTES) + .dataPoint( + UnknownDataPointSnapshot.builder() + .value(0.7) + .labels(Labels.of("test.env", "7")) + .exemplar(exemplarWithDots) + .build()) + .build(); + assertOpenMetricsText(openMetrics, unknown); + assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + openMetricsWithExemplarsOnAllTimeSeries, unknown); + assertPrometheusText(prometheus, unknown); + assertPrometheusProtobuf(prometheusProtobuf, unknown); + } - @Test - public void testLabelValueEscape() throws IOException { - String openMetrics = "" + - "# TYPE test counter\n" + - "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n" + - "# EOF\n"; - String prometheus = "" + - "# TYPE test_total counter\n" + - "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; - CounterSnapshot counter = CounterSnapshot.builder() - .name("test") - .dataPoint(CounterDataPointSnapshot.builder() - // example from https://openMetrics.io - .labels(Labels.of("a", "x", "b", "escaping\" example \n ")) - .value(1.0) - .build()) - .build(); - assertOpenMetricsText(openMetrics, counter); - assertPrometheusText(prometheus, counter); - } + @Test + public void testHelpEscape() throws IOException { + String openMetrics = + "" + + "# TYPE test counter\n" + + "# HELP test Some text and \\n some \\\" escaping\n" + + "test_total 1.0\n" + + "# EOF\n"; + String prometheus = + "" + + "# HELP test_total Some text and \\n some \" escaping\n" + + "# TYPE test_total counter\n" + + "test_total 1.0\n"; + CounterSnapshot counter = + CounterSnapshot.builder() + .name("test") + .help("Some text and \n some \" escaping") // example from https://openMetrics.io + .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + assertOpenMetricsText(openMetrics, counter); + assertPrometheusText(prometheus, counter); + assertOpenMetricsTextWithoutCreated(openMetrics, counter); + assertPrometheusTextWithoutCreated(prometheus, counter); + } + + @Test + public void testLabelValueEscape() throws IOException { + String openMetrics = + "" + + "# TYPE test counter\n" + + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n" + + "# EOF\n"; + String prometheus = + "" + + "# TYPE test_total counter\n" + + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; + CounterSnapshot counter = + CounterSnapshot.builder() + .name("test") + .dataPoint( + CounterDataPointSnapshot.builder() + // example from https://openMetrics.io + .labels(Labels.of("a", "x", "b", "escaping\" example \n ")) + .value(1.0) + .build()) + .build(); + assertOpenMetricsText(openMetrics, counter); + assertPrometheusText(prometheus, counter); + } - private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); - } + private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } - private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries(String expected, MetricSnapshot snapshot) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); - } + private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( + String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } - private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); - } + private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) + throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } - private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); - } + private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } - private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); - writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); - } + private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) + throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); + writer.write(out, MetricSnapshots.of(snapshot)); + Assert.assertEquals(expected, out.toString()); + } - private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { - PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); - Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = TextFormat.printer().shortDebugString(protobufData); - Assert.assertEquals(expected, actual); - } + private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { + PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); + Metrics.MetricFamily protobufData = writer.convert(snapshot); + String actual = TextFormat.printer().shortDebugString(protobufData); + Assert.assertEquals(expected, actual); + } } diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java index 985a15711..69b852a41 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java @@ -10,19 +10,18 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; - import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; - /** * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache. + * *

      - *

      {@code
        *
      + * 
      {@code
        * // Note that `recordStats()` is required to gather non-zero statistics
        * Cache cache = Caffeine.newBuilder().recordStats().build();
        * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      @@ -32,7 +31,8 @@
        *
        * Exposed metrics are labeled with the provided cache name.
        *
      - * With the example above, sample metric names would be:
      + * 

      With the example above, sample metric names would be: + * *

        *     caffeine_cache_hit_total{cache="mycache"} 10.0
        *     caffeine_cache_miss_total{cache="mycache"} 3.0
      @@ -42,191 +42,183 @@
        * 
      * * Additionally, if the cache includes a loader, the following metrics would be provided: + * *
        *     caffeine_cache_load_failure_total{cache="mycache"} 2.0
        *     caffeine_cache_loads_total{cache="mycache"} 7.0
        *     caffeine_cache_load_duration_seconds_count{cache="mycache"} 7.0
        *     caffeine_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
        * 
      - * */ public class CacheMetricsCollector implements MultiCollector { - private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; - - protected final ConcurrentMap children = new ConcurrentHashMap(); - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, Cache cache) { - children.put(cacheName, cache); - } - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, AsyncCache cache) { - children.put(cacheName, cache.synchronous()); - } - - /** - * Remove the cache with the given name. - *

      - * Any references to the cache are invalidated. - * - * @param cacheName cache to be removed - */ - public Cache removeCache(String cacheName) { - return children.remove(cacheName); - } - - /** - * Remove all caches. - *

      - * Any references to all caches are invalidated. - */ - public void clear(){ - children.clear(); - } - - @Override - public MetricSnapshots collect() { - final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); - final List labelNames = Arrays.asList("cache"); - - final CounterSnapshot.Builder cacheHitTotal = CounterSnapshot.builder() - .name("caffeine_cache_hit") - .help("Cache hit totals"); - - final CounterSnapshot.Builder cacheMissTotal = CounterSnapshot.builder() - .name("caffeine_cache_miss") - .help("Cache miss totals"); - - final CounterSnapshot.Builder cacheRequestsTotal = CounterSnapshot.builder() + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; + + protected final ConcurrentMap children = new ConcurrentHashMap(); + + /** + * Add or replace the cache with the given name. + * + *

      Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, Cache cache) { + children.put(cacheName, cache); + } + + /** + * Add or replace the cache with the given name. + * + *

      Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, AsyncCache cache) { + children.put(cacheName, cache.synchronous()); + } + + /** + * Remove the cache with the given name. + * + *

      Any references to the cache are invalidated. + * + * @param cacheName cache to be removed + */ + public Cache removeCache(String cacheName) { + return children.remove(cacheName); + } + + /** + * Remove all caches. + * + *

      Any references to all caches are invalidated. + */ + public void clear() { + children.clear(); + } + + @Override + public MetricSnapshots collect() { + final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); + final List labelNames = Arrays.asList("cache"); + + final CounterSnapshot.Builder cacheHitTotal = + CounterSnapshot.builder().name("caffeine_cache_hit").help("Cache hit totals"); + + final CounterSnapshot.Builder cacheMissTotal = + CounterSnapshot.builder().name("caffeine_cache_miss").help("Cache miss totals"); + + final CounterSnapshot.Builder cacheRequestsTotal = + CounterSnapshot.builder() .name("caffeine_cache_requests") .help("Cache request totals, hits + misses"); - final CounterSnapshot.Builder cacheEvictionTotal = CounterSnapshot.builder() + final CounterSnapshot.Builder cacheEvictionTotal = + CounterSnapshot.builder() .name("caffeine_cache_eviction") .help("Cache eviction totals, doesn't include manually removed entries"); - final GaugeSnapshot.Builder cacheEvictionWeight = GaugeSnapshot.builder() + final GaugeSnapshot.Builder cacheEvictionWeight = + GaugeSnapshot.builder() .name("caffeine_cache_eviction_weight") .help("Cache eviction weight"); - final CounterSnapshot.Builder cacheLoadFailure = CounterSnapshot.builder() - .name("caffeine_cache_load_failure") - .help("Cache load failures"); + final CounterSnapshot.Builder cacheLoadFailure = + CounterSnapshot.builder().name("caffeine_cache_load_failure").help("Cache load failures"); - final CounterSnapshot.Builder cacheLoadTotal = CounterSnapshot.builder() + final CounterSnapshot.Builder cacheLoadTotal = + CounterSnapshot.builder() .name("caffeine_cache_loads") .help("Cache loads: both success and failures"); - final GaugeSnapshot.Builder cacheSize = GaugeSnapshot.builder() - .name("caffeine_cache_estimated_size") - .help("Estimated cache size"); + final GaugeSnapshot.Builder cacheSize = + GaugeSnapshot.builder().name("caffeine_cache_estimated_size").help("Estimated cache size"); - final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() + final SummarySnapshot.Builder cacheLoadSummary = + SummarySnapshot.builder() .name("caffeine_cache_load_duration_seconds") .help("Cache load duration: both success and failures"); - for (final Map.Entry c: children.entrySet()) { - final List cacheName = Arrays.asList(c.getKey()); - final Labels labels = Labels.of(labelNames, cacheName); - - final CacheStats stats = c.getValue().stats(); - - try { - cacheEvictionWeight.dataPoint( - GaugeSnapshot.GaugeDataPointSnapshot.builder() - .labels(labels) - .value(stats.evictionWeight()) - .build() - ); - } catch (Exception e) { - // EvictionWeight metric is unavailable, newer version of Caffeine is needed. - } - - cacheHitTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.hitCount()) - .build() - ); - - cacheMissTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.missCount()) - .build() - ); - - cacheRequestsTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.requestCount()) - .build() - ); - - cacheEvictionTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.evictionCount()) - .build() - ); - - cacheSize.dataPoint( - GaugeSnapshot.GaugeDataPointSnapshot.builder() - .labels(labels) - .value(c.getValue().estimatedSize()) - .build() - ); - - if (c.getValue() instanceof LoadingCache) { - cacheLoadFailure.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.loadFailureCount()) - .build() - ); - - cacheLoadTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.loadCount()) - .build() - ); - - cacheLoadSummary.dataPoint( - SummarySnapshot.SummaryDataPointSnapshot.builder() - .labels(labels) - .count(stats.loadCount()) - .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) - .build() - ); - } - } - - return metricSnapshotsBuilder - .metricSnapshot(cacheHitTotal.build()) - .metricSnapshot(cacheMissTotal.build()) - .metricSnapshot(cacheRequestsTotal.build()) - .metricSnapshot(cacheEvictionTotal.build()) - .metricSnapshot(cacheEvictionWeight.build()) - .metricSnapshot(cacheLoadFailure.build()) - .metricSnapshot(cacheLoadTotal.build()) - .metricSnapshot(cacheSize.build()) - .metricSnapshot(cacheLoadSummary.build()) - .build(); + for (final Map.Entry c : children.entrySet()) { + final List cacheName = Arrays.asList(c.getKey()); + final Labels labels = Labels.of(labelNames, cacheName); + + final CacheStats stats = c.getValue().stats(); + + try { + cacheEvictionWeight.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionWeight()) + .build()); + } catch (Exception e) { + // EvictionWeight metric is unavailable, newer version of Caffeine is needed. + } + + cacheHitTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.hitCount()) + .build()); + + cacheMissTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.missCount()) + .build()); + + cacheRequestsTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.requestCount()) + .build()); + + cacheEvictionTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionCount()) + .build()); + + cacheSize.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(c.getValue().estimatedSize()) + .build()); + + if (c.getValue() instanceof LoadingCache) { + cacheLoadFailure.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadFailureCount()) + .build()); + + cacheLoadTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadCount()) + .build()); + + cacheLoadSummary.dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(labels) + .count(stats.loadCount()) + .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) + .build()); + } } + + return metricSnapshotsBuilder + .metricSnapshot(cacheHitTotal.build()) + .metricSnapshot(cacheMissTotal.build()) + .metricSnapshot(cacheRequestsTotal.build()) + .metricSnapshot(cacheEvictionTotal.build()) + .metricSnapshot(cacheEvictionWeight.build()) + .metricSnapshot(cacheLoadFailure.build()) + .metricSnapshot(cacheLoadTotal.build()) + .metricSnapshot(cacheSize.build()) + .metricSnapshot(cacheLoadSummary.build()) + .build(); + } } diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java index 86f7ed185..acbfe3e1e 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -1,5 +1,11 @@ package io.prometheus.metrics.instrumentation.caffeine; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine; @@ -10,144 +16,143 @@ import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.Executor; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.junit.Test; public class CacheMetricsCollectorTest { - @Test - public void cacheExposesMetricsForHitMissAndEviction() { - final Cache cache = Caffeine.newBuilder().maximumSize(2).recordStats().executor(new Executor() { - @Override - public void execute(Runnable command) { - // Run cleanup in same thread, to remove async behavior with evictions - command.run(); - } - }).build(); - - final CacheMetricsCollector collector = new CacheMetricsCollector(); - collector.addCache("users", cache); - - final PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - - cache.getIfPresent("user1"); - cache.getIfPresent("user1"); - cache.put("user1", "First User"); - cache.getIfPresent("user1"); - - // Add to cache to trigger eviction. - cache.put("user2", "Second User"); - cache.put("user3", "Third User"); - cache.put("user4", "Fourth User"); - - assertCounterMetric(registry, "caffeine_cache_hit", "users", 1.0); - assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0); - assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0); - assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0); - - final String expected = "# TYPE caffeine_cache_estimated_size gauge\n" + - "# HELP caffeine_cache_estimated_size Estimated cache size\n" + - "caffeine_cache_estimated_size{cache=\"users\"} 2.0\n" + - "# TYPE caffeine_cache_eviction counter\n" + - "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + - "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n" + - "# TYPE caffeine_cache_eviction_weight gauge\n" + - "# HELP caffeine_cache_eviction_weight Cache eviction weight\n" + - "caffeine_cache_eviction_weight{cache=\"users\"} 2.0\n" + - "# TYPE caffeine_cache_hit counter\n" + - "# HELP caffeine_cache_hit Cache hit totals\n" + - "caffeine_cache_hit_total{cache=\"users\"} 1.0\n" + - "# TYPE caffeine_cache_miss counter\n" + - "# HELP caffeine_cache_miss Cache miss totals\n" + - "caffeine_cache_miss_total{cache=\"users\"} 2.0\n" + - "# TYPE caffeine_cache_requests counter\n" + - "# HELP caffeine_cache_requests Cache request totals, hits + misses\n" + - "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + - "# EOF\n"; - - assertEquals(expected, convertToOpenMetricsFormat(registry)); - } - - @SuppressWarnings("unchecked") - @Test - public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { - final CacheLoader loader = mock(CacheLoader.class); - when(loader.load(anyString())) - .thenReturn("First User") - .thenThrow(new RuntimeException("Seconds time fails")) - .thenReturn("Third User"); - - final LoadingCache cache = Caffeine.newBuilder().recordStats().build(loader); - final CacheMetricsCollector collector = new CacheMetricsCollector(); - - collector.addCache("loadingusers", cache); - - final PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - - cache.get("user1"); - cache.get("user1"); - try { - cache.get("user2"); - } catch (Exception e) { - // ignoring. - } - cache.get("user3"); - - assertCounterMetric(registry, "caffeine_cache_hit", "loadingusers", 1.0); - assertCounterMetric(registry, "caffeine_cache_miss", "loadingusers", 3.0); - - assertCounterMetric(registry, "caffeine_cache_load_failure", "loadingusers", 1.0); - assertCounterMetric(registry, "caffeine_cache_loads", "loadingusers", 3.0); - - final SummarySnapshot.SummaryDataPointSnapshot loadDuration = (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot( - registry, - "caffeine_cache_load_duration_seconds", - "loadingusers" - ); - - assertEquals(3, loadDuration.getCount()); - assertThat(loadDuration.getSum()).isGreaterThan(0); - } - - private void assertCounterMetric(PrometheusRegistry registry, String name, String cacheName, double value) { - final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = - (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); - - assertEquals(value, dataPointSnapshot.getValue(), 0); - } - - private DataPointSnapshot getDataPointSnapshot(PrometheusRegistry registry, String name, String cacheName) - { - final Labels labels = Labels.of(new String[]{"cache"}, new String[]{cacheName}); - - return registry.scrape(name::equals).stream() - .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) - .filter(dataPoint -> dataPoint.getLabels().equals(labels)) - .findFirst() - .get(); + @Test + public void cacheExposesMetricsForHitMissAndEviction() { + final Cache cache = + Caffeine.newBuilder() + .maximumSize(2) + .recordStats() + .executor( + new Executor() { + @Override + public void execute(Runnable command) { + // Run cleanup in same thread, to remove async behavior with evictions + command.run(); + } + }) + .build(); + + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("users", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.getIfPresent("user1"); + cache.getIfPresent("user1"); + cache.put("user1", "First User"); + cache.getIfPresent("user1"); + + // Add to cache to trigger eviction. + cache.put("user2", "Second User"); + cache.put("user3", "Third User"); + cache.put("user4", "Fourth User"); + + assertCounterMetric(registry, "caffeine_cache_hit", "users", 1.0); + assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0); + assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0); + assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0); + + final String expected = + "# TYPE caffeine_cache_estimated_size gauge\n" + + "# HELP caffeine_cache_estimated_size Estimated cache size\n" + + "caffeine_cache_estimated_size{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_eviction counter\n" + + "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_eviction_weight gauge\n" + + "# HELP caffeine_cache_eviction_weight Cache eviction weight\n" + + "caffeine_cache_eviction_weight{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_hit counter\n" + + "# HELP caffeine_cache_hit Cache hit totals\n" + + "caffeine_cache_hit_total{cache=\"users\"} 1.0\n" + + "# TYPE caffeine_cache_miss counter\n" + + "# HELP caffeine_cache_miss Cache miss totals\n" + + "caffeine_cache_miss_total{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_requests counter\n" + + "# HELP caffeine_cache_requests Cache request totals, hits + misses\n" + + "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat(registry)); + } + + @SuppressWarnings("unchecked") + @Test + public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { + final CacheLoader loader = mock(CacheLoader.class); + when(loader.load(anyString())) + .thenReturn("First User") + .thenThrow(new RuntimeException("Seconds time fails")) + .thenReturn("Third User"); + + final LoadingCache cache = Caffeine.newBuilder().recordStats().build(loader); + final CacheMetricsCollector collector = new CacheMetricsCollector(); + + collector.addCache("loadingusers", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.get("user1"); + cache.get("user1"); + try { + cache.get("user2"); + } catch (Exception e) { + // ignoring. } - - private String convertToOpenMetricsFormat(PrometheusRegistry registry) { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - try { - writer.write(out, registry.scrape()); - return out.toString(StandardCharsets.UTF_8.name()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + cache.get("user3"); + + assertCounterMetric(registry, "caffeine_cache_hit", "loadingusers", 1.0); + assertCounterMetric(registry, "caffeine_cache_miss", "loadingusers", 3.0); + + assertCounterMetric(registry, "caffeine_cache_load_failure", "loadingusers", 1.0); + assertCounterMetric(registry, "caffeine_cache_loads", "loadingusers", 3.0); + + final SummarySnapshot.SummaryDataPointSnapshot loadDuration = + (SummarySnapshot.SummaryDataPointSnapshot) + getDataPointSnapshot(registry, "caffeine_cache_load_duration_seconds", "loadingusers"); + + assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getSum()).isGreaterThan(0); + } + + private void assertCounterMetric( + PrometheusRegistry registry, String name, String cacheName, double value) { + final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = + (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); + + assertEquals(value, dataPointSnapshot.getValue(), 0); + } + + private DataPointSnapshot getDataPointSnapshot( + PrometheusRegistry registry, String name, String cacheName) { + final Labels labels = Labels.of(new String[] {"cache"}, new String[] {cacheName}); + + return registry.scrape(name::equals).stream() + .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) + .filter(dataPoint -> dataPoint.getLabels().equals(labels)) + .findFirst() + .get(); + } + + private String convertToOpenMetricsFormat(PrometheusRegistry registry) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, registry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new UncheckedIOException(e); } + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java index ec2bfa2e4..c87f4aa90 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java @@ -1,221 +1,252 @@ package io.prometheus.metrics.instrumentation.dropwizard5; -import io.dropwizard.metrics5.Timer; import io.dropwizard.metrics5.*; +import io.dropwizard.metrics5.Timer; import io.prometheus.metrics.instrumentation.dropwizard5.labels.CustomLabelMapper; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.*; - import java.util.*; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -/** - * Collect Dropwizard metrics from a MetricRegistry. - */ +/** Collect Dropwizard metrics from a MetricRegistry. */ public class DropwizardExports implements MultiCollector { - private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName()); - private final MetricRegistry registry; - private final MetricFilter metricFilter; - private final Optional labelMapper; - - /** - * Creates a new DropwizardExports and {@link MetricFilter#ALL}. - * - * @param registry a metric registry to export in prometheus. - */ - public DropwizardExports(MetricRegistry registry) { - super(); - this.registry = registry; - this.metricFilter = MetricFilter.ALL; - this.labelMapper = Optional.empty(); + private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName()); + private final MetricRegistry registry; + private final MetricFilter metricFilter; + private final Optional labelMapper; + + /** + * Creates a new DropwizardExports and {@link MetricFilter#ALL}. + * + * @param registry a metric registry to export in prometheus. + */ + public DropwizardExports(MetricRegistry registry) { + super(); + this.registry = registry; + this.metricFilter = MetricFilter.ALL; + this.labelMapper = Optional.empty(); + } + + /** + * Creates a new DropwizardExports with a custom {@link MetricFilter}. + * + * @param registry a metric registry to export in prometheus. + * @param metricFilter a custom metric filter. + */ + public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) { + this.registry = registry; + this.metricFilter = metricFilter; + this.labelMapper = Optional.empty(); + } + + /** + * @param registry a metric registry to export in prometheus. + * @param metricFilter a custom metric filter. + * @param labelMapper a labelMapper to use to map labels. + */ + public DropwizardExports( + MetricRegistry registry, MetricFilter metricFilter, CustomLabelMapper labelMapper) { + this.registry = registry; + this.metricFilter = metricFilter; + this.labelMapper = Optional.ofNullable(labelMapper); + } + + private static String getHelpMessage(String metricName, Metric metric) { + return String.format( + "Generated from Dropwizard metric import (metric=%s, type=%s)", + metricName, metric.getClass().getName()); + } + + private MetricMetadata getMetricMetaData(String metricName, Metric metric) { + String name = labelMapper.isPresent() ? labelMapper.get().getName(metricName) : metricName; + return new MetricMetadata( + PrometheusNaming.sanitizeMetricName(name), getHelpMessage(metricName, metric)); + } + + /** + * Export counter as Prometheus Gauge. + */ + MetricSnapshot fromCounter(String dropwizardName, Counter counter) { + MetricMetadata metadata = getMetricMetaData(dropwizardName, counter); + CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = + CounterSnapshot.CounterDataPointSnapshot.builder() + .value(Long.valueOf(counter.getCount()).doubleValue()); + labelMapper.map( + mapper -> + dataPointBuilder.labels( + mapper.getLabels( + dropwizardName, Collections.emptyList(), Collections.emptyList()))); + return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + } + + /** Export gauge as a prometheus gauge. */ + MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { + Object obj = gauge.getValue(); + double value; + if (obj instanceof Number) { + value = ((Number) obj).doubleValue(); + } else if (obj instanceof Boolean) { + value = ((Boolean) obj) ? 1 : 0; + } else { + LOGGER.log( + Level.FINE, + String.format( + "Invalid type for Gauge %s: %s", + PrometheusNaming.sanitizeMetricName(dropwizardName), + obj == null ? "null" : obj.getClass().getName())); + return null; } - - /** - * Creates a new DropwizardExports with a custom {@link MetricFilter}. - * - * @param registry a metric registry to export in prometheus. - * @param metricFilter a custom metric filter. - */ - public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) { - this.registry = registry; - this.metricFilter = metricFilter; - this.labelMapper = Optional.empty(); + MetricMetadata metadata = getMetricMetaData(dropwizardName, gauge); + GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPointBuilder = + GaugeSnapshot.GaugeDataPointSnapshot.builder().value(value); + labelMapper.map( + mapper -> + dataPointBuilder.labels( + mapper.getLabels( + dropwizardName, Collections.emptyList(), Collections.emptyList()))); + return new GaugeSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + } + + /** + * Export a histogram snapshot as a prometheus SUMMARY. + * + * @param dropwizardName metric name. + * @param snapshot the histogram snapshot. + * @param count the total sample count for this snapshot. + * @param factor a factor to apply to histogram values. + */ + MetricSnapshot fromSnapshotAndCount( + String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) { + Quantiles quantiles = + Quantiles.builder() + .quantile(0.5, snapshot.getMedian() * factor) + .quantile(0.75, snapshot.get75thPercentile() * factor) + .quantile(0.95, snapshot.get95thPercentile() * factor) + .quantile(0.98, snapshot.get98thPercentile() * factor) + .quantile(0.99, snapshot.get99thPercentile() * factor) + .quantile(0.999, snapshot.get999thPercentile() * factor) + .build(); + + MetricMetadata metadata = + new MetricMetadata(PrometheusNaming.sanitizeMetricName(dropwizardName), helpMessage); + SummarySnapshot.SummaryDataPointSnapshot.Builder dataPointBuilder = + SummarySnapshot.SummaryDataPointSnapshot.builder().quantiles(quantiles).count(count); + labelMapper.map( + mapper -> + dataPointBuilder.labels( + mapper.getLabels( + dropwizardName, Collections.emptyList(), Collections.emptyList()))); + return new SummarySnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + } + + /** Convert histogram snapshot. */ + MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) { + return fromSnapshotAndCount( + dropwizardName, + histogram.getSnapshot(), + histogram.getCount(), + 1.0, + getHelpMessage(dropwizardName, histogram)); + } + + /** Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit. */ + MetricSnapshot fromTimer(String dropwizardName, Timer timer) { + return fromSnapshotAndCount( + dropwizardName, + timer.getSnapshot(), + timer.getCount(), + 1.0D / TimeUnit.SECONDS.toNanos(1L), + getHelpMessage(dropwizardName, timer)); + } + + /** Export a Meter as a prometheus COUNTER. */ + MetricSnapshot fromMeter(String dropwizardName, Meter meter) { + MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter); + CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = + CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount()); + labelMapper.map( + mapper -> + dataPointBuilder.labels( + mapper.getLabels( + dropwizardName, Collections.emptyList(), Collections.emptyList()))); + return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + } + + @Override + public MetricSnapshots collect() { + MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder(); + for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) { + Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue())) + .map(metricSnapshots::metricSnapshot); } - - /** - * @param registry a metric registry to export in prometheus. - * @param metricFilter a custom metric filter. - * @param labelMapper a labelMapper to use to map labels. - */ - public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter, CustomLabelMapper labelMapper) { - this.registry = registry; - this.metricFilter = metricFilter; - this.labelMapper = Optional.ofNullable(labelMapper); + for (SortedMap.Entry entry : + registry.getCounters(metricFilter).entrySet()) { + metricSnapshots.metricSnapshot(fromCounter(entry.getKey().getKey(), entry.getValue())); } - - private static String getHelpMessage(String metricName, Metric metric) { - return String.format("Generated from Dropwizard metric import (metric=%s, type=%s)", - metricName, metric.getClass().getName()); + for (SortedMap.Entry entry : + registry.getHistograms(metricFilter).entrySet()) { + metricSnapshots.metricSnapshot(fromHistogram(entry.getKey().getKey(), entry.getValue())); } - - private MetricMetadata getMetricMetaData(String metricName, Metric metric) { - String name = labelMapper.isPresent() ? labelMapper.get().getName(metricName) : metricName; - return new MetricMetadata(PrometheusNaming.sanitizeMetricName(name), getHelpMessage(metricName, metric)); + for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) { + metricSnapshots.metricSnapshot(fromTimer(entry.getKey().getKey(), entry.getValue())); } - - /** - * Export counter as Prometheus Gauge. - */ - MetricSnapshot fromCounter(String dropwizardName, Counter counter) { - MetricMetadata metadata = getMetricMetaData(dropwizardName, counter); - CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(Long.valueOf(counter.getCount()).doubleValue()); - labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList()))); - return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) { + metricSnapshots.metricSnapshot(fromMeter(entry.getKey().getKey(), entry.getValue())); } + return metricSnapshots.build(); + } - /** - * Export gauge as a prometheus gauge. - */ - MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { - Object obj = gauge.getValue(); - double value; - if (obj instanceof Number) { - value = ((Number) obj).doubleValue(); - } else if (obj instanceof Boolean) { - value = ((Boolean) obj) ? 1 : 0; - } else { - LOGGER.log(Level.FINE, String.format("Invalid type for Gauge %s: %s", PrometheusNaming.sanitizeMetricName(dropwizardName), - obj == null ? "null" : obj.getClass().getName())); - return null; - } - MetricMetadata metadata = getMetricMetaData(dropwizardName, gauge); - GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder().value(value); - labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList()))); - return new GaugeSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); - } + public static Builder builder() { + return new Builder(); + } - /** - * Export a histogram snapshot as a prometheus SUMMARY. - * - * @param dropwizardName metric name. - * @param snapshot the histogram snapshot. - * @param count the total sample count for this snapshot. - * @param factor a factor to apply to histogram values. - */ - MetricSnapshot fromSnapshotAndCount(String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) { - Quantiles quantiles = Quantiles.builder() - .quantile(0.5, snapshot.getMedian() * factor) - .quantile(0.75, snapshot.get75thPercentile() * factor) - .quantile(0.95, snapshot.get95thPercentile() * factor) - .quantile(0.98, snapshot.get98thPercentile() * factor) - .quantile(0.99, snapshot.get99thPercentile() * factor) - .quantile(0.999, snapshot.get999thPercentile() * factor) - .build(); - - MetricMetadata metadata = new MetricMetadata(PrometheusNaming.sanitizeMetricName(dropwizardName), helpMessage); - SummarySnapshot.SummaryDataPointSnapshot.Builder dataPointBuilder = SummarySnapshot.SummaryDataPointSnapshot.builder().quantiles(quantiles).count(count); - labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList()))); - return new SummarySnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); - } + // Builder class for DropwizardExports + public static class Builder { + private MetricRegistry registry; + private MetricFilter metricFilter; + private CustomLabelMapper labelMapper; - /** - * Convert histogram snapshot. - */ - MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) { - return fromSnapshotAndCount(dropwizardName, histogram.getSnapshot(), histogram.getCount(), 1.0, - getHelpMessage(dropwizardName, histogram)); + private Builder() { + this.metricFilter = MetricFilter.ALL; } - /** - * Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit. - */ - MetricSnapshot fromTimer(String dropwizardName, Timer timer) { - return fromSnapshotAndCount(dropwizardName, timer.getSnapshot(), timer.getCount(), - 1.0D / TimeUnit.SECONDS.toNanos(1L), getHelpMessage(dropwizardName, timer)); + public Builder dropwizardRegistry(MetricRegistry registry) { + this.registry = registry; + return this; } - /** - * Export a Meter as a prometheus COUNTER. - */ - MetricSnapshot fromMeter(String dropwizardName, Meter meter) { - MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter); - CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount()); - labelMapper.map(mapper -> dataPointBuilder.labels(mapper.getLabels(dropwizardName, Collections.emptyList(), Collections.emptyList()))); - return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build())); + public Builder metricFilter(MetricFilter metricFilter) { + this.metricFilter = metricFilter; + return this; } - @Override - public MetricSnapshots collect() { - MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder(); - for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) { - Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue())).map(metricSnapshots::metricSnapshot); - } - for (SortedMap.Entry entry : registry.getCounters(metricFilter).entrySet()) { - metricSnapshots.metricSnapshot(fromCounter(entry.getKey().getKey(), entry.getValue())); - } - for (SortedMap.Entry entry : registry.getHistograms(metricFilter).entrySet()) { - metricSnapshots.metricSnapshot(fromHistogram(entry.getKey().getKey(), entry.getValue())); - } - for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) { - metricSnapshots.metricSnapshot(fromTimer(entry.getKey().getKey(), entry.getValue())); - } - for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) { - metricSnapshots.metricSnapshot(fromMeter(entry.getKey().getKey(), entry.getValue())); - } - return metricSnapshots.build(); + public Builder customLabelMapper(CustomLabelMapper labelMapper) { + this.labelMapper = labelMapper; + return this; } - public static Builder builder() { - return new Builder(); + DropwizardExports build() { + if (registry == null) { + throw new IllegalArgumentException("MetricRegistry must be set"); + } + if (labelMapper == null) { + return new DropwizardExports(registry, metricFilter); + } else { + return new DropwizardExports(registry, metricFilter, labelMapper); + } } - //Builder class for DropwizardExports - public static class Builder { - private MetricRegistry registry; - private MetricFilter metricFilter; - private CustomLabelMapper labelMapper; - - private Builder() { - this.metricFilter = MetricFilter.ALL; - } - - public Builder dropwizardRegistry(MetricRegistry registry) { - this.registry = registry; - return this; - } - - public Builder metricFilter(MetricFilter metricFilter) { - this.metricFilter = metricFilter; - return this; - } - - public Builder customLabelMapper(CustomLabelMapper labelMapper) { - this.labelMapper = labelMapper; - return this; - } - - DropwizardExports build() { - if (registry == null) { - throw new IllegalArgumentException("MetricRegistry must be set"); - } - if (labelMapper == null) { - return new DropwizardExports(registry, metricFilter); - } else { - return new DropwizardExports(registry, metricFilter, labelMapper); - } - } - - public void register() { - register(PrometheusRegistry.defaultRegistry); - } - - public void register(PrometheusRegistry registry) { - DropwizardExports dropwizardExports = build(); - registry.register(dropwizardExports); - } + public void register() { + register(PrometheusRegistry.defaultRegistry); } -} \ No newline at end of file + public void register(PrometheusRegistry registry) { + DropwizardExports dropwizardExports = build(); + registry.register(dropwizardExports); + } + } +} diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java index db5f6a64f..af45769cc 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapper.java @@ -1,117 +1,120 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; import io.prometheus.metrics.model.snapshots.Labels; - import java.util.ArrayList; import java.util.List; import java.util.Map; /** - * A LabelMapper to allow Dropwizard metrics to be translated to Prometheus metrics including custom labels and names. - * Prometheus metric name and labels are extracted from the Dropwizard name based on the provided list of {@link MapperConfig}s. - * The FIRST matching config will be used. + * A LabelMapper to allow Dropwizard metrics to be translated to Prometheus metrics including custom + * labels and names. Prometheus metric name and labels are extracted from the Dropwizard name based + * on the provided list of {@link MapperConfig}s. The FIRST matching config will be used. */ -public class CustomLabelMapper { - private final List compiledMapperConfigs; - - public CustomLabelMapper(final List mapperConfigs) { - if (mapperConfigs == null || mapperConfigs.isEmpty()) { - throw new IllegalArgumentException("CustomLabelMapper needs some mapper configs!"); - } - - this.compiledMapperConfigs = new ArrayList(mapperConfigs.size()); - for (MapperConfig config : mapperConfigs) { - this.compiledMapperConfigs.add(new CompiledMapperConfig(config)); - } +public class CustomLabelMapper { + private final List compiledMapperConfigs; + + public CustomLabelMapper(final List mapperConfigs) { + if (mapperConfigs == null || mapperConfigs.isEmpty()) { + throw new IllegalArgumentException("CustomLabelMapper needs some mapper configs!"); } - public String getName(final String dropwizardName){ - if (dropwizardName == null) { - throw new IllegalArgumentException("Dropwizard metric name cannot be null"); - } - - CompiledMapperConfig matchingConfig = null; - for (CompiledMapperConfig config : this.compiledMapperConfigs) { - if (config.pattern.matches(dropwizardName)) { - matchingConfig = config; - break; - } - } - - if (matchingConfig != null) { - final Map params = matchingConfig.pattern.extractParameters(dropwizardName); - final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params); - return nameAndLabels.name; - } - - return dropwizardName; + this.compiledMapperConfigs = new ArrayList(mapperConfigs.size()); + for (MapperConfig config : mapperConfigs) { + this.compiledMapperConfigs.add(new CompiledMapperConfig(config)); } + } + public String getName(final String dropwizardName) { + if (dropwizardName == null) { + throw new IllegalArgumentException("Dropwizard metric name cannot be null"); + } + + CompiledMapperConfig matchingConfig = null; + for (CompiledMapperConfig config : this.compiledMapperConfigs) { + if (config.pattern.matches(dropwizardName)) { + matchingConfig = config; + break; + } + } - public Labels getLabels(final String dropwizardName, final List additionalLabelNames, final List additionalLabelValues){ - if (dropwizardName == null) { - throw new IllegalArgumentException("Dropwizard metric name cannot be null"); - } - - CompiledMapperConfig matchingConfig = null; - for (CompiledMapperConfig config : this.compiledMapperConfigs) { - if (config.pattern.matches(dropwizardName)) { - matchingConfig = config; - break; - } - } - - if (matchingConfig != null) { - final Map params = matchingConfig.pattern.extractParameters(dropwizardName); - final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params); - nameAndLabels.labelNames.addAll(additionalLabelNames); - nameAndLabels.labelValues.addAll(additionalLabelValues); - return Labels.of(nameAndLabels.labelNames, nameAndLabels.labelValues); - } - - return Labels.of(additionalLabelNames, additionalLabelValues); + if (matchingConfig != null) { + final Map params = matchingConfig.pattern.extractParameters(dropwizardName); + final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params); + return nameAndLabels.name; } - protected NameAndLabels getNameAndLabels(final MapperConfig config, final Map parameters) { - final String metricName = formatTemplate(config.getName(), parameters); - final List labels = new ArrayList(config.getLabels().size()); - final List labelValues = new ArrayList(config.getLabels().size()); - for (Map.Entry entry : config.getLabels().entrySet()) { - labels.add(entry.getKey()); - labelValues.add(formatTemplate(entry.getValue(), parameters)); - } + return dropwizardName; + } - return new NameAndLabels(metricName, labels, labelValues); + public Labels getLabels( + final String dropwizardName, + final List additionalLabelNames, + final List additionalLabelValues) { + if (dropwizardName == null) { + throw new IllegalArgumentException("Dropwizard metric name cannot be null"); } - private String formatTemplate(final String template, final Map params) { - String result = template; - for (Map.Entry entry : params.entrySet()) { - result = result.replace(entry.getKey(), entry.getValue()); - } + CompiledMapperConfig matchingConfig = null; + for (CompiledMapperConfig config : this.compiledMapperConfigs) { + if (config.pattern.matches(dropwizardName)) { + matchingConfig = config; + break; + } + } + + if (matchingConfig != null) { + final Map params = matchingConfig.pattern.extractParameters(dropwizardName); + final NameAndLabels nameAndLabels = getNameAndLabels(matchingConfig.mapperConfig, params); + nameAndLabels.labelNames.addAll(additionalLabelNames); + nameAndLabels.labelValues.addAll(additionalLabelValues); + return Labels.of(nameAndLabels.labelNames, nameAndLabels.labelValues); + } - return result; + return Labels.of(additionalLabelNames, additionalLabelValues); + } + + protected NameAndLabels getNameAndLabels( + final MapperConfig config, final Map parameters) { + final String metricName = formatTemplate(config.getName(), parameters); + final List labels = new ArrayList(config.getLabels().size()); + final List labelValues = new ArrayList(config.getLabels().size()); + for (Map.Entry entry : config.getLabels().entrySet()) { + labels.add(entry.getKey()); + labelValues.add(formatTemplate(entry.getValue(), parameters)); } - static class CompiledMapperConfig { - final MapperConfig mapperConfig; - final GraphiteNamePattern pattern; + return new NameAndLabels(metricName, labels, labelValues); + } - CompiledMapperConfig(final MapperConfig mapperConfig) { - this.mapperConfig = mapperConfig; - this.pattern = new GraphiteNamePattern(mapperConfig.getMatch()); - } + private String formatTemplate(final String template, final Map params) { + String result = template; + for (Map.Entry entry : params.entrySet()) { + result = result.replace(entry.getKey(), entry.getValue()); } - static class NameAndLabels { - final String name; - final List labelNames; - final List labelValues; + return result; + } - NameAndLabels(final String name, final List labelNames, final List labelValues) { - this.name = name; - this.labelNames = labelNames; - this.labelValues = labelValues; - } + static class CompiledMapperConfig { + final MapperConfig mapperConfig; + final GraphiteNamePattern pattern; + + CompiledMapperConfig(final MapperConfig mapperConfig) { + this.mapperConfig = mapperConfig; + this.pattern = new GraphiteNamePattern(mapperConfig.getMatch()); + } + } + + static class NameAndLabels { + final String name; + final List labelNames; + final List labelValues; + + NameAndLabels( + final String name, final List labelNames, final List labelValues) { + this.name = name; + this.labelNames = labelNames; + this.labelValues = labelValues; } + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java index 4823c736f..bd37fe04c 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePattern.java @@ -1,94 +1,95 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; +import static io.prometheus.metrics.instrumentation.dropwizard5.labels.MapperConfig.METRIC_GLOB_REGEX; + import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static io.prometheus.metrics.instrumentation.dropwizard5.labels.MapperConfig.METRIC_GLOB_REGEX; - /** - * GraphiteNamePattern is initialised with a simplified glob pattern that only allows '*' as special character. - * Examples of valid patterns: + * GraphiteNamePattern is initialised with a simplified glob pattern that only allows '*' as special + * character. Examples of valid patterns: + * *

        - *
      • org.test.controller.gather.status.400
      • - *
      • org.test.controller.gather.status.*
      • - *
      • org.test.controller.*.status.*
      • - *
      • *.test.controller.*.status.*
      • + *
      • org.test.controller.gather.status.400 + *
      • org.test.controller.gather.status.* + *
      • org.test.controller.*.status.* + *
      • *.test.controller.*.status.* *
      - *

      - * It contains logic to match a metric name and to extract named parameters from it. + * + *

      It contains logic to match a metric name and to extract named parameters from it. */ class GraphiteNamePattern { - private static final Pattern VALIDATION_PATTERN = Pattern.compile(METRIC_GLOB_REGEX); + private static final Pattern VALIDATION_PATTERN = Pattern.compile(METRIC_GLOB_REGEX); - private Pattern pattern; - private String patternStr; + private Pattern pattern; + private String patternStr; - /** - * Creates a new GraphiteNamePattern from the given simplified glob pattern. - * - * @param pattern The glob style pattern to be used. - */ - GraphiteNamePattern(final String pattern) throws IllegalArgumentException { - if (!VALIDATION_PATTERN.matcher(pattern).matches()) { - throw new IllegalArgumentException(String.format("Provided pattern [%s] does not matches [%s]", pattern, METRIC_GLOB_REGEX)); - } - initializePattern(pattern); + /** + * Creates a new GraphiteNamePattern from the given simplified glob pattern. + * + * @param pattern The glob style pattern to be used. + */ + GraphiteNamePattern(final String pattern) throws IllegalArgumentException { + if (!VALIDATION_PATTERN.matcher(pattern).matches()) { + throw new IllegalArgumentException( + String.format("Provided pattern [%s] does not matches [%s]", pattern, METRIC_GLOB_REGEX)); } + initializePattern(pattern); + } - /** - * Matches the metric name against the pattern. - * - * @param metricName The metric name to be tested. - * @return {@code true} if the name is matched, {@code false} otherwise. - */ - boolean matches(final String metricName) { - return metricName != null && pattern.matcher(metricName).matches(); - } - - /** - * Extracts parameters from the given metric name based on the pattern. - * The resulting map has keys named as '${n}' where n is the 0 based position in the pattern. - * E.g.: - * pattern: org.test.controller.*.status.* - * extractParameters("org.test.controller.gather.status.400") -> - * {${0} -> "gather", ${1} -> "400"} - * - * @param metricName The metric name to extract parameters from. - * @return A parameter map where keys are named '${n}' where n is 0 based parameter position in the pattern. - */ - Map extractParameters(final String metricName) { - final Matcher matcher = this.pattern.matcher(metricName); - final Map params = new HashMap(); - if (matcher.find()) { - for (int i = 1; i <= matcher.groupCount(); i++) { - params.put(String.format("${%d}", i - 1), matcher.group(i)); - } - } + /** + * Matches the metric name against the pattern. + * + * @param metricName The metric name to be tested. + * @return {@code true} if the name is matched, {@code false} otherwise. + */ + boolean matches(final String metricName) { + return metricName != null && pattern.matcher(metricName).matches(); + } - return params; + /** + * Extracts parameters from the given metric name based on the pattern. The resulting map has keys + * named as '${n}' where n is the 0 based position in the pattern. E.g.: pattern: + * org.test.controller.*.status.* extractParameters("org.test.controller.gather.status.400") -> + * {${0} -> "gather", ${1} -> "400"} + * + * @param metricName The metric name to extract parameters from. + * @return A parameter map where keys are named '${n}' where n is 0 based parameter position in + * the pattern. + */ + Map extractParameters(final String metricName) { + final Matcher matcher = this.pattern.matcher(metricName); + final Map params = new HashMap(); + if (matcher.find()) { + for (int i = 1; i <= matcher.groupCount(); i++) { + params.put(String.format("${%d}", i - 1), matcher.group(i)); + } } - /** - * Turns the GLOB pattern into a REGEX. - * - * @param pattern The pattern to use - */ - private void initializePattern(final String pattern) { - final String[] split = pattern.split(Pattern.quote("*"), -1); - final StringBuilder escapedPattern = new StringBuilder(Pattern.quote(split[0])); - for (int i = 1; i < split.length; i++) { - String quoted = Pattern.quote(split[i]); - escapedPattern.append("([^.]*)").append(quoted); - } + return params; + } - final String regex = "^" + escapedPattern.toString() + "$"; - this.patternStr = regex; - this.pattern = Pattern.compile(regex); + /** + * Turns the GLOB pattern into a REGEX. + * + * @param pattern The pattern to use + */ + private void initializePattern(final String pattern) { + final String[] split = pattern.split(Pattern.quote("*"), -1); + final StringBuilder escapedPattern = new StringBuilder(Pattern.quote(split[0])); + for (int i = 1; i < split.length; i++) { + String quoted = Pattern.quote(split[i]); + escapedPattern.append("([^.]*)").append(quoted); } - String getPatternString() { - return this.patternStr; - } + final String regex = "^" + escapedPattern.toString() + "$"; + this.patternStr = regex; + this.pattern = Pattern.compile(regex); + } + + String getPatternString() { + return this.patternStr; + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java index c1eb1ae08..19e52d788 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java @@ -5,155 +5,143 @@ import java.util.regex.Pattern; /** - * POJO containing info on how to map a graphite metric to a prometheus one. - * Example mapping in yaml format: - *

      - * match: test.dispatcher.*.*.* - * name: dispatcher_events_total - * labels: - * action: ${1} - * outcome: ${2}_out - * processor: ${0} - * status: ${1}_${2} - *

      - * Dropwizard metrics that match the "match" pattern will be further processed to have a new name and new labels based on this config. + * POJO containing info on how to map a graphite metric to a prometheus one. Example mapping in yaml + * format: + * + *

      match: test.dispatcher.*.*.* name: dispatcher_events_total labels: action: ${1} outcome: + * ${2}_out processor: ${0} status: ${1}_${2} + * + *

      Dropwizard metrics that match the "match" pattern will be further processed to have a new name + * and new labels based on this config. */ public class MapperConfig { - // each part of the metric name between dots - private static final String METRIC_PART_REGEX = "[a-zA-Z_0-9](-?[a-zA-Z0-9_])+"; - // Simplified GLOB: we can have "*." at the beginning and "*" only at the end - static final String METRIC_GLOB_REGEX = "^(\\*\\.|" + METRIC_PART_REGEX + "\\.)+(\\*|" + METRIC_PART_REGEX + ")$"; - // Labels validation. - private static final String LABEL_REGEX = "^[a-zA-Z_][a-zA-Z0-9_]+$"; - private static final Pattern MATCH_EXPRESSION_PATTERN = Pattern.compile(METRIC_GLOB_REGEX); - private static final Pattern LABEL_PATTERN = Pattern.compile(LABEL_REGEX); - - /** - * Regex used to match incoming metric name. - * Uses a simplified glob syntax where only '*' are allowed. - * E.g: - * org.company.controller.*.status.* - * Will be used to match - * org.company.controller.controller1.status.200 - * and - * org.company.controller.controller2.status.400 - */ - private String match; - - /** - * New metric name. Can contain placeholders to be replaced with actual values from the incoming metric name. - * Placeholders are in the ${n} format where n is the zero based index of the group to extract from the original metric name. - * E.g.: - * match: test.dispatcher.*.*.* - * name: dispatcher_events_total_${1} - *

      - * A metric "test.dispatcher.old.test.yay" will be converted in a new metric with name "dispatcher_events_total_test" - */ - private String name; - - /** - * Labels to be extracted from the metric name. - * They should contain placeholders to be replaced with actual values from the incoming metric name. - * Placeholders are in the ${n} format where n is the zero based index of the group to extract from the original metric name. - * E.g.: - * match: test.dispatcher.*.* - * name: dispatcher_events_total_${0} - * labels: - * label1: ${1}_t - *

      - * A metric "test.dispatcher.sp1.yay" will be converted in a new metric with name "dispatcher_events_total_sp1" with label {label1: yay_t} - *

      - * Label names have to match the regex ^[a-zA-Z_][a-zA-Z0-9_]+$ - */ - - private Map labels = new HashMap(); - - public MapperConfig() { - // empty constructor + // each part of the metric name between dots + private static final String METRIC_PART_REGEX = "[a-zA-Z_0-9](-?[a-zA-Z0-9_])+"; + // Simplified GLOB: we can have "*." at the beginning and "*" only at the end + static final String METRIC_GLOB_REGEX = + "^(\\*\\.|" + METRIC_PART_REGEX + "\\.)+(\\*|" + METRIC_PART_REGEX + ")$"; + // Labels validation. + private static final String LABEL_REGEX = "^[a-zA-Z_][a-zA-Z0-9_]+$"; + private static final Pattern MATCH_EXPRESSION_PATTERN = Pattern.compile(METRIC_GLOB_REGEX); + private static final Pattern LABEL_PATTERN = Pattern.compile(LABEL_REGEX); + + /** + * Regex used to match incoming metric name. Uses a simplified glob syntax where only '*' are + * allowed. E.g: org.company.controller.*.status.* Will be used to match + * org.company.controller.controller1.status.200 and org.company.controller.controller2.status.400 + */ + private String match; + + /** + * New metric name. Can contain placeholders to be replaced with actual values from the incoming + * metric name. Placeholders are in the ${n} format where n is the zero based index of the group + * to extract from the original metric name. E.g.: match: test.dispatcher.*.*.* name: + * dispatcher_events_total_${1} + * + *

      A metric "test.dispatcher.old.test.yay" will be converted in a new metric with name + * "dispatcher_events_total_test" + */ + private String name; + + /** + * Labels to be extracted from the metric name. They should contain placeholders to be replaced + * with actual values from the incoming metric name. Placeholders are in the ${n} format where n + * is the zero based index of the group to extract from the original metric name. E.g.: match: + * test.dispatcher.*.* name: dispatcher_events_total_${0} labels: label1: ${1}_t + * + *

      A metric "test.dispatcher.sp1.yay" will be converted in a new metric with name + * "dispatcher_events_total_sp1" with label {label1: yay_t} + * + *

      Label names have to match the regex ^[a-zA-Z_][a-zA-Z0-9_]+$ + */ + private Map labels = new HashMap(); + + public MapperConfig() { + // empty constructor + } + + // for tests + MapperConfig(final String match) { + validateMatch(match); + this.match = match; + } + + public MapperConfig(final String match, final String name, final Map labels) { + this.name = name; + validateMatch(match); + this.match = match; + validateLabels(labels); + this.labels = labels; + } + + @Override + public String toString() { + return String.format("MapperConfig{match=%s, name=%s, labels=%s}", match, name, labels); + } + + public String getMatch() { + return match; + } + + public void setMatch(final String match) { + validateMatch(match); + this.match = match; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public Map getLabels() { + return labels; + } + + public void setLabels(final Map labels) { + validateLabels(labels); + this.labels = labels; + } + + private void validateMatch(final String match) { + if (!MATCH_EXPRESSION_PATTERN.matcher(match).matches()) { + throw new IllegalArgumentException( + String.format( + "Match expression [%s] does not match required pattern %s", + match, MATCH_EXPRESSION_PATTERN)); } - - // for tests - MapperConfig(final String match) { - validateMatch(match); - this.match = match; - } - - public MapperConfig(final String match, final String name, final Map labels) { - this.name = name; - validateMatch(match); - this.match = match; - validateLabels(labels); - this.labels = labels; - } - - @Override - public String toString() { - return String.format("MapperConfig{match=%s, name=%s, labels=%s}", match, name, labels); - } - - public String getMatch() { - return match; - } - - public void setMatch(final String match) { - validateMatch(match); - this.match = match; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - - } - - public Map getLabels() { - return labels; - } - - public void setLabels(final Map labels) { - validateLabels(labels); - this.labels = labels; - } - - private void validateMatch(final String match) - { - if (!MATCH_EXPRESSION_PATTERN.matcher(match).matches()) { - throw new IllegalArgumentException(String.format("Match expression [%s] does not match required pattern %s", match, MATCH_EXPRESSION_PATTERN)); + } + + private void validateLabels(final Map labels) { + if (labels != null) { + for (final String key : labels.keySet()) { + if (!LABEL_PATTERN.matcher(key).matches()) { + throw new IllegalArgumentException( + String.format("Label [%s] does not match required pattern %s", match, LABEL_PATTERN)); } + } } - - private void validateLabels(final Map labels) - { - if (labels != null) { - for (final String key : labels.keySet()) { - if (!LABEL_PATTERN.matcher(key).matches()) { - throw new IllegalArgumentException(String.format("Label [%s] does not match required pattern %s", match, LABEL_PATTERN)); - } - } - - } - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final MapperConfig that = (MapperConfig) o; - - if (match != null ? !match.equals(that.match) : that.match != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - return labels != null ? labels.equals(that.labels) : that.labels == null; - } - - @Override - public int hashCode() { - int result = match != null ? match.hashCode() : 0; - result = 31 * result + (name != null ? name.hashCode() : 0); - result = 31 * result + (labels != null ? labels.hashCode() : 0); - return result; - } + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final MapperConfig that = (MapperConfig) o; + + if (match != null ? !match.equals(that.match) : that.match != null) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + return labels != null ? labels.equals(that.labels) : that.labels == null; + } + + @Override + public int hashCode() { + int result = match != null ? match.hashCode() : 0; + result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (labels != null ? labels.hashCode() : 0); + return result; + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java index 6fbbb68b1..0473329ce 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java @@ -1,298 +1,313 @@ package io.prometheus.metrics.instrumentation.dropwizard5; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import io.dropwizard.metrics5.*; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.Quantiles; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; public class DropwizardExportsTest { - private PrometheusRegistry registry = new PrometheusRegistry(); - private MetricRegistry metricRegistry; - - - @Before - public void setUp() { - metricRegistry = new MetricRegistry(); - DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(registry); - } - - - @Test - public void testCounter() { - metricRegistry.counter("foo.bar").inc(1); - String expected = "# TYPE foo_bar counter\n" + - "# HELP foo_bar Generated from Dropwizard metric import (metric=foo.bar, type=io.dropwizard.metrics5.Counter)\n" + - "foo_bar_total 1.0\n" + - "# EOF\n"; - - assertEquals(expected, convertToOpenMetricsFormat()); - } - - @Test - public void testGauge() { - Gauge integerGauge = new Gauge() { - @Override - public Integer getValue() { - return 1234; - } + private PrometheusRegistry registry = new PrometheusRegistry(); + private MetricRegistry metricRegistry; + + @Before + public void setUp() { + metricRegistry = new MetricRegistry(); + DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(registry); + } + + @Test + public void testCounter() { + metricRegistry.counter("foo.bar").inc(1); + String expected = + "# TYPE foo_bar counter\n" + + "# HELP foo_bar Generated from Dropwizard metric import (metric=foo.bar, type=io.dropwizard.metrics5.Counter)\n" + + "foo_bar_total 1.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat()); + } + + @Test + public void testGauge() { + Gauge integerGauge = + new Gauge() { + @Override + public Integer getValue() { + return 1234; + } }; - Gauge doubleGauge = new Gauge() { - @Override - public Double getValue() { - return 1.234D; - } + Gauge doubleGauge = + new Gauge() { + @Override + public Double getValue() { + return 1.234D; + } }; - Gauge longGauge = new Gauge() { - @Override - public Long getValue() { - return 1234L; - } + Gauge longGauge = + new Gauge() { + @Override + public Long getValue() { + return 1234L; + } }; - Gauge floatGauge = new Gauge() { - @Override - public Float getValue() { - return 0.1234F; - } + Gauge floatGauge = + new Gauge() { + @Override + public Float getValue() { + return 0.1234F; + } }; - Gauge booleanGauge = new Gauge() { - @Override - public Boolean getValue() { - return true; - } + Gauge booleanGauge = + new Gauge() { + @Override + public Boolean getValue() { + return true; + } }; - metricRegistry.register("double.gauge", doubleGauge); - metricRegistry.register("long.gauge", longGauge); - metricRegistry.register("integer.gauge", integerGauge); - metricRegistry.register("float.gauge", floatGauge); - metricRegistry.register("boolean.gauge", booleanGauge); - - String expected = "# TYPE boolean_gauge gauge\n" + - "# HELP boolean_gauge Generated from Dropwizard metric import (metric=boolean.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$5)\n" + - "boolean_gauge 1.0\n" + - "# TYPE double_gauge gauge\n" + - "# HELP double_gauge Generated from Dropwizard metric import (metric=double.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$2)\n" + - "double_gauge 1.234\n" + - "# TYPE float_gauge gauge\n" + - "# HELP float_gauge Generated from Dropwizard metric import (metric=float.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$4)\n" + - "float_gauge 0.1234000027179718\n" + - "# TYPE integer_gauge gauge\n" + - "# HELP integer_gauge Generated from Dropwizard metric import (metric=integer.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$1)\n" + - "integer_gauge 1234.0\n" + - "# TYPE long_gauge gauge\n" + - "# HELP long_gauge Generated from Dropwizard metric import (metric=long.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$3)\n" + - "long_gauge 1234.0\n" + - "# EOF\n"; - - assertEquals(expected, convertToOpenMetricsFormat()); - } - - @Test - public void testInvalidGaugeType() { - Gauge invalidGauge = new Gauge() { - @Override - public String getValue() { - return "foobar"; - } + metricRegistry.register("double.gauge", doubleGauge); + metricRegistry.register("long.gauge", longGauge); + metricRegistry.register("integer.gauge", integerGauge); + metricRegistry.register("float.gauge", floatGauge); + metricRegistry.register("boolean.gauge", booleanGauge); + + String expected = + "# TYPE boolean_gauge gauge\n" + + "# HELP boolean_gauge Generated from Dropwizard metric import (metric=boolean.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$5)\n" + + "boolean_gauge 1.0\n" + + "# TYPE double_gauge gauge\n" + + "# HELP double_gauge Generated from Dropwizard metric import (metric=double.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$2)\n" + + "double_gauge 1.234\n" + + "# TYPE float_gauge gauge\n" + + "# HELP float_gauge Generated from Dropwizard metric import (metric=float.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$4)\n" + + "float_gauge 0.1234000027179718\n" + + "# TYPE integer_gauge gauge\n" + + "# HELP integer_gauge Generated from Dropwizard metric import (metric=integer.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$1)\n" + + "integer_gauge 1234.0\n" + + "# TYPE long_gauge gauge\n" + + "# HELP long_gauge Generated from Dropwizard metric import (metric=long.gauge, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$3)\n" + + "long_gauge 1234.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat()); + } + + @Test + public void testInvalidGaugeType() { + Gauge invalidGauge = + new Gauge() { + @Override + public String getValue() { + return "foobar"; + } }; - metricRegistry.register("invalid_gauge", invalidGauge); + metricRegistry.register("invalid_gauge", invalidGauge); - String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); - } + String expected = "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat()); + } - @Test - public void testGaugeReturningNullValue() { - Gauge invalidGauge = new Gauge() { - @Override - public String getValue() { - return null; - } + @Test + public void testGaugeReturningNullValue() { + Gauge invalidGauge = + new Gauge() { + @Override + public String getValue() { + return null; + } }; - metricRegistry.register("invalid_gauge", invalidGauge); - String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + metricRegistry.register("invalid_gauge", invalidGauge); + String expected = "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat()); + } + + @Test + public void testHistogram() throws IOException { + // just test the standard mapper + final MetricRegistry metricRegistry = new MetricRegistry(); + PrometheusRegistry pmRegistry = new PrometheusRegistry(); + DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(pmRegistry); + + Histogram hist = metricRegistry.histogram("hist"); + int i = 0; + while (i < 100) { + hist.update(i); + i += 1; } - @Test - public void testHistogram() throws IOException { - // just test the standard mapper - final MetricRegistry metricRegistry = new MetricRegistry(); - PrometheusRegistry pmRegistry = new PrometheusRegistry(); - DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(pmRegistry); - - Histogram hist = metricRegistry.histogram("hist"); - int i = 0; - while (i < 100) { - hist.update(i); - i += 1; - } - - // The result should look like this - // - // # TYPE hist summary - // # HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram) - // hist{quantile="0.5"} 49.0 - // hist{quantile="0.75"} 74.0 - // hist{quantile="0.95"} 94.0 - // hist{quantile="0.98"} 97.0 - // hist{quantile="0.99"} 98.0 - // hist{quantile="0.999"} 99.0 - // hist_count 100 - // # EOF - // - // However, Dropwizard uses a random reservoir sampling algorithm, so the values could as well be off-by-one - // - // # TYPE hist summary - // # HELP hist Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram) - // hist{quantile="0.5"} 50.0 - // hist{quantile="0.75"} 75.0 - // hist{quantile="0.95"} 95.0 - // hist{quantile="0.98"} 98.0 - // hist{quantile="0.99"} 99.0 - // hist{quantile="0.999"} 99.0 - // hist_count 100 - // # EOF - // - // The following asserts the values, but allows an error of 1.0 for quantile values. - - MetricSnapshots snapshots = pmRegistry.scrape(name -> name.equals("hist")); - Assert.assertEquals(1, snapshots.size()); - SummarySnapshot snapshot = (SummarySnapshot) snapshots.get(0); - Assert.assertEquals("hist", snapshot.getMetadata().getName()); - Assert.assertEquals("Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)", snapshot.getMetadata().getHelp()); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - SummarySnapshot.SummaryDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0); - Assert.assertTrue(dataPoint.hasCount()); - Assert.assertEquals(100, dataPoint.getCount()); - Assert.assertFalse(dataPoint.hasSum()); - Quantiles quantiles = dataPoint.getQuantiles(); - Assert.assertEquals(6, quantiles.size()); - Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0.0); - Assert.assertEquals(49.0, quantiles.get(0).getValue(), 1.0); - Assert.assertEquals(0.75, quantiles.get(1).getQuantile(), 0.0); - Assert.assertEquals(74.0, quantiles.get(1).getValue(), 1.0); - Assert.assertEquals(0.95, quantiles.get(2).getQuantile(), 0.0); - Assert.assertEquals(94.0, quantiles.get(2).getValue(), 1.0); - Assert.assertEquals(0.98, quantiles.get(3).getQuantile(), 0.0); - Assert.assertEquals(97.0, quantiles.get(3).getValue(), 1.0); - Assert.assertEquals(0.99, quantiles.get(4).getQuantile(), 0.0); - Assert.assertEquals(98.0, quantiles.get(4).getValue(), 1.0); - Assert.assertEquals(0.999, quantiles.get(5).getQuantile(), 0.0); - Assert.assertEquals(99.0, quantiles.get(5).getValue(), 1.0); + // The result should look like this + // + // # TYPE hist summary + // # HELP hist Generated from Dropwizard metric import (metric=hist, + // type=io.dropwizard.metrics5.Histogram) + // hist{quantile="0.5"} 49.0 + // hist{quantile="0.75"} 74.0 + // hist{quantile="0.95"} 94.0 + // hist{quantile="0.98"} 97.0 + // hist{quantile="0.99"} 98.0 + // hist{quantile="0.999"} 99.0 + // hist_count 100 + // # EOF + // + // However, Dropwizard uses a random reservoir sampling algorithm, so the values could as well + // be off-by-one + // + // # TYPE hist summary + // # HELP hist Generated from Dropwizard metric import (metric=hist, + // type=io.dropwizard.metrics5.Histogram) + // hist{quantile="0.5"} 50.0 + // hist{quantile="0.75"} 75.0 + // hist{quantile="0.95"} 95.0 + // hist{quantile="0.98"} 98.0 + // hist{quantile="0.99"} 99.0 + // hist{quantile="0.999"} 99.0 + // hist_count 100 + // # EOF + // + // The following asserts the values, but allows an error of 1.0 for quantile values. + + MetricSnapshots snapshots = pmRegistry.scrape(name -> name.equals("hist")); + Assert.assertEquals(1, snapshots.size()); + SummarySnapshot snapshot = (SummarySnapshot) snapshots.get(0); + Assert.assertEquals("hist", snapshot.getMetadata().getName()); + Assert.assertEquals( + "Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)", + snapshot.getMetadata().getHelp()); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + SummarySnapshot.SummaryDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0); + Assert.assertTrue(dataPoint.hasCount()); + Assert.assertEquals(100, dataPoint.getCount()); + Assert.assertFalse(dataPoint.hasSum()); + Quantiles quantiles = dataPoint.getQuantiles(); + Assert.assertEquals(6, quantiles.size()); + Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0.0); + Assert.assertEquals(49.0, quantiles.get(0).getValue(), 1.0); + Assert.assertEquals(0.75, quantiles.get(1).getQuantile(), 0.0); + Assert.assertEquals(74.0, quantiles.get(1).getValue(), 1.0); + Assert.assertEquals(0.95, quantiles.get(2).getQuantile(), 0.0); + Assert.assertEquals(94.0, quantiles.get(2).getValue(), 1.0); + Assert.assertEquals(0.98, quantiles.get(3).getQuantile(), 0.0); + Assert.assertEquals(97.0, quantiles.get(3).getValue(), 1.0); + Assert.assertEquals(0.99, quantiles.get(4).getQuantile(), 0.0); + Assert.assertEquals(98.0, quantiles.get(4).getValue(), 1.0); + Assert.assertEquals(0.999, quantiles.get(5).getQuantile(), 0.0); + Assert.assertEquals(99.0, quantiles.get(5).getValue(), 1.0); + } + + @Test + public void testMeter() { + Meter meter = metricRegistry.meter("meter"); + meter.mark(); + meter.mark(); + + String expected = + "# TYPE meter counter\n" + + "# HELP meter Generated from Dropwizard metric import (metric=meter_total, type=io.dropwizard.metrics5.Meter)\n" + + "meter_total 2.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat()); + } + + @Test + public void testTimer() throws InterruptedException { + final MetricRegistry metricRegistry = new MetricRegistry(); + DropwizardExports exports = new DropwizardExports(metricRegistry); + Timer t = metricRegistry.timer("timer"); + Timer.Context time = t.time(); + Thread.sleep(100L); + long timeSpentNanos = time.stop(); + double timeSpentMillis = TimeUnit.NANOSECONDS.toMillis(timeSpentNanos); + System.out.println(timeSpentMillis); + + SummarySnapshot.SummaryDataPointSnapshot dataPointSnapshot = + (SummarySnapshot.SummaryDataPointSnapshot) + exports.collect().stream().flatMap(i -> i.getDataPoints().stream()).findFirst().get(); + // We slept for 1Ms so we ensure that all timers are above 1ms: + assertTrue(dataPointSnapshot.getQuantiles().size() > 1); + dataPointSnapshot + .getQuantiles() + .forEach( + i -> { + System.out.println(i.getQuantile() + " : " + i.getValue()); + assertTrue(i.getValue() > timeSpentMillis / 1000d); + }); + assertEquals(1, dataPointSnapshot.getCount()); + } + + @Test + public void testThatMetricHelpUsesOriginalDropwizardName() { + + metricRegistry.timer("my.application.namedTimer1"); + metricRegistry.counter("my.application.namedCounter1"); + metricRegistry.meter("my.application.namedMeter1"); + metricRegistry.histogram("my.application.namedHistogram1"); + metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge()); + + String expected = + "# TYPE my_application_namedCounter1 counter\n" + + "# HELP my_application_namedCounter1 Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=io.dropwizard.metrics5.Counter)\n" + + "my_application_namedCounter1_total 0.0\n" + + "# TYPE my_application_namedGauge1 gauge\n" + + "# HELP my_application_namedGauge1 Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$ExampleDoubleGauge)\n" + + "my_application_namedGauge1 0.0\n" + + "# TYPE my_application_namedHistogram1 summary\n" + + "# HELP my_application_namedHistogram1 Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=io.dropwizard.metrics5.Histogram)\n" + + "my_application_namedHistogram1{quantile=\"0.5\"} 0.0\n" + + "my_application_namedHistogram1{quantile=\"0.75\"} 0.0\n" + + "my_application_namedHistogram1{quantile=\"0.95\"} 0.0\n" + + "my_application_namedHistogram1{quantile=\"0.98\"} 0.0\n" + + "my_application_namedHistogram1{quantile=\"0.99\"} 0.0\n" + + "my_application_namedHistogram1{quantile=\"0.999\"} 0.0\n" + + "my_application_namedHistogram1_count 0\n" + + "# TYPE my_application_namedMeter1 counter\n" + + "# HELP my_application_namedMeter1 Generated from Dropwizard metric import (metric=my.application.namedMeter1_total, type=io.dropwizard.metrics5.Meter)\n" + + "my_application_namedMeter1_total 0.0\n" + + "# TYPE my_application_namedTimer1 summary\n" + + "# HELP my_application_namedTimer1 Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=io.dropwizard.metrics5.Timer)\n" + + "my_application_namedTimer1{quantile=\"0.5\"} 0.0\n" + + "my_application_namedTimer1{quantile=\"0.75\"} 0.0\n" + + "my_application_namedTimer1{quantile=\"0.95\"} 0.0\n" + + "my_application_namedTimer1{quantile=\"0.98\"} 0.0\n" + + "my_application_namedTimer1{quantile=\"0.99\"} 0.0\n" + + "my_application_namedTimer1{quantile=\"0.999\"} 0.0\n" + + "my_application_namedTimer1_count 0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat()); + } + + private static class ExampleDoubleGauge implements Gauge { + @Override + public Double getValue() { + return 0.0; } - - @Test - public void testMeter() { - Meter meter = metricRegistry.meter("meter"); - meter.mark(); - meter.mark(); - - String expected = "# TYPE meter counter\n" + - "# HELP meter Generated from Dropwizard metric import (metric=meter_total, type=io.dropwizard.metrics5.Meter)\n" + - "meter_total 2.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); - + } + + private String convertToOpenMetricsFormat(PrometheusRegistry _registry) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, _registry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new RuntimeException(e); } + } - @Test - public void testTimer() throws InterruptedException { - final MetricRegistry metricRegistry = new MetricRegistry(); - DropwizardExports exports = new DropwizardExports(metricRegistry); - Timer t = metricRegistry.timer("timer"); - Timer.Context time = t.time(); - Thread.sleep(100L); - long timeSpentNanos = time.stop(); - double timeSpentMillis = TimeUnit.NANOSECONDS.toMillis(timeSpentNanos); - System.out.println(timeSpentMillis); - - SummarySnapshot.SummaryDataPointSnapshot dataPointSnapshot = (SummarySnapshot.SummaryDataPointSnapshot) exports.collect().stream().flatMap(i -> i.getDataPoints().stream()).findFirst().get(); - // We slept for 1Ms so we ensure that all timers are above 1ms: - assertTrue(dataPointSnapshot.getQuantiles().size() > 1); - dataPointSnapshot.getQuantiles().forEach( i-> { - System.out.println(i.getQuantile() + " : " + i.getValue()); - assertTrue(i.getValue() > timeSpentMillis/1000d); - }); - assertEquals(1, dataPointSnapshot.getCount()); - } - - @Test - public void testThatMetricHelpUsesOriginalDropwizardName() { - - metricRegistry.timer("my.application.namedTimer1"); - metricRegistry.counter("my.application.namedCounter1"); - metricRegistry.meter("my.application.namedMeter1"); - metricRegistry.histogram("my.application.namedHistogram1"); - metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge()); - - String expected = "# TYPE my_application_namedCounter1 counter\n" + - "# HELP my_application_namedCounter1 Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=io.dropwizard.metrics5.Counter)\n" + - "my_application_namedCounter1_total 0.0\n" + - "# TYPE my_application_namedGauge1 gauge\n" + - "# HELP my_application_namedGauge1 Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExportsTest$ExampleDoubleGauge)\n" + - "my_application_namedGauge1 0.0\n" + - "# TYPE my_application_namedHistogram1 summary\n" + - "# HELP my_application_namedHistogram1 Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=io.dropwizard.metrics5.Histogram)\n" + - "my_application_namedHistogram1{quantile=\"0.5\"} 0.0\n" + - "my_application_namedHistogram1{quantile=\"0.75\"} 0.0\n" + - "my_application_namedHistogram1{quantile=\"0.95\"} 0.0\n" + - "my_application_namedHistogram1{quantile=\"0.98\"} 0.0\n" + - "my_application_namedHistogram1{quantile=\"0.99\"} 0.0\n" + - "my_application_namedHistogram1{quantile=\"0.999\"} 0.0\n" + - "my_application_namedHistogram1_count 0\n" + - "# TYPE my_application_namedMeter1 counter\n" + - "# HELP my_application_namedMeter1 Generated from Dropwizard metric import (metric=my.application.namedMeter1_total, type=io.dropwizard.metrics5.Meter)\n" + - "my_application_namedMeter1_total 0.0\n" + - "# TYPE my_application_namedTimer1 summary\n" + - "# HELP my_application_namedTimer1 Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=io.dropwizard.metrics5.Timer)\n" + - "my_application_namedTimer1{quantile=\"0.5\"} 0.0\n" + - "my_application_namedTimer1{quantile=\"0.75\"} 0.0\n" + - "my_application_namedTimer1{quantile=\"0.95\"} 0.0\n" + - "my_application_namedTimer1{quantile=\"0.98\"} 0.0\n" + - "my_application_namedTimer1{quantile=\"0.99\"} 0.0\n" + - "my_application_namedTimer1{quantile=\"0.999\"} 0.0\n" + - "my_application_namedTimer1_count 0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); - } - - - private static class ExampleDoubleGauge implements Gauge { - @Override - public Double getValue() { - return 0.0; - } - } - - private String convertToOpenMetricsFormat(PrometheusRegistry _registry) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - try { - writer.write(out, _registry.scrape()); - return out.toString(StandardCharsets.UTF_8.name()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String convertToOpenMetricsFormat() { - return convertToOpenMetricsFormat(registry); - } + private String convertToOpenMetricsFormat() { + return convertToOpenMetricsFormat(registry); + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java index d5003332c..5d1950111 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java @@ -1,213 +1,214 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; +import static org.junit.Assert.assertEquals; + import io.dropwizard.metrics5.MetricFilter; import io.dropwizard.metrics5.MetricRegistry; -import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.instrumentation.dropwizard5.DropwizardExports; -import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Before; -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; - -import static org.junit.Assert.assertEquals; +import org.junit.Before; +import org.junit.Test; public class CustomLabelMapperTest { - private MetricRegistry metricRegistry; - - - @Before - public void setUp() { - metricRegistry = new MetricRegistry(); - } - - @Test(expected = IllegalArgumentException.class) - public void test_WHEN_EmptyConfig_THEN_Fail() { - final CustomLabelMapper converter = new CustomLabelMapper(Collections.emptyList()); - } - - @Test - public void test_WHEN_NoMatches_THEN_ShouldReturnDefaultSample() { - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - new MapperConfig("*.client-nope.*.*.*"), - new MapperConfig("not.even.this.*.*.*") - ); - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); - - metricRegistry.counter("app.okhttpclient.client.HttpClient.service.total").inc(1); - System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect())); - - String expected = "# TYPE app_okhttpclient_client_HttpClient_service counter\n" + - "# HELP app_okhttpclient_client_HttpClient_service Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.service.total, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_service_total 1.0\n" + - "# EOF\n"; - - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + private MetricRegistry metricRegistry; + + @Before + public void setUp() { + metricRegistry = new MetricRegistry(); + } + + @Test(expected = IllegalArgumentException.class) + public void test_WHEN_EmptyConfig_THEN_Fail() { + final CustomLabelMapper converter = + new CustomLabelMapper(Collections.emptyList()); + } + + @Test + public void test_WHEN_NoMatches_THEN_ShouldReturnDefaultSample() { + final List mapperConfigs = + Arrays.asList( + new MapperConfig("client-nope.*.*.*"), + new MapperConfig("*.client-nope.*.*.*"), + new MapperConfig("not.even.this.*.*.*")); + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + + metricRegistry.counter("app.okhttpclient.client.HttpClient.service.total").inc(1); + System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect())); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient_service counter\n" + + "# HELP app_okhttpclient_client_HttpClient_service Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.service.total, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_service_total 1.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + @Test + public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() { + final Map labels = new HashMap(); + labels.put("service", "${0}"); + final MapperConfig mapperConfig = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.total", + "app.okhttpclient.client.HttpClient.total", + labels); + final List mapperConfigs = + Arrays.asList( + new MapperConfig("client-nope.*.*.*"), + mapperConfig, + new MapperConfig("not.even.this.*.*.*")); + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + + metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient counter\n" + + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + @Test + public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() { + final Map labels = new HashMap(); + labels.put("service", "${0}"); + final MapperConfig mapperConfig = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.total", + "app.okhttpclient.client.HttpClient.total", + labels); + final List mapperConfigs = + Arrays.asList( + new MapperConfig("client-nope.*.*.*"), + mapperConfig, + new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well + ); + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + + metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient counter\n" + + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + @Test + public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { + final Map labels = new LinkedHashMap(); + labels.put("service", "${0}"); + labels.put("status", "${1}"); + final MapperConfig mapperConfig = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.*", "app.okhttpclient.client.HttpClient", labels); + + final MapperConfig mapperConfig2 = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.*", + "app.okhttpclient.client.HttpClient2", + labels); + + final List mapperConfigs = + Arrays.asList( + new MapperConfig("client-nope.*.*.*"), + mapperConfig, + mapperConfig2 // this matches as well + ); + + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient counter\n" + + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_total{service=\"greatService\",status=\"400\"} 1.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + @Test + public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() { + final Map labels = new LinkedHashMap(); + labels.put("service", "${0}_${1}"); + labels.put("status", "s_${1}"); + final MapperConfig mapperConfig = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.*", + "app.okhttpclient.client.HttpClient.${0}", + labels); + final List mapperConfigs = + Arrays.asList( + new MapperConfig("client-nope.*.*.*"), + mapperConfig, + new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well + ); + + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); + System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect())); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" + + "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + @Test + public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() { + final Map labels = new LinkedHashMap(); + labels.put("service", "${0}"); + labels.put("status", "s_${1}"); + labels.put("client", "sampleClient"); + final MapperConfig mapperConfig = + new MapperConfig( + "app.okhttpclient.client.HttpClient.*.*", + "app.okhttpclient.client.HttpClient.${0}", + labels); + final List mapperConfigs = + Arrays.asList(new MapperConfig("client-nope.*.*.*"), mapperConfig); + + final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); + DropwizardExports dropwizardExports = + new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); + metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); + + String expected = + "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" + + "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + + "app_okhttpclient_client_HttpClient_greatService_total{client=\"sampleClient\",service=\"greatService\",status=\"s_400\"} 1.0\n" + + "# EOF\n"; + assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + } + + private String convertToOpenMetricsFormat(MetricSnapshots snapshots) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, snapshots); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new RuntimeException(e); } - - @Test - public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() { - final Map labels = new HashMap(); - labels.put("service", "${0}"); - final MapperConfig mapperConfig = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.total", - "app.okhttpclient.client.HttpClient.total", - labels - ); - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - mapperConfig, - new MapperConfig("not.even.this.*.*.*") - ); - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); - - metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1); - - String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" + - "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); - } - - @Test - public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() { - final Map labels = new HashMap(); - labels.put("service", "${0}"); - final MapperConfig mapperConfig = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.total", - "app.okhttpclient.client.HttpClient.total", - labels - ); - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - mapperConfig, - new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well - ); - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); - - metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.total").inc(1); - - - String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" + - "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); - } - - @Test - public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { - final Map labels = new LinkedHashMap(); - labels.put("service", "${0}"); - labels.put("status", "${1}"); - final MapperConfig mapperConfig = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.*", - "app.okhttpclient.client.HttpClient", - labels - ); - - final MapperConfig mapperConfig2 = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.*", - "app.okhttpclient.client.HttpClient2", - labels - ); - - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - mapperConfig, - mapperConfig2 // this matches as well - ); - - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry, MetricFilter.ALL, labelMapper); - metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); - - String expected = "# TYPE app_okhttpclient_client_HttpClient counter\n" + - "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_total{service=\"greatService\",status=\"400\"} 1.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); - - } - - @Test - public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() { - final Map labels = new LinkedHashMap(); - labels.put("service", "${0}_${1}"); - labels.put("status", "s_${1}"); - final MapperConfig mapperConfig = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.*", - "app.okhttpclient.client.HttpClient.${0}", - labels - ); - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - mapperConfig, - new MapperConfig("app.okhttpclient.client.HttpClient.*.*") // this matches as well - ); - - - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry,MetricFilter.ALL, labelMapper); - metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); - System.out.println(convertToOpenMetricsFormat(dropwizardExports.collect())); - - - String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" + - "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); - } - - - @Test - public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() { - final Map labels = new LinkedHashMap(); - labels.put("service", "${0}"); - labels.put("status", "s_${1}"); - labels.put("client", "sampleClient"); - final MapperConfig mapperConfig = new MapperConfig( - "app.okhttpclient.client.HttpClient.*.*", - "app.okhttpclient.client.HttpClient.${0}", - labels - ); - final List mapperConfigs = Arrays.asList( - new MapperConfig("client-nope.*.*.*"), - mapperConfig - ); - - final CustomLabelMapper labelMapper = new CustomLabelMapper(mapperConfigs); - DropwizardExports dropwizardExports = new DropwizardExports(metricRegistry,MetricFilter.ALL, labelMapper); - metricRegistry.counter("app.okhttpclient.client.HttpClient.greatService.400").inc(1); - - String expected = "# TYPE app_okhttpclient_client_HttpClient_greatService counter\n" + - "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + - "app_okhttpclient_client_HttpClient_greatService_total{client=\"sampleClient\",service=\"greatService\",status=\"s_400\"} 1.0\n" + - "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); - } - - - private String convertToOpenMetricsFormat(MetricSnapshots snapshots) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - try { - writer.write(out, snapshots); - return out.toString(StandardCharsets.UTF_8.name()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - + } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java index 5b704e6bd..9e8316d0b 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java @@ -1,144 +1,147 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; -import org.assertj.core.api.Assertions; -import org.junit.Test; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.assertj.core.api.Assertions; +import org.junit.Test; public class GraphiteNamePatternTest { - @Test(expected = IllegalArgumentException.class) - public void createNew_WHEN_InvalidPattern_THEN_ShouldThrowException() { - final List invalidPatterns = Arrays.asList( - "", - "a", - "1org", - "1org.", - "org.", - "org.**", - "org.**", - "org.company-", - "org.company-.", - "org.company-*", - "org.company.**", - "org.company.**-", - "org.com*pany.*", - "org.test.contr.oller.gather.status..400", - "org.test.controller.gather.status..400" - ); - final GraphiteNamePattern graphiteNamePattern = new GraphiteNamePattern(""); - for (String pattern : invalidPatterns) { - try { - new GraphiteNamePattern(pattern); - - Assertions.failBecauseExceptionWasNotThrown(IllegalArgumentException.class); - } catch (IllegalArgumentException e) { - Assertions.assertThat(e).hasMessageContaining(pattern); - } - } + @Test(expected = IllegalArgumentException.class) + public void createNew_WHEN_InvalidPattern_THEN_ShouldThrowException() { + final List invalidPatterns = + Arrays.asList( + "", + "a", + "1org", + "1org.", + "org.", + "org.**", + "org.**", + "org.company-", + "org.company-.", + "org.company-*", + "org.company.**", + "org.company.**-", + "org.com*pany.*", + "org.test.contr.oller.gather.status..400", + "org.test.controller.gather.status..400"); + final GraphiteNamePattern graphiteNamePattern = new GraphiteNamePattern(""); + for (String pattern : invalidPatterns) { + try { + new GraphiteNamePattern(pattern); + + Assertions.failBecauseExceptionWasNotThrown(IllegalArgumentException.class); + } catch (IllegalArgumentException e) { + Assertions.assertThat(e).hasMessageContaining(pattern); + } } - - @Test - public void createNew_WHEN_ValidPattern_THEN_ShouldCreateThePatternSuccessfully() { - final List validPatterns = Arrays.asList( - "org.test.controller.gather.status.400", - "org.test.controller.*.status.400", - "org.test.controller.*.status.*", - "*.test.controller.*.status.*", - "*.test.controller-1.*.status.*", - "*.amazing-test.controller-1.*.status.*" - - ); - for (String pattern : validPatterns) { - new GraphiteNamePattern(pattern); - } + } + + @Test + public void createNew_WHEN_ValidPattern_THEN_ShouldCreateThePatternSuccessfully() { + final List validPatterns = + Arrays.asList( + "org.test.controller.gather.status.400", + "org.test.controller.*.status.400", + "org.test.controller.*.status.*", + "*.test.controller.*.status.*", + "*.test.controller-1.*.status.*", + "*.amazing-test.controller-1.*.status.*"); + for (String pattern : validPatterns) { + new GraphiteNamePattern(pattern); } - - @Test - public void createNew_WHEN_ValidPattern_THEN_ShouldInitInternalPatternSuccessfully() { - final Map validPatterns = new HashMap(); - validPatterns.put("org.test.controller.gather.status.400", "^\\Qorg.test.controller.gather.status.400\\E$"); - validPatterns.put("org.test.controller.*.status.400", "^\\Qorg.test.controller.\\E([^.]*)\\Q.status.400\\E$"); - validPatterns.put("org.test.controller.*.status.*", "^\\Qorg.test.controller.\\E([^.]*)\\Q.status.\\E([^.]*)\\Q\\E$"); - validPatterns.put("*.test.controller.*.status.*", "^\\Q\\E([^.]*)\\Q.test.controller.\\E([^.]*)\\Q.status.\\E([^.]*)\\Q\\E$"); - - for (Map.Entry expected : validPatterns.entrySet()) { - final GraphiteNamePattern pattern = new GraphiteNamePattern(expected.getKey()); - Assertions.assertThat(pattern.getPatternString()).isEqualTo(expected.getValue()); - } + } + + @Test + public void createNew_WHEN_ValidPattern_THEN_ShouldInitInternalPatternSuccessfully() { + final Map validPatterns = new HashMap(); + validPatterns.put( + "org.test.controller.gather.status.400", "^\\Qorg.test.controller.gather.status.400\\E$"); + validPatterns.put( + "org.test.controller.*.status.400", "^\\Qorg.test.controller.\\E([^.]*)\\Q.status.400\\E$"); + validPatterns.put( + "org.test.controller.*.status.*", + "^\\Qorg.test.controller.\\E([^.]*)\\Q.status.\\E([^.]*)\\Q\\E$"); + validPatterns.put( + "*.test.controller.*.status.*", + "^\\Q\\E([^.]*)\\Q.test.controller.\\E([^.]*)\\Q.status.\\E([^.]*)\\Q\\E$"); + + for (Map.Entry expected : validPatterns.entrySet()) { + final GraphiteNamePattern pattern = new GraphiteNamePattern(expected.getKey()); + Assertions.assertThat(pattern.getPatternString()).isEqualTo(expected.getValue()); } - - @Test - public void match_WHEN_NotMatchingMetricNameProvided_THEN_ShouldNotMatch() { - final GraphiteNamePattern pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); - final List notMatchingMetricNamed = Arrays.asList( - "org.test.controller.status.400", - "", - null - ); - - for (String metricName : notMatchingMetricNamed) { - Assertions.assertThat(pattern.matches(metricName)).as("Matching [%s] against [%s]", metricName, pattern.getPatternString()).isFalse(); - } + } + + @Test + public void match_WHEN_NotMatchingMetricNameProvided_THEN_ShouldNotMatch() { + final GraphiteNamePattern pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); + final List notMatchingMetricNamed = + Arrays.asList("org.test.controller.status.400", "", null); + + for (String metricName : notMatchingMetricNamed) { + Assertions.assertThat(pattern.matches(metricName)) + .as("Matching [%s] against [%s]", metricName, pattern.getPatternString()) + .isFalse(); } - - @Test - public void match_WHEN_MatchingMetricNameProvided_THEN_ShouldMatch() { - final GraphiteNamePattern pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); - final List matchingMetricNamed = Arrays.asList( - "org.test.controller.gather.status.400", - "org.test.controller.gather2.status.500", - "org.test.controller.gather1.status.", - "org.test.controller.*.status.*", - "org.test.controller..status.*" - ); - - for (String metricName : matchingMetricNamed) { - Assertions.assertThat(pattern.matches(metricName)).as("Matching [%s] against [%s]", metricName, pattern.getPatternString()).isTrue(); - } - } - - @Test - public void extractParameters() { - GraphiteNamePattern pattern; - Map expected = new HashMap(); - expected.put("${0}", "gather"); - expected.put("${1}", "400"); - pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); - Assertions.assertThat(pattern.extractParameters("org.test.controller.gather.status.400")) - .isEqualTo(expected); - - expected = new HashMap(); - expected.put("${0}", "org"); - expected.put("${1}", "gather"); - expected.put("${2}", "400"); - pattern = new GraphiteNamePattern("*.test.controller.*.status.*"); - Assertions.assertThat(pattern.extractParameters("org.test.controller.gather.status.400")) - .isEqualTo(expected); - } - - @Test - public void extractParameters_WHEN_emptyStringInDottedMetricsName_THEN_ShouldReturnEmptyString() { - GraphiteNamePattern pattern; - Map expected = new HashMap(); - expected.put("${0}", ""); - expected.put("${1}", "400"); - pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); - Assertions.assertThat(pattern.extractParameters("org.test.controller..status.400")) - .isEqualTo(expected); - - } - - @Test - public void extractParameters_WHEN_moreDots_THEN_ShouldReturnNoMatches() { - GraphiteNamePattern pattern; - pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); - Assertions.assertThat(pattern.extractParameters("org.test.controller...status.400")) - .isEqualTo(Collections.emptyMap()); - + } + + @Test + public void match_WHEN_MatchingMetricNameProvided_THEN_ShouldMatch() { + final GraphiteNamePattern pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); + final List matchingMetricNamed = + Arrays.asList( + "org.test.controller.gather.status.400", + "org.test.controller.gather2.status.500", + "org.test.controller.gather1.status.", + "org.test.controller.*.status.*", + "org.test.controller..status.*"); + + for (String metricName : matchingMetricNamed) { + Assertions.assertThat(pattern.matches(metricName)) + .as("Matching [%s] against [%s]", metricName, pattern.getPatternString()) + .isTrue(); } -} \ No newline at end of file + } + + @Test + public void extractParameters() { + GraphiteNamePattern pattern; + Map expected = new HashMap(); + expected.put("${0}", "gather"); + expected.put("${1}", "400"); + pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); + Assertions.assertThat(pattern.extractParameters("org.test.controller.gather.status.400")) + .isEqualTo(expected); + + expected = new HashMap(); + expected.put("${0}", "org"); + expected.put("${1}", "gather"); + expected.put("${2}", "400"); + pattern = new GraphiteNamePattern("*.test.controller.*.status.*"); + Assertions.assertThat(pattern.extractParameters("org.test.controller.gather.status.400")) + .isEqualTo(expected); + } + + @Test + public void extractParameters_WHEN_emptyStringInDottedMetricsName_THEN_ShouldReturnEmptyString() { + GraphiteNamePattern pattern; + Map expected = new HashMap(); + expected.put("${0}", ""); + expected.put("${1}", "400"); + pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); + Assertions.assertThat(pattern.extractParameters("org.test.controller..status.400")) + .isEqualTo(expected); + } + + @Test + public void extractParameters_WHEN_moreDots_THEN_ShouldReturnNoMatches() { + GraphiteNamePattern pattern; + pattern = new GraphiteNamePattern("org.test.controller.*.status.*"); + Assertions.assertThat(pattern.extractParameters("org.test.controller...status.400")) + .isEqualTo(Collections.emptyMap()); + } +} diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java index 03d244b89..7bf7b6520 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java @@ -1,57 +1,58 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.Collections; import java.util.HashMap; import java.util.Map; - -import static org.junit.Assert.assertEquals; +import org.junit.Test; public class MapperConfigTest { - @Test - public void setMatch_WHEN_ExpressionMatchesPattern_AllGood() { - final MapperConfig mapperConfig = new MapperConfig(); - mapperConfig.setMatch("com.company.meter.*"); - assertEquals("com.company.meter.*", mapperConfig.getMatch()); - } - - @Test(expected = IllegalArgumentException.class) - public void setMatch_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { - final MapperConfig mapperConfig = new MapperConfig(); - mapperConfig.setMatch("com.company.meter.**.yay"); - } - - @Test - public void setLabels_WHEN_ExpressionMatchesPattern_AllGood() { - final MapperConfig mapperConfig = new MapperConfig(); - final Map labels = new HashMap(); - labels.put("valid", "${0}"); - mapperConfig.setLabels(labels); - assertEquals(labels, mapperConfig.getLabels()); - } - - @Test(expected = IllegalArgumentException.class) - public void setLabels_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { - final MapperConfig mapperConfig = new MapperConfig(); - final Map labels = new HashMap(); - labels.put("valid", "${0}"); - labels.put("not valid", "${0}"); - mapperConfig.setLabels(labels); - } - - @Test - public void toString_WHEN_EmptyConfig_AllGood() { - final MapperConfig mapperConfig = new MapperConfig(); - assertEquals("MapperConfig{match=null, name=null, labels={}}", mapperConfig.toString()); - } - - @Test - public void toString_WHEN_FullyConfigured_AllGood() { - final MapperConfig mapperConfig = new MapperConfig(); - mapperConfig.setMatch("com.company.meter.*.foo"); - mapperConfig.setName("foo"); - mapperConfig.setLabels(Collections.singletonMap("type", "${0}")); - assertEquals("MapperConfig{match=com.company.meter.*.foo, name=foo, labels={type=${0}}}", mapperConfig.toString()); - } + @Test + public void setMatch_WHEN_ExpressionMatchesPattern_AllGood() { + final MapperConfig mapperConfig = new MapperConfig(); + mapperConfig.setMatch("com.company.meter.*"); + assertEquals("com.company.meter.*", mapperConfig.getMatch()); + } + + @Test(expected = IllegalArgumentException.class) + public void setMatch_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { + final MapperConfig mapperConfig = new MapperConfig(); + mapperConfig.setMatch("com.company.meter.**.yay"); + } + + @Test + public void setLabels_WHEN_ExpressionMatchesPattern_AllGood() { + final MapperConfig mapperConfig = new MapperConfig(); + final Map labels = new HashMap(); + labels.put("valid", "${0}"); + mapperConfig.setLabels(labels); + assertEquals(labels, mapperConfig.getLabels()); + } + + @Test(expected = IllegalArgumentException.class) + public void setLabels_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { + final MapperConfig mapperConfig = new MapperConfig(); + final Map labels = new HashMap(); + labels.put("valid", "${0}"); + labels.put("not valid", "${0}"); + mapperConfig.setLabels(labels); + } + + @Test + public void toString_WHEN_EmptyConfig_AllGood() { + final MapperConfig mapperConfig = new MapperConfig(); + assertEquals("MapperConfig{match=null, name=null, labels={}}", mapperConfig.toString()); + } + + @Test + public void toString_WHEN_FullyConfigured_AllGood() { + final MapperConfig mapperConfig = new MapperConfig(); + mapperConfig.setMatch("com.company.meter.*.foo"); + mapperConfig.setName("foo"); + mapperConfig.setLabels(Collections.singletonMap("type", "${0}")); + assertEquals( + "MapperConfig{match=com.company.meter.*.foo, name=foo, labels={type=${0}}}", + mapperConfig.toString()); + } } diff --git a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java index 71ffea01c..5e17338b7 100644 --- a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java @@ -9,7 +9,6 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; - import java.util.Arrays; import java.util.List; import java.util.Map; @@ -18,9 +17,10 @@ /** * Collect metrics from Guava's com.google.common.cache.Cache. + * *

      - *

      {@code
        *
      + * 
      {@code
        * // Note that `recordStats()` is required to gather non-zero statistics
        * Cache cache = CacheBuilder.newBuilder().recordStats().build();
        * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      @@ -30,7 +30,8 @@
        *
        * Exposed metrics are labeled with the provided cache name.
        *
      - * With the example above, sample metric names would be:
      + * 

      With the example above, sample metric names would be: + * *

        *     guava_cache_hit_total{cache="mycache"} 10.0
        *     guava_cache_miss_total{cache="mycache"} 3.0
      @@ -40,164 +41,154 @@
        * 
      * * Additionally, if the cache includes a loader, the following metrics would be provided: + * *
        *     guava_cache_load_failure_total{cache="mycache"} 2.0
        *     guava_cache_loads_total{cache="mycache"} 7.0
        *     guava_cache_load_duration_seconds_count{cache="mycache"} 7.0
        *     guava_cache_load_duration_seconds_sum{cache="mycache"} 0.0034
        * 
      - * */ public class CacheMetricsCollector implements MultiCollector { - private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; - - protected final ConcurrentMap children = new ConcurrentHashMap<>(); - - /** - * Add or replace the cache with the given name. - *

      - * Any references any previous cache with this name is invalidated. - * - * @param cacheName The name of the cache, will be the metrics label value - * @param cache The cache being monitored - */ - public void addCache(String cacheName, Cache cache) { - children.put(cacheName, cache); - } - - /** - * Remove the cache with the given name. - *

      - * Any references to the cache are invalidated. - * - * @param cacheName cache to be removed - */ - public Cache removeCache(String cacheName) { - return children.remove(cacheName); - } - - /** - * Remove all caches. - *

      - * Any references to all caches are invalidated. - */ - public void clear(){ - children.clear(); - } - - @Override - public MetricSnapshots collect() { - final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); - final List labelNames = Arrays.asList("cache"); - - final CounterSnapshot.Builder cacheHitTotal = CounterSnapshot.builder() - .name("guava_cache_hit") - .help("Cache hit totals"); - - final CounterSnapshot.Builder cacheMissTotal = CounterSnapshot.builder() - .name("guava_cache_miss") - .help("Cache miss totals"); - - final CounterSnapshot.Builder cacheRequestsTotal = CounterSnapshot.builder() - .name("guava_cache_requests") - .help("Cache request totals"); - - final CounterSnapshot.Builder cacheEvictionTotal = CounterSnapshot.builder() + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; + + protected final ConcurrentMap children = new ConcurrentHashMap<>(); + + /** + * Add or replace the cache with the given name. + * + *

      Any references any previous cache with this name is invalidated. + * + * @param cacheName The name of the cache, will be the metrics label value + * @param cache The cache being monitored + */ + public void addCache(String cacheName, Cache cache) { + children.put(cacheName, cache); + } + + /** + * Remove the cache with the given name. + * + *

      Any references to the cache are invalidated. + * + * @param cacheName cache to be removed + */ + public Cache removeCache(String cacheName) { + return children.remove(cacheName); + } + + /** + * Remove all caches. + * + *

      Any references to all caches are invalidated. + */ + public void clear() { + children.clear(); + } + + @Override + public MetricSnapshots collect() { + final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); + final List labelNames = Arrays.asList("cache"); + + final CounterSnapshot.Builder cacheHitTotal = + CounterSnapshot.builder().name("guava_cache_hit").help("Cache hit totals"); + + final CounterSnapshot.Builder cacheMissTotal = + CounterSnapshot.builder().name("guava_cache_miss").help("Cache miss totals"); + + final CounterSnapshot.Builder cacheRequestsTotal = + CounterSnapshot.builder().name("guava_cache_requests").help("Cache request totals"); + + final CounterSnapshot.Builder cacheEvictionTotal = + CounterSnapshot.builder() .name("guava_cache_eviction") .help("Cache eviction totals, doesn't include manually removed entries"); - final CounterSnapshot.Builder cacheLoadFailure = CounterSnapshot.builder() - .name("guava_cache_load_failure") - .help("Cache load failures"); + final CounterSnapshot.Builder cacheLoadFailure = + CounterSnapshot.builder().name("guava_cache_load_failure").help("Cache load failures"); - final CounterSnapshot.Builder cacheLoadTotal = CounterSnapshot.builder() + final CounterSnapshot.Builder cacheLoadTotal = + CounterSnapshot.builder() .name("guava_cache_loads") .help("Cache loads: both success and failures"); - final GaugeSnapshot.Builder cacheSize = GaugeSnapshot.builder() - .name("guava_cache_size") - .help("Cache size"); + final GaugeSnapshot.Builder cacheSize = + GaugeSnapshot.builder().name("guava_cache_size").help("Cache size"); - final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() + final SummarySnapshot.Builder cacheLoadSummary = + SummarySnapshot.builder() .name("guava_cache_load_duration_seconds") .help("Cache load duration: both success and failures"); - for (final Map.Entry c: children.entrySet()) { - final List cacheName = Arrays.asList(c.getKey()); - final Labels labels = Labels.of(labelNames, cacheName); - - final CacheStats stats = c.getValue().stats(); - - cacheHitTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.hitCount()) - .build() - ); - - cacheMissTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.missCount()) - .build() - ); - - cacheRequestsTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.requestCount()) - .build() - ); - - cacheEvictionTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.evictionCount()) - .build() - ); - - cacheSize.dataPoint( - GaugeSnapshot.GaugeDataPointSnapshot.builder() - .labels(labels) - .value(c.getValue().size()) - .build() - ); - - if (c.getValue() instanceof LoadingCache) { - cacheLoadFailure.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.loadExceptionCount()) - .build() - ); - - cacheLoadTotal.dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(labels) - .value(stats.loadCount()) - .build() - ); - - cacheLoadSummary.dataPoint( - SummarySnapshot.SummaryDataPointSnapshot.builder() - .labels(labels) - .count(stats.loadCount()) - .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) - .build() - ); - } - } - - metricSnapshotsBuilder.metricSnapshot(cacheHitTotal.build()); - metricSnapshotsBuilder.metricSnapshot(cacheMissTotal.build()); - metricSnapshotsBuilder.metricSnapshot(cacheRequestsTotal.build()); - metricSnapshotsBuilder.metricSnapshot(cacheEvictionTotal.build()); - metricSnapshotsBuilder.metricSnapshot(cacheLoadFailure.build()); - metricSnapshotsBuilder.metricSnapshot(cacheLoadTotal.build()); - metricSnapshotsBuilder.metricSnapshot(cacheSize.build()); - metricSnapshotsBuilder.metricSnapshot(cacheLoadSummary.build()); - - return metricSnapshotsBuilder.build(); + for (final Map.Entry c : children.entrySet()) { + final List cacheName = Arrays.asList(c.getKey()); + final Labels labels = Labels.of(labelNames, cacheName); + + final CacheStats stats = c.getValue().stats(); + + cacheHitTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.hitCount()) + .build()); + + cacheMissTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.missCount()) + .build()); + + cacheRequestsTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.requestCount()) + .build()); + + cacheEvictionTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionCount()) + .build()); + + cacheSize.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(c.getValue().size()) + .build()); + + if (c.getValue() instanceof LoadingCache) { + cacheLoadFailure.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadExceptionCount()) + .build()); + + cacheLoadTotal.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.loadCount()) + .build()); + + cacheLoadSummary.dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(labels) + .count(stats.loadCount()) + .sum(stats.totalLoadTime() / NANOSECONDS_PER_SECOND) + .build()); + } } + + metricSnapshotsBuilder.metricSnapshot(cacheHitTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheMissTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheRequestsTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheEvictionTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadFailure.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadTotal.build()); + metricSnapshotsBuilder.metricSnapshot(cacheSize.build()); + metricSnapshotsBuilder.metricSnapshot(cacheLoadSummary.build()); + + return metricSnapshotsBuilder.build(); + } } diff --git a/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java index 41b3bba8d..96de845a8 100644 --- a/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java @@ -1,5 +1,11 @@ package io.prometheus.metrics.instrumentation.guava; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -10,133 +16,128 @@ import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import org.junit.Test; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.junit.Test; public class CacheMetricsCollectorTest { - @Test - public void cacheExposesMetricsForHitMissAndEviction() { - final Cache cache = CacheBuilder.newBuilder().maximumSize(2).recordStats().build(); - - final CacheMetricsCollector collector = new CacheMetricsCollector(); - collector.addCache("users", cache); - - final PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - - cache.getIfPresent("user1"); - cache.getIfPresent("user1"); - cache.put("user1", "First User"); - cache.getIfPresent("user1"); - - // Add to cache to trigger eviction. - cache.put("user2", "Second User"); - cache.put("user3", "Third User"); - cache.put("user4", "Fourth User"); - - assertCounterMetric(registry, "guava_cache_hit", "users", 1.0); - assertCounterMetric(registry, "guava_cache_miss", "users", 2.0); - assertCounterMetric(registry, "guava_cache_requests", "users", 3.0); - assertCounterMetric(registry, "guava_cache_eviction", "users", 2.0); - - final String expected = "# TYPE guava_cache_eviction counter\n" + - "# HELP guava_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + - "guava_cache_eviction_total{cache=\"users\"} 2.0\n" + - "# TYPE guava_cache_hit counter\n" + - "# HELP guava_cache_hit Cache hit totals\n" + - "guava_cache_hit_total{cache=\"users\"} 1.0\n" + - "# TYPE guava_cache_miss counter\n" + - "# HELP guava_cache_miss Cache miss totals\n" + - "guava_cache_miss_total{cache=\"users\"} 2.0\n" + - "# TYPE guava_cache_requests counter\n" + - "# HELP guava_cache_requests Cache request totals\n" + - "guava_cache_requests_total{cache=\"users\"} 3.0\n" + - "# TYPE guava_cache_size gauge\n" + - "# HELP guava_cache_size Cache size\n" + - "guava_cache_size{cache=\"users\"} 2.0\n" + - "# EOF\n"; - - assertEquals(expected, convertToOpenMetricsFormat(registry)); - } - - @SuppressWarnings("unchecked") - @Test - public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { - final CacheLoader loader = mock(CacheLoader.class); - when(loader.load(anyString())) - .thenReturn("First User") - .thenThrow(new RuntimeException("Seconds time fails")) - .thenReturn("Third User"); - - final LoadingCache cache = CacheBuilder.newBuilder().recordStats().build(loader); - final CacheMetricsCollector collector = new CacheMetricsCollector(); - collector.addCache("loadingusers", cache); - - final PrometheusRegistry registry = new PrometheusRegistry(); - registry.register(collector); - - cache.get("user1"); - cache.get("user1"); - try { - cache.get("user2"); - } catch (Exception e) { - // ignoring. - } - cache.get("user3"); - - assertCounterMetric(registry, "guava_cache_hit", "loadingusers", 1.0); - assertCounterMetric(registry, "guava_cache_miss", "loadingusers", 3.0); - - assertCounterMetric(registry, "guava_cache_load_failure", "loadingusers", 1.0); - assertCounterMetric(registry, "guava_cache_loads", "loadingusers", 3.0); - - final SummarySnapshot.SummaryDataPointSnapshot loadDuration = (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot( - registry, - "guava_cache_load_duration_seconds", - "loadingusers" - ); - - assertEquals(3, loadDuration.getCount()); - assertThat(loadDuration.getSum()).isGreaterThan(0); - } - - private void assertCounterMetric(PrometheusRegistry registry, String name, String cacheName, double value) { - final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = - (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); - - assertEquals(value, dataPointSnapshot.getValue(), 0); - } - - private DataPointSnapshot getDataPointSnapshot(PrometheusRegistry registry, String name, String cacheName) - { - final Labels labels = Labels.of(new String[]{"cache"}, new String[]{cacheName}); - - return registry.scrape(name::equals).stream() - .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) - .filter(dataPoint -> dataPoint.getLabels().equals(labels)) - .findFirst() - .get(); + @Test + public void cacheExposesMetricsForHitMissAndEviction() { + final Cache cache = + CacheBuilder.newBuilder().maximumSize(2).recordStats().build(); + + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("users", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.getIfPresent("user1"); + cache.getIfPresent("user1"); + cache.put("user1", "First User"); + cache.getIfPresent("user1"); + + // Add to cache to trigger eviction. + cache.put("user2", "Second User"); + cache.put("user3", "Third User"); + cache.put("user4", "Fourth User"); + + assertCounterMetric(registry, "guava_cache_hit", "users", 1.0); + assertCounterMetric(registry, "guava_cache_miss", "users", 2.0); + assertCounterMetric(registry, "guava_cache_requests", "users", 3.0); + assertCounterMetric(registry, "guava_cache_eviction", "users", 2.0); + + final String expected = + "# TYPE guava_cache_eviction counter\n" + + "# HELP guava_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + + "guava_cache_eviction_total{cache=\"users\"} 2.0\n" + + "# TYPE guava_cache_hit counter\n" + + "# HELP guava_cache_hit Cache hit totals\n" + + "guava_cache_hit_total{cache=\"users\"} 1.0\n" + + "# TYPE guava_cache_miss counter\n" + + "# HELP guava_cache_miss Cache miss totals\n" + + "guava_cache_miss_total{cache=\"users\"} 2.0\n" + + "# TYPE guava_cache_requests counter\n" + + "# HELP guava_cache_requests Cache request totals\n" + + "guava_cache_requests_total{cache=\"users\"} 3.0\n" + + "# TYPE guava_cache_size gauge\n" + + "# HELP guava_cache_size Cache size\n" + + "guava_cache_size{cache=\"users\"} 2.0\n" + + "# EOF\n"; + + assertEquals(expected, convertToOpenMetricsFormat(registry)); + } + + @SuppressWarnings("unchecked") + @Test + public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { + final CacheLoader loader = mock(CacheLoader.class); + when(loader.load(anyString())) + .thenReturn("First User") + .thenThrow(new RuntimeException("Seconds time fails")) + .thenReturn("Third User"); + + final LoadingCache cache = + CacheBuilder.newBuilder().recordStats().build(loader); + final CacheMetricsCollector collector = new CacheMetricsCollector(); + collector.addCache("loadingusers", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.get("user1"); + cache.get("user1"); + try { + cache.get("user2"); + } catch (Exception e) { + // ignoring. } - - private String convertToOpenMetricsFormat(PrometheusRegistry registry) { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - try { - writer.write(out, registry.scrape()); - return out.toString(StandardCharsets.UTF_8.name()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } + cache.get("user3"); + + assertCounterMetric(registry, "guava_cache_hit", "loadingusers", 1.0); + assertCounterMetric(registry, "guava_cache_miss", "loadingusers", 3.0); + + assertCounterMetric(registry, "guava_cache_load_failure", "loadingusers", 1.0); + assertCounterMetric(registry, "guava_cache_loads", "loadingusers", 3.0); + + final SummarySnapshot.SummaryDataPointSnapshot loadDuration = + (SummarySnapshot.SummaryDataPointSnapshot) + getDataPointSnapshot(registry, "guava_cache_load_duration_seconds", "loadingusers"); + + assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getSum()).isGreaterThan(0); + } + + private void assertCounterMetric( + PrometheusRegistry registry, String name, String cacheName, double value) { + final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = + (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); + + assertEquals(value, dataPointSnapshot.getValue(), 0); + } + + private DataPointSnapshot getDataPointSnapshot( + PrometheusRegistry registry, String name, String cacheName) { + final Labels labels = Labels.of(new String[] {"cache"}, new String[] {cacheName}); + + return registry.scrape(name::equals).stream() + .flatMap(metricSnapshot -> metricSnapshot.getDataPoints().stream()) + .filter(dataPoint -> dataPoint.getLabels().equals(labels)) + .findFirst() + .get(); + } + + private String convertToOpenMetricsFormat(PrometheusRegistry registry) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + final OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + try { + writer.write(out, registry.scrape()); + return out.toString(StandardCharsets.UTF_8.name()); + } catch (IOException e) { + throw new UncheckedIOException(e); } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java index 9c8cddb46..ad047f1ba 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.java @@ -4,21 +4,26 @@ import io.prometheus.metrics.core.metrics.GaugeWithCallback; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.Unit; - import java.lang.management.BufferPoolMXBean; import java.lang.management.ManagementFactory; import java.util.List; /** - * JVM Buffer Pool metrics. The {@link JvmBufferPoolMetrics} are registered as part of the {@link JvmMetrics} like this: + * JVM Buffer Pool metrics. The {@link JvmBufferPoolMetrics} are registered as part of the {@link + * JvmMetrics} like this: + * *

      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmBufferPoolMetrics} you can also register them directly: + * *
      {@code
      - *   JvmBufferPoolMetrics.builder().register();
      + * JvmBufferPoolMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.
        * # TYPE jvm_buffer_pool_capacity_bytes gauge
      @@ -36,91 +41,93 @@
        */
       public class JvmBufferPoolMetrics {
       
      -    private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes";
      -    private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes";
      -    private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers";
      +  private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes";
      +  private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes";
      +  private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers";
      +
      +  private final PrometheusProperties config;
      +  private final List bufferPoolBeans;
      +
      +  private JvmBufferPoolMetrics(
      +      List bufferPoolBeans, PrometheusProperties config) {
      +    this.config = config;
      +    this.bufferPoolBeans = bufferPoolBeans;
      +  }
      +
      +  private void register(PrometheusRegistry registry) {
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_BUFFER_POOL_USED_BYTES)
      +        .help("Used bytes of a given JVM buffer pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            callback -> {
      +              for (BufferPoolMXBean pool : bufferPoolBeans) {
      +                callback.call(pool.getMemoryUsed(), pool.getName());
      +              }
      +            })
      +        .register(registry);
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_BUFFER_POOL_CAPACITY_BYTES)
      +        .help("Bytes capacity of a given JVM buffer pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            callback -> {
      +              for (BufferPoolMXBean pool : bufferPoolBeans) {
      +                callback.call(pool.getTotalCapacity(), pool.getName());
      +              }
      +            })
      +        .register(registry);
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_BUFFER_POOL_USED_BUFFERS)
      +        .help("Used buffers of a given JVM buffer pool.")
      +        .labelNames("pool")
      +        .callback(
      +            callback -> {
      +              for (BufferPoolMXBean pool : bufferPoolBeans) {
      +                callback.call(pool.getCount(), pool.getName());
      +              }
      +            })
      +        .register(registry);
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder {
       
           private final PrometheusProperties config;
      -    private final List bufferPoolBeans;
      -
      -    private JvmBufferPoolMetrics(List bufferPoolBeans, PrometheusProperties config) {
      -        this.config = config;
      -        this.bufferPoolBeans = bufferPoolBeans;
      -    }
      +    private List bufferPoolBeans;
       
      -    private void register(PrometheusRegistry registry) {
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_BUFFER_POOL_USED_BYTES)
      -                .help("Used bytes of a given JVM buffer pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(callback -> {
      -                    for (BufferPoolMXBean pool : bufferPoolBeans) {
      -                        callback.call(pool.getMemoryUsed(), pool.getName());
      -                    }
      -                })
      -                .register(registry);
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_BUFFER_POOL_CAPACITY_BYTES)
      -                .help("Bytes capacity of a given JVM buffer pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(callback -> {
      -                    for (BufferPoolMXBean pool : bufferPoolBeans) {
      -                        callback.call(pool.getTotalCapacity(), pool.getName());
      -                    }
      -                })
      -                .register(registry);
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_BUFFER_POOL_USED_BUFFERS)
      -                .help("Used buffers of a given JVM buffer pool.")
      -                .labelNames("pool")
      -                .callback(callback -> {
      -                    for (BufferPoolMXBean pool : bufferPoolBeans) {
      -                        callback.call(pool.getCount(), pool.getName());
      -                    }
      -                })
      -                .register(registry);
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      +    /** Package private. For testing only. */
      +    Builder bufferPoolBeans(List bufferPoolBeans) {
      +      this.bufferPoolBeans = bufferPoolBeans;
      +      return this;
           }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
           }
       
      -    public static class Builder {
      -
      -        private final PrometheusProperties config;
      -        private List bufferPoolBeans;
      -
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder bufferPoolBeans(List bufferPoolBeans) {
      -            this.bufferPoolBeans = bufferPoolBeans;
      -            return this;
      -        }
      -
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      -
      -        public void register(PrometheusRegistry registry) {
      -            List bufferPoolBeans = this.bufferPoolBeans;
      -            if (bufferPoolBeans == null) {
      -                bufferPoolBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
      -            }
      -            new JvmBufferPoolMetrics(bufferPoolBeans, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      List bufferPoolBeans = this.bufferPoolBeans;
      +      if (bufferPoolBeans == null) {
      +        bufferPoolBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
      +      }
      +      new JvmBufferPoolMetrics(bufferPoolBeans, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
      index 69d3c4ecd..f87618f63 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java
      @@ -4,20 +4,25 @@
       import io.prometheus.metrics.core.metrics.CounterWithCallback;
       import io.prometheus.metrics.core.metrics.GaugeWithCallback;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -
       import java.lang.management.ClassLoadingMXBean;
       import java.lang.management.ManagementFactory;
       
       /**
      - * JVM Class Loading metrics. The {@link JvmClassLoadingMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM Class Loading metrics. The {@link JvmClassLoadingMetrics} are registered as part of the
      + * {@link JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmClassLoadingMetrics} you can also register them directly: + * *
      {@code
      - *   JvmClassLoadingMetrics.builder().register();
      + * JvmClassLoadingMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM
        * # TYPE jvm_classes_currently_loaded gauge
      @@ -32,71 +37,74 @@
        */
       public class JvmClassLoadingMetrics {
       
      -    private static final String JVM_CLASSES_CURRENTLY_LOADED = "jvm_classes_currently_loaded";
      -    private static final String JVM_CLASSES_LOADED_TOTAL = "jvm_classes_loaded_total";
      -    private static final String JVM_CLASSES_UNLOADED_TOTAL = "jvm_classes_unloaded_total";
      +  private static final String JVM_CLASSES_CURRENTLY_LOADED = "jvm_classes_currently_loaded";
      +  private static final String JVM_CLASSES_LOADED_TOTAL = "jvm_classes_loaded_total";
      +  private static final String JVM_CLASSES_UNLOADED_TOTAL = "jvm_classes_unloaded_total";
       
      -    private final PrometheusProperties config;
      -    private final ClassLoadingMXBean classLoadingBean;
      +  private final PrometheusProperties config;
      +  private final ClassLoadingMXBean classLoadingBean;
       
      -    private JvmClassLoadingMetrics(ClassLoadingMXBean classLoadingBean, PrometheusProperties config) {
      -        this.classLoadingBean = classLoadingBean;
      -        this.config = config;
      -    }
      +  private JvmClassLoadingMetrics(ClassLoadingMXBean classLoadingBean, PrometheusProperties config) {
      +    this.classLoadingBean = classLoadingBean;
      +    this.config = config;
      +  }
       
      -    private void register(PrometheusRegistry registry) {
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_CLASSES_CURRENTLY_LOADED)
      -                .help("The number of classes that are currently loaded in the JVM")
      -                .callback(callback -> callback.call(classLoadingBean.getLoadedClassCount()))
      -                .register(registry);
      -
      -        CounterWithCallback.builder(config)
      -                .name(JVM_CLASSES_LOADED_TOTAL)
      -                .help("The total number of classes that have been loaded since the JVM has started execution")
      -                .callback(callback -> callback.call(classLoadingBean.getTotalLoadedClassCount()))
      -                .register(registry);
      -
      -        CounterWithCallback.builder(config)
      -                .name(JVM_CLASSES_UNLOADED_TOTAL)
      -                .help("The total number of classes that have been unloaded since the JVM has started execution")
      -                .callback(callback -> callback.call(classLoadingBean.getUnloadedClassCount()))
      -                .register(registry);
      -    }
      +  private void register(PrometheusRegistry registry) {
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_CLASSES_CURRENTLY_LOADED)
      +        .help("The number of classes that are currently loaded in the JVM")
      +        .callback(callback -> callback.call(classLoadingBean.getLoadedClassCount()))
      +        .register(registry);
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      -    }
      +    CounterWithCallback.builder(config)
      +        .name(JVM_CLASSES_LOADED_TOTAL)
      +        .help(
      +            "The total number of classes that have been loaded since the JVM has started execution")
      +        .callback(callback -> callback.call(classLoadingBean.getTotalLoadedClassCount()))
      +        .register(registry);
       
      -    public static class Builder {
      +    CounterWithCallback.builder(config)
      +        .name(JVM_CLASSES_UNLOADED_TOTAL)
      +        .help(
      +            "The total number of classes that have been unloaded since the JVM has started execution")
      +        .callback(callback -> callback.call(classLoadingBean.getUnloadedClassCount()))
      +        .register(registry);
      +  }
       
      -        private final PrometheusProperties config;
      -        private ClassLoadingMXBean classLoadingBean;
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
       
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder classLoadingBean(ClassLoadingMXBean classLoadingBean) {
      -            this.classLoadingBean = classLoadingBean;
      -            return this;
      -        }
      +  public static class Builder {
       
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      +    private final PrometheusProperties config;
      +    private ClassLoadingMXBean classLoadingBean;
      +
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
      +    }
      +
      +    /** Package private. For testing only. */
      +    Builder classLoadingBean(ClassLoadingMXBean classLoadingBean) {
      +      this.classLoadingBean = classLoadingBean;
      +      return this;
      +    }
      +
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
      +    }
       
      -        public void register(PrometheusRegistry registry) {
      -            ClassLoadingMXBean classLoadingBean = this.classLoadingBean != null ? this.classLoadingBean : ManagementFactory.getClassLoadingMXBean();
      -            new JvmClassLoadingMetrics(classLoadingBean, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      ClassLoadingMXBean classLoadingBean =
      +          this.classLoadingBean != null
      +              ? this.classLoadingBean
      +              : ManagementFactory.getClassLoadingMXBean();
      +      new JvmClassLoadingMetrics(classLoadingBean, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
      index 0fbebf46e..308b00877 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.java
      @@ -1,25 +1,30 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
      +import static io.prometheus.metrics.model.snapshots.Unit.millisToSeconds;
      +
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.core.metrics.CounterWithCallback;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.Unit;
      -
       import java.lang.management.CompilationMXBean;
       import java.lang.management.ManagementFactory;
       
      -import static io.prometheus.metrics.model.snapshots.Unit.millisToSeconds;
      -
       /**
      - * JVM Compilation metrics. The {@link JvmCompilationMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM Compilation metrics. The {@link JvmCompilationMetrics} are registered as part of the {@link
      + * JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmCompilationMetrics} you can also register them directly: + * *
      {@code
      - *   JvmCompilationMetrics.builder().register();
      + * JvmCompilationMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_compilation_time_seconds_total The total time in seconds taken for HotSpot class compilation
        * # TYPE jvm_compilation_time_seconds_total counter
      @@ -28,62 +33,65 @@
        */
       public class JvmCompilationMetrics {
       
      -    private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL = "jvm_compilation_time_seconds_total";
      -
      -    private final PrometheusProperties config;
      -    private final CompilationMXBean compilationBean;
      +  private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL =
      +      "jvm_compilation_time_seconds_total";
       
      -    private JvmCompilationMetrics(CompilationMXBean compilationBean, PrometheusProperties config) {
      -        this.compilationBean = compilationBean;
      -        this.config = config;
      -    }
      +  private final PrometheusProperties config;
      +  private final CompilationMXBean compilationBean;
       
      -    private void register(PrometheusRegistry registry) {
      +  private JvmCompilationMetrics(CompilationMXBean compilationBean, PrometheusProperties config) {
      +    this.compilationBean = compilationBean;
      +    this.config = config;
      +  }
       
      -        if (compilationBean == null || !compilationBean.isCompilationTimeMonitoringSupported()) {
      -            return;
      -        }
      +  private void register(PrometheusRegistry registry) {
       
      -        CounterWithCallback.builder(config)
      -                .name(JVM_COMPILATION_TIME_SECONDS_TOTAL)
      -                .help("The total time in seconds taken for HotSpot class compilation")
      -                .unit(Unit.SECONDS)
      -                .callback(callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime())))
      -                .register(registry);
      +    if (compilationBean == null || !compilationBean.isCompilationTimeMonitoringSupported()) {
      +      return;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +    CounterWithCallback.builder(config)
      +        .name(JVM_COMPILATION_TIME_SECONDS_TOTAL)
      +        .help("The total time in seconds taken for HotSpot class compilation")
      +        .unit(Unit.SECONDS)
      +        .callback(
      +            callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime())))
      +        .register(registry);
      +  }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      -    }
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -    public static class Builder {
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
       
      -        private final PrometheusProperties config;
      -        private CompilationMXBean compilationBean;
      +  public static class Builder {
       
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      +    private final PrometheusProperties config;
      +    private CompilationMXBean compilationBean;
       
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder compilationBean(CompilationMXBean compilationBean) {
      -            this.compilationBean = compilationBean;
      -            return this;
      -        }
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
      +    }
       
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      +    /** Package private. For testing only. */
      +    Builder compilationBean(CompilationMXBean compilationBean) {
      +      this.compilationBean = compilationBean;
      +      return this;
      +    }
      +
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
      +    }
       
      -        public void register(PrometheusRegistry registry) {
      -            CompilationMXBean compilationBean = this.compilationBean != null ? this.compilationBean : ManagementFactory.getCompilationMXBean();
      -            new JvmCompilationMetrics(compilationBean, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      CompilationMXBean compilationBean =
      +          this.compilationBean != null
      +              ? this.compilationBean
      +              : ManagementFactory.getCompilationMXBean();
      +      new JvmCompilationMetrics(compilationBean, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
      index ab9877a85..e8b9aaa70 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.java
      @@ -5,21 +5,27 @@
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.Quantiles;
       import io.prometheus.metrics.model.snapshots.Unit;
      -
       import java.lang.management.GarbageCollectorMXBean;
       import java.lang.management.ManagementFactory;
       import java.util.List;
       
       /**
      - * JVM Garbage Collector metrics. The {@link JvmGarbageCollectorMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM Garbage Collector metrics. The {@link JvmGarbageCollectorMetrics} are registered as part of
      + * the {@link JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      - * However, if you want only the {@link JvmGarbageCollectorMetrics} you can also register them directly: + * + * However, if you want only the {@link JvmGarbageCollectorMetrics} you can also register them + * directly: + * *
      {@code
      - *   JvmGarbageCollectorMetrics.builder().register();
      + * JvmGarbageCollectorMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
        * # TYPE jvm_gc_collection_seconds summary
      @@ -31,66 +37,70 @@
        */
       public class JvmGarbageCollectorMetrics {
       
      -    private static final String JVM_GC_COLLECTION_SECONDS = "jvm_gc_collection_seconds";
      +  private static final String JVM_GC_COLLECTION_SECONDS = "jvm_gc_collection_seconds";
      +
      +  private final PrometheusProperties config;
      +  private final List garbageCollectorBeans;
      +
      +  private JvmGarbageCollectorMetrics(
      +      List garbageCollectorBeans, PrometheusProperties config) {
      +    this.config = config;
      +    this.garbageCollectorBeans = garbageCollectorBeans;
      +  }
      +
      +  private void register(PrometheusRegistry registry) {
      +
      +    SummaryWithCallback.builder(config)
      +        .name(JVM_GC_COLLECTION_SECONDS)
      +        .help("Time spent in a given JVM garbage collector in seconds.")
      +        .unit(Unit.SECONDS)
      +        .labelNames("gc")
      +        .callback(
      +            callback -> {
      +              for (GarbageCollectorMXBean gc : garbageCollectorBeans) {
      +                callback.call(
      +                    gc.getCollectionCount(),
      +                    Unit.millisToSeconds(gc.getCollectionTime()),
      +                    Quantiles.EMPTY,
      +                    gc.getName());
      +              }
      +            })
      +        .register(registry);
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder {
       
           private final PrometheusProperties config;
      -    private final List garbageCollectorBeans;
      +    private List garbageCollectorBeans;
       
      -    private JvmGarbageCollectorMetrics(List garbageCollectorBeans, PrometheusProperties config) {
      -        this.config = config;
      -        this.garbageCollectorBeans = garbageCollectorBeans;
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
           }
       
      -    private void register(PrometheusRegistry registry) {
      -
      -        SummaryWithCallback.builder(config)
      -                .name(JVM_GC_COLLECTION_SECONDS)
      -                .help("Time spent in a given JVM garbage collector in seconds.")
      -                .unit(Unit.SECONDS)
      -                .labelNames("gc")
      -                .callback(callback -> {
      -                    for (GarbageCollectorMXBean gc : garbageCollectorBeans) {
      -                        callback.call(gc.getCollectionCount(), Unit.millisToSeconds(gc.getCollectionTime()), Quantiles.EMPTY, gc.getName());
      -                    }
      -                })
      -                .register(registry);
      +    /** Package private. For testing only. */
      +    Builder garbageCollectorBeans(List garbageCollectorBeans) {
      +      this.garbageCollectorBeans = garbageCollectorBeans;
      +      return this;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
           }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      -    }
      -
      -    public static class Builder {
      -
      -        private final PrometheusProperties config;
      -        private List garbageCollectorBeans;
      -
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder garbageCollectorBeans(List garbageCollectorBeans) {
      -            this.garbageCollectorBeans = garbageCollectorBeans;
      -            return this;
      -        }
      -
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      -
      -        public void register(PrometheusRegistry registry) {
      -            List garbageCollectorBeans = this.garbageCollectorBeans;
      -            if (garbageCollectorBeans == null) {
      -                garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans();
      -            }
      -            new JvmGarbageCollectorMetrics(garbageCollectorBeans, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      List garbageCollectorBeans = this.garbageCollectorBeans;
      +      if (garbageCollectorBeans == null) {
      +        garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans();
      +      }
      +      new JvmGarbageCollectorMetrics(garbageCollectorBeans, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
      index 3e3b95efa..b0672aaf3 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java
      @@ -4,7 +4,6 @@
       import io.prometheus.metrics.core.metrics.GaugeWithCallback;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.Unit;
      -
       import java.lang.management.ManagementFactory;
       import java.lang.management.MemoryMXBean;
       import java.lang.management.MemoryPoolMXBean;
      @@ -14,15 +13,21 @@
       import java.util.function.Function;
       
       /**
      - * JVM memory metrics. The {@link JvmMemoryMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM memory metrics. The {@link JvmMemoryMetrics} are registered as part of the {@link JvmMetrics}
      + * like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmMemoryMetrics} you can also register them directly: + * *
      {@code
      - *   JvmMemoryMetrics.builder().register();
      + * JvmMemoryMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.
        * # TYPE jvm_memory_committed_bytes gauge
      @@ -99,200 +104,216 @@
        */
       public class JvmMemoryMetrics {
       
      -    private static final String JVM_MEMORY_OBJECTS_PENDING_FINALIZATION = "jvm_memory_objects_pending_finalization";
      -    private static final String JVM_MEMORY_USED_BYTES = "jvm_memory_used_bytes";
      -    private static final String JVM_MEMORY_COMMITTED_BYTES = "jvm_memory_committed_bytes";
      -    private static final String JVM_MEMORY_MAX_BYTES = "jvm_memory_max_bytes";
      -    private static final String JVM_MEMORY_INIT_BYTES = "jvm_memory_init_bytes";
      -    private static final String JVM_MEMORY_POOL_USED_BYTES = "jvm_memory_pool_used_bytes";
      -    private static final String JVM_MEMORY_POOL_COMMITTED_BYTES = "jvm_memory_pool_committed_bytes";
      -    private static final String JVM_MEMORY_POOL_MAX_BYTES = "jvm_memory_pool_max_bytes";
      -    private static final String JVM_MEMORY_POOL_INIT_BYTES = "jvm_memory_pool_init_bytes";
      -    private static final String JVM_MEMORY_POOL_COLLECTION_USED_BYTES = "jvm_memory_pool_collection_used_bytes";
      -    private static final String JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES = "jvm_memory_pool_collection_committed_bytes";
      -    private static final String JVM_MEMORY_POOL_COLLECTION_MAX_BYTES = "jvm_memory_pool_collection_max_bytes";
      -    private static final String JVM_MEMORY_POOL_COLLECTION_INIT_BYTES = "jvm_memory_pool_collection_init_bytes";
      +  private static final String JVM_MEMORY_OBJECTS_PENDING_FINALIZATION =
      +      "jvm_memory_objects_pending_finalization";
      +  private static final String JVM_MEMORY_USED_BYTES = "jvm_memory_used_bytes";
      +  private static final String JVM_MEMORY_COMMITTED_BYTES = "jvm_memory_committed_bytes";
      +  private static final String JVM_MEMORY_MAX_BYTES = "jvm_memory_max_bytes";
      +  private static final String JVM_MEMORY_INIT_BYTES = "jvm_memory_init_bytes";
      +  private static final String JVM_MEMORY_POOL_USED_BYTES = "jvm_memory_pool_used_bytes";
      +  private static final String JVM_MEMORY_POOL_COMMITTED_BYTES = "jvm_memory_pool_committed_bytes";
      +  private static final String JVM_MEMORY_POOL_MAX_BYTES = "jvm_memory_pool_max_bytes";
      +  private static final String JVM_MEMORY_POOL_INIT_BYTES = "jvm_memory_pool_init_bytes";
      +  private static final String JVM_MEMORY_POOL_COLLECTION_USED_BYTES =
      +      "jvm_memory_pool_collection_used_bytes";
      +  private static final String JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES =
      +      "jvm_memory_pool_collection_committed_bytes";
      +  private static final String JVM_MEMORY_POOL_COLLECTION_MAX_BYTES =
      +      "jvm_memory_pool_collection_max_bytes";
      +  private static final String JVM_MEMORY_POOL_COLLECTION_INIT_BYTES =
      +      "jvm_memory_pool_collection_init_bytes";
       
      -    private final PrometheusProperties config;
      -    private final MemoryMXBean memoryBean;
      -    private final List poolBeans;
      +  private final PrometheusProperties config;
      +  private final MemoryMXBean memoryBean;
      +  private final List poolBeans;
       
      -    private JvmMemoryMetrics(List poolBeans, MemoryMXBean memoryBean, PrometheusProperties config) {
      -        this.config = config;
      -        this.poolBeans = poolBeans;
      -        this.memoryBean = memoryBean;
      -    }
      +  private JvmMemoryMetrics(
      +      List poolBeans, MemoryMXBean memoryBean, PrometheusProperties config) {
      +    this.config = config;
      +    this.poolBeans = poolBeans;
      +    this.memoryBean = memoryBean;
      +  }
       
      -    private void register(PrometheusRegistry registry) {
      +  private void register(PrometheusRegistry registry) {
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION)
      -                .help("The number of objects waiting in the finalizer queue.")
      -                .callback(callback -> callback.call(memoryBean.getObjectPendingFinalizationCount()))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_OBJECTS_PENDING_FINALIZATION)
      +        .help("The number of objects waiting in the finalizer queue.")
      +        .callback(callback -> callback.call(memoryBean.getObjectPendingFinalizationCount()))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_USED_BYTES)
      -                .help("Used bytes of a given JVM memory area.")
      -                .unit(Unit.BYTES)
      -                .labelNames("area")
      -                .callback(callback -> {
      -                    callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap");
      -                    callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap");
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_USED_BYTES)
      +        .help("Used bytes of a given JVM memory area.")
      +        .unit(Unit.BYTES)
      +        .labelNames("area")
      +        .callback(
      +            callback -> {
      +              callback.call(memoryBean.getHeapMemoryUsage().getUsed(), "heap");
      +              callback.call(memoryBean.getNonHeapMemoryUsage().getUsed(), "nonheap");
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_COMMITTED_BYTES)
      -                .help("Committed (bytes) of a given JVM memory area.")
      -                .unit(Unit.BYTES)
      -                .labelNames("area")
      -                .callback(callback -> {
      -                    callback.call(memoryBean.getHeapMemoryUsage().getCommitted(), "heap");
      -                    callback.call(memoryBean.getNonHeapMemoryUsage().getCommitted(), "nonheap");
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_COMMITTED_BYTES)
      +        .help("Committed (bytes) of a given JVM memory area.")
      +        .unit(Unit.BYTES)
      +        .labelNames("area")
      +        .callback(
      +            callback -> {
      +              callback.call(memoryBean.getHeapMemoryUsage().getCommitted(), "heap");
      +              callback.call(memoryBean.getNonHeapMemoryUsage().getCommitted(), "nonheap");
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_MAX_BYTES)
      -                .help("Max (bytes) of a given JVM memory area.")
      -                .unit(Unit.BYTES)
      -                .labelNames("area")
      -                .callback(callback -> {
      -                    callback.call(memoryBean.getHeapMemoryUsage().getMax(), "heap");
      -                    callback.call(memoryBean.getNonHeapMemoryUsage().getMax(), "nonheap");
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_MAX_BYTES)
      +        .help("Max (bytes) of a given JVM memory area.")
      +        .unit(Unit.BYTES)
      +        .labelNames("area")
      +        .callback(
      +            callback -> {
      +              callback.call(memoryBean.getHeapMemoryUsage().getMax(), "heap");
      +              callback.call(memoryBean.getNonHeapMemoryUsage().getMax(), "nonheap");
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_INIT_BYTES)
      -                .help("Initial bytes of a given JVM memory area.")
      -                .unit(Unit.BYTES)
      -                .labelNames("area")
      -                .callback(callback -> {
      -                    callback.call(memoryBean.getHeapMemoryUsage().getInit(), "heap");
      -                    callback.call(memoryBean.getNonHeapMemoryUsage().getInit(), "nonheap");
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_INIT_BYTES)
      +        .help("Initial bytes of a given JVM memory area.")
      +        .unit(Unit.BYTES)
      +        .labelNames("area")
      +        .callback(
      +            callback -> {
      +              callback.call(memoryBean.getHeapMemoryUsage().getInit(), "heap");
      +              callback.call(memoryBean.getNonHeapMemoryUsage().getInit(), "nonheap");
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_USED_BYTES)
      -                .help("Used bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getUsed))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_USED_BYTES)
      +        .help("Used bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getUsed))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_COMMITTED_BYTES)
      -                .help("Committed bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getCommitted))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_COMMITTED_BYTES)
      +        .help("Committed bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getCommitted))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_MAX_BYTES)
      -                .help("Max bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getMax))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_MAX_BYTES)
      +        .help("Max bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getMax))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_INIT_BYTES)
      -                .help("Initial bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getInit))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_INIT_BYTES)
      +        .help("Initial bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(makeCallback(poolBeans, MemoryPoolMXBean::getUsage, MemoryUsage::getInit))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_COLLECTION_USED_BYTES)
      -                .help("Used bytes after last collection of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getUsed))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_COLLECTION_USED_BYTES)
      +        .help("Used bytes after last collection of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getUsed))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES)
      -                .help("Committed after last collection bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getCommitted))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_COLLECTION_COMMITTED_BYTES)
      +        .help("Committed after last collection bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            makeCallback(
      +                poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getCommitted))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES)
      -                .help("Max bytes after last collection of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getMax))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_COLLECTION_MAX_BYTES)
      +        .help("Max bytes after last collection of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getMax))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES)
      -                .help("Initial after last collection bytes of a given JVM memory pool.")
      -                .unit(Unit.BYTES)
      -                .labelNames("pool")
      -                .callback(makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getInit))
      -                .register(registry);
      -    }
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_MEMORY_POOL_COLLECTION_INIT_BYTES)
      +        .help("Initial after last collection bytes of a given JVM memory pool.")
      +        .unit(Unit.BYTES)
      +        .labelNames("pool")
      +        .callback(
      +            makeCallback(poolBeans, MemoryPoolMXBean::getCollectionUsage, MemoryUsage::getInit))
      +        .register(registry);
      +  }
       
      -    private Consumer makeCallback(List poolBeans, Function memoryUsageFunc, Function valueFunc) {
      -        return callback -> {
      -            for (MemoryPoolMXBean pool : poolBeans) {
      -                MemoryUsage poolUsage = memoryUsageFunc.apply(pool);
      -                if (poolUsage != null) {
      -                    callback.call(valueFunc.apply(poolUsage), pool.getName());
      -                }
      -            }
      -        };
      -    }
      +  private Consumer makeCallback(
      +      List poolBeans,
      +      Function memoryUsageFunc,
      +      Function valueFunc) {
      +    return callback -> {
      +      for (MemoryPoolMXBean pool : poolBeans) {
      +        MemoryUsage poolUsage = memoryUsageFunc.apply(pool);
      +        if (poolUsage != null) {
      +          callback.call(valueFunc.apply(poolUsage), pool.getName());
      +        }
      +      }
      +    };
      +  }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      -    }
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      -    }
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
       
      -    public static class Builder {
      +  public static class Builder {
       
      -        private final PrometheusProperties config;
      -        private MemoryMXBean memoryBean;
      -        private List poolBeans;
      +    private final PrometheusProperties config;
      +    private MemoryMXBean memoryBean;
      +    private List poolBeans;
       
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
      +    }
       
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder withMemoryBean(MemoryMXBean memoryBean) {
      -            this.memoryBean = memoryBean;
      -            return this;
      -        }
      +    /** Package private. For testing only. */
      +    Builder withMemoryBean(MemoryMXBean memoryBean) {
      +      this.memoryBean = memoryBean;
      +      return this;
      +    }
       
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder withMemoryPoolBeans(List memoryPoolBeans) {
      -            this.poolBeans = memoryPoolBeans;
      -            return this;
      -        }
      +    /** Package private. For testing only. */
      +    Builder withMemoryPoolBeans(List memoryPoolBeans) {
      +      this.poolBeans = memoryPoolBeans;
      +      return this;
      +    }
       
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
      +    }
       
      -        public void register(PrometheusRegistry registry) {
      -            MemoryMXBean memoryMXBean = this.memoryBean != null ? this.memoryBean : ManagementFactory.getMemoryMXBean();
      -            List poolBeans = this.poolBeans != null ? this.poolBeans : ManagementFactory.getMemoryPoolMXBeans();
      -            new JvmMemoryMetrics(poolBeans, memoryMXBean, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      MemoryMXBean memoryMXBean =
      +          this.memoryBean != null ? this.memoryBean : ManagementFactory.getMemoryMXBean();
      +      List poolBeans =
      +          this.poolBeans != null ? this.poolBeans : ManagementFactory.getMemoryPoolMXBeans();
      +      new JvmMemoryMetrics(poolBeans, memoryMXBean, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      index 522a2ef81..09aab0659 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      @@ -5,28 +5,34 @@
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.core.metrics.Counter;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -
      -import javax.management.Notification;
      -import javax.management.NotificationEmitter;
      -import javax.management.NotificationListener;
      -import javax.management.openmbean.CompositeData;
       import java.lang.management.GarbageCollectorMXBean;
       import java.lang.management.ManagementFactory;
       import java.lang.management.MemoryUsage;
       import java.util.HashMap;
       import java.util.List;
       import java.util.Map;
      +import javax.management.Notification;
      +import javax.management.NotificationEmitter;
      +import javax.management.NotificationListener;
      +import javax.management.openmbean.CompositeData;
       
       /**
      - * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM memory allocation metrics. The {@link JvmMemoryPoolAllocationMetrics} are registered as part
      + * of the {@link JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      - * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them directly: + * + * However, if you want only the {@link JvmMemoryPoolAllocationMetrics} you can also register them + * directly: + * *
      {@code
      - *   JvmMemoryAllocationMetrics.builder().register();
      + * JvmMemoryAllocationMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.
        * # TYPE jvm_memory_pool_allocated_bytes_total counter
      @@ -40,131 +46,136 @@
        */
       public class JvmMemoryPoolAllocationMetrics {
       
      -    private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL = "jvm_memory_pool_allocated_bytes_total";
      +  private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL =
      +      "jvm_memory_pool_allocated_bytes_total";
      +
      +  private final PrometheusProperties config;
      +  private final List garbageCollectorBeans;
      +
      +  private JvmMemoryPoolAllocationMetrics(
      +      List garbageCollectorBeans, PrometheusProperties config) {
      +    this.garbageCollectorBeans = garbageCollectorBeans;
      +    this.config = config;
      +  }
      +
      +  private void register(PrometheusRegistry registry) {
      +
      +    Counter allocatedCounter =
      +        Counter.builder()
      +            .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL)
      +            .help(
      +                "Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.")
      +            .labelNames("pool")
      +            .register(registry);
      +
      +    AllocationCountingNotificationListener listener =
      +        new AllocationCountingNotificationListener(allocatedCounter);
      +    for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) {
      +      if (garbageCollectorMXBean instanceof NotificationEmitter) {
      +        ((NotificationEmitter) garbageCollectorMXBean)
      +            .addNotificationListener(listener, null, null);
      +      }
      +    }
      +  }
       
      -    private final PrometheusProperties config;
      -    private final List garbageCollectorBeans;
      +  static class AllocationCountingNotificationListener implements NotificationListener {
      +
      +    private final Map lastMemoryUsage = new HashMap();
      +    private final Counter counter;
       
      -    private JvmMemoryPoolAllocationMetrics(List garbageCollectorBeans, PrometheusProperties config) {
      -        this.garbageCollectorBeans = garbageCollectorBeans;
      -        this.config = config;
      +    AllocationCountingNotificationListener(Counter counter) {
      +      this.counter = counter;
           }
       
      -    private void register(PrometheusRegistry registry) {
      +    @Override
      +    public synchronized void handleNotification(Notification notification, Object handback) {
      +      GarbageCollectionNotificationInfo info =
      +          GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
      +      GcInfo gcInfo = info.getGcInfo();
      +      Map memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc();
      +      Map memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc();
      +      for (Map.Entry entry : memoryUsageBeforeGc.entrySet()) {
      +        String memoryPool = entry.getKey();
      +        long before = entry.getValue().getUsed();
      +        long after = memoryUsageAfterGc.get(memoryPool).getUsed();
      +        handleMemoryPool(memoryPool, before, after);
      +      }
      +    }
       
      -        Counter allocatedCounter = Counter.builder()
      -                .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL)
      -                .help("Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.")
      -                .labelNames("pool")
      -                .register(registry);
      +    // Visible for testing
      +    void handleMemoryPool(String memoryPool, long before, long after) {
      +      /*
      +       * Calculate increase in the memory pool by comparing memory used
      +       * after last GC, before this GC, and after this GC.
      +       * See ascii illustration below.
      +       * Make sure to count only increases and ignore decreases.
      +       * (Typically a pool will only increase between GCs or during GCs, not both.
      +       * E.g. eden pools between GCs. Survivor and old generation pools during GCs.)
      +       *
      +       *                         |<-- diff1 -->|<-- diff2 -->|
      +       * Timeline: |-- last GC --|             |---- GC -----|
      +       *                      ___^__        ___^____      ___^___
      +       * Mem. usage vars:    / last \      / before \    / after \
      +       */
      +
      +      // Get last memory usage after GC and remember memory used after for next time
      +      long last = getAndSet(lastMemoryUsage, memoryPool, after);
      +      // Difference since last GC
      +      long diff1 = before - last;
      +      // Difference during this GC
      +      long diff2 = after - before;
      +      // Make sure to only count increases
      +      if (diff1 < 0) {
      +        diff1 = 0;
      +      }
      +      if (diff2 < 0) {
      +        diff2 = 0;
      +      }
      +      long increase = diff1 + diff2;
      +      if (increase > 0) {
      +        counter.labelValues(memoryPool).inc(increase);
      +      }
      +    }
       
      -        AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter);
      -        for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) {
      -            if (garbageCollectorMXBean instanceof NotificationEmitter) {
      -                ((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null);
      -            }
      -        }
      +    private static long getAndSet(Map map, String key, long value) {
      +      Long last = map.put(key, value);
      +      return last == null ? 0 : last;
           }
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder {
      +
      +    private final PrometheusProperties config;
      +    private List garbageCollectorBeans;
       
      -    static class AllocationCountingNotificationListener implements NotificationListener {
      -
      -        private final Map lastMemoryUsage = new HashMap();
      -        private final Counter counter;
      -
      -        AllocationCountingNotificationListener(Counter counter) {
      -            this.counter = counter;
      -        }
      -
      -        @Override
      -        public synchronized void handleNotification(Notification notification, Object handback) {
      -            GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) notification.getUserData());
      -            GcInfo gcInfo = info.getGcInfo();
      -            Map memoryUsageBeforeGc = gcInfo.getMemoryUsageBeforeGc();
      -            Map memoryUsageAfterGc = gcInfo.getMemoryUsageAfterGc();
      -            for (Map.Entry entry : memoryUsageBeforeGc.entrySet()) {
      -                String memoryPool = entry.getKey();
      -                long before = entry.getValue().getUsed();
      -                long after = memoryUsageAfterGc.get(memoryPool).getUsed();
      -                handleMemoryPool(memoryPool, before, after);
      -            }
      -        }
      -
      -        // Visible for testing
      -        void handleMemoryPool(String memoryPool, long before, long after) {
      -            /*
      -             * Calculate increase in the memory pool by comparing memory used
      -             * after last GC, before this GC, and after this GC.
      -             * See ascii illustration below.
      -             * Make sure to count only increases and ignore decreases.
      -             * (Typically a pool will only increase between GCs or during GCs, not both.
      -             * E.g. eden pools between GCs. Survivor and old generation pools during GCs.)
      -             *
      -             *                         |<-- diff1 -->|<-- diff2 -->|
      -             * Timeline: |-- last GC --|             |---- GC -----|
      -             *                      ___^__        ___^____      ___^___
      -             * Mem. usage vars:    / last \      / before \    / after \
      -             */
      -
      -            // Get last memory usage after GC and remember memory used after for next time
      -            long last = getAndSet(lastMemoryUsage, memoryPool, after);
      -            // Difference since last GC
      -            long diff1 = before - last;
      -            // Difference during this GC
      -            long diff2 = after - before;
      -            // Make sure to only count increases
      -            if (diff1 < 0) {
      -                diff1 = 0;
      -            }
      -            if (diff2 < 0) {
      -                diff2 = 0;
      -            }
      -            long increase = diff1 + diff2;
      -            if (increase > 0) {
      -                counter.labelValues(memoryPool).inc(increase);
      -            }
      -        }
      -
      -        private static long getAndSet(Map map, String key, long value) {
      -            Long last = map.put(key, value);
      -            return last == null ? 0 : last;
      -        }
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      +    /** Package private. For testing only. */
      +    Builder withGarbageCollectorBeans(List garbageCollectorBeans) {
      +      this.garbageCollectorBeans = garbageCollectorBeans;
      +      return this;
           }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
           }
       
      -    public static class Builder {
      -
      -        private final PrometheusProperties config;
      -        private List garbageCollectorBeans;
      -
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder withGarbageCollectorBeans(List garbageCollectorBeans) {
      -            this.garbageCollectorBeans = garbageCollectorBeans;
      -            return this;
      -        }
      -
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      -
      -        public void register(PrometheusRegistry registry) {
      -            List garbageCollectorBeans = this.garbageCollectorBeans;
      -            if (garbageCollectorBeans == null) {
      -                garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans();
      -            }
      -            new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      List garbageCollectorBeans = this.garbageCollectorBeans;
      +      if (garbageCollectorBeans == null) {
      +        garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans();
      +      }
      +      new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
      index 54d937688..0f5a56eee 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMetrics.java
      @@ -2,67 +2,70 @@
       
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -
       import java.util.Set;
       import java.util.concurrent.ConcurrentHashMap;
       
       /**
        * Registers all JVM metrics. Example usage:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      */ public class JvmMetrics { - private static final Set REGISTERED = ConcurrentHashMap.newKeySet(); - public static Builder builder() { - return new Builder(PrometheusProperties.get()); - } + private static final Set REGISTERED = ConcurrentHashMap.newKeySet(); - // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you pass a config or not. - // However, we will add config options in the future, like whether you want to use Prometheus naming conventions - // or OpenTelemetry semantic conventions for JVM metrics. - public static Builder builder(PrometheusProperties config) { - return new Builder(config); - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - public static class Builder { + // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you + // pass a config or not. + // However, we will add config options in the future, like whether you want to use Prometheus + // naming conventions + // or OpenTelemetry semantic conventions for JVM metrics. + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - private final PrometheusProperties config; + public static class Builder { - private Builder(PrometheusProperties config) { - this.config = config; - } + private final PrometheusProperties config; - /** - * Register all JVM metrics with the default registry. - *

      - * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls - * will be ignored. - */ - public void register() { - register(PrometheusRegistry.defaultRegistry); - } + private Builder(PrometheusProperties config) { + this.config = config; + } + + /** + * Register all JVM metrics with the default registry. + * + *

      It's safe to call this multiple times, only the first call will register the metrics, all + * subsequent calls will be ignored. + */ + public void register() { + register(PrometheusRegistry.defaultRegistry); + } - /** - * Register all JVM metrics with the {@code registry}. - *

      - * It's safe to call this multiple times, only the first call will register the metrics, all subsequent calls - * will be ignored. - */ - public void register(PrometheusRegistry registry) { - if (REGISTERED.add(registry)) { - JvmThreadsMetrics.builder(config).register(registry); - JvmBufferPoolMetrics.builder(config).register(registry); - JvmClassLoadingMetrics.builder(config).register(registry); - JvmCompilationMetrics.builder(config).register(registry); - JvmGarbageCollectorMetrics.builder(config).register(registry); - JvmMemoryPoolAllocationMetrics.builder(config).register(registry); - JvmMemoryMetrics.builder(config).register(registry); - JvmNativeMemoryMetrics.builder(config).register(registry); - JvmRuntimeInfoMetric.builder(config).register(registry); - ProcessMetrics.builder(config).register(registry); - } - } + /** + * Register all JVM metrics with the {@code registry}. + * + *

      It's safe to call this multiple times, only the first call will register the metrics, all + * subsequent calls will be ignored. + */ + public void register(PrometheusRegistry registry) { + if (REGISTERED.add(registry)) { + JvmThreadsMetrics.builder(config).register(registry); + JvmBufferPoolMetrics.builder(config).register(registry); + JvmClassLoadingMetrics.builder(config).register(registry); + JvmCompilationMetrics.builder(config).register(registry); + JvmGarbageCollectorMetrics.builder(config).register(registry); + JvmMemoryPoolAllocationMetrics.builder(config).register(registry); + JvmMemoryMetrics.builder(config).register(registry); + JvmNativeMemoryMetrics.builder(config).register(registry); + JvmRuntimeInfoMetric.builder(config).register(registry); + ProcessMetrics.builder(config).register(registry); + } } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java index 8e60a31d9..4f02823f1 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java @@ -4,34 +4,41 @@ import io.prometheus.metrics.core.metrics.GaugeWithCallback; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.Unit; - -import javax.management.InstanceNotFoundException; -import javax.management.MBeanException; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import javax.management.ReflectionException; import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.ReflectionException; /** - * JVM native memory. JVM native memory tracking is disabled by default. You need to enable it by starting your JVM with this flag: + * JVM native memory. JVM native memory tracking is disabled by default. You need to enable it by + * starting your JVM with this flag: + * *

      -XX:NativeMemoryTracking=summary
      + * + *

      When native memory tracking is disabled the metrics are not registered either. + * *

      - * When native memory tracking is disabled the metrics are not registered either. - *

      - *

      - * The {@link JvmNativeMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + * + *

      The {@link JvmNativeMemoryMetrics} are registered as part of the {@link JvmMetrics} like this: + * *

      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmNativeMemoryMetrics} you can also register them directly: + * *
      {@code
      - *   JvmNativeMemoryMetrics.builder().register();
      + * JvmNativeMemoryMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.
        * # TYPE jvm_native_memory_committed_bytes gauge
      @@ -79,13 +86,13 @@
        */
       public class JvmNativeMemoryMetrics {
         private static final String JVM_NATIVE_MEMORY_RESERVED_BYTES = "jvm_native_memory_reserved_bytes";
      -  private static final String JVM_NATIVE_MEMORY_COMMITTED_BYTES = "jvm_native_memory_committed_bytes";
      +  private static final String JVM_NATIVE_MEMORY_COMMITTED_BYTES =
      +      "jvm_native_memory_committed_bytes";
       
      -  private static final Pattern pattern = Pattern.compile("\\s*([A-Z][A-Za-z\\s]*[A-Za-z]+).*reserved=(\\d+), committed=(\\d+)");
      +  private static final Pattern pattern =
      +      Pattern.compile("\\s*([A-Z][A-Za-z\\s]*[A-Za-z]+).*reserved=(\\d+), committed=(\\d+)");
       
      -  /**
      -   * Package private. For testing only.
      -   */
      +  /** Package private. For testing only. */
         static final AtomicBoolean isEnabled = new AtomicBoolean(true);
       
         private final PrometheusProperties config;
      @@ -102,7 +109,8 @@ private void register(PrometheusRegistry registry) {
           if (isEnabled.get()) {
             GaugeWithCallback.builder(config)
                 .name(JVM_NATIVE_MEMORY_RESERVED_BYTES)
      -          .help("Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.")
      +          .help(
      +              "Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.")
                 .unit(Unit.BYTES)
                 .labelNames("pool")
                 .callback(makeCallback(true))
      @@ -110,7 +118,8 @@ private void register(PrometheusRegistry registry) {
       
             GaugeWithCallback.builder(config)
                 .name(JVM_NATIVE_MEMORY_COMMITTED_BYTES)
      -          .help("Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.")
      +          .help(
      +              "Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.")
                 .unit(Unit.BYTES)
                 .labelNames("pool")
                 .callback(makeCallback(false))
      @@ -165,12 +174,17 @@ static class DefaultPlatformMBeanServerAdapter implements PlatformMBeanServerAda
           @Override
           public String vmNativeMemorySummaryInBytes() {
             try {
      -        return (String) ManagementFactory.getPlatformMBeanServer().invoke(
      -            new ObjectName("com.sun.management:type=DiagnosticCommand"),
      -            "vmNativeMemory",
      -            new Object[]{new String[]{"summary", "scale=B"}},
      -            new String[]{"[Ljava.lang.String;"});
      -      } catch (ReflectionException | MalformedObjectNameException | InstanceNotFoundException | MBeanException e) {
      +        return (String)
      +            ManagementFactory.getPlatformMBeanServer()
      +                .invoke(
      +                    new ObjectName("com.sun.management:type=DiagnosticCommand"),
      +                    "vmNativeMemory",
      +                    new Object[] {new String[] {"summary", "scale=B"}},
      +                    new String[] {"[Ljava.lang.String;"});
      +      } catch (ReflectionException
      +          | MalformedObjectNameException
      +          | InstanceNotFoundException
      +          | MBeanException e) {
               throw new IllegalStateException("Native memory tracking is not enabled", e);
             }
           }
      @@ -193,9 +207,7 @@ private Builder(PrometheusProperties config) {
             this(config, new DefaultPlatformMBeanServerAdapter());
           }
       
      -    /**
      -     * Package private. For testing only.
      -     */
      +    /** Package private. For testing only. */
           Builder(PrometheusProperties config, PlatformMBeanServerAdapter adapter) {
             this.config = config;
             this.adapter = adapter;
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java
      index c7024b14e..333395425 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.java
      @@ -5,13 +5,17 @@
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       
       /**
      - * JVM Runtime Info metric. The {@link JvmRuntimeInfoMetric} is registered as part of the {@link JvmMetrics} like this:
      + * JVM Runtime Info metric. The {@link JvmRuntimeInfoMetric} is registered as part of the {@link
      + * JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmRuntimeInfoMetric} you can also register them directly: + * *
      {@code
      - *   JvmRuntimeInfoMetric.builder().register();
      + * JvmRuntimeInfoMetric.builder().register();
        * }
      * *
      @@ -22,83 +26,84 @@
        */
       public class JvmRuntimeInfoMetric {
       
      -    private static final String JVM_RUNTIME_INFO = "jvm_runtime_info";
      +  private static final String JVM_RUNTIME_INFO = "jvm_runtime_info";
      +
      +  private final PrometheusProperties config;
      +  private final String version;
      +  private final String vendor;
      +  private final String runtime;
      +
      +  private JvmRuntimeInfoMetric(
      +      String version, String vendor, String runtime, PrometheusProperties config) {
      +    this.config = config;
      +    this.version = version;
      +    this.vendor = vendor;
      +    this.runtime = runtime;
      +  }
      +
      +  private void register(PrometheusRegistry registry) {
      +
      +    Info jvmInfo =
      +        Info.builder(config)
      +            .name(JVM_RUNTIME_INFO)
      +            .help("JVM runtime info")
      +            .labelNames("version", "vendor", "runtime")
      +            .register(registry);
      +
      +    jvmInfo.setLabelValues(version, vendor, runtime);
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder {
       
           private final PrometheusProperties config;
      -    private final String version;
      -    private final String vendor;
      -    private final String runtime;
      -
      -    private JvmRuntimeInfoMetric(String version, String vendor, String runtime, PrometheusProperties config) {
      -        this.config = config;
      -        this.version = version;
      -        this.vendor = vendor;
      -        this.runtime = runtime;
      -    }
      +    private String version;
      +    private String vendor;
      +    private String runtime;
       
      -    private void register(PrometheusRegistry registry) {
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
      +    }
       
      -        Info jvmInfo = Info.builder(config)
      -                .name(JVM_RUNTIME_INFO)
      -                .help("JVM runtime info")
      -                .labelNames("version", "vendor", "runtime")
      -                .register(registry);
      +    /** Package private. For testing only. */
      +    Builder version(String version) {
      +      this.version = version;
      +      return this;
      +    }
       
      -        jvmInfo.setLabelValues(version, vendor, runtime);
      +    /** Package private. For testing only. */
      +    Builder vendor(String vendor) {
      +      this.vendor = vendor;
      +      return this;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      +    /** Package private. For testing only. */
      +    Builder runtime(String runtime) {
      +      this.runtime = runtime;
      +      return this;
           }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
           }
       
      -    public static class Builder {
      -
      -        private final PrometheusProperties config;
      -        private String version;
      -        private String vendor;
      -        private String runtime;
      -
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder version(String version) {
      -            this.version = version;
      -            return this;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder vendor(String vendor) {
      -            this.vendor = vendor;
      -            return this;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder runtime(String runtime) {
      -            this.runtime = runtime;
      -            return this;
      -        }
      -
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      -
      -        public void register(PrometheusRegistry registry) {
      -            String version = this.version != null ? this.version : System.getProperty("java.runtime.version", "unknown");
      -            String vendor = this.vendor != null ? this.vendor : System.getProperty("java.vm.vendor", "unknown");
      -            String runtime = this.runtime != null ? this.runtime : System.getProperty("java.runtime.name", "unknown");
      -            new JvmRuntimeInfoMetric(version, vendor, runtime, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      String version =
      +          this.version != null
      +              ? this.version
      +              : System.getProperty("java.runtime.version", "unknown");
      +      String vendor =
      +          this.vendor != null ? this.vendor : System.getProperty("java.vm.vendor", "unknown");
      +      String runtime =
      +          this.runtime != null ? this.runtime : System.getProperty("java.runtime.name", "unknown");
      +      new JvmRuntimeInfoMetric(version, vendor, runtime, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      index d38c50a54..4027551ac 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      @@ -4,7 +4,6 @@
       import io.prometheus.metrics.core.metrics.CounterWithCallback;
       import io.prometheus.metrics.core.metrics.GaugeWithCallback;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -
       import java.lang.management.ManagementFactory;
       import java.lang.management.ThreadInfo;
       import java.lang.management.ThreadMXBean;
      @@ -13,15 +12,21 @@
       import java.util.Map;
       
       /**
      - * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link JvmMetrics} like this:
      + * JVM Thread metrics. The {@link JvmThreadsMetrics} are registered as part of the {@link
      + * JvmMetrics} like this:
      + *
        * 
      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link JvmThreadsMetrics} you can also register them directly: + * *
      {@code
      - *   JvmThreadMetrics.builder().register();
      + * JvmThreadMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP jvm_threads_current Current thread count of a JVM
        * # TYPE jvm_threads_current gauge
      @@ -54,162 +59,165 @@
        */
       public class JvmThreadsMetrics {
       
      -    private static final String UNKNOWN = "UNKNOWN";
      -    private static final String JVM_THREADS_STATE = "jvm_threads_state";
      -    private static final String JVM_THREADS_CURRENT = "jvm_threads_current";
      -    private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon";
      -    private static final String JVM_THREADS_PEAK = "jvm_threads_peak";
      -    private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total";
      -    private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked";
      -    private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor";
      +  private static final String UNKNOWN = "UNKNOWN";
      +  private static final String JVM_THREADS_STATE = "jvm_threads_state";
      +  private static final String JVM_THREADS_CURRENT = "jvm_threads_current";
      +  private static final String JVM_THREADS_DAEMON = "jvm_threads_daemon";
      +  private static final String JVM_THREADS_PEAK = "jvm_threads_peak";
      +  private static final String JVM_THREADS_STARTED_TOTAL = "jvm_threads_started_total";
      +  private static final String JVM_THREADS_DEADLOCKED = "jvm_threads_deadlocked";
      +  private static final String JVM_THREADS_DEADLOCKED_MONITOR = "jvm_threads_deadlocked_monitor";
      +
      +  private final PrometheusProperties config;
      +  private final ThreadMXBean threadBean;
      +  private final boolean isNativeImage;
      +
      +  private JvmThreadsMetrics(
      +      boolean isNativeImage, ThreadMXBean threadBean, PrometheusProperties config) {
      +    this.config = config;
      +    this.threadBean = threadBean;
      +    this.isNativeImage = isNativeImage;
      +  }
      +
      +  private void register(PrometheusRegistry registry) {
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_THREADS_CURRENT)
      +        .help("Current thread count of a JVM")
      +        .callback(callback -> callback.call(threadBean.getThreadCount()))
      +        .register(registry);
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_THREADS_DAEMON)
      +        .help("Daemon thread count of a JVM")
      +        .callback(callback -> callback.call(threadBean.getDaemonThreadCount()))
      +        .register(registry);
      +
      +    GaugeWithCallback.builder(config)
      +        .name(JVM_THREADS_PEAK)
      +        .help("Peak thread count of a JVM")
      +        .callback(callback -> callback.call(threadBean.getPeakThreadCount()))
      +        .register(registry);
      +
      +    CounterWithCallback.builder(config)
      +        .name(JVM_THREADS_STARTED_TOTAL)
      +        .help("Started thread count of a JVM")
      +        .callback(callback -> callback.call(threadBean.getTotalStartedThreadCount()))
      +        .register(registry);
      +
      +    if (!isNativeImage) {
      +      GaugeWithCallback.builder(config)
      +          .name(JVM_THREADS_DEADLOCKED)
      +          .help(
      +              "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers")
      +          .callback(
      +              callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads())))
      +          .register(registry);
      +
      +      GaugeWithCallback.builder(config)
      +          .name(JVM_THREADS_DEADLOCKED_MONITOR)
      +          .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors")
      +          .callback(
      +              callback ->
      +                  callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())))
      +          .register(registry);
      +
      +      GaugeWithCallback.builder(config)
      +          .name(JVM_THREADS_STATE)
      +          .help("Current count of threads by state")
      +          .labelNames("state")
      +          .callback(
      +              callback -> {
      +                Map threadStateCounts = getThreadStateCountMap(threadBean);
      +                for (Map.Entry entry : threadStateCounts.entrySet()) {
      +                  callback.call(entry.getValue(), entry.getKey());
      +                }
      +              })
      +          .register(registry);
      +    }
      +  }
      +
      +  private Map getThreadStateCountMap(ThreadMXBean threadBean) {
      +    long[] threadIds = threadBean.getAllThreadIds();
       
      -    private final PrometheusProperties config;
      -    private final ThreadMXBean threadBean;
      -    private final boolean isNativeImage;
      +    // Code to remove any thread id values <= 0
      +    int writePos = 0;
      +    for (int i = 0; i < threadIds.length; i++) {
      +      if (threadIds[i] > 0) {
      +        threadIds[writePos++] = threadIds[i];
      +      }
      +    }
      +
      +    int numberOfInvalidThreadIds = threadIds.length - writePos;
      +    threadIds = Arrays.copyOf(threadIds, writePos);
       
      -    private JvmThreadsMetrics(boolean isNativeImage, ThreadMXBean threadBean, PrometheusProperties config) {
      -        this.config = config;
      -        this.threadBean = threadBean;
      -        this.isNativeImage = isNativeImage;
      +    // Get thread information without computing any stack traces
      +    ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0);
      +
      +    // Initialize the map with all thread states
      +    HashMap threadCounts = new HashMap();
      +    for (Thread.State state : Thread.State.values()) {
      +      threadCounts.put(state.name(), 0);
           }
       
      -    private void register(PrometheusRegistry registry) {
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_THREADS_CURRENT)
      -                .help("Current thread count of a JVM")
      -                .callback(callback -> callback.call(threadBean.getThreadCount()))
      -                .register(registry);
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_THREADS_DAEMON)
      -                .help("Daemon thread count of a JVM")
      -                .callback(callback -> callback.call(threadBean.getDaemonThreadCount()))
      -                .register(registry);
      -
      -        GaugeWithCallback.builder(config)
      -                .name(JVM_THREADS_PEAK)
      -                .help("Peak thread count of a JVM")
      -                .callback(callback -> callback.call(threadBean.getPeakThreadCount()))
      -                .register(registry);
      -
      -        CounterWithCallback.builder(config)
      -                .name(JVM_THREADS_STARTED_TOTAL)
      -                .help("Started thread count of a JVM")
      -                .callback(callback -> callback.call(threadBean.getTotalStartedThreadCount()))
      -                .register(registry);
      -
      -        if (!isNativeImage) {
      -            GaugeWithCallback.builder(config)
      -                    .name(JVM_THREADS_DEADLOCKED)
      -                    .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers")
      -                    .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads())))
      -                    .register(registry);
      -
      -            GaugeWithCallback.builder(config)
      -                    .name(JVM_THREADS_DEADLOCKED_MONITOR)
      -                    .help("Cycles of JVM-threads that are in deadlock waiting to acquire object monitors")
      -                    .callback(callback -> callback.call(nullSafeArrayLength(threadBean.findMonitorDeadlockedThreads())))
      -                    .register(registry);
      -
      -
      -            GaugeWithCallback.builder(config)
      -                    .name(JVM_THREADS_STATE)
      -                    .help("Current count of threads by state")
      -                    .labelNames("state")
      -                    .callback(callback -> {
      -                        Map threadStateCounts = getThreadStateCountMap(threadBean);
      -                        for (Map.Entry entry : threadStateCounts.entrySet()) {
      -                            callback.call(entry.getValue(), entry.getKey());
      -                        }
      -                    })
      -                    .register(registry);
      -        }
      +    // Collect the actual thread counts
      +    for (ThreadInfo curThread : allThreads) {
      +      if (curThread != null) {
      +        Thread.State threadState = curThread.getThreadState();
      +        threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1);
      +      }
           }
       
      -    private Map getThreadStateCountMap(ThreadMXBean threadBean) {
      -        long[] threadIds = threadBean.getAllThreadIds();
      -
      -        // Code to remove any thread id values <= 0
      -        int writePos = 0;
      -        for (int i = 0; i < threadIds.length; i++) {
      -            if (threadIds[i] > 0) {
      -                threadIds[writePos++] = threadIds[i];
      -            }
      -        }
      -
      -        int numberOfInvalidThreadIds = threadIds.length - writePos;
      -        threadIds = Arrays.copyOf(threadIds, writePos);
      -
      -        // Get thread information without computing any stack traces
      -        ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0);
      -
      -        // Initialize the map with all thread states
      -        HashMap threadCounts = new HashMap();
      -        for (Thread.State state : Thread.State.values()) {
      -            threadCounts.put(state.name(), 0);
      -        }
      -
      -        // Collect the actual thread counts
      -        for (ThreadInfo curThread : allThreads) {
      -            if (curThread != null) {
      -                Thread.State threadState = curThread.getThreadState();
      -                threadCounts.put(threadState.name(), threadCounts.get(threadState.name()) + 1);
      -            }
      -        }
      -
      -        // Add the thread count for invalid thread ids
      -        threadCounts.put(UNKNOWN, numberOfInvalidThreadIds);
      -
      -        return threadCounts;
      +    // Add the thread count for invalid thread ids
      +    threadCounts.put(UNKNOWN, numberOfInvalidThreadIds);
      +
      +    return threadCounts;
      +  }
      +
      +  private double nullSafeArrayLength(long[] array) {
      +    return null == array ? 0 : array.length;
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder(PrometheusProperties.get());
      +  }
      +
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
      +
      +  public static class Builder {
      +
      +    private final PrometheusProperties config;
      +    private Boolean isNativeImage;
      +    private ThreadMXBean threadBean;
      +
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
           }
       
      -    private double nullSafeArrayLength(long[] array) {
      -        return null == array ? 0 : array.length;
      +    /** Package private. For testing only. */
      +    Builder threadBean(ThreadMXBean threadBean) {
      +      this.threadBean = threadBean;
      +      return this;
           }
       
      -    public static Builder builder() {
      -        return new Builder(PrometheusProperties.get());
      +    /** Package private. For testing only. */
      +    Builder isNativeImage(boolean isNativeImage) {
      +      this.isNativeImage = isNativeImage;
      +      return this;
           }
       
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
           }
       
      -    public static class Builder {
      -
      -        private final PrometheusProperties config;
      -        private Boolean isNativeImage;
      -        private ThreadMXBean threadBean;
      -
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder threadBean(ThreadMXBean threadBean) {
      -            this.threadBean = threadBean;
      -            return this;
      -        }
      -
      -        /**
      -         * Package private. For testing only.
      -         */
      -        Builder isNativeImage(boolean isNativeImage) {
      -            this.isNativeImage = isNativeImage;
      -            return this;
      -        }
      -
      -        public void register() {
      -            register(PrometheusRegistry.defaultRegistry);
      -        }
      -
      -        public void register(PrometheusRegistry registry) {
      -            ThreadMXBean threadBean = this.threadBean != null ? this.threadBean : ManagementFactory.getThreadMXBean();
      -            boolean isNativeImage = this.isNativeImage != null ? this.isNativeImage : NativeImageChecker.isGraalVmNativeImage;
      -            new JvmThreadsMetrics(isNativeImage, threadBean, config).register(registry);
      -        }
      +    public void register(PrometheusRegistry registry) {
      +      ThreadMXBean threadBean =
      +          this.threadBean != null ? this.threadBean : ManagementFactory.getThreadMXBean();
      +      boolean isNativeImage =
      +          this.isNativeImage != null ? this.isNativeImage : NativeImageChecker.isGraalVmNativeImage;
      +      new JvmThreadsMetrics(isNativeImage, threadBean, config).register(registry);
           }
      +  }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java
      index 11e3efb2d..e75350bce 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/NativeImageChecker.java
      @@ -1,13 +1,15 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       /**
      - * Contains utilities to check if we are running inside or building for native image. Default behavior is to check
      - * if specific for graalvm runtime property is present. For additional optimizations it is possible to do add
      - * "--initialize-at-build-time=io.prometheus.client.hotspot.NativeImageChecker" to graalvm native image build command and
      - * the native image will be identified during build time.
      + * Contains utilities to check if we are running inside or building for native image. Default
      + * behavior is to check if specific for graalvm runtime property is present. For additional
      + * optimizations it is possible to do add
      + * "--initialize-at-build-time=io.prometheus.client.hotspot.NativeImageChecker" to graalvm native
      + * image build command and the native image will be identified during build time.
        */
       class NativeImageChecker {
      -    static final boolean isGraalVmNativeImage = System.getProperty("org.graalvm.nativeimage.imagecode") != null;
      +  static final boolean isGraalVmNativeImage =
      +      System.getProperty("org.graalvm.nativeimage.imagecode") != null;
       
      -    private NativeImageChecker() {}
      +  private NativeImageChecker() {}
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      index bca58942a..f875c104f 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      @@ -5,7 +5,6 @@
       import io.prometheus.metrics.core.metrics.GaugeWithCallback;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.Unit;
      -
       import java.io.BufferedReader;
       import java.io.File;
       import java.io.FileReader;
      @@ -18,23 +17,31 @@
       
       /**
        * Process metrics.
      - * 

      - * These metrics are defined in the process metrics - * section of the Prometheus client library documentation, and they are implemented across client libraries in multiple programming languages. - *

      - * Technically, some of them are OS-level metrics and not JVM-level metrics. However, I'm still putting them - * in the {@code prometheus-metrics-instrumentation-jvm} module, because first it seems overkill to create a separate - * Maven module just for the {@link ProcessMetrics} class, and seconds some of these metrics are coming from the JVM via JMX anyway. - *

      - * The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: + * + *

      These metrics are defined in the process + * metrics section of the Prometheus client library documentation, and they are implemented + * across client libraries in multiple programming languages. + * + *

      Technically, some of them are OS-level metrics and not JVM-level metrics. However, I'm still + * putting them in the {@code prometheus-metrics-instrumentation-jvm} module, because first it seems + * overkill to create a separate Maven module just for the {@link ProcessMetrics} class, and seconds + * some of these metrics are coming from the JVM via JMX anyway. + * + *

      The {@link ProcessMetrics} are registered as part of the {@link JvmMetrics} like this: + * *

      {@code
      - *   JvmMetrics.builder().register();
      + * JvmMetrics.builder().register();
        * }
      + * * However, if you want only the {@link ProcessMetrics} you can also register them directly: + * *
      {@code
      - *   ProcessMetrics.builder().register();
      + * ProcessMetrics.builder().register();
        * }
      + * * Example metrics being exported: + * *
        * # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
        * # TYPE process_cpu_seconds_total counter
      @@ -58,228 +65,237 @@
        */
       public class ProcessMetrics {
       
      -    private static final String PROCESS_CPU_SECONDS_TOTAL = "process_cpu_seconds_total";
      -    private static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds";
      -    private static final String PROCESS_OPEN_FDS = "process_open_fds";
      -    private static final String PROCESS_MAX_FDS = "process_max_fds";
      -    private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes";
      -    private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes";
      +  private static final String PROCESS_CPU_SECONDS_TOTAL = "process_cpu_seconds_total";
      +  private static final String PROCESS_START_TIME_SECONDS = "process_start_time_seconds";
      +  private static final String PROCESS_OPEN_FDS = "process_open_fds";
      +  private static final String PROCESS_MAX_FDS = "process_max_fds";
      +  private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes";
      +  private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes";
       
      -    private static final File PROC_SELF_STATUS = new File("/proc/self/status");
      +  private static final File PROC_SELF_STATUS = new File("/proc/self/status");
       
      -    private final PrometheusProperties config;
      -    private final OperatingSystemMXBean osBean;
      -    private final RuntimeMXBean runtimeBean;
      -    private final Grepper grepper;
      -    private final boolean linux;
      +  private final PrometheusProperties config;
      +  private final OperatingSystemMXBean osBean;
      +  private final RuntimeMXBean runtimeBean;
      +  private final Grepper grepper;
      +  private final boolean linux;
       
      -    private ProcessMetrics(OperatingSystemMXBean osBean, RuntimeMXBean runtimeBean, Grepper grepper, PrometheusProperties config) {
      -        this.osBean = osBean;
      -        this.runtimeBean = runtimeBean;
      -        this.grepper = grepper;
      -        this.config = config;
      -        this.linux = PROC_SELF_STATUS.canRead();
      -    }
      +  private ProcessMetrics(
      +      OperatingSystemMXBean osBean,
      +      RuntimeMXBean runtimeBean,
      +      Grepper grepper,
      +      PrometheusProperties config) {
      +    this.osBean = osBean;
      +    this.runtimeBean = runtimeBean;
      +    this.grepper = grepper;
      +    this.config = config;
      +    this.linux = PROC_SELF_STATUS.canRead();
      +  }
       
      -    private void register(PrometheusRegistry registry) {
      +  private void register(PrometheusRegistry registry) {
       
      -        CounterWithCallback.builder(config)
      -                .name(PROCESS_CPU_SECONDS_TOTAL)
      -                .help("Total user and system CPU time spent in seconds.")
      -                .unit(Unit.SECONDS)
      -                .callback(callback -> {
      -                    try {
      -                        // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean interfaces, in
      -                        // com.sun.management and com.ibm.lang.management. Hence use reflection and recursively go
      -                        // through implemented interfaces until the method can be made accessible and invoked.
      -                        Long processCpuTime = callLongGetter("getProcessCpuTime", osBean);
      -                        if (processCpuTime != null) {
      -                            callback.call(Unit.nanosToSeconds(processCpuTime));
      -                        }
      -                    } catch (Exception ignored) {
      -                    }
      -                })
      -                .register(registry);
      +    CounterWithCallback.builder(config)
      +        .name(PROCESS_CPU_SECONDS_TOTAL)
      +        .help("Total user and system CPU time spent in seconds.")
      +        .unit(Unit.SECONDS)
      +        .callback(
      +            callback -> {
      +              try {
      +                // There exist at least 2 similar but unrelated UnixOperatingSystemMXBean
      +                // interfaces, in
      +                // com.sun.management and com.ibm.lang.management. Hence use reflection and
      +                // recursively go
      +                // through implemented interfaces until the method can be made accessible and
      +                // invoked.
      +                Long processCpuTime = callLongGetter("getProcessCpuTime", osBean);
      +                if (processCpuTime != null) {
      +                  callback.call(Unit.nanosToSeconds(processCpuTime));
      +                }
      +              } catch (Exception ignored) {
      +              }
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(PROCESS_START_TIME_SECONDS)
      -                .help("Start time of the process since unix epoch in seconds.")
      -                .unit(Unit.SECONDS)
      -                .callback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime())))
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(PROCESS_START_TIME_SECONDS)
      +        .help("Start time of the process since unix epoch in seconds.")
      +        .unit(Unit.SECONDS)
      +        .callback(callback -> callback.call(Unit.millisToSeconds(runtimeBean.getStartTime())))
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(PROCESS_OPEN_FDS)
      -                .help("Number of open file descriptors.")
      -                .callback(callback -> {
      -                    try {
      -                        Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean);
      -                        if (openFds != null) {
      -                            callback.call(openFds);
      -                        }
      -                    } catch (Exception ignored) {
      -                    }
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(PROCESS_OPEN_FDS)
      +        .help("Number of open file descriptors.")
      +        .callback(
      +            callback -> {
      +              try {
      +                Long openFds = callLongGetter("getOpenFileDescriptorCount", osBean);
      +                if (openFds != null) {
      +                  callback.call(openFds);
      +                }
      +              } catch (Exception ignored) {
      +              }
      +            })
      +        .register(registry);
       
      -        GaugeWithCallback.builder(config)
      -                .name(PROCESS_MAX_FDS)
      -                .help("Maximum number of open file descriptors.")
      -                .callback(callback -> {
      -                    try {
      -                        Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean);
      -                        if (maxFds != null) {
      -                            callback.call(maxFds);
      -                        }
      -                    } catch (Exception ignored) {
      -                    }
      -                })
      -                .register(registry);
      +    GaugeWithCallback.builder(config)
      +        .name(PROCESS_MAX_FDS)
      +        .help("Maximum number of open file descriptors.")
      +        .callback(
      +            callback -> {
      +              try {
      +                Long maxFds = callLongGetter("getMaxFileDescriptorCount", osBean);
      +                if (maxFds != null) {
      +                  callback.call(maxFds);
      +                }
      +              } catch (Exception ignored) {
      +              }
      +            })
      +        .register(registry);
       
      -        if (linux) {
      +    if (linux) {
       
      -            GaugeWithCallback.builder(config)
      -                    .name(PROCESS_VIRTUAL_MEMORY_BYTES)
      -                    .help("Virtual memory size in bytes.")
      -                    .unit(Unit.BYTES)
      -                    .callback(callback -> {
      -                        try {
      -                            String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:");
      -                            callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
      -                        } catch (Exception ignored) {
      -                        }
      -                    })
      -                    .register(registry);
      +      GaugeWithCallback.builder(config)
      +          .name(PROCESS_VIRTUAL_MEMORY_BYTES)
      +          .help("Virtual memory size in bytes.")
      +          .unit(Unit.BYTES)
      +          .callback(
      +              callback -> {
      +                try {
      +                  String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:");
      +                  callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
      +                } catch (Exception ignored) {
      +                }
      +              })
      +          .register(registry);
       
      -            GaugeWithCallback.builder(config)
      -                    .name(PROCESS_RESIDENT_MEMORY_BYTES)
      -                    .help("Resident memory size in bytes.")
      -                    .unit(Unit.BYTES)
      -                    .callback(callback -> {
      -                        try {
      -                            String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:");
      -                            callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
      -                        } catch (Exception ignored) {
      -                        }
      -                    })
      -                    .register(registry);
      -        }
      +      GaugeWithCallback.builder(config)
      +          .name(PROCESS_RESIDENT_MEMORY_BYTES)
      +          .help("Resident memory size in bytes.")
      +          .unit(Unit.BYTES)
      +          .callback(
      +              callback -> {
      +                try {
      +                  String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:");
      +                  callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1])));
      +                } catch (Exception ignored) {
      +                }
      +              })
      +          .register(registry);
           }
      +  }
      +
      +  private Long callLongGetter(String getterName, Object obj)
      +      throws NoSuchMethodException, InvocationTargetException {
      +    return callLongGetter(obj.getClass().getMethod(getterName), obj);
      +  }
       
      -    private Long callLongGetter(String getterName, Object obj) throws NoSuchMethodException, InvocationTargetException {
      -        return callLongGetter(obj.getClass().getMethod(getterName), obj);
      +  /**
      +   * Attempts to call a method either directly or via one of the implemented interfaces.
      +   *
      +   * 

      A Method object refers to a specific method declared in a specific class. The first + * invocation might happen with method == SomeConcreteClass.publicLongGetter() and will fail if + * SomeConcreteClass is not public. We then recurse over all interfaces implemented by + * SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke + * callMethod() with method == SomePublicInterface.publicLongGetter(), which will then succeed. + * + *

      There is a built-in assumption that the method will never return null (or, equivalently, + * that it returns the primitive data type, i.e. {@code long} rather than {@code Long}). If this + * assumption doesn't hold, the method might be called repeatedly and the returned value will be + * the one produced by the last call. + */ + private Long callLongGetter(Method method, Object obj) throws InvocationTargetException { + try { + return (Long) method.invoke(obj); + } catch (IllegalAccessException e) { + // Expected, the declaring class or interface might not be public. } - /** - * Attempts to call a method either directly or via one of the implemented interfaces. - *

      - * A Method object refers to a specific method declared in a specific class. The first invocation - * might happen with method == SomeConcreteClass.publicLongGetter() and will fail if - * SomeConcreteClass is not public. We then recurse over all interfaces implemented by - * SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke - * callMethod() with method == SomePublicInterface.publicLongGetter(), which will then succeed. - *

      - * There is a built-in assumption that the method will never return null (or, equivalently, that - * it returns the primitive data type, i.e. {@code long} rather than {@code Long}). If this - * assumption doesn't hold, the method might be called repeatedly and the returned value will be - * the one produced by the last call. - */ - private Long callLongGetter(Method method, Object obj) throws InvocationTargetException { - try { - return (Long) method.invoke(obj); - } catch (IllegalAccessException e) { - // Expected, the declaring class or interface might not be public. + // Iterate over all implemented/extended interfaces and attempt invoking the method with the + // same name and parameters on each. + for (Class clazz : method.getDeclaringClass().getInterfaces()) { + try { + Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); + Long result = callLongGetter(interfaceMethod, obj); + if (result != null) { + return result; } - - // Iterate over all implemented/extended interfaces and attempt invoking the method with the - // same name and parameters on each. - for (Class clazz : method.getDeclaringClass().getInterfaces()) { - try { - Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes()); - Long result = callLongGetter(interfaceMethod, obj); - if (result != null) { - return result; - } - } catch (NoSuchMethodException e) { - // Expected, class might implement multiple, unrelated interfaces. - } - } - return null; + } catch (NoSuchMethodException e) { + // Expected, class might implement multiple, unrelated interfaces. + } } + return null; + } - interface Grepper { - String lineStartingWith(File file, String prefix) throws IOException; - } + interface Grepper { + String lineStartingWith(File file, String prefix) throws IOException; + } - private static class FileGrepper implements Grepper { + private static class FileGrepper implements Grepper { - @Override - public String lineStartingWith(File file, String prefix) throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line = reader.readLine(); - while (line != null) { - if (line.startsWith(prefix)) { - return line; - } - line = reader.readLine(); - } - } - return null; + @Override + public String lineStartingWith(File file, String prefix) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line = reader.readLine(); + while (line != null) { + if (line.startsWith(prefix)) { + return line; + } + line = reader.readLine(); } + } + return null; } + } - public static Builder builder() { - return new Builder(PrometheusProperties.get()); - } + public static Builder builder() { + return new Builder(PrometheusProperties.get()); + } - public static Builder builder(PrometheusProperties config) { - return new Builder(config); - } + public static Builder builder(PrometheusProperties config) { + return new Builder(config); + } - public static class Builder { + public static class Builder { - private final PrometheusProperties config; - private OperatingSystemMXBean osBean; - private RuntimeMXBean runtimeBean; - private Grepper grepper; + private final PrometheusProperties config; + private OperatingSystemMXBean osBean; + private RuntimeMXBean runtimeBean; + private Grepper grepper; - private Builder(PrometheusProperties config) { - this.config = config; - } + private Builder(PrometheusProperties config) { + this.config = config; + } - /** - * Package private. For testing only. - */ - Builder osBean(OperatingSystemMXBean osBean) { - this.osBean = osBean; - return this; - } + /** Package private. For testing only. */ + Builder osBean(OperatingSystemMXBean osBean) { + this.osBean = osBean; + return this; + } - /** - * Package private. For testing only. - */ - Builder runtimeBean(RuntimeMXBean runtimeBean) { - this.runtimeBean = runtimeBean; - return this; - } + /** Package private. For testing only. */ + Builder runtimeBean(RuntimeMXBean runtimeBean) { + this.runtimeBean = runtimeBean; + return this; + } - /** - * Package private. For testing only. - */ - Builder grepper(Grepper grepper) { - this.grepper = grepper; - return this; - } + /** Package private. For testing only. */ + Builder grepper(Grepper grepper) { + this.grepper = grepper; + return this; + } - public void register() { - register(PrometheusRegistry.defaultRegistry); - } + public void register() { + register(PrometheusRegistry.defaultRegistry); + } - public void register(PrometheusRegistry registry) { - OperatingSystemMXBean osBean = this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); - RuntimeMXBean runtimeMXBean = this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); - Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); - new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); - } + public void register(PrometheusRegistry registry) { + OperatingSystemMXBean osBean = + this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); + RuntimeMXBean runtimeMXBean = + this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); + Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); + new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java index 16b59b85a..b3d1c8169 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java @@ -1,25 +1,22 @@ package io.prometheus.metrics.instrumentation.jvm; import io.prometheus.metrics.exporter.httpserver.HTTPServer; - import java.io.IOException; - public class ExampleExporterForManualTesting { - public static void main(String[] args) throws IOException, InterruptedException { + public static void main(String[] args) throws IOException, InterruptedException { - JvmMetrics.builder().register(); + JvmMetrics.builder().register(); - HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + HTTPServer server = HTTPServer.builder().port(9400).buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println( + "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); - while (true) { - Thread.sleep(100); - Runtime.getRuntime().gc(); // Memory allocation metrics only start after GC run. - } + while (true) { + Thread.sleep(100); + Runtime.getRuntime().gc(); // Memory allocation metrics only start after GC run. } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java index b8aafa0ea..df6dddf99 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java @@ -1,82 +1,81 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.BufferPoolMXBean; +import java.util.Arrays; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.BufferPoolMXBean; -import java.util.Arrays; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class JvmBufferPoolMetricsTest { - private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); - private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); + private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); + private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); - @Before - public void setUp() { - when(directBuffer.getName()).thenReturn("direct"); - when(directBuffer.getCount()).thenReturn(2L); - when(directBuffer.getMemoryUsed()).thenReturn(1234L); - when(directBuffer.getTotalCapacity()).thenReturn(3456L); - when(mappedBuffer.getName()).thenReturn("mapped"); - when(mappedBuffer.getCount()).thenReturn(3L); - when(mappedBuffer.getMemoryUsed()).thenReturn(2345L); - when(mappedBuffer.getTotalCapacity()).thenReturn(4567L); - } + @Before + public void setUp() { + when(directBuffer.getName()).thenReturn("direct"); + when(directBuffer.getCount()).thenReturn(2L); + when(directBuffer.getMemoryUsed()).thenReturn(1234L); + when(directBuffer.getTotalCapacity()).thenReturn(3456L); + when(mappedBuffer.getName()).thenReturn("mapped"); + when(mappedBuffer.getCount()).thenReturn(3L); + when(mappedBuffer.getMemoryUsed()).thenReturn(2345L); + when(mappedBuffer.getTotalCapacity()).thenReturn(4567L); + } - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmBufferPoolMetrics.builder() - .bufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.builder() + .bufferPoolBeans(Arrays.asList(mappedBuffer, directBuffer)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + - "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + - "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + - "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" + - "jvm_buffer_pool_capacity_bytes{pool=\"mapped\"} 4567.0\n" + - "# TYPE jvm_buffer_pool_used_buffers gauge\n" + - "# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.\n" + - "jvm_buffer_pool_used_buffers{pool=\"direct\"} 2.0\n" + - "jvm_buffer_pool_used_buffers{pool=\"mapped\"} 3.0\n" + - "# TYPE jvm_buffer_pool_used_bytes gauge\n" + - "# UNIT jvm_buffer_pool_used_bytes bytes\n" + - "# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.\n" + - "jvm_buffer_pool_used_bytes{pool=\"direct\"} 1234.0\n" + - "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + + "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + + "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" + + "jvm_buffer_pool_capacity_bytes{pool=\"mapped\"} 4567.0\n" + + "# TYPE jvm_buffer_pool_used_buffers gauge\n" + + "# HELP jvm_buffer_pool_used_buffers Used buffers of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_buffers{pool=\"direct\"} 2.0\n" + + "jvm_buffer_pool_used_buffers{pool=\"mapped\"} 3.0\n" + + "# TYPE jvm_buffer_pool_used_bytes gauge\n" + + "# UNIT jvm_buffer_pool_used_bytes bytes\n" + + "# HELP jvm_buffer_pool_used_bytes Used bytes of a given JVM buffer pool.\n" + + "jvm_buffer_pool_used_bytes{pool=\"direct\"} 1234.0\n" + + "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes") - .build(); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_buffer_pool_used_bytes").build(); - PrometheusRegistry registry = new PrometheusRegistry(); - JvmBufferPoolMetrics.builder() - .bufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer)) - .register(registry); - registry.scrape(filter); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmBufferPoolMetrics.builder() + .bufferPoolBeans(Arrays.asList(directBuffer, mappedBuffer)) + .register(registry); + registry.scrape(filter); - verify(directBuffer, times(0)).getMemoryUsed(); - verify(mappedBuffer, times(0)).getMemoryUsed(); - verify(directBuffer, times(1)).getTotalCapacity(); - verify(mappedBuffer, times(1)).getTotalCapacity(); - } + verify(directBuffer, times(0)).getMemoryUsed(); + verify(mappedBuffer, times(0)).getMemoryUsed(); + verify(directBuffer, times(1)).getTotalCapacity(); + verify(mappedBuffer, times(1)).getTotalCapacity(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java index 16413b839..4196031bf 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java @@ -1,68 +1,63 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.ClassLoadingMXBean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.ClassLoadingMXBean; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - public class JvmClassLoadingMetricsTest { - private ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); - - @Before - public void setUp() { - when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); - when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); - when(mockClassLoadingBean.getUnloadedClassCount()).thenReturn(500L); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmClassLoadingMetrics.builder() - .classLoadingBean(mockClassLoadingBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = "" + - "# TYPE jvm_classes_currently_loaded gauge\n" + - "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + - "jvm_classes_currently_loaded 1000.0\n" + - "# TYPE jvm_classes_loaded counter\n" + - "# HELP jvm_classes_loaded The total number of classes that have been loaded since the JVM has started execution\n" + - "jvm_classes_loaded_total 2000.0\n" + - "# TYPE jvm_classes_unloaded counter\n" + - "# HELP jvm_classes_unloaded The total number of classes that have been unloaded since the JVM has started execution\n" + - "jvm_classes_unloaded_total 500.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_classes_currently_loaded") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmClassLoadingMetrics.builder() - .classLoadingBean(mockClassLoadingBean) - .register(registry); - registry.scrape(filter); - - verify(mockClassLoadingBean, times(0)).getLoadedClassCount(); - verify(mockClassLoadingBean, times(1)).getTotalLoadedClassCount(); - } + private ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); + + @Before + public void setUp() { + when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); + when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); + when(mockClassLoadingBean.getUnloadedClassCount()).thenReturn(500L); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.builder().classLoadingBean(mockClassLoadingBean).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "" + + "# TYPE jvm_classes_currently_loaded gauge\n" + + "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + + "jvm_classes_currently_loaded 1000.0\n" + + "# TYPE jvm_classes_loaded counter\n" + + "# HELP jvm_classes_loaded The total number of classes that have been loaded since the JVM has started execution\n" + + "jvm_classes_loaded_total 2000.0\n" + + "# TYPE jvm_classes_unloaded counter\n" + + "# HELP jvm_classes_unloaded The total number of classes that have been unloaded since the JVM has started execution\n" + + "jvm_classes_unloaded_total 500.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_classes_currently_loaded").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmClassLoadingMetrics.builder().classLoadingBean(mockClassLoadingBean).register(registry); + registry.scrape(filter); + + verify(mockClassLoadingBean, times(0)).getLoadedClassCount(); + verify(mockClassLoadingBean, times(1)).getTotalLoadedClassCount(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java index 75ecc8370..780d6a949 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java @@ -1,62 +1,59 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.internal.verification.VerificationModeFactory.times; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.lang.management.CompilationMXBean; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; -import java.lang.management.CompilationMXBean; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.internal.verification.VerificationModeFactory.times; - public class JvmCompilationMetricsTest { - private CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); - - @Before - public void setUp() { - when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000l); - when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmCompilationMetrics.builder() - .compilationBean(mockCompilationBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = "" + - "# TYPE jvm_compilation_time_seconds counter\n" + - "# UNIT jvm_compilation_time_seconds seconds\n" + - "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + - "jvm_compilation_time_seconds_total 10.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmCompilationMetrics.builder() - .compilationBean(mockCompilationBean) - .register(registry); - MetricSnapshots snapshots = registry.scrape(filter); - - verify(mockCompilationBean, times(0)).getTotalCompilationTime(); - Assert.assertEquals(0, snapshots.size()); - } + private CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); + + @Before + public void setUp() { + when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000l); + when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.builder().compilationBean(mockCompilationBean).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "" + + "# TYPE jvm_compilation_time_seconds counter\n" + + "# UNIT jvm_compilation_time_seconds seconds\n" + + "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + + "jvm_compilation_time_seconds_total 10.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder() + .nameMustNotBeEqualTo("jvm_compilation_time_seconds_total") + .build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmCompilationMetrics.builder().compilationBean(mockCompilationBean).register(registry); + MetricSnapshots snapshots = registry.scrape(filter); + + verify(mockCompilationBean, times(0)).getTotalCompilationTime(); + Assert.assertEquals(0, snapshots.size()); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java index d7dad1787..67ba4f064 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java @@ -1,74 +1,72 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.GarbageCollectorMXBean; import java.util.Arrays; import java.util.concurrent.TimeUnit; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmGarbageCollectorMetricsTest { - private GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); - private GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); + private GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); + private GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); - @Before - public void setUp() { - when(mockGcBean1.getName()).thenReturn("MyGC1"); - when(mockGcBean1.getCollectionCount()).thenReturn(100L); - when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10)); - when(mockGcBean2.getName()).thenReturn("MyGC2"); - when(mockGcBean2.getCollectionCount()).thenReturn(200L); - when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20)); - } + @Before + public void setUp() { + when(mockGcBean1.getName()).thenReturn("MyGC1"); + when(mockGcBean1.getCollectionCount()).thenReturn(100L); + when(mockGcBean1.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(10)); + when(mockGcBean2.getName()).thenReturn("MyGC2"); + when(mockGcBean2.getCollectionCount()).thenReturn(200L); + when(mockGcBean2.getCollectionTime()).thenReturn(TimeUnit.SECONDS.toMillis(20)); + } - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmGarbageCollectorMetrics.builder() - .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.builder() + .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE jvm_gc_collection_seconds summary\n" + - "# UNIT jvm_gc_collection_seconds seconds\n" + - "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + - "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" + - "jvm_gc_collection_seconds_sum{gc=\"MyGC1\"} 10.0\n" + - "jvm_gc_collection_seconds_count{gc=\"MyGC2\"} 200\n" + - "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE jvm_gc_collection_seconds summary\n" + + "# UNIT jvm_gc_collection_seconds seconds\n" + + "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC1\"} 10.0\n" + + "jvm_gc_collection_seconds_count{gc=\"MyGC2\"} 200\n" + + "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_gc_collection_seconds") - .build(); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_gc_collection_seconds").build(); - PrometheusRegistry registry = new PrometheusRegistry(); - JvmGarbageCollectorMetrics.builder() - .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(filter); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmGarbageCollectorMetrics.builder() + .garbageCollectorBeans(Arrays.asList(mockGcBean1, mockGcBean2)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(filter); - verify(mockGcBean1, times(0)).getCollectionTime(); - verify(mockGcBean1, times(0)).getCollectionCount(); - Assert.assertEquals(0, snapshots.size()); - } + verify(mockGcBean1, times(0)).getCollectionTime(); + verify(mockGcBean1, times(0)).getCollectionCount(); + Assert.assertEquals(0, snapshots.size()); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java index b70bb0bba..167299291 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java @@ -1,177 +1,177 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryUsage; import java.util.Arrays; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmMemoryMetricsTest { - private MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); - private MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); - private MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class); - private MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class); - private MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class); - private MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class); - private MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class); - private MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); - private MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); - - @Before - public void setUp() { - when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); - when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); - - long val = 1L; - when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn((int) val++); - - when(memoryUsageHeap.getUsed()).thenReturn(val++); - when(memoryUsageHeap.getMax()).thenReturn(val++); - when(memoryUsageHeap.getCommitted()).thenReturn(val++); - when(memoryUsageHeap.getInit()).thenReturn(val++); - - when(memoryUsageNonHeap.getUsed()).thenReturn(val++); - when(memoryUsageNonHeap.getMax()).thenReturn(val++); - when(memoryUsageNonHeap.getCommitted()).thenReturn(val++); - when(memoryUsageNonHeap.getInit()).thenReturn(val++); - - when(memoryUsagePoolEdenSpace.getUsed()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getMax()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getCommitted()).thenReturn(val++); - when(memoryUsagePoolEdenSpace.getInit()).thenReturn(val++); - - when(memoryUsagePoolOldGen.getUsed()).thenReturn(val++); - when(memoryUsagePoolOldGen.getMax()).thenReturn(val++); - when(memoryUsagePoolOldGen.getCommitted()).thenReturn(val++); - when(memoryUsagePoolOldGen.getInit()).thenReturn(val++); - - when(memoryUsagePoolCollectionEdenSpace.getUsed()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getMax()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getCommitted()).thenReturn(val++); - when(memoryUsagePoolCollectionEdenSpace.getInit()).thenReturn(val++); - - when(memoryUsagePoolCollectionOldGen.getUsed()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getMax()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getCommitted()).thenReturn(val++); - when(memoryUsagePoolCollectionOldGen.getInit()).thenReturn(val++); - - when(mockPoolsBeanEdenSpace.getName()).thenReturn("PS Eden Space"); - when(mockPoolsBeanEdenSpace.getUsage()).thenReturn(memoryUsagePoolEdenSpace); - when(mockPoolsBeanEdenSpace.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionEdenSpace); - - when(mockPoolsBeanOldGen.getName()).thenReturn("PS Old Gen"); - when(mockPoolsBeanOldGen.getUsage()).thenReturn(memoryUsagePoolOldGen); - when(mockPoolsBeanOldGen.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionOldGen); - } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmMemoryMetrics.builder() - .withMemoryBean(mockMemoryBean) - .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = "" + - "# TYPE jvm_memory_committed_bytes gauge\n" + - "# UNIT jvm_memory_committed_bytes bytes\n" + - "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + - "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" + - "jvm_memory_committed_bytes{area=\"nonheap\"} 8.0\n" + - "# TYPE jvm_memory_init_bytes gauge\n" + - "# UNIT jvm_memory_init_bytes bytes\n" + - "# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.\n" + - "jvm_memory_init_bytes{area=\"heap\"} 5.0\n" + - "jvm_memory_init_bytes{area=\"nonheap\"} 9.0\n" + - "# TYPE jvm_memory_max_bytes gauge\n" + - "# UNIT jvm_memory_max_bytes bytes\n" + - "# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.\n" + - "jvm_memory_max_bytes{area=\"heap\"} 3.0\n" + - "jvm_memory_max_bytes{area=\"nonheap\"} 7.0\n" + - "# TYPE jvm_memory_objects_pending_finalization gauge\n" + - "# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.\n" + - "jvm_memory_objects_pending_finalization 1.0\n" + - "# TYPE jvm_memory_pool_collection_committed_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_committed_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_committed_bytes{pool=\"PS Eden Space\"} 20.0\n" + - "jvm_memory_pool_collection_committed_bytes{pool=\"PS Old Gen\"} 24.0\n" + - "# TYPE jvm_memory_pool_collection_init_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_init_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_init_bytes{pool=\"PS Eden Space\"} 21.0\n" + - "jvm_memory_pool_collection_init_bytes{pool=\"PS Old Gen\"} 25.0\n" + - "# TYPE jvm_memory_pool_collection_max_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_max_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_max_bytes{pool=\"PS Eden Space\"} 19.0\n" + - "jvm_memory_pool_collection_max_bytes{pool=\"PS Old Gen\"} 23.0\n" + - "# TYPE jvm_memory_pool_collection_used_bytes gauge\n" + - "# UNIT jvm_memory_pool_collection_used_bytes bytes\n" + - "# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.\n" + - "jvm_memory_pool_collection_used_bytes{pool=\"PS Eden Space\"} 18.0\n" + - "jvm_memory_pool_collection_used_bytes{pool=\"PS Old Gen\"} 22.0\n" + - "# TYPE jvm_memory_pool_committed_bytes gauge\n" + - "# UNIT jvm_memory_pool_committed_bytes bytes\n" + - "# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_committed_bytes{pool=\"PS Eden Space\"} 12.0\n" + - "jvm_memory_pool_committed_bytes{pool=\"PS Old Gen\"} 16.0\n" + - "# TYPE jvm_memory_pool_init_bytes gauge\n" + - "# UNIT jvm_memory_pool_init_bytes bytes\n" + - "# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_init_bytes{pool=\"PS Eden Space\"} 13.0\n" + - "jvm_memory_pool_init_bytes{pool=\"PS Old Gen\"} 17.0\n" + - "# TYPE jvm_memory_pool_max_bytes gauge\n" + - "# UNIT jvm_memory_pool_max_bytes bytes\n" + - "# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_max_bytes{pool=\"PS Eden Space\"} 11.0\n" + - "jvm_memory_pool_max_bytes{pool=\"PS Old Gen\"} 15.0\n" + - "# TYPE jvm_memory_pool_used_bytes gauge\n" + - "# UNIT jvm_memory_pool_used_bytes bytes\n" + - "# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.\n" + - "jvm_memory_pool_used_bytes{pool=\"PS Eden Space\"} 10.0\n" + - "jvm_memory_pool_used_bytes{pool=\"PS Old Gen\"} 14.0\n" + - "# TYPE jvm_memory_used_bytes gauge\n" + - "# UNIT jvm_memory_used_bytes bytes\n" + - "# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.\n" + - "jvm_memory_used_bytes{area=\"heap\"} 2.0\n" + - "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_memory_pool_used_bytes") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmMemoryMetrics.builder() - .withMemoryBean(mockMemoryBean) - .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) - .register(registry); - registry.scrape(filter); - - verify(memoryUsagePoolEdenSpace, times(0)).getUsed(); - verify(memoryUsagePoolOldGen, times(0)).getUsed(); - verify(memoryUsagePoolEdenSpace, times(1)).getMax(); - verify(memoryUsagePoolOldGen, times(1)).getMax(); - } + private MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); + private MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); + private MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class); + private MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); + private MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); + + @Before + public void setUp() { + when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); + when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); + + long val = 1L; + when(mockMemoryBean.getObjectPendingFinalizationCount()).thenReturn((int) val++); + + when(memoryUsageHeap.getUsed()).thenReturn(val++); + when(memoryUsageHeap.getMax()).thenReturn(val++); + when(memoryUsageHeap.getCommitted()).thenReturn(val++); + when(memoryUsageHeap.getInit()).thenReturn(val++); + + when(memoryUsageNonHeap.getUsed()).thenReturn(val++); + when(memoryUsageNonHeap.getMax()).thenReturn(val++); + when(memoryUsageNonHeap.getCommitted()).thenReturn(val++); + when(memoryUsageNonHeap.getInit()).thenReturn(val++); + + when(memoryUsagePoolEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolOldGen.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionEdenSpace.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionEdenSpace.getInit()).thenReturn(val++); + + when(memoryUsagePoolCollectionOldGen.getUsed()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getMax()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getCommitted()).thenReturn(val++); + when(memoryUsagePoolCollectionOldGen.getInit()).thenReturn(val++); + + when(mockPoolsBeanEdenSpace.getName()).thenReturn("PS Eden Space"); + when(mockPoolsBeanEdenSpace.getUsage()).thenReturn(memoryUsagePoolEdenSpace); + when(mockPoolsBeanEdenSpace.getCollectionUsage()) + .thenReturn(memoryUsagePoolCollectionEdenSpace); + + when(mockPoolsBeanOldGen.getName()).thenReturn("PS Old Gen"); + when(mockPoolsBeanOldGen.getUsage()).thenReturn(memoryUsagePoolOldGen); + when(mockPoolsBeanOldGen.getCollectionUsage()).thenReturn(memoryUsagePoolCollectionOldGen); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.builder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "" + + "# TYPE jvm_memory_committed_bytes gauge\n" + + "# UNIT jvm_memory_committed_bytes bytes\n" + + "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + + "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" + + "jvm_memory_committed_bytes{area=\"nonheap\"} 8.0\n" + + "# TYPE jvm_memory_init_bytes gauge\n" + + "# UNIT jvm_memory_init_bytes bytes\n" + + "# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.\n" + + "jvm_memory_init_bytes{area=\"heap\"} 5.0\n" + + "jvm_memory_init_bytes{area=\"nonheap\"} 9.0\n" + + "# TYPE jvm_memory_max_bytes gauge\n" + + "# UNIT jvm_memory_max_bytes bytes\n" + + "# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.\n" + + "jvm_memory_max_bytes{area=\"heap\"} 3.0\n" + + "jvm_memory_max_bytes{area=\"nonheap\"} 7.0\n" + + "# TYPE jvm_memory_objects_pending_finalization gauge\n" + + "# HELP jvm_memory_objects_pending_finalization The number of objects waiting in the finalizer queue.\n" + + "jvm_memory_objects_pending_finalization 1.0\n" + + "# TYPE jvm_memory_pool_collection_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_committed_bytes Committed after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Eden Space\"} 20.0\n" + + "jvm_memory_pool_collection_committed_bytes{pool=\"PS Old Gen\"} 24.0\n" + + "# TYPE jvm_memory_pool_collection_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_init_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_init_bytes Initial after last collection bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Eden Space\"} 21.0\n" + + "jvm_memory_pool_collection_init_bytes{pool=\"PS Old Gen\"} 25.0\n" + + "# TYPE jvm_memory_pool_collection_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_max_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_max_bytes Max bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Eden Space\"} 19.0\n" + + "jvm_memory_pool_collection_max_bytes{pool=\"PS Old Gen\"} 23.0\n" + + "# TYPE jvm_memory_pool_collection_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_collection_used_bytes bytes\n" + + "# HELP jvm_memory_pool_collection_used_bytes Used bytes after last collection of a given JVM memory pool.\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Eden Space\"} 18.0\n" + + "jvm_memory_pool_collection_used_bytes{pool=\"PS Old Gen\"} 22.0\n" + + "# TYPE jvm_memory_pool_committed_bytes gauge\n" + + "# UNIT jvm_memory_pool_committed_bytes bytes\n" + + "# HELP jvm_memory_pool_committed_bytes Committed bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Eden Space\"} 12.0\n" + + "jvm_memory_pool_committed_bytes{pool=\"PS Old Gen\"} 16.0\n" + + "# TYPE jvm_memory_pool_init_bytes gauge\n" + + "# UNIT jvm_memory_pool_init_bytes bytes\n" + + "# HELP jvm_memory_pool_init_bytes Initial bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Eden Space\"} 13.0\n" + + "jvm_memory_pool_init_bytes{pool=\"PS Old Gen\"} 17.0\n" + + "# TYPE jvm_memory_pool_max_bytes gauge\n" + + "# UNIT jvm_memory_pool_max_bytes bytes\n" + + "# HELP jvm_memory_pool_max_bytes Max bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Eden Space\"} 11.0\n" + + "jvm_memory_pool_max_bytes{pool=\"PS Old Gen\"} 15.0\n" + + "# TYPE jvm_memory_pool_used_bytes gauge\n" + + "# UNIT jvm_memory_pool_used_bytes bytes\n" + + "# HELP jvm_memory_pool_used_bytes Used bytes of a given JVM memory pool.\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Eden Space\"} 10.0\n" + + "jvm_memory_pool_used_bytes{pool=\"PS Old Gen\"} 14.0\n" + + "# TYPE jvm_memory_used_bytes gauge\n" + + "# UNIT jvm_memory_used_bytes bytes\n" + + "# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.\n" + + "jvm_memory_used_bytes{area=\"heap\"} 2.0\n" + + "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_memory_pool_used_bytes").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmMemoryMetrics.builder() + .withMemoryBean(mockMemoryBean) + .withMemoryPoolBeans(Arrays.asList(mockPoolsBeanEdenSpace, mockPoolsBeanOldGen)) + .register(registry); + registry.scrape(filter); + + verify(memoryUsagePoolEdenSpace, times(0)).getUsed(); + verify(memoryUsagePoolOldGen, times(0)).getUsed(); + verify(memoryUsagePoolEdenSpace, times(1)).getMax(); + verify(memoryUsagePoolOldGen, times(1)).getMax(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java index 945ac5e27..8f90a9cb8 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; +import static org.junit.Assert.assertEquals; + import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.instrumentation.jvm.JvmMemoryPoolAllocationMetrics.AllocationCountingNotificationListener; import io.prometheus.metrics.model.registry.PrometheusRegistry; @@ -9,57 +11,56 @@ import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.assertEquals; - public class JvmMemoryPoolAllocationMetricsTest { - @Test - public void testListenerLogic() { - PrometheusRegistry registry = new PrometheusRegistry(); - Counter counter = Counter.builder().name("test").labelNames("pool").register(registry); - AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(counter); + @Test + public void testListenerLogic() { + PrometheusRegistry registry = new PrometheusRegistry(); + Counter counter = Counter.builder().name("test").labelNames("pool").register(registry); + AllocationCountingNotificationListener listener = + new AllocationCountingNotificationListener(counter); - // Increase by 123 - listener.handleMemoryPool("TestPool", 0, 123); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // Increase by 123 + listener.handleMemoryPool("TestPool", 0, 123); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // No increase - listener.handleMemoryPool("TestPool", 123, 123); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // No increase + listener.handleMemoryPool("TestPool", 123, 123); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // No increase, then decrease to 0 - listener.handleMemoryPool("TestPool", 123, 0); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // No increase, then decrease to 0 + listener.handleMemoryPool("TestPool", 123, 0); + assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // No increase, then increase by 7 - listener.handleMemoryPool("TestPool", 0, 7); - assertEquals(130, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // No increase, then increase by 7 + listener.handleMemoryPool("TestPool", 0, 7); + assertEquals(130, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // Increase by 10, then decrease to 10 - listener.handleMemoryPool("TestPool", 17, 10); - assertEquals(140, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // Increase by 10, then decrease to 10 + listener.handleMemoryPool("TestPool", 17, 10); + assertEquals(140, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // Increase by 7, then increase by 3 - listener.handleMemoryPool("TestPool", 17, 20); - assertEquals(150, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + // Increase by 7, then increase by 3 + listener.handleMemoryPool("TestPool", 17, 20); + assertEquals(150, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - // Decrease to 17, then increase by 3 - listener.handleMemoryPool("TestPool", 17, 20); - assertEquals(153, getCountByPool("test", "TestPool", registry.scrape()), 0.0); - } + // Decrease to 17, then increase by 3 + listener.handleMemoryPool("TestPool", 17, 20); + assertEquals(153, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + } - private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) { - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getPrometheusName().equals(metricName)) { - for (CounterSnapshot.CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { - if (data.getLabels().get("pool").equals(poolName)) { - return data.getValue(); - } - } - } + private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) { + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getPrometheusName().equals(metricName)) { + for (CounterSnapshot.CounterDataPointSnapshot data : + ((CounterSnapshot) snapshot).getDataPoints()) { + if (data.getLabels().get("pool").equals(poolName)) { + return data.getValue(); + } } - Assert.fail("pool " + poolName + " not found."); - return 0.0; + } } - + Assert.fail("pool " + poolName + " not found."); + return 0.0; + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java index d93b1682d..f0df40538 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java @@ -1,19 +1,19 @@ package io.prometheus.metrics.instrumentation.jvm; -import io.prometheus.metrics.model.registry.PrometheusRegistry; -import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.junit.Test; + public class JvmMetricsTest { - @Test - public void testRegisterIdempotent() { - PrometheusRegistry registry = new PrometheusRegistry(); - assertEquals(0, registry.scrape().size()); - JvmMetrics.builder().register(registry); - assertTrue(registry.scrape().size() > 0); - JvmMetrics.builder().register(registry); - } + @Test + public void testRegisterIdempotent() { + PrometheusRegistry registry = new PrometheusRegistry(); + assertEquals(0, registry.scrape().size()); + JvmMetrics.builder().register(registry); + assertTrue(registry.scrape().size() > 0); + JvmMetrics.builder().register(registry); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java index 4b9321660..13d1cc99f 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java @@ -1,25 +1,25 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; import junit.framework.TestCase; import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; -import java.io.IOException; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.when; - public class JvmNativeMemoryMetricsTest extends TestCase { @Test public void testNativeMemoryTrackingFail() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); when(adapter.vmNativeMemorySummaryInBytes()).thenThrow(new RuntimeException("mock")); PrometheusRegistry registry = new PrometheusRegistry(); @@ -35,7 +35,8 @@ public void testNativeMemoryTrackingFail() throws IOException { public void testNativeMemoryTrackingEmpty() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); when(adapter.vmNativeMemorySummaryInBytes()).thenReturn(""); PrometheusRegistry registry = new PrometheusRegistry(); @@ -51,8 +52,10 @@ public void testNativeMemoryTrackingEmpty() throws IOException { public void testNativeMemoryTrackingDisabled() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); - when(adapter.vmNativeMemorySummaryInBytes()).thenReturn("Native memory tracking is not enabled"); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()) + .thenReturn("Native memory tracking is not enabled"); PrometheusRegistry registry = new PrometheusRegistry(); new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); @@ -67,159 +70,161 @@ public void testNativeMemoryTrackingDisabled() throws IOException { public void testNativeMemoryTrackingEnabled() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); - JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); - when(adapter.vmNativeMemorySummaryInBytes()).thenReturn( - "Native Memory Tracking:\n" + - "\n" + - "Total: reserved=10341970661, committed=642716389\n" + - " malloc: 27513573 #22947\n" + - " mmap: reserved=10314457088, committed=615202816\n" + - "\n" + - "- Java Heap (reserved=8531214336, committed=536870912)\n" + - " (mmap: reserved=8531214336, committed=536870912) \n" + - " \n" + - "- Class (reserved=1073899939, committed=616867)\n" + - " (classes #1630)\n" + - " ( instance classes #1462, array classes #168)\n" + - " (malloc=158115 #2350) \n" + - " (mmap: reserved=1073741824, committed=458752) \n" + - " ( Metadata: )\n" + - " ( reserved=67108864, committed=2818048)\n" + - " ( used=2748008)\n" + - " ( waste=70040 =2.49%)\n" + - " ( Class space:)\n" + - " ( reserved=1073741824, committed=458752)\n" + - " ( used=343568)\n" + - " ( waste=115184 =25.11%)\n" + - " \n" + - "- Thread (reserved=21020080, committed=847280)\n" + - " (thread #20)\n" + - " (stack: reserved=20971520, committed=798720)\n" + - " (malloc=27512 #125) \n" + - " (arena=21048 #37)\n" + - " \n" + - "- Code (reserved=253796784, committed=7836080)\n" + - " (malloc=105944 #1403) \n" + - " (mmap: reserved=253689856, committed=7729152) \n" + - " (arena=984 #1)\n" + - " \n" + - "- GC (reserved=373343252, committed=76530708)\n" + - " (malloc=22463508 #720) \n" + - " (mmap: reserved=350879744, committed=54067200) \n" + - " \n" + - "- Compiler (reserved=1926356, committed=1926356)\n" + - " (malloc=20428 #73) \n" + - " (arena=1905928 #20)\n" + - " \n" + - "- Internal (reserved=242257, committed=242257)\n" + - " (malloc=176721 #1808) \n" + - " (mmap: reserved=65536, committed=65536) \n" + - " \n" + - "- Other (reserved=4096, committed=4096)\n" + - " (malloc=4096 #2) \n" + - " \n" + - "- Symbol (reserved=1505072, committed=1505072)\n" + - " (malloc=1136432 #14482) \n" + - " (arena=368640 #1)\n" + - " \n" + - "- Native Memory Tracking (reserved=373448, committed=373448)\n" + - " (malloc=6280 #91) \n" + - " (tracking overhead=367168)\n" + - " \n" + - "- Shared class space (reserved=16777216, committed=12386304)\n" + - " (mmap: reserved=16777216, committed=12386304) \n" + - " \n" + - "- Arena Chunk (reserved=503216, committed=503216)\n" + - " (malloc=503216) \n" + - " \n" + - "- Tracing (reserved=33097, committed=33097)\n" + - " (malloc=369 #10) \n" + - " (arena=32728 #1)\n" + - " \n" + - "- Arguments (reserved=160, committed=160)\n" + - " (malloc=160 #5) \n" + - " \n" + - "- Module (reserved=169168, committed=169168)\n" + - " (malloc=169168 #1266) \n" + - " \n" + - "- Safepoint (reserved=8192, committed=8192)\n" + - " (mmap: reserved=8192, committed=8192) \n" + - " \n" + - "- Synchronization (reserved=31160, committed=31160)\n" + - " (malloc=31160 #452) \n" + - " \n" + - "- Serviceability (reserved=600, committed=600)\n" + - " (malloc=600 #6) \n" + - " \n" + - "- Metaspace (reserved=67120768, committed=2829952)\n" + - " (malloc=11904 #12) \n" + - " (mmap: reserved=67108864, committed=2818048) \n" + - " \n" + - "- String Deduplication (reserved=632, committed=632)\n" + - " (malloc=632 #8) \n" + - " \n" + - "- Object Monitors (reserved=832, committed=832)\n" + - " (malloc=832 #4) \n" + - " \n" + - "\n" - ); + JvmNativeMemoryMetrics.PlatformMBeanServerAdapter adapter = + Mockito.mock(JvmNativeMemoryMetrics.PlatformMBeanServerAdapter.class); + when(adapter.vmNativeMemorySummaryInBytes()) + .thenReturn( + "Native Memory Tracking:\n" + + "\n" + + "Total: reserved=10341970661, committed=642716389\n" + + " malloc: 27513573 #22947\n" + + " mmap: reserved=10314457088, committed=615202816\n" + + "\n" + + "- Java Heap (reserved=8531214336, committed=536870912)\n" + + " (mmap: reserved=8531214336, committed=536870912) \n" + + " \n" + + "- Class (reserved=1073899939, committed=616867)\n" + + " (classes #1630)\n" + + " ( instance classes #1462, array classes #168)\n" + + " (malloc=158115 #2350) \n" + + " (mmap: reserved=1073741824, committed=458752) \n" + + " ( Metadata: )\n" + + " ( reserved=67108864, committed=2818048)\n" + + " ( used=2748008)\n" + + " ( waste=70040 =2.49%)\n" + + " ( Class space:)\n" + + " ( reserved=1073741824, committed=458752)\n" + + " ( used=343568)\n" + + " ( waste=115184 =25.11%)\n" + + " \n" + + "- Thread (reserved=21020080, committed=847280)\n" + + " (thread #20)\n" + + " (stack: reserved=20971520, committed=798720)\n" + + " (malloc=27512 #125) \n" + + " (arena=21048 #37)\n" + + " \n" + + "- Code (reserved=253796784, committed=7836080)\n" + + " (malloc=105944 #1403) \n" + + " (mmap: reserved=253689856, committed=7729152) \n" + + " (arena=984 #1)\n" + + " \n" + + "- GC (reserved=373343252, committed=76530708)\n" + + " (malloc=22463508 #720) \n" + + " (mmap: reserved=350879744, committed=54067200) \n" + + " \n" + + "- Compiler (reserved=1926356, committed=1926356)\n" + + " (malloc=20428 #73) \n" + + " (arena=1905928 #20)\n" + + " \n" + + "- Internal (reserved=242257, committed=242257)\n" + + " (malloc=176721 #1808) \n" + + " (mmap: reserved=65536, committed=65536) \n" + + " \n" + + "- Other (reserved=4096, committed=4096)\n" + + " (malloc=4096 #2) \n" + + " \n" + + "- Symbol (reserved=1505072, committed=1505072)\n" + + " (malloc=1136432 #14482) \n" + + " (arena=368640 #1)\n" + + " \n" + + "- Native Memory Tracking (reserved=373448, committed=373448)\n" + + " (malloc=6280 #91) \n" + + " (tracking overhead=367168)\n" + + " \n" + + "- Shared class space (reserved=16777216, committed=12386304)\n" + + " (mmap: reserved=16777216, committed=12386304) \n" + + " \n" + + "- Arena Chunk (reserved=503216, committed=503216)\n" + + " (malloc=503216) \n" + + " \n" + + "- Tracing (reserved=33097, committed=33097)\n" + + " (malloc=369 #10) \n" + + " (arena=32728 #1)\n" + + " \n" + + "- Arguments (reserved=160, committed=160)\n" + + " (malloc=160 #5) \n" + + " \n" + + "- Module (reserved=169168, committed=169168)\n" + + " (malloc=169168 #1266) \n" + + " \n" + + "- Safepoint (reserved=8192, committed=8192)\n" + + " (mmap: reserved=8192, committed=8192) \n" + + " \n" + + "- Synchronization (reserved=31160, committed=31160)\n" + + " (malloc=31160 #452) \n" + + " \n" + + "- Serviceability (reserved=600, committed=600)\n" + + " (malloc=600 #6) \n" + + " \n" + + "- Metaspace (reserved=67120768, committed=2829952)\n" + + " (malloc=11904 #12) \n" + + " (mmap: reserved=67108864, committed=2818048) \n" + + " \n" + + "- String Deduplication (reserved=632, committed=632)\n" + + " (malloc=632 #8) \n" + + " \n" + + "- Object Monitors (reserved=832, committed=832)\n" + + " (malloc=832 #4) \n" + + " \n" + + "\n"); PrometheusRegistry registry = new PrometheusRegistry(); new JvmNativeMemoryMetrics.Builder(PrometheusProperties.get(), adapter).register(registry); MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE jvm_native_memory_committed_bytes gauge\n" + - "# UNIT jvm_native_memory_committed_bytes bytes\n" + - "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + - "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Arguments\"} 160.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Class\"} 616867.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Code\"} 7836080.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Compiler\"} 1926356.0\n" + - "jvm_native_memory_committed_bytes{pool=\"GC\"} 7.6530708E7\n" + - "jvm_native_memory_committed_bytes{pool=\"Internal\"} 242257.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Java Heap\"} 5.36870912E8\n" + - "jvm_native_memory_committed_bytes{pool=\"Metaspace\"} 2829952.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Module\"} 169168.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Object Monitors\"} 832.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Other\"} 4096.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Safepoint\"} 8192.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Serviceability\"} 600.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Shared class space\"} 1.2386304E7\n" + - "jvm_native_memory_committed_bytes{pool=\"String Deduplication\"} 632.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Symbol\"} 1505072.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Synchronization\"} 31160.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Thread\"} 847280.0\n" + - "jvm_native_memory_committed_bytes{pool=\"Total\"} 6.42716389E8\n" + - "jvm_native_memory_committed_bytes{pool=\"Tracing\"} 33097.0\n" + - "# TYPE jvm_native_memory_reserved_bytes gauge\n" + - "# UNIT jvm_native_memory_reserved_bytes bytes\n" + - "# HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.\n" + - "jvm_native_memory_reserved_bytes{pool=\"Arena Chunk\"} 503216.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Arguments\"} 160.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Class\"} 1.073899939E9\n" + - "jvm_native_memory_reserved_bytes{pool=\"Code\"} 2.53796784E8\n" + - "jvm_native_memory_reserved_bytes{pool=\"Compiler\"} 1926356.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"GC\"} 3.73343252E8\n" + - "jvm_native_memory_reserved_bytes{pool=\"Internal\"} 242257.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Java Heap\"} 8.531214336E9\n" + - "jvm_native_memory_reserved_bytes{pool=\"Metaspace\"} 6.7120768E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"Module\"} 169168.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Object Monitors\"} 832.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Other\"} 4096.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Safepoint\"} 8192.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Serviceability\"} 600.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Shared class space\"} 1.6777216E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"String Deduplication\"} 632.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Symbol\"} 1505072.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Synchronization\"} 31160.0\n" + - "jvm_native_memory_reserved_bytes{pool=\"Thread\"} 2.102008E7\n" + - "jvm_native_memory_reserved_bytes{pool=\"Total\"} 1.0341970661E10\n" + - "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE jvm_native_memory_committed_bytes gauge\n" + + "# UNIT jvm_native_memory_committed_bytes bytes\n" + + "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + + "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Class\"} 616867.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Code\"} 7836080.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_committed_bytes{pool=\"GC\"} 7.6530708E7\n" + + "jvm_native_memory_committed_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Java Heap\"} 5.36870912E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Metaspace\"} 2829952.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Shared class space\"} 1.2386304E7\n" + + "jvm_native_memory_committed_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Thread\"} 847280.0\n" + + "jvm_native_memory_committed_bytes{pool=\"Total\"} 6.42716389E8\n" + + "jvm_native_memory_committed_bytes{pool=\"Tracing\"} 33097.0\n" + + "# TYPE jvm_native_memory_reserved_bytes gauge\n" + + "# UNIT jvm_native_memory_reserved_bytes bytes\n" + + "# HELP jvm_native_memory_reserved_bytes Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arena Chunk\"} 503216.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Arguments\"} 160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Class\"} 1.073899939E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Code\"} 2.53796784E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Compiler\"} 1926356.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"GC\"} 3.73343252E8\n" + + "jvm_native_memory_reserved_bytes{pool=\"Internal\"} 242257.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Java Heap\"} 8.531214336E9\n" + + "jvm_native_memory_reserved_bytes{pool=\"Metaspace\"} 6.7120768E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Module\"} 169168.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Native Memory Tracking\"} 373448.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Object Monitors\"} 832.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Other\"} 4096.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Safepoint\"} 8192.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Serviceability\"} 600.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Shared class space\"} 1.6777216E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"String Deduplication\"} 632.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Symbol\"} 1505072.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Synchronization\"} 31160.0\n" + + "jvm_native_memory_reserved_bytes{pool=\"Thread\"} 2.102008E7\n" + + "jvm_native_memory_reserved_bytes{pool=\"Total\"} 1.0341970661E10\n" + + "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + + "# EOF\n"; Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java index 0c4dd786a..a99178234 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java @@ -1,32 +1,32 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; + import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; import org.junit.Assert; import org.junit.Test; -import java.io.IOException; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; - public class JvmRuntimeInfoMetricTest { - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmRuntimeInfoMetric.builder() - .version("1.8.0_382-b05") - .vendor("Oracle Corporation") - .runtime("OpenJDK Runtime Environment") - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmRuntimeInfoMetric.builder() + .version("1.8.0_382-b05") + .vendor("Oracle Corporation") + .runtime("OpenJDK Runtime Environment") + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE jvm_runtime info\n" + - "# HELP jvm_runtime JVM runtime info\n" + - "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE jvm_runtime info\n" + + "# HELP jvm_runtime JVM runtime info\n" + + "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index 94cadc268..e454082b2 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -1,200 +1,199 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.IOException; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class JvmThreadsMetricsTest { - private ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); - private ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); - private ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); - private ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); - - @Before - public void setUp() { - when(mockThreadsBean.getThreadCount()).thenReturn(300); - when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); - when(mockThreadsBean.getPeakThreadCount()).thenReturn(301); - when(mockThreadsBean.getTotalStartedThreadCount()).thenReturn(503L); - when(mockThreadsBean.findDeadlockedThreads()).thenReturn(new long[]{1L, 2L, 3L}); - when(mockThreadsBean.findMonitorDeadlockedThreads()).thenReturn(new long[]{2L, 3L, 4L}); - when(mockThreadsBean.getAllThreadIds()).thenReturn(new long[]{3L, 4L, 5L}); - when(mockThreadInfoBlocked.getThreadState()).thenReturn(Thread.State.BLOCKED); - when(mockThreadInfoRunnable1.getThreadState()).thenReturn(Thread.State.RUNNABLE); - when(mockThreadInfoRunnable2.getThreadState()).thenReturn(Thread.State.RUNNABLE); - when(mockThreadsBean.getThreadInfo(new long[]{3L, 4L, 5L}, 0)).thenReturn(new ThreadInfo[]{ - mockThreadInfoBlocked, mockThreadInfoRunnable1, mockThreadInfoRunnable2 - }); + private ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); + private ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); + private ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); + private ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); + + @Before + public void setUp() { + when(mockThreadsBean.getThreadCount()).thenReturn(300); + when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); + when(mockThreadsBean.getPeakThreadCount()).thenReturn(301); + when(mockThreadsBean.getTotalStartedThreadCount()).thenReturn(503L); + when(mockThreadsBean.findDeadlockedThreads()).thenReturn(new long[] {1L, 2L, 3L}); + when(mockThreadsBean.findMonitorDeadlockedThreads()).thenReturn(new long[] {2L, 3L, 4L}); + when(mockThreadsBean.getAllThreadIds()).thenReturn(new long[] {3L, 4L, 5L}); + when(mockThreadInfoBlocked.getThreadState()).thenReturn(Thread.State.BLOCKED); + when(mockThreadInfoRunnable1.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadInfoRunnable2.getThreadState()).thenReturn(Thread.State.RUNNABLE); + when(mockThreadsBean.getThreadInfo(new long[] {3L, 4L, 5L}, 0)) + .thenReturn( + new ThreadInfo[] { + mockThreadInfoBlocked, mockThreadInfoRunnable1, mockThreadInfoRunnable2 + }); + } + + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().threadBean(mockThreadsBean).isNativeImage(false).register(registry); + MetricSnapshots snapshots = registry.scrape(); + + String expected = + "" + + "# TYPE jvm_threads_current gauge\n" + + "# HELP jvm_threads_current Current thread count of a JVM\n" + + "jvm_threads_current 300.0\n" + + "# TYPE jvm_threads_daemon gauge\n" + + "# HELP jvm_threads_daemon Daemon thread count of a JVM\n" + + "jvm_threads_daemon 200.0\n" + + "# TYPE jvm_threads_deadlocked gauge\n" + + "# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers\n" + + "jvm_threads_deadlocked 3.0\n" + + "# TYPE jvm_threads_deadlocked_monitor gauge\n" + + "# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors\n" + + "jvm_threads_deadlocked_monitor 3.0\n" + + "# TYPE jvm_threads_peak gauge\n" + + "# HELP jvm_threads_peak Peak thread count of a JVM\n" + + "jvm_threads_peak 301.0\n" + + "# TYPE jvm_threads_started counter\n" + + "# HELP jvm_threads_started Started thread count of a JVM\n" + + "jvm_threads_started_total 503.0\n" + + "# TYPE jvm_threads_state gauge\n" + + "# HELP jvm_threads_state Current count of threads by state\n" + + "jvm_threads_state{state=\"BLOCKED\"} 1.0\n" + + "jvm_threads_state{state=\"NEW\"} 0.0\n" + + "jvm_threads_state{state=\"RUNNABLE\"} 2.0\n" + + "jvm_threads_state{state=\"TERMINATED\"} 0.0\n" + + "jvm_threads_state{state=\"TIMED_WAITING\"} 0.0\n" + + "jvm_threads_state{state=\"UNKNOWN\"} 0.0\n" + + "jvm_threads_state{state=\"WAITING\"} 0.0\n" + + "# EOF\n"; + + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } + + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("jvm_threads_deadlocked").build(); + + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().threadBean(mockThreadsBean).isNativeImage(false).register(registry); + registry.scrape(filter); + + verify(mockThreadsBean, times(0)).findDeadlockedThreads(); + verify(mockThreadsBean, times(1)).getThreadCount(); + } + + @Test + public void testInvalidThreadIds() { + try { + String javaVersion = System.getProperty("java.version"); // Example: "21.0.2" + String majorJavaVersion = javaVersion.replaceAll("\\..*", ""); // Example: "21" + if (Integer.parseInt(majorJavaVersion) >= 21) { + // With Java 21 and newer you can no longer have invalid thread ids. + return; + } + } catch (NumberFormatException ignored) { } - - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder() - .threadBean(mockThreadsBean) - .isNativeImage(false) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); - - String expected = "" + - "# TYPE jvm_threads_current gauge\n" + - "# HELP jvm_threads_current Current thread count of a JVM\n" + - "jvm_threads_current 300.0\n" + - "# TYPE jvm_threads_daemon gauge\n" + - "# HELP jvm_threads_daemon Daemon thread count of a JVM\n" + - "jvm_threads_daemon 200.0\n" + - "# TYPE jvm_threads_deadlocked gauge\n" + - "# HELP jvm_threads_deadlocked Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers\n" + - "jvm_threads_deadlocked 3.0\n" + - "# TYPE jvm_threads_deadlocked_monitor gauge\n" + - "# HELP jvm_threads_deadlocked_monitor Cycles of JVM-threads that are in deadlock waiting to acquire object monitors\n" + - "jvm_threads_deadlocked_monitor 3.0\n" + - "# TYPE jvm_threads_peak gauge\n" + - "# HELP jvm_threads_peak Peak thread count of a JVM\n" + - "jvm_threads_peak 301.0\n" + - "# TYPE jvm_threads_started counter\n" + - "# HELP jvm_threads_started Started thread count of a JVM\n" + - "jvm_threads_started_total 503.0\n" + - "# TYPE jvm_threads_state gauge\n" + - "# HELP jvm_threads_state Current count of threads by state\n" + - "jvm_threads_state{state=\"BLOCKED\"} 1.0\n" + - "jvm_threads_state{state=\"NEW\"} 0.0\n" + - "jvm_threads_state{state=\"RUNNABLE\"} 2.0\n" + - "jvm_threads_state{state=\"TERMINATED\"} 0.0\n" + - "jvm_threads_state{state=\"TIMED_WAITING\"} 0.0\n" + - "jvm_threads_state{state=\"UNKNOWN\"} 0.0\n" + - "jvm_threads_state{state=\"WAITING\"} 0.0\n" + - "# EOF\n"; - - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } - - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("jvm_threads_deadlocked") - .build(); - - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder() - .threadBean(mockThreadsBean) - .isNativeImage(false) - .register(registry); - registry.scrape(filter); - - verify(mockThreadsBean, times(0)).findDeadlockedThreads(); - verify(mockThreadsBean, times(1)).getThreadCount(); + PrometheusRegistry registry = new PrometheusRegistry(); + JvmThreadsMetrics.builder().register(registry); + + // Number of threads to create with invalid thread ids + int numberOfInvalidThreadIds = 2; + + Map expected = getCountByState(registry.scrape()); + expected.compute( + "UNKNOWN", + (key, oldValue) -> + oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); + + final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + + try { + // Create and start threads with invalid thread ids (id=0, id=-1, etc.) + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + new ThreadWithInvalidId(-i, new TestRunnable(countDownLatch)).start(); + } + + Map actual = getCountByState(registry.scrape()); + + Assert.assertEquals(expected.size(), actual.size()); + for (String threadState : expected.keySet()) { + Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0); + } + } finally { + for (int i = 0; i < numberOfInvalidThreadIds; i++) { + countDownLatch.countDown(); + } } - - @Test - public void testInvalidThreadIds() { - try { - String javaVersion = System.getProperty("java.version"); // Example: "21.0.2" - String majorJavaVersion = javaVersion.replaceAll("\\..*", ""); // Example: "21" - if (Integer.parseInt(majorJavaVersion) >= 21) { - // With Java 21 and newer you can no longer have invalid thread ids. - return; - } - } catch (NumberFormatException ignored) { + } + + private Map getCountByState(MetricSnapshots snapshots) { + Map result = new HashMap<>(); + for (MetricSnapshot snapshot : snapshots) { + if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { + for (GaugeSnapshot.GaugeDataPointSnapshot data : + ((GaugeSnapshot) snapshot).getDataPoints()) { + String state = data.getLabels().get("state"); + Assert.assertNotNull(state); + result.put(state, data.getValue()); } - PrometheusRegistry registry = new PrometheusRegistry(); - JvmThreadsMetrics.builder().register(registry); - - // Number of threads to create with invalid thread ids - int numberOfInvalidThreadIds = 2; - - Map expected = getCountByState(registry.scrape()); - expected.compute("UNKNOWN", (key, oldValue) -> oldValue == null ? numberOfInvalidThreadIds : oldValue + numberOfInvalidThreadIds); - - final CountDownLatch countDownLatch = new CountDownLatch(numberOfInvalidThreadIds); + } + } + return result; + } - try { - // Create and start threads with invalid thread ids (id=0, id=-1, etc.) - for (int i = 0; i < numberOfInvalidThreadIds; i++) { - new ThreadWithInvalidId(-i, new TestRunnable(countDownLatch)).start(); - } + private static class ThreadWithInvalidId extends Thread { - Map actual = getCountByState(registry.scrape()); + private final long id; - Assert.assertEquals(expected.size(), actual.size()); - for (String threadState : expected.keySet()) { - Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0); - } - } finally { - for (int i = 0; i < numberOfInvalidThreadIds; i++) { - countDownLatch.countDown(); - } - } + public ThreadWithInvalidId(long id, Runnable runnable) { + super(runnable); + setDaemon(true); + this.id = id; } - private Map getCountByState(MetricSnapshots snapshots) { - Map result = new HashMap<>(); - for (MetricSnapshot snapshot : snapshots) { - if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { - for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { - String state = data.getLabels().get("state"); - Assert.assertNotNull(state); - result.put(state, data.getValue()); - } - } - } - return result; + /** + * Note that only Java versions < 21 call this to get the thread id. With Java 21 and newer it's + * no longer possible to make an invalid thread id. + */ + @Override + public long getId() { + return this.id; } + } - private static class ThreadWithInvalidId extends Thread { - - private final long id; + private static class TestRunnable implements Runnable { - public ThreadWithInvalidId(long id, Runnable runnable) { - super(runnable); - setDaemon(true); - this.id = id; - } + private final CountDownLatch countDownLatch; - /** - * Note that only Java versions < 21 call this to get the thread id. - * With Java 21 and newer it's no longer possible to make an invalid thread id. - */ - @Override - public long getId() { - return this.id; - } + public TestRunnable(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; } - private static class TestRunnable implements Runnable { - - private final CountDownLatch countDownLatch; - - public TestRunnable(CountDownLatch countDownLatch) { - this.countDownLatch = countDownLatch; - } - - @Override - public void run() { - try { - countDownLatch.await(); - } catch (InterruptedException e) { - // DO NOTHING - } - } + @Override + public void run() { + try { + countDownLatch.await(); + } catch (InterruptedException e) { + // DO NOTHING + } } + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java index 92f286e01..41a5b514b 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java @@ -1,116 +1,120 @@ package io.prometheus.metrics.instrumentation.jvm; +import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import io.prometheus.metrics.model.registry.MetricNameFilter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; - import java.io.File; import java.io.IOException; import java.lang.management.RuntimeMXBean; import java.util.concurrent.TimeUnit; - -import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; public class ProcessMetricsTest { - private com.sun.management.UnixOperatingSystemMXBean sunOsBean = Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); - private java.lang.management.OperatingSystemMXBean javaOsBean = Mockito.mock(java.lang.management.OperatingSystemMXBean.class); - private ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class); - private ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); - private RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); + private com.sun.management.UnixOperatingSystemMXBean sunOsBean = + Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); + private java.lang.management.OperatingSystemMXBean javaOsBean = + Mockito.mock(java.lang.management.OperatingSystemMXBean.class); + private ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); + private RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); - @Before - public void setUp() throws IOException { - when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); - when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); - when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); - when(runtimeBean.getStartTime()).thenReturn(37100L); - when(linuxGrepper.lineStartingWith(any(File.class), eq("VmSize:"))).thenReturn("VmSize: 6036 kB"); - when(linuxGrepper.lineStartingWith(any(File.class), eq("VmRSS:"))).thenReturn("VmRSS: 1012 kB"); - } + @Before + public void setUp() throws IOException { + when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); + when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); + when(sunOsBean.getMaxFileDescriptorCount()).thenReturn(244L); + when(runtimeBean.getStartTime()).thenReturn(37100L); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmSize:"))) + .thenReturn("VmSize: 6036 kB"); + when(linuxGrepper.lineStartingWith(any(File.class), eq("VmRSS:"))) + .thenReturn("VmRSS: 1012 kB"); + } - @Test - public void testGoodCase() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(sunOsBean) - .runtimeBean(runtimeBean) - .grepper(linuxGrepper) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testGoodCase() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(sunOsBean) + .runtimeBean(runtimeBean) + .grepper(linuxGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE process_cpu_seconds counter\n" + - "# UNIT process_cpu_seconds seconds\n" + - "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + - "process_cpu_seconds_total 0.072\n" + - "# TYPE process_max_fds gauge\n" + - "# HELP process_max_fds Maximum number of open file descriptors.\n" + - "process_max_fds 244.0\n" + - "# TYPE process_open_fds gauge\n" + - "# HELP process_open_fds Number of open file descriptors.\n" + - "process_open_fds 127.0\n" + - "# TYPE process_resident_memory_bytes gauge\n" + - "# UNIT process_resident_memory_bytes bytes\n" + - "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + - "process_resident_memory_bytes 1036288.0\n" + - "# TYPE process_start_time_seconds gauge\n" + - "# UNIT process_start_time_seconds seconds\n" + - "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + - "process_start_time_seconds 37.1\n" + - "# TYPE process_virtual_memory_bytes gauge\n" + - "# UNIT process_virtual_memory_bytes bytes\n" + - "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + - "process_virtual_memory_bytes 6180864.0\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE process_cpu_seconds counter\n" + + "# UNIT process_cpu_seconds seconds\n" + + "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + + "process_cpu_seconds_total 0.072\n" + + "# TYPE process_max_fds gauge\n" + + "# HELP process_max_fds Maximum number of open file descriptors.\n" + + "process_max_fds 244.0\n" + + "# TYPE process_open_fds gauge\n" + + "# HELP process_open_fds Number of open file descriptors.\n" + + "process_open_fds 127.0\n" + + "# TYPE process_resident_memory_bytes gauge\n" + + "# UNIT process_resident_memory_bytes bytes\n" + + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + + "process_resident_memory_bytes 1036288.0\n" + + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n" + + "# TYPE process_virtual_memory_bytes gauge\n" + + "# UNIT process_virtual_memory_bytes bytes\n" + + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + + "process_virtual_memory_bytes 6180864.0\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testMinimal() throws IOException { - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(javaOsBean) - .runtimeBean(runtimeBean) - .grepper(windowsGrepper) - .register(registry); - MetricSnapshots snapshots = registry.scrape(); + @Test + public void testMinimal() throws IOException { + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(javaOsBean) + .runtimeBean(runtimeBean) + .grepper(windowsGrepper) + .register(registry); + MetricSnapshots snapshots = registry.scrape(); - String expected = "" + - "# TYPE process_start_time_seconds gauge\n" + - "# UNIT process_start_time_seconds seconds\n" + - "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + - "process_start_time_seconds 37.1\n" + - "# EOF\n"; + String expected = + "" + + "# TYPE process_start_time_seconds gauge\n" + + "# UNIT process_start_time_seconds seconds\n" + + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + + "process_start_time_seconds 37.1\n" + + "# EOF\n"; - Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); - } + Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + } - @Test - public void testIgnoredMetricNotScraped() { - MetricNameFilter filter = MetricNameFilter.builder() - .nameMustNotBeEqualTo("process_max_fds") - .build(); + @Test + public void testIgnoredMetricNotScraped() { + MetricNameFilter filter = + MetricNameFilter.builder().nameMustNotBeEqualTo("process_max_fds").build(); - PrometheusRegistry registry = new PrometheusRegistry(); - ProcessMetrics.builder() - .osBean(sunOsBean) - .runtimeBean(runtimeBean) - .grepper(linuxGrepper) - .register(registry); - registry.scrape(filter); + PrometheusRegistry registry = new PrometheusRegistry(); + ProcessMetrics.builder() + .osBean(sunOsBean) + .runtimeBean(runtimeBean) + .grepper(linuxGrepper) + .register(registry); + registry.scrape(filter); - verify(sunOsBean, times(0)).getMaxFileDescriptorCount(); - verify(sunOsBean, times(1)).getOpenFileDescriptorCount(); - } + verify(sunOsBean, times(0)).getMaxFileDescriptorCount(); + verify(sunOsBean, times(1)).getOpenFileDescriptorCount(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java index 2b0d7972c..a86517368 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java @@ -2,17 +2,16 @@ import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.model.snapshots.MetricSnapshots; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; public class TestUtil { - static String convertToOpenMetricsFormat(MetricSnapshots snapshots) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); - writer.write(out, snapshots); - return out.toString(StandardCharsets.UTF_8.name()); - } + static String convertToOpenMetricsFormat(MetricSnapshots snapshots) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + writer.write(out, snapshots); + return out.toString(StandardCharsets.UTF_8.name()); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java index c0c345a1b..59fbe6a13 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MetricNameFilter.java @@ -1,196 +1,197 @@ package io.prometheus.metrics.model.registry; +import static java.util.Collections.unmodifiableCollection; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.function.Predicate; -import static java.util.Collections.unmodifiableCollection; - -/** - * Filter samples (i.e. time series) by name. - */ +/** Filter samples (i.e. time series) by name. */ public class MetricNameFilter implements Predicate { + /** For convenience, a filter that allows all names. */ + public static final Predicate ALLOW_ALL = name -> true; + + private final Collection nameIsEqualTo; + private final Collection nameIsNotEqualTo; + private final Collection nameStartsWith; + private final Collection nameDoesNotStartWith; + + private MetricNameFilter( + Collection nameIsEqualTo, + Collection nameIsNotEqualTo, + Collection nameStartsWith, + Collection nameDoesNotStartWith) { + this.nameIsEqualTo = unmodifiableCollection(new ArrayList<>(nameIsEqualTo)); + this.nameIsNotEqualTo = unmodifiableCollection(new ArrayList<>(nameIsNotEqualTo)); + this.nameStartsWith = unmodifiableCollection(new ArrayList<>(nameStartsWith)); + this.nameDoesNotStartWith = unmodifiableCollection(new ArrayList<>(nameDoesNotStartWith)); + } + + @Override + public boolean test(String sampleName) { + return matchesNameEqualTo(sampleName) + && !matchesNameNotEqualTo(sampleName) + && matchesNameStartsWith(sampleName) + && !matchesNameDoesNotStartWith(sampleName); + } + + private boolean matchesNameEqualTo(String metricName) { + if (nameIsEqualTo.isEmpty()) { + return true; + } + for (String name : nameIsEqualTo) { + // The following ignores suffixes like _total. + // "request_count" and "request_count_total" both match a metric named "request_count". + if (name.startsWith(metricName)) { + return true; + } + } + return false; + } + + private boolean matchesNameNotEqualTo(String metricName) { + if (nameIsNotEqualTo.isEmpty()) { + return false; + } + for (String name : nameIsNotEqualTo) { + // The following ignores suffixes like _total. + // "request_count" and "request_count_total" both match a metric named "request_count". + if (name.startsWith(metricName)) { + return true; + } + } + return false; + } + + private boolean matchesNameStartsWith(String metricName) { + if (nameStartsWith.isEmpty()) { + return true; + } + for (String prefix : nameStartsWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + private boolean matchesNameDoesNotStartWith(String metricName) { + if (nameDoesNotStartWith.isEmpty()) { + return false; + } + for (String prefix : nameDoesNotStartWith) { + if (metricName.startsWith(prefix)) { + return true; + } + } + return false; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final Collection nameEqualTo = new ArrayList<>(); + private final Collection nameNotEqualTo = new ArrayList<>(); + private final Collection nameStartsWith = new ArrayList<>(); + private final Collection nameDoesNotStartWith = new ArrayList<>(); + + private Builder() {} + + /** + * @see #nameMustBeEqualTo(Collection) + */ + public Builder nameMustBeEqualTo(String... names) { + return nameMustBeEqualTo(Arrays.asList(names)); + } + + /** + * Only samples with one of the {@code names} will be included. + * + *

      Note that the provided {@code names} will be matched against the sample name (i.e. the + * time series name) and not the metric name. For instance, to retrieve all samples from a + * histogram, you must include the '_count', '_sum' and '_bucket' names. + * + *

      This method should be used by HTTP exporters to implement the {@code ?name[]=} URL + * parameters. + * + * @param names empty means no restriction. + */ + public Builder nameMustBeEqualTo(Collection names) { + if (names != null) { + nameEqualTo.addAll(names); + } + return this; + } + + /** + * @see #nameMustNotBeEqualTo(Collection) + */ + public Builder nameMustNotBeEqualTo(String... names) { + return nameMustNotBeEqualTo(Arrays.asList(names)); + } + /** - * For convenience, a filter that allows all names. + * All samples that are not in {@code names} will be excluded. + * + *

      Note that the provided {@code names} will be matched against the sample name (i.e. the + * time series name) and not the metric name. For instance, to exclude all samples from a + * histogram, you must exclude the '_count', '_sum' and '_bucket' names. + * + * @param names empty means no name will be excluded. */ - public static final Predicate ALLOW_ALL = name -> true; - - private final Collection nameIsEqualTo; - private final Collection nameIsNotEqualTo; - private final Collection nameStartsWith; - private final Collection nameDoesNotStartWith; - - private MetricNameFilter(Collection nameIsEqualTo, Collection nameIsNotEqualTo, Collection nameStartsWith, Collection nameDoesNotStartWith) { - this.nameIsEqualTo = unmodifiableCollection(new ArrayList<>(nameIsEqualTo)); - this.nameIsNotEqualTo = unmodifiableCollection(new ArrayList<>(nameIsNotEqualTo)); - this.nameStartsWith = unmodifiableCollection(new ArrayList<>(nameStartsWith)); - this.nameDoesNotStartWith = unmodifiableCollection(new ArrayList<>(nameDoesNotStartWith)); - } - - @Override - public boolean test(String sampleName) { - return matchesNameEqualTo(sampleName) - && !matchesNameNotEqualTo(sampleName) - && matchesNameStartsWith(sampleName) - && !matchesNameDoesNotStartWith(sampleName); - } - - private boolean matchesNameEqualTo(String metricName) { - if (nameIsEqualTo.isEmpty()) { - return true; - } - for (String name : nameIsEqualTo) { - // The following ignores suffixes like _total. - // "request_count" and "request_count_total" both match a metric named "request_count". - if (name.startsWith(metricName)) { - return true; - } - } - return false; - } - - private boolean matchesNameNotEqualTo(String metricName) { - if (nameIsNotEqualTo.isEmpty()) { - return false; - } - for (String name : nameIsNotEqualTo) { - // The following ignores suffixes like _total. - // "request_count" and "request_count_total" both match a metric named "request_count". - if (name.startsWith(metricName)) { - return true; - } - } - return false; - } - - private boolean matchesNameStartsWith(String metricName) { - if (nameStartsWith.isEmpty()) { - return true; - } - for (String prefix : nameStartsWith) { - if (metricName.startsWith(prefix)) { - return true; - } - } - return false; - } - - private boolean matchesNameDoesNotStartWith(String metricName) { - if (nameDoesNotStartWith.isEmpty()) { - return false; - } - for (String prefix : nameDoesNotStartWith) { - if (metricName.startsWith(prefix)) { - return true; - } - } - return false; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - - private final Collection nameEqualTo = new ArrayList<>(); - private final Collection nameNotEqualTo = new ArrayList<>(); - private final Collection nameStartsWith = new ArrayList<>(); - private final Collection nameDoesNotStartWith = new ArrayList<>(); - - private Builder() { - } - - /** - * @see #nameMustBeEqualTo(Collection) - */ - public Builder nameMustBeEqualTo(String... names) { - return nameMustBeEqualTo(Arrays.asList(names)); - } - - /** - * Only samples with one of the {@code names} will be included. - *

      - * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) - * and not the metric name. For instance, to retrieve all samples from a histogram, you must include the - * '_count', '_sum' and '_bucket' names. - *

      - * This method should be used by HTTP exporters to implement the {@code ?name[]=} URL parameters. - * - * @param names empty means no restriction. - */ - public Builder nameMustBeEqualTo(Collection names) { - if (names != null) { - nameEqualTo.addAll(names); - } - return this; - } - - /** - * @see #nameMustNotBeEqualTo(Collection) - */ - public Builder nameMustNotBeEqualTo(String... names) { - return nameMustNotBeEqualTo(Arrays.asList(names)); - } - - /** - * All samples that are not in {@code names} will be excluded. - *

      - * Note that the provided {@code names} will be matched against the sample name (i.e. the time series name) - * and not the metric name. For instance, to exclude all samples from a histogram, you must exclude the - * '_count', '_sum' and '_bucket' names. - * - * @param names empty means no name will be excluded. - */ - public Builder nameMustNotBeEqualTo(Collection names) { - if (names != null) { - nameNotEqualTo.addAll(names); - } - return this; - } - - /** - * @see #nameMustStartWith(Collection) - */ - public Builder nameMustStartWith(String... prefixes) { - return nameMustStartWith(Arrays.asList(prefixes)); - } - - /** - * Only samples whose name starts with one of the {@code prefixes} will be included. - * - * @param prefixes empty means no restriction. - */ - public Builder nameMustStartWith(Collection prefixes) { - if (prefixes != null) { - nameStartsWith.addAll(prefixes); - } - return this; - } - - /** - * @see #nameMustNotStartWith(Collection) - */ - public Builder nameMustNotStartWith(String... prefixes) { - return nameMustNotStartWith(Arrays.asList(prefixes)); - } - - /** - * Samples with names starting with one of the {@code prefixes} will be excluded. - * - * @param prefixes empty means no time series will be excluded. - */ - public Builder nameMustNotStartWith(Collection prefixes) { - if (prefixes != null) { - nameDoesNotStartWith.addAll(prefixes); - } - return this; - } - - public MetricNameFilter build() { - return new MetricNameFilter(nameEqualTo, nameNotEqualTo, nameStartsWith, nameDoesNotStartWith); - } + public Builder nameMustNotBeEqualTo(Collection names) { + if (names != null) { + nameNotEqualTo.addAll(names); + } + return this; + } + + /** + * @see #nameMustStartWith(Collection) + */ + public Builder nameMustStartWith(String... prefixes) { + return nameMustStartWith(Arrays.asList(prefixes)); + } + + /** + * Only samples whose name starts with one of the {@code prefixes} will be included. + * + * @param prefixes empty means no restriction. + */ + public Builder nameMustStartWith(Collection prefixes) { + if (prefixes != null) { + nameStartsWith.addAll(prefixes); + } + return this; + } + + /** + * @see #nameMustNotStartWith(Collection) + */ + public Builder nameMustNotStartWith(String... prefixes) { + return nameMustNotStartWith(Arrays.asList(prefixes)); + } + + /** + * Samples with names starting with one of the {@code prefixes} will be excluded. + * + * @param prefixes empty means no time series will be excluded. + */ + public Builder nameMustNotStartWith(Collection prefixes) { + if (prefixes != null) { + nameDoesNotStartWith.addAll(prefixes); + } + return this; + } + + public MetricNameFilter build() { + return new MetricNameFilter( + nameEqualTo, nameNotEqualTo, nameStartsWith, nameDoesNotStartWith); } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java index 5434c0ec0..a4f52746e 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -2,70 +2,71 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; - import java.util.Collections; import java.util.List; import java.util.function.Predicate; -/** - * Like {@link Collector}, but collecting multiple Snapshots at once. - */ +/** Like {@link Collector}, but collecting multiple Snapshots at once. */ @FunctionalInterface public interface MultiCollector { - /** - * Called when the Prometheus server scrapes metrics. - */ - MetricSnapshots collect(); + /** Called when the Prometheus server scrapes metrics. */ + MetricSnapshots 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 MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { - return collect(); - } - - - /** - * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} is {@code true}. - *

      - * Override this if there is a more efficient way than first collecting all snapshot and then discarding the excluded ones. - */ - default MetricSnapshots collect(Predicate includedNames) { - return collect(includedNames, 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 MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { + return collect(); + } - /** - * 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 MetricSnapshots collect(Predicate includedNames, PrometheusScrapeRequest scrapeRequest) { - MetricSnapshots allSnapshots = scrapeRequest == null ? collect(): collect(scrapeRequest); - MetricSnapshots.Builder result = MetricSnapshots.builder(); - for (MetricSnapshot snapshot : allSnapshots) { - if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { - result.metricSnapshot(snapshot); - } - } - return result.build(); - } + /** + * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} + * is {@code true}. + * + *

      Override this if there is a more efficient way than first collecting all snapshot and then + * discarding the excluded ones. + */ + default MetricSnapshots collect(Predicate includedNames) { + return collect(includedNames, null); + } - - /** - * This is called in two places: - *

        - *
      1. During registration to check if a metric with that name already exists.
      2. - *
      3. During scrape to check if the collector can be skipped because a name filter is present and all names are excluded.
      4. - *
      - * Returning an empty list means checks are omitted (registration metric always succeeds), - * and the collector is always scraped (if a name filter is present and all names are excluded the result is dropped). - *

      - * If your collector returns a constant list of metrics that have names that do not change at runtime - * it is a good idea to overwrite this and return the names. - */ - default List getPrometheusNames() { - return Collections.emptyList(); + /** + * 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 MetricSnapshots collect( + Predicate includedNames, PrometheusScrapeRequest scrapeRequest) { + MetricSnapshots allSnapshots = scrapeRequest == null ? collect() : collect(scrapeRequest); + MetricSnapshots.Builder result = MetricSnapshots.builder(); + for (MetricSnapshot snapshot : allSnapshots) { + if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { + result.metricSnapshot(snapshot); + } } + return result.build(); + } + + /** + * This is called in two places: + * + *

        + *
      1. During registration to check if a metric with that name already exists. + *
      2. During scrape to check if the collector can be skipped because a name filter is present + * and all names are excluded. + *
      + * + * Returning an empty list means checks are omitted (registration metric always succeeds), and the + * collector is always scraped (if a name filter is present and all names are excluded the result + * is dropped). + * + *

      If your collector returns a constant list of metrics that have names that do not change at + * runtime it is a good idea to overwrite this and return the names. + */ + default List getPrometheusNames() { + return Collections.emptyList(); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java index e8651292e..b1789c3bd 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusScrapeRequest.java @@ -1,17 +1,11 @@ package io.prometheus.metrics.model.registry; -/** - * Infos extracted from the request received by the endpoint - */ +/** Infos extracted from the request received by the endpoint */ public interface PrometheusScrapeRequest { - /** - * Absolute path of the HTTP request. - */ - String getRequestPath(); + /** Absolute path of the HTTP request. */ + String getRequestPath(); - /** - * See {@code jakarta.servlet.ServletRequest.getParameterValues(String name)} - */ - String[] getParameterValues(String name); + /** See {@code jakarta.servlet.ServletRequest.getParameterValues(String name)} */ + String[] getParameterValues(String name); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java index 6ca2f90ec..ebadd1f16 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucket.java @@ -1,42 +1,44 @@ package io.prometheus.metrics.model.snapshots; /** - * Helper class for iterating over {@link ClassicHistogramBuckets}. - * Note that the {@code count} is not cumulative. + * Helper class for iterating over {@link ClassicHistogramBuckets}. Note that the {@code count} is + * not cumulative. */ public class ClassicHistogramBucket implements Comparable { - private final long count; // not cumulative - private final double upperBound; + private final long count; // not cumulative + private final double upperBound; - public ClassicHistogramBucket(double upperBound, long count) { - this.count = count; - this.upperBound = upperBound; - if (Double.isNaN(upperBound)) { - throw new IllegalArgumentException("Cannot use NaN as an upper bound for a histogram bucket"); - } - if (count < 0) { - throw new IllegalArgumentException(count + ": " + ClassicHistogramBuckets.class.getSimpleName() + " cannot have a negative count"); - } + public ClassicHistogramBucket(double upperBound, long count) { + this.count = count; + this.upperBound = upperBound; + if (Double.isNaN(upperBound)) { + throw new IllegalArgumentException("Cannot use NaN as an upper bound for a histogram bucket"); } - - public long getCount() { - return count; + if (count < 0) { + throw new IllegalArgumentException( + count + + ": " + + ClassicHistogramBuckets.class.getSimpleName() + + " cannot have a negative count"); } + } - public double getUpperBound() { - return upperBound; - } + public long getCount() { + return count; + } + + public double getUpperBound() { + return upperBound; + } - /** - * For sorting a list of buckets by upper bound. - */ - @Override - public int compareTo(ClassicHistogramBucket other) { - int result = Double.compare(upperBound, other.upperBound); - if (result != 0) { - return result; - } - return Long.compare(count, other.count); + /** For sorting a list of buckets by upper bound. */ + @Override + public int compareTo(ClassicHistogramBucket other) { + int result = Double.compare(upperBound, other.upperBound); + if (result != 0) { + return result; } + return Long.compare(count, other.count); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java index 4d7c6d279..6b5d4dea6 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java @@ -8,216 +8,220 @@ import java.util.stream.Stream; /** - * Immutable container for histogram buckets with fixed bucket boundaries. - * Note that the counts are not cumulative. + * Immutable container for histogram buckets with fixed bucket boundaries. Note that the counts are + * not cumulative. */ public class ClassicHistogramBuckets implements Iterable { - /** - * Used in native histograms to indicate that no classic histogram buckets are present. - */ - public static final ClassicHistogramBuckets EMPTY = new ClassicHistogramBuckets(new double[]{}, new long[]{}); - - private final double[] upperBounds; - private final long[] counts; // not cumulative - - private ClassicHistogramBuckets(double[] upperBounds, long[] counts) { - this.upperBounds = upperBounds; - this.counts = counts; - } - - /** - * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@link ClassicHistogramBuckets#builder()}. - *

      - * This method will create a copy of upperBounds and counts. - * - * @param upperBounds must have the same length as counts. Must not contain duplicates. - * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. - * An upper bound must not be {@link Double#NaN}. - * The upperBounds array does not need to be sorted. - * @param counts must have the same length as {@code upperBounds}. - * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. - * For each count, {@link Number#longValue()} is called to get the value. - * Counts are not cumulative. Counts must not be negative. - */ - public static ClassicHistogramBuckets of(List upperBounds, List counts) { - double[] upperBoundsCopy = new double[upperBounds.size()]; - for (int i = 0; i < upperBounds.size(); i++) { - upperBoundsCopy[i] = upperBounds.get(i); + /** Used in native histograms to indicate that no classic histogram buckets are present. */ + public static final ClassicHistogramBuckets EMPTY = + new ClassicHistogramBuckets(new double[] {}, new long[] {}); + + private final double[] upperBounds; + private final long[] counts; // not cumulative + + private ClassicHistogramBuckets(double[] upperBounds, long[] counts) { + this.upperBounds = upperBounds; + this.counts = counts; + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code + * of(...)} methods, or use {@link ClassicHistogramBuckets#builder()}. + * + *

      This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. Must + * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper + * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is + * the count for the {@code upperBound} at index {@code i}. For each count, {@link + * Number#longValue()} is called to get the value. Counts are not cumulative. Counts + * must not be negative. + */ + public static ClassicHistogramBuckets of( + List upperBounds, List counts) { + double[] upperBoundsCopy = new double[upperBounds.size()]; + for (int i = 0; i < upperBounds.size(); i++) { + upperBoundsCopy[i] = upperBounds.get(i); + } + long[] countsCopy = new long[counts.size()]; + for (int i = 0; i < counts.size(); i++) { + countsCopy[i] = counts.get(i).longValue(); + } + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code + * of(...)} methods, or use {@link ClassicHistogramBuckets#builder()}. + * + *

      This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. Must + * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper + * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is + * the count for the {@code upperBound} at index {@code i}. For each count, {@link + * Number#longValue()} is called to get the value. Counts are not cumulative. Counts + * must not be negative. + */ + public static ClassicHistogramBuckets of(double[] upperBounds, Number[] counts) { + double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); + long[] countsCopy = new long[counts.length]; + for (int i = 0; i < counts.length; i++) { + countsCopy[i] = counts[i].longValue(); + } + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code + * of(...)} methods, or use {@link ClassicHistogramBuckets#builder()}. + * + *

      This method will create a copy of upperBounds and counts. + * + * @param upperBounds must have the same length as counts. Must not contain duplicates. Must + * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper + * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. + * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is + * the count for the {@code upperBound} at index {@code i}. Counts are not cumulative. + * Counts must not be negative. + */ + public static ClassicHistogramBuckets of(double[] upperBounds, long[] counts) { + double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); + long[] countsCopy = Arrays.copyOf(counts, counts.length); + sortAndValidate(upperBoundsCopy, countsCopy); + return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } + + private static void sortAndValidate(double[] upperBounds, long[] counts) { + if (upperBounds.length != counts.length) { + throw new IllegalArgumentException( + "upperBounds.length == " + + upperBounds.length + + " but counts.length == " + + counts.length + + ". Expected the same length."); + } + sort(upperBounds, counts); + validate(upperBounds, counts); + } + + private static void sort(double[] upperBounds, long[] counts) { + // Bubblesort. Should be efficient here as in most cases upperBounds is already sorted. + int n = upperBounds.length; + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (upperBounds[j] > upperBounds[j + 1]) { + swap(j, j + 1, upperBounds, counts); } - long[] countsCopy = new long[counts.size()]; - for (int i = 0; i < counts.size(); i++) { - countsCopy[i] = counts.get(i).longValue(); + } + } + } + + private static void swap(int i, int j, double[] upperBounds, long[] counts) { + double tmpDouble = upperBounds[j]; + upperBounds[j] = upperBounds[i]; + upperBounds[i] = tmpDouble; + long tmpLong = counts[j]; + counts[j] = counts[i]; + counts[i] = tmpLong; + } + + private static void validate(double[] upperBounds, long[] counts) { + // Preconditions: + // * upperBounds sorted + // * upperBounds and counts have the same length + if (upperBounds.length == 0) { + throw new IllegalArgumentException( + ClassicHistogramBuckets.class.getSimpleName() + + " cannot be empty. They must contain at least the +Inf bucket."); + } + if (upperBounds[upperBounds.length - 1] != Double.POSITIVE_INFINITY) { + throw new IllegalArgumentException( + ClassicHistogramBuckets.class.getSimpleName() + " must contain the +Inf bucket."); + } + for (int i = 0; i < upperBounds.length; i++) { + if (Double.isNaN(upperBounds[i])) { + throw new IllegalArgumentException( + "Cannot use NaN as an upper bound in " + ClassicHistogramBuckets.class.getSimpleName()); + } + if (counts[i] < 0) { + throw new IllegalArgumentException( + "Counts in " + ClassicHistogramBuckets.class.getSimpleName() + " cannot be negative."); + } + if (i > 0) { + if (upperBounds[i - 1] == upperBounds[i]) { + throw new IllegalArgumentException("Duplicate upper bound " + upperBounds[i]); } - sortAndValidate(upperBoundsCopy, countsCopy); - return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); + } } + } - /** - * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@link ClassicHistogramBuckets#builder()}. - *

      - * This method will create a copy of upperBounds and counts. - * - * @param upperBounds must have the same length as counts. Must not contain duplicates. - * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. - * An upper bound must not be {@link Double#NaN}. - * The upperBounds array does not need to be sorted. - * @param counts must have the same length as {@code upperBounds}. - * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. - * For each count, {@link Number#longValue()} is called to get the value. - * Counts are not cumulative. Counts must not be negative. - */ - public static ClassicHistogramBuckets of(double[] upperBounds, Number[] counts) { - double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); - long[] countsCopy = new long[counts.length]; - for (int i = 0; i < counts.length; i++) { - countsCopy[i] = counts[i].longValue(); - } - sortAndValidate(upperBoundsCopy, countsCopy); - return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); - } + public int size() { + return upperBounds.length; + } - /** - * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@link ClassicHistogramBuckets#builder()}. - *

      - * This method will create a copy of upperBounds and counts. - * - * @param upperBounds must have the same length as counts. Must not contain duplicates. - * Must contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. - * An upper bound must not be {@link Double#NaN}. - * The upperBounds array does not need to be sorted. - * @param counts must have the same length as {@code upperBounds}. - * The entry at index {@code i} is the count for the {@code upperBound} at index {@code i}. - * Counts are not cumulative. Counts must not be negative. - */ - public static ClassicHistogramBuckets of(double[] upperBounds, long[] counts) { - double[] upperBoundsCopy = Arrays.copyOf(upperBounds, upperBounds.length); - long[] countsCopy = Arrays.copyOf(counts, counts.length); - sortAndValidate(upperBoundsCopy, countsCopy); - return new ClassicHistogramBuckets(upperBoundsCopy, countsCopy); - } + public double getUpperBound(int i) { + return upperBounds[i]; + } - private static void sortAndValidate(double[] upperBounds, long[] counts) { - if (upperBounds.length != counts.length) { - throw new IllegalArgumentException("upperBounds.length == " + upperBounds.length + " but counts.length == " + counts.length + ". Expected the same length."); - } - sort(upperBounds, counts); - validate(upperBounds, counts); - } + /** The count is not cumulative. */ + public long getCount(int i) { + return counts[i]; + } - private static void sort(double[] upperBounds, long[] counts) { - // Bubblesort. Should be efficient here as in most cases upperBounds is already sorted. - int n = upperBounds.length; - for (int i = 0; i < n - 1; i++) { - for (int j = 0; j < n - i - 1; j++) { - if (upperBounds[j] > upperBounds[j + 1]) { - swap(j, j + 1, upperBounds, counts); - } - } - } - } + public boolean isEmpty() { + return this.upperBounds.length == 0; + } - private static void swap(int i, int j, double[] upperBounds, long[] counts) { - double tmpDouble = upperBounds[j]; - upperBounds[j] = upperBounds[i]; - upperBounds[i] = tmpDouble; - long tmpLong = counts[j]; - counts[j] = counts[i]; - counts[i] = tmpLong; + private List asList() { + List result = new ArrayList<>(size()); + for (int i = 0; i < upperBounds.length; i++) { + result.add(new ClassicHistogramBucket(upperBounds[i], counts[i])); } + return Collections.unmodifiableList(result); + } - private static void validate(double[] upperBounds, long[] counts) { - // Preconditions: - // * upperBounds sorted - // * upperBounds and counts have the same length - if (upperBounds.length == 0) { - throw new IllegalArgumentException(ClassicHistogramBuckets.class.getSimpleName() + " cannot be empty. They must contain at least the +Inf bucket."); - } - if (upperBounds[upperBounds.length - 1] != Double.POSITIVE_INFINITY) { - throw new IllegalArgumentException(ClassicHistogramBuckets.class.getSimpleName() + " must contain the +Inf bucket."); - } - for (int i = 0; i < upperBounds.length; i++) { - if (Double.isNaN(upperBounds[i])) { - throw new IllegalArgumentException("Cannot use NaN as an upper bound in " + ClassicHistogramBuckets.class.getSimpleName()); - } - if (counts[i] < 0) { - throw new IllegalArgumentException("Counts in " + ClassicHistogramBuckets.class.getSimpleName() + " cannot be negative."); - } - if (i > 0) { - if (upperBounds[i - 1] == upperBounds[i]) { - throw new IllegalArgumentException("Duplicate upper bound " + upperBounds[i]); - } - } - } - } - - public int size() { - return upperBounds.length; - } - - public double getUpperBound(int i) { - return upperBounds[i]; - } + @Override + public Iterator iterator() { + return asList().iterator(); + } - /** - * The count is not cumulative. - */ - public long getCount(int i) { - return counts[i]; - } + public Stream stream() { + return asList().stream(); + } - public boolean isEmpty() { - return this.upperBounds.length == 0; - } + /** + * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code + * of(...)} methods, or use {@code builder()}. + */ + public static Builder builder() { + return new Builder(); + } - private List asList() { - List result = new ArrayList<>(size()); - for (int i = 0; i < upperBounds.length; i++) { - result.add(new ClassicHistogramBucket(upperBounds[i], counts[i])); - } - return Collections.unmodifiableList(result); - } + public static class Builder { + private final List upperBounds = new ArrayList<>(); + private final List counts = new ArrayList<>(); - @Override - public Iterator iterator() { - return asList().iterator(); - } + private Builder() {} - public Stream stream() { - return asList().stream(); + /** Must be called at least once for the {@link Double#POSITIVE_INFINITY} bucket. */ + public Builder bucket(double upperBound, long count) { + upperBounds.add(upperBound); + counts.add(count); + return this; } /** - * To create new {@link ClassicHistogramBuckets}, you can either use one of the static {@code of(...)} methods, - * or use {@code builder()}. + * Will throw an {@link IllegalArgumentException} if the {@link Double#POSITIVE_INFINITY} bucket + * is missing. */ - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private final List upperBounds = new ArrayList<>(); - private final List counts = new ArrayList<>(); - - private Builder() {} - - /** - * Must be called at least once for the {@link Double#POSITIVE_INFINITY} bucket. - */ - public Builder bucket(double upperBound, long count) { - upperBounds.add(upperBound); - counts.add(count); - return this; - } - - /** - * Will throw an {@link IllegalArgumentException} if the {@link Double#POSITIVE_INFINITY} bucket is missing. - */ - public ClassicHistogramBuckets build() { - return ClassicHistogramBuckets.of(upperBounds, counts); - } + public ClassicHistogramBuckets build() { + return ClassicHistogramBuckets.of(upperBounds, counts); } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java index 4aceea6bd..fa807af19 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -4,149 +4,146 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of a Counter. - */ +/** Immutable snapshot of a Counter. */ public class CounterSnapshot extends MetricSnapshot { + /** + * To create a new {@link CounterSnapshot}, you can either call the constructor directly or use + * the builder with {@link CounterSnapshot#builder()}. + * + * @param metadata the metric name in metadata must not include the {@code _total} suffix. See + * {@link MetricMetadata} for more naming conventions. + * @param dataPoints the constructor will create a sorted copy of the collection. + */ + public CounterSnapshot(MetricMetadata metadata, Collection dataPoints) { + super(metadata, dataPoints); + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static class CounterDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + /** - * To create a new {@link CounterSnapshot}, you can either call the constructor directly or use - * the builder with {@link CounterSnapshot#builder()}. + * To create a new {@link CounterDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link CounterDataPointSnapshot#builder()}. * - * @param metadata the metric name in metadata must not include the {@code _total} suffix. - * See {@link MetricMetadata} for more naming conventions. - * @param dataPoints the constructor will create a sorted copy of the collection. + * @param value the counter value. Must not be negative. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the + * time series (this specific set of labels) was created (or reset to zero). It's optional. + * Use {@code 0L} if there is no created timestamp. */ - public CounterSnapshot(MetricMetadata metadata, Collection dataPoints) { - super(metadata, dataPoints); + public CounterDataPointSnapshot( + double value, Labels labels, Exemplar exemplar, long createdTimestampMillis) { + this(value, labels, exemplar, createdTimestampMillis, 0); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 CounterDataPointSnapshot( + double value, + Labels labels, + Exemplar exemplar, + long createdTimestampMillis, + long scrapeTimestampMillis) { + super(labels, createdTimestampMillis, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; + validate(); } - public static class CounterDataPointSnapshot extends DataPointSnapshot { - - private final double value; - private final Exemplar exemplar; // may be null - - /** - * To create a new {@link CounterDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link CounterDataPointSnapshot#builder()}. - * - * @param value the counter value. Must not be negative. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplar may be null. - * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series - * (this specific set of labels) was created (or reset to zero). - * It's optional. Use {@code 0L} if there is no created timestamp. - */ - public CounterDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long createdTimestampMillis) { - this(value, labels, exemplar, createdTimestampMillis, 0); - } + public double getValue() { + return value; + } - /** - * 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 CounterDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long createdTimestampMillis, long scrapeTimestampMillis) { - super(labels, createdTimestampMillis, scrapeTimestampMillis); - this.value = value; - this.exemplar = exemplar; - validate(); - } + /** May be {@code null}. */ + public Exemplar getExemplar() { + return exemplar; + } - public double getValue() { - return value; - } + protected void validate() { + if (value < 0.0) { + throw new IllegalArgumentException(value + ": counters cannot have a negative value"); + } + } - /** - * May be {@code null}. - */ - public Exemplar getExemplar() { - return exemplar; - } + public static Builder builder() { + return new Builder(); + } - protected void validate() { - if (value < 0.0) { - throw new IllegalArgumentException(value + ": counters cannot have a negative value"); - } - } + public static class Builder extends DataPointSnapshot.Builder { - public static Builder builder() { - return new Builder(); - } + private Exemplar exemplar = null; + private Double value = null; + private long createdTimestampMillis = 0L; + + private Builder() {} + + /** Counter value. This is required. The value must not be negative. */ + public Builder value(double value) { + this.value = value; + return this; + } - public static class Builder extends DataPointSnapshot.Builder { - - private Exemplar exemplar = null; - private Double value = null; - private long createdTimestampMillis = 0L; - - private Builder() { - } - - /** - * Counter value. This is required. The value must not be negative. - */ - public Builder value(double value) { - this.value = value; - return this; - } - - public Builder exemplar(Exemplar exemplar) { - this.exemplar = exemplar; - return this; - } - - public Builder createdTimestampMillis(long createdTimestampMillis) { - this.createdTimestampMillis = createdTimestampMillis; - return this; - } - - public CounterDataPointSnapshot build() { - if (value == null) { - throw new IllegalArgumentException("Missing required field: value is null."); - } - return new CounterDataPointSnapshot(value, labels, exemplar, createdTimestampMillis, scrapeTimestampMillis); - } - - @Override - protected Builder self() { - return this; - } + public Builder exemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } + + public Builder createdTimestampMillis(long createdTimestampMillis) { + this.createdTimestampMillis = createdTimestampMillis; + return this; + } + + public CounterDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); } + return new CounterDataPointSnapshot( + value, labels, exemplar, createdTimestampMillis, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } } + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder extends MetricSnapshot.Builder { + public static class Builder extends MetricSnapshot.Builder { - private final List dataPoints = new ArrayList<>(); + private final List dataPoints = new ArrayList<>(); - private Builder() { - } + private Builder() {} - /** - * Add a data point. Can be called multiple times to add multiple data points. - */ - public Builder dataPoint(CounterDataPointSnapshot dataPoint) { - dataPoints.add(dataPoint); - return this; - } + /** Add a data point. Can be called multiple times to add multiple data points. */ + public Builder dataPoint(CounterDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); + return this; + } - @Override - public CounterSnapshot build() { - return new CounterSnapshot(buildMetadata(), dataPoints); - } + @Override + public CounterSnapshot build() { + return new CounterSnapshot(buildMetadata(), dataPoints); + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java index 7710754e2..47ad4486b 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java @@ -1,82 +1,85 @@ package io.prometheus.metrics.model.snapshots; public abstract class DataPointSnapshot { - private final Labels labels; - private final long createdTimestampMillis; - private final long scrapeTimestampMillis; + private final Labels labels; + private final long createdTimestampMillis; + private final long scrapeTimestampMillis; - protected DataPointSnapshot(Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { - this.labels = labels; - this.createdTimestampMillis = createdTimestampMillis; - this.scrapeTimestampMillis = scrapeTimestampMillis; - validate(); - } + protected DataPointSnapshot( + Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { + this.labels = labels; + this.createdTimestampMillis = createdTimestampMillis; + this.scrapeTimestampMillis = scrapeTimestampMillis; + validate(); + } - private void validate() { - if (labels == null) { - throw new IllegalArgumentException("Labels cannot be null. Use Labels.EMPTY if there are no labels."); - } - if (createdTimestampMillis < 0) { - throw new IllegalArgumentException("Created timestamp cannot be negative. Use 0 if the metric doesn't have a created timestamp."); - } - if (scrapeTimestampMillis < 0) { - throw new IllegalArgumentException("Scrape timestamp cannot be negative. Use 0 to indicate that the Prometheus server should set the scrape timestamp."); - } - if (hasCreatedTimestamp() && hasScrapeTimestamp()) { - if (scrapeTimestampMillis < createdTimestampMillis) { - throw new IllegalArgumentException("The scrape timestamp cannot be before the created timestamp"); - } - } + private void validate() { + if (labels == null) { + throw new IllegalArgumentException( + "Labels cannot be null. Use Labels.EMPTY if there are no labels."); } - - public Labels getLabels() { - return labels; + if (createdTimestampMillis < 0) { + throw new IllegalArgumentException( + "Created timestamp cannot be negative. Use 0 if the metric doesn't have a created timestamp."); } - - public boolean hasScrapeTimestamp() { - return scrapeTimestampMillis != 0L; + if (scrapeTimestampMillis < 0) { + throw new IllegalArgumentException( + "Scrape timestamp cannot be negative. Use 0 to indicate that the Prometheus server should set the scrape timestamp."); } - - /** - * This will only return a reasonable value if {@link #hasScrapeTimestamp()} is true. - */ - public long getScrapeTimestampMillis() { - return scrapeTimestampMillis; + if (hasCreatedTimestamp() && hasScrapeTimestamp()) { + if (scrapeTimestampMillis < createdTimestampMillis) { + throw new IllegalArgumentException( + "The scrape timestamp cannot be before the created timestamp"); + } } + } - public boolean hasCreatedTimestamp() { - return createdTimestampMillis != 0L; - } + public Labels getLabels() { + return labels; + } - /** - * This will only return a reasonable value if {@link #hasCreatedTimestamp()} is true. - * Some metrics like Gauge don't have created timestamps. For these metrics {@link #hasCreatedTimestamp()} - * is always false. - */ - public long getCreatedTimestampMillis() { - return createdTimestampMillis; - } + public boolean hasScrapeTimestamp() { + return scrapeTimestampMillis != 0L; + } + + /** This will only return a reasonable value if {@link #hasScrapeTimestamp()} is true. */ + public long getScrapeTimestampMillis() { + return scrapeTimestampMillis; + } + + public boolean hasCreatedTimestamp() { + return createdTimestampMillis != 0L; + } - public static abstract class Builder> { + /** + * This will only return a reasonable value if {@link #hasCreatedTimestamp()} is true. Some + * metrics like Gauge don't have created timestamps. For these metrics {@link + * #hasCreatedTimestamp()} is always false. + */ + public long getCreatedTimestampMillis() { + return createdTimestampMillis; + } - protected Labels labels = Labels.EMPTY; - protected long scrapeTimestampMillis = 0L; + public abstract static class Builder> { - public T labels(Labels labels) { - this.labels = labels; - return self(); - } + protected Labels labels = Labels.EMPTY; + protected long scrapeTimestampMillis = 0L; - /** - * In most cases you should not set a scrape timestamp, - * because the scrape timestamp is set by the Prometheus server during scraping. - * Exceptions include mirroring metrics with given timestamps from other metric sources. - */ - public T scrapeTimestampMillis(long scrapeTimestampMillis) { - this.scrapeTimestampMillis = scrapeTimestampMillis; - return self(); - } + public T labels(Labels labels) { + this.labels = labels; + return self(); + } - protected abstract T self(); + /** + * In most cases you should not set a scrape timestamp, because the scrape timestamp is set by + * the Prometheus server during scraping. Exceptions include mirroring metrics with given + * timestamps from other metric sources. + */ + public T scrapeTimestampMillis(long scrapeTimestampMillis) { + this.scrapeTimestampMillis = scrapeTimestampMillis; + return self(); } + + protected abstract T self(); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java index fe5f729c1..c8092237c 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DistributionDataPointSnapshot.java @@ -1,89 +1,86 @@ package io.prometheus.metrics.model.snapshots; /** - * Common base class for histogram and summary data. - * Histograms and Summaries represent distributions, like a latency distribution or a distribution - * of request sizes in Bytes. + * Common base class for histogram and summary data. Histograms and Summaries represent + * distributions, like a latency distribution or a distribution of request sizes in Bytes. */ public abstract class DistributionDataPointSnapshot extends DataPointSnapshot { - private final long count; // optional, negative value means no count. - private final double sum; // optional, Double.NaN means no sum. - private final Exemplars exemplars; // optional, Exemplars.EMPTY means no Exemplars. + private final long count; // optional, negative value means no count. + private final double sum; // optional, Double.NaN means no sum. + private final Exemplars exemplars; // optional, Exemplars.EMPTY means no Exemplars. - /** - * See JavaDoc of the child classes. - */ - protected DistributionDataPointSnapshot(long count, double sum, Exemplars exemplars, Labels labels, long createdTimestampMillis, long scrapeTimestampMillis) { - super(labels, createdTimestampMillis, scrapeTimestampMillis); - this.count = count; - this.sum = sum; - this.exemplars = exemplars == null ? Exemplars.EMPTY : exemplars; - validate(); - } + /** See JavaDoc of the child classes. */ + protected DistributionDataPointSnapshot( + long count, + double sum, + Exemplars exemplars, + Labels labels, + long createdTimestampMillis, + long scrapeTimestampMillis) { + super(labels, createdTimestampMillis, scrapeTimestampMillis); + this.count = count; + this.sum = sum; + this.exemplars = exemplars == null ? Exemplars.EMPTY : exemplars; + validate(); + } - private void validate() { - // If a histogram or summary observes negative values the sum could be negative. - // According to OpenMetrics sum should be omitted in that case, but we don't enforce this here. - } + private void validate() { + // If a histogram or summary observes negative values the sum could be negative. + // According to OpenMetrics sum should be omitted in that case, but we don't enforce this here. + } - public boolean hasCount() { - return count >= 0; - } + public boolean hasCount() { + return count >= 0; + } - public boolean hasSum() { - return !Double.isNaN(sum); - } + public boolean hasSum() { + return !Double.isNaN(sum); + } - /** - * This will return garbage if {@link #hasCount()} is {@code false}. - */ - public long getCount() { - return count; - } + /** This will return garbage if {@link #hasCount()} is {@code false}. */ + public long getCount() { + return count; + } - /** - * This will return garbage if {@link #hasSum()} is {@code false}. - */ - public double getSum() { - return sum; - } + /** This will return garbage if {@link #hasSum()} is {@code false}. */ + public double getSum() { + return sum; + } - /** - * May be {@link Exemplars#EMPTY}, but will never be {@code null}. - */ - public Exemplars getExemplars() { - return exemplars; - } + /** May be {@link Exemplars#EMPTY}, but will never be {@code null}. */ + public Exemplars getExemplars() { + return exemplars; + } - static abstract class Builder> extends DataPointSnapshot.Builder { + abstract static class Builder> extends DataPointSnapshot.Builder { - protected long count = -1; - protected double sum = Double.NaN; - protected long createdTimestampMillis = 0L; - protected Exemplars exemplars = Exemplars.EMPTY; + protected long count = -1; + protected double sum = Double.NaN; + protected long createdTimestampMillis = 0L; + protected Exemplars exemplars = Exemplars.EMPTY; - /** - * Count can be explicitly set on summaries (this is a public method for summary metrics), - * and it is set implicitly on histograms (derived from the bucket counts). - */ - protected T count(long count) { - this.count = count; - return self(); - } + /** + * Count can be explicitly set on summaries (this is a public method for summary metrics), and + * it is set implicitly on histograms (derived from the bucket counts). + */ + protected T count(long count) { + this.count = count; + return self(); + } - public T sum(double sum) { - this.sum = sum; - return self(); - } + public T sum(double sum) { + this.sum = sum; + return self(); + } - public T exemplars(Exemplars exemplars) { - this.exemplars = exemplars; - return self(); - } + public T exemplars(Exemplars exemplars) { + this.exemplars = exemplars; + return self(); + } - public T createdTimestampMillis(long createdTimestampMillis) { - this.createdTimestampMillis = createdTimestampMillis; - return self(); - } + public T createdTimestampMillis(long createdTimestampMillis) { + this.createdTimestampMillis = createdTimestampMillis; + return self(); } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java index 4588b344d..d1f3f3414 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java @@ -1,25 +1,25 @@ package io.prometheus.metrics.model.snapshots; /** - * Thrown when a collector tries to create a {@link MetricSnapshot} - * where multiple data points have the same labels (same label names and label values). + * Thrown when a collector tries to create a {@link MetricSnapshot} where multiple data points have + * the same labels (same label names and label values). */ public class DuplicateLabelsException extends IllegalArgumentException { - private final MetricMetadata metadata; - private final Labels labels; + private final MetricMetadata metadata; + private final Labels labels; - public DuplicateLabelsException(MetricMetadata metadata, Labels labels) { - super("Duplicate labels for metric \"" + metadata.getName() + "\": " + labels); - this.metadata = metadata; - this.labels = labels; - } + public DuplicateLabelsException(MetricMetadata metadata, Labels labels) { + super("Duplicate labels for metric \"" + metadata.getName() + "\": " + labels); + this.metadata = metadata; + this.labels = labels; + } - public MetricMetadata getMetadata() { - return metadata; - } + public MetricMetadata getMetadata() { + return metadata; + } - public Labels getLabels() { - return labels; - } -} \ No newline at end of file + public Labels getLabels() { + return labels; + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java index aa46bd229..e56d9e1c7 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplar.java @@ -1,129 +1,121 @@ package io.prometheus.metrics.model.snapshots; -/** - * Immutable representation of an Exemplar. - */ +/** Immutable representation of an Exemplar. */ public class Exemplar { - /** - * Label name for trace id. - */ - public static final String TRACE_ID = "trace_id"; - - /** - * Label name for span id. - */ - public static final String SPAN_ID = "span_id"; - - private final double value; - private final Labels labels; - private final long timestampMillis; - - /** - * To create a new {@link Exemplar}, you can either call the constructor directly - * or use the Builder with {@link Exemplar#builder()}. - * - * @param value the observed value. This is required. - * @param labels in most cases the labels will contain the {@link #TRACE_ID} and {@link #SPAN_ID}. - * Must not be {@code null}. Use {@link Labels#EMPTY} if no labels are present. - * @param timestampMillis timestamp when the value was observed. Optional. Use 0L if not available. - */ - public Exemplar(double value, Labels labels, long timestampMillis) { - if (labels == null) { - throw new NullPointerException("Labels cannot be null. Use Labels.EMPTY."); - } - this.value = value; - this.labels = labels; - this.timestampMillis = timestampMillis; + /** Label name for trace id. */ + public static final String TRACE_ID = "trace_id"; + + /** Label name for span id. */ + public static final String SPAN_ID = "span_id"; + + private final double value; + private final Labels labels; + private final long timestampMillis; + + /** + * To create a new {@link Exemplar}, you can either call the constructor directly or use the + * Builder with {@link Exemplar#builder()}. + * + * @param value the observed value. This is required. + * @param labels in most cases the labels will contain the {@link #TRACE_ID} and {@link #SPAN_ID}. + * Must not be {@code null}. Use {@link Labels#EMPTY} if no labels are present. + * @param timestampMillis timestamp when the value was observed. Optional. Use 0L if not + * available. + */ + public Exemplar(double value, Labels labels, long timestampMillis) { + if (labels == null) { + throw new NullPointerException("Labels cannot be null. Use Labels.EMPTY."); } - - public double getValue() { - return value; + this.value = value; + this.labels = labels; + this.timestampMillis = timestampMillis; + } + + public double getValue() { + return value; + } + + /** + * In most cases labels will contain {@link #TRACE_ID} and {@link #SPAN_ID}, but this is not + * required. May be {@link Labels#EMPTY}, but may not be {@code null}. + */ + public Labels getLabels() { + return labels; + } + + public boolean hasTimestamp() { + return timestampMillis != 0L; + } + + /** Will return garbage if {@link #hasTimestamp()} is {@code false}. */ + public long getTimestampMillis() { + return timestampMillis; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private Double value = null; + private Labels labels = Labels.EMPTY; + private String traceId = null; + private String spanId = null; + private long timestampMillis = 0L; + + private Builder() {} + + public Builder value(double value) { + this.value = value; + return this; } - /** - * In most cases labels will contain {@link #TRACE_ID} and {@link #SPAN_ID}, but this is not required. - * May be {@link Labels#EMPTY}, but may not be {@code null}. - */ - public Labels getLabels() { - return labels; + public Builder traceId(String traceId) { + this.traceId = traceId; + return this; } - public boolean hasTimestamp() { - return timestampMillis != 0L; + public Builder spanId(String spanId) { + this.spanId = spanId; + return this; } - /** - * Will return garbage if {@link #hasTimestamp()} is {@code false}. - */ - public long getTimestampMillis() { - return timestampMillis; + public Builder labels(Labels labels) { + if (labels == null) { + throw new NullPointerException(); + } + this.labels = labels; + return this; } - public static Builder builder() { - return new Builder(); + public Builder timestampMillis(long timestampMillis) { + this.timestampMillis = timestampMillis; + return this; } - public static class Builder { - - private Double value = null; - private Labels labels = Labels.EMPTY; - private String traceId = null; - private String spanId = null; - private long timestampMillis = 0L; - - private Builder() { - } - - public Builder value(double value) { - this.value = value; - return this; - } - - public Builder traceId(String traceId) { - this.traceId = traceId; - return this; - } - - public Builder spanId(String spanId) { - this.spanId = spanId; - return this; - } - - public Builder labels(Labels labels) { - if (labels == null) { - throw new NullPointerException(); - } - this.labels = labels; - return this; - } - - public Builder timestampMillis(long timestampMillis) { - this.timestampMillis = timestampMillis; - return this; - } - - /** - * @throws IllegalStateException if {@link #value(double)} wasn't called. - */ - public Exemplar build() { - if (value == null) { - throw new IllegalStateException("cannot build an Exemplar without a value"); - } - Labels allLabels; - if (traceId != null && spanId != null) { - allLabels = Labels.of(TRACE_ID, traceId, SPAN_ID, spanId); - } else if (traceId != null) { - allLabels = Labels.of(TRACE_ID, traceId); - } else if (spanId != null) { - allLabels = Labels.of(SPAN_ID, spanId); - } else { - allLabels = Labels.EMPTY; - } - if (!labels.isEmpty()) { - allLabels = allLabels.merge(labels); - } - return new Exemplar(value, allLabels, timestampMillis); - } + /** + * @throws IllegalStateException if {@link #value(double)} wasn't called. + */ + public Exemplar build() { + if (value == null) { + throw new IllegalStateException("cannot build an Exemplar without a value"); + } + Labels allLabels; + if (traceId != null && spanId != null) { + allLabels = Labels.of(TRACE_ID, traceId, SPAN_ID, spanId); + } else if (traceId != null) { + allLabels = Labels.of(TRACE_ID, traceId); + } else if (spanId != null) { + allLabels = Labels.of(SPAN_ID, spanId); + } else { + allLabels = Labels.EMPTY; + } + if (!labels.isEmpty()) { + allLabels = allLabels.merge(labels); + } + return new Exemplar(value, allLabels, timestampMillis); } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java index 2600214aa..c94faf8dd 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java @@ -4,135 +4,124 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of a Gauge. - */ +/** Immutable snapshot of a Gauge. */ public final class GaugeSnapshot extends MetricSnapshot { + /** + * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use the + * builder with {@link GaugeSnapshot#builder()}. + * + * @param metadata see {@link MetricMetadata} for naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public GaugeSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static final class GaugeDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + /** - * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use - * the builder with {@link GaugeSnapshot#builder()}. + * To create a new {@link GaugeDataPointSnapshot}, you can either call the constructor directly + * or use the Builder with {@link GaugeDataPointSnapshot#builder()}. * - * @param metadata see {@link MetricMetadata} for naming conventions. - * @param data the constructor will create a sorted copy of the collection. + * @param value the gauge value. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. */ - public GaugeSnapshot(MetricMetadata metadata, Collection data) { - super(metadata, data); + public GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { + this(value, labels, exemplar, 0); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 GaugeDataPointSnapshot( + double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; } - public static final class GaugeDataPointSnapshot extends DataPointSnapshot { - - private final double value; - private final Exemplar exemplar; // may be null - - /** - * To create a new {@link GaugeDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link GaugeDataPointSnapshot#builder()}. - * - * @param value the gauge value. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplar may be null. - */ - public GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { - this(value, labels, exemplar, 0); - } + public double getValue() { + return value; + } - /** - * 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 GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { - super(labels, 0L, scrapeTimestampMillis); - this.value = value; - this.exemplar = exemplar; - } + /** May be {@code null}. */ + public Exemplar getExemplar() { + return exemplar; + } - public double getValue() { - return value; - } + public static Builder builder() { + return new Builder(); + } - /** - * May be {@code null}. - */ - public Exemplar getExemplar() { - return exemplar; - } + public static class Builder extends DataPointSnapshot.Builder { - public static Builder builder() { - return new Builder(); - } + private Exemplar exemplar = null; + private Double value = null; + + private Builder() {} + + /** Gauge value. This is required. */ + public Builder value(double value) { + this.value = value; + return this; + } + + /** Optional */ + public Builder exemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } - public static class Builder extends DataPointSnapshot.Builder { - - private Exemplar exemplar = null; - private Double value = null; - - private Builder() { - } - - /** - * Gauge value. This is required. - */ - public Builder value(double value) { - this.value = value; - return this; - } - - /** - * Optional - */ - public Builder exemplar(Exemplar exemplar) { - this.exemplar = exemplar; - return this; - } - - public GaugeDataPointSnapshot build() { - if (value == null) { - throw new IllegalArgumentException("Missing required field: value is null."); - } - return new GaugeDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); - } - - @Override - protected Builder self() { - return this; - } + public GaugeDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); } - } + return new GaugeDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); + } - public static Builder builder() { - return new Builder(); + @Override + protected Builder self() { + return this; + } } + } - 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. This can be called multiple times to add multiple data points. - */ - public Builder dataPoint(GaugeDataPointSnapshot dataPoint) { - dataPoints.add(dataPoint); - return this; - } + private Builder() {} - @Override - public GaugeSnapshot build() { - return new GaugeSnapshot(buildMetadata(), dataPoints); - } + /** Add a data point. This can be called multiple times to add multiple data points. */ + public Builder dataPoint(GaugeDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); + return this; + } - @Override - protected Builder self() { - return this; - } + @Override + public GaugeSnapshot build() { + return new GaugeSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index 0737f7368..5988cce3d 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -4,399 +4,487 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of a Histogram. - */ +/** Immutable snapshot of a Histogram. */ public final class HistogramSnapshot extends MetricSnapshot { - private final boolean gaugeHistogram; - public static final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; + private final boolean gaugeHistogram; + public static final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; + + /** + * To create a new {@link HistogramSnapshot}, you can either call the constructor directly or use + * the builder with {@link HistogramSnapshot#builder()}. + * + * @param metadata see {@link MetricMetadata} for naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public HistogramSnapshot(MetricMetadata metadata, Collection data) { + this(false, metadata, data); + } + + /** + * Use this with the first parameter {@code true} to create a snapshot of a Gauge Histogram. The + * data model for Gauge Histograms is the same as for regular histograms, except that bucket + * values are semantically gauges and not counters. See openmetrics.io for more info on Gauge Histograms. + */ + public HistogramSnapshot( + boolean isGaugeHistogram, + MetricMetadata metadata, + Collection data) { + super(metadata, data); + this.gaugeHistogram = isGaugeHistogram; + } + + public boolean isGaugeHistogram() { + return gaugeHistogram; + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static final class HistogramDataPointSnapshot extends DistributionDataPointSnapshot { + + // There are two types of histograms: Classic histograms and native histograms. + // Classic histograms have a fixed set of buckets. + // Native histograms have "infinitely many" buckets with exponentially growing boundaries. + // The OpenTelemetry terminology for native histogram is "exponential histogram". + // --- + // A histogram can be a classic histogram (indicated by nativeSchema == CLASSIC_HISTOGRAM), + // or a native histogram (indicated by classicBuckets == ClassicHistogramBuckets.EMPTY), + // or both. + // --- + // A histogram that is both classic and native is great for migrating from classic histograms + // to native histograms: Old Prometheus servers can still scrape the classic histogram, while + // new Prometheus servers can scrape the native histogram. + + private final ClassicHistogramBuckets + classicBuckets; // May be ClassicHistogramBuckets.EMPTY for native histograms. + private final int + nativeSchema; // Number in [-4, 8]. May be CLASSIC_HISTOGRAM for classic histograms. + private final long nativeZeroCount; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final double nativeZeroThreshold; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final NativeHistogramBuckets + nativeBucketsForPositiveValues; // only used if nativeSchema != CLASSIC_HISTOGRAM + private final NativeHistogramBuckets + nativeBucketsForNegativeValues; // only used if nativeSchema != CLASSIC_HISTOGRAM /** - * To create a new {@link HistogramSnapshot}, you can either call the constructor directly or use - * the builder with {@link HistogramSnapshot#builder()}. + * Constructor for classic histograms (as opposed to native histograms). * - * @param metadata see {@link MetricMetadata} for naming conventions. - * @param data the constructor will create a sorted copy of the collection. + *

      To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link HistogramSnapshot#builder()}. + * + * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. + * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the + * time series (this specific set of labels) was created (or reset to zero). It's optional. + * Use {@code 0L} if there is no created timestamp. */ - public HistogramSnapshot(MetricMetadata metadata, Collection data) { - this(false, metadata, data); + public HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this( + classicBuckets, + CLASSIC_HISTOGRAM, + 0, + 0, + NativeHistogramBuckets.EMPTY, + NativeHistogramBuckets.EMPTY, + sum, + labels, + exemplars, + createdTimestampMillis, + 0L); } /** - * Use this with the first parameter {@code true} to create a snapshot of a Gauge Histogram. - * The data model for Gauge Histograms is the same as for regular histograms, except that bucket values - * are semantically gauges and not counters. - * See openmetrics.io for more info on Gauge Histograms. + * Constructor for native histograms (as opposed to classic histograms). + * + *

      To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link HistogramSnapshot#builder()}. + * + * @param nativeSchema number in [-4, 8]. See Prometheus + * client_model metrics.proto. + * @param nativeZeroCount number of observed zero values (zero is special because there is no + * histogram bucket for zero values). + * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as + * zero. This is to avoid creating a large number of buckets if observations fluctuate + * around zero. + * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link + * NativeHistogramBuckets#EMPTY} if empty. + * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link + * NativeHistogramBuckets#EMPTY} if empty. + * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the + * time series (this specific set of labels) was created (or reset to zero). It's optional. + * Use {@code 0L} if there is no created timestamp. */ - public HistogramSnapshot(boolean isGaugeHistogram, MetricMetadata metadata, Collection data) { - super(metadata, data); - this.gaugeHistogram = isGaugeHistogram; + public HistogramDataPointSnapshot( + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this( + ClassicHistogramBuckets.EMPTY, + nativeSchema, + nativeZeroCount, + nativeZeroThreshold, + nativeBucketsForPositiveValues, + nativeBucketsForNegativeValues, + sum, + labels, + exemplars, + createdTimestampMillis, + 0L); } - public boolean isGaugeHistogram() { - return gaugeHistogram; + /** + * Constructor for a histogram with both, classic and native data. + * + *

      To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link HistogramSnapshot#builder()}. + * + * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. + * @param nativeSchema number in [-4, 8]. See Prometheus + * client_model metrics.proto. + * @param nativeZeroCount number of observed zero values (zero is special because there is no + * histogram bucket for zero values). + * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as + * zero. This is to avoid creating a large number of buckets if observations fluctuate + * around zero. + * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link + * NativeHistogramBuckets#EMPTY} if empty. + * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link + * NativeHistogramBuckets#EMPTY} if empty. + * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the + * time series (this specific set of labels) was created (or reset to zero). It's optional. + * Use {@code 0L} if there is no created timestamp. + */ + public HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this( + classicBuckets, + nativeSchema, + nativeZeroCount, + nativeZeroThreshold, + nativeBucketsForPositiveValues, + nativeBucketsForNegativeValues, + sum, + labels, + exemplars, + createdTimestampMillis, + 0L); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 HistogramDataPointSnapshot( + ClassicHistogramBuckets classicBuckets, + int nativeSchema, + long nativeZeroCount, + double nativeZeroThreshold, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues, + double sum, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis, + long scrapeTimestampMillis) { + super( + calculateCount( + classicBuckets, + nativeSchema, + nativeZeroCount, + nativeBucketsForPositiveValues, + nativeBucketsForNegativeValues), + sum, + exemplars, + labels, + createdTimestampMillis, + scrapeTimestampMillis); + this.classicBuckets = classicBuckets; + this.nativeSchema = nativeSchema; + this.nativeZeroCount = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroCount; + this.nativeZeroThreshold = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroThreshold; + this.nativeBucketsForPositiveValues = + nativeSchema == CLASSIC_HISTOGRAM + ? NativeHistogramBuckets.EMPTY + : nativeBucketsForPositiveValues; + this.nativeBucketsForNegativeValues = + nativeSchema == CLASSIC_HISTOGRAM + ? NativeHistogramBuckets.EMPTY + : nativeBucketsForNegativeValues; + validate(); } - public static final class HistogramDataPointSnapshot extends DistributionDataPointSnapshot { - - // There are two types of histograms: Classic histograms and native histograms. - // Classic histograms have a fixed set of buckets. - // Native histograms have "infinitely many" buckets with exponentially growing boundaries. - // The OpenTelemetry terminology for native histogram is "exponential histogram". - // --- - // A histogram can be a classic histogram (indicated by nativeSchema == CLASSIC_HISTOGRAM), - // or a native histogram (indicated by classicBuckets == ClassicHistogramBuckets.EMPTY), - // or both. - // --- - // A histogram that is both classic and native is great for migrating from classic histograms - // to native histograms: Old Prometheus servers can still scrape the classic histogram, while - // new Prometheus servers can scrape the native histogram. - - private final ClassicHistogramBuckets classicBuckets; // May be ClassicHistogramBuckets.EMPTY for native histograms. - private final int nativeSchema; // Number in [-4, 8]. May be CLASSIC_HISTOGRAM for classic histograms. - private final long nativeZeroCount; // only used if nativeSchema != CLASSIC_HISTOGRAM - private final double nativeZeroThreshold; // only used if nativeSchema != CLASSIC_HISTOGRAM - private final NativeHistogramBuckets nativeBucketsForPositiveValues; // only used if nativeSchema != CLASSIC_HISTOGRAM - private final NativeHistogramBuckets nativeBucketsForNegativeValues; // only used if nativeSchema != CLASSIC_HISTOGRAM - - /** - * Constructor for classic histograms (as opposed to native histograms). - *

      - * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#builder()}. - * - * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. - * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. - * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series - * (this specific set of labels) was created (or reset to zero). - * It's optional. Use {@code 0L} if there is no created timestamp. - */ - public HistogramDataPointSnapshot( - ClassicHistogramBuckets classicBuckets, - double sum, - Labels labels, - Exemplars exemplars, - long createdTimestampMillis) { - this(classicBuckets, CLASSIC_HISTOGRAM, 0, 0, NativeHistogramBuckets.EMPTY, NativeHistogramBuckets.EMPTY, sum, labels, exemplars, createdTimestampMillis, 0L); - } - - /** - * Constructor for native histograms (as opposed to classic histograms). - *

      - * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#builder()}. - * - * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. - * @param nativeZeroCount number of observed zero values (zero is special because there is no - * histogram bucket for zero values). - * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as zero. - * This is to avoid creating a large number of buckets if observations fluctuate around zero. - * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. - * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. - * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. - * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series - * (this specific set of labels) was created (or reset to zero). - * It's optional. Use {@code 0L} if there is no created timestamp. - */ - public HistogramDataPointSnapshot( - int nativeSchema, - long nativeZeroCount, - double nativeZeroThreshold, - NativeHistogramBuckets nativeBucketsForPositiveValues, - NativeHistogramBuckets nativeBucketsForNegativeValues, - double sum, - Labels labels, - Exemplars exemplars, - long createdTimestampMillis) { - this(ClassicHistogramBuckets.EMPTY, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, 0L); + private static long calculateCount( + ClassicHistogramBuckets classicBuckets, + int nativeSchema, + long nativeZeroCount, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues) { + if (classicBuckets.isEmpty()) { + // This is a native histogram + return calculateNativeCount( + nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); + } else if (nativeSchema == CLASSIC_HISTOGRAM) { + // This is a classic histogram + return calculateClassicCount(classicBuckets); + } else { + // This is both, a native and a classic histogram. Count should be the same for both. + long classicCount = calculateClassicCount(classicBuckets); + long nativeCount = + calculateNativeCount( + nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); + if (classicCount != nativeCount) { + throw new IllegalArgumentException( + "Inconsistent observation count: If a histogram has both classic and native data the observation count must be the same. Classic count is " + + classicCount + + " but native count is " + + nativeCount + + "."); } + return classicCount; + } + } - /** - * Constructor for a histogram with both, classic and native data. - *

      - * To create a new {@link HistogramDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link HistogramSnapshot#builder()}. - * - * @param classicBuckets required. Must not be empty. Must at least contain the +Inf bucket. - * @param nativeSchema number in [-4, 8]. See Prometheus client_model metrics.proto. - * @param nativeZeroCount number of observed zero values (zero is special because there is no - * histogram bucket for zero values). - * @param nativeZeroThreshold observations in [-zeroThreshold, +zeroThreshold] are treated as zero. - * This is to avoid creating a large number of buckets if observations fluctuate around zero. - * @param nativeBucketsForPositiveValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. - * @param nativeBucketsForNegativeValues must not be {@code null}. Use {@link NativeHistogramBuckets#EMPTY} if empty. - * @param sum sum of all observed values. Optional, use {@link Double#NaN} if not available. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplars must not be null. Use {@link Exemplars#EMPTY} if there are no Exemplars. - * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when the time series - * (this specific set of labels) was created (or reset to zero). - * It's optional. Use {@code 0L} if there is no created timestamp. - */ - public HistogramDataPointSnapshot( - ClassicHistogramBuckets classicBuckets, - int nativeSchema, - long nativeZeroCount, - double nativeZeroThreshold, - NativeHistogramBuckets nativeBucketsForPositiveValues, - NativeHistogramBuckets nativeBucketsForNegativeValues, - double sum, - Labels labels, - Exemplars exemplars, - long createdTimestampMillis) { - this(classicBuckets, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, 0L); - } + private static long calculateClassicCount(ClassicHistogramBuckets classicBuckets) { + long count = 0; + for (int i = 0; i < classicBuckets.size(); i++) { + count += classicBuckets.getCount(i); + } + return count; + } - /** - * 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 HistogramDataPointSnapshot( - ClassicHistogramBuckets classicBuckets, - int nativeSchema, - long nativeZeroCount, - double nativeZeroThreshold, - NativeHistogramBuckets nativeBucketsForPositiveValues, - NativeHistogramBuckets nativeBucketsForNegativeValues, - double sum, - Labels labels, - Exemplars exemplars, - long createdTimestampMillis, - long scrapeTimestampMillis) { - super(calculateCount(classicBuckets, nativeSchema, nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues), sum, exemplars, labels, createdTimestampMillis, scrapeTimestampMillis); - this.classicBuckets = classicBuckets; - this.nativeSchema = nativeSchema; - this.nativeZeroCount = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroCount; - this.nativeZeroThreshold = nativeSchema == CLASSIC_HISTOGRAM ? 0 : nativeZeroThreshold; - this.nativeBucketsForPositiveValues = nativeSchema == CLASSIC_HISTOGRAM ? NativeHistogramBuckets.EMPTY : nativeBucketsForPositiveValues; - this.nativeBucketsForNegativeValues = nativeSchema == CLASSIC_HISTOGRAM ? NativeHistogramBuckets.EMPTY : nativeBucketsForNegativeValues; - validate(); - } + private static long calculateNativeCount( + long nativeZeroCount, + NativeHistogramBuckets nativeBucketsForPositiveValues, + NativeHistogramBuckets nativeBucketsForNegativeValues) { + long count = nativeZeroCount; + for (int i = 0; i < nativeBucketsForNegativeValues.size(); i++) { + count += nativeBucketsForNegativeValues.getCount(i); + } + for (int i = 0; i < nativeBucketsForPositiveValues.size(); i++) { + count += nativeBucketsForPositiveValues.getCount(i); + } + return count; + } - private static long calculateCount(ClassicHistogramBuckets classicBuckets, int nativeSchema, long nativeZeroCount, NativeHistogramBuckets nativeBucketsForPositiveValues, NativeHistogramBuckets nativeBucketsForNegativeValues) { - if (classicBuckets.isEmpty()) { - // This is a native histogram - return calculateNativeCount(nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); - } else if (nativeSchema == CLASSIC_HISTOGRAM) { - // This is a classic histogram - return calculateClassicCount(classicBuckets); - } else { - // This is both, a native and a classic histogram. Count should be the same for both. - long classicCount = calculateClassicCount(classicBuckets); - long nativeCount = calculateNativeCount(nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); - if (classicCount != nativeCount) { - throw new IllegalArgumentException("Inconsistent observation count: If a histogram has both classic and native data the observation count must be the same. Classic count is " + classicCount + " but native count is " + nativeCount + "."); - } - return classicCount; - } - } + public boolean hasClassicHistogramData() { + return !classicBuckets.isEmpty(); + } - private static long calculateClassicCount(ClassicHistogramBuckets classicBuckets) { - long count = 0; - for (int i = 0; i < classicBuckets.size(); i++) { - count += classicBuckets.getCount(i); - } - return count; - } + public boolean hasNativeHistogramData() { + return nativeSchema != CLASSIC_HISTOGRAM; + } - private static long calculateNativeCount(long nativeZeroCount, NativeHistogramBuckets nativeBucketsForPositiveValues, NativeHistogramBuckets nativeBucketsForNegativeValues) { - long count = nativeZeroCount; - for (int i = 0; i < nativeBucketsForNegativeValues.size(); i++) { - count += nativeBucketsForNegativeValues.getCount(i); - } - for (int i = 0; i < nativeBucketsForPositiveValues.size(); i++) { - count += nativeBucketsForPositiveValues.getCount(i); - } - return count; - } + /** Will return garbage if {@link #hasClassicHistogramData()} is {@code false}. */ + public ClassicHistogramBuckets getClassicBuckets() { + return classicBuckets; + } - public boolean hasClassicHistogramData() { - return !classicBuckets.isEmpty(); - } + /** + * The schema defines the scale of the native histogram, i.g. the granularity of the buckets. + * Current supported values are -4 <= schema <= 8. See {@link NativeHistogramBuckets} for + * more info. This will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public int getNativeSchema() { + return nativeSchema; + } - public boolean hasNativeHistogramData() { - return nativeSchema != CLASSIC_HISTOGRAM; - } + /** + * Number of observed zero values. Will return garbage if {@link #hasNativeHistogramData()} is + * {@code false}. + */ + public long getNativeZeroCount() { + return nativeZeroCount; + } - /** - * Will return garbage if {@link #hasClassicHistogramData()} is {@code false}. - */ - public ClassicHistogramBuckets getClassicBuckets() { - return classicBuckets; - } + /** + * All observations in [-nativeZeroThreshold; +nativeZeroThreshold] are treated as zero. This is + * useful to avoid creation of a large number of buckets if observations fluctuate around zero. + * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. + */ + public double getNativeZeroThreshold() { + return nativeZeroThreshold; + } - /** - * The schema defines the scale of the native histogram, i.g. the granularity of the buckets. - * Current supported values are -4 <= schema <= 8. - * See {@link NativeHistogramBuckets} for more info. - * This will return garbage if {@link #hasNativeHistogramData()} is {@code false}. - */ - public int getNativeSchema() { - return nativeSchema; - } + /** Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. */ + public NativeHistogramBuckets getNativeBucketsForPositiveValues() { + return nativeBucketsForPositiveValues; + } - /** - * Number of observed zero values. - * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. - */ - public long getNativeZeroCount() { - return nativeZeroCount; - } + /** Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. */ + public NativeHistogramBuckets getNativeBucketsForNegativeValues() { + return nativeBucketsForNegativeValues; + } - /** - * All observations in [-nativeZeroThreshold; +nativeZeroThreshold] are treated as zero. - * This is useful to avoid creation of a large number of buckets if observations fluctuate around zero. - * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. - */ - public double getNativeZeroThreshold() { - return nativeZeroThreshold; + private void validate() { + for (Label label : getLabels()) { + if (label.getName().equals("le")) { + throw new IllegalArgumentException("le is a reserved label name for histograms"); } - - /** - * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. - */ - public NativeHistogramBuckets getNativeBucketsForPositiveValues() { - return nativeBucketsForPositiveValues; + } + if (nativeSchema == CLASSIC_HISTOGRAM && classicBuckets.isEmpty()) { + throw new IllegalArgumentException( + "Histogram buckets cannot be empty, must at least have the +Inf bucket."); + } + if (nativeSchema != CLASSIC_HISTOGRAM) { + if (nativeSchema < -4 || nativeSchema > 8) { + throw new IllegalArgumentException( + nativeSchema + ": illegal schema. Expecting number in [-4, 8]."); } - - /** - * Will return garbage if {@link #hasNativeHistogramData()} is {@code false}. - */ - public NativeHistogramBuckets getNativeBucketsForNegativeValues() { - return nativeBucketsForNegativeValues; + if (nativeZeroCount < 0) { + throw new IllegalArgumentException( + nativeZeroCount + ": nativeZeroCount cannot be negative"); } - - private void validate() { - for (Label label : getLabels()) { - if (label.getName().equals("le")) { - throw new IllegalArgumentException("le is a reserved label name for histograms"); - } - } - if (nativeSchema == CLASSIC_HISTOGRAM && classicBuckets.isEmpty()) { - throw new IllegalArgumentException("Histogram buckets cannot be empty, must at least have the +Inf bucket."); - } - if (nativeSchema != CLASSIC_HISTOGRAM) { - if (nativeSchema < -4 || nativeSchema > 8) { - throw new IllegalArgumentException(nativeSchema + ": illegal schema. Expecting number in [-4, 8]."); - } - if (nativeZeroCount < 0) { - throw new IllegalArgumentException(nativeZeroCount + ": nativeZeroCount cannot be negative"); - } - if (Double.isNaN(nativeZeroThreshold) || nativeZeroThreshold < 0) { - throw new IllegalArgumentException(nativeZeroThreshold + ": illegal nativeZeroThreshold. Must be >= 0."); - } - } + if (Double.isNaN(nativeZeroThreshold) || nativeZeroThreshold < 0) { + throw new IllegalArgumentException( + nativeZeroThreshold + ": illegal nativeZeroThreshold. Must be >= 0."); } + } + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder extends DistributionDataPointSnapshot.Builder { - - private ClassicHistogramBuckets classicHistogramBuckets = ClassicHistogramBuckets.EMPTY; - private int nativeSchema = CLASSIC_HISTOGRAM; - private long nativeZeroCount = 0; - private double nativeZeroThreshold = 0; - private NativeHistogramBuckets nativeBucketsForPositiveValues = NativeHistogramBuckets.EMPTY; - private NativeHistogramBuckets nativeBucketsForNegativeValues = NativeHistogramBuckets.EMPTY; - - private Builder() { - } - - @Override - protected Builder self() { - return this; - } - - public Builder classicHistogramBuckets(ClassicHistogramBuckets classicBuckets) { - this.classicHistogramBuckets = classicBuckets; - return this; - } - - public Builder nativeSchema(int nativeSchema) { - this.nativeSchema = nativeSchema; - return this; - } - - public Builder nativeZeroCount(long zeroCount) { - this.nativeZeroCount = zeroCount; - return this; - } - - public Builder nativeZeroThreshold(double zeroThreshold) { - this.nativeZeroThreshold = zeroThreshold; - return this; - } - - public Builder nativeBucketsForPositiveValues(NativeHistogramBuckets bucketsForPositiveValues) { - this.nativeBucketsForPositiveValues = bucketsForPositiveValues; - return this; - } - - public Builder nativeBucketsForNegativeValues(NativeHistogramBuckets bucketsForNegativeValues) { - this.nativeBucketsForNegativeValues = bucketsForNegativeValues; - return this; - } - - public HistogramDataPointSnapshot build() { - if (nativeSchema == CLASSIC_HISTOGRAM && classicHistogramBuckets.isEmpty()) { - throw new IllegalArgumentException("One of nativeSchema and classicHistogramBuckets is required."); - } - return new HistogramDataPointSnapshot(classicHistogramBuckets, nativeSchema, nativeZeroCount, nativeZeroThreshold, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues, sum, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); - } + public static class Builder extends DistributionDataPointSnapshot.Builder { + + private ClassicHistogramBuckets classicHistogramBuckets = ClassicHistogramBuckets.EMPTY; + private int nativeSchema = CLASSIC_HISTOGRAM; + private long nativeZeroCount = 0; + private double nativeZeroThreshold = 0; + private NativeHistogramBuckets nativeBucketsForPositiveValues = NativeHistogramBuckets.EMPTY; + private NativeHistogramBuckets nativeBucketsForNegativeValues = NativeHistogramBuckets.EMPTY; + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + public Builder classicHistogramBuckets(ClassicHistogramBuckets classicBuckets) { + this.classicHistogramBuckets = classicBuckets; + return this; + } + + public Builder nativeSchema(int nativeSchema) { + this.nativeSchema = nativeSchema; + return this; + } + + public Builder nativeZeroCount(long zeroCount) { + this.nativeZeroCount = zeroCount; + return this; + } + + public Builder nativeZeroThreshold(double zeroThreshold) { + this.nativeZeroThreshold = zeroThreshold; + return this; + } + + public Builder nativeBucketsForPositiveValues( + NativeHistogramBuckets bucketsForPositiveValues) { + this.nativeBucketsForPositiveValues = bucketsForPositiveValues; + return this; + } + + public Builder nativeBucketsForNegativeValues( + NativeHistogramBuckets bucketsForNegativeValues) { + this.nativeBucketsForNegativeValues = bucketsForNegativeValues; + return this; + } + + public HistogramDataPointSnapshot build() { + if (nativeSchema == CLASSIC_HISTOGRAM && classicHistogramBuckets.isEmpty()) { + throw new IllegalArgumentException( + "One of nativeSchema and classicHistogramBuckets is required."); } + return new HistogramDataPointSnapshot( + classicHistogramBuckets, + nativeSchema, + nativeZeroCount, + nativeZeroThreshold, + nativeBucketsForPositiveValues, + nativeBucketsForNegativeValues, + sum, + labels, + exemplars, + createdTimestampMillis, + scrapeTimestampMillis); + } } + } - public static Builder builder() { - return new Builder(); - } + public static Builder builder() { + return new Builder(); + } - public static class Builder extends MetricSnapshot.Builder { + public static class Builder extends MetricSnapshot.Builder { - private final List dataPoints = new ArrayList<>(); - private boolean isGaugeHistogram = false; + private final List dataPoints = new ArrayList<>(); + private boolean isGaugeHistogram = false; - private Builder() { - } + private Builder() {} - /** - * Add a data point. Call multiple times to add multiple data points. - */ - public Builder dataPoint(HistogramDataPointSnapshot dataPoint) { - dataPoints.add(dataPoint); - return this; - } + /** Add a data point. Call multiple times to add multiple data points. */ + public Builder dataPoint(HistogramDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); + return this; + } - /** - * {@code true} indicates that this histogram is a gauge histogram. - * The data model for gauge histograms is the same as for regular histograms, - * except that bucket values are semantically gauges and not counters. - * See openmetrics.io for more info on gauge histograms. - */ - public Builder gaugeHistogram(boolean isGaugeHistogram) { - this.isGaugeHistogram = isGaugeHistogram; - return this; - } + /** + * {@code true} indicates that this histogram is a gauge histogram. The data model for gauge + * histograms is the same as for regular histograms, except that bucket values are semantically + * gauges and not counters. See openmetrics.io for more + * info on gauge histograms. + */ + public Builder gaugeHistogram(boolean isGaugeHistogram) { + this.isGaugeHistogram = isGaugeHistogram; + return this; + } - @Override - public HistogramSnapshot build() { - return new HistogramSnapshot(isGaugeHistogram, buildMetadata(), dataPoints); - } + @Override + public HistogramSnapshot build() { + return new HistogramSnapshot(isGaugeHistogram, buildMetadata(), dataPoints); + } - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java index 5d3890c0e..c7f180d9f 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -4,105 +4,98 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of an Info metric. - */ +/** Immutable snapshot of an Info metric. */ public final class InfoSnapshot extends MetricSnapshot { + /** + * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use the + * builder with {@link InfoSnapshot#builder()}. + * + * @param metadata the metric name in metadata must not include the {@code _info} suffix. See + * {@link MetricMetadata} for more naming conventions. The metadata must not have a unit. + * @param data the constructor will create a sorted copy of the collection. + */ + public InfoSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + if (metadata.hasUnit()) { + throw new IllegalArgumentException("An Info metric cannot have a unit."); + } + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static class InfoDataPointSnapshot extends DataPointSnapshot { + /** - * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use - * the builder with {@link InfoSnapshot#builder()}. + * To create a new {@link InfoDataPointSnapshot}, you can either call the constructor directly + * or use the Builder with {@link InfoDataPointSnapshot#builder()}. * - * @param metadata the metric name in metadata must not include the {@code _info} suffix. - * See {@link MetricMetadata} for more naming conventions. - * The metadata must not have a unit. - * @param data the constructor will create a sorted copy of the collection. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. */ - public InfoSnapshot(MetricMetadata metadata, Collection data) { - super(metadata, data); - if (metadata.hasUnit()) { - throw new IllegalArgumentException("An Info metric cannot have a unit."); - } + public InfoDataPointSnapshot(Labels labels) { + this(labels, 0L); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); } - public static class InfoDataPointSnapshot extends DataPointSnapshot { - - /** - * To create a new {@link InfoDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link InfoDataPointSnapshot#builder()}. - * - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - */ - public InfoDataPointSnapshot(Labels labels) { - this(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 InfoDataPointSnapshot(Labels labels, long scrapeTimestampMillis) { - super(labels, 0L, scrapeTimestampMillis); - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder extends DataPointSnapshot.Builder { - - private Builder() { - } - - public InfoDataPointSnapshot build() { - return new InfoDataPointSnapshot(labels, scrapeTimestampMillis); - } - - @Override - protected Builder self() { - return this; - } - } + public static Builder builder() { + return new Builder(); } - public static Builder builder() { - return new Builder(); + public static class Builder extends DataPointSnapshot.Builder { + + private Builder() {} + + public InfoDataPointSnapshot build() { + return new InfoDataPointSnapshot(labels, scrapeTimestampMillis); + } + + @Override + protected Builder self() { + return this; + } } + } - 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 for adding multiple data points. - */ - public Builder dataPoint(InfoDataPointSnapshot dataPoint) { - dataPoints.add(dataPoint); - return this; - } + private Builder() {} - @Override - public Builder unit(Unit unit) { - throw new IllegalArgumentException("Info metric cannot have a unit."); - } + /** Add a data point. Call multiple times for adding multiple data points. */ + public Builder dataPoint(InfoDataPointSnapshot dataPoint) { + dataPoints.add(dataPoint); + return this; + } - @Override - public InfoSnapshot build() { - return new InfoSnapshot(buildMetadata(), dataPoints); - } + @Override + public Builder unit(Unit unit) { + throw new IllegalArgumentException("Info metric cannot have a unit."); + } - @Override - protected Builder self() { - return this; - } + @Override + public InfoSnapshot build() { + return new InfoSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java index 674eafff8..f14af41ce 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java @@ -2,51 +2,46 @@ import java.util.Objects; -/** - * Utility for iterating over {@link Labels}. - */ +/** Utility for iterating over {@link Labels}. */ public final class Label implements Comparable

      - * For example, the name for a counter "http_requests_total" is "http_requests". - * The name of an info called "jvm_info" is "jvm". - *

      - * We allow dots in label names. Dots are automatically replaced with underscores in Prometheus - * exposition formats. However, if metrics from this library are exposed in OpenTelemetry - * format dots are retained. - *

      - * See {@link #MetricMetadata(String, String, Unit)} for more info on naming conventions. - */ - private final String name; + /** + * Name without suffix. + * + *

      For example, the name for a counter "http_requests_total" is "http_requests". The name of an + * info called "jvm_info" is "jvm". + * + *

      We allow dots in label names. Dots are automatically replaced with underscores in Prometheus + * exposition formats. However, if metrics from this library are exposed in OpenTelemetry format + * dots are retained. + * + *

      See {@link #MetricMetadata(String, String, Unit)} for more info on naming conventions. + */ + private final String name; - /** - * Same as name, except if name contains dots, then the prometheusName is {@code name.replace(".", "_")}. - */ - private final String prometheusName; + /** + * Same as name, except if name contains dots, then the prometheusName is {@code name.replace(".", + * "_")}. + */ + private final String prometheusName; - /** - * optional, may be {@code null}. - */ - private final String help; + /** optional, may be {@code null}. */ + private final String help; - /** - * optional, may be {@code null}. - */ - private final Unit unit; + /** optional, may be {@code null}. */ + private final Unit unit; - /** - * See {@link #MetricMetadata(String, String, Unit)} - */ - public MetricMetadata(String name) { - this(name, null, null); - } + /** See {@link #MetricMetadata(String, String, Unit)} */ + public MetricMetadata(String name) { + this(name, null, null); + } - /** - * See {@link #MetricMetadata(String, String, Unit)} - */ - public MetricMetadata(String name, String help) { - this(name, help, null); - } + /** See {@link #MetricMetadata(String, String, Unit)} */ + public MetricMetadata(String name, String help) { + this(name, help, null); + } - /** - * Constructor. - * @param name must not be {@code null}. {@link PrometheusNaming#isValidMetricName(String) isValidMetricName(name)} - * must be {@code true}. Use {@link PrometheusNaming#sanitizeMetricName(String)} to convert arbitrary - * strings into valid names. - * @param help optional. May be {@code null}. - * @param unit optional. May be {@code null}. - */ - public MetricMetadata(String name, String help, Unit unit) { - this.name = name; - this.help = help; - this.unit = unit; - validate(); - this.prometheusName = name.contains(".") ? PrometheusNaming.prometheusName(name) : name; - } + /** + * Constructor. + * + * @param name must not be {@code null}. {@link PrometheusNaming#isValidMetricName(String) + * isValidMetricName(name)} must be {@code true}. Use {@link + * PrometheusNaming#sanitizeMetricName(String)} to convert arbitrary strings into valid names. + * @param help optional. May be {@code null}. + * @param unit optional. May be {@code null}. + */ + public MetricMetadata(String name, String help, Unit unit) { + this.name = name; + this.help = help; + this.unit = unit; + validate(); + this.prometheusName = name.contains(".") ? PrometheusNaming.prometheusName(name) : name; + } - /** - * The name does not include the {@code _total} suffix for counter metrics - * or the {@code _info} suffix for Info metrics. - *

      - * The name may contain dots. Use {@link #getPrometheusName()} to get the name in Prometheus format, - * i.e. with dots replaced by underscores. - */ - public String getName() { - return name; - } + /** + * The name does not include the {@code _total} suffix for counter metrics or the {@code _info} + * suffix for Info metrics. + * + *

      The name may contain dots. Use {@link #getPrometheusName()} to get the name in Prometheus + * format, i.e. with dots replaced by underscores. + */ + public String getName() { + return name; + } - /** - * Same as {@link #getName()} but with dots replaced by underscores. - *

      - * This is used by Prometheus exposition formats. - */ - public String getPrometheusName() { - return prometheusName; - } + /** + * Same as {@link #getName()} but with dots replaced by underscores. + * + *

      This is used by Prometheus exposition formats. + */ + public String getPrometheusName() { + return prometheusName; + } - public String getHelp() { - return help; - } + public String getHelp() { + return help; + } - public boolean hasUnit() { - return unit != null; - } + public boolean hasUnit() { + return unit != null; + } - public Unit getUnit() { - return unit; - } + public Unit getUnit() { + return unit; + } - private void validate() { - if (name == null) { - throw new IllegalArgumentException("Missing required field: name is null"); - } - String error = PrometheusNaming.validateMetricName(name); - if (error != null) { - throw new IllegalArgumentException("'" + name + "': Illegal metric name. " + error - + " Call " + PrometheusNaming.class.getSimpleName() + ".sanitizeMetricName(name) to avoid this error."); - } - if (hasUnit()) { - if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { - throw new IllegalArgumentException("'" + name + "': Illegal metric name. If the unit is non-null, the name must end with the unit: _" + unit + "." - + " Call " + PrometheusNaming.class.getSimpleName() + ".sanitizeMetricName(name, unit) to avoid this error."); - } - } + private void validate() { + if (name == null) { + throw new IllegalArgumentException("Missing required field: name is null"); + } + String error = PrometheusNaming.validateMetricName(name); + if (error != null) { + throw new IllegalArgumentException( + "'" + + name + + "': Illegal metric name. " + + error + + " Call " + + PrometheusNaming.class.getSimpleName() + + ".sanitizeMetricName(name) to avoid this error."); + } + if (hasUnit()) { + if (!name.endsWith("_" + unit) && !name.endsWith("." + unit)) { + throw new IllegalArgumentException( + "'" + + name + + "': Illegal metric name. If the unit is non-null, the name must end with the unit: _" + + unit + + "." + + " Call " + + PrometheusNaming.class.getSimpleName() + + ".sanitizeMetricName(name, unit) to avoid this error."); + } } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java index dcf41bc09..d44e54ff9 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -7,81 +7,81 @@ import java.util.Comparator; import java.util.List; -/** - * Base class for metric snapshots. - */ +/** Base class for metric snapshots. */ public abstract class MetricSnapshot { - private final MetricMetadata metadata; - protected final List dataPoints; + private final MetricMetadata metadata; + protected final List dataPoints; - protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... dataPoints) { - this(metadata, Arrays.asList(dataPoints)); - } + protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... dataPoints) { + this(metadata, Arrays.asList(dataPoints)); + } - protected MetricSnapshot(MetricMetadata metadata, Collection dataPoints) { - if (metadata == null) { - throw new NullPointerException("metadata"); - } - if (dataPoints == null) { - throw new NullPointerException("dataPoints"); - } - this.metadata = metadata; - List dataCopy = new ArrayList<>(dataPoints); - dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); - this.dataPoints = Collections.unmodifiableList(dataCopy); - validateLabels(); + protected MetricSnapshot( + MetricMetadata metadata, Collection dataPoints) { + if (metadata == null) { + throw new NullPointerException("metadata"); } - - public MetricMetadata getMetadata() { - return metadata; + if (dataPoints == null) { + throw new NullPointerException("dataPoints"); } - - public abstract List getDataPoints(); - - protected void validateLabels() { - // Verify that labels are unique (the same set of names/values must not be used multiple times for the same metric). - for (int i = 0; i < dataPoints.size() - 1; i++) { - if (dataPoints.get(i).getLabels().equals(dataPoints.get(i + 1).getLabels())) { - throw new DuplicateLabelsException(metadata, dataPoints.get(i).getLabels()); - } - } - // Should we verify that all entries in data have the same label names? - // No. They should have the same label names, but according to OpenMetrics this is not a MUST. + this.metadata = metadata; + List dataCopy = new ArrayList<>(dataPoints); + dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); + this.dataPoints = Collections.unmodifiableList(dataCopy); + validateLabels(); + } + + public MetricMetadata getMetadata() { + return metadata; + } + + public abstract List getDataPoints(); + + protected void validateLabels() { + // Verify that labels are unique (the same set of names/values must not be used multiple times + // for the same metric). + for (int i = 0; i < dataPoints.size() - 1; i++) { + if (dataPoints.get(i).getLabels().equals(dataPoints.get(i + 1).getLabels())) { + throw new DuplicateLabelsException(metadata, dataPoints.get(i).getLabels()); + } + } + // Should we verify that all entries in data have the same label names? + // No. They should have the same label names, but according to OpenMetrics this is not a MUST. + } + + public abstract static class Builder> { + + private String name; + private String help; + private Unit unit; + + /** + * The name is required. If the name is missing or invalid, {@code build()} will throw an {@link + * IllegalArgumentException}. See {@link PrometheusNaming#isValidMetricName(String)} for info on + * valid metric names. + */ + public T name(String name) { + this.name = name; + return self(); } - public static abstract class Builder> { - - private String name; - private String help; - private Unit unit; - - /** - * The name is required. - * If the name is missing or invalid, {@code build()} will throw an {@link IllegalArgumentException}. - * See {@link PrometheusNaming#isValidMetricName(String)} for info on valid metric names. - */ - public T name(String name) { - this.name = name; - return self(); - } - - public T help(String help) { - this.help = help; - return self(); - } - - public T unit(Unit unit) { - this.unit = unit; - return self(); - } + public T help(String help) { + this.help = help; + return self(); + } - public abstract MetricSnapshot build(); + public T unit(Unit unit) { + this.unit = unit; + return self(); + } - protected MetricMetadata buildMetadata() { - return new MetricMetadata(name, help, unit); - } + public abstract MetricSnapshot build(); - protected abstract T self(); + protected MetricMetadata buildMetadata() { + return new MetricMetadata(name, help, unit); } + + protected abstract T self(); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java index a4865acb9..ecee897e4 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -1,5 +1,9 @@ package io.prometheus.metrics.model.snapshots; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; +import static java.util.Collections.unmodifiableList; +import static java.util.Comparator.comparing; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -9,97 +13,90 @@ import java.util.Set; import java.util.stream.Stream; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; -import static java.util.Collections.unmodifiableList; -import static java.util.Comparator.comparing; - -/** - * Immutable list of metric snapshots. - */ +/** Immutable list of metric snapshots. */ public class MetricSnapshots implements Iterable { - private final List snapshots; - - /** - * See {@link #MetricSnapshots(Collection)} - */ - public MetricSnapshots(MetricSnapshot... snapshots) { - this(Arrays.asList(snapshots)); + private final List snapshots; + + /** See {@link #MetricSnapshots(Collection)} */ + public MetricSnapshots(MetricSnapshot... snapshots) { + this(Arrays.asList(snapshots)); + } + + /** + * To create MetricSnapshots, you can either call the constructor directly or use {@link + * #builder()}. + * + * @param snapshots the constructor creates a sorted copy of snapshots. + * @throws IllegalArgumentException if snapshots contains duplicate metric names. To avoid + * duplicate metric names use {@link #builder()} and check {@link + * Builder#containsMetricName(String)} before calling {@link + * Builder#metricSnapshot(MetricSnapshot)}. + */ + public MetricSnapshots(Collection snapshots) { + List list = new ArrayList<>(snapshots); + list.sort(comparing(s -> s.getMetadata().getPrometheusName())); + for (int i = 0; i < snapshots.size() - 1; i++) { + if (list.get(i) + .getMetadata() + .getPrometheusName() + .equals(list.get(i + 1).getMetadata().getPrometheusName())) { + throw new IllegalArgumentException( + list.get(i).getMetadata().getPrometheusName() + ": duplicate metric name"); + } } + this.snapshots = unmodifiableList(list); + } - /** - * To create MetricSnapshots, you can either call the constructor directly - * or use {@link #builder()}. - * - * @param snapshots the constructor creates a sorted copy of snapshots. - * @throws IllegalArgumentException if snapshots contains duplicate metric names. - * To avoid duplicate metric names use {@link #builder()} and check - * {@link Builder#containsMetricName(String)} before calling - * {@link Builder#metricSnapshot(MetricSnapshot)}. - */ - public MetricSnapshots(Collection snapshots) { - List list = new ArrayList<>(snapshots); - list.sort(comparing(s -> s.getMetadata().getPrometheusName())); - for (int i = 0; i < snapshots.size() - 1; i++) { - if (list.get(i).getMetadata().getPrometheusName().equals(list.get(i + 1).getMetadata().getPrometheusName())) { - throw new IllegalArgumentException(list.get(i).getMetadata().getPrometheusName() + ": duplicate metric name"); - } - } - this.snapshots = unmodifiableList(list); - } + public static MetricSnapshots of(MetricSnapshot... snapshots) { + return new MetricSnapshots(snapshots); + } - public static MetricSnapshots of(MetricSnapshot... snapshots) { - return new MetricSnapshots(snapshots); - } + @Override + public Iterator iterator() { + return snapshots.iterator(); + } - @Override - public Iterator iterator() { - return snapshots.iterator(); - } + public int size() { + return snapshots.size(); + } - public int size() { - return snapshots.size(); - } + public MetricSnapshot get(int i) { + return snapshots.get(i); + } - public MetricSnapshot get(int i) { - return snapshots.get(i); - } + public Stream stream() { + return snapshots.stream(); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final List snapshots = new ArrayList<>(); + private final Set prometheusNames = new HashSet<>(); + + private Builder() {} - public Stream stream() { - return snapshots.stream(); + public boolean containsMetricName(String name) { + if (name == null) { + return false; + } + String prometheusName = prometheusName(name); + return prometheusNames.contains(prometheusName); } - public static Builder builder() { - return new Builder(); + /** Add a metric snapshot. Call multiple times to add multiple metric snapshots. */ + public Builder metricSnapshot(MetricSnapshot snapshot) { + snapshots.add(snapshot); + prometheusNames.add(snapshot.getMetadata().getPrometheusName()); + return this; } - public static class Builder { - - private final List snapshots = new ArrayList<>(); - private final Set prometheusNames = new HashSet<>(); - - private Builder() { - } - - public boolean containsMetricName(String name) { - if (name == null) { - return false; - } - String prometheusName = prometheusName(name); - return prometheusNames.contains(prometheusName); - } - - /** - * Add a metric snapshot. Call multiple times to add multiple metric snapshots. - */ - public Builder metricSnapshot(MetricSnapshot snapshot) { - snapshots.add(snapshot); - prometheusNames.add(snapshot.getMetadata().getPrometheusName()); - return this; - } - - public MetricSnapshots build() { - return new MetricSnapshots(snapshots); - } + public MetricSnapshots build() { + return new MetricSnapshots(snapshots); } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java index e7af0e6e8..9e58af18f 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucket.java @@ -1,26 +1,22 @@ package io.prometheus.metrics.model.snapshots; -/** - * For iterating over {@link NativeHistogramBuckets}. - */ +/** For iterating over {@link NativeHistogramBuckets}. */ public class NativeHistogramBucket { - private final int bucketIndex; - private final long count; + private final int bucketIndex; + private final long count; - public NativeHistogramBucket(int bucketIndex, long count) { - this.bucketIndex = bucketIndex; - this.count = count; - } + public NativeHistogramBucket(int bucketIndex, long count) { + this.bucketIndex = bucketIndex; + this.count = count; + } - /** - * See {@link NativeHistogramBuckets} for info on native bucket indexes. - */ - public int getBucketIndex() { - return bucketIndex; - } + /** See {@link NativeHistogramBuckets} for info on native bucket indexes. */ + public int getBucketIndex() { + return bucketIndex; + } - public long getCount() { - return count; - } + public long getCount() { + return count; + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java index e4f722168..3b1214364 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/NativeHistogramBuckets.java @@ -9,9 +9,10 @@ /** * Immutable representation of native histogram buckets. - *

      - * The bucket index defines the boundaries of the bucket, - * depending on the histogram's {@link HistogramSnapshot.HistogramDataPointSnapshot#getNativeSchema() schema}. + * + *

      The bucket index defines the boundaries of the bucket, depending on the histogram's {@link + * HistogramSnapshot.HistogramDataPointSnapshot#getNativeSchema() schema}. + * *

        *     base = 2^(2^-schema)
        *     lower bound = base^(index - 1)
      @@ -20,143 +21,149 @@
        */
       public class NativeHistogramBuckets implements Iterable {
       
      -    public static final NativeHistogramBuckets EMPTY = new NativeHistogramBuckets(new int[]{}, new long[]{});
      -    private final int[] bucketIndexes; // sorted
      -    private final long[] counts;
      -
      -    private NativeHistogramBuckets(int[] bucketIndexes, long[] counts) {
      -        this.bucketIndexes = bucketIndexes;
      -        this.counts = counts;
      -    }
      -
      -    /**
      -     * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)}
      -     * methods, or use {@link NativeHistogramBuckets#builder()}.
      -     * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty.
      -     * @param counts must have the same length as bucketIndexes
      -     */
      -    public static NativeHistogramBuckets of(int[] bucketIndexes, long[] counts) {
      -        int[] bucketIndexesCopy = Arrays.copyOf(bucketIndexes, bucketIndexes.length);
      -        long[] countsCopy = Arrays.copyOf(counts, counts.length);
      -        sortAndValidate(bucketIndexesCopy, countsCopy);
      -        return new NativeHistogramBuckets(bucketIndexesCopy, countsCopy);
      -    }
      -
      -    /**
      -     * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static {@code of(...)}
      -     * methods, or use {@link NativeHistogramBuckets#builder()}.
      -     * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty.
      -     * @param counts must have the same size as bucketIndexes
      -     */
      -    public static NativeHistogramBuckets of(List bucketIndexes, List counts) {
      -        int[] bucketIndexesCopy = new int[bucketIndexes.size()];
      -        for (int i=0; i asList() {
      -        List result = new ArrayList<>(size());
      -        for (int i=0; i iterator() {
      -        return asList().iterator();
      +  public static final NativeHistogramBuckets EMPTY =
      +      new NativeHistogramBuckets(new int[] {}, new long[] {});
      +  private final int[] bucketIndexes; // sorted
      +  private final long[] counts;
      +
      +  private NativeHistogramBuckets(int[] bucketIndexes, long[] counts) {
      +    this.bucketIndexes = bucketIndexes;
      +    this.counts = counts;
      +  }
      +
      +  /**
      +   * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static
      +   * {@code of(...)} methods, or use {@link NativeHistogramBuckets#builder()}.
      +   *
      +   * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty.
      +   * @param counts must have the same length as bucketIndexes
      +   */
      +  public static NativeHistogramBuckets of(int[] bucketIndexes, long[] counts) {
      +    int[] bucketIndexesCopy = Arrays.copyOf(bucketIndexes, bucketIndexes.length);
      +    long[] countsCopy = Arrays.copyOf(counts, counts.length);
      +    sortAndValidate(bucketIndexesCopy, countsCopy);
      +    return new NativeHistogramBuckets(bucketIndexesCopy, countsCopy);
      +  }
      +
      +  /**
      +   * To create a new {@link NativeHistogramBuckets} instance, you can either use one of the static
      +   * {@code of(...)} methods, or use {@link NativeHistogramBuckets#builder()}.
      +   *
      +   * @param bucketIndexes see class javadoc of {@link NativeHistogramBuckets}. May be empty.
      +   * @param counts must have the same size as bucketIndexes
      +   */
      +  public static NativeHistogramBuckets of(List bucketIndexes, List counts) {
      +    int[] bucketIndexesCopy = new int[bucketIndexes.size()];
      +    for (int i = 0; i < bucketIndexes.size(); i++) {
      +      bucketIndexesCopy[i] = bucketIndexes.get(i);
           }
      -
      -    public Stream stream() {
      -        return asList().stream();
      +    long[] countsCopy = new long[counts.size()];
      +    for (int i = 0; i < counts.size(); i++) {
      +      countsCopy[i] = counts.get(i);
           }
      -
      -    public int getBucketIndex(int i) {
      -        return bucketIndexes[i];
      +    sortAndValidate(bucketIndexesCopy, countsCopy);
      +    return new NativeHistogramBuckets(bucketIndexesCopy, countsCopy);
      +  }
      +
      +  public int size() {
      +    return bucketIndexes.length;
      +  }
      +
      +  private List asList() {
      +    List result = new ArrayList<>(size());
      +    for (int i = 0; i < bucketIndexes.length; i++) {
      +      result.add(new NativeHistogramBucket(bucketIndexes[i], counts[i]));
           }
      -
      -    public long getCount(int i) {
      -        return counts[i];
      +    return Collections.unmodifiableList(result);
      +  }
      +
      +  @Override
      +  public Iterator iterator() {
      +    return asList().iterator();
      +  }
      +
      +  public Stream stream() {
      +    return asList().stream();
      +  }
      +
      +  public int getBucketIndex(int i) {
      +    return bucketIndexes[i];
      +  }
      +
      +  public long getCount(int i) {
      +    return counts[i];
      +  }
      +
      +  private static void sortAndValidate(int[] bucketIndexes, long[] counts) {
      +    if (bucketIndexes.length != counts.length) {
      +      throw new IllegalArgumentException(
      +          "bucketIndexes.length == "
      +              + bucketIndexes.length
      +              + " but counts.length == "
      +              + counts.length
      +              + ". Expected the same length.");
           }
      -
      -    private static void sortAndValidate(int[] bucketIndexes, long[] counts) {
      -        if (bucketIndexes.length != counts.length) {
      -            throw new IllegalArgumentException("bucketIndexes.length == " + bucketIndexes.length + " but counts.length == " + counts.length + ". Expected the same length.");
      -        }
      -        sort(bucketIndexes, counts);
      -        validate(bucketIndexes, counts);
      -    }
      -
      -    private static void sort(int[] bucketIndexes, long[] counts) {
      -        // Bubblesort. Should be efficient here as in most cases bucketIndexes is already sorted.
      -        int n = bucketIndexes.length;
      -        for (int i = 0; i < n - 1; i++) {
      -            for (int j = 0; j < n - i - 1; j++) {
      -                if (bucketIndexes[j] > bucketIndexes[j + 1]) {
      -                    swap(j, j+1, bucketIndexes, counts);
      -                }
      -            }
      +    sort(bucketIndexes, counts);
      +    validate(bucketIndexes, counts);
      +  }
      +
      +  private static void sort(int[] bucketIndexes, long[] counts) {
      +    // Bubblesort. Should be efficient here as in most cases bucketIndexes is already sorted.
      +    int n = bucketIndexes.length;
      +    for (int i = 0; i < n - 1; i++) {
      +      for (int j = 0; j < n - i - 1; j++) {
      +        if (bucketIndexes[j] > bucketIndexes[j + 1]) {
      +          swap(j, j + 1, bucketIndexes, counts);
               }
      +      }
           }
      -
      -    private static void swap(int i, int j, int[] bucketIndexes, long[] counts) {
      -        int tmpInt = bucketIndexes[j];
      -        bucketIndexes[j] = bucketIndexes[i];
      -        bucketIndexes[i] = tmpInt;
      -        long tmpLong = counts[j];
      -        counts[j] = counts[i];
      -        counts[i] = tmpLong;
      -    }
      -
      -    private static void validate(int[] bucketIndexes, long[] counts) {
      -        // Preconditions:
      -        // * bucketIndexes sorted
      -        // * bucketIndexes and counts have the same length
      -        for (int i=0; i 0) {
      -                if (bucketIndexes[i-1] == bucketIndexes[i]) {
      -                    throw new IllegalArgumentException("Duplicate bucket index " + bucketIndexes[i]);
      -                }
      -            }
      +  }
      +
      +  private static void swap(int i, int j, int[] bucketIndexes, long[] counts) {
      +    int tmpInt = bucketIndexes[j];
      +    bucketIndexes[j] = bucketIndexes[i];
      +    bucketIndexes[i] = tmpInt;
      +    long tmpLong = counts[j];
      +    counts[j] = counts[i];
      +    counts[i] = tmpLong;
      +  }
      +
      +  private static void validate(int[] bucketIndexes, long[] counts) {
      +    // Preconditions:
      +    // * bucketIndexes sorted
      +    // * bucketIndexes and counts have the same length
      +    for (int i = 0; i < bucketIndexes.length; i++) {
      +      if (counts[i] < 0) {
      +        throw new IllegalArgumentException("Bucket counts cannot be negative.");
      +      }
      +      if (i > 0) {
      +        if (bucketIndexes[i - 1] == bucketIndexes[i]) {
      +          throw new IllegalArgumentException("Duplicate bucket index " + bucketIndexes[i]);
               }
      +      }
           }
      +  }
       
      -    public static Builder builder() {
      -        return new Builder();
      -    }
      +  public static Builder builder() {
      +    return new Builder();
      +  }
       
      -    public static class Builder {
      +  public static class Builder {
       
      -        private final List bucketIndexes = new ArrayList<>();
      -        private final List counts = new ArrayList<>();
      +    private final List bucketIndexes = new ArrayList<>();
      +    private final List counts = new ArrayList<>();
       
      -        private Builder() {}
      +    private Builder() {}
       
      -        /**
      -         * Add a native histogram bucket. Call multiple times to add multiple buckets.
      -         */
      -        public Builder bucket(int bucketIndex, long count) {
      -            bucketIndexes.add(bucketIndex);
      -            counts.add(count);
      -            return this;
      -        }
      +    /** Add a native histogram bucket. Call multiple times to add multiple buckets. */
      +    public Builder bucket(int bucketIndex, long count) {
      +      bucketIndexes.add(bucketIndex);
      +      counts.add(count);
      +      return this;
      +    }
       
      -        public NativeHistogramBuckets build() {
      -            return NativeHistogramBuckets.of(bucketIndexes, counts);
      -        }
      +    public NativeHistogramBuckets build() {
      +      return NativeHistogramBuckets.of(bucketIndexes, counts);
           }
      +  }
       }
      diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      index 21c162632..d4f9db699 100644
      --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
      @@ -4,276 +4,280 @@
       
       /**
        * Utility for Prometheus Metric and Label naming.
      - * 

      - * Note that this library allows dots in metric and label names. Dots will automatically be replaced with underscores - * in Prometheus exposition formats. However, if metrics are exposed in OpenTelemetry format the dots are retained. + * + *

      Note that this library allows dots in metric and label names. Dots will automatically be + * replaced with underscores in Prometheus exposition formats. However, if metrics are exposed in + * OpenTelemetry format the dots are retained. */ public class PrometheusNaming { - /** - * Legal characters for metric names, including dot. - */ - private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.:][a-zA-Z0-9_.:]*$"); + /** Legal characters for metric names, including dot. */ + private static final Pattern METRIC_NAME_PATTERN = + Pattern.compile("^[a-zA-Z_.:][a-zA-Z0-9_.:]*$"); - /** - * Legal characters for label names, including dot. - */ - private static final Pattern LABEL_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.][a-zA-Z0-9_.]*$"); + /** Legal characters for label names, including dot. */ + private static final Pattern LABEL_NAME_PATTERN = Pattern.compile("^[a-zA-Z_.][a-zA-Z0-9_.]*$"); - /** - * Legal characters for unit names, including dot. - */ - private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$"); + /** Legal characters for unit names, including dot. */ + private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$"); - /** - * According to OpenMetrics {@code _count} and {@code _sum} (and {@code _gcount}, {@code _gsum}) should also be - * reserved metric name suffixes. However, popular instrumentation libraries have Gauges with names - * ending in {@code _count}. - * Examples: - *

        - *
      • Micrometer: {@code jvm_buffer_count}
      • - *
      • OpenTelemetry: {@code process_runtime_jvm_buffer_count}
      • - *
      - * We do not treat {@code _count} and {@code _sum} as reserved suffixes here for compatibility with these libraries. - * However, there is a risk of name conflict if someone creates a gauge named {@code my_data_count} and a - * histogram or summary named {@code my_data}, because the histogram or summary will implicitly have a sample - * named {@code my_data_count}. - */ - private static final String[] RESERVED_METRIC_NAME_SUFFIXES = { - "_total", "_created", "_bucket", "_info", - ".total", ".created", ".bucket", ".info" - }; + /** + * According to OpenMetrics {@code _count} and {@code _sum} (and {@code _gcount}, {@code _gsum}) + * should also be reserved metric name suffixes. However, popular instrumentation libraries have + * Gauges with names ending in {@code _count}. Examples: + * + *
        + *
      • Micrometer: {@code jvm_buffer_count} + *
      • OpenTelemetry: {@code process_runtime_jvm_buffer_count} + *
      + * + * We do not treat {@code _count} and {@code _sum} as reserved suffixes here for compatibility + * with these libraries. However, there is a risk of name conflict if someone creates a gauge + * named {@code my_data_count} and a histogram or summary named {@code my_data}, because the + * histogram or summary will implicitly have a sample named {@code my_data_count}. + */ + private static final String[] RESERVED_METRIC_NAME_SUFFIXES = { + "_total", "_created", "_bucket", "_info", + ".total", ".created", ".bucket", ".info" + }; - /** - * Test if a metric name is valid. Rules: - *
        - *
      • The name must match {@link #METRIC_NAME_PATTERN}.
      • - *
      • The name MUST NOT end with one of the {@link #RESERVED_METRIC_NAME_SUFFIXES}.
      • - *
      - * If a metric has a {@link Unit}, the metric name SHOULD end with the unit as a suffix. - * Note that OpenMetrics requires metric names to have their unit as suffix, - * and we implement this in {@code prometheus-metrics-core}. However, {@code prometheus-metrics-model} - * does not enforce Unit suffixes. - *

      - * Example: If you create a Counter for a processing time with Unit {@link Unit#SECONDS SECONDS}, - * the name should be {@code processing_time_seconds}. When exposed in OpenMetrics Text format, - * this will be represented as two values: {@code processing_time_seconds_total} for the counter value, - * and the optional {@code processing_time_seconds_created} timestamp. - *

      - * Use {@link #sanitizeMetricName(String)} to convert arbitrary Strings to valid metric names. - */ - public static boolean isValidMetricName(String name) { - return validateMetricName(name) == null; - } + /** + * Test if a metric name is valid. Rules: + * + *

        + *
      • The name must match {@link #METRIC_NAME_PATTERN}. + *
      • The name MUST NOT end with one of the {@link #RESERVED_METRIC_NAME_SUFFIXES}. + *
      + * + * If a metric has a {@link Unit}, the metric name SHOULD end with the unit as a suffix. Note that + * OpenMetrics requires metric names to have their unit as + * suffix, and we implement this in {@code prometheus-metrics-core}. However, {@code + * prometheus-metrics-model} does not enforce Unit suffixes. + * + *

      Example: If you create a Counter for a processing time with Unit {@link Unit#SECONDS + * SECONDS}, the name should be {@code processing_time_seconds}. When exposed in OpenMetrics Text + * format, this will be represented as two values: {@code processing_time_seconds_total} for the + * counter value, and the optional {@code processing_time_seconds_created} timestamp. + * + *

      Use {@link #sanitizeMetricName(String)} to convert arbitrary Strings to valid metric names. + */ + public static boolean isValidMetricName(String name) { + return validateMetricName(name) == null; + } - /** - * Same as {@link #isValidMetricName(String)}, but produces an error message. - *

      - * The name is valid if the error message is {@code null}. - */ - static String validateMetricName(String name) { - for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { - if (name.endsWith(reservedSuffix)) { - return "The metric name must not include the '" + reservedSuffix + "' suffix."; - } - } - if (!METRIC_NAME_PATTERN.matcher(name).matches()) { - return "The metric name contains unsupported characters"; - } - return null; + /** + * Same as {@link #isValidMetricName(String)}, but produces an error message. + * + *

      The name is valid if the error message is {@code null}. + */ + static String validateMetricName(String name) { + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + if (name.endsWith(reservedSuffix)) { + return "The metric name must not include the '" + reservedSuffix + "' suffix."; + } } - - public static boolean isValidLabelName(String name) { - return LABEL_NAME_PATTERN.matcher(name).matches() && - !(name.startsWith("__") || name.startsWith("._") || name.startsWith("..") || name.startsWith("_.")); + if (!METRIC_NAME_PATTERN.matcher(name).matches()) { + return "The metric name contains unsupported characters"; } + return null; + } - /** - * Units may not have illegal characters, and they may not end with a reserved suffix like 'total'. - */ - public static boolean isValidUnitName(String name) { - return validateUnitName(name) == null; - } + public static boolean isValidLabelName(String name) { + return LABEL_NAME_PATTERN.matcher(name).matches() + && !(name.startsWith("__") + || name.startsWith("._") + || name.startsWith("..") + || name.startsWith("_.")); + } - /** - * Same as {@link #isValidUnitName(String)} but returns an error message. - */ - public static String validateUnitName(String name) { - if (name.isEmpty()) { - return "The unit name must not be empty."; - } - for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { - String suffixName = reservedSuffix.substring(1); - if (name.endsWith(suffixName)) { - return suffixName + " is a reserved suffix in Prometheus"; - } - } - if (!UNIT_NAME_PATTERN.matcher(name).matches()) { - return "The unit name contains unsupported characters"; - } - return null; - } + /** + * Units may not have illegal characters, and they may not end with a reserved suffix like + * 'total'. + */ + public static boolean isValidUnitName(String name) { + return validateUnitName(name) == null; + } - /** - * Get the metric or label name that is used in Prometheus exposition format. - * - * @param name must be a valid metric or label name, - * i.e. {@link #isValidMetricName(String) isValidMetricName(name)} - * or {@link #isValidLabelName(String) isValidLabelName(name)} must be true. - * @return the name with dots replaced by underscores. - */ - public static String prometheusName(String name) { - return name.replace(".", "_"); + /** Same as {@link #isValidUnitName(String)} but returns an error message. */ + public static String validateUnitName(String name) { + if (name.isEmpty()) { + return "The unit name must not be empty."; } + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + String suffixName = reservedSuffix.substring(1); + if (name.endsWith(suffixName)) { + return suffixName + " is a reserved suffix in Prometheus"; + } + } + if (!UNIT_NAME_PATTERN.matcher(name).matches()) { + return "The unit name contains unsupported characters"; + } + return null; + } + + /** + * Get the metric or label name that is used in Prometheus exposition format. + * + * @param name must be a valid metric or label name, i.e. {@link #isValidMetricName(String) + * isValidMetricName(name)} or {@link #isValidLabelName(String) isValidLabelName(name)} must + * be true. + * @return the name with dots replaced by underscores. + */ + public static String prometheusName(String name) { + return name.replace(".", "_"); + } - /** - * Convert an arbitrary string to a name where {@link #isValidMetricName(String) isValidMetricName(name)} is true. - */ - public static String sanitizeMetricName(String metricName) { - if (metricName.isEmpty()) { - throw new IllegalArgumentException("Cannot convert an empty string to a valid metric name."); + /** + * Convert an arbitrary string to a name where {@link #isValidMetricName(String) + * isValidMetricName(name)} is true. + */ + public static String sanitizeMetricName(String metricName) { + if (metricName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert an empty string to a valid metric name."); + } + String sanitizedName = replaceIllegalCharsInMetricName(metricName); + boolean modified = true; + while (modified) { + modified = false; + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + if (sanitizedName.equals(reservedSuffix)) { + // This is for the corner case when you call sanitizeMetricName("_total"). + // In that case the result will be "total". + return reservedSuffix.substring(1); } - String sanitizedName = replaceIllegalCharsInMetricName(metricName); - boolean modified = true; - while (modified) { - modified = false; - for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { - if (sanitizedName.equals(reservedSuffix)) { - // This is for the corner case when you call sanitizeMetricName("_total"). - // In that case the result will be "total". - return reservedSuffix.substring(1); - } - if (sanitizedName.endsWith(reservedSuffix)) { - sanitizedName = sanitizedName.substring(0, sanitizedName.length() - reservedSuffix.length()); - modified = true; - } - } + if (sanitizedName.endsWith(reservedSuffix)) { + sanitizedName = + sanitizedName.substring(0, sanitizedName.length() - reservedSuffix.length()); + modified = true; } - return sanitizedName; + } } + return sanitizedName; + } - /** - * Like {@link #sanitizeMetricName(String)}, but also makes sure that the unit is appended - * as a suffix if the unit is not {@code null}. - */ - public static String sanitizeMetricName(String metricName, Unit unit) { - String result = sanitizeMetricName(metricName); - if (unit != null) { - if (!result.endsWith("_" + unit) && !result.endsWith("." + unit)) { - result += "_" + unit; - } - } - return result; + /** + * Like {@link #sanitizeMetricName(String)}, but also makes sure that the unit is appended as a + * suffix if the unit is not {@code null}. + */ + public static String sanitizeMetricName(String metricName, Unit unit) { + String result = sanitizeMetricName(metricName); + if (unit != null) { + if (!result.endsWith("_" + unit) && !result.endsWith("." + unit)) { + result += "_" + unit; + } } + return result; + } - /** - * Convert an arbitrary string to a name where {@link #isValidLabelName(String) isValidLabelName(name)} is true. - */ - public static String sanitizeLabelName(String labelName) { - if (labelName.isEmpty()) { - throw new IllegalArgumentException("Cannot convert an empty string to a valid label name."); - } - String sanitizedName = replaceIllegalCharsInLabelName(labelName); - while (sanitizedName.startsWith("__") || sanitizedName.startsWith("_.") || sanitizedName.startsWith("._") || sanitizedName.startsWith("..")) { - sanitizedName = sanitizedName.substring(1); - } - return sanitizedName; + /** + * Convert an arbitrary string to a name where {@link #isValidLabelName(String) + * isValidLabelName(name)} is true. + */ + public static String sanitizeLabelName(String labelName) { + if (labelName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert an empty string to a valid label name."); + } + String sanitizedName = replaceIllegalCharsInLabelName(labelName); + while (sanitizedName.startsWith("__") + || sanitizedName.startsWith("_.") + || sanitizedName.startsWith("._") + || sanitizedName.startsWith("..")) { + sanitizedName = sanitizedName.substring(1); } + return sanitizedName; + } - /** - * Convert an arbitrary string to a name where {@link #isValidUnitName(String) isValidUnitName(name)} is true. - * - * @throws IllegalArgumentException if the {@code unitName} cannot be converted, for example if you call {@code sanitizeUnitName("total")} or {@code sanitizeUnitName("")}. - * @throws NullPointerException if {@code unitName} is null. - */ - public static String sanitizeUnitName(String unitName) { - if (unitName.isEmpty()) { - throw new IllegalArgumentException("Cannot convert an empty string to a valid unit name."); - } - String sanitizedName = replaceIllegalCharsInUnitName(unitName); - boolean modified = true; - while (modified) { - modified = false; - while (sanitizedName.startsWith("_") || sanitizedName.startsWith(".")) { - sanitizedName = sanitizedName.substring(1); - modified = true; - } - while (sanitizedName.endsWith(".") || sanitizedName.endsWith("_")) { - sanitizedName = sanitizedName.substring(0, sanitizedName.length()-1); - modified = true; - } - for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { - String suffixName = reservedSuffix.substring(1); - if (sanitizedName.endsWith(suffixName)) { - sanitizedName = sanitizedName.substring(0, sanitizedName.length() - suffixName.length()); - modified = true; - } - } - } - if (sanitizedName.isEmpty()) { - throw new IllegalArgumentException("Cannot convert '" + unitName + "' into a valid unit name."); + /** + * Convert an arbitrary string to a name where {@link #isValidUnitName(String) + * isValidUnitName(name)} is true. + * + * @throws IllegalArgumentException if the {@code unitName} cannot be converted, for example if + * you call {@code sanitizeUnitName("total")} or {@code sanitizeUnitName("")}. + * @throws NullPointerException if {@code unitName} is null. + */ + public static String sanitizeUnitName(String unitName) { + if (unitName.isEmpty()) { + throw new IllegalArgumentException("Cannot convert an empty string to a valid unit name."); + } + String sanitizedName = replaceIllegalCharsInUnitName(unitName); + boolean modified = true; + while (modified) { + modified = false; + while (sanitizedName.startsWith("_") || sanitizedName.startsWith(".")) { + sanitizedName = sanitizedName.substring(1); + modified = true; + } + while (sanitizedName.endsWith(".") || sanitizedName.endsWith("_")) { + sanitizedName = sanitizedName.substring(0, sanitizedName.length() - 1); + modified = true; + } + for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { + String suffixName = reservedSuffix.substring(1); + if (sanitizedName.endsWith(suffixName)) { + sanitizedName = sanitizedName.substring(0, sanitizedName.length() - suffixName.length()); + modified = true; } - return sanitizedName; + } + } + if (sanitizedName.isEmpty()) { + throw new IllegalArgumentException( + "Cannot convert '" + unitName + "' into a valid unit name."); } + return sanitizedName; + } - /** - * Returns a string that matches {@link #METRIC_NAME_PATTERN}. - */ - private static String replaceIllegalCharsInMetricName(String name) { - int length = name.length(); - char[] sanitized = new char[length]; - for (int i = 0; i < length; i++) { - char ch = name.charAt(i); - if (ch == '.' || - (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (i > 0 && ch >= '0' && ch <= '9')) { - sanitized[i] = ch; - } else { - sanitized[i] = '_'; - } - } - return new String(sanitized); + /** Returns a string that matches {@link #METRIC_NAME_PATTERN}. */ + private static String replaceIllegalCharsInMetricName(String name) { + int length = name.length(); + char[] sanitized = new char[length]; + for (int i = 0; i < length; i++) { + char ch = name.charAt(i); + if (ch == '.' + || (ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (i > 0 && ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } } + return new String(sanitized); + } - /** - * Returns a string that matches {@link #LABEL_NAME_PATTERN}. - */ - private static String replaceIllegalCharsInLabelName(String name) { - int length = name.length(); - char[] sanitized = new char[length]; - for (int i = 0; i < length; i++) { - char ch = name.charAt(i); - if (ch == '.' || - (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (i > 0 && ch >= '0' && ch <= '9')) { - sanitized[i] = ch; - } else { - sanitized[i] = '_'; - } - } - return new String(sanitized); + /** Returns a string that matches {@link #LABEL_NAME_PATTERN}. */ + private static String replaceIllegalCharsInLabelName(String name) { + int length = name.length(); + char[] sanitized = new char[length]; + for (int i = 0; i < length; i++) { + char ch = name.charAt(i); + if (ch == '.' + || (ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (i > 0 && ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } } + return new String(sanitized); + } - /** - * Returns a string that matches {@link #UNIT_NAME_PATTERN}. - */ - private static String replaceIllegalCharsInUnitName(String name) { - int length = name.length(); - char[] sanitized = new char[length]; - for (int i = 0; i < length; i++) { - char ch = name.charAt(i); - if (ch == ':' || - ch == '.' || - (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9')) { - sanitized[i] = ch; - } else { - sanitized[i] = '_'; - } - } - return new String(sanitized); + /** Returns a string that matches {@link #UNIT_NAME_PATTERN}. */ + private static String replaceIllegalCharsInUnitName(String name) { + int length = name.length(); + char[] sanitized = new char[length]; + for (int i = 0; i < length; i++) { + char ch = name.charAt(i); + if (ch == ':' + || ch == '.' + || (ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (ch >= '0' && ch <= '9')) { + sanitized[i] = ch; + } else { + sanitized[i] = '_'; + } } + return new String(sanitized); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java index 40a31f85a..7bc575ef8 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java @@ -4,137 +4,151 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of a Summary metric. - */ +/** Immutable snapshot of a Summary metric. */ public final class SummarySnapshot extends MetricSnapshot { + /** + * To create a new {@link SummarySnapshot}, you can either call the constructor directly or use + * the builder with {@link SummarySnapshot#builder()}. + * + * @param metadata See {@link MetricMetadata} for more naming conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public SummarySnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static final class SummaryDataPointSnapshot extends DistributionDataPointSnapshot { + + private final Quantiles quantiles; + /** - * To create a new {@link SummarySnapshot}, you can either call the constructor directly or use - * the builder with {@link SummarySnapshot#builder()}. + * To create a new {@link SummaryDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link SummaryDataPointSnapshot#builder()}. * - * @param metadata See {@link MetricMetadata} for more naming conventions. - * @param data the constructor will create a sorted copy of the collection. + * @param count total number of observations. Optional, pass -1 if not available. + * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. + * @param quantiles must not be {@code null}. Use {@link Quantiles#EMPTY} if there are no + * quantiles. + * @param labels must not be {@code null}. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplars must not be {@code null}. Use {@link Exemplars#EMPTY} if there are no + * exemplars. + * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when this + * summary data (this specific set of labels) was created. Note that this refers to the + * creation of the timeseries, not the creation of the snapshot. The created timestamp + * optional. Use {@code 0L} if there is no created timestamp. */ - public SummarySnapshot(MetricMetadata metadata, Collection data) { - super(metadata, data); + public SummaryDataPointSnapshot( + long count, + double sum, + Quantiles quantiles, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis) { + this(count, sum, quantiles, labels, exemplars, createdTimestampMillis, 0); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 SummaryDataPointSnapshot( + long count, + double sum, + Quantiles quantiles, + Labels labels, + Exemplars exemplars, + long createdTimestampMillis, + long scrapeTimestampMillis) { + super(count, sum, exemplars, labels, createdTimestampMillis, scrapeTimestampMillis); + this.quantiles = quantiles; + validate(); } - public static final class SummaryDataPointSnapshot extends DistributionDataPointSnapshot { - - private final Quantiles quantiles; - - - /** - * To create a new {@link SummaryDataPointSnapshot}, you can either call the constructor directly - * or use the Builder with {@link SummaryDataPointSnapshot#builder()}. - * - * @param count total number of observations. Optional, pass -1 if not available. - * @param sum sum of all observed values. Optional, pass {@link Double#NaN} if not available. - * @param quantiles must not be {@code null}. Use {@link Quantiles#EMPTY} if there are no quantiles. - * @param labels must not be {@code null}. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplars must not be {@code null}. Use {@link Exemplars#EMPTY} if there are no exemplars. - * @param createdTimestampMillis timestamp (as in {@link System#currentTimeMillis()}) when this summary - * data (this specific set of labels) was created. - * Note that this refers to the creation of the timeseries, - * not the creation of the snapshot. - * The created timestamp optional. Use {@code 0L} if there is no created timestamp. - */ - public SummaryDataPointSnapshot(long count, double sum, Quantiles quantiles, Labels labels, Exemplars exemplars, long createdTimestampMillis) { - this(count, sum, quantiles, labels, exemplars, createdTimestampMillis, 0); - } - - /** - * 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 SummaryDataPointSnapshot(long count, double sum, Quantiles quantiles, Labels labels, Exemplars exemplars, long createdTimestampMillis, long scrapeTimestampMillis) { - super(count, sum, exemplars, labels, createdTimestampMillis, scrapeTimestampMillis); - this.quantiles = quantiles; - validate(); - } - - public Quantiles getQuantiles() { - return quantiles; - } - - private void validate() { - for (Label label : getLabels()) { - if (label.getName().equals("quantile")) { - throw new IllegalArgumentException("quantile is a reserved label name for summaries"); - } - } - if (quantiles == null) { - throw new NullPointerException(); - } - } + public Quantiles getQuantiles() { + return quantiles; + } - public static Builder builder() { - return new Builder(); + private void validate() { + for (Label label : getLabels()) { + if (label.getName().equals("quantile")) { + throw new IllegalArgumentException("quantile is a reserved label name for summaries"); } + } + if (quantiles == null) { + throw new NullPointerException(); + } + } - public static class Builder extends DistributionDataPointSnapshot.Builder { + public static Builder builder() { + return new Builder(); + } - private Quantiles quantiles = Quantiles.EMPTY; + public static class Builder extends DistributionDataPointSnapshot.Builder { + + private Quantiles quantiles = Quantiles.EMPTY; + + private Builder() {} + + @Override + protected Builder self() { + return this; + } + + public Builder quantiles(Quantiles quantiles) { + this.quantiles = quantiles; + return this; + } + + @Override + public Builder count(long count) { + super.count(count); + return this; + } + + public SummaryDataPointSnapshot build() { + return new SummaryDataPointSnapshot( + count, + sum, + quantiles, + labels, + exemplars, + createdTimestampMillis, + scrapeTimestampMillis); + } + } + } - private Builder() { - } + public static Builder builder() { + return new Builder(); + } - @Override - protected Builder self() { - return this; - } + public static class Builder extends MetricSnapshot.Builder { - public Builder quantiles(Quantiles quantiles) { - this.quantiles = quantiles; - return this; - } + private final List dataPoints = new ArrayList<>(); - @Override - public Builder count(long count) { - super.count(count); - return this; - } + private Builder() {} - public SummaryDataPointSnapshot build() { - return new SummaryDataPointSnapshot(count, sum, quantiles, labels, exemplars, createdTimestampMillis, scrapeTimestampMillis); - } - } + /** Add a data point. Call multiple times to add multiple data points. */ + public Builder dataPoint(SummaryDataPointSnapshot data) { + dataPoints.add(data); + return this; } - public static Builder builder() { - return new Builder(); + @Override + public SummarySnapshot build() { + return new SummarySnapshot(buildMetadata(), dataPoints); } - public static class Builder extends MetricSnapshot.Builder { - - private final List dataPoints = new ArrayList<>(); - - private Builder() { - } - - /** - * Add a data point. Call multiple times to add multiple data points. - */ - public Builder dataPoint(SummaryDataPointSnapshot data) { - dataPoints.add(data); - return this; - } - - @Override - public SummarySnapshot build() { - return new SummarySnapshot(buildMetadata(), dataPoints); - } - - @Override - protected Builder self() { - return this; - } + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index 16a6c5941..cb3d93cda 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -4,69 +4,71 @@ /** * Some pre-defined units for convenience. You can create your own units with + * *

        *     new Unit("myUnit");
        * 
      - * Note that in Prometheus, units are largely based on SI base units - * (seconds, bytes, joules, grams, meters, ratio, volts, amperes, and celsius). + * + * Note that in Prometheus, units are largely based on SI base units (seconds, bytes, joules, grams, + * meters, ratio, volts, amperes, and celsius). */ public class Unit { - private final String name; + private final String name; - public static final Unit RATIO = new Unit("ratio"); - public static final Unit SECONDS = new Unit("seconds"); - public static final Unit BYTES = new Unit("bytes"); - public static final Unit CELSIUS = new Unit("celsius"); - public static final Unit JOULES = new Unit("joules"); - public static final Unit GRAMS = new Unit("grams"); - public static final Unit METERS = new Unit("meters"); - public static final Unit VOLTS = new Unit("volts"); - public static final Unit AMPERES = new Unit("amperes"); + public static final Unit RATIO = new Unit("ratio"); + public static final Unit SECONDS = new Unit("seconds"); + public static final Unit BYTES = new Unit("bytes"); + public static final Unit CELSIUS = new Unit("celsius"); + public static final Unit JOULES = new Unit("joules"); + public static final Unit GRAMS = new Unit("grams"); + public static final Unit METERS = new Unit("meters"); + public static final Unit VOLTS = new Unit("volts"); + public static final Unit AMPERES = new Unit("amperes"); - public Unit(String name) { - if (name == null) { - throw new NullPointerException("Unit name cannot be null."); - } - name = name.trim(); - String error = PrometheusNaming.validateUnitName(name); - if (error != null) { - throw new IllegalArgumentException(name + ": Illegal unit name: " + error); - } - this.name = name; + public Unit(String name) { + if (name == null) { + throw new NullPointerException("Unit name cannot be null."); } - - @Override - public String toString() { - return name; + name = name.trim(); + String error = PrometheusNaming.validateUnitName(name); + if (error != null) { + throw new IllegalArgumentException(name + ": Illegal unit name: " + error); } + this.name = name; + } - public static double nanosToSeconds(long nanos) { - return nanos / 1E9; - } + @Override + public String toString() { + return name; + } - public static double millisToSeconds(long millis) { - return millis / 1E3; - } + public static double nanosToSeconds(long nanos) { + return nanos / 1E9; + } - public static double secondsToMillis(double seconds) { - return seconds * 1E3; - } + public static double millisToSeconds(long millis) { + return millis / 1E3; + } - public static double kiloBytesToBytes(double kilobytes) { - return kilobytes * 1024; - } + public static double secondsToMillis(double seconds) { + return seconds * 1E3; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Unit unit = (Unit) o; - return Objects.equals(name, unit.name); - } + public static double kiloBytesToBytes(double kilobytes) { + return kilobytes * 1024; + } - @Override - public int hashCode() { - return Objects.hash(name); - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Unit unit = (Unit) o; + return Objects.equals(name, unit.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java index 70cf07326..3fe01c9df 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -4,136 +4,125 @@ import java.util.Collection; import java.util.List; -/** - * Immutable snapshot of an Unknown (Untyped) metric. - */ +/** Immutable snapshot of an Unknown (Untyped) metric. */ public final class UnknownSnapshot extends MetricSnapshot { + /** + * To create a new {@link UnknownSnapshot}, you can either call the constructor directly or use + * the builder with {@link UnknownSnapshot#builder()}. + * + * @param metadata required name and optional help and unit. See {@link MetricMetadata} for naming + * conventions. + * @param data the constructor will create a sorted copy of the collection. + */ + public UnknownSnapshot(MetricMetadata metadata, Collection data) { + super(metadata, data); + } + + @Override + public List getDataPoints() { + return (List) dataPoints; + } + + public static final class UnknownDataPointSnapshot extends DataPointSnapshot { + + private final double value; + private final Exemplar exemplar; // may be null + /** - * To create a new {@link UnknownSnapshot}, you can either call the constructor directly or use - * the builder with {@link UnknownSnapshot#builder()}. + * To create a new {@link UnknownDataPointSnapshot}, you can either call the constructor + * directly or use the Builder with {@link UnknownDataPointSnapshot#builder()}. * - * @param metadata required name and optional help and unit. - * See {@link MetricMetadata} for naming conventions. - * @param data the constructor will create a sorted copy of the collection. + * @param value the value. + * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. + * @param exemplar may be null. */ - public UnknownSnapshot(MetricMetadata metadata, Collection data) { - super(metadata, data); + public UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { + this(value, labels, exemplar, 0); } - @Override - public List getDataPoints() { - return (List) dataPoints; + /** + * 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 UnknownDataPointSnapshot( + double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { + super(labels, 0L, scrapeTimestampMillis); + this.value = value; + this.exemplar = exemplar; } - public static final class UnknownDataPointSnapshot extends DataPointSnapshot { - - private final double value; - private final Exemplar exemplar; // may be null - - /** - * To create a new {@link UnknownDataPointSnapshot}, you can either call the constructor directly or use the - * Builder with {@link UnknownDataPointSnapshot#builder()}. - * - * @param value the value. - * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels. - * @param exemplar may be null. - */ - public UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar) { - this(value, labels, exemplar, 0); - } + public double getValue() { + return value; + } - /** - * 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 UnknownDataPointSnapshot(double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) { - super(labels, 0L, scrapeTimestampMillis); - this.value = value; - this.exemplar = exemplar; - } + /** May return {@code null}. */ + public Exemplar getExemplar() { + return exemplar; + } - public double getValue() { - return value; - } + public static Builder builder() { + return new Builder(); + } - /** - * May return {@code null}. - */ - public Exemplar getExemplar() { - return exemplar; - } + public static class Builder extends DataPointSnapshot.Builder { - public static Builder builder() { - return new Builder(); - } + private Exemplar exemplar = null; + private Double value = null; + + private Builder() {} + + /** required. */ + public Builder value(double value) { + this.value = value; + return this; + } + + /** Optional */ + public Builder exemplar(Exemplar exemplar) { + this.exemplar = exemplar; + return this; + } - public static class Builder extends DataPointSnapshot.Builder { - - private Exemplar exemplar = null; - private Double value = null; - - private Builder() { - } - - /** - * required. - */ - public Builder value(double value) { - this.value = value; - return this; - } - - /** - * Optional - */ - public Builder exemplar(Exemplar exemplar) { - this.exemplar = exemplar; - return this; - } - - public UnknownDataPointSnapshot build() { - if (value == null) { - throw new IllegalArgumentException("Missing required field: value is null."); - } - return new UnknownDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); - } - - @Override - protected Builder self() { - return this; - } + public UnknownDataPointSnapshot build() { + if (value == null) { + throw new IllegalArgumentException("Missing required field: value is null."); } - } + return new UnknownDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis); + } - public static Builder builder() { - return new Builder(); + @Override + protected Builder self() { + return this; + } } + } - 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(UnknownDataPointSnapshot data) { - dataPoints.add(data); - return this; - } + private Builder() {} - @Override - public UnknownSnapshot build() { - return new UnknownSnapshot(buildMetadata(), dataPoints); - } + /** Add a data point. Call multiple times to add multiple data points. */ + public Builder dataPoint(UnknownDataPointSnapshot data) { + dataPoints.add(data); + return this; + } - @Override - protected Builder self() { - return this; - } + @Override + public UnknownSnapshot build() { + return new UnknownSnapshot(buildMetadata(), dataPoints); + } + + @Override + protected Builder self() { + return this; } + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java index 78bf8c564..082981431 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java @@ -1,102 +1,98 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class ClassicHistogramBucketsTest { - @Test - public void testGoodCase() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() - .bucket(Double.NEGATIVE_INFINITY, 0) - .bucket(-10.0, 7) - .bucket(1024, 3) - .bucket(Double.POSITIVE_INFINITY, 8) - .build(); - Assert.assertEquals(4, buckets.size()); - } + @Test + public void testGoodCase() { + ClassicHistogramBuckets buckets = + ClassicHistogramBuckets.builder() + .bucket(Double.NEGATIVE_INFINITY, 0) + .bucket(-10.0, 7) + .bucket(1024, 3) + .bucket(Double.POSITIVE_INFINITY, 8) + .build(); + Assert.assertEquals(4, buckets.size()); + } - @Test - public void testSort() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() - .bucket(7, 2) - .bucket(2, 0) - .bucket(Double.POSITIVE_INFINITY, 3) - .build(); - Assert.assertEquals(3, buckets.size()); - Assert.assertEquals(2, buckets.getUpperBound(0), 0.0); - Assert.assertEquals(7, buckets.getUpperBound(1), 0.0); - Assert.assertEquals(Double.POSITIVE_INFINITY, buckets.getUpperBound(2), 0.0); - Assert.assertEquals(0, buckets.getCount(0)); - Assert.assertEquals(2, buckets.getCount(1)); - Assert.assertEquals(3, buckets.getCount(2)); - } + @Test + public void testSort() { + ClassicHistogramBuckets buckets = + ClassicHistogramBuckets.builder() + .bucket(7, 2) + .bucket(2, 0) + .bucket(Double.POSITIVE_INFINITY, 3) + .build(); + Assert.assertEquals(3, buckets.size()); + Assert.assertEquals(2, buckets.getUpperBound(0), 0.0); + Assert.assertEquals(7, buckets.getUpperBound(1), 0.0); + Assert.assertEquals(Double.POSITIVE_INFINITY, buckets.getUpperBound(2), 0.0); + Assert.assertEquals(0, buckets.getCount(0)); + Assert.assertEquals(2, buckets.getCount(1)); + Assert.assertEquals(3, buckets.getCount(2)); + } - @Test - public void testMinimalBuckets() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); - Assert.assertEquals(1, buckets.size()); - } + @Test + public void testMinimalBuckets() { + ClassicHistogramBuckets buckets = + ClassicHistogramBuckets.builder().bucket(Double.POSITIVE_INFINITY, 0).build(); + Assert.assertEquals(1, buckets.size()); + } - @Test(expected = IllegalArgumentException.class) - public void testInfBucketMissing() { - ClassicHistogramBuckets.builder() - .bucket(Double.NEGATIVE_INFINITY, 0) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testInfBucketMissing() { + ClassicHistogramBuckets.builder().bucket(Double.NEGATIVE_INFINITY, 0).build(); + } - @Test(expected = IllegalArgumentException.class) - public void testNegativeCount() { - ClassicHistogramBuckets.builder() - .bucket(0.0, 10) - .bucket(Double.POSITIVE_INFINITY, -1) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testNegativeCount() { + ClassicHistogramBuckets.builder().bucket(0.0, 10).bucket(Double.POSITIVE_INFINITY, -1).build(); + } - @Test(expected = IllegalArgumentException.class) - public void testNaNBoundary() { - ClassicHistogramBuckets.builder() - .bucket(0.0, 1) - .bucket(Double.NaN, 2) - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testNaNBoundary() { + ClassicHistogramBuckets.builder() + .bucket(0.0, 1) + .bucket(Double.NaN, 2) + .bucket(Double.POSITIVE_INFINITY, 0) + .build(); + } - @Test(expected = IllegalArgumentException.class) - public void testDuplicateBoundary() { - ClassicHistogramBuckets.builder() - .bucket(1.0, 1) - .bucket(2.0, 2) - .bucket(1.0, 2) - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testDuplicateBoundary() { + ClassicHistogramBuckets.builder() + .bucket(1.0, 1) + .bucket(2.0, 2) + .bucket(1.0, 2) + .bucket(Double.POSITIVE_INFINITY, 0) + .build(); + } - @Test(expected = IllegalArgumentException.class) - public void testEmptyBuckets() { - ClassicHistogramBuckets.builder().build(); - } + @Test(expected = IllegalArgumentException.class) + public void testEmptyBuckets() { + ClassicHistogramBuckets.builder().build(); + } - @Test(expected = IllegalArgumentException.class) - public void testDifferentLength() { - double[] upperBounds = new double[] {0.7, 1.3, Double.POSITIVE_INFINITY}; - long[] counts = new long[] {13, 178, 1024, 3000}; - ClassicHistogramBuckets.of(upperBounds, counts); - } + @Test(expected = IllegalArgumentException.class) + public void testDifferentLength() { + double[] upperBounds = new double[] {0.7, 1.3, Double.POSITIVE_INFINITY}; + long[] counts = new long[] {13, 178, 1024, 3000}; + ClassicHistogramBuckets.of(upperBounds, counts); + } - @Test(expected = UnsupportedOperationException.class) - public void testImmutable() { - ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() - .bucket(1.0, 7) - .bucket(2.0, 8) - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); - Iterator iterator = buckets.iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + ClassicHistogramBuckets buckets = + ClassicHistogramBuckets.builder() + .bucket(1.0, 7) + .bucket(2.0, 8) + .bucket(Double.POSITIVE_INFINITY, 0) + .build(); + Iterator iterator = buckets.iterator(); + iterator.next(); + iterator.remove(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java index b990de196..96e8df4c9 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java @@ -1,108 +1,115 @@ package io.prometheus.metrics.model.snapshots; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; -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 CounterSnapshotTest { - @Test - public void testCompleteGoodCase() { - long createdTimestamp1 = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); - long createdTimestamp2 = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); - long exemplarTimestamp = System.currentTimeMillis(); - CounterSnapshot snapshot = CounterSnapshot.builder() - .name("http_server_requests_seconds") - .help("total time spent serving requests") - .unit(Unit.SECONDS) - .dataPoint(CounterDataPointSnapshot.builder() - .value(1.0) - .exemplar(Exemplar.builder() - .value(3.0) - .traceId("abc123") - .spanId("123457") - .timestampMillis(exemplarTimestamp) - .build()) - .labels(Labels.builder() - .label("path", "/world") - .build()) - .createdTimestampMillis(createdTimestamp1) - .build() - ).dataPoint(CounterDataPointSnapshot.builder() - .value(2.0) - .exemplar(Exemplar.builder() - .value(4.0) - .traceId("def456") - .spanId("234567") - .timestampMillis(exemplarTimestamp) - .build()) - .labels(Labels.builder() - .label("path", "/hello") - .build()) - .createdTimestampMillis(createdTimestamp2) - .build() - ) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "http_server_requests_seconds", "total time spent serving requests", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); // data is sorted by labels, so the first one should be path="/hello" - Assert.assertEquals(Labels.of("path", "/hello"), data.getLabels()); - Assert.assertEquals(2.0, data.getValue(), 0.0); - Assert.assertEquals(4.0, data.getExemplar().getValue(), 0.0); - Assert.assertEquals(createdTimestamp2, data.getCreatedTimestampMillis()); - Assert.assertFalse(data.hasScrapeTimestamp()); - data = snapshot.getDataPoints().get(1); - Assert.assertEquals(Labels.of("path", "/world"), data.getLabels()); - Assert.assertEquals(1.0, data.getValue(), 0.0); - Assert.assertEquals(3.0, data.getExemplar().getValue(), 0.0); - Assert.assertEquals(createdTimestamp1, data.getCreatedTimestampMillis()); - Assert.assertFalse(data.hasScrapeTimestamp()); - } + @Test + public void testCompleteGoodCase() { + long createdTimestamp1 = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); + long createdTimestamp2 = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); + long exemplarTimestamp = System.currentTimeMillis(); + CounterSnapshot snapshot = + CounterSnapshot.builder() + .name("http_server_requests_seconds") + .help("total time spent serving requests") + .unit(Unit.SECONDS) + .dataPoint( + CounterDataPointSnapshot.builder() + .value(1.0) + .exemplar( + Exemplar.builder() + .value(3.0) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) + .build()) + .labels(Labels.builder().label("path", "/world").build()) + .createdTimestampMillis(createdTimestamp1) + .build()) + .dataPoint( + CounterDataPointSnapshot.builder() + .value(2.0) + .exemplar( + Exemplar.builder() + .value(4.0) + .traceId("def456") + .spanId("234567") + .timestampMillis(exemplarTimestamp) + .build()) + .labels(Labels.builder().label("path", "/hello").build()) + .createdTimestampMillis(createdTimestamp2) + .build()) + .build(); + SnapshotTestUtil.assertMetadata( + snapshot, "http_server_requests_seconds", "total time spent serving requests", "seconds"); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + CounterDataPointSnapshot data = + snapshot + .getDataPoints() + .get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(Labels.of("path", "/hello"), data.getLabels()); + Assert.assertEquals(2.0, data.getValue(), 0.0); + Assert.assertEquals(4.0, data.getExemplar().getValue(), 0.0); + Assert.assertEquals(createdTimestamp2, data.getCreatedTimestampMillis()); + Assert.assertFalse(data.hasScrapeTimestamp()); + data = snapshot.getDataPoints().get(1); + Assert.assertEquals(Labels.of("path", "/world"), data.getLabels()); + Assert.assertEquals(1.0, data.getValue(), 0.0); + Assert.assertEquals(3.0, data.getExemplar().getValue(), 0.0); + Assert.assertEquals(createdTimestamp1, data.getCreatedTimestampMillis()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } - @Test - public void testMinimalGoodCase() { - CounterSnapshot snapshot = CounterSnapshot.builder() - .name("events") - .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "events", null, null); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.EMPTY, data.getLabels()); - Assert.assertEquals(1.0, data.getValue(), 0.0); - Assert.assertNull(data.getExemplar()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - } + @Test + public void testMinimalGoodCase() { + CounterSnapshot snapshot = + CounterSnapshot.builder() + .name("events") + .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "events", null, null); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); + Assert.assertEquals(Labels.EMPTY, data.getLabels()); + Assert.assertEquals(1.0, data.getValue(), 0.0); + Assert.assertNull(data.getExemplar()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } - @Test - public void testEmptyCounter() { - CounterSnapshot snapshot = CounterSnapshot.builder().name("events").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } + @Test + public void testEmptyCounter() { + CounterSnapshot snapshot = CounterSnapshot.builder().name("events").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } - @Test(expected = IllegalArgumentException.class) - public void testTotalSuffixPresent() { - CounterSnapshot.builder().name("test_total").build(); - } + @Test(expected = IllegalArgumentException.class) + public void testTotalSuffixPresent() { + CounterSnapshot.builder().name("test_total").build(); + } - @Test(expected = IllegalArgumentException.class) - public void testValueMissing() { - CounterDataPointSnapshot.builder().build(); - } + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + CounterDataPointSnapshot.builder().build(); + } - @Test(expected = UnsupportedOperationException.class) - public void testDataImmutable() { - CounterSnapshot snapshot = CounterSnapshot.builder() - .name("events") - .dataPoint(CounterDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(1.0).build()) - .dataPoint(CounterDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(2.0).build()) - .build(); - Iterator iterator = snapshot.getDataPoints().iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + CounterSnapshot snapshot = + CounterSnapshot.builder() + .name("events") + .dataPoint( + CounterDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(1.0).build()) + .dataPoint( + CounterDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(2.0).build()) + .build(); + Iterator iterator = snapshot.getDataPoints().iterator(); + iterator.next(); + iterator.remove(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java index 84134b6b3..1a94b12f1 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java @@ -5,72 +5,76 @@ public class ExemplarTest { - @Test - public void testGoodCaseComplete() { - long timestamp = System.currentTimeMillis(); - Exemplar exemplar = Exemplar.builder() - .value(2.2) - .traceId("abc123abc123") - .spanId("def456def456") - .timestampMillis(timestamp) - .labels(Labels.of("path", "/", "error", "none")) - .build(); - Assert.assertEquals(2.2, exemplar.getValue(), 0.0); - Assert.assertEquals(Labels.of(Exemplar.TRACE_ID, "abc123abc123", Exemplar.SPAN_ID, "def456def456", "path", "/", "error", "none"), exemplar.getLabels()); - Assert.assertTrue(exemplar.hasTimestamp()); - Assert.assertEquals(timestamp, exemplar.getTimestampMillis()); - } + @Test + public void testGoodCaseComplete() { + long timestamp = System.currentTimeMillis(); + Exemplar exemplar = + Exemplar.builder() + .value(2.2) + .traceId("abc123abc123") + .spanId("def456def456") + .timestampMillis(timestamp) + .labels(Labels.of("path", "/", "error", "none")) + .build(); + Assert.assertEquals(2.2, exemplar.getValue(), 0.0); + Assert.assertEquals( + Labels.of( + Exemplar.TRACE_ID, + "abc123abc123", + Exemplar.SPAN_ID, + "def456def456", + "path", + "/", + "error", + "none"), + exemplar.getLabels()); + Assert.assertTrue(exemplar.hasTimestamp()); + Assert.assertEquals(timestamp, exemplar.getTimestampMillis()); + } - @Test(expected = IllegalStateException.class) - public void testValueMissing() { - Exemplar.builder().build(); - } + @Test(expected = IllegalStateException.class) + public void testValueMissing() { + Exemplar.builder().build(); + } - @Test - public void testMinimal() { - Exemplar exemplar = Exemplar.builder().value(0.0).build(); - Assert.assertEquals(0.0, exemplar.getValue(), 0.0); - Assert.assertEquals(Labels.EMPTY, exemplar.getLabels()); - Assert.assertFalse(exemplar.hasTimestamp()); - } + @Test + public void testMinimal() { + Exemplar exemplar = Exemplar.builder().value(0.0).build(); + Assert.assertEquals(0.0, exemplar.getValue(), 0.0); + Assert.assertEquals(Labels.EMPTY, exemplar.getLabels()); + Assert.assertFalse(exemplar.hasTimestamp()); + } - @Test - public void testLabelsMergeTraceId() { - Exemplar exemplar = Exemplar.builder() - .value(0.0) - .labels(Labels.of("a", "b")) - .traceId("abc") - .build(); - Assert.assertEquals(Labels.of("a", "b", "trace_id", "abc"), exemplar.getLabels()); - } + @Test + public void testLabelsMergeTraceId() { + Exemplar exemplar = + Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).traceId("abc").build(); + Assert.assertEquals(Labels.of("a", "b", "trace_id", "abc"), exemplar.getLabels()); + } - @Test - public void testLabelsMergeSpanId() { - Exemplar exemplar = Exemplar.builder() - .value(0.0) - .labels(Labels.of("a", "b")) - .spanId("abc") - .build(); - Assert.assertEquals(Labels.of("a", "b", "span_id", "abc"), exemplar.getLabels()); - } + @Test + public void testLabelsMergeSpanId() { + Exemplar exemplar = + Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).spanId("abc").build(); + Assert.assertEquals(Labels.of("a", "b", "span_id", "abc"), exemplar.getLabels()); + } - @Test - public void testLabelsMergeTraceIdAndSpanId() { - Exemplar exemplar = Exemplar.builder() - .value(0.0) - .labels(Labels.of("a", "b")) - .spanId("abc") - .traceId("def") - .build(); - Assert.assertEquals(Labels.of("span_id", "abc", "a", "b", "trace_id", "def"), exemplar.getLabels()); - } + @Test + public void testLabelsMergeTraceIdAndSpanId() { + Exemplar exemplar = + Exemplar.builder() + .value(0.0) + .labels(Labels.of("a", "b")) + .spanId("abc") + .traceId("def") + .build(); + Assert.assertEquals( + Labels.of("span_id", "abc", "a", "b", "trace_id", "def"), exemplar.getLabels()); + } - @Test - public void testLabelsMergeNone() { - Exemplar exemplar = Exemplar.builder() - .value(0.0) - .labels(Labels.of("a", "b")) - .build(); - Assert.assertEquals(Labels.of("a", "b"), exemplar.getLabels()); - } + @Test + public void testLabelsMergeNone() { + Exemplar exemplar = Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).build(); + Assert.assertEquals(Labels.of("a", "b"), exemplar.getLabels()); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java index 4ca64d6fb..93a1c1efa 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -1,52 +1,54 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class ExemplarsTest { - @Test - public void testUpperBound() { - Exemplars exemplars = Exemplars.of( - Exemplar.builder().value(1.0).build(), - Exemplar.builder().value(3.0).build(), - Exemplar.builder().value(2.0).build() - ); - Assert.assertEquals(3, exemplars.size()); - Assert.assertEquals(1.0, exemplars.get(0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(1).getValue(), 0.0); - Assert.assertEquals(2.0, exemplars.get(2).getValue(), 0.0); - Assert.assertEquals(1.0, exemplars.get(0.0, Double.POSITIVE_INFINITY).getValue(), 0.0); - Assert.assertEquals(1.0, exemplars.get(0.0, 1.0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(1.0, 4.0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(2.0, 3.0).getValue(), 0.0); - Assert.assertEquals(2.0, exemplars.get(1.0, 2.1).getValue(), 0.0); - Assert.assertNull(exemplars.get(2.0, 2.1)); - } + @Test + public void testUpperBound() { + Exemplars exemplars = + Exemplars.of( + Exemplar.builder().value(1.0).build(), + Exemplar.builder().value(3.0).build(), + Exemplar.builder().value(2.0).build()); + Assert.assertEquals(3, exemplars.size()); + Assert.assertEquals(1.0, exemplars.get(0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(1).getValue(), 0.0); + Assert.assertEquals(2.0, exemplars.get(2).getValue(), 0.0); + Assert.assertEquals(1.0, exemplars.get(0.0, Double.POSITIVE_INFINITY).getValue(), 0.0); + Assert.assertEquals(1.0, exemplars.get(0.0, 1.0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(1.0, 4.0).getValue(), 0.0); + Assert.assertEquals(3.0, exemplars.get(2.0, 3.0).getValue(), 0.0); + Assert.assertEquals(2.0, exemplars.get(1.0, 2.1).getValue(), 0.0); + Assert.assertNull(exemplars.get(2.0, 2.1)); + } - @Test(expected = UnsupportedOperationException.class) - public void testImmutable() { - Exemplars exemplars = Exemplars.of( - Exemplar.builder().value(1.0).build(), - Exemplar.builder().value(3.0).build(), - Exemplar.builder().value(2.0).build() - ); - Iterator iterator = exemplars.iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + Exemplars exemplars = + Exemplars.of( + Exemplar.builder().value(1.0).build(), + Exemplar.builder().value(3.0).build(), + Exemplar.builder().value(2.0).build()); + Iterator iterator = exemplars.iterator(); + iterator.next(); + iterator.remove(); + } - @Test - public void testGet() { - Exemplar oldest = Exemplar.builder().timestampMillis(System.currentTimeMillis() - 100).value(1.8).build(); - Exemplar middle = Exemplar.builder().timestampMillis(System.currentTimeMillis() - 50).value(1.2).build(); - Exemplar newest = Exemplar.builder().timestampMillis(System.currentTimeMillis()).value(1.0).build(); - Exemplars exemplars = Exemplars.of(oldest, newest, middle); - Exemplar result = exemplars.get(1.1, 1.9); // newest is not within these bounds - Assert.assertSame(result, middle); - result = exemplars.get(0.9, Double.POSITIVE_INFINITY); - Assert.assertSame(result, newest); - } + @Test + public void testGet() { + Exemplar oldest = + Exemplar.builder().timestampMillis(System.currentTimeMillis() - 100).value(1.8).build(); + Exemplar middle = + Exemplar.builder().timestampMillis(System.currentTimeMillis() - 50).value(1.2).build(); + Exemplar newest = + Exemplar.builder().timestampMillis(System.currentTimeMillis()).value(1.0).build(); + Exemplars exemplars = Exemplars.of(oldest, newest, middle); + Exemplar result = exemplars.get(1.1, 1.9); // newest is not within these bounds + Assert.assertSame(result, middle); + result = exemplars.get(0.9, Double.POSITIVE_INFINITY); + Assert.assertSame(result, newest); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java index b64298529..fe7f386ba 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java @@ -2,110 +2,114 @@ import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class GaugeSnapshotTest { - @Test - public void testCompleteGoodCase() { - long exemplarTimestamp = System.currentTimeMillis(); - GaugeSnapshot snapshot = GaugeSnapshot.builder() - .name("cache_size_bytes") - .help("cache size in Bytes") - .unit(Unit.BYTES) - .dataPoint(GaugeDataPointSnapshot.builder() - .value(1024.0) - .exemplar(Exemplar.builder() - .value(1024.0) - .traceId("abc123") - .spanId("123457") - .timestampMillis(exemplarTimestamp) - .build()) - .labels(Labels.builder() - .label("env", "prod") - .build()) - .build() - ).dataPoint(GaugeDataPointSnapshot.builder() - .value(128.0) - .exemplar(Exemplar.builder() - .value(128.0) - .traceId("def456") - .spanId("234567") - .timestampMillis(exemplarTimestamp) - .build()) - .labels(Labels.builder() - .label("env", "dev") - .build()) - .build() - ) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "cache_size_bytes", "cache size in Bytes", "bytes"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); // data is sorted by labels, so the first one should be path="/hello" - Assert.assertEquals(Labels.of("env", "dev"), data.getLabels()); - Assert.assertEquals(128.0, data.getValue(), 0.0); - Assert.assertEquals(128.0, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - data = snapshot.getDataPoints().get(1); - Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); - Assert.assertEquals(1024.0, data.getValue(), 0.0); - Assert.assertEquals(1024.0, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - } + @Test + public void testCompleteGoodCase() { + long exemplarTimestamp = System.currentTimeMillis(); + GaugeSnapshot snapshot = + GaugeSnapshot.builder() + .name("cache_size_bytes") + .help("cache size in Bytes") + .unit(Unit.BYTES) + .dataPoint( + GaugeDataPointSnapshot.builder() + .value(1024.0) + .exemplar( + Exemplar.builder() + .value(1024.0) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) + .build()) + .labels(Labels.builder().label("env", "prod").build()) + .build()) + .dataPoint( + GaugeDataPointSnapshot.builder() + .value(128.0) + .exemplar( + Exemplar.builder() + .value(128.0) + .traceId("def456") + .spanId("234567") + .timestampMillis(exemplarTimestamp) + .build()) + .labels(Labels.builder().label("env", "dev").build()) + .build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "cache_size_bytes", "cache size in Bytes", "bytes"); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + GaugeDataPointSnapshot data = + snapshot + .getDataPoints() + .get(0); // data is sorted by labels, so the first one should be path="/hello" + Assert.assertEquals(Labels.of("env", "dev"), data.getLabels()); + Assert.assertEquals(128.0, data.getValue(), 0.0); + Assert.assertEquals(128.0, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + data = snapshot.getDataPoints().get(1); + Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); + Assert.assertEquals(1024.0, data.getValue(), 0.0); + Assert.assertEquals(1024.0, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } - @Test - public void testMinimalGoodCase() { - GaugeSnapshot snapshot = GaugeSnapshot.builder() - .name("temperature") - .dataPoint(GaugeDataPointSnapshot.builder().value(23.0).build()) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "temperature", null, null); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.EMPTY, data.getLabels()); - Assert.assertEquals(23.0, data.getValue(), 0.0); - Assert.assertNull(data.getExemplar()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - } + @Test + public void testMinimalGoodCase() { + GaugeSnapshot snapshot = + GaugeSnapshot.builder() + .name("temperature") + .dataPoint(GaugeDataPointSnapshot.builder().value(23.0).build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "temperature", null, null); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); + Assert.assertEquals(Labels.EMPTY, data.getLabels()); + Assert.assertEquals(23.0, data.getValue(), 0.0); + Assert.assertNull(data.getExemplar()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } - @Test - public void testEmptyGauge() { - GaugeSnapshot snapshot = GaugeSnapshot.builder() - .name("temperature") - .build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } + @Test + public void testEmptyGauge() { + GaugeSnapshot snapshot = GaugeSnapshot.builder().name("temperature").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } - @Test(expected = IllegalArgumentException.class) - public void testTotalSuffixPresent() { - CounterSnapshot.builder().name("test_total").build(); - } + @Test(expected = IllegalArgumentException.class) + public void testTotalSuffixPresent() { + CounterSnapshot.builder().name("test_total").build(); + } - @Test(expected = IllegalArgumentException.class) - public void testTotalSuffixPresentDot() { - CounterSnapshot.builder().name("test.total").build(); - } + @Test(expected = IllegalArgumentException.class) + public void testTotalSuffixPresentDot() { + CounterSnapshot.builder().name("test.total").build(); + } - @Test(expected = IllegalArgumentException.class) - public void testValueMissing() { - CounterDataPointSnapshot.builder().build(); - } + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + CounterDataPointSnapshot.builder().build(); + } - @Test(expected = UnsupportedOperationException.class) - public void testDataImmutable() { - GaugeSnapshot snapshot = GaugeSnapshot.builder() - .name("gauge") - .dataPoint(GaugeDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(23.0).build()) - .dataPoint(GaugeDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(23.0).build()) - .build(); - Iterator iterator = snapshot.getDataPoints().iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + GaugeSnapshot snapshot = + GaugeSnapshot.builder() + .name("gauge") + .dataPoint( + GaugeDataPointSnapshot.builder().labels(Labels.of("a", "a")).value(23.0).build()) + .dataPoint( + GaugeDataPointSnapshot.builder().labels(Labels.of("a", "b")).value(23.0).build()) + .build(); + Iterator iterator = snapshot.getDataPoints().iterator(); + iterator.next(); + iterator.remove(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java index dd4f2f0cb..78e26d100 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java @@ -1,60 +1,62 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class InfoSnapshotTest { - @Test - public void testCompleteGoodCase() { - InfoSnapshot snapshot = InfoSnapshot.builder() - .name("target") - .help("Target info") - .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() - .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) - .build()) - .build(); - Assert.assertEquals("target", snapshot.getMetadata().getName()); - Assert.assertEquals("Target info", snapshot.getMetadata().getHelp()); - Assert.assertFalse(snapshot.getMetadata().hasUnit()); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - } - - @Test - public void testEmptyInfo() { - InfoSnapshot snapshot = InfoSnapshot.builder().name("target").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } - - @Test(expected = UnsupportedOperationException.class) - public void testDataImmutable() { - InfoSnapshot snapshot = InfoSnapshot.builder() - .name("target") - .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() - .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway.v1")) - .build()) - .dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder() - .labels(Labels.of("instance_id", "127.0.0.1:9200", "service_name", "gateway.v2")) - .build()) - .build(); - Iterator iterator = snapshot.getDataPoints().iterator(); - iterator.next(); - iterator.remove(); - } - - @Test(expected = IllegalArgumentException.class) - public void testNameMustNotIncludeSuffix() { + @Test + public void testCompleteGoodCase() { + InfoSnapshot snapshot = InfoSnapshot.builder() - .name("jvm_info") - .build(); - } - - @Test(expected = IllegalArgumentException.class) - public void testNameMustNotIncludeSuffixDot() { + .name("target") + .help("Target info") + .dataPoint( + InfoSnapshot.InfoDataPointSnapshot.builder() + .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) + .build()) + .build(); + Assert.assertEquals("target", snapshot.getMetadata().getName()); + Assert.assertEquals("Target info", snapshot.getMetadata().getHelp()); + Assert.assertFalse(snapshot.getMetadata().hasUnit()); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + } + + @Test + public void testEmptyInfo() { + InfoSnapshot snapshot = InfoSnapshot.builder().name("target").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testDataImmutable() { + InfoSnapshot snapshot = InfoSnapshot.builder() - .name("jvm.info") - .build(); - } + .name("target") + .dataPoint( + InfoSnapshot.InfoDataPointSnapshot.builder() + .labels( + Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway.v1")) + .build()) + .dataPoint( + InfoSnapshot.InfoDataPointSnapshot.builder() + .labels( + Labels.of("instance_id", "127.0.0.1:9200", "service_name", "gateway.v2")) + .build()) + .build(); + Iterator iterator = snapshot.getDataPoints().iterator(); + iterator.next(); + iterator.remove(); + } + + @Test(expected = IllegalArgumentException.class) + public void testNameMustNotIncludeSuffix() { + InfoSnapshot.builder().name("jvm_info").build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testNameMustNotIncludeSuffixDot() { + InfoSnapshot.builder().name("jvm.info").build(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java index acd659dbf..e387d7155 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -5,33 +5,36 @@ public class MetricSnapshotTest { - @Test(expected = IllegalArgumentException.class) - public void testDuplicateLabels() { - CounterSnapshot.builder() - .name("events") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("path", "/hello", "status", "200")) - .value(1.0) - .build()) - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("path", "/world", "status", "200")) - .value(2.0) - .build()) - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("status", "200", "path", "/hello")) - .value(3.0) - .build()) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testDuplicateLabels() { + CounterSnapshot.builder() + .name("events") + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/hello", "status", "200")) + .value(1.0) + .build()) + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/world", "status", "200")) + .value(2.0) + .build()) + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("status", "200", "path", "/hello")) + .value(3.0) + .build()) + .build(); + } - @Test - public void testNoData() { - MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } + @Test + public void testNoData() { + MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } - @Test(expected = NullPointerException.class) - public void testNullData() { - new CounterSnapshot(new MetricMetadata("test"), null); - } + @Test(expected = NullPointerException.class) + public void testNullData() { + new CounterSnapshot(new MetricMetadata("test"), null); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java index 61b54cb3a..b85fe629f 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java @@ -1,86 +1,96 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class MetricSnapshotsTest { - @Test - public void testEmpty() { - MetricSnapshots snapshots = MetricSnapshots.builder().build(); - Assert.assertFalse(snapshots.stream().findAny().isPresent()); - } + @Test + public void testEmpty() { + MetricSnapshots snapshots = MetricSnapshots.builder().build(); + Assert.assertFalse(snapshots.stream().findAny().isPresent()); + } - @Test - public void testSort() { - CounterSnapshot c1 = CounterSnapshot.builder() - .name("counter1") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - CounterSnapshot c2 = CounterSnapshot.builder() - .name("counter2") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - CounterSnapshot c3 = CounterSnapshot.builder() - .name("counter3") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); - Assert.assertEquals(3, snapshots.size()); - Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName()); - Assert.assertEquals("counter2", snapshots.get(1).getMetadata().getName()); - Assert.assertEquals("counter3", snapshots.get(2).getMetadata().getName()); - } + @Test + public void testSort() { + CounterSnapshot c1 = + CounterSnapshot.builder() + .name("counter1") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + CounterSnapshot c2 = + CounterSnapshot.builder() + .name("counter2") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + CounterSnapshot c3 = + CounterSnapshot.builder() + .name("counter3") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); + Assert.assertEquals(3, snapshots.size()); + Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName()); + Assert.assertEquals("counter2", snapshots.get(1).getMetadata().getName()); + Assert.assertEquals("counter3", snapshots.get(2).getMetadata().getName()); + } - @Test(expected = IllegalArgumentException.class) - public void testDuplicateName() { - // Q: What if you have a counter named "foo" and a gauge named "foo"? - // A: Great question. You might think this is a valid scenario, because the counter will produce - // the values "foo_total" and "foo_created" while the gauge will produce the value "foo". - // So from that perspective there is no conflict. However, the name for HELP, TYPE, UNIT is the same, - // and that is the conflict. Therefore, you cannot have a counter named "foo" and a gauge named "foo". - CounterSnapshot c = CounterSnapshot.builder() - .name("my_metric") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - GaugeSnapshot g = GaugeSnapshot.builder() - .name("my_metric") - .dataPoint(GaugeSnapshot.GaugeDataPointSnapshot.builder().value(1.0).build()) - .build(); - new MetricSnapshots(c, g); - } + @Test(expected = IllegalArgumentException.class) + public void testDuplicateName() { + // Q: What if you have a counter named "foo" and a gauge named "foo"? + // A: Great question. You might think this is a valid scenario, because the counter will produce + // the values "foo_total" and "foo_created" while the gauge will produce the value "foo". + // So from that perspective there is no conflict. However, the name for HELP, TYPE, UNIT is + // the same, + // and that is the conflict. Therefore, you cannot have a counter named "foo" and a gauge + // named "foo". + CounterSnapshot c = + CounterSnapshot.builder() + .name("my_metric") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + GaugeSnapshot g = + GaugeSnapshot.builder() + .name("my_metric") + .dataPoint(GaugeSnapshot.GaugeDataPointSnapshot.builder().value(1.0).build()) + .build(); + new MetricSnapshots(c, g); + } - @Test - public void testBuilder() { - CounterSnapshot counter = CounterSnapshot.builder() - .name("my_metric") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - MetricSnapshots.Builder builder = MetricSnapshots.builder(); - Assert.assertFalse(builder.containsMetricName("my_metric")); - builder.metricSnapshot(counter); - Assert.assertTrue(builder.containsMetricName("my_metric")); - } + @Test + public void testBuilder() { + CounterSnapshot counter = + CounterSnapshot.builder() + .name("my_metric") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + MetricSnapshots.Builder builder = MetricSnapshots.builder(); + Assert.assertFalse(builder.containsMetricName("my_metric")); + builder.metricSnapshot(counter); + Assert.assertTrue(builder.containsMetricName("my_metric")); + } - @Test(expected = UnsupportedOperationException.class) - public void testImmutable() { - CounterSnapshot c1 = CounterSnapshot.builder() - .name("counter1") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - CounterSnapshot c2 = CounterSnapshot.builder() - .name("counter2") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - CounterSnapshot c3 = CounterSnapshot.builder() - .name("counter3") - .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) - .build(); - MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); - Iterator iterator = snapshots.iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + CounterSnapshot c1 = + CounterSnapshot.builder() + .name("counter1") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + CounterSnapshot c2 = + CounterSnapshot.builder() + .name("counter2") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + CounterSnapshot c3 = + CounterSnapshot.builder() + .name("counter3") + .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) + .build(); + MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); + Iterator iterator = snapshots.iterator(); + iterator.next(); + iterator.remove(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java index 3c031d682..1aa7a1023 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java @@ -1,63 +1,54 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class NativeHistogramBucketsTest { - @Test - public void testGoodCase() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() - .bucket(-10, 12) - .bucket(120, 17) - .build(); - Assert.assertEquals(2, buckets.size()); - Assert.assertEquals(-10, buckets.getBucketIndex(0)); - Assert.assertEquals(12, buckets.getCount(0)); - Assert.assertEquals(120, buckets.getBucketIndex(1)); - Assert.assertEquals(17, buckets.getCount(1)); - } - - @Test - public void testEmpty() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().build(); - Assert.assertEquals(0, buckets.size()); - } - - @Test - public void testSort() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() - .bucket(7, 4) - .bucket(2, 0) - .bucket(5, 3) - .build(); - Assert.assertEquals(3, buckets.size()); - Assert.assertEquals(2, buckets.getBucketIndex(0)); - Assert.assertEquals(5, buckets.getBucketIndex(1)); - Assert.assertEquals(7, buckets.getBucketIndex(2)); - Assert.assertEquals(0, buckets.getCount(0)); - Assert.assertEquals(3, buckets.getCount(1)); - Assert.assertEquals(4, buckets.getCount(2)); - } - - @Test(expected = IllegalArgumentException.class) - public void testDifferentLength() { - int[] bucketIndexes = new int[] {0, 1, 2}; - long[] cumulativeCounts = new long[] {13, 178, 1024, 3000}; - NativeHistogramBuckets.of(bucketIndexes, cumulativeCounts); - } - - @Test(expected = UnsupportedOperationException.class) - public void testImmutable() { - NativeHistogramBuckets buckets = NativeHistogramBuckets.builder() - .bucket(1, 1) - .bucket(2, 1) - .build(); - Iterator iterator = buckets.iterator(); - iterator.next(); - iterator.remove(); - } - + @Test + public void testGoodCase() { + NativeHistogramBuckets buckets = + NativeHistogramBuckets.builder().bucket(-10, 12).bucket(120, 17).build(); + Assert.assertEquals(2, buckets.size()); + Assert.assertEquals(-10, buckets.getBucketIndex(0)); + Assert.assertEquals(12, buckets.getCount(0)); + Assert.assertEquals(120, buckets.getBucketIndex(1)); + Assert.assertEquals(17, buckets.getCount(1)); + } + + @Test + public void testEmpty() { + NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().build(); + Assert.assertEquals(0, buckets.size()); + } + + @Test + public void testSort() { + NativeHistogramBuckets buckets = + NativeHistogramBuckets.builder().bucket(7, 4).bucket(2, 0).bucket(5, 3).build(); + Assert.assertEquals(3, buckets.size()); + Assert.assertEquals(2, buckets.getBucketIndex(0)); + Assert.assertEquals(5, buckets.getBucketIndex(1)); + Assert.assertEquals(7, buckets.getBucketIndex(2)); + Assert.assertEquals(0, buckets.getCount(0)); + Assert.assertEquals(3, buckets.getCount(1)); + Assert.assertEquals(4, buckets.getCount(2)); + } + + @Test(expected = IllegalArgumentException.class) + public void testDifferentLength() { + int[] bucketIndexes = new int[] {0, 1, 2}; + long[] cumulativeCounts = new long[] {13, 178, 1024, 3000}; + NativeHistogramBuckets.of(bucketIndexes, cumulativeCounts); + } + + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + NativeHistogramBuckets buckets = + NativeHistogramBuckets.builder().bucket(1, 1).bucket(2, 1).build(); + Iterator iterator = buckets.iterator(); + iterator.next(); + iterator.remove(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java index 9631f9df3..62f2fc2c8 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java @@ -1,90 +1,95 @@ package io.prometheus.metrics.model.snapshots; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.*; + import org.junit.Assert; import org.junit.Test; -import static io.prometheus.metrics.model.snapshots.PrometheusNaming.*; - public class PrometheusNamingTest { - @Test - public void testSanitizeMetricName() { - Assert.assertEquals("_abc_def", prometheusName(sanitizeMetricName("0abc.def"))); - Assert.assertEquals("___ab__c0", prometheusName(sanitizeMetricName("___ab.:c0"))); - Assert.assertEquals("my_prefix_my_metric", sanitizeMetricName("my_prefix/my_metric")); - Assert.assertEquals("my_counter", prometheusName(sanitizeMetricName("my_counter_total"))); - Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); - Assert.assertEquals("jvm", sanitizeMetricName("jvm_info")); - Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); - Assert.assertEquals("a.b", sanitizeMetricName("a.b")); - Assert.assertEquals("total", sanitizeMetricName("_total")); - Assert.assertEquals("total", sanitizeMetricName("total")); - } + @Test + public void testSanitizeMetricName() { + Assert.assertEquals("_abc_def", prometheusName(sanitizeMetricName("0abc.def"))); + Assert.assertEquals("___ab__c0", prometheusName(sanitizeMetricName("___ab.:c0"))); + Assert.assertEquals("my_prefix_my_metric", sanitizeMetricName("my_prefix/my_metric")); + Assert.assertEquals("my_counter", prometheusName(sanitizeMetricName("my_counter_total"))); + Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); + Assert.assertEquals("jvm", sanitizeMetricName("jvm_info")); + Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); + Assert.assertEquals("a.b", sanitizeMetricName("a.b")); + Assert.assertEquals("total", sanitizeMetricName("_total")); + Assert.assertEquals("total", sanitizeMetricName("total")); + } - @Test - public void testSanitizeMetricNameWithUnit() { - Assert.assertEquals("_abc_def_" + Unit.RATIO, prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO))); - Assert.assertEquals("___ab__c0_" + Unit.RATIO, prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO))); - Assert.assertEquals("my_prefix_my_metric_" + Unit.RATIO, sanitizeMetricName("my_prefix/my_metric", Unit.RATIO)); - Assert.assertEquals("my_counter_" + Unit.RATIO, prometheusName(sanitizeMetricName("my_counter_total", Unit.RATIO))); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm_info", Unit.RATIO)); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); - Assert.assertEquals("a.b_" + Unit.RATIO, sanitizeMetricName("a.b", Unit.RATIO)); - Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("_total", Unit.RATIO)); - Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("total", Unit.RATIO)); - } + @Test + public void testSanitizeMetricNameWithUnit() { + Assert.assertEquals( + "_abc_def_" + Unit.RATIO, prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO))); + Assert.assertEquals( + "___ab__c0_" + Unit.RATIO, prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO))); + Assert.assertEquals( + "my_prefix_my_metric_" + Unit.RATIO, sanitizeMetricName("my_prefix/my_metric", Unit.RATIO)); + Assert.assertEquals( + "my_counter_" + Unit.RATIO, + prometheusName(sanitizeMetricName("my_counter_total", Unit.RATIO))); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm_info", Unit.RATIO)); + Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); + Assert.assertEquals("a.b_" + Unit.RATIO, sanitizeMetricName("a.b", Unit.RATIO)); + Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("_total", Unit.RATIO)); + Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("total", Unit.RATIO)); + } - @Test - public void testSanitizeLabelName() { - Assert.assertEquals("_abc_def", prometheusName(sanitizeLabelName("0abc.def"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("__abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("___abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_.abc"))); - Assert.assertEquals("abc.def", sanitizeLabelName("abc.def")); - Assert.assertEquals("abc.def2", sanitizeLabelName("abc.def2")); - } + @Test + public void testSanitizeLabelName() { + Assert.assertEquals("_abc_def", prometheusName(sanitizeLabelName("0abc.def"))); + Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_abc"))); + Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("__abc"))); + Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("___abc"))); + Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_.abc"))); + Assert.assertEquals("abc.def", sanitizeLabelName("abc.def")); + Assert.assertEquals("abc.def2", sanitizeLabelName("abc.def2")); + } - @Test - public void testValidateUnitName() { - Assert.assertNotNull(validateUnitName("secondstotal")); - Assert.assertNotNull(validateUnitName("total")); - Assert.assertNotNull(validateUnitName("seconds_total")); - Assert.assertNotNull(validateUnitName("_total")); - Assert.assertNotNull(validateUnitName("")); + @Test + public void testValidateUnitName() { + Assert.assertNotNull(validateUnitName("secondstotal")); + Assert.assertNotNull(validateUnitName("total")); + Assert.assertNotNull(validateUnitName("seconds_total")); + Assert.assertNotNull(validateUnitName("_total")); + Assert.assertNotNull(validateUnitName("")); - Assert.assertNull(validateUnitName("seconds")); - Assert.assertNull(validateUnitName("2")); - } + Assert.assertNull(validateUnitName("seconds")); + Assert.assertNull(validateUnitName("2")); + } - @Test - public void testSanitizeUnitName() { - Assert.assertEquals("seconds", sanitizeUnitName("seconds")); - Assert.assertEquals("seconds", sanitizeUnitName("seconds_total")); - Assert.assertEquals("seconds", sanitizeUnitName("seconds_total_total")); - Assert.assertEquals("m_s", sanitizeUnitName("m/s")); - Assert.assertEquals("seconds", sanitizeUnitName("secondstotal")); - Assert.assertEquals("2", sanitizeUnitName("2")); - } + @Test + public void testSanitizeUnitName() { + Assert.assertEquals("seconds", sanitizeUnitName("seconds")); + Assert.assertEquals("seconds", sanitizeUnitName("seconds_total")); + Assert.assertEquals("seconds", sanitizeUnitName("seconds_total_total")); + Assert.assertEquals("m_s", sanitizeUnitName("m/s")); + Assert.assertEquals("seconds", sanitizeUnitName("secondstotal")); + Assert.assertEquals("2", sanitizeUnitName("2")); + } - @Test(expected = IllegalArgumentException.class) - public void testInvalidUnitName1() { - sanitizeUnitName("total"); - } + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName1() { + sanitizeUnitName("total"); + } - @Test(expected = IllegalArgumentException.class) - public void testInvalidUnitName2() { - sanitizeUnitName("_total"); - } + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName2() { + sanitizeUnitName("_total"); + } - @Test(expected = IllegalArgumentException.class) - public void testInvalidUnitName3() { - sanitizeUnitName("%"); - } + @Test(expected = IllegalArgumentException.class) + public void testInvalidUnitName3() { + sanitizeUnitName("%"); + } - @Test(expected = IllegalArgumentException.class) - public void testEmptyUnitName() { - sanitizeUnitName(""); - } + @Test(expected = IllegalArgumentException.class) + public void testEmptyUnitName() { + sanitizeUnitName(""); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java index c0956361d..0d66d5632 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java @@ -1,51 +1,40 @@ package io.prometheus.metrics.model.snapshots; +import java.util.Iterator; import org.junit.Assert; import org.junit.Test; -import java.util.Iterator; - public class QuantilesTest { - @Test - public void testSort() { - Quantiles quantiles = Quantiles.builder() - .quantile(0.99, 0.23) - .quantile(0.5, 0.2) - .quantile(0.95, 0.22) - .build(); - Assert.assertEquals(3, quantiles.size()); - Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0); - Assert.assertEquals(0.2, quantiles.get(0).getValue(), 0); - Assert.assertEquals(0.95, quantiles.get(1).getQuantile(), 0); - Assert.assertEquals(0.22, quantiles.get(1).getValue(), 0); - Assert.assertEquals(0.99, quantiles.get(2).getQuantile(), 0); - Assert.assertEquals(0.23, quantiles.get(2).getValue(), 0); - } + @Test + public void testSort() { + Quantiles quantiles = + Quantiles.builder().quantile(0.99, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); + Assert.assertEquals(3, quantiles.size()); + Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0); + Assert.assertEquals(0.2, quantiles.get(0).getValue(), 0); + Assert.assertEquals(0.95, quantiles.get(1).getQuantile(), 0); + Assert.assertEquals(0.22, quantiles.get(1).getValue(), 0); + Assert.assertEquals(0.99, quantiles.get(2).getQuantile(), 0); + Assert.assertEquals(0.23, quantiles.get(2).getValue(), 0); + } - @Test(expected = UnsupportedOperationException.class) - public void testImmutable() { - Quantiles quantiles = Quantiles.builder() - .quantile(0.99, 0.23) - .quantile(0.5, 0.2) - .quantile(0.95, 0.22) - .build(); - Iterator iterator = quantiles.iterator(); - iterator.next(); - iterator.remove(); - } + @Test(expected = UnsupportedOperationException.class) + public void testImmutable() { + Quantiles quantiles = + Quantiles.builder().quantile(0.99, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); + Iterator iterator = quantiles.iterator(); + iterator.next(); + iterator.remove(); + } - @Test - public void testEmpty() { - Assert.assertEquals(0, Quantiles.EMPTY.size()); - } + @Test + public void testEmpty() { + Assert.assertEquals(0, Quantiles.EMPTY.size()); + } - @Test(expected = IllegalArgumentException.class) - public void testDuplicate() { - Quantiles.builder() - .quantile(0.95, 0.23) - .quantile(0.5, 0.2) - .quantile(0.95, 0.22) - .build(); - } + @Test(expected = IllegalArgumentException.class) + public void testDuplicate() { + Quantiles.builder().quantile(0.95, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java index b5067b17e..4a4a2a355 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java @@ -1,105 +1,111 @@ package io.prometheus.metrics.model.snapshots; +import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; -import java.util.concurrent.TimeUnit; - public class SummarySnapshotTest { - @Test - public void testCompleteGoodCase() { - long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); - long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); - long exemplarTimestamp = System.currentTimeMillis(); - SummarySnapshot snapshot = SummarySnapshot.builder() - .name("latency_seconds") - .help("latency in seconds") - .unit(Unit.SECONDS) - .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() - .createdTimestampMillis(createdTimestamp) - .scrapeTimestampMillis(scrapeTimestamp) - .labels(Labels.of("endpoint", "/")) - .quantiles(Quantiles.builder() - .quantile(0.5, 0.2) - .quantile(0.95, 0.22) - .quantile(0.99, 0.23) - .build()) - .exemplars(Exemplars.builder() - .exemplar(Exemplar.builder() - .value(0.2) - .traceId("abc123") - .spanId("123457") - .timestampMillis(exemplarTimestamp) - .build()) - .exemplar(Exemplar.builder() - .value(0.21) - .traceId("abc124") - .spanId("123458") - .timestampMillis(exemplarTimestamp) - .build()) - .build()) - .count(1093) - .sum(218.6) - .build()) - .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() - .labels(Labels.of("endpoint", "/test")) - .count(1093) - .sum(218.6) - .build()) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "latency_seconds", "latency in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.of("endpoint", "/"), data.getLabels()); - Assert.assertTrue(data.hasCount()); - Assert.assertEquals(1093, data.getCount()); - Assert.assertTrue(data.hasSum()); - Assert.assertEquals(218.6, data.getSum(), 0); - Assert.assertTrue(data.hasCreatedTimestamp()); - Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis()); - Assert.assertTrue(data.hasScrapeTimestamp()); - Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis()); - Quantiles quantiles = data.getQuantiles(); - Assert.assertEquals(3, quantiles.size()); - // quantiles are tested in QuantilesTest already, skipping here. - Assert.assertEquals(2, data.getExemplars().size()); - // exemplars are tested in ExemplarsTest already, skipping here. + @Test + public void testCompleteGoodCase() { + long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); + long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2); + long exemplarTimestamp = System.currentTimeMillis(); + SummarySnapshot snapshot = + SummarySnapshot.builder() + .name("latency_seconds") + .help("latency in seconds") + .unit(Unit.SECONDS) + .dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .createdTimestampMillis(createdTimestamp) + .scrapeTimestampMillis(scrapeTimestamp) + .labels(Labels.of("endpoint", "/")) + .quantiles( + Quantiles.builder() + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) + .quantile(0.99, 0.23) + .build()) + .exemplars( + Exemplars.builder() + .exemplar( + Exemplar.builder() + .value(0.2) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) + .build()) + .exemplar( + Exemplar.builder() + .value(0.21) + .traceId("abc124") + .spanId("123458") + .timestampMillis(exemplarTimestamp) + .build()) + .build()) + .count(1093) + .sum(218.6) + .build()) + .dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder() + .labels(Labels.of("endpoint", "/test")) + .count(1093) + .sum(218.6) + .build()) + .build(); + SnapshotTestUtil.assertMetadata(snapshot, "latency_seconds", "latency in seconds", "seconds"); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getDataPoints().get(0); + Assert.assertEquals(Labels.of("endpoint", "/"), data.getLabels()); + Assert.assertTrue(data.hasCount()); + Assert.assertEquals(1093, data.getCount()); + Assert.assertTrue(data.hasSum()); + Assert.assertEquals(218.6, data.getSum(), 0); + Assert.assertTrue(data.hasCreatedTimestamp()); + Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis()); + Assert.assertTrue(data.hasScrapeTimestamp()); + Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis()); + Quantiles quantiles = data.getQuantiles(); + Assert.assertEquals(3, quantiles.size()); + // quantiles are tested in QuantilesTest already, skipping here. + Assert.assertEquals(2, data.getExemplars().size()); + // exemplars are tested in ExemplarsTest already, skipping here. - data = snapshot.getDataPoints().get(1); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - Assert.assertTrue(data.hasCount()); - Assert.assertTrue(data.hasSum()); - } + data = snapshot.getDataPoints().get(1); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + Assert.assertTrue(data.hasCount()); + Assert.assertTrue(data.hasSum()); + } - @Test - public void testMinimal() { - SummarySnapshot snapshot = SummarySnapshot.builder() - .name("size_bytes") - .dataPoint(SummarySnapshot.SummaryDataPointSnapshot.builder() - .count(10) - .sum(12.0) - .build()) - .build(); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - Assert.assertEquals(Labels.EMPTY, snapshot.getDataPoints().get(0).getLabels()); - } + @Test + public void testMinimal() { + SummarySnapshot snapshot = + SummarySnapshot.builder() + .name("size_bytes") + .dataPoint( + SummarySnapshot.SummaryDataPointSnapshot.builder().count(10).sum(12.0).build()) + .build(); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + Assert.assertEquals(Labels.EMPTY, snapshot.getDataPoints().get(0).getLabels()); + } - @Test - public void testEmptySnapshot() { - SummarySnapshot snapshot = SummarySnapshot.builder().name("empty_summary").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } + @Test + public void testEmptySnapshot() { + SummarySnapshot snapshot = SummarySnapshot.builder().name("empty_summary").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } - @Test - public void testEmptyData() { - SummarySnapshot.SummaryDataPointSnapshot data = SummarySnapshot.SummaryDataPointSnapshot.builder().build(); - Assert.assertEquals(0, data.getQuantiles().size()); - Assert.assertFalse(data.hasCount()); - Assert.assertFalse(data.hasSum()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - Assert.assertEquals(0, data.getExemplars().size()); - } + @Test + public void testEmptyData() { + SummarySnapshot.SummaryDataPointSnapshot data = + SummarySnapshot.SummaryDataPointSnapshot.builder().build(); + Assert.assertEquals(0, data.getQuantiles().size()); + Assert.assertFalse(data.hasCount()); + Assert.assertFalse(data.hasSum()); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + Assert.assertEquals(0, data.getExemplars().size()); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java index a6d7973b5..cdb81c9dc 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java @@ -5,83 +5,83 @@ public class UnknownSnapshotTest { - @Test - public void testCompleteGoodCase() { - long exemplarTimestamp = System.currentTimeMillis(); - UnknownSnapshot snapshot = UnknownSnapshot.builder() - .name("my_unknown_seconds") - .help("something in seconds") - .unit(Unit.SECONDS) - .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() - .value(0.3) - .exemplar(Exemplar.builder() - .value(0.12) - .traceId("abc123") - .spanId("123457") - .timestampMillis(exemplarTimestamp) - .build()) - .labels(Labels.builder() - .label("env", "prod") - .build()) - .build() - ).dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() - .value(0.29) - .labels(Labels.builder() - .label("env", "dev") - .build()) - .build() - ) - .build(); - SnapshotTestUtil.assertMetadata(snapshot, "my_unknown_seconds", "something in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getDataPoints().get(1); // env="prod" - Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); - Assert.assertEquals(0.3, data.getValue(), 0.0); - Assert.assertEquals(0.12, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - } + @Test + public void testCompleteGoodCase() { + long exemplarTimestamp = System.currentTimeMillis(); + UnknownSnapshot snapshot = + UnknownSnapshot.builder() + .name("my_unknown_seconds") + .help("something in seconds") + .unit(Unit.SECONDS) + .dataPoint( + UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(0.3) + .exemplar( + Exemplar.builder() + .value(0.12) + .traceId("abc123") + .spanId("123457") + .timestampMillis(exemplarTimestamp) + .build()) + .labels(Labels.builder().label("env", "prod").build()) + .build()) + .dataPoint( + UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(0.29) + .labels(Labels.builder().label("env", "dev").build()) + .build()) + .build(); + SnapshotTestUtil.assertMetadata( + snapshot, "my_unknown_seconds", "something in seconds", "seconds"); + Assert.assertEquals(2, snapshot.getDataPoints().size()); + UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getDataPoints().get(1); // env="prod" + Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); + Assert.assertEquals(0.3, data.getValue(), 0.0); + Assert.assertEquals(0.12, data.getExemplar().getValue(), 0.0); + Assert.assertFalse(data.hasCreatedTimestamp()); + Assert.assertFalse(data.hasScrapeTimestamp()); + } - @Test - public void testMinimal() { - UnknownSnapshot snapshot = UnknownSnapshot.builder() - .name("test") - .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder() - .value(1.0) - .build()) - .build(); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - } + @Test + public void testMinimal() { + UnknownSnapshot snapshot = + UnknownSnapshot.builder() + .name("test") + .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder().value(1.0).build()) + .build(); + Assert.assertEquals(1, snapshot.getDataPoints().size()); + } - @Test - public void testEmpty() { - UnknownSnapshot snapshot = UnknownSnapshot.builder().name("test").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); - } + @Test + public void testEmpty() { + UnknownSnapshot snapshot = UnknownSnapshot.builder().name("test").build(); + Assert.assertEquals(0, snapshot.getDataPoints().size()); + } - @Test(expected = IllegalArgumentException.class) - public void testNameMissing() { - UnknownSnapshot.builder().build(); - } + @Test(expected = IllegalArgumentException.class) + public void testNameMissing() { + UnknownSnapshot.builder().build(); + } - @Test(expected = IllegalArgumentException.class) - public void testValueMissing() { - UnknownSnapshot.UnknownDataPointSnapshot.builder().build(); - } + @Test(expected = IllegalArgumentException.class) + public void testValueMissing() { + UnknownSnapshot.UnknownDataPointSnapshot.builder().build(); + } - @Test - public void testUnknownDataPointSnapshot() { - Labels labels = Labels.of("k1", "v1"); - Exemplar exemplar = Exemplar.builder().value(2.0).build(); + @Test + public void testUnknownDataPointSnapshot() { + Labels labels = Labels.of("k1", "v1"); + Exemplar exemplar = Exemplar.builder().value(2.0).build(); - UnknownSnapshot.UnknownDataPointSnapshot data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar); - Assert.assertEquals(1.0, data.getValue(), 0.1); - Assert.assertEquals(labels, data.getLabels()); - Assert.assertEquals(exemplar, data.getExemplar()); + UnknownSnapshot.UnknownDataPointSnapshot data = + new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar); + Assert.assertEquals(1.0, data.getValue(), 0.1); + Assert.assertEquals(labels, data.getLabels()); + Assert.assertEquals(exemplar, data.getExemplar()); - data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar, 0L); - Assert.assertEquals(1.0, data.getValue(), 0.1); - Assert.assertEquals(labels, data.getLabels()); - Assert.assertEquals(exemplar, data.getExemplar()); - } + data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar, 0L); + Assert.assertEquals(1.0, data.getValue(), 0.1); + Assert.assertEquals(labels, data.getLabels()); + Assert.assertEquals(exemplar, data.getExemplar()); + } } diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java index 7b0019461..ca831e691 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.shaded.io_opentelemetry; /** - * This module does not need any source code, however, in order to publish it to Maven central it needs JavaDoc. - *

      - * I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. + * This module does not need any source code, however, in order to publish it to Maven central it + * needs JavaDoc. + * + *

      I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. */ -public class PrometheusMetricsShadedOpenTelemetry { -} +public class PrometheusMetricsShadedOpenTelemetry {} diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java index 3f63392a7..9d78ee8e1 100644 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.shaded.com_google_protobuf; /** - * This module does not need any source code, however, in order to publish it to Maven central it needs JavaDoc. - *

      - * I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. + * This module does not need any source code, however, in order to publish it to Maven central it + * needs JavaDoc. + * + *

      I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. */ -public class PrometheusMetricsShadedProtobuf { -} +public class PrometheusMetricsShadedProtobuf {} diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index e1b5a3113..f1b592eaa 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -23,25 +23,27 @@ import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.Unit; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; - import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Predicate; /** - * Bridge from {@code simpleclient} (version 0.16.0 and older) to the new {@code prometheus-metrics} (version 1.0.0 and newer). - *

      - * Usage: The following line will register all metrics from a {@code simpleclient} {@link CollectorRegistry#defaultRegistry} - * to a {@code prometheus-metrics} {@link PrometheusRegistry#defaultRegistry}: + * Bridge from {@code simpleclient} (version 0.16.0 and older) to the new {@code prometheus-metrics} + * (version 1.0.0 and newer). + * + *

      Usage: The following line will register all metrics from a {@code simpleclient} {@link + * CollectorRegistry#defaultRegistry} to a {@code prometheus-metrics} {@link + * PrometheusRegistry#defaultRegistry}: + * *

      {@code
        * SimpleclientCollector.builder().register();
        * }
      - *

      - * If you have custom registries (not the default registries), use the following snippet: + * + *

      If you have custom registries (not the default registries), use the following snippet: + * *

      {@code
        * CollectorRegistry simpleclientRegistry = ...;
        * PrometheusRegistry prometheusRegistry = ...;
      @@ -52,354 +54,373 @@
        */
       public class SimpleclientCollector implements MultiCollector {
       
      -    private final CollectorRegistry simpleclientRegistry;
      +  private final CollectorRegistry simpleclientRegistry;
       
      -    private SimpleclientCollector(CollectorRegistry simpleclientRegistry) {
      -        this.simpleclientRegistry = simpleclientRegistry;
      -    }
      +  private SimpleclientCollector(CollectorRegistry simpleclientRegistry) {
      +    this.simpleclientRegistry = simpleclientRegistry;
      +  }
       
      -    @Override
      -    public MetricSnapshots collect() {
      -        return convert(simpleclientRegistry.metricFamilySamples());
      -    }
      +  @Override
      +  public MetricSnapshots collect() {
      +    return convert(simpleclientRegistry.metricFamilySamples());
      +  }
       
      -    private MetricSnapshots convert(Enumeration samples) {
      -        MetricSnapshots.Builder result = MetricSnapshots.builder();
      -        while (samples.hasMoreElements()) {
      -            Collector.MetricFamilySamples sample = samples.nextElement();
      -            switch (sample.type) {
      -                case COUNTER:
      -                    result.metricSnapshot(convertCounter(sample));
      -                    break;
      -                case GAUGE:
      -                    result.metricSnapshot(convertGauge(sample));
      -                    break;
      -                case HISTOGRAM:
      -                    result.metricSnapshot(convertHistogram(sample, false));
      -                    break;
      -                case GAUGE_HISTOGRAM:
      -                    result.metricSnapshot(convertHistogram(sample, true));
      -                    break;
      -                case SUMMARY:
      -                    result.metricSnapshot(convertSummary(sample));
      -                    break;
      -                case INFO:
      -                    result.metricSnapshot(convertInfo(sample));
      -                    break;
      -                case STATE_SET:
      -                    result.metricSnapshot(convertStateSet(sample));
      -                    break;
      -                case UNKNOWN:
      -                    result.metricSnapshot(convertUnknown(sample));
      -                    break;
      -                default:
      -                    throw new IllegalStateException(sample.type + ": Unexpected metric type");
      -            }
      -        }
      -        return result.build();
      +  private MetricSnapshots convert(Enumeration samples) {
      +    MetricSnapshots.Builder result = MetricSnapshots.builder();
      +    while (samples.hasMoreElements()) {
      +      Collector.MetricFamilySamples sample = samples.nextElement();
      +      switch (sample.type) {
      +        case COUNTER:
      +          result.metricSnapshot(convertCounter(sample));
      +          break;
      +        case GAUGE:
      +          result.metricSnapshot(convertGauge(sample));
      +          break;
      +        case HISTOGRAM:
      +          result.metricSnapshot(convertHistogram(sample, false));
      +          break;
      +        case GAUGE_HISTOGRAM:
      +          result.metricSnapshot(convertHistogram(sample, true));
      +          break;
      +        case SUMMARY:
      +          result.metricSnapshot(convertSummary(sample));
      +          break;
      +        case INFO:
      +          result.metricSnapshot(convertInfo(sample));
      +          break;
      +        case STATE_SET:
      +          result.metricSnapshot(convertStateSet(sample));
      +          break;
      +        case UNKNOWN:
      +          result.metricSnapshot(convertUnknown(sample));
      +          break;
      +        default:
      +          throw new IllegalStateException(sample.type + ": Unexpected metric type");
      +      }
           }
      +    return result.build();
      +  }
       
      -    private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) {
      -        CounterSnapshot.Builder counter = CounterSnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help)
      -                .unit(convertUnit(samples));
      -        Map dataPoints = new HashMap<>();
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            Labels labels = Labels.of(sample.labelNames, sample.labelValues);
      -            CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint = dataPoints.computeIfAbsent(labels, l -> CounterSnapshot.CounterDataPointSnapshot.builder().labels(labels));
      -            if (sample.name.endsWith("_created")) {
      -                dataPoint.createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      -            } else {
      -                dataPoint.value(sample.value).exemplar(convertExemplar(sample.exemplar));
      -                if (sample.timestampMs != null) {
      -                    dataPoint.scrapeTimestampMillis(sample.timestampMs);
      -                }
      -            }
      -        }
      -        for (CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint : dataPoints.values()) {
      -            counter.dataPoint(dataPoint.build());
      +  private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) {
      +    CounterSnapshot.Builder counter =
      +        CounterSnapshot.builder()
      +            .name(sanitizeMetricName(samples.name))
      +            .help(samples.help)
      +            .unit(convertUnit(samples));
      +    Map dataPoints = new HashMap<>();
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      Labels labels = Labels.of(sample.labelNames, sample.labelValues);
      +      CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint =
      +          dataPoints.computeIfAbsent(
      +              labels, l -> CounterSnapshot.CounterDataPointSnapshot.builder().labels(labels));
      +      if (sample.name.endsWith("_created")) {
      +        dataPoint.createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      +      } else {
      +        dataPoint.value(sample.value).exemplar(convertExemplar(sample.exemplar));
      +        if (sample.timestampMs != null) {
      +          dataPoint.scrapeTimestampMillis(sample.timestampMs);
               }
      -        return counter.build();
      +      }
           }
      -
      -    private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) {
      -        GaugeSnapshot.Builder gauge = GaugeSnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help)
      -                .unit(convertUnit(samples));
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPoint = GaugeSnapshot.GaugeDataPointSnapshot.builder()
      -                    .value(sample.value)
      -                    .labels(Labels.of(sample.labelNames, sample.labelValues))
      -                    .exemplar(convertExemplar(sample.exemplar));
      -            if (sample.timestampMs != null) {
      -                dataPoint.scrapeTimestampMillis(sample.timestampMs);
      -            }
      -            gauge.dataPoint(dataPoint.build());
      -        }
      -        return gauge.build();
      +    for (CounterSnapshot.CounterDataPointSnapshot.Builder dataPoint : dataPoints.values()) {
      +      counter.dataPoint(dataPoint.build());
           }
      +    return counter.build();
      +  }
       
      -    private MetricSnapshot convertHistogram(Collector.MetricFamilySamples samples, boolean isGaugeHistogram) {
      -        HistogramSnapshot.Builder histogram = HistogramSnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help)
      -                .unit(convertUnit(samples))
      -                .gaugeHistogram(isGaugeHistogram);
      -        Map dataPoints = new HashMap<>();
      -        Map> cumulativeBuckets = new HashMap<>();
      -        Map exemplars = new HashMap<>();
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            Labels labels = labelsWithout(sample, "le");
      -            dataPoints.computeIfAbsent(labels, l -> HistogramSnapshot.HistogramDataPointSnapshot.builder()
      -                    .labels(labels));
      -            cumulativeBuckets.computeIfAbsent(labels, l -> new HashMap<>());
      -            exemplars.computeIfAbsent(labels, l -> Exemplars.builder());
      -            if (sample.name.endsWith("_sum")) {
      -                dataPoints.get(labels).sum(sample.value);
      -            }
      -            if (sample.name.endsWith("_bucket")) {
      -                addBucket(cumulativeBuckets.get(labels), sample);
      -            }
      -            if (sample.name.endsWith("_created")) {
      -                dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      -            }
      -            if (sample.exemplar != null) {
      -                exemplars.get(labels).exemplar(convertExemplar(sample.exemplar));
      -            }
      -            if (sample.timestampMs != null) {
      -                dataPoints.get(labels).scrapeTimestampMillis(sample.timestampMs);
      -            }
      -        }
      -        for (Labels labels : dataPoints.keySet()) {
      -            histogram.dataPoint(dataPoints.get(labels)
      -                    .classicHistogramBuckets(makeBuckets(cumulativeBuckets.get(labels)))
      -                    .exemplars(exemplars.get(labels).build())
      -                    .build());
      -        }
      -        return histogram.build();
      +  private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) {
      +    GaugeSnapshot.Builder gauge =
      +        GaugeSnapshot.builder()
      +            .name(sanitizeMetricName(samples.name))
      +            .help(samples.help)
      +            .unit(convertUnit(samples));
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPoint =
      +          GaugeSnapshot.GaugeDataPointSnapshot.builder()
      +              .value(sample.value)
      +              .labels(Labels.of(sample.labelNames, sample.labelValues))
      +              .exemplar(convertExemplar(sample.exemplar));
      +      if (sample.timestampMs != null) {
      +        dataPoint.scrapeTimestampMillis(sample.timestampMs);
      +      }
      +      gauge.dataPoint(dataPoint.build());
           }
      +    return gauge.build();
      +  }
       
      -    private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) {
      -        SummarySnapshot.Builder summary = SummarySnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help)
      -                .unit(convertUnit(samples));
      -        Map dataPoints = new HashMap<>();
      -        Map quantiles = new HashMap<>();
      -        Map exemplars = new HashMap<>();
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            Labels labels = labelsWithout(sample, "quantile");
      -            dataPoints.computeIfAbsent(labels, l -> SummarySnapshot.SummaryDataPointSnapshot.builder()
      -                    .labels(labels));
      -            quantiles.computeIfAbsent(labels, l -> Quantiles.builder());
      -            exemplars.computeIfAbsent(labels, l -> Exemplars.builder());
      -            if (sample.name.endsWith("_sum")) {
      -                dataPoints.get(labels).sum(sample.value);
      -            } else if (sample.name.endsWith("_count")) {
      -                dataPoints.get(labels).count((long) sample.value);
      -            } else if (sample.name.endsWith("_created")) {
      -                dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      -            } else {
      -                for (int i=0; i dataPoints = new HashMap<>();
      +    Map> cumulativeBuckets = new HashMap<>();
      +    Map exemplars = new HashMap<>();
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      Labels labels = labelsWithout(sample, "le");
      +      dataPoints.computeIfAbsent(
      +          labels, l -> HistogramSnapshot.HistogramDataPointSnapshot.builder().labels(labels));
      +      cumulativeBuckets.computeIfAbsent(labels, l -> new HashMap<>());
      +      exemplars.computeIfAbsent(labels, l -> Exemplars.builder());
      +      if (sample.name.endsWith("_sum")) {
      +        dataPoints.get(labels).sum(sample.value);
      +      }
      +      if (sample.name.endsWith("_bucket")) {
      +        addBucket(cumulativeBuckets.get(labels), sample);
      +      }
      +      if (sample.name.endsWith("_created")) {
      +        dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      +      }
      +      if (sample.exemplar != null) {
      +        exemplars.get(labels).exemplar(convertExemplar(sample.exemplar));
      +      }
      +      if (sample.timestampMs != null) {
      +        dataPoints.get(labels).scrapeTimestampMillis(sample.timestampMs);
      +      }
           }
      -
      -    private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) {
      -        StateSetSnapshot.Builder stateSet = StateSetSnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help);
      -        Map dataPoints = new HashMap<>();
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            Labels labels = labelsWithout(sample, sample.name);
      -            dataPoints.computeIfAbsent(labels, l -> StateSetSnapshot.StateSetDataPointSnapshot.builder().labels(labels));
      -            String stateName = null;
      -            for (int i=0; i dataPoints = new HashMap<>();
      +    Map quantiles = new HashMap<>();
      +    Map exemplars = new HashMap<>();
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      Labels labels = labelsWithout(sample, "quantile");
      +      dataPoints.computeIfAbsent(
      +          labels, l -> SummarySnapshot.SummaryDataPointSnapshot.builder().labels(labels));
      +      quantiles.computeIfAbsent(labels, l -> Quantiles.builder());
      +      exemplars.computeIfAbsent(labels, l -> Exemplars.builder());
      +      if (sample.name.endsWith("_sum")) {
      +        dataPoints.get(labels).sum(sample.value);
      +      } else if (sample.name.endsWith("_count")) {
      +        dataPoints.get(labels).count((long) sample.value);
      +      } else if (sample.name.endsWith("_created")) {
      +        dataPoints.get(labels).createdTimestampMillis((long) Unit.secondsToMillis(sample.value));
      +      } else {
      +        for (int i = 0; i < sample.labelNames.size(); i++) {
      +          if (sample.labelNames.get(i).equals("quantile")) {
      +            quantiles
      +                .get(labels)
      +                .quantile(
      +                    new Quantile(Double.parseDouble(sample.labelValues.get(i)), sample.value));
      +            break;
      +          }
               }
      -        return unknown.build();
      +      }
      +      if (sample.exemplar != null) {
      +        exemplars.get(labels).exemplar(convertExemplar(sample.exemplar));
      +      }
      +      if (sample.timestampMs != null) {
      +        dataPoints.get(labels).scrapeTimestampMillis(sample.timestampMs);
      +      }
           }
      -
      -    private String stripSuffix(String name, String suffix) {
      -        if (name.endsWith(suffix)) {
      -            return name.substring(0, name.length() - suffix.length());
      -        } else {
      -            return name;
      -        }
      +    for (Labels labels : dataPoints.keySet()) {
      +      summary.dataPoint(
      +          dataPoints
      +              .get(labels)
      +              .quantiles(quantiles.get(labels).build())
      +              .exemplars(exemplars.get(labels).build())
      +              .build());
           }
      +    return summary.build();
      +  }
       
      -    private Unit convertUnit(Collector.MetricFamilySamples samples) {
      -        if (samples.unit != null && !samples.unit.isEmpty()) {
      -            return new Unit(samples.unit);
      -        } else {
      -            return null;
      +  private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) {
      +    StateSetSnapshot.Builder stateSet =
      +        StateSetSnapshot.builder().name(sanitizeMetricName(samples.name)).help(samples.help);
      +    Map dataPoints = new HashMap<>();
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      Labels labels = labelsWithout(sample, sample.name);
      +      dataPoints.computeIfAbsent(
      +          labels, l -> StateSetSnapshot.StateSetDataPointSnapshot.builder().labels(labels));
      +      String stateName = null;
      +      for (int i = 0; i < sample.labelNames.size(); i++) {
      +        if (sample.labelNames.get(i).equals(sample.name)) {
      +          stateName = sample.labelValues.get(i);
      +          break;
               }
      +      }
      +      if (stateName == null) {
      +        throw new IllegalStateException("Invalid StateSet metric: No state name found.");
      +      }
      +      dataPoints.get(labels).state(stateName, sample.value == 1.0);
      +      if (sample.timestampMs != null) {
      +        dataPoints.get(labels).scrapeTimestampMillis(sample.timestampMs);
      +      }
      +    }
      +    for (StateSetSnapshot.StateSetDataPointSnapshot.Builder dataPoint : dataPoints.values()) {
      +      stateSet.dataPoint(dataPoint.build());
           }
      +    return stateSet.build();
      +  }
       
      -    private ClassicHistogramBuckets makeBuckets(Map cumulativeBuckets) {
      -        List upperBounds = new ArrayList<>(cumulativeBuckets.size());
      -        upperBounds.addAll(cumulativeBuckets.keySet());
      -        Collections.sort(upperBounds);
      -        ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.builder();
      -        long previousCount = 0L;
      -        for (Double upperBound : upperBounds) {
      -            long cumulativeCount = cumulativeBuckets.get(upperBound);
      -            result.bucket(upperBound, cumulativeCount - previousCount);
      -            previousCount = cumulativeCount;
      -        }
      -        return result.build();
      +  private MetricSnapshot convertUnknown(Collector.MetricFamilySamples samples) {
      +    UnknownSnapshot.Builder unknown =
      +        UnknownSnapshot.builder()
      +            .name(sanitizeMetricName(samples.name))
      +            .help(samples.help)
      +            .unit(convertUnit(samples));
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      UnknownSnapshot.UnknownDataPointSnapshot.Builder dataPoint =
      +          UnknownSnapshot.UnknownDataPointSnapshot.builder()
      +              .value(sample.value)
      +              .labels(Labels.of(sample.labelNames, sample.labelValues))
      +              .exemplar(convertExemplar(sample.exemplar));
      +      if (sample.timestampMs != null) {
      +        dataPoint.scrapeTimestampMillis(sample.timestampMs);
      +      }
      +      unknown.dataPoint(dataPoint.build());
           }
      +    return unknown.build();
      +  }
       
      -    private void addBucket(Map buckets, Collector.MetricFamilySamples.Sample sample) {
      -        for (int i = 0; i < sample.labelNames.size(); i++) {
      -            if (sample.labelNames.get(i).equals("le")) {
      -                double upperBound;
      -                switch (sample.labelValues.get(i)) {
      -                    case "+Inf":
      -                        upperBound = Double.POSITIVE_INFINITY;
      -                        break;
      -                    case "-Inf": // Doesn't make sense as count would always be zero. Catch this anyway.
      -                        upperBound = Double.NEGATIVE_INFINITY;
      -                        break;
      -                    default:
      -                        upperBound = Double.parseDouble(sample.labelValues.get(i));
      -                }
      -                buckets.put(upperBound, (long) sample.value);
      -                return;
      -            }
      -        }
      -        throw new IllegalStateException(sample.name + " does not have a le label.");
      +  private String stripSuffix(String name, String suffix) {
      +    if (name.endsWith(suffix)) {
      +      return name.substring(0, name.length() - suffix.length());
      +    } else {
      +      return name;
           }
      +  }
       
      +  private Unit convertUnit(Collector.MetricFamilySamples samples) {
      +    if (samples.unit != null && !samples.unit.isEmpty()) {
      +      return new Unit(samples.unit);
      +    } else {
      +      return null;
      +    }
      +  }
       
      -    private Labels labelsWithout(Collector.MetricFamilySamples.Sample sample, String excludedLabelName) {
      -        Labels.Builder labels = Labels.builder();
      -        for (int i = 0; i < sample.labelNames.size(); i++) {
      -            if (!sample.labelNames.get(i).equals(excludedLabelName)) {
      -                labels.label(sample.labelNames.get(i), sample.labelValues.get(i));
      -            }
      -        }
      -        return labels.build();
      +  private ClassicHistogramBuckets makeBuckets(Map cumulativeBuckets) {
      +    List upperBounds = new ArrayList<>(cumulativeBuckets.size());
      +    upperBounds.addAll(cumulativeBuckets.keySet());
      +    Collections.sort(upperBounds);
      +    ClassicHistogramBuckets.Builder result = ClassicHistogramBuckets.builder();
      +    long previousCount = 0L;
      +    for (Double upperBound : upperBounds) {
      +      long cumulativeCount = cumulativeBuckets.get(upperBound);
      +      result.bucket(upperBound, cumulativeCount - previousCount);
      +      previousCount = cumulativeCount;
           }
      +    return result.build();
      +  }
       
      -    private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) {
      -        InfoSnapshot.Builder info = InfoSnapshot.builder()
      -                .name(sanitizeMetricName(samples.name))
      -                .help(samples.help);
      -        for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      -            info.dataPoint(InfoSnapshot.InfoDataPointSnapshot.builder()
      -                    .labels(Labels.of(sample.labelNames, sample.labelValues))
      -                    .build());
      +  private void addBucket(Map buckets, Collector.MetricFamilySamples.Sample sample) {
      +    for (int i = 0; i < sample.labelNames.size(); i++) {
      +      if (sample.labelNames.get(i).equals("le")) {
      +        double upperBound;
      +        switch (sample.labelValues.get(i)) {
      +          case "+Inf":
      +            upperBound = Double.POSITIVE_INFINITY;
      +            break;
      +          case "-Inf": // Doesn't make sense as count would always be zero. Catch this anyway.
      +            upperBound = Double.NEGATIVE_INFINITY;
      +            break;
      +          default:
      +            upperBound = Double.parseDouble(sample.labelValues.get(i));
               }
      -        return info.build();
      +        buckets.put(upperBound, (long) sample.value);
      +        return;
      +      }
           }
      +    throw new IllegalStateException(sample.name + " does not have a le label.");
      +  }
       
      -    private Exemplar convertExemplar(io.prometheus.client.exemplars.Exemplar exemplar) {
      -        if (exemplar == null) {
      -            return null;
      -        }
      -        Exemplar.Builder result = Exemplar.builder().value(exemplar.getValue());
      -        if (exemplar.getTimestampMs() != null) {
      -            result.timestampMillis(exemplar.getTimestampMs());
      -        }
      -        Labels.Builder labels = Labels.builder();
      -        for (int i = 0; i < exemplar.getNumberOfLabels(); i++) {
      -            labels.label(exemplar.getLabelName(i), exemplar.getLabelValue(i));
      -        }
      -        return result.labels(labels.build()).build();
      +  private Labels labelsWithout(
      +      Collector.MetricFamilySamples.Sample sample, String excludedLabelName) {
      +    Labels.Builder labels = Labels.builder();
      +    for (int i = 0; i < sample.labelNames.size(); i++) {
      +      if (!sample.labelNames.get(i).equals(excludedLabelName)) {
      +        labels.label(sample.labelNames.get(i), sample.labelValues.get(i));
      +      }
           }
      +    return labels.build();
      +  }
       
      -    /**
      -     * Currently there are no configuration options for the SimpleclientCollector.
      -     * However, we want to follow the pattern to pass the config everywhere so that
      -     * we can introduce config options later without the need for API changes.
      -     */
      -    public static Builder builder(PrometheusProperties config) {
      -        return new Builder(config);
      +  private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) {
      +    InfoSnapshot.Builder info =
      +        InfoSnapshot.builder().name(sanitizeMetricName(samples.name)).help(samples.help);
      +    for (Collector.MetricFamilySamples.Sample sample : samples.samples) {
      +      info.dataPoint(
      +          InfoSnapshot.InfoDataPointSnapshot.builder()
      +              .labels(Labels.of(sample.labelNames, sample.labelValues))
      +              .build());
           }
      +    return info.build();
      +  }
       
      -    public static Builder builder() {
      -        return builder(PrometheusProperties.get());
      +  private Exemplar convertExemplar(io.prometheus.client.exemplars.Exemplar exemplar) {
      +    if (exemplar == null) {
      +      return null;
      +    }
      +    Exemplar.Builder result = Exemplar.builder().value(exemplar.getValue());
      +    if (exemplar.getTimestampMs() != null) {
      +      result.timestampMillis(exemplar.getTimestampMs());
           }
      +    Labels.Builder labels = Labels.builder();
      +    for (int i = 0; i < exemplar.getNumberOfLabels(); i++) {
      +      labels.label(exemplar.getLabelName(i), exemplar.getLabelValue(i));
      +    }
      +    return result.labels(labels.build()).build();
      +  }
       
      -    public static class Builder {
      +  /**
      +   * Currently there are no configuration options for the SimpleclientCollector. However, we want to
      +   * follow the pattern to pass the config everywhere so that we can introduce config options later
      +   * without the need for API changes.
      +   */
      +  public static Builder builder(PrometheusProperties config) {
      +    return new Builder(config);
      +  }
       
      -        private final PrometheusProperties config;
      -        private CollectorRegistry collectorRegistry;
      +  public static Builder builder() {
      +    return builder(PrometheusProperties.get());
      +  }
       
      -        private Builder(PrometheusProperties config) {
      -            this.config = config;
      -        }
      +  public static class Builder {
       
      -        public Builder collectorRegistry(CollectorRegistry registry) {
      -            this.collectorRegistry = registry;
      -            return this;
      -        }
      +    private final PrometheusProperties config;
      +    private CollectorRegistry collectorRegistry;
       
      -        public SimpleclientCollector build() {
      -            return collectorRegistry != null ? new SimpleclientCollector(collectorRegistry) : new SimpleclientCollector(CollectorRegistry.defaultRegistry);
      -        }
      +    private Builder(PrometheusProperties config) {
      +      this.config = config;
      +    }
       
      -        public SimpleclientCollector register() {
      -            return register(PrometheusRegistry.defaultRegistry);
      -        }
      +    public Builder collectorRegistry(CollectorRegistry registry) {
      +      this.collectorRegistry = registry;
      +      return this;
      +    }
       
      -        public SimpleclientCollector register(PrometheusRegistry registry) {
      -            SimpleclientCollector result = build();
      -            registry.register(result);
      -            return result;
      -        }
      +    public SimpleclientCollector build() {
      +      return collectorRegistry != null
      +          ? new SimpleclientCollector(collectorRegistry)
      +          : new SimpleclientCollector(CollectorRegistry.defaultRegistry);
      +    }
      +
      +    public SimpleclientCollector register() {
      +      return register(PrometheusRegistry.defaultRegistry);
      +    }
      +
      +    public SimpleclientCollector register(PrometheusRegistry registry) {
      +      SimpleclientCollector result = build();
      +      registry.register(result);
      +      return result;
           }
      +  }
       }
      diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      index 2681ceed7..83e28d982 100644
      --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java
      @@ -10,10 +10,6 @@
       import io.prometheus.client.exporter.common.TextFormat;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
      -import org.junit.Assert;
      -import org.junit.Before;
      -import org.junit.Test;
      -
       import java.io.ByteArrayOutputStream;
       import java.io.IOException;
       import java.io.StringWriter;
      @@ -22,236 +18,255 @@
       import java.util.Arrays;
       import java.util.Collections;
       import java.util.List;
      +import org.junit.Assert;
      +import org.junit.Before;
      +import org.junit.Test;
       
       public class SimpleclientCollectorTest {
       
      -    private CollectorRegistry origRegistry;
      -    private PrometheusRegistry newRegistry;
      -
      -    @Before
      -    public void setUp() {
      -        origRegistry = new CollectorRegistry();
      -        newRegistry = new PrometheusRegistry();
      -        SimpleclientCollector.builder()
      -                .collectorRegistry(origRegistry)
      -                .register(newRegistry);
      -    }
      -
      -    @Test
      -    public void testCounterComplete() throws IOException, InterruptedException {
      -        Counter counter = Counter.build()
      -                .name("service_time_seconds_total")
      -                .help("total time spent serving")
      -                .labelNames("path", "status")
      -                .register(origRegistry);
      -        counter.labels("/hello", "200").incWithExemplar(0.8, "trace_id", "12345", "span_id", "abcde");
      -        Thread.sleep(3); // make timestamps a bit different
      -        counter.labels("/hello", "500").incWithExemplar(2.4, "trace_id", "23446", "span_id", "bcdef");
      -
      -        Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testCounterMinimal() throws IOException {
      +  private CollectorRegistry origRegistry;
      +  private PrometheusRegistry newRegistry;
      +
      +  @Before
      +  public void setUp() {
      +    origRegistry = new CollectorRegistry();
      +    newRegistry = new PrometheusRegistry();
      +    SimpleclientCollector.builder().collectorRegistry(origRegistry).register(newRegistry);
      +  }
      +
      +  @Test
      +  public void testCounterComplete() throws IOException, InterruptedException {
      +    Counter counter =
               Counter.build()
      -                .name("events")
      -                .help("total number of events")
      -                .register(origRegistry);
      -
      -        Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testGaugeComplete() throws IOException, InterruptedException {
      -        Gauge gauge = Gauge.build()
      -                .name("disk_usage_ratio")
      -                .help("percentage used")
      -                .unit("ratio")
      -                .labelNames("device")
      -                .register(origRegistry);
      -        gauge.labels("/dev/sda1").set(0.2);
      -        Thread.sleep(3);
      -        gauge.labels("/dev/sda2").set(0.7);
      -
      -        Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testGaugeMinimal() throws IOException, InterruptedException {
      -        Gauge gauge = Gauge.build()
      -                .name("temperature_centigrade")
      -                .help("temperature")
      -                .unit("celsius")
      -                .register(origRegistry);
      -        gauge.set(22.3);
      -
      -        Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testHistogramComplete() throws IOException, InterruptedException {
      -        Histogram histogram = Histogram.build()
      -                .name("response_size_bytes")
      -                .help("response size in Bytes")
      -                .labelNames("status")
      -                .buckets(64, 256, 512.1)
      -                .register(origRegistry);
      -        histogram.labels("200").observeWithExemplar(38, "trace_id", "1", "span_id", "2");
      -        histogram.labels("200").observeWithExemplar(127, "trace_id", "3", "span_id", "4");
      -        histogram.labels("200").observeWithExemplar(130, "trace_id", "5", "span_id", "6");
      -        histogram.labels("200").observeWithExemplar(40, "trace_id", "7", "span_id", "8");
      -        histogram.labels("200").observeWithExemplar(41, "trace_id", "9", "span_id", "10");
      -        Thread.sleep(3); // make timestamps a bit different
      -        histogram.labels("500").observeWithExemplar(10000, "trace_id", "11", "span_id", "12");
      -
      -        Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testHistogramMinimal() throws IOException, InterruptedException {
      +            .name("service_time_seconds_total")
      +            .help("total time spent serving")
      +            .labelNames("path", "status")
      +            .register(origRegistry);
      +    counter.labels("/hello", "200").incWithExemplar(0.8, "trace_id", "12345", "span_id", "abcde");
      +    Thread.sleep(3); // make timestamps a bit different
      +    counter.labels("/hello", "500").incWithExemplar(2.4, "trace_id", "23446", "span_id", "bcdef");
      +
      +    Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testCounterMinimal() throws IOException {
      +    Counter.build().name("events").help("total number of events").register(origRegistry);
      +
      +    Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testGaugeComplete() throws IOException, InterruptedException {
      +    Gauge gauge =
      +        Gauge.build()
      +            .name("disk_usage_ratio")
      +            .help("percentage used")
      +            .unit("ratio")
      +            .labelNames("device")
      +            .register(origRegistry);
      +    gauge.labels("/dev/sda1").set(0.2);
      +    Thread.sleep(3);
      +    gauge.labels("/dev/sda2").set(0.7);
      +
      +    Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testGaugeMinimal() throws IOException, InterruptedException {
      +    Gauge gauge =
      +        Gauge.build()
      +            .name("temperature_centigrade")
      +            .help("temperature")
      +            .unit("celsius")
      +            .register(origRegistry);
      +    gauge.set(22.3);
      +
      +    Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testHistogramComplete() throws IOException, InterruptedException {
      +    Histogram histogram =
               Histogram.build()
      -                .name("request_latency")
      -                .help("request latency")
      -                .register(origRegistry);
      -
      -        Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testSummaryComplete() throws IOException, InterruptedException {
      -        Summary summary = Summary.build()
      -                .name("http_request_duration_seconds")
      -                .help("request duration")
      -                .labelNames("path", "status")
      -                .quantile(0.5, 0.01)
      -                .quantile(0.95, 0.01)
      -                .quantile(0.99, 0.001)
      -                .register(origRegistry);
      -        summary.labels("/", "200").observe(0.2);
      -        Thread.sleep(3);
      -        summary.labels("/info", "200").observe(0.7);
      -        summary.labels("/info", "200").observe(0.8);
      -        summary.labels("/info", "200").observe(0.9);
      -        Thread.sleep(3);
      -        summary.labels("/", "500").observe(0.3);
      -        summary.labels("/", "500").observe(0.31);
      -        summary.labels("/", "500").observe(0.32);
      -
      -        Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testSummaryMinimal() throws IOException, InterruptedException {
      -        Summary summary = Summary.build()
      -                .name("request_size")
      -                .help("request size")
      -                .register(origRegistry);
      -
      -        Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testInfoComplete() throws IOException, InterruptedException {
      -        Info info = Info.build()
      -                .name("version")
      -                .help("version information")
      -                .labelNames("env")
      -                .register(origRegistry);
      -        info.labels("prod").info("major_version", "12", "minor_version", "3");
      -        Thread.sleep(3);
      -        info.labels("dev").info("major_version", "13", "minor_version", "1");
      -
      -        Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testInfoMinimal() throws IOException, InterruptedException {
      -        Info info = Info.build()
      -                .name("jvm")
      -                .help("JVM info")
      -                .register(origRegistry);
      -        info.info("version", "17");
      -
      -        Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testStateSetComplete() throws IOException {
      -        Collector stateSet = new Collector() {
      -            @Override
      -            public List collect() {
      -                List samples = new ArrayList<>();
      -                samples.add(new Collector.MetricFamilySamples.Sample("state", Arrays.asList("env", "state"), Arrays.asList("dev", "state1"), 1.0));
      -                samples.add(new Collector.MetricFamilySamples.Sample("state", Arrays.asList("env", "state"), Arrays.asList("dev", "state2"), 0.0));
      -                return Collections.singletonList(new Collector.MetricFamilySamples("state", Collector.Type.STATE_SET, "my state", samples));
      -            }
      +            .name("response_size_bytes")
      +            .help("response size in Bytes")
      +            .labelNames("status")
      +            .buckets(64, 256, 512.1)
      +            .register(origRegistry);
      +    histogram.labels("200").observeWithExemplar(38, "trace_id", "1", "span_id", "2");
      +    histogram.labels("200").observeWithExemplar(127, "trace_id", "3", "span_id", "4");
      +    histogram.labels("200").observeWithExemplar(130, "trace_id", "5", "span_id", "6");
      +    histogram.labels("200").observeWithExemplar(40, "trace_id", "7", "span_id", "8");
      +    histogram.labels("200").observeWithExemplar(41, "trace_id", "9", "span_id", "10");
      +    Thread.sleep(3); // make timestamps a bit different
      +    histogram.labels("500").observeWithExemplar(10000, "trace_id", "11", "span_id", "12");
      +
      +    Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testHistogramMinimal() throws IOException, InterruptedException {
      +    Histogram.build().name("request_latency").help("request latency").register(origRegistry);
      +
      +    Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testSummaryComplete() throws IOException, InterruptedException {
      +    Summary summary =
      +        Summary.build()
      +            .name("http_request_duration_seconds")
      +            .help("request duration")
      +            .labelNames("path", "status")
      +            .quantile(0.5, 0.01)
      +            .quantile(0.95, 0.01)
      +            .quantile(0.99, 0.001)
      +            .register(origRegistry);
      +    summary.labels("/", "200").observe(0.2);
      +    Thread.sleep(3);
      +    summary.labels("/info", "200").observe(0.7);
      +    summary.labels("/info", "200").observe(0.8);
      +    summary.labels("/info", "200").observe(0.9);
      +    Thread.sleep(3);
      +    summary.labels("/", "500").observe(0.3);
      +    summary.labels("/", "500").observe(0.31);
      +    summary.labels("/", "500").observe(0.32);
      +
      +    Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testSummaryMinimal() throws IOException, InterruptedException {
      +    Summary summary =
      +        Summary.build().name("request_size").help("request size").register(origRegistry);
      +
      +    Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testInfoComplete() throws IOException, InterruptedException {
      +    Info info =
      +        Info.build()
      +            .name("version")
      +            .help("version information")
      +            .labelNames("env")
      +            .register(origRegistry);
      +    info.labels("prod").info("major_version", "12", "minor_version", "3");
      +    Thread.sleep(3);
      +    info.labels("dev").info("major_version", "13", "minor_version", "1");
      +
      +    Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testInfoMinimal() throws IOException, InterruptedException {
      +    Info info = Info.build().name("jvm").help("JVM info").register(origRegistry);
      +    info.info("version", "17");
      +
      +    Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testStateSetComplete() throws IOException {
      +    Collector stateSet =
      +        new Collector() {
      +          @Override
      +          public List collect() {
      +            List samples = new ArrayList<>();
      +            samples.add(
      +                new Collector.MetricFamilySamples.Sample(
      +                    "state", Arrays.asList("env", "state"), Arrays.asList("dev", "state1"), 1.0));
      +            samples.add(
      +                new Collector.MetricFamilySamples.Sample(
      +                    "state", Arrays.asList("env", "state"), Arrays.asList("dev", "state2"), 0.0));
      +            return Collections.singletonList(
      +                new Collector.MetricFamilySamples(
      +                    "state", Collector.Type.STATE_SET, "my state", samples));
      +          }
               };
      -        origRegistry.register(stateSet);
      -
      -        Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      -    }
      -
      -    @Test
      -    public void testUnknownComplete() throws IOException {
      -        Collector unknown = new Collector() {
      -            @Override
      -            public List collect() {
      -                List samples = new ArrayList<>();
      -                samples.add(new Collector.MetricFamilySamples.Sample("my_unknown_metric_seconds", Arrays.asList("env", "status"), Arrays.asList("dev", "ok"), 3.0));
      -                samples.add(new Collector.MetricFamilySamples.Sample("my_unknown_metric_seconds", Arrays.asList("env", "status"), Arrays.asList("prod", "error"), 0.0));
      -                return Collections.singletonList(new Collector.MetricFamilySamples("my_unknown_metric_seconds", "seconds", Type.UNKNOWN, "test metric of type unknown", samples));
      -            }
      +    origRegistry.register(stateSet);
      +
      +    Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics()));
      +  }
      +
      +  @Test
      +  public void testUnknownComplete() throws IOException {
      +    Collector unknown =
      +        new Collector() {
      +          @Override
      +          public List collect() {
      +            List samples = new ArrayList<>();
      +            samples.add(
      +                new Collector.MetricFamilySamples.Sample(
      +                    "my_unknown_metric_seconds",
      +                    Arrays.asList("env", "status"),
      +                    Arrays.asList("dev", "ok"),
      +                    3.0));
      +            samples.add(
      +                new Collector.MetricFamilySamples.Sample(
      +                    "my_unknown_metric_seconds",
      +                    Arrays.asList("env", "status"),
      +                    Arrays.asList("prod", "error"),
      +                    0.0));
      +            return Collections.singletonList(
      +                new Collector.MetricFamilySamples(
      +                    "my_unknown_metric_seconds",
      +                    "seconds",
      +                    Type.UNKNOWN,
      +                    "test metric of type unknown",
      +                    samples));
      +          }
               };
      -        origRegistry.register(unknown);
      -
      -        Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      -    }
      -
      -    private String fixBoolean(String s) {
      -        return s.replaceAll(" 1.0", " 1").replaceAll(" 0.0", " 0");
      -    }
      -
      -    private String sort(String s) {
      -        String[] lines = s.split("\n");
      -        Arrays.sort(lines);
      -        return String.join("\n", lines);
      -    }
      -
      -    private String fixTimestamps(String s) {
      -        // Example of a "_created" timestamp in orig format: 1.694464002939E9
      -        // Example of a "_created" timestamp in new format: 1694464002.939
      -        // The following regex translates the orig timestamp to the new timestamp
      -        return s
      -                .replaceAll("1\\.([0-9]{9})([0-9]{3})E9", "1$1.$2")   // Example: 1.694464002939E9
      -                .replaceAll("1\\.([0-9]{9})([0-9]{2})E9", "1$1.$20")  // Example: 1.69460725747E9
      -                .replaceAll("1\\.([0-9]{9})([0-9])E9", "1$1.$200") // Example: 1.6946072574E9
      -                .replaceAll("1\\.([0-9]{9})E9", "1$1.000")  // Example: 1.712332231E9
      -                .replaceAll("1\\.([0-9]{8})E9", "1$10.000") // Example: 1.71233242E9
      -                .replaceAll("1\\.([0-9]{7})E9", "1$100.000") // Example: 1.7123324E9
      -                .replaceAll("1\\.([0-9]{6})E9", "1$1000.000")
      -                .replaceAll("1\\.([0-9]{5})E9", "1$10000.000")
      -                .replaceAll("1\\.([0-9]{4})E9", "1$100000.000")
      -                .replaceAll("1\\.([0-9]{3})E9", "1$1000000.000")
      -                .replaceAll("1\\.([0-9]{2})E9", "1$10000000.000");
      -    }
      -
      -    private String fixCounts(String s) {
      -        // Example of a "_count" or "_bucket" in orig format: 3.0
      -        // Example of a "_count" or "_bucket" in new format: 3
      -        // The following regex translates the orig bucket counts to the new bucket counts
      -        return s.replaceAll("((_count|_bucket)(\\{[^}]*})? [0-9])\\.0", "$1");
      -    }
      -
      -    private String origOpenMetrics() throws IOException {
      -        StringWriter out = new StringWriter();
      -        TextFormat.writeOpenMetrics100(out, origRegistry.metricFamilySamples());
      -        return out.toString();
      -    }
      -
      -    private String newOpenMetrics() throws IOException {
      -        ByteArrayOutputStream out = new ByteArrayOutputStream();
      -        OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false);
      -        writer.write(out, newRegistry.scrape());
      -        return out.toString(StandardCharsets.UTF_8.name());
      -    }
      +    origRegistry.register(unknown);
      +
      +    Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics()));
      +  }
      +
      +  private String fixBoolean(String s) {
      +    return s.replaceAll(" 1.0", " 1").replaceAll(" 0.0", " 0");
      +  }
      +
      +  private String sort(String s) {
      +    String[] lines = s.split("\n");
      +    Arrays.sort(lines);
      +    return String.join("\n", lines);
      +  }
      +
      +  private String fixTimestamps(String s) {
      +    // Example of a "_created" timestamp in orig format: 1.694464002939E9
      +    // Example of a "_created" timestamp in new format: 1694464002.939
      +    // The following regex translates the orig timestamp to the new timestamp
      +    return s.replaceAll("1\\.([0-9]{9})([0-9]{3})E9", "1$1.$2") // Example: 1.694464002939E9
      +        .replaceAll("1\\.([0-9]{9})([0-9]{2})E9", "1$1.$20") // Example: 1.69460725747E9
      +        .replaceAll("1\\.([0-9]{9})([0-9])E9", "1$1.$200") // Example: 1.6946072574E9
      +        .replaceAll("1\\.([0-9]{9})E9", "1$1.000") // Example: 1.712332231E9
      +        .replaceAll("1\\.([0-9]{8})E9", "1$10.000") // Example: 1.71233242E9
      +        .replaceAll("1\\.([0-9]{7})E9", "1$100.000") // Example: 1.7123324E9
      +        .replaceAll("1\\.([0-9]{6})E9", "1$1000.000")
      +        .replaceAll("1\\.([0-9]{5})E9", "1$10000.000")
      +        .replaceAll("1\\.([0-9]{4})E9", "1$100000.000")
      +        .replaceAll("1\\.([0-9]{3})E9", "1$1000000.000")
      +        .replaceAll("1\\.([0-9]{2})E9", "1$10000000.000");
      +  }
      +
      +  private String fixCounts(String s) {
      +    // Example of a "_count" or "_bucket" in orig format: 3.0
      +    // Example of a "_count" or "_bucket" in new format: 3
      +    // The following regex translates the orig bucket counts to the new bucket counts
      +    return s.replaceAll("((_count|_bucket)(\\{[^}]*})? [0-9])\\.0", "$1");
      +  }
      +
      +  private String origOpenMetrics() throws IOException {
      +    StringWriter out = new StringWriter();
      +    TextFormat.writeOpenMetrics100(out, origRegistry.metricFamilySamples());
      +    return out.toString();
      +  }
      +
      +  private String newOpenMetrics() throws IOException {
      +    ByteArrayOutputStream out = new ByteArrayOutputStream();
      +    OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false);
      +    writer.write(out, newRegistry.scrape());
      +    return out.toString(StandardCharsets.UTF_8.name());
      +  }
       }
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java
      index e71cef98e..7ff30a09f 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/src/main/java/io/prometheus/metrics/tracer/common/SpanContext.java
      @@ -6,19 +6,22 @@ public interface SpanContext {
         String EXEMPLAR_ATTRIBUTE_VALUE = "true";
       
         /**
      -   * @return the current trace id, or {@code null} if this call is not happening within a span context.
      +   * @return the current trace id, or {@code null} if this call is not happening within a span
      +   *     context.
          */
         String getCurrentTraceId();
       
         /**
      -   * @return the current span id, or {@code null} if this call is not happening within a span context.
      +   * @return the current span id, or {@code null} if this call is not happening within a span
      +   *     context.
          */
         String getCurrentSpanId();
      -  
      +
         /**
      -   * @return the state of the current Span. If this value is false a component before in the chain take the decision to not record it. Subsequent calling service have
      -   * to respect this value in order not to have partial TraceID with only some Span in it. This value is important to be sure to choose a recorded Trace in Examplar
      -   * sampling process
      +   * @return the state of the current Span. If this value is false a component before in the chain
      +   *     take the decision to not record it. Subsequent calling service have to respect this value
      +   *     in order not to have partial TraceID with only some Span in it. This value is important to
      +   *     be sure to choose a recorded Trace in Examplar sampling process
          */
         boolean isCurrentSpanSampled();
       
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java
      index caecb6055..11d14ed8f 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java
      @@ -3,43 +3,43 @@
       import io.prometheus.metrics.tracer.common.SpanContext;
       import io.prometheus.metrics.tracer.otel.OpenTelemetrySpanContext;
       import io.prometheus.metrics.tracer.otel_agent.OpenTelemetryAgentSpanContext;
      -
       import java.util.concurrent.atomic.AtomicReference;
       
       public class SpanContextSupplier {
       
      -    private static final AtomicReference spanContextRef = new AtomicReference();
      -
      -    public static void setSpanContext(SpanContext spanContext) {
      -        spanContextRef.set(spanContext);
      -    }
      -
      -    public static boolean hasSpanContext() {
      -        return getSpanContext() != null;
      +  private static final AtomicReference spanContextRef =
      +      new AtomicReference();
      +
      +  public static void setSpanContext(SpanContext spanContext) {
      +    spanContextRef.set(spanContext);
      +  }
      +
      +  public static boolean hasSpanContext() {
      +    return getSpanContext() != null;
      +  }
      +
      +  public static SpanContext getSpanContext() {
      +    return spanContextRef.get();
      +  }
      +
      +  static {
      +    try {
      +      if (OpenTelemetrySpanContext.isAvailable()) {
      +        spanContextRef.set(new OpenTelemetrySpanContext());
      +      }
      +    } catch (NoClassDefFoundError ignored) {
      +      // tracer_otel dependency not found
      +    } catch (UnsupportedClassVersionError ignored) {
      +      // OpenTelemetry requires Java 8, but client_java might run on Java 6.
           }
      -
      -    public static SpanContext getSpanContext() {
      -        return spanContextRef.get();
      -    }
      -
      -    static {
      -        try {
      -            if (OpenTelemetrySpanContext.isAvailable()) {
      -                spanContextRef.set(new OpenTelemetrySpanContext());
      -            }
      -        } catch (NoClassDefFoundError ignored) {
      -            // tracer_otel dependency not found
      -        } catch (UnsupportedClassVersionError ignored) {
      -            // OpenTelemetry requires Java 8, but client_java might run on Java 6.
      -        }
      -        try {
      -            if (OpenTelemetryAgentSpanContext.isAvailable()) {
      -                spanContextRef.set(new OpenTelemetryAgentSpanContext());
      -            }
      -        } catch (NoClassDefFoundError ignored) {
      -            // tracer_otel_agent dependency not found
      -        } catch (UnsupportedClassVersionError ignored) {
      -            // OpenTelemetry requires Java 8, but client_java might run on Java 6.
      -        }
      +    try {
      +      if (OpenTelemetryAgentSpanContext.isAvailable()) {
      +        spanContextRef.set(new OpenTelemetryAgentSpanContext());
      +      }
      +    } catch (NoClassDefFoundError ignored) {
      +      // tracer_otel_agent dependency not found
      +    } catch (UnsupportedClassVersionError ignored) {
      +      // OpenTelemetry requires Java 8, but client_java might run on Java 6.
           }
      +  }
       }
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java
      index 36cba7076..3c757ed6b 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java
      @@ -6,9 +6,9 @@
       import io.prometheus.metrics.tracer.common.SpanContext;
       
       /**
      - * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}.
      - * However, the {@code io.opentelemetry.api} package is relocated to
      - * {@code io.opentelemetry.javaagent.shaded.io.opentelemetry.api} in the OpenTelemetry agent.
      + * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}. However, the {@code
      + * io.opentelemetry.api} package is relocated to {@code
      + * io.opentelemetry.javaagent.shaded.io.opentelemetry.api} in the OpenTelemetry agent.
        */
       public class OpenTelemetryAgentSpanContext implements SpanContext {
       
      @@ -21,9 +21,11 @@ public static boolean isAvailable() {
             return true;
           } catch (LinkageError ignored) {
             // NoClassDefFoundError:
      -      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist.
      +      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when
      +      // io.opentelemetry.api.trace.Span did not exist.
             // IncompatibleClassChangeError:
      -      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface.
      +      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext
      +      // was a class, and not an interface.
             return false;
           }
         }
      diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java
      index dd338cea2..73f8d1316 100644
      --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java
      +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/src/main/java/io/prometheus/metrics/tracer/otel/OpenTelemetrySpanContext.java
      @@ -7,7 +7,7 @@
       
       public class OpenTelemetrySpanContext implements SpanContext {
       
      -	public static boolean isAvailable() {
      +  public static boolean isAvailable() {
           try {
             OpenTelemetrySpanContext test = new OpenTelemetrySpanContext();
             test.getCurrentSpanId();
      @@ -16,32 +16,34 @@ public static boolean isAvailable() {
             return true;
           } catch (LinkageError ignored) {
             // NoClassDefFoundError:
      -      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist.
      +      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when
      +      // io.opentelemetry.api.trace.Span did not exist.
             // IncompatibleClassChangeError:
      -      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface.
      +      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext
      +      // was a class, and not an interface.
             return false;
           }
         }
       
      -	@Override
      -	public String getCurrentTraceId() {
      -		String traceId = Span.current().getSpanContext().getTraceId();
      -		return TraceId.isValid(traceId) ? traceId : null;
      -	}
      +  @Override
      +  public String getCurrentTraceId() {
      +    String traceId = Span.current().getSpanContext().getTraceId();
      +    return TraceId.isValid(traceId) ? traceId : null;
      +  }
       
      -	@Override
      -	public String getCurrentSpanId() {
      -		String spanId = Span.current().getSpanContext().getSpanId();
      -		return SpanId.isValid(spanId) ? spanId : null;
      -	}
      +  @Override
      +  public String getCurrentSpanId() {
      +    String spanId = Span.current().getSpanContext().getSpanId();
      +    return SpanId.isValid(spanId) ? spanId : null;
      +  }
       
      -	@Override
      -	public boolean isCurrentSpanSampled() {
      -		return Span.current().getSpanContext().isSampled();
      -	}
      +  @Override
      +  public boolean isCurrentSpanSampled() {
      +    return Span.current().getSpanContext().isSampled();
      +  }
       
      -	@Override
      -	public void markCurrentSpanAsExemplar() {
      -		Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE);
      -	}
      +  @Override
      +  public void markCurrentSpanAsExemplar() {
      +    Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE);
      +  }
       }
      
      From caf86d1839f667c1a2dad58a0ca54d0899f6c3b6 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 08:10:06 +0200
      Subject: [PATCH 375/980] Bump org.apache.maven.plugins:maven-jar-plugin from
       2.4 to 3.4.2 (#995)
      
      Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 2.4 to 3.4.2.
      - [Release notes](https://github.com/apache/maven-jar-plugin/releases)
      - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-2.4...maven-jar-plugin-3.4.2)
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.maven.plugins:maven-jar-plugin
        dependency-type: direct:production
        update-type: version-update:semver-major
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 5ab8f42e2..1cc04dc57 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -110,7 +110,7 @@
                       
                       
                           maven-jar-plugin
      -                    2.4
      +                    3.4.2
                       
                       
                           maven-deploy-plugin
      
      From 959a8ed288dcdbfa3556fc79fc7253c2b4b446e4 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 08:20:15 +0200
      Subject: [PATCH 376/980] Bump org.apache.tomcat.embed:tomcat-embed-core
       (#1004)
      
      Bumps org.apache.tomcat.embed:tomcat-embed-core from 10.1.24 to 10.1.25.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.tomcat.embed:tomcat-embed-core
        dependency-type: direct:production
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       examples/example-exporter-servlet-tomcat/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 1f9df84c5..08fcd39e3 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.24
      +            10.1.25
               
           
       
      
      From a63c9f63451f85317dfded842cbda4ac23b2e8cd Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 08:25:49 +0200
      Subject: [PATCH 377/980] Bump ch.qos.logback:logback-classic (#1013)
      
      Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.2.11 to 1.2.13.
      - [Commits](https://github.com/qos-ch/logback/compare/v_1.2.11...v_1.2.13)
      
      ---
      updated-dependencies:
      - dependency-name: ch.qos.logback:logback-classic
        dependency-type: direct:development
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       .../integration_tests/it_exemplars_otel_agent/pom.xml           | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml
      index 3453178c4..5b81447c6 100644
      --- a/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml
      +++ b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml
      @@ -58,7 +58,7 @@
           
             ch.qos.logback
             logback-classic
      -      1.2.11
      +      1.2.13
             test
           
           
      
      From f2a043963130b2ef673d8ebe4b046216b015007d Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 08:30:48 +0200
      Subject: [PATCH 378/980] Bump io.vertx:vertx-web in
       /simpleclient-archive/simpleclient_vertx4 (#1017)
      
      Bumps io.vertx:vertx-web from 4.3.1 to 4.3.8.
      
      ---
      updated-dependencies:
      - dependency-name: io.vertx:vertx-web
        dependency-type: direct:production
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       simpleclient-archive/simpleclient_vertx4/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/simpleclient-archive/simpleclient_vertx4/pom.xml b/simpleclient-archive/simpleclient_vertx4/pom.xml
      index 5e365bd2a..d3785bbf0 100644
      --- a/simpleclient-archive/simpleclient_vertx4/pom.xml
      +++ b/simpleclient-archive/simpleclient_vertx4/pom.xml
      @@ -50,7 +50,7 @@
               
                   io.vertx
                   vertx-web
      -            4.3.1
      +            4.3.8
                   provided
               
               
      
      From fd816bdef773b7ea9444df1ffd9d2fb35d22a773 Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Wed, 2 Oct 2024 09:25:15 +0200
      Subject: [PATCH 379/980] update gh action trigger condition  (#1019)
      
      * update trigger condition (trying to find out why outside prs don't trigger)
      
      Signed-off-by: Gregor Zeitlinger 
      
      * exclude archive from dependabot
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       .github/dependabot.yml                        | 22 ++++++++++++++++++-
       .github/workflows/build.yml                   |  6 ++++-
       .../integration_tests/it_pushgateway/pom.xml  |  2 +-
       .../pom.xml                                   |  2 +-
       .../simpleclient_logback/pom.xml              |  2 +-
       .../simpleclient_vertx4/pom.xml               |  2 +-
       6 files changed, 30 insertions(+), 6 deletions(-)
      
      diff --git a/.github/dependabot.yml b/.github/dependabot.yml
      index b3a1dddd8..5c739e0bb 100644
      --- a/.github/dependabot.yml
      +++ b/.github/dependabot.yml
      @@ -5,6 +5,26 @@ updates:
           schedule:
             interval: weekly
         - package-ecosystem: maven
      -    directory: "/"
      +    directories:
      +      - prometheus-metrics-bom
      +      - prometheus-metrics-core
      +      - prometheus-metrics-config
      +      - prometheus-metrics-model
      +      - prometheus-metrics-tracer
      +      - prometheus-metrics-exposition-formats
      +      - prometheus-metrics-exporter-common
      +      - prometheus-metrics-exporter-servlet-jakarta
      +      - prometheus-metrics-exporter-servlet-javax
      +      - prometheus-metrics-exporter-httpserver
      +      - prometheus-metrics-exporter-opentelemetry
      +      - prometheus-metrics-exporter-pushgateway
      +      - prometheus-metrics-instrumentation-caffeine
      +      - prometheus-metrics-instrumentation-jvm
      +      - prometheus-metrics-instrumentation-dropwizard5
      +      - prometheus-metrics-instrumentation-guava
      +      - prometheus-metrics-simpleclient-bridge
      +      - examples
      +      - benchmarks
      +      - integration-tests
           schedule:
             interval: daily
      diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
      index 835d4dcde..3592f25ff 100644
      --- a/.github/workflows/build.yml
      +++ b/.github/workflows/build.yml
      @@ -1,6 +1,10 @@
       name: Build
       
      -on: [push]
      +on:
      +  push:
      +    branches: [ "main" ]
      +  pull_request:
      +    branches: [ "main" ]
       
       jobs:
         build:
      diff --git a/simpleclient-archive/integration_tests/it_pushgateway/pom.xml b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml
      index 5fd8c8a5a..2eba31efa 100644
      --- a/simpleclient-archive/integration_tests/it_pushgateway/pom.xml
      +++ b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml
      @@ -36,7 +36,7 @@
           
             ch.qos.logback
             logback-classic
      -      1.2.13
      +      1.2.11
             test
           
           
      diff --git a/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml
      index 061733553..71e8c536a 100644
      --- a/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml
      +++ b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml
      @@ -45,7 +45,7 @@
           
             ch.qos.logback
             logback-classic
      -      1.2.13
      +      1.2.11
           
             
                 jakarta.servlet
      diff --git a/simpleclient-archive/simpleclient_logback/pom.xml b/simpleclient-archive/simpleclient_logback/pom.xml
      index a92b408b4..96f4fb34d 100644
      --- a/simpleclient-archive/simpleclient_logback/pom.xml
      +++ b/simpleclient-archive/simpleclient_logback/pom.xml
      @@ -41,7 +41,7 @@
               
                   ch.qos.logback
                   logback-classic
      -            1.2.13
      +            1.2.11
               
               
       
      diff --git a/simpleclient-archive/simpleclient_vertx4/pom.xml b/simpleclient-archive/simpleclient_vertx4/pom.xml
      index d3785bbf0..5e365bd2a 100644
      --- a/simpleclient-archive/simpleclient_vertx4/pom.xml
      +++ b/simpleclient-archive/simpleclient_vertx4/pom.xml
      @@ -50,7 +50,7 @@
               
                   io.vertx
                   vertx-web
      -            4.3.8
      +            4.3.1
                   provided
               
               
      
      From 12fbc0d0d078f4094c4b2930ca9b765dca9d4ad3 Mon Sep 17 00:00:00 2001
      From: Mickael Maison 
      Date: Wed, 2 Oct 2024 09:45:20 +0200
      Subject: [PATCH 380/980] Various cleanups in instrumentation-jvm (#1016)
      
      * Various cleanups in instrumentation-jvm
      
      Signed-off-by: Mickael Maison 
      
      * Add comment in ProcessMetricsTest.testGoodCase
      
      Signed-off-by: Mickael Maison 
      
      ---------
      
      Signed-off-by: Mickael Maison 
      Co-authored-by: Gregor Zeitlinger 
      ---
       .../jvm/JvmMemoryPoolAllocationMetrics.java   |  4 +-
       .../jvm/JvmNativeMemoryMetrics.java           |  8 +--
       .../jvm/JvmThreadsMetrics.java                |  2 +-
       .../instrumentation/jvm/ProcessMetrics.java   |  2 +-
       .../jvm/JvmBufferPoolMetricsTest.java         |  4 +-
       .../jvm/JvmClassLoadingMetricsTest.java       |  6 +--
       .../jvm/JvmCompilationMetricsTest.java        | 10 ++--
       .../jvm/JvmGarbageCollectorMetricsTest.java   | 10 ++--
       .../jvm/JvmMemoryMetricsTest.java             | 22 ++++----
       .../JvmMemoryPoolAllocationMetricsTest.java   |  4 +-
       .../jvm/JvmNativeMemoryMetricsTest.java       | 13 +++--
       .../jvm/JvmRuntimeInfoMetricTest.java         |  4 +-
       .../jvm/JvmThreadsMetricsTest.java            | 19 +++----
       .../jvm/ProcessMetricsTest.java               | 50 ++++++++++++-------
       14 files changed, 82 insertions(+), 76 deletions(-)
      
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      index 09aab0659..3bd39a59f 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java
      @@ -49,13 +49,11 @@ public class JvmMemoryPoolAllocationMetrics {
         private static final String JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL =
             "jvm_memory_pool_allocated_bytes_total";
       
      -  private final PrometheusProperties config;
         private final List garbageCollectorBeans;
       
         private JvmMemoryPoolAllocationMetrics(
             List garbageCollectorBeans, PrometheusProperties config) {
           this.garbageCollectorBeans = garbageCollectorBeans;
      -    this.config = config;
         }
       
         private void register(PrometheusRegistry registry) {
      @@ -80,7 +78,7 @@ private void register(PrometheusRegistry registry) {
       
         static class AllocationCountingNotificationListener implements NotificationListener {
       
      -    private final Map lastMemoryUsage = new HashMap();
      +    private final Map lastMemoryUsage = new HashMap<>();
           private final Counter counter;
       
           AllocationCountingNotificationListener(Counter counter) {
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java
      index 4f02823f1..e350568ac 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java
      @@ -134,12 +134,8 @@ private Consumer makeCallback(Boolean reserved) {
               Matcher matcher = pattern.matcher(summary);
               while (matcher.find()) {
                 String category = matcher.group(1);
      -          long value;
      -          if (reserved) {
      -            value = Long.parseLong(matcher.group(2));
      -          } else {
      -            value = Long.parseLong(matcher.group(3));
      -          }
      +          long value =
      +              reserved ? Long.parseLong(matcher.group(2)) : Long.parseLong(matcher.group(3));
                 callback.call(value, category);
               }
             }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      index 4027551ac..8b6e57ac1 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java
      @@ -155,7 +155,7 @@ private Map getThreadStateCountMap(ThreadMXBean threadBean) {
           ThreadInfo[] allThreads = threadBean.getThreadInfo(threadIds, 0);
       
           // Initialize the map with all thread states
      -    HashMap threadCounts = new HashMap();
      +    Map threadCounts = new HashMap<>();
           for (Thread.State state : Thread.State.values()) {
             threadCounts.put(state.name(), 0);
           }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      index f875c104f..bd7fb14b1 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java
      @@ -72,7 +72,7 @@ public class ProcessMetrics {
         private static final String PROCESS_VIRTUAL_MEMORY_BYTES = "process_virtual_memory_bytes";
         private static final String PROCESS_RESIDENT_MEMORY_BYTES = "process_resident_memory_bytes";
       
      -  private static final File PROC_SELF_STATUS = new File("/proc/self/status");
      +  static final File PROC_SELF_STATUS = new File("/proc/self/status");
       
         private final PrometheusProperties config;
         private final OperatingSystemMXBean osBean;
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
      index df6dddf99..cad2e8eb5 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.times;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
      @@ -11,7 +12,6 @@
       import java.io.IOException;
       import java.lang.management.BufferPoolMXBean;
       import java.util.Arrays;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
      @@ -59,7 +59,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
      index 4196031bf..0d8d77b51 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.times;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
      @@ -10,14 +11,13 @@
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
       import java.io.IOException;
       import java.lang.management.ClassLoadingMXBean;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class JvmClassLoadingMetricsTest {
       
      -  private ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class);
      +  private final ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class);
       
         @Before
         public void setUp() {
      @@ -45,7 +45,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_classes_unloaded_total 500.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
      index 780d6a949..e966d0c11 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
       import static org.mockito.internal.verification.VerificationModeFactory.times;
      @@ -10,18 +11,17 @@
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
       import java.io.IOException;
       import java.lang.management.CompilationMXBean;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class JvmCompilationMetricsTest {
       
      -  private CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class);
      +  private final CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class);
       
         @Before
         public void setUp() {
      -    when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000l);
      +    when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000L);
           when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true);
         }
       
      @@ -39,7 +39,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_compilation_time_seconds_total 10.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -54,6 +54,6 @@ public void testIgnoredMetricNotScraped() {
           MetricSnapshots snapshots = registry.scrape(filter);
       
           verify(mockCompilationBean, times(0)).getTotalCompilationTime();
      -    Assert.assertEquals(0, snapshots.size());
      +    assertEquals(0, snapshots.size());
         }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
      index 67ba4f064..5bbf3a427 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.times;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
      @@ -12,15 +13,14 @@
       import java.lang.management.GarbageCollectorMXBean;
       import java.util.Arrays;
       import java.util.concurrent.TimeUnit;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class JvmGarbageCollectorMetricsTest {
       
      -  private GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class);
      -  private GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class);
      +  private final GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class);
      +  private final GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class);
       
         @Before
         public void setUp() {
      @@ -51,7 +51,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -67,6 +67,6 @@ public void testIgnoredMetricNotScraped() {
       
           verify(mockGcBean1, times(0)).getCollectionTime();
           verify(mockGcBean1, times(0)).getCollectionCount();
      -    Assert.assertEquals(0, snapshots.size());
      +    assertEquals(0, snapshots.size());
         }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
      index 167299291..94bdbbee3 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.times;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
      @@ -13,22 +14,21 @@
       import java.lang.management.MemoryPoolMXBean;
       import java.lang.management.MemoryUsage;
       import java.util.Arrays;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class JvmMemoryMetricsTest {
       
      -  private MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class);
      -  private MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class);
      -  private MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class);
      -  private MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class);
      -  private MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class);
      -  private MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class);
      -  private MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class);
      -  private MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class);
      -  private MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class);
      +  private final MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class);
      +  private final MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class);
      +  private final MemoryPoolMXBean mockPoolsBeanOldGen = Mockito.mock(MemoryPoolMXBean.class);
      +  private final MemoryUsage memoryUsageHeap = Mockito.mock(MemoryUsage.class);
      +  private final MemoryUsage memoryUsageNonHeap = Mockito.mock(MemoryUsage.class);
      +  private final MemoryUsage memoryUsagePoolEdenSpace = Mockito.mock(MemoryUsage.class);
      +  private final MemoryUsage memoryUsagePoolOldGen = Mockito.mock(MemoryUsage.class);
      +  private final MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class);
      +  private final MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class);
       
         @Before
         public void setUp() {
      @@ -154,7 +154,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
      index 8f90a9cb8..9a75e9e15 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static org.junit.Assert.assertEquals;
      +import static org.junit.Assert.fail;
       
       import io.prometheus.metrics.core.metrics.Counter;
       import io.prometheus.metrics.instrumentation.jvm.JvmMemoryPoolAllocationMetrics.AllocationCountingNotificationListener;
      @@ -8,7 +9,6 @@
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.MetricSnapshot;
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      -import org.junit.Assert;
       import org.junit.Test;
       
       public class JvmMemoryPoolAllocationMetricsTest {
      @@ -60,7 +60,7 @@ private double getCountByPool(String metricName, String poolName, MetricSnapshot
               }
             }
           }
      -    Assert.fail("pool " + poolName + " not found.");
      +    fail("pool " + poolName + " not found.");
           return 0.0;
         }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java
      index 13d1cc99f..e5a90e38d 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java
      @@ -1,18 +1,17 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.Mockito.when;
       
       import io.prometheus.metrics.config.PrometheusProperties;
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
       import java.io.IOException;
      -import junit.framework.TestCase;
      -import org.junit.Assert;
       import org.junit.Test;
       import org.mockito.Mockito;
       
      -public class JvmNativeMemoryMetricsTest extends TestCase {
      +public class JvmNativeMemoryMetricsTest {
       
         @Test
         public void testNativeMemoryTrackingFail() throws IOException {
      @@ -28,7 +27,7 @@ public void testNativeMemoryTrackingFail() throws IOException {
       
           String expected = "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -45,7 +44,7 @@ public void testNativeMemoryTrackingEmpty() throws IOException {
       
           String expected = "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -63,7 +62,7 @@ public void testNativeMemoryTrackingDisabled() throws IOException {
       
           String expected = "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -226,6 +225,6 @@ public void testNativeMemoryTrackingEnabled() throws IOException {
                   + "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
      index a99178234..1dcaff2d9 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java
      @@ -1,11 +1,11 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       
       import io.prometheus.metrics.model.registry.PrometheusRegistry;
       import io.prometheus.metrics.model.snapshots.MetricSnapshots;
       import java.io.IOException;
      -import org.junit.Assert;
       import org.junit.Test;
       
       public class JvmRuntimeInfoMetricTest {
      @@ -27,6 +27,6 @@ public void testGoodCase() throws IOException {
                   + "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      index e454082b2..3aaa5b94b 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java
      @@ -1,6 +1,8 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
      +import static org.junit.Assert.assertNotNull;
       import static org.mockito.Mockito.times;
       import static org.mockito.Mockito.verify;
       import static org.mockito.Mockito.when;
      @@ -16,17 +18,16 @@
       import java.util.HashMap;
       import java.util.Map;
       import java.util.concurrent.CountDownLatch;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class JvmThreadsMetricsTest {
       
      -  private ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class);
      -  private ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class);
      -  private ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class);
      -  private ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class);
      +  private final ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class);
      +  private final ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class);
      +  private final ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class);
      +  private final ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class);
       
         @Before
         public void setUp() {
      @@ -84,7 +85,7 @@ public void testGoodCase() throws IOException {
                   + "jvm_threads_state{state=\"WAITING\"} 0.0\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -133,9 +134,9 @@ public void testInvalidThreadIds() {
       
             Map actual = getCountByState(registry.scrape());
       
      -      Assert.assertEquals(expected.size(), actual.size());
      +      assertEquals(expected.size(), actual.size());
             for (String threadState : expected.keySet()) {
      -        Assert.assertEquals(expected.get(threadState), actual.get(threadState), 0.0);
      +        assertEquals(expected.get(threadState), actual.get(threadState), 0.0);
             }
           } finally {
             for (int i = 0; i < numberOfInvalidThreadIds; i++) {
      @@ -151,7 +152,7 @@ private Map getCountByState(MetricSnapshots snapshots) {
               for (GaugeSnapshot.GaugeDataPointSnapshot data :
                   ((GaugeSnapshot) snapshot).getDataPoints()) {
                 String state = data.getLabels().get("state");
      -          Assert.assertNotNull(state);
      +          assertNotNull(state);
                 result.put(state, data.getValue());
               }
             }
      diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
      index 41a5b514b..6dafa1fb3 100644
      --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
      +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java
      @@ -1,6 +1,7 @@
       package io.prometheus.metrics.instrumentation.jvm;
       
       import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat;
      +import static org.junit.Assert.assertEquals;
       import static org.mockito.ArgumentMatchers.any;
       import static org.mockito.ArgumentMatchers.eq;
       import static org.mockito.Mockito.times;
      @@ -14,20 +15,19 @@
       import java.io.IOException;
       import java.lang.management.RuntimeMXBean;
       import java.util.concurrent.TimeUnit;
      -import org.junit.Assert;
       import org.junit.Before;
       import org.junit.Test;
       import org.mockito.Mockito;
       
       public class ProcessMetricsTest {
       
      -  private com.sun.management.UnixOperatingSystemMXBean sunOsBean =
      +  private final com.sun.management.UnixOperatingSystemMXBean sunOsBean =
             Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class);
      -  private java.lang.management.OperatingSystemMXBean javaOsBean =
      +  private final java.lang.management.OperatingSystemMXBean javaOsBean =
             Mockito.mock(java.lang.management.OperatingSystemMXBean.class);
      -  private ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class);
      -  private ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class);
      -  private RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class);
      +  private final ProcessMetrics.Grepper linuxGrepper = Mockito.mock(ProcessMetrics.Grepper.class);
      +  private final ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class);
      +  private final RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class);
       
         @Before
         public void setUp() throws IOException {
      @@ -62,22 +62,34 @@ public void testGoodCase() throws IOException {
                   + "process_max_fds 244.0\n"
                   + "# TYPE process_open_fds gauge\n"
                   + "# HELP process_open_fds Number of open file descriptors.\n"
      -            + "process_open_fds 127.0\n"
      -            + "# TYPE process_resident_memory_bytes gauge\n"
      -            + "# UNIT process_resident_memory_bytes bytes\n"
      -            + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n"
      -            + "process_resident_memory_bytes 1036288.0\n"
      +            + "process_open_fds 127.0\n";
      +    // To allow running this test in non-linux environments
      +    if (ProcessMetrics.PROC_SELF_STATUS.canRead()) {
      +      expected +=
      +          ""
      +              + "# TYPE process_resident_memory_bytes gauge\n"
      +              + "# UNIT process_resident_memory_bytes bytes\n"
      +              + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n"
      +              + "process_resident_memory_bytes 1036288.0\n";
      +    }
      +    expected +=
      +        ""
                   + "# TYPE process_start_time_seconds gauge\n"
                   + "# UNIT process_start_time_seconds seconds\n"
                   + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n"
      -            + "process_start_time_seconds 37.1\n"
      -            + "# TYPE process_virtual_memory_bytes gauge\n"
      -            + "# UNIT process_virtual_memory_bytes bytes\n"
      -            + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n"
      -            + "process_virtual_memory_bytes 6180864.0\n"
      -            + "# EOF\n";
      +            + "process_start_time_seconds 37.1\n";
      +    // To allow running this test in non-linux environments
      +    if (ProcessMetrics.PROC_SELF_STATUS.canRead()) {
      +      expected +=
      +          ""
      +              + "# TYPE process_virtual_memory_bytes gauge\n"
      +              + "# UNIT process_virtual_memory_bytes bytes\n"
      +              + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n"
      +              + "process_virtual_memory_bytes 6180864.0\n";
      +    }
      +    expected += "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      @@ -98,7 +110,7 @@ public void testMinimal() throws IOException {
                   + "process_start_time_seconds 37.1\n"
                   + "# EOF\n";
       
      -    Assert.assertEquals(expected, convertToOpenMetricsFormat(snapshots));
      +    assertEquals(expected, convertToOpenMetricsFormat(snapshots));
         }
       
         @Test
      
      From 3d39267cc77381938b50eae2135821386a25d99f Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Wed, 2 Oct 2024 09:57:57 +0200
      Subject: [PATCH 381/980] Limit to 1 open PR at a time until
       https://github.com/dependabot/dependabot-core/issues/10415 is fixed (#1061)
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       .github/dependabot.yml | 2 ++
       1 file changed, 2 insertions(+)
      
      diff --git a/.github/dependabot.yml b/.github/dependabot.yml
      index 5c739e0bb..e6d0d3adc 100644
      --- a/.github/dependabot.yml
      +++ b/.github/dependabot.yml
      @@ -5,6 +5,8 @@ updates:
           schedule:
             interval: weekly
         - package-ecosystem: maven
      +    open-pull-requests-limit: 1 # Limit to 1 open PR at a time until https://github.com/dependabot/dependabot-core/issues/10415 is fixed
      +    # excluding simpleclient_archive from the update is not possible, only includes are supported
           directories:
             - prometheus-metrics-bom
             - prometheus-metrics-core
      
      From 0cd8711638f79994c99a94a8ef59f1944d87f84e Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 10:03:44 +0200
      Subject: [PATCH 382/980] Bump org.apache.maven.plugins:maven-install-plugin
       (#1060)
      
      Bumps [org.apache.maven.plugins:maven-install-plugin](https://github.com/apache/maven-install-plugin) from 2.4 to 3.1.3.
      - [Release notes](https://github.com/apache/maven-install-plugin/releases)
      - [Commits](https://github.com/apache/maven-install-plugin/compare/maven-install-plugin-2.4...maven-install-plugin-3.1.3)
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.maven.plugins:maven-install-plugin
        dependency-type: direct:production
        update-type: version-update:semver-major
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 1cc04dc57..01cb6cd84 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -94,7 +94,7 @@
                       
                       
                           maven-install-plugin
      -                    2.4
      +                    3.1.3
                       
                       
                           maven-resources-plugin
      
      From 06e873a9d64f29edb96df979fe91a0f69ad74819 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 10:12:04 +0200
      Subject: [PATCH 383/980] Bump org.apache.maven.plugins:maven-enforcer-plugin
       (#1059)
      
      Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 1.4.1 to 3.5.0.
      - [Release notes](https://github.com/apache/maven-enforcer/releases)
      - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-1.4.1...enforcer-3.5.0)
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin
        dependency-type: direct:production
        update-type: version-update:semver-major
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 01cb6cd84..59dd75a1e 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -155,7 +155,7 @@
                       
                       
                           maven-enforcer-plugin
      -                    1.4.1
      +                    3.5.0
                       
                       
                           com.diffplug.spotless
      
      From 26b249a349a9f8d46509edcd04568dbdf006cd2b Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 10:29:10 +0200
      Subject: [PATCH 384/980] Bump org.apache.tomcat.embed:tomcat-embed-core in
       /examples (#1024)
      
      Bumps org.apache.tomcat.embed:tomcat-embed-core from 10.1.24 to 10.1.30.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.tomcat.embed:tomcat-embed-core
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       .../example-greeting-service/pom.xml                            | 2 +-
       .../example-hello-world-app/pom.xml                             | 2 +-
       examples/example-exporter-servlet-tomcat/pom.xml                | 2 +-
       3 files changed, 3 insertions(+), 3 deletions(-)
      
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 72ebcbedd..38177339d 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.24
      +            10.1.30
               
           
       
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index ae0b36799..1661521a7 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.24
      +            10.1.30
               
           
       
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 08fcd39e3..6d59ed9ca 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -50,7 +50,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.25
      +            10.1.30
               
           
       
      
      From c25cd5a8c77ba758cf84bbff91b0fa9edf6c694d Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 10:42:32 +0200
      Subject: [PATCH 385/980] Bump opentelemetry.version from 1.30.1 to 1.42.1
       (#1001)
      
      * Bump opentelemetry.version from 1.30.1 to 1.42.1
      
      Bumps `opentelemetry.version` from 1.30.1 to 1.42.1.
      
      Updates `io.opentelemetry:opentelemetry-api` from 1.30.1 to 1.42.1
      - [Release notes](https://github.com/open-telemetry/opentelemetry-java/releases)
      - [Changelog](https://github.com/open-telemetry/opentelemetry-java/blob/main/CHANGELOG.md)
      - [Commits](https://github.com/open-telemetry/opentelemetry-java/compare/v1.30.1...v1.42.1)
      
      Updates `io.opentelemetry:opentelemetry-sdk` from 1.30.1 to 1.42.1
      - [Release notes](https://github.com/open-telemetry/opentelemetry-java/releases)
      - [Changelog](https://github.com/open-telemetry/opentelemetry-java/blob/main/CHANGELOG.md)
      - [Commits](https://github.com/open-telemetry/opentelemetry-java/compare/v1.30.1...v1.42.1)
      
      Updates `io.opentelemetry:opentelemetry-sdk-testing` from 1.30.1 to 1.42.1
      - [Release notes](https://github.com/open-telemetry/opentelemetry-java/releases)
      - [Changelog](https://github.com/open-telemetry/opentelemetry-java/blob/main/CHANGELOG.md)
      - [Commits](https://github.com/open-telemetry/opentelemetry-java/compare/v1.30.1...v1.42.1)
      
      ---
      updated-dependencies:
      - dependency-name: io.opentelemetry:opentelemetry-api
        dependency-type: direct:production
        update-type: version-update:semver-minor
      - dependency-name: io.opentelemetry:opentelemetry-sdk
        dependency-type: direct:production
        update-type: version-update:semver-minor
      - dependency-name: io.opentelemetry:opentelemetry-sdk-testing
        dependency-type: direct:production
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      
      * update otel
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: dependabot[bot] 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       benchmarks/pom.xml                                            | 2 +-
       prometheus-metrics-exporter-opentelemetry/pom.xml             | 2 +-
       .../prometheus-metrics-shaded-opentelemetry/pom.xml           | 4 ++--
       prometheus-metrics-tracer/pom.xml                             | 2 +-
       4 files changed, 5 insertions(+), 5 deletions(-)
      
      diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
      index f9d2f1866..80a201a20 100644
      --- a/benchmarks/pom.xml
      +++ b/benchmarks/pom.xml
      @@ -19,7 +19,7 @@
               1.37
               0.16.0
               3.0.2
      -        1.30.1
      +        1.42.1
           
       
           
      diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml
      index 6c576eae6..448390bb2 100644
      --- a/prometheus-metrics-exporter-opentelemetry/pom.xml
      +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml
      @@ -17,7 +17,7 @@
           
       
           
      -        1.38.0
      +        1.42.1
               io.prometheus.metrics.exporter.opentelemetry
           
       
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      index 415735290..eaf67fa89 100644
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      +++ b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml
      @@ -16,8 +16,8 @@
           
       
           
      -        1.38.0
      -        1_38_0
      +        1.42.1
      +        1_42_1
           
       
           
      diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml
      index 2d10bca44..0a22ec790 100644
      --- a/prometheus-metrics-tracer/pom.xml
      +++ b/prometheus-metrics-tracer/pom.xml
      @@ -37,7 +37,7 @@
             
               io.opentelemetry
               opentelemetry-api
      -        1.38.0
      +        1.42.1
             
           
         
      
      From 131648417a49256a73208b56c1737708f3153108 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 10:49:43 +0200
      Subject: [PATCH 386/980] Bump org.apache.tomcat.embed:tomcat-embed-core from
       10.1.24 to 10.1.30 (#996)
      
      Bumps org.apache.tomcat.embed:tomcat-embed-core from 10.1.24 to 10.1.30.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.tomcat.embed:tomcat-embed-core
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml       | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index bb78e0543..306b2eea5 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -45,7 +45,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            10.1.24
      +            10.1.30
               
           
       
      
      From b7a0be4bcecb1247e7bc53cf399248bc96e04ff3 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 2 Oct 2024 15:35:36 +0200
      Subject: [PATCH 387/980] Bump org.apache.felix:maven-bundle-plugin in
       /prometheus-metrics-tracer (#1083)
      
      Bumps org.apache.felix:maven-bundle-plugin from 2.4.0 to 5.1.9.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.felix:maven-bundle-plugin
        dependency-type: direct:production
        update-type: version-update:semver-major
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 59dd75a1e..f55a754c2 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -220,7 +220,7 @@
                   
                       org.apache.felix
                       maven-bundle-plugin
      -                2.4.0
      +                5.1.9
                       true
                       
                           
      
      From 2ca4dc8faafdff8c9101ddc37385932b60a9266a Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 7 Oct 2024 08:18:37 +0200
      Subject: [PATCH 388/980] Bump org.apache.felix:maven-bundle-plugin (#1080)
      
      Bumps org.apache.felix:maven-bundle-plugin from 2.4.0 to 5.1.9.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.felix:maven-bundle-plugin
        dependency-type: direct:production
        update-type: version-update:semver-major
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      
      From 0327d2f79bb057813ed7c527abfc9303f0fca939 Mon Sep 17 00:00:00 2001
      From: Mickael Maison 
      Date: Mon, 7 Oct 2024 10:14:16 +0200
      Subject: [PATCH 389/980] Various cleanups in prometheus-metrics-core (#1085)
      
      Signed-off-by: Mickael Maison 
      ---
       .../core/exemplars/ExemplarSampler.java       |   2 +-
       .../metrics/core/metrics/Buffer.java          |   2 +-
       .../metrics/core/metrics/CKMSQuantiles.java   |   4 +-
       .../metrics/core/metrics/Histogram.java       |  14 +-
       .../metrics/core/metrics/StatefulMetric.java  |   4 +-
       .../exemplars/SpanContextSupplierTest.java    |   2 +-
       .../core/metrics/CKMSQuantilesTest.java       |   8 +-
       .../metrics/core/metrics/CounterTest.java     |  54 ++---
       .../core/metrics/CounterWithCallbackTest.java |  38 +++-
       .../metrics/core/metrics/GaugeTest.java       |  20 +-
       .../core/metrics/GaugeWithCallbackTest.java   |  38 +++-
       .../metrics/core/metrics/HistogramTest.java   |  51 ++---
       .../metrics/core/metrics/InfoTest.java        |  23 +-
       .../core/metrics/SlidingWindowTest.java       |   7 +-
       .../metrics/core/metrics/StateSetTest.java    |  36 ++--
       .../core/metrics/StatefulMetricTest.java      |  26 +--
       .../metrics/core/metrics/SummaryTest.java     | 197 +++++++++++++++++-
       .../core/metrics/SummaryWithCallbackTest.java |  49 ++++-
       .../metrics/core/metrics/TestUtil.java        |   7 +-
       19 files changed, 452 insertions(+), 130 deletions(-)
      
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      index b606d5239..0d4a71f63 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java
      @@ -34,7 +34,7 @@ public class ExemplarSampler {
         private final Exemplar[] exemplars;
         private final Exemplar[]
             customExemplars; // Separate from exemplars, because we don't want custom exemplars
      -  // to be overwritten by automatic exemplar sampling. exemplars.lengt == customExemplars.length
      +  // to be overwritten by automatic exemplar sampling. exemplars.length == customExemplars.length
         private final AtomicBoolean acceptingNewExemplars = new AtomicBoolean(true);
         private final AtomicBoolean acceptingNewCustomExemplars = new AtomicBoolean(true);
         private final SpanContext
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java
      index 113a85d55..720c8228c 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java
      @@ -54,7 +54,7 @@  T run(
           int bufferSize;
           T result;
           synchronized (runLock) {
      -      Long count = observationCount.getAndAdd(signBit);
      +      long count = observationCount.getAndAdd(signBit);
             while (!complete.apply(count)) {
               Thread.yield();
             }
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java
      index c86f17c21..adfd5c6d8 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java
      @@ -38,7 +38,7 @@ final class CKMSQuantiles {
         int n = 0;
       
         /** List of sampled observations, ordered by Sample.value. */
      -  final LinkedList samples = new LinkedList();
      +  final LinkedList samples = new LinkedList<>();
       
         /**
          * Compress is called every compressInterval inserts. Note that the buffer is flushed whenever
      @@ -127,7 +127,7 @@ private void insertBefore(ListIterator iterator, double value, int r) {
         public double get(double q) {
           flush();
       
      -    if (samples.size() == 0) {
      +    if (samples.isEmpty()) {
             return Double.NaN;
           }
       
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      index 494f7fded..2952222c6 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java
      @@ -481,8 +481,8 @@ private boolean maybeReset() {
             nativeZeroCount.reset();
             count.reset();
             sum.reset();
      -      for (int i = 0; i < classicBuckets.length; i++) {
      -        classicBuckets[i].reset();
      +      for (LongAdder classicBucket : classicBuckets) {
      +        classicBucket.reset();
             }
             nativeZeroThreshold = nativeMinZeroThreshold;
             nativeSchema = Histogram.this.nativeInitialSchema;
      @@ -592,11 +592,7 @@ private void doubleBucketWidth(Map buckets) {
             buckets.clear();
             for (i = 0; i < keys.length; i++) {
               int index = (keys[i] + 1) / 2;
      -        LongAdder count = buckets.get(index);
      -        if (count == null) {
      -          count = new LongAdder();
      -          buckets.put(index, count);
      -        }
      +        LongAdder count = buckets.computeIfAbsent(index, k -> new LongAdder());
               count.add(values[i]);
             }
           }
      @@ -789,9 +785,9 @@ public Builder classicLinearUpperBounds(double start, double width, int count) {
           }
       
           /**
      -     * Create classic histogram bucxkets with exponential boundaries.
      +     * Create classic histogram buckets with exponential boundaries.
            *
      -     * 

      Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket bounaries + *

      Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket boundaries * {@code [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]} * * @param start is the first bucket boundary diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 188a0c15f..dc61b943d 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -48,7 +48,7 @@ protected StatefulMetric(Builder builder) { protected abstract MetricSnapshot collect(List labels, List metricData); public MetricSnapshot collect() { - if (labelNames.length == 0 && data.size() == 0) { + if (labelNames.length == 0 && data.isEmpty()) { // This is a metric without labels that has not been used yet. Initialize the data on the fly. labelValues(); } @@ -138,7 +138,7 @@ protected T getNoLabels() { } protected MetricsProperties[] getMetricProperties( - Builder builder, PrometheusProperties prometheusProperties) { + Builder builder, PrometheusProperties prometheusProperties) { String metricName = getMetadata().getName(); if (prometheusProperties.getMetricProperties(metricName) != null) { return new MetricsProperties[] { diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java index b1409b142..cc7005c77 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java @@ -42,7 +42,7 @@ public void markCurrentSpanAsExemplar() {} new ExemplarSamplerConfig( 10, // min retention period in milliseconds 20, // max retention period in milliseconds - 5, // sample interval in millisecnods + 5, // sample interval in milliseconds 1, // number of exemplars null // histogram upper bounds ); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java index e8adc42fe..326b0a463 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java @@ -1,6 +1,8 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import io.prometheus.metrics.core.metrics.CKMSQuantiles.Quantile; import java.util.*; @@ -233,7 +235,7 @@ public void testGetGaussian() { new NormalDistribution( rand, mean, stddev, NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY); - List quantiles = new ArrayList(); + List quantiles = new ArrayList<>(); quantiles.add(new Quantile(0.10, 0.001)); quantiles.add(new Quantile(0.50, 0.01)); quantiles.add(new Quantile(0.90, 0.001)); @@ -297,7 +299,7 @@ public void testIllegalArgumentException() { } private List shuffledValues(int n, Random random) { - List result = new ArrayList(n); + List result = new ArrayList<>(n); for (int i = 0; i < n; i++) { result.add(i + 1.0); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 435c5b8fe..0c1408c56 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -2,6 +2,8 @@ import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.rules.ExpectedException.none; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -14,9 +16,9 @@ import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; +import java.util.Arrays; import java.util.Iterator; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -24,11 +26,11 @@ public class CounterTest { - Counter noLabels; - Counter labels; + private Counter noLabels; + private Counter labels; private static final long exemplarSampleIntervalMillis = 10; private static final long exemplarMinAgeMillis = 100; - SpanContext origSpanContext; + private SpanContext origSpanContext; @Rule public final ExpectedException thrown = none(); @@ -53,7 +55,10 @@ private CounterSnapshot.CounterDataPointSnapshot getData(Counter counter, String return counter.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) .findAny() - .orElseThrow(() -> new RuntimeException("counter with labels " + labels + " not found")); + .orElseThrow( + () -> + new RuntimeException( + "counter with labels " + Arrays.toString(labels) + " not found")); } private double getValue(Counter counter, String... labels) { @@ -61,7 +66,7 @@ private double getValue(Counter counter, String... labels) { } private int getNumberOfLabels(Counter counter) { - return ((CounterSnapshot) counter.collect()).getDataPoints().size(); + return counter.collect().getDataPoints().size(); } @Test @@ -131,30 +136,30 @@ public void testSnapshotComplete() { .build(); counter.labelValues("/", "200").inc(2); counter.labelValues("/", "500").inc(); - CounterSnapshot snapshot = (CounterSnapshot) counter.collect(); - Assert.assertEquals("test_seconds", snapshot.getMetadata().getName()); - Assert.assertEquals("seconds", snapshot.getMetadata().getUnit().toString()); - Assert.assertEquals("help message", snapshot.getMetadata().getHelp()); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + CounterSnapshot snapshot = counter.collect(); + assertEquals("test_seconds", snapshot.getMetadata().getName()); + assertEquals("seconds", snapshot.getMetadata().getUnit().toString()); + assertEquals("help message", snapshot.getMetadata().getHelp()); + assertEquals(2, snapshot.getDataPoints().size()); Iterator iter = snapshot.getDataPoints().iterator(); // data is ordered by labels, so 200 comes before 500 CounterSnapshot.CounterDataPointSnapshot data = iter.next(); - Assert.assertEquals( + assertEquals( Labels.of( "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"), data.getLabels()); - Assert.assertEquals(2, data.getValue(), 0.0001); - Assert.assertTrue(data.getCreatedTimestampMillis() >= before); - Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + assertEquals(2, data.getValue(), 0.0001); + assertTrue(data.getCreatedTimestampMillis() >= before); + assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); // 500 data = iter.next(); - Assert.assertEquals( + assertEquals( Labels.of( "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "500"), data.getLabels()); - Assert.assertEquals(1, data.getValue(), 0.0001); - Assert.assertTrue(data.getCreatedTimestampMillis() >= before); - Assert.assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + assertEquals(1, data.getValue(), 0.0001); + assertTrue(data.getCreatedTimestampMillis() >= before); + assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); } @Test @@ -175,7 +180,7 @@ public void testIncWithExemplar() throws Exception { private void assertExemplar(Counter counter, double value, String... labels) { Exemplar exemplar = getData(counter).getExemplar(); - Assert.assertEquals(value, exemplar.getValue(), 0.0001); + assertEquals(value, exemplar.getValue(), 0.0001); assertEquals(Labels.of(labels), exemplar.getLabels()); } @@ -230,10 +235,7 @@ public String getCurrentSpanId() { @Override public boolean isCurrentSpanSampled() { callNumber++; - if (callNumber == 2) { - return false; - } - return true; + return callNumber != 2; } @Override @@ -289,9 +291,9 @@ public void testExemplarSamplerDisabled() { .withoutExemplars() .build(); counter.incWithExemplar(3.0, Labels.of("a", "b")); - Assert.assertNull(getData(counter).getExemplar()); + assertNull(getData(counter).getExemplar()); counter.inc(2.0); - Assert.assertNull(getData(counter).getExemplar()); + assertNull(getData(counter).getExemplar()); } @Test(expected = IllegalArgumentException.class) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java index f7c18666d..e4af61bde 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java @@ -1,6 +1,42 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.Test; + public class CounterWithCallbackTest { - // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. + @Test + public void testCounter() { + final AtomicInteger value = new AtomicInteger(1); + List labelValues = Arrays.asList("v1", "v2"); + CounterWithCallback counter = + CounterWithCallback.builder() + .name("counter") + .labelNames("l1", "l2") + .callback( + callback -> callback.call(value.doubleValue(), labelValues.toArray(new String[0]))) + .build(); + CounterSnapshot snapshot = counter.collect(); + + assertEquals(1, snapshot.getDataPoints().size()); + CounterSnapshot.CounterDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); + assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + assertEquals(labelValues.size(), datapoint.getLabels().size()); + + value.incrementAndGet(); + snapshot = counter.collect(); + assertEquals(1, snapshot.getDataPoints().size()); + datapoint = snapshot.getDataPoints().get(0); + assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + } + + @Test(expected = IllegalArgumentException.class) + public void testCounterNoCallback() { + CounterWithCallback.builder().name("counter").labelNames("l1", "l2").build(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java index 678158cbd..0443cc7bf 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java @@ -2,6 +2,7 @@ import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import io.prometheus.metrics.core.datapoints.Timer; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -11,7 +12,6 @@ import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -37,11 +37,10 @@ public void tearDown() { } private GaugeSnapshot.GaugeDataPointSnapshot getData(Gauge gauge, String... labels) { - return ((GaugeSnapshot) gauge.collect()) - .getDataPoints().stream() - .filter(data -> data.getLabels().equals(Labels.of(labels))) - .findAny() - .orElseThrow(RuntimeException::new); + return gauge.collect().getDataPoints().stream() + .filter(data -> data.getLabels().equals(Labels.of(labels))) + .findAny() + .orElseThrow(RuntimeException::new); } private double getValue(Gauge gauge, String... labels) { @@ -153,10 +152,7 @@ public String getCurrentSpanId() { @Override public boolean isCurrentSpanSampled() { callNumber++; - if (callNumber == 2) { - return false; - } - return true; + return callNumber != 2; } @Override @@ -206,8 +202,8 @@ public void markCurrentSpanAsExemplar() {} public void testExemplarSamplerDisabled() { Gauge gauge = Gauge.builder().name("test").withoutExemplars().build(); gauge.setWithExemplar(3.0, Labels.of("a", "b")); - Assert.assertNull(getData(gauge).getExemplar()); + assertNull(getData(gauge).getExemplar()); gauge.inc(2.0); - Assert.assertNull(getData(gauge).getExemplar()); + assertNull(getData(gauge).getExemplar()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java index f8f54aa69..3a6a4ffac 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java @@ -1,6 +1,42 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.Test; + public class GaugeWithCallbackTest { - // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. + @Test + public void testGauge() { + final AtomicInteger value = new AtomicInteger(1); + List labelValues = Arrays.asList("v1", "v2"); + GaugeWithCallback gauge = + GaugeWithCallback.builder() + .name("gauge") + .labelNames("l1", "l2") + .callback( + callback -> callback.call(value.doubleValue(), labelValues.toArray(new String[0]))) + .build(); + GaugeSnapshot snapshot = gauge.collect(); + + assertEquals(1, snapshot.getDataPoints().size()); + GaugeSnapshot.GaugeDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); + assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + assertEquals(labelValues.size(), datapoint.getLabels().size()); + + value.incrementAndGet(); + snapshot = gauge.collect(); + assertEquals(1, snapshot.getDataPoints().size()); + datapoint = snapshot.getDataPoints().get(0); + assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + } + + @Test(expected = IllegalArgumentException.class) + public void testGaugeNoCallback() { + GaugeWithCallback.builder().name("gauge").labelNames("l1", "l2").build(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index da7da5a89..0b9f90260 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -2,7 +2,9 @@ import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -40,7 +42,6 @@ import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -828,7 +829,7 @@ public void testNativeBucketIndexToUpperBound() Histogram.builder().name("test").nativeInitialSchema(schemas[i]).build(); Histogram.DataPoint histogramData = histogram.newDataPoint(); double result = (double) method.invoke(histogramData, schemas[i], indexes[i]); - Assert.assertEquals( + assertEquals( "index=" + indexes[i] + ", schema=" + schemas[i], expectedUpperBounds[i], result, @@ -866,7 +867,7 @@ public void testFindBucketIndex() (double) nativeBucketIndexToUpperBound.invoke( histogram.getNoLabels(), schema, bucketIndex); - Assert.assertTrue( + assertTrue( "Bucket index " + bucketIndex + " with schema " @@ -925,9 +926,8 @@ public void testDefaults() throws IOException { + "} }"; String expectedTextFormat = "" - + // default classic buckets - "# TYPE test histogram\n" + + "# TYPE test histogram\n" + "test_bucket{le=\"0.005\"} 0\n" + "test_bucket{le=\"0.01\"} 0\n" + "test_bucket{le=\"0.025\"} 0\n" @@ -946,13 +946,13 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - Assert.assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); + assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expectedTextFormat, out.toString()); + assertEquals(expectedTextFormat, out.toString()); } @Test @@ -1154,13 +1154,12 @@ private void assertExemplar(Histogram histogram, double value, String... labels) } } Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); - Assert.assertNotNull( - "No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); - Assert.assertEquals(value, exemplar.getValue(), 0.0); - Assert.assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); + assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); + assertEquals(value, exemplar.getValue(), 0.0); + assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); for (int i = 0; i < labels.length; i += 2) { - Assert.assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); - Assert.assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); + assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); + assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); } } @@ -1271,7 +1270,7 @@ public void testDuplicateClassicBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); + assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); } @Test @@ -1281,7 +1280,7 @@ public void testUnsortedBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); + assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); } @Test @@ -1291,7 +1290,7 @@ public void testEmptyBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - Assert.assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); + assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); } @Test @@ -1305,7 +1304,7 @@ public void testBucketsIncludePositiveInfinity() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - Assert.assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); + assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); } @Test @@ -1316,7 +1315,7 @@ public void testLinearBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - Assert.assertEquals( + assertEquals( Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY), upperBounds); } @@ -1473,10 +1472,10 @@ public void testObserveMultithreaded() List snapshots = future.get(5, TimeUnit.SECONDS); long count = 0; for (HistogramSnapshot snapshot : snapshots) { - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertEquals(1, snapshot.getDataPoints().size()); HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream().findFirst().orElseThrow(RuntimeException::new); - Assert.assertTrue( + assertTrue( data.getCount() >= (count + 1000)); // 1000 own observations plus the ones from other threads count = data.getCount(); @@ -1485,11 +1484,10 @@ public void testObserveMultithreaded() maxCount = count; } } - Assert.assertEquals( - nThreads * 10_000, maxCount); // the last collect() has seen all observations - Assert.assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); + assertEquals(nThreads * 10_000, maxCount); // the last collect() has seen all observations + assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); executor.shutdown(); - Assert.assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); + assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); } private HistogramSnapshot.HistogramDataPointSnapshot getData( @@ -1497,6 +1495,9 @@ private HistogramSnapshot.HistogramDataPointSnapshot getData( return histogram.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) .findAny() - .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); + .orElseThrow( + () -> + new RuntimeException( + "histogram with labels " + Arrays.toString(labels) + " not found")); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 4175ae733..e527a3340 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -11,7 +11,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import org.junit.Assert; import org.junit.Test; public class InfoTest { @@ -35,21 +34,21 @@ public void testInfoStrippedFromName() { } @Test - public void testAddAndRemove() throws IOException { + public void testAddAndRemove() { Info info = Info.builder().name("test_info").labelNames("a", "b").build(); - Assert.assertEquals(0, info.collect().getDataPoints().size()); + assertEquals(0, info.collect().getDataPoints().size()); info.addLabelValues("val1", "val2"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); info.addLabelValues("val1", "val2"); // already exist, so no change - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); info.addLabelValues("val2", "val2"); - Assert.assertEquals(2, info.collect().getDataPoints().size()); + assertEquals(2, info.collect().getDataPoints().size()); info.remove("val1", "val3"); // does not exist, so no change - Assert.assertEquals(2, info.collect().getDataPoints().size()); + assertEquals(2, info.collect().getDataPoints().size()); info.remove("val1", "val2"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); info.remove("val2", "val2"); - Assert.assertEquals(0, info.collect().getDataPoints().size()); + assertEquals(0, info.collect().getDataPoints().size()); } @Test @@ -61,9 +60,9 @@ public void testSet() throws IOException { .labelNames("service.version") .build(); info.setLabelValues("1.0.0"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); info.setLabelValues("2.0.0"); - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); assertTextFormat( "target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info); @@ -76,7 +75,7 @@ public void testConstLabelsOnly() throws IOException { .name("target_info") .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) .build(); - Assert.assertEquals(1, info.collect().getDataPoints().size()); + assertEquals(1, info.collect().getDataPoints().size()); assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java index ce43b141c..54639e7b6 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java @@ -1,9 +1,10 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -18,11 +19,11 @@ public void observe(double value) { } void assertValues(double... expectedValues) { - ArrayList expectedList = new ArrayList<>(); + List expectedList = new ArrayList<>(); for (double expectedValue : expectedValues) { expectedList.add(expectedValue); } - Assert.assertEquals( + assertEquals( "Start time: " + startTime + ", current time: " diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java index 776aeacde..ddb2c4e9b 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java @@ -1,7 +1,12 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import java.util.Arrays; import org.junit.Assert; import org.junit.Test; @@ -34,16 +39,16 @@ public void testEnumStateSet() { stateSet.labelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); stateSet.labelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); StateSetSnapshot snapshot = stateSet.collect(); - Assert.assertEquals(2, snapshot.getDataPoints().size()); - Assert.assertEquals(2, getData(stateSet, "environment", "dev").size()); - Assert.assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); - Assert.assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); - Assert.assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); - Assert.assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); - Assert.assertEquals(2, getData(stateSet, "environment", "prod").size()); - Assert.assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); + assertEquals(2, snapshot.getDataPoints().size()); + assertEquals(2, getData(stateSet, "environment", "dev").size()); + assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); + assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); + assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); + assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); + assertEquals(2, getData(stateSet, "environment", "prod").size()); + assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(0)); - Assert.assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); + assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(1)); } @@ -51,12 +56,12 @@ public void testEnumStateSet() { public void testDefaultFalse() { StateSet stateSet = StateSet.builder().name("test").states("state1", "state2", "state3").build(); - Assert.assertEquals(3, getData(stateSet).size()); - Assert.assertEquals("state1", getData(stateSet).getName(0)); + assertEquals(3, getData(stateSet).size()); + assertEquals("state1", getData(stateSet).getName(0)); Assert.assertFalse(getData(stateSet).isTrue(0)); - Assert.assertEquals("state2", getData(stateSet).getName(1)); + assertEquals("state2", getData(stateSet).getName(1)); Assert.assertFalse(getData(stateSet).isTrue(1)); - Assert.assertEquals("state3", getData(stateSet).getName(2)); + assertEquals("state3", getData(stateSet).getName(2)); Assert.assertFalse(getData(stateSet).isTrue(2)); } @@ -64,7 +69,10 @@ private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, St return stateSet.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) .findAny() - .orElseThrow(() -> new RuntimeException("stateset with labels " + labels + " not found")); + .orElseThrow( + () -> + new RuntimeException( + "stateset with labels " + Arrays.toString(labels) + " not found")); } @Test(expected = IllegalStateException.class) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index d77ec6e83..a3ddbcc84 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -1,8 +1,10 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + import java.lang.reflect.Field; import java.util.Map; -import org.junit.Assert; import org.junit.Test; public class StatefulMetricTest { @@ -28,8 +30,8 @@ public void testLabelRemoveWhileCollecting() throws Exception { counter.remove("c", "d"); counter.remove("e", "f"); } - Assert.assertNotNull(entry.getKey()); - Assert.assertNotNull(entry.getValue()); + assertNotNull(entry.getKey()); + assertNotNull(entry.getValue()); } } @@ -39,31 +41,31 @@ public void testClear() { counter.labelValues("a", "b").inc(3.0); counter.labelValues("c", "d").inc(3.0); counter.labelValues("a", "b").inc(); - Assert.assertEquals(2, counter.collect().getDataPoints().size()); + assertEquals(2, counter.collect().getDataPoints().size()); counter.clear(); - Assert.assertEquals(0, counter.collect().getDataPoints().size()); + assertEquals(0, counter.collect().getDataPoints().size()); counter.labelValues("a", "b").inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); + assertEquals(1, counter.collect().getDataPoints().size()); } @Test public void testClearNoLabels() { Counter counter = Counter.builder().name("test").build(); counter.inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertEquals(1, counter.collect().getDataPoints().size()); + assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); counter.clear(); // No labels is always present, but as no value has been observed after clear() the value should // be 0.0 - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertEquals(1, counter.collect().getDataPoints().size()); + assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); // Making inc() works correctly after clear() counter.inc(); - Assert.assertEquals(1, counter.collect().getDataPoints().size()); - Assert.assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertEquals(1, counter.collect().getDataPoints().size()); + assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java index d5bc791a8..365ff1824 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java @@ -1,5 +1,200 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import io.prometheus.metrics.core.datapoints.Timer; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import java.util.List; +import org.junit.Before; +import org.junit.Test; + public class SummaryTest { - // TODO, port the SummaryTest from simpleclient over. + + private final Label label = new Label("name", "value"); + private final Labels labels = Labels.builder().label(label.getName(), label.getValue()).build(); + + private PrometheusRegistry registry; + private Summary noLabels; + private Summary withLabels; + private Summary withLabelsAndQuantiles; + private Summary noLabelsAndQuantiles; + + @Before + public void setUp() { + registry = new PrometheusRegistry(); + noLabels = + Summary.builder().name("nolabels").unit(Unit.SECONDS).help("help").register(registry); + withLabels = + Summary.builder() + .name("labels") + .unit(Unit.SECONDS) + .help("help") + .labelNames(label.getName()) + .register(registry); + noLabelsAndQuantiles = + Summary.builder() + .quantile(0.5, 0.05) + .quantile(0.9, 0.01) + .quantile(0.99, 0.001) + .name("no_labels_and_quantiles") + .unit(Unit.SECONDS) + .help("help") + .register(registry); + withLabelsAndQuantiles = + Summary.builder() + .quantile(0.5) + .quantile(0.9) + .quantile(0.99) + .name("labels_and_quantiles") + .unit(Unit.SECONDS) + .help("help") + .labelNames(label.getName()) + .register(registry); + } + + @Test + public void testObserve() { + noLabels.observe(2); + assertEquals(1, getCount(noLabels, Labels.EMPTY)); + assertEquals(2.0, getSum(noLabels, Labels.EMPTY), .001); + noLabels.observe(3); + assertEquals(2, getCount(noLabels, Labels.EMPTY)); + assertEquals(5.0, getSum(noLabels, Labels.EMPTY), .001); + + withLabels.labelValues(label.getValue()).observe(4); + assertEquals(1, getCount(withLabels, labels)); + assertEquals(4.0, getSum(withLabels, labels), .001); + + withLabels.labelValues(label.getValue()).observeWithExemplar(6, labels); + assertEquals(2, getCount(withLabels, labels)); + assertEquals(10.0, getSum(withLabels, labels), .001); + } + + @Test + public void testNegativeAmount() { + noLabels.observe(-1); + noLabels.observe(-3); + assertEquals(2, getCount(noLabels, Labels.EMPTY)); + assertEquals(-4.0, getSum(noLabels, Labels.EMPTY), .001); + } + + @Test + public void testQuantiles() { + int nSamples = 1000000; // simulate one million samples + + for (int i = 1; i <= nSamples; i++) { + // In this test, we observe the numbers from 1 to nSamples, + // because that makes it easy to verify if the quantiles are correct. + withLabelsAndQuantiles.labelValues(label.getValue()).observe(i); + noLabelsAndQuantiles.observe(i); + } + assertEquals( + getQuantile(noLabelsAndQuantiles, 0.5, Labels.EMPTY), 0.5 * nSamples, 0.05 * nSamples); + assertEquals( + getQuantile(noLabelsAndQuantiles, 0.9, Labels.EMPTY), 0.9 * nSamples, 0.01 * nSamples); + assertEquals( + getQuantile(noLabelsAndQuantiles, 0.99, Labels.EMPTY), 0.99 * nSamples, 0.001 * nSamples); + + assertEquals(getQuantile(withLabelsAndQuantiles, 0.5, labels), 0.5 * nSamples, 0.05 * nSamples); + assertEquals(getQuantile(withLabelsAndQuantiles, 0.9, labels), 0.9 * nSamples, 0.01 * nSamples); + assertEquals( + getQuantile(withLabelsAndQuantiles, 0.99, labels), 0.99 * nSamples, 0.001 * nSamples); + } + + @Test + public void testMaxAge() throws InterruptedException { + Summary summary = + Summary.builder() + .quantile(0.99, 0.001) + .maxAgeSeconds(1) // After 1s, all observations will be discarded. + .numberOfAgeBuckets(2) // We got 2 buckets, so we discard one bucket every 500ms. + .name("short_attention_span") + .help("help") + .register(registry); + summary.observe(8.0); + assertEquals(8.0, getQuantile(summary, 0.99, Labels.EMPTY), 0.0); // From bucket 1. + Thread.sleep(600); + assertEquals(8.0, getQuantile(summary, 0.99, Labels.EMPTY), 0.0); // From bucket 2. + Thread.sleep(600); + assertEquals( + Double.NaN, + getQuantile(summary, 0.99, Labels.EMPTY), + 0.0); // Bucket 1 again, now it is empty. + } + + @Test + public void testTimer() { + int result = noLabels.time(() -> 123); + assertEquals(123, result); + assertEquals(1, getCount(noLabels, Labels.EMPTY)); + + try (Timer timer = noLabels.startTimer()) { + timer.observeDuration(); + assertEquals(2, getCount(noLabels, Labels.EMPTY), .001); + } + } + + @Test + public void noLabelsDefaultZeroValue() { + assertEquals(0.0, getCount(noLabels, Labels.EMPTY), .001); + assertEquals(0.0, getSum(noLabels, Labels.EMPTY), .001); + } + + @Test(expected = IllegalArgumentException.class) + public void testBuilderInvalidNumberOfAgeBuckets() { + Summary.builder().name("name").numberOfAgeBuckets(-1).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testBuilderInvalidMaxAge() { + Summary.builder().name("name").maxAgeSeconds(-1).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testBuilderInvalidQuantile() { + Summary.builder().name("name").quantile(42).build(); + } + + @Test(expected = IllegalArgumentException.class) + public void testBuilderInvalidQuantileError() { + Summary.builder().name("name").quantile(0.5, 20).build(); + } + + private double getQuantile(Summary summary, double quantile, Labels labels) { + SummarySnapshot.SummaryDataPointSnapshot datapoint = getDatapoint(summary, labels); + Quantiles quantiles = datapoint.getQuantiles(); + for (Quantile q : quantiles) { + if (q.getQuantile() == quantile) { + return q.getValue(); + } + } + fail("Unable to find quantile"); + return 0.0; + } + + private SummarySnapshot.SummaryDataPointSnapshot getDatapoint(Summary summary, Labels labels) { + SummarySnapshot snapshot = summary.collect(); + List datapoints = snapshot.getDataPoints(); + assertEquals(1, datapoints.size()); + SummarySnapshot.SummaryDataPointSnapshot datapoint = datapoints.get(0); + assertEquals(labels, datapoint.getLabels()); + return datapoint; + } + + private long getCount(Summary summary, Labels labels) { + SummarySnapshot.SummaryDataPointSnapshot datapoint = getDatapoint(summary, labels); + return datapoint.getCount(); + } + + private double getSum(Summary summary, Labels labels) { + SummarySnapshot.SummaryDataPointSnapshot datapoint = getDatapoint(summary, labels); + return datapoint.getSum(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java index 8231d86f2..ba1df05ff 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java @@ -1,6 +1,53 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + +import io.prometheus.metrics.model.snapshots.Quantile; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.Test; + public class SummaryWithCallbackTest { - // TODO :). Anyway, callbacks are implicitly covered by the JVM metrics tests as well. + @Test + public void testGauge() { + final AtomicInteger count = new AtomicInteger(1); + final AtomicInteger sum = new AtomicInteger(1); + final Quantiles quantiles = Quantiles.of(new Quantile(0.5, 10)); + List labelValues = Arrays.asList("v1", "v2"); + SummaryWithCallback gauge = + SummaryWithCallback.builder() + .name("summary") + .labelNames("l1", "l2") + .callback( + callback -> { + callback.call( + count.get(), sum.get(), quantiles, labelValues.toArray(new String[0])); + }) + .build(); + SummarySnapshot snapshot = gauge.collect(); + + assertEquals(1, snapshot.getDataPoints().size()); + SummarySnapshot.SummaryDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); + assertEquals(count.get(), datapoint.getCount()); + assertEquals(sum.doubleValue(), datapoint.getSum(), 0.1); + assertEquals(quantiles, datapoint.getQuantiles()); + assertEquals(labelValues.size(), datapoint.getLabels().size()); + + count.incrementAndGet(); + sum.incrementAndGet(); + snapshot = gauge.collect(); + assertEquals(1, snapshot.getDataPoints().size()); + datapoint = snapshot.getDataPoints().get(0); + assertEquals(count.get(), datapoint.getCount()); + assertEquals(sum.doubleValue(), datapoint.getSum(), 0.1); + } + + @Test(expected = IllegalArgumentException.class) + public void testSummaryNoCallback() { + SummaryWithCallback.builder().name("summary").labelNames("l1", "l2").build(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java index 95a8b90fb..6a242a8be 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java @@ -1,13 +1,14 @@ package io.prometheus.metrics.core.metrics; +import static org.junit.Assert.assertEquals; + import io.prometheus.metrics.model.snapshots.Exemplar; -import org.junit.Assert; public class TestUtil { public static void assertExemplarEquals(Exemplar expected, Exemplar actual) { // ignore timestamp - Assert.assertEquals(expected.getValue(), actual.getValue(), 0.00001); - Assert.assertEquals(expected.getLabels(), actual.getLabels()); + assertEquals(expected.getValue(), actual.getValue(), 0.00001); + assertEquals(expected.getLabels(), actual.getLabels()); } } From 5e282c85b95b6d3d131cef53958b4975baa11c0e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 7 Oct 2024 15:30:09 +0200 Subject: [PATCH 390/980] convert to junit 5 / use assertj everywhere (#1092) * include common test dependencies by default Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to assertj Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger * convert to junit5 Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .../ManualCompleteMetricsTest.java | 2 +- .../prometheus/client/it/common/Volume.java | 10 +- .../it-exporter/it-exporter-test/pom.xml | 13 +- .../metrics/it/exporter/test/ExporterIT.java | 168 ++++--- .../it/exporter/test/HttpServerIT.java | 10 + .../metrics/it/exporter/test/JettyIT.java | 10 + .../metrics/it/exporter/test/TomcatIT.java | 10 + integration-tests/it-pushgateway/pom.xml | 4 + .../it/pushgateway/PushGatewayTestApp.java | 2 +- .../metrics/it/pushgateway/PushGatewayIT.java | 35 +- pom.xml | 28 ++ prometheus-metrics-config/pom.xml | 10 - .../PrometheusPropertiesLoaderTests.java | 45 +- .../config/PrometheusPropertiesTest.java | 22 +- prometheus-metrics-core/pom.xml | 6 - .../metrics/core/datapoints/TimerApiTest.java | 2 +- .../core/exemplars/ExemplarSamplerTest.java | 19 +- .../exemplars/SpanContextSupplierTest.java | 23 +- .../core/metrics/CKMSQuantilesTest.java | 72 +-- .../metrics/core/metrics/CounterTest.java | 150 ++++--- .../core/metrics/CounterWithCallbackTest.java | 24 +- .../metrics/core/metrics/GaugeTest.java | 50 +-- .../core/metrics/GaugeWithCallbackTest.java | 23 +- .../metrics/core/metrics/HistogramTest.java | 267 +++++------ .../metrics/core/metrics/InfoTest.java | 45 +- .../core/metrics/SlidingWindowTest.java | 30 +- .../metrics/core/metrics/StateSetTest.java | 51 ++- .../core/metrics/StatefulMetricTest.java | 30 +- .../metrics/core/metrics/SummaryTest.java | 104 +++-- .../core/metrics/SummaryWithCallbackTest.java | 30 +- .../metrics/core/metrics/TestUtil.java | 10 +- .../metrics/core/metrics/TodoTest.java | 2 +- .../pom.xml | 6 - .../exporter/opentelemetry/ExemplarTest.java | 49 +- .../pom.xml | 23 +- .../pushgateway/BasicAuthPushGatewayTest.java | 22 +- .../BearerTokenPushGatewayTest.java | 21 +- .../exporter/pushgateway/PushGatewayTest.java | 103 +++-- prometheus-metrics-exposition-formats/pom.xml | 8 - .../ExpositionFormatsTest.java | 420 ++++++------------ .../pom.xml | 22 +- .../caffeine/CacheMetricsCollectorTest.java | 29 +- .../pom.xml | 21 +- .../dropwizard5/DropwizardExportsTest.java | 94 ++-- .../labels/CustomLabelMapperTest.java | 37 +- .../labels/GraphiteNamePatternTest.java | 21 +- .../dropwizard5/labels/MapperConfigTest.java | 33 +- .../pom.xml | 22 - .../guava/CacheMetricsCollectorTest.java | 14 +- .../pom.xml | 12 - .../jvm/ExampleExporterForManualTesting.java | 2 +- .../jvm/JvmBufferPoolMetricsTest.java | 15 +- .../jvm/JvmClassLoadingMetricsTest.java | 15 +- .../jvm/JvmCompilationMetricsTest.java | 17 +- .../jvm/JvmGarbageCollectorMetricsTest.java | 17 +- .../jvm/JvmMemoryMetricsTest.java | 15 +- .../JvmMemoryPoolAllocationMetricsTest.java | 23 +- .../instrumentation/jvm/JvmMetricsTest.java | 11 +- .../jvm/JvmNativeMemoryMetricsTest.java | 17 +- .../jvm/JvmRuntimeInfoMetricTest.java | 11 +- .../jvm/JvmThreadsMetricsTest.java | 23 +- .../jvm/ProcessMetricsTest.java | 29 +- .../metrics/instrumentation/jvm/TestUtil.java | 2 +- prometheus-metrics-model/pom.xml | 10 - .../model/registry/MetricNameFilterTest.java | 29 +- .../MultiCollectorNameFilterTest.java | 131 +++--- .../registry/PrometheusRegistryTest.java | 35 +- .../ClassicHistogramBucketsTest.java | 89 ++-- .../model/snapshots/CounterSnapshotTest.java | 59 +-- .../metrics/model/snapshots/ExemplarTest.java | 63 +-- .../model/snapshots/ExemplarsTest.java | 37 +- .../model/snapshots/GaugeSnapshotTest.java | 64 +-- .../snapshots/HistogramSnapshotTest.java | 143 +++--- .../model/snapshots/InfoSnapshotTest.java | 32 +- .../metrics/model/snapshots/LabelsTest.java | 84 ++-- .../model/snapshots/MetricMetadataTest.java | 53 ++- .../model/snapshots/MetricSnapshotTest.java | 56 +-- .../model/snapshots/MetricSnapshotsTest.java | 31 +- .../snapshots/NativeHistogramBucketsTest.java | 43 +- .../model/snapshots/PrometheusNamingTest.java | 116 ++--- .../model/snapshots/QuantilesTest.java | 40 +- .../model/snapshots/SnapshotTestUtil.java | 12 +- .../model/snapshots/StateSetSnapshotTest.java | 102 +++-- .../model/snapshots/SummarySnapshotTest.java | 59 +-- .../metrics/model/snapshots/UnitTest.java | 20 +- .../model/snapshots/UnknownSnapshotTest.java | 47 +- .../pom.xml | 6 - .../bridge/SimpleclientCollectorTest.java | 35 +- .../simpleclient_graphite_bridge/pom.xml | 7 - .../client/bridge/GraphiteTest.java | 2 +- .../simpleclient_hibernate/pom.xml | 17 +- .../HibernateStatisticsCollector.java | 2 +- .../HibernateStatisticsCollectorTest.java | 4 +- .../simpleclient_httpserver/pom.xml | 12 - .../client/exporter/TestDaemonFlags.java | 2 +- .../client/exporter/TestHTTPServer.java | 2 +- .../simpleclient_jetty/pom.xml | 6 - .../jetty/JettyStatisticsCollectorTest.java | 2 +- .../simpleclient_jetty_jdk8/pom.xml | 6 - ...euedThreadPoolStatisticsCollectorTest.java | 2 +- .../simpleclient_log4j/pom.xml | 14 - .../log4j/InstrumentedAppenderTest.java | 2 +- .../simpleclient_log4j2/pom.xml | 14 - .../log4j2/InstrumentedAppenderTest.java | 2 +- .../simpleclient_logback/pom.xml | 15 - .../logback/InstrumentedAppenderTest.java | 2 +- .../simpleclient_servlet/pom.xml | 18 - .../simpleclient_servlet_common/pom.xml | 13 - .../servlet/common/exporter/ExporterTest.java | 2 +- .../servlet/common/filter/FilterTest.java | 2 +- .../simpleclient_servlet_jakarta/pom.xml | 18 - .../simpleclient_spring_web/pom.xml | 6 - .../client/spring/web/MethodTimerAppTest.java | 4 +- .../client/spring/web/MethodTimerTest.java | 2 +- .../simpleclient_vertx/pom.xml | 13 - .../client/vertx/MetricsHandlerTest.java | 2 +- .../simpleclient_vertx4/pom.xml | 13 - .../client/vertx/MetricsHandlerTest.java | 2 +- 118 files changed, 1926 insertions(+), 2139 deletions(-) create mode 100644 integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/HttpServerIT.java create mode 100644 integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/JettyIT.java create mode 100644 integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java index b8b8ef98b..7a2715647 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java @@ -17,7 +17,7 @@ import java.util.Random; */ -public class ManualCompleteMetricsTest { +class ManualCompleteMetricsTest { // This contains a complete set of all metric types, and target_info and otel_scope_info. // I used this to expose in Prometheus format and OTLP format at the same time and compare the diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java index 783ccb7a5..af5b0918e 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java @@ -1,6 +1,8 @@ package io.prometheus.client.it.common; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import java.io.File; import java.io.IOException; @@ -8,7 +10,6 @@ import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.function.Predicate; -import org.junit.Assert; /** Temporary directory in ./target/ to be mounted as a volume in Docker containers. */ public class Volume { @@ -21,8 +22,9 @@ private Volume(Path tmpDir) { public static Volume create(String prefix) throws IOException, URISyntaxException { Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent(); - Assert.assertEquals( - "failed to locate target/ directory", "target", targetDir.getFileName().toString()); + assertThat(targetDir.getFileName().toString()) + .as("failed to locate target/ directory") + .isEqualTo("target"); return new Volume(Files.createTempDirectory(targetDir, prefix + "-")); } @@ -59,7 +61,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) } }); } else { - Assert.fail(src + ": No such file or directory"); + fail(src + ": No such file or directory"); } return this; } diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 899a17f10..5135e35e1 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -15,6 +16,10 @@ Integration Tests for Exporters + + true + + The Apache Software License, Version 2.0 @@ -37,12 +42,6 @@ prometheus-metrics-exposition-formats ${project.version} - - junit - junit - 4.13.2 - test - org.testcontainers testcontainers diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 949f71840..b0e319190 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -1,6 +1,8 @@ package io.prometheus.metrics.it.exporter.test; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Volume; @@ -20,30 +22,17 @@ import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; import org.apache.commons.io.IOUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; -@RunWith(Parameterized.class) -public class ExporterIT { +abstract class ExporterIT { private final GenericContainer sampleAppContainer; private final Volume sampleAppVolume; private final String sampleApp; - @Parameterized.Parameters(name = "{0}") - public static String[] sampleApps() { - return new String[] { - "exporter-httpserver-sample", - "exporter-servlet-tomcat-sample", - "exporter-servlet-jetty-sample", - }; - } - public ExporterIT(String sampleApp) throws IOException, URISyntaxException { this.sampleApp = sampleApp; this.sampleAppVolume = @@ -57,7 +46,7 @@ public ExporterIT(String sampleApp) throws IOException, URISyntaxException { .withExposedPorts(9400); } - @After + @AfterEach public void tearDown() throws IOException { sampleAppContainer.stop(); sampleAppVolume.remove(); @@ -70,22 +59,22 @@ public void testOpenMetricsTextFormat() throws IOException { .start(); Response response = scrape("GET", "", "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals( - Integer.toString(response.body.length), response.getHeader("Content-Length")); + assertThat(response.getHeader("Content-Encoding")).isNull(); + assertThat(response.getHeader("Transfer-Encoding")).isNull(); + assertThat(response.getHeader("Content-Length")) + .isEqualTo(Integer.toString(response.body.length)); String bodyString = new String(response.body); - Assert.assertTrue( - bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - // OpenMetrics text format has a UNIT. - Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); + assertThat(bodyString) + .contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1") + .contains("temperature_celsius{location=\"inside\"} 23.0") + .contains("temperature_celsius{location=\"outside\"} 27.0") + .contains("uptime_seconds_total 17.0") + // OpenMetrics text format has a UNIT. + .contains("# UNIT uptime_seconds seconds"); } @Test @@ -94,21 +83,21 @@ public void testPrometheusTextFormat() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") .start(); Response response = scrape("GET", ""); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals( - Integer.toString(response.body.length), response.getHeader("Content-Length")); + assertThat(response.getHeader("Content-Encoding")).isNull(); + assertThat(response.getHeader("Transfer-Encoding")).isNull(); + assertThat(response.getHeader("Content-Length")) + .isEqualTo(Integer.toString(response.body.length)); String bodyString = new String(response.body); - Assert.assertTrue( - bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0")); - Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - // Prometheus text format does not have a UNIT. - Assert.assertFalse(bodyString.contains("# UNIT uptime_seconds seconds")); + assertThat(bodyString) + .contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1") + .contains("temperature_celsius{location=\"inside\"} 23.0") + .contains("temperature_celsius{location=\"outside\"} 27.0") + .contains("uptime_seconds_total 17.0") + // Prometheus text format does not have a UNIT. + .doesNotContain("# UNIT uptime_seconds seconds"); } @Test @@ -122,24 +111,24 @@ public void testPrometheusProtobufFormat() throws IOException { "", "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type")); - Assert.assertNull(response.getHeader("Content-Encoding")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); - Assert.assertEquals( - Integer.toString(response.body.length), response.getHeader("Content-Length")); + assertThat(response.getHeader("Content-Encoding")).isNull(); + assertThat(response.getHeader("Transfer-Encoding")).isNull(); + assertThat(response.getHeader("Content-Length")) + .isEqualTo(Integer.toString(response.body.length)); List metrics = new ArrayList<>(); InputStream in = new ByteArrayInputStream(response.body); while (in.available() > 0) { metrics.add(Metrics.MetricFamily.parseDelimitedFrom(in)); } - Assert.assertEquals(3, metrics.size()); + assertThat(metrics.size()).isEqualTo(3); // metrics are sorted by name - Assert.assertEquals("integration_test_info", metrics.get(0).getName()); - Assert.assertEquals("temperature_celsius", metrics.get(1).getName()); - Assert.assertEquals("uptime_seconds_total", metrics.get(2).getName()); + assertThat(metrics.get(0).getName()).isEqualTo("integration_test_info"); + assertThat(metrics.get(1).getName()).isEqualTo("temperature_celsius"); + assertThat(metrics.get(2).getName()).isEqualTo("uptime_seconds_total"); } @Test @@ -155,16 +144,16 @@ public void testCompression() throws IOException { "application/openmetrics-text; version=1.0.0; charset=utf-8", "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + assertThat(response.status).isEqualTo(200); + assertThat(response.getHeader("Content-Encoding")).isEqualTo("gzip"); if (response.getHeader("Content-Length") != null) { // The servlet container might set a content length as the body is very small. - Assert.assertEquals( - Integer.toString(response.body.length), response.getHeader("Content-Length")); - Assert.assertNull(response.getHeader("Transfer-Encoding")); + assertThat(response.getHeader("Content-Length")) + .isEqualTo(Integer.toString(response.body.length)); + assertThat(response.getHeader("Transfer-Encoding")).isNull(); } else { // If no content length is set, transfer-encoding chunked must be used. - Assert.assertEquals("chunked", response.getHeader("Transfer-Encoding")); + assertThat(response.getHeader("Transfer-Encoding")).isEqualTo("chunked"); } assertContentType( "application/openmetrics-text; version=1.0.0; charset=utf-8", @@ -173,7 +162,7 @@ public void testCompression() throws IOException { new String( IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertTrue(body.contains("uptime_seconds_total 17.0")); + assertThat(body).contains("uptime_seconds_total 17.0"); } @Test @@ -182,8 +171,8 @@ public void testErrorHandling() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "error") .start(); Response response = scrape("GET", ""); - Assert.assertEquals(500, response.status); - Assert.assertTrue(new String(response.body, UTF_8).contains("Simulating an error.")); + assertThat(response.status).isEqualTo(500); + assertThat(new String(response.body, UTF_8)).contains("Simulating an error."); } @Test @@ -193,11 +182,11 @@ public void testHeadRequest() throws IOException { .start(); Response fullResponse = scrape("GET", ""); int size = fullResponse.body.length; - Assert.assertTrue(size > 0); + assertThat(size > 0).isTrue(); Response headResponse = scrape("HEAD", ""); - Assert.assertEquals(200, headResponse.status); - Assert.assertEquals(Integer.toString(size), headResponse.getHeader("Content-Length")); - Assert.assertEquals(0, headResponse.body.length); + assertThat(headResponse.status).isEqualTo(200); + assertThat(headResponse.getHeader("Content-Length")).isEqualTo(Integer.toString(size)); + assertThat(headResponse.body.length).isZero(); } @Test @@ -206,11 +195,12 @@ public void testDebug() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") .start(); Response response = scrape("GET", "debug=openmetrics"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); String bodyString = new String(response.body, UTF_8); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds")); + assertThat(bodyString) + .contains("uptime_seconds_total 17.0") + .contains("# UNIT uptime_seconds seconds"); } @Test @@ -224,15 +214,15 @@ public void testNameFilter() throws IOException { nameParam("integration_test_info") + "&" + nameParam("uptime_seconds_total"), "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); String bodyString = new String(response.body, UTF_8); - Assert.assertTrue( - bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1")); - Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0")); - Assert.assertFalse(bodyString.contains("temperature_celsius")); + assertThat(bodyString) + .contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1") + .contains("uptime_seconds_total 17.0") + .doesNotContain("temperature_celsius"); } @Test @@ -246,13 +236,13 @@ public void testEmptyResponseOpenMetrics() throws IOException { nameParam("none_existing"), "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type")); - Assert.assertEquals( - Integer.toString(response.body.length), response.getHeader("Content-Length")); - Assert.assertEquals("# EOF\n", new String(response.body, UTF_8)); + assertThat(response.getHeader("Content-Length")) + .isEqualTo(Integer.toString(response.body.length)); + assertThat(new String(response.body, UTF_8)).isEqualTo("# EOF\n"); } @Test @@ -261,14 +251,14 @@ public void testEmptyResponseText() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") .start(); Response response = scrape("GET", nameParam("none_existing")); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type")); if (response.getHeader("Content-Length") != null) { // HTTPServer does not send a zero content length, which is ok - Assert.assertEquals("0", response.getHeader("Content-Length")); + assertThat(response.getHeader("Content-Length")).isEqualTo("0"); } - Assert.assertEquals(0, response.body.length); + assertThat(response.body.length).isZero(); } @Test @@ -282,11 +272,11 @@ public void testEmptyResponseProtobuf() throws IOException { nameParam("none_existing"), "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); - Assert.assertEquals(200, response.status); + assertThat(response.status).isEqualTo(200); assertContentType( "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type")); - Assert.assertEquals(0, response.body.length); + assertThat(response.body.length).isZero(); } @Test @@ -302,13 +292,13 @@ public void testEmptyResponseGzipOpenMetrics() throws IOException { "application/openmetrics-text; version=1.0.0; charset=utf-8", "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + assertThat(response.status).isEqualTo(200); + assertThat(response.getHeader("Content-Encoding")).isEqualTo("gzip"); String body = new String( IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertEquals("# EOF\n", body); + assertThat(body).isEqualTo("# EOF\n"); } @Test @@ -317,13 +307,13 @@ public void testEmptyResponseGzipText() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") .start(); Response response = scrape("GET", nameParam("none_existing"), "Accept-Encoding", "gzip"); - Assert.assertEquals(200, response.status); - Assert.assertEquals("gzip", response.getHeader("Content-Encoding")); + assertThat(response.status).isEqualTo(200); + assertThat(response.getHeader("Content-Encoding")).isEqualTo("gzip"); String body = new String( IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8); - Assert.assertEquals(0, body.length()); + assertThat(body.length()).isZero(); } private String nameParam(String name) throws UnsupportedEncodingException { @@ -336,13 +326,13 @@ public void testDebugUnknown() throws IOException { .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success") .start(); Response response = scrape("GET", "debug=unknown"); - Assert.assertEquals(500, response.status); + assertThat(response.status).isEqualTo(500); assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type")); } private void assertContentType(String expected, String actual) { if (!expected.replace(" ", "").equals(actual)) { - Assert.assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } } @@ -386,7 +376,7 @@ private Response scrape(String method, String queryString, String... requestHead if (exception != null) { exception.printStackTrace(); } - Assert.fail("timeout while getting metrics from " + url); + fail("timeout while getting metrics from " + url); return null; // will not happen } diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/HttpServerIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/HttpServerIT.java new file mode 100644 index 000000000..4c7e61472 --- /dev/null +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/HttpServerIT.java @@ -0,0 +1,10 @@ +package io.prometheus.metrics.it.exporter.test; + +import java.io.IOException; +import java.net.URISyntaxException; + +class HttpServerIT extends ExporterIT { + public HttpServerIT() throws IOException, URISyntaxException { + super("exporter-httpserver-sample"); + } +} diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/JettyIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/JettyIT.java new file mode 100644 index 000000000..a3d3e7da6 --- /dev/null +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/JettyIT.java @@ -0,0 +1,10 @@ +package io.prometheus.metrics.it.exporter.test; + +import java.io.IOException; +import java.net.URISyntaxException; + +class JettyIT extends ExporterIT { + public JettyIT() throws IOException, URISyntaxException { + super("exporter-servlet-jetty-sample"); + } +} diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java new file mode 100644 index 000000000..ea5e6b69d --- /dev/null +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java @@ -0,0 +1,10 @@ +package io.prometheus.metrics.it.exporter.test; + +import java.io.IOException; +import java.net.URISyntaxException; + +class TomcatIT extends ExporterIT { + public TomcatIT() throws IOException, URISyntaxException { + super("exporter-servlet-tomcat-sample"); + } +} diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 25ce45b12..1956f1dad 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -16,6 +16,10 @@ Integration tests for the Pushgateway Exporter + + true + + The Apache Software License, Version 2.0 diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java index 6376b03fb..61032600b 100644 --- a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java +++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java @@ -18,7 +18,7 @@ import javax.net.ssl.X509TrustManager; /** Example application using the {@link PushGateway}. */ -public class PushGatewayTestApp { +class PushGatewayTestApp { public static void main(String[] args) throws IOException { if (args.length != 1) { diff --git a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java index 7e1198a55..cf11671f3 100644 --- a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java +++ b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java @@ -1,5 +1,9 @@ package io.prometheus.metrics.it.pushgateway; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.data.Offset.offset; + import com.jayway.jsonpath.Criteria; import com.jayway.jsonpath.Filter; import com.jayway.jsonpath.JsonPath; @@ -10,10 +14,9 @@ import java.net.URISyntaxException; import java.util.concurrent.TimeUnit; import net.minidev.json.JSONArray; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; @@ -27,7 +30,7 @@ public class PushGatewayIT { private GenericContainer prometheusContainer; private Volume sampleAppVolume; - @Before + @BeforeEach public void setUp() throws IOException, URISyntaxException { Network network = Network.newNetwork(); sampleAppVolume = Volume.create("it-pushgateway").copy("pushgateway-test-app.jar"); @@ -53,7 +56,7 @@ public void setUp() throws IOException, URISyntaxException { .withLogConsumer(LogConsumer.withPrefix("prometheus")); } - @After + @AfterEach public void tearDown() throws IOException { prometheusContainer.stop(); pushGatewayContainer.stop(); @@ -177,13 +180,13 @@ public void testProtobuf() throws IOException, InterruptedException { private void assertMetrics() throws IOException, InterruptedException { double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app"); - Assert.assertEquals(0.5, value, 0.0); + assertThat(value).isCloseTo(0.5, offset(0.0)); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512"); - Assert.assertEquals(0.0, value, 0.0); + assertThat(value).isCloseTo(0.0, offset(0.0)); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024"); - Assert.assertEquals(2.0, value, 0.0); + assertThat(value).isCloseTo(2.0, offset(0.0)); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf"); - Assert.assertEquals(3.0, value, 0.0); + assertThat(value).isCloseTo(3.0, offset(0.0)); } private double getValue(String name, String... labels) throws IOException, InterruptedException { @@ -195,13 +198,13 @@ private double getValue(String name, String... labels) throws IOException, Inter JSONArray result = JsonPath.parse(scrapeResponseJson) .read("$.data.result" + Filter.filter(criteria) + ".value[1]"); - Assert.assertEquals(1, result.size()); - return Double.valueOf(result.get(0).toString()); + assertThat(result.size()).isOne(); + return Double.parseDouble(result.get(0).toString()); } private void assertNativeHistogram() throws IOException, InterruptedException { double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app"); - Assert.assertEquals(3, count, 0.0); + assertThat(count).isCloseTo(3, offset(0.0)); } private double getNativeHistogramCount(String name, String job) @@ -211,7 +214,7 @@ private double getNativeHistogramCount(String name, String job) JSONArray result = JsonPath.parse(scrapeResponseJson) .read("$.data.result" + Filter.filter(criteria) + ".value[1]"); - return Double.valueOf(result.get(0).toString()); + return Double.parseDouble(result.get(0).toString()); } private String scrape(String query) throws IOException, InterruptedException { @@ -242,7 +245,7 @@ private String scrape(String query) throws IOException, InterruptedException { Thread.sleep(250); timeRemaining -= 250; } - Assert.fail("timeout while scraping " + url); + fail("timeout while scraping " + url); return null; } @@ -251,7 +254,7 @@ private void awaitTermination(GenericContainer container, long timeout, TimeU long waitTimeMillis = 0; while (container.isRunning()) { if (waitTimeMillis > unit.toMillis(timeout)) { - Assert.fail( + fail( container.getContainerName() + " did not terminate after " + timeout diff --git a/pom.xml b/pom.xml index f55a754c2..75f31709f 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ UTF-8 --module-name-need-to-be-overriden-- + 5.11.2 @@ -87,6 +88,33 @@ + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + test + + + org.mockito + mockito-core + 5.12.0 + test + + + org.assertj + assertj-core + 3.26.3 + test + + + diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 2d1e95c88..94f2904cb 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -35,14 +35,4 @@ fabian@fstab.de - - - - - junit - junit - 4.13.2 - test - - diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java index 8d16eadb7..9da800c27 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java @@ -1,25 +1,25 @@ package io.prometheus.metrics.config; +import static org.assertj.core.api.Assertions.assertThat; + import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** Tests for {@link PrometheusPropertiesLoader}. */ -public class PrometheusPropertiesLoaderTests { +class PrometheusPropertiesLoaderTests { @Test public void propertiesShouldBeLoadedFromPropertiesFile() { PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(); - Assert.assertEquals( - 11, - prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals( - 4, - prometheusProperties - .getMetricProperties("http_duration_seconds") - .getHistogramClassicUpperBounds() - .size()); - Assert.assertTrue(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); + assertThat(prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds()) + .hasSize(11); + assertThat( + prometheusProperties + .getMetricProperties("http_duration_seconds") + .getHistogramClassicUpperBounds()) + .hasSize(4); + assertThat(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()) + .isTrue(); } @Test @@ -32,15 +32,14 @@ public void externalPropertiesShouldOverridePropertiesFile() { properties.setProperty("io.prometheus.exporter.exemplarsOnAllMetricTypes", "false"); PrometheusProperties prometheusProperties = PrometheusPropertiesLoader.load(properties); - Assert.assertEquals( - 2, - prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals( - 3, - prometheusProperties - .getMetricProperties("http_duration_seconds") - .getHistogramClassicUpperBounds() - .size()); - Assert.assertFalse(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()); + assertThat(prometheusProperties.getDefaultMetricProperties().getHistogramClassicUpperBounds()) + .hasSize(2); + assertThat( + prometheusProperties + .getMetricProperties("http_duration_seconds") + .getHistogramClassicUpperBounds()) + .hasSize(3); + assertThat(prometheusProperties.getExporterProperties().getExemplarsOnAllMetricTypes()) + .isFalse(); } } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java index f9ef25a7a..cce7213a6 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesTest.java @@ -1,24 +1,20 @@ package io.prometheus.metrics.config; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.IOException; import java.io.InputStream; import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class PrometheusPropertiesTest { +class PrometheusPropertiesTest { @Test public void testPrometheusConfig() { PrometheusProperties result = PrometheusProperties.get(); - Assert.assertEquals( - 11, result.getDefaultMetricProperties().getHistogramClassicUpperBounds().size()); - Assert.assertEquals( - 4, - result - .getMetricProperties("http_duration_seconds") - .getHistogramClassicUpperBounds() - .size()); + assertThat(result.getDefaultMetricProperties().getHistogramClassicUpperBounds()).hasSize(11); + assertThat(result.getMetricProperties("http_duration_seconds").getHistogramClassicUpperBounds()) + .hasSize(4); } @Test @@ -30,8 +26,8 @@ public void testEmptyUpperBounds() throws IOException { .getResourceAsStream("emptyUpperBounds.properties")) { properties.load(stream); } - Assert.assertEquals(1, properties.size()); + assertThat(properties).hasSize(1); MetricsProperties.load("io.prometheus.metrics", properties); - Assert.assertEquals(0, properties.size()); + assertThat(properties).isEmpty(); } } diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index fd3c9a04f..5afaac18a 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -66,11 +66,5 @@ 3.6.1 test - - junit - junit - 4.13.2 - test - diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java index 8c015f591..70755b938 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.core.datapoints; -public class TimerApiTest { +class TimerApiTest { // TODO: Port this from the simpleclient SimpleTimerTest } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java index 9d51ae17b..1572eb645 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java @@ -1,16 +1,17 @@ package io.prometheus.metrics.core.exemplars; +import static org.assertj.core.api.Assertions.assertThat; + import io.prometheus.metrics.core.util.Scheduler; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class ExemplarSamplerTest { +class ExemplarSamplerTest { private final int tick = 10; // Time step in milliseconds. Make this larger if the test is flaky. private final int sampleInterval = 10 * tick; // do not change this @@ -60,12 +61,12 @@ public void testCustomExemplarsBuckets() throws Exception { private io.prometheus.metrics.tracer.common.SpanContext origContext; - @Before + @BeforeEach public void setUp() { origContext = SpanContextSupplier.getSpanContext(); } - @After + @AfterEach public void tearDown() { SpanContextSupplier.setSpanContext(origContext); } @@ -185,7 +186,7 @@ public void testDefaultExemplarsNoBuckets() throws Exception { private void assertExemplars(ExemplarSampler sampler, double... values) { Exemplars exemplars = sampler.collect(); - Assert.assertEquals(values.length, exemplars.size()); + assertThat(exemplars.size()).isEqualTo(values.length); for (double value : values) { boolean found = false; for (Exemplar exemplar : exemplars) { @@ -194,7 +195,7 @@ private void assertExemplars(ExemplarSampler sampler, double... values) { break; } } - Assert.assertTrue(value + " not found", found); + assertThat(found).as(value + " not found").isTrue(); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java index cc7005c77..6c89b48a5 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/SpanContextSupplierTest.java @@ -1,15 +1,18 @@ package io.prometheus.metrics.core.exemplars; import static io.prometheus.metrics.model.snapshots.Exemplar.TRACE_ID; +import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.metrics.config.ExemplarsProperties; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; -import org.junit.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class SpanContextSupplierTest { +class SpanContextSupplierTest { public SpanContext makeSpanContext(String traceId, String spanId) { @@ -47,12 +50,12 @@ public void markCurrentSpanAsExemplar() {} null // histogram upper bounds ); - @Before + @BeforeEach public void setUp() { origSpanContext = SpanContextSupplier.getSpanContext(); } - @After + @AfterEach public void tearDown() { SpanContextSupplier.setSpanContext(origSpanContext); } @@ -71,9 +74,9 @@ public void testConstructorInjection() { SpanContextSupplier.setSpanContext(spanContextB); exemplarSampler.observe(1.0); Exemplars exemplars = exemplarSampler.collect(); - Assert.assertEquals(1, exemplars.size()); + assertThat(exemplars.size()).isOne(); Exemplar exemplar = exemplars.get(0); - Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID)); + assertThat(exemplar.getLabels().get(TRACE_ID)).isEqualTo("A"); } /** @@ -89,17 +92,17 @@ public void testUpdateSpanContext() throws InterruptedException { SpanContextSupplier.setSpanContext(spanContextB); exemplarSampler.observe(1.0); Exemplars exemplars = exemplarSampler.collect(); - Assert.assertEquals(1, exemplars.size()); + assertThat(exemplars.size()).isOne(); Exemplar exemplar = exemplars.get(0); - Assert.assertEquals("B", exemplar.getLabels().get(TRACE_ID)); + assertThat(exemplar.getLabels().get(TRACE_ID)).isEqualTo("B"); Thread.sleep(15); // more than the minimum retention period defined in config above. SpanContextSupplier.setSpanContext(spanContextA); exemplarSampler.observe(1.0); exemplars = exemplarSampler.collect(); - Assert.assertEquals(1, exemplars.size()); + assertThat(exemplars.size()).isOne(); exemplar = exemplars.get(0); - Assert.assertEquals("A", exemplar.getLabels().get(TRACE_ID)); + assertThat(exemplar.getLabels().get(TRACE_ID)).isEqualTo("A"); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java index 326b0a463..19f32f677 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CKMSQuantilesTest.java @@ -1,17 +1,17 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.metrics.CKMSQuantiles.Quantile; import java.util.*; import org.apache.commons.math3.distribution.NormalDistribution; import org.apache.commons.math3.random.JDKRandomGenerator; import org.apache.commons.math3.random.RandomGenerator; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class CKMSQuantilesTest { +class CKMSQuantilesTest { private final Quantile qMin = new Quantile(0.0, 0.00); private final Quantile q50 = new Quantile(0.5, 0.01); @@ -22,7 +22,7 @@ public class CKMSQuantilesTest { @Test public void testGetOnEmptyValues() { CKMSQuantiles ckms = new CKMSQuantiles(q50, q95, q99); - assertTrue(Double.isNaN(ckms.get(q95.quantile))); + assertThat(Double.isNaN(ckms.get(q95.quantile))).isTrue(); } @Test @@ -95,7 +95,7 @@ public void testGetWithAMillionElements() { ckms.insert(v); } validateResults(ckms); - assertTrue("sample size should be way below 1_000_000", ckms.samples.size() < 1000); + assertThat(ckms.samples).as("sample size should be way below 1_000_000").hasSizeLessThan(1000); } @Test @@ -108,7 +108,7 @@ public void testMin() { } validateResults(ckms); ckms.compress(); - assertEquals(2, ckms.samples.size()); + assertThat(ckms.samples).hasSize(2); } @Test @@ -121,7 +121,7 @@ public void testMax() { } validateResults(ckms); ckms.compress(); - assertEquals(2, ckms.samples.size()); + assertThat(ckms.samples).hasSize(2); } @Test @@ -134,7 +134,7 @@ public void testMinMax() { } validateResults(ckms); ckms.compress(); - assertEquals(2, ckms.samples.size()); + assertThat(ckms.samples).hasSize(2); } @Test @@ -146,7 +146,7 @@ public void testMinAndOthers() { ckms.insert(v); } validateResults(ckms); - assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + assertThat(ckms.samples).hasSizeLessThan(200); // should be a lot less than input.size() } @Test @@ -158,7 +158,7 @@ public void testMaxAndOthers() { ckms.insert(v); } validateResults(ckms); - assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + assertThat(ckms.samples).hasSizeLessThan(200); // should be a lot less than input.size() } @Test @@ -170,7 +170,7 @@ public void testMinMaxAndOthers() { ckms.insert(v); } validateResults(ckms); - assertTrue(ckms.samples.size() < 200); // should be a lot less than input.size() + assertThat(ckms.samples).hasSizeLessThan(200); // should be a lot less than input.size() } @Test @@ -183,7 +183,7 @@ public void testExactQuantile() { } validateResults(ckms); // With epsilon == 0 we need to keep all inputs in samples. - assertEquals(input.size(), ckms.samples.size()); + assertThat(ckms.samples).hasSameSizeAs(input); } @Test @@ -196,7 +196,7 @@ public void testExactAndOthers() { } validateResults(ckms); // With epsilon == 0 we need to keep all inputs in samples. - assertEquals(input.size(), ckms.samples.size()); + assertThat(ckms.samples).hasSameSizeAs(input); } @Test @@ -209,7 +209,7 @@ public void testExactAndMin() { } validateResults(ckms); // With epsilon == 0 we need to keep all inputs in samples. - assertEquals(input.size(), ckms.samples.size()); + assertThat(ckms.samples).hasSameSizeAs(input); } @Test @@ -260,15 +260,18 @@ public void testGetGaussian() { // ε-approximate quantiles relaxes the requirement // to finding an item with rank between (φ−ε)n and (φ+ε)n. - assertEquals(p10, ckms.get(0.1), errorBoundsNormalDistribution(0.1, 0.001, normalDistribution)); - assertEquals(mean, ckms.get(0.5), errorBoundsNormalDistribution(0.5, 0.01, normalDistribution)); - assertEquals(p90, ckms.get(0.9), errorBoundsNormalDistribution(0.9, 0.001, normalDistribution)); - assertEquals( - p95, ckms.get(0.95), errorBoundsNormalDistribution(0.95, 0.001, normalDistribution)); - assertEquals( - p99, ckms.get(0.99), errorBoundsNormalDistribution(0.99, 0.001, normalDistribution)); - - assertTrue("sample size should be below 1000", ckms.samples.size() < 1000); + assertThat(ckms.get(0.1)) + .isCloseTo(p10, offset(errorBoundsNormalDistribution(0.1, 0.001, normalDistribution))); + assertThat(ckms.get(0.5)) + .isCloseTo(mean, offset(errorBoundsNormalDistribution(0.5, 0.01, normalDistribution))); + assertThat(ckms.get(0.9)) + .isCloseTo(p90, offset(errorBoundsNormalDistribution(0.9, 0.001, normalDistribution))); + assertThat(ckms.get(0.95)) + .isCloseTo(p95, offset(errorBoundsNormalDistribution(0.95, 0.001, normalDistribution))); + assertThat(ckms.get(0.99)) + .isCloseTo(p99, offset(errorBoundsNormalDistribution(0.99, 0.001, normalDistribution))); + + assertThat(ckms.samples).as("sample size should be below 1000").hasSizeLessThan(1000); } double errorBoundsNormalDistribution(double p, double epsilon, NormalDistribution nd) { @@ -285,14 +288,14 @@ public void testIllegalArgumentException() { try { new Quantile(-1, 0); } catch (IllegalArgumentException e) { - assertEquals("Quantile must be between 0 and 1", e.getMessage()); + assertThat(e.getMessage()).isEqualTo("Quantile must be between 0 and 1"); } catch (Exception e) { fail("Wrong exception thrown" + e); } try { new Quantile(0.95, 2); } catch (IllegalArgumentException e) { - assertEquals("Epsilon must be between 0 and 1", e.getMessage()); + assertThat(e.getMessage()).isEqualTo("Epsilon must be between 0 and 1"); } catch (Exception e) { fail("Wrong exception thrown" + e); } @@ -314,14 +317,17 @@ private void validateSamples(CKMSQuantiles ckms) { for (CKMSQuantiles.Sample sample : ckms.samples) { String msg = "invalid sample " + sample + ": count=" + ckms.n + " r=" + r + " f(r)=" + ckms.f(r); - assertTrue(msg, sample.g + sample.delta <= ckms.f(r)); - assertTrue( - "Samples not ordered. Keep in mind that insertBatch() takes a sorted array as parameter.", - prev <= sample.value); + assertThat(sample.g + sample.delta).as(msg).isLessThanOrEqualTo(ckms.f(r)); + assertThat(prev) + .as( + "Samples not ordered. Keep in mind that insertBatch() takes a sorted array as parameter.") + .isLessThanOrEqualTo(sample.value); prev = sample.value; r += sample.g; } - assertEquals("the sum of all g's must be the total number of observations", r, ckms.n); + assertThat(ckms.n) + .as("the sum of all g's must be the total number of observations") + .isEqualTo(r); } /** @@ -365,7 +371,7 @@ private void validateResults(CKMSQuantiles ckms) { + ckms.n + "=" + (q.quantile * ckms.n); - assertTrue(errorMessage, ok); + assertThat(ok).as(errorMessage).isTrue(); } } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 0c1408c56..087b230d2 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -1,16 +1,16 @@ package io.prometheus.metrics.core.metrics; import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.rules.ExpectedException.none; +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.Unit; import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; @@ -18,13 +18,11 @@ import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import java.util.Arrays; import java.util.Iterator; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class CounterTest { +class CounterTest { private Counter noLabels; private Counter labels; @@ -32,9 +30,7 @@ public class CounterTest { private static final long exemplarMinAgeMillis = 100; private SpanContext origSpanContext; - @Rule public final ExpectedException thrown = none(); - - @Before + @BeforeEach public void setUp() throws NoSuchFieldException, IllegalAccessException { noLabels = Counter.builder().name("nolabels").build(); labels = @@ -46,7 +42,7 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException { ExemplarSamplerConfigTestUtil.setMinRetentionPeriodMillis(labels, exemplarMinAgeMillis); } - @After + @AfterEach public void tearDown() { SpanContextSupplier.setSpanContext(origSpanContext); } @@ -72,38 +68,38 @@ private int getNumberOfLabels(Counter counter) { @Test public void testIncrement() { noLabels.inc(); - assertEquals(1.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(1.0, offset(.001)); noLabels.inc(2); - assertEquals(3.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(3.0, offset(.001)); noLabels.labelValues().inc(4); - assertEquals(7.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(7.0, offset(.001)); noLabels.labelValues().inc(); - assertEquals(8.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(8.0, offset(.001)); } @Test public void testNegativeIncrementFails() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Negative increment -1 is illegal for Counter metrics."); - noLabels.inc(-1); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> noLabels.inc(-1)) + .withMessage("Negative increment -1 is illegal for Counter metrics."); } @Test public void testEmptyCountersHaveNoLabels() { - assertEquals(1, getNumberOfLabels(noLabels)); - assertEquals(0, getNumberOfLabels(labels)); + assertThat(getNumberOfLabels(noLabels)).isOne(); + assertThat(getNumberOfLabels(labels)).isZero(); } @Test public void testLabels() { - assertEquals(0, getNumberOfLabels(labels)); + assertThat(getNumberOfLabels(labels)).isZero(); labels.labelValues("a").inc(); - assertEquals(1, getNumberOfLabels(labels)); - assertEquals(1.0, getValue(labels, "l", "a"), .001); + assertThat(getNumberOfLabels(labels)).isOne(); + assertThat(getValue(labels, "l", "a")).isCloseTo(1.0, offset(.001)); labels.labelValues("b").inc(3); - assertEquals(2, getNumberOfLabels(labels)); - assertEquals(1.0, getValue(labels, "l", "a"), .001); - assertEquals(3.0, getValue(labels, "l", "b"), .001); + assertThat(getNumberOfLabels(labels)).isEqualTo(2); + assertThat(getValue(labels, "l", "a")).isCloseTo(1.0, offset(.001)); + assertThat(getValue(labels, "l", "b")).isCloseTo(3.0, offset(.001)); } @Test @@ -117,9 +113,9 @@ public void testTotalStrippedFromName() { }) { Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build(); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertEquals( - "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }", - TextFormat.printer().shortDebugString(protobufData)); + assertThat(TextFormat.printer().shortDebugString(protobufData)) + .isEqualTo( + "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }"); } } @@ -137,29 +133,45 @@ public void testSnapshotComplete() { counter.labelValues("/", "200").inc(2); counter.labelValues("/", "500").inc(); CounterSnapshot snapshot = counter.collect(); - assertEquals("test_seconds", snapshot.getMetadata().getName()); - assertEquals("seconds", snapshot.getMetadata().getUnit().toString()); - assertEquals("help message", snapshot.getMetadata().getHelp()); - assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getMetadata().getName()).isEqualTo("test_seconds"); + assertThat(snapshot.getMetadata().getUnit()).hasToString("seconds"); + assertThat(snapshot.getMetadata().getHelp()).isEqualTo("help message"); + assertThat(snapshot.getDataPoints()).hasSize(2); Iterator iter = snapshot.getDataPoints().iterator(); // data is ordered by labels, so 200 comes before 500 CounterSnapshot.CounterDataPointSnapshot data = iter.next(); - assertEquals( - Labels.of( - "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "200"), - data.getLabels()); - assertEquals(2, data.getValue(), 0.0001); - assertTrue(data.getCreatedTimestampMillis() >= before); - assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + assertThat((Iterable) data.getLabels()) + .isEqualTo( + Labels.of( + "const1name", + "const1value", + "const2name", + "const2value", + "path", + "/", + "status", + "200")); + assertThat(data.getValue()).isCloseTo(2, offset(0.0001)); + assertThat(data.getCreatedTimestampMillis()) + .isGreaterThanOrEqualTo(before) + .isLessThanOrEqualTo(System.currentTimeMillis()); // 500 data = iter.next(); - assertEquals( - Labels.of( - "const1name", "const1value", "const2name", "const2value", "path", "/", "status", "500"), - data.getLabels()); - assertEquals(1, data.getValue(), 0.0001); - assertTrue(data.getCreatedTimestampMillis() >= before); - assertTrue(data.getCreatedTimestampMillis() <= System.currentTimeMillis()); + assertThat((Iterable) data.getLabels()) + .isEqualTo( + Labels.of( + "const1name", + "const1value", + "const2name", + "const2value", + "path", + "/", + "status", + "500")); + assertThat(data.getValue()).isCloseTo(1, offset(0.0001)); + assertThat(data.getCreatedTimestampMillis()) + .isGreaterThanOrEqualTo(before) + .isLessThanOrEqualTo(System.currentTimeMillis()); } @Test @@ -180,8 +192,8 @@ public void testIncWithExemplar() throws Exception { private void assertExemplar(Counter counter, double value, String... labels) { Exemplar exemplar = getData(counter).getExemplar(); - assertEquals(value, exemplar.getValue(), 0.0001); - assertEquals(Labels.of(labels), exemplar.getLabels()); + assertThat(exemplar.getValue()).isCloseTo(value, offset(0.0001)); + assertThat((Iterable) exemplar.getLabels()).isEqualTo(Labels.of(labels)); } @Test @@ -291,26 +303,32 @@ public void testExemplarSamplerDisabled() { .withoutExemplars() .build(); counter.incWithExemplar(3.0, Labels.of("a", "b")); - assertNull(getData(counter).getExemplar()); + assertThat(getData(counter).getExemplar()).isNull(); counter.inc(2.0); - assertNull(getData(counter).getExemplar()); + assertThat(getData(counter).getExemplar()).isNull(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testConstLabelsFirst() { - Counter.builder() - .name("test_total") - .constLabels(Labels.of("const_a", "const_b")) - .labelNames("const.a") - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + Counter.builder() + .name("test_total") + .constLabels(Labels.of("const_a", "const_b")) + .labelNames("const.a") + .build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testConstLabelsSecond() { - Counter.builder() - .name("test_total") - .labelNames("const.a") - .constLabels(Labels.of("const_a", "const_b")) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + Counter.builder() + .name("test_total") + .labelNames("const.a") + .constLabels(Labels.of("const_a", "const_b")) + .build()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java index e4af61bde..47c5f5c57 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterWithCallbackTest.java @@ -1,14 +1,16 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class CounterWithCallbackTest { +class CounterWithCallbackTest { @Test public void testCounter() { @@ -23,20 +25,22 @@ public void testCounter() { .build(); CounterSnapshot snapshot = counter.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); CounterSnapshot.CounterDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); - assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); - assertEquals(labelValues.size(), datapoint.getLabels().size()); + assertThat(datapoint.getValue()).isCloseTo(value.doubleValue(), offset(0.1)); + assertThat(datapoint.getLabels().size()).isEqualTo(labelValues.size()); value.incrementAndGet(); snapshot = counter.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); datapoint = snapshot.getDataPoints().get(0); - assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + assertThat(datapoint.getValue()).isCloseTo(value.doubleValue(), offset(0.1)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testCounterNoCallback() { - CounterWithCallback.builder().name("counter").labelNames("l1", "l2").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> CounterWithCallback.builder().name("counter").labelNames("l1", "l2").build()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java index 0443cc7bf..1e48d63c0 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.core.metrics; import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.datapoints.Timer; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -11,11 +11,11 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class GaugeTest { +class GaugeTest { private static final long exemplarSampleIntervalMillis = 10; private static final long exemplarMinAgeMillis = 100; @@ -24,14 +24,14 @@ public class GaugeTest { private SpanContext origSpanContext; - @Before + @BeforeEach public void setUp() { noLabels = Gauge.builder().name("nolabels").build(); labels = Gauge.builder().name("labels").labelNames("l").build(); origSpanContext = SpanContextSupplier.getSpanContext(); } - @After + @AfterEach public void tearDown() { SpanContextSupplier.setSpanContext(origSpanContext); } @@ -50,33 +50,33 @@ private double getValue(Gauge gauge, String... labels) { @Test public void testIncrement() { noLabels.inc(); - assertEquals(1.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(1.0, offset(.001)); noLabels.inc(2); - assertEquals(3.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(3.0, offset(.001)); noLabels.inc(4); - assertEquals(7.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(7.0, offset(.001)); noLabels.inc(); - assertEquals(8.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(8.0, offset(.001)); } @Test public void testDecrement() { noLabels.dec(); - assertEquals(-1.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(-1.0, offset(.001)); noLabels.dec(2); - assertEquals(-3.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(-3.0, offset(.001)); noLabels.dec(4); - assertEquals(-7.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(-7.0, offset(.001)); noLabels.dec(); - assertEquals(-8.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(-8.0, offset(.001)); } @Test public void testSet() { noLabels.set(42); - assertEquals(42, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(42, offset(.001)); noLabels.set(7); - assertEquals(7.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(7.0, offset(.001)); } @Test @@ -84,21 +84,21 @@ public void testTimer() throws InterruptedException { try (Timer timer = noLabels.startTimer()) { Thread.sleep(12); } - assertEquals( - 0.012, getValue(noLabels), 0.005); // 5ms delta should be enough so this isn't flaky + assertThat(getValue(noLabels)) + .isCloseTo(0.012, offset(0.005)); // 5ms delta should be enough so this isn't flaky } @Test public void noLabelsDefaultZeroValue() { - assertEquals(0.0, getValue(noLabels), .001); + assertThat(getValue(noLabels)).isCloseTo(0.0, offset(.001)); } @Test public void testLabels() { labels.labelValues("a").inc(); labels.labelValues("b").inc(3); - assertEquals(1.0, getValue(labels, "l", "a"), .001); - assertEquals(3.0, getValue(labels, "l", "b"), .001); + assertThat(getValue(labels, "l", "a")).isCloseTo(1.0, offset(.001)); + assertThat(getValue(labels, "l", "b")).isCloseTo(3.0, offset(.001)); } @Test @@ -202,8 +202,8 @@ public void markCurrentSpanAsExemplar() {} public void testExemplarSamplerDisabled() { Gauge gauge = Gauge.builder().name("test").withoutExemplars().build(); gauge.setWithExemplar(3.0, Labels.of("a", "b")); - assertNull(getData(gauge).getExemplar()); + assertThat(getData(gauge).getExemplar()).isNull(); gauge.inc(2.0); - assertNull(getData(gauge).getExemplar()); + assertThat(getData(gauge).getExemplar()).isNull(); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java index 3a6a4ffac..92a2d605e 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeWithCallbackTest.java @@ -1,14 +1,16 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class GaugeWithCallbackTest { +class GaugeWithCallbackTest { @Test public void testGauge() { @@ -23,20 +25,21 @@ public void testGauge() { .build(); GaugeSnapshot snapshot = gauge.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); GaugeSnapshot.GaugeDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); - assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); - assertEquals(labelValues.size(), datapoint.getLabels().size()); + assertThat(datapoint.getValue()).isCloseTo(value.doubleValue(), offset(0.1)); + assertThat(datapoint.getLabels().size()).isEqualTo(labelValues.size()); value.incrementAndGet(); snapshot = gauge.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); datapoint = snapshot.getDataPoints().get(0); - assertEquals(value.doubleValue(), datapoint.getValue(), 0.1); + assertThat(datapoint.getValue()).isCloseTo(value.doubleValue(), offset(0.1)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testGaugeNoCallback() { - GaugeWithCallback.builder().name("gauge").labelNames("l1", "l2").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> GaugeWithCallback.builder().name("gauge").labelNames("l1", "l2").build()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 0b9f90260..1eb1121ad 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1,10 +1,9 @@ package io.prometheus.metrics.core.metrics; import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -41,11 +40,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class HistogramTest { +class HistogramTest { private static final double RESET_DURATION_REACHED = -123.456; // just a random value indicating that we should simulate that the reset duration @@ -53,12 +52,12 @@ public class HistogramTest { private SpanContext origSpanContext; - @Before + @BeforeEach public void setUp() { origSpanContext = SpanContextSupplier.getSpanContext(); } - @After + @AfterEach public void tearDown() { SpanContextSupplier.setSpanContext(origSpanContext); } @@ -93,10 +92,9 @@ private void run() throws NoSuchFieldException, IllegalAccessException { new PrometheusProtobufWriter().convert(histogram.collect()); String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; - assertEquals( - "test \"" + name + "\" failed", - expectedWithMetadata, - TextFormat.printer().shortDebugString(protobufData)); + assertThat(TextFormat.printer().shortDebugString(protobufData)) + .as("test \"" + name + "\" failed") + .isEqualTo(expectedWithMetadata); } } @@ -829,11 +827,9 @@ public void testNativeBucketIndexToUpperBound() Histogram.builder().name("test").nativeInitialSchema(schemas[i]).build(); Histogram.DataPoint histogramData = histogram.newDataPoint(); double result = (double) method.invoke(histogramData, schemas[i], indexes[i]); - assertEquals( - "index=" + indexes[i] + ", schema=" + schemas[i], - expectedUpperBounds[i], - result, - 0.0000000000001); + assertThat(result) + .as("index=" + indexes[i] + ", schema=" + schemas[i]) + .isCloseTo(expectedUpperBounds[i], offset(0.0000000000001)); } } @@ -867,19 +863,20 @@ public void testFindBucketIndex() (double) nativeBucketIndexToUpperBound.invoke( histogram.getNoLabels(), schema, bucketIndex); - assertTrue( - "Bucket index " - + bucketIndex - + " with schema " - + schema - + " has range [" - + lowerBound - + ", " - + upperBound - + "]. Value " - + value - + " is outside of that range.", - lowerBound < value && upperBound >= value); + assertThat(lowerBound < value && upperBound >= value) + .as( + "Bucket index " + + bucketIndex + + " with schema " + + schema + + " has range [" + + lowerBound + + ", " + + upperBound + + "]. Value " + + value + + " is outside of that range.") + .isTrue(); } } } @@ -891,8 +888,7 @@ public void testDefaults() throws IOException { histogram.observe(0.5); HistogramSnapshot snapshot = histogram.collect(); String expectedProtobuf = - "" - + "name: \"test\" " + "name: \"test\" " + "type: HISTOGRAM " + "metric { " + "histogram { " @@ -925,9 +921,8 @@ public void testDefaults() throws IOException { + "positive_delta: 1 " + "} }"; String expectedTextFormat = - "" - // default classic buckets - + "# TYPE test histogram\n" + // default classic buckets + "# TYPE test histogram\n" + "test_bucket{le=\"0.005\"} 0\n" + "test_bucket{le=\"0.01\"} 0\n" + "test_bucket{le=\"0.025\"} 0\n" @@ -946,13 +941,13 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - assertEquals(expectedProtobuf, TextFormat.printer().shortDebugString(protobufData)); + assertThat(TextFormat.printer().shortDebugString(protobufData)).isEqualTo(expectedProtobuf); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true); writer.write(out, MetricSnapshots.of(snapshot)); - assertEquals(expectedTextFormat, out.toString()); + assertThat(out).hasToString(expectedTextFormat); } @Test @@ -1012,14 +1007,14 @@ public void markCurrentSpanAsExemplar() {} HistogramSnapshot snapshot = histogram.collect(); assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); - assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 2.0, "path", "/world")); - assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 3.0, "path", "/world")); - assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 4.0, "path", "/world")); - assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); - assertNull(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); + assertThat(getExemplar(snapshot, 2.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 2.0, "path", "/world")).isNull(); + assertThat(getExemplar(snapshot, 3.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 3.0, "path", "/world")).isNull(); + assertThat(getExemplar(snapshot, 4.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 4.0, "path", "/world")).isNull(); + assertThat(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")).isNull(); Thread.sleep(sampleIntervalMillis + 1); histogram.labelValues("/hello").observe(4.5); @@ -1028,12 +1023,12 @@ public void markCurrentSpanAsExemplar() {} snapshot = histogram.collect(); assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello")); assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world")); - assertNull(getExemplar(snapshot, 2.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 2.0, "path", "/world")); - assertNull(getExemplar(snapshot, 3.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 3.0, "path", "/world")); - assertNull(getExemplar(snapshot, 4.0, "path", "/hello")); - assertNull(getExemplar(snapshot, 4.0, "path", "/world")); + assertThat(getExemplar(snapshot, 2.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 2.0, "path", "/world")).isNull(); + assertThat(getExemplar(snapshot, 3.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 3.0, "path", "/world")).isNull(); + assertThat(getExemplar(snapshot, 4.0, "path", "/hello")).isNull(); + assertThat(getExemplar(snapshot, 4.0, "path", "/world")).isNull(); assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello")); assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world")); @@ -1154,12 +1149,16 @@ private void assertExemplar(Histogram histogram, double value, String... labels) } } Exemplar exemplar = data.getExemplars().get(lowerBound, upperBound); - assertNotNull("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]", exemplar); - assertEquals(value, exemplar.getValue(), 0.0); - assertEquals("" + exemplar.getLabels(), labels.length / 2, exemplar.getLabels().size()); + assertThat(exemplar) + .as("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]") + .isNotNull(); + assertThat(exemplar.getValue()).isCloseTo(value, offset(0.0)); + assertThat(exemplar.getLabels().size()) + .as("" + exemplar.getLabels()) + .isEqualTo(labels.length / 2); for (int i = 0; i < labels.length; i += 2) { - assertEquals(labels[i], exemplar.getLabels().getName(i / 2)); - assertEquals(labels[i + 1], exemplar.getLabels().getValue(i / 2)); + assertThat(exemplar.getLabels().getName(i / 2)).isEqualTo(labels[i]); + assertThat(exemplar.getLabels().getValue(i / 2)).isEqualTo(labels[i + 1]); } } @@ -1207,59 +1206,69 @@ public void markCurrentSpanAsExemplar() {} histogram.labelValues("/hello").observe(3.11); histogram.labelValues("/world").observe(3.12); - assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertThat(getData(histogram, "path", "/hello").getExemplars().size()).isOne(); assertExemplarEquals( ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); - assertEquals(1, getData(histogram, "path", "/world").getExemplars().size()); + assertThat(getData(histogram, "path", "/world").getExemplars().size()).isOne(); assertExemplarEquals( ex2, getData(histogram, "path", "/world").getExemplars().iterator().next()); histogram .labelValues("/world") .observeWithExemplar(3.13, Labels.of("key1", "value1", "key2", "value2")); - assertEquals(1, getData(histogram, "path", "/hello").getExemplars().size()); + assertThat(getData(histogram, "path", "/hello").getExemplars().size()).isOne(); assertExemplarEquals( ex1, getData(histogram, "path", "/hello").getExemplars().iterator().next()); - assertEquals(2, getData(histogram, "path", "/world").getExemplars().size()); + assertThat(getData(histogram, "path", "/world").getExemplars().size()).isEqualTo(2); Exemplars exemplars = getData(histogram, "path", "/world").getExemplars(); List exemplarList = new ArrayList<>(exemplars.size()); for (Exemplar exemplar : exemplars) { exemplarList.add(exemplar); } exemplarList.sort(Comparator.comparingDouble(Exemplar::getValue)); - assertEquals(2, exemplars.size()); + assertThat(exemplars.size()).isEqualTo(2); assertExemplarEquals(ex2, exemplarList.get(0)); assertExemplarEquals(ex3, exemplarList.get(1)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalLabelName() { - Histogram.builder().name("test").labelNames("label", "le"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Histogram.builder().name("test").labelNames("label", "le")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalLabelNameConstLabels() { - Histogram.builder().name("test").constLabels(Labels.of("label1", "value1", "le", "0.3")); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + Histogram.builder() + .name("test") + .constLabels(Labels.of("label1", "value1", "le", "0.3"))); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalLabelNamePrefix() { - Histogram.builder().name("test").labelNames("__hello"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Histogram.builder().name("test").labelNames("__hello")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalName() { - Histogram.builder().name("my_namespace/server.durations"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Histogram.builder().name("my_namespace/server.durations")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNoName() { - Histogram.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Histogram.builder().build()); } - @Test(expected = NullPointerException.class) + @Test public void testNullName() { - Histogram.builder().name(null); + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> Histogram.builder().name(null)); } @Test @@ -1270,7 +1279,8 @@ public void testDuplicateClassicBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY), upperBounds); + assertThat(upperBounds) + .isEqualTo(Arrays.asList(0.0, 3.0, 17.0, 21.0, Double.POSITIVE_INFINITY)); } @Test @@ -1280,7 +1290,7 @@ public void testUnsortedBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY), upperBounds); + assertThat(upperBounds).isEqualTo(Arrays.asList(0.1, 0.2, Double.POSITIVE_INFINITY)); } @Test @@ -1290,7 +1300,7 @@ public void testEmptyBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals(Collections.singletonList(Double.POSITIVE_INFINITY), upperBounds); + assertThat(upperBounds).isEqualTo(Collections.singletonList(Double.POSITIVE_INFINITY)); } @Test @@ -1304,7 +1314,7 @@ public void testBucketsIncludePositiveInfinity() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY), upperBounds); + assertThat(upperBounds).isEqualTo(Arrays.asList(0.01, 0.1, 1.0, Double.POSITIVE_INFINITY)); } @Test @@ -1315,9 +1325,10 @@ public void testLinearBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals( - Arrays.asList(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY), - upperBounds); + assertThat(upperBounds) + .isEqualTo( + Arrays.asList( + 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, Double.POSITIVE_INFINITY)); } @Test @@ -1328,20 +1339,22 @@ public void testExponentialBuckets() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getUpperBound) .collect(Collectors.toList()); - assertEquals(Arrays.asList(2.0, 5.0, 12.5, Double.POSITIVE_INFINITY), upperBounds); + assertThat(upperBounds).isEqualTo(Arrays.asList(2.0, 5.0, 12.5, Double.POSITIVE_INFINITY)); } - @Test(expected = RuntimeException.class) + @Test public void testBucketsIncludeNaN() { - Histogram.builder().name("test").classicUpperBounds(0.01, 0.1, 1.0, Double.NaN); + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy( + () -> Histogram.builder().name("test").classicUpperBounds(0.01, 0.1, 1.0, Double.NaN)); } @Test public void testNoLabelsDefaultZeroValue() { Histogram noLabels = Histogram.builder().name("test").build(); - assertEquals(0.0, getBucket(noLabels, 0.005).getCount(), 0.0); - assertEquals(0, getData(noLabels).getCount()); - assertEquals(0.0, getData(noLabels).getSum(), 0.0); + assertThat(getBucket(noLabels, 0.005).getCount()).isZero(); + assertThat(getData(noLabels).getCount()).isZero(); + assertThat(getData(noLabels).getSum()).isCloseTo(0.0, offset(0.0)); } private ClassicHistogramBucket getBucket(Histogram histogram, double le, String... labels) { @@ -1355,18 +1368,18 @@ private ClassicHistogramBucket getBucket(Histogram histogram, double le, String. public void testObserve() { Histogram noLabels = Histogram.builder().name("test").build(); noLabels.observe(2); - assertEquals(1, getData(noLabels).getCount()); - assertEquals(2.0, getData(noLabels).getSum(), .0); - assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); + assertThat(getData(noLabels).getCount()).isOne(); + assertThat(getData(noLabels).getSum()).isCloseTo(2.0, offset(.0)); + assertThat(getBucket(noLabels, 1).getCount()).isZero(); + assertThat(getBucket(noLabels, 2.5).getCount()).isOne(); noLabels.observe(4); - assertEquals(2.0, getData(noLabels).getCount(), .0); - assertEquals(6.0, getData(noLabels).getSum(), .0); - assertEquals(0.0, getBucket(noLabels, 1).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 2.5).getCount(), .0); - assertEquals(1.0, getBucket(noLabels, 5).getCount(), .0); - assertEquals(0.0, getBucket(noLabels, 10).getCount(), .0); - assertEquals(0.0, getBucket(noLabels, Double.POSITIVE_INFINITY).getCount(), .0); + assertThat(getData(noLabels).getCount()).isEqualTo(2); + assertThat(getData(noLabels).getSum()).isCloseTo(6.0, offset(.0)); + assertThat(getBucket(noLabels, 1).getCount()).isZero(); + assertThat(getBucket(noLabels, 2.5).getCount()).isOne(); + assertThat(getBucket(noLabels, 5).getCount()).isOne(); + assertThat(getBucket(noLabels, 10).getCount()).isZero(); + assertThat(getBucket(noLabels, Double.POSITIVE_INFINITY).getCount()).isZero(); } @Test @@ -1384,8 +1397,8 @@ public void testNegativeAmount() { histogram.observe(i); expectedCount++; expectedSum += i; - assertEquals(expectedSum, getData(histogram).getSum(), .001); - assertEquals(expectedCount, getData(histogram).getCount(), .001); + assertThat(getData(histogram).getSum()).isCloseTo(expectedSum, offset(.001)); + assertThat(getData(histogram).getCount()).isEqualTo((long) expectedCount); } List expectedBucketCounts = Arrays.asList(2L, 5L, 5L, 5L, 5L, 0L); // buckets -10, -5, 0, 5, 10, +Inf @@ -1393,22 +1406,22 @@ public void testNegativeAmount() { getData(histogram).getClassicBuckets().stream() .map(ClassicHistogramBucket::getCount) .collect(Collectors.toList()); - assertEquals(expectedBucketCounts, actualBucketCounts); + assertThat(actualBucketCounts).isEqualTo(expectedBucketCounts); } @Test public void testBoundaryConditions() { Histogram histogram = Histogram.builder().name("test").build(); histogram.observe(2.5); - assertEquals(0, getBucket(histogram, 1).getCount()); - assertEquals(1, getBucket(histogram, 2.5).getCount()); + assertThat(getBucket(histogram, 1).getCount()).isZero(); + assertThat(getBucket(histogram, 2.5).getCount()).isOne(); histogram.observe(Double.POSITIVE_INFINITY); - assertEquals(0, getBucket(histogram, 1).getCount()); - assertEquals(1, getBucket(histogram, 2.5).getCount()); - assertEquals(0, getBucket(histogram, 5).getCount()); - assertEquals(0, getBucket(histogram, 10).getCount()); - assertEquals(1, getBucket(histogram, Double.POSITIVE_INFINITY).getCount()); + assertThat(getBucket(histogram, 1).getCount()).isZero(); + assertThat(getBucket(histogram, 2.5).getCount()).isOne(); + assertThat(getBucket(histogram, 5).getCount()).isZero(); + assertThat(getBucket(histogram, 10).getCount()).isZero(); + assertThat(getBucket(histogram, Double.POSITIVE_INFINITY).getCount()).isOne(); } @Test @@ -1426,17 +1439,17 @@ public void testObserveWithLabels() { getData(histogram, "env", "prod", "path", "/hello", "status", "200"); HistogramSnapshot.HistogramDataPointSnapshot data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); - assertEquals(2, data200.getCount()); - assertEquals(0.31, data200.getSum(), 0.0000001); - assertEquals(1, data500.getCount()); - assertEquals(0.19, data500.getSum(), 0.0000001); + assertThat(data200.getCount()).isEqualTo(2); + assertThat(data200.getSum()).isCloseTo(0.31, offset(0.0000001)); + assertThat(data500.getCount()).isOne(); + assertThat(data500.getSum()).isCloseTo(0.19, offset(0.0000001)); histogram.labelValues("/hello", "200").observe(0.13); data200 = getData(histogram, "env", "prod", "path", "/hello", "status", "200"); data500 = getData(histogram, "env", "prod", "path", "/hello", "status", "500"); - assertEquals(3, data200.getCount()); - assertEquals(0.44, data200.getSum(), 0.0000001); - assertEquals(1, data500.getCount()); - assertEquals(0.19, data500.getSum(), 0.0000001); + assertThat(data200.getCount()).isEqualTo(3); + assertThat(data200.getSum()).isCloseTo(0.44, offset(0.0000001)); + assertThat(data500.getCount()).isOne(); + assertThat(data500.getSum()).isCloseTo(0.19, offset(0.0000001)); } @Test @@ -1472,22 +1485,23 @@ public void testObserveMultithreaded() List snapshots = future.get(5, TimeUnit.SECONDS); long count = 0; for (HistogramSnapshot snapshot : snapshots) { - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); HistogramSnapshot.HistogramDataPointSnapshot data = snapshot.getDataPoints().stream().findFirst().orElseThrow(RuntimeException::new); - assertTrue( - data.getCount() - >= (count + 1000)); // 1000 own observations plus the ones from other threads + assertThat(data.getCount()) + .isGreaterThanOrEqualTo( + (count + 1000)); // 1000 own observations plus the ones from other threads count = data.getCount(); } if (count > maxCount) { maxCount = count; } } - assertEquals(nThreads * 10_000, maxCount); // the last collect() has seen all observations - assertEquals(getBucket(histogram, 2.5, "status", "200").getCount(), nThreads * 10_000); + assertThat(maxCount) + .isEqualTo(nThreads * 10_000); // the last collect() has seen all observations + assertThat(nThreads * 10_000).isEqualTo(getBucket(histogram, 2.5, "status", "200").getCount()); executor.shutdown(); - assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS)); + assertThat(executor.awaitTermination(5, TimeUnit.SECONDS)).isTrue(); } private HistogramSnapshot.HistogramDataPointSnapshot getData( @@ -1495,9 +1509,6 @@ private HistogramSnapshot.HistogramDataPointSnapshot getData( return histogram.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) .findAny() - .orElseThrow( - () -> - new RuntimeException( - "histogram with labels " + Arrays.toString(labels) + " not found")); + .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index e527a3340..efdf211bb 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; @@ -11,9 +12,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class InfoTest { +class InfoTest { @Test public void testInfoStrippedFromName() { @@ -26,9 +27,9 @@ public void testInfoStrippedFromName() { Info info = Info.builder().name(name).labelNames(labelName).build(); info.addLabelValues("value"); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertEquals( - "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }", - TextFormat.printer().shortDebugString(protobufData)); + assertThat(TextFormat.printer().shortDebugString(protobufData)) + .isEqualTo( + "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }"); } } } @@ -36,19 +37,19 @@ public void testInfoStrippedFromName() { @Test public void testAddAndRemove() { Info info = Info.builder().name("test_info").labelNames("a", "b").build(); - assertEquals(0, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).isEmpty(); info.addLabelValues("val1", "val2"); - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); info.addLabelValues("val1", "val2"); // already exist, so no change - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); info.addLabelValues("val2", "val2"); - assertEquals(2, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(2); info.remove("val1", "val3"); // does not exist, so no change - assertEquals(2, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(2); info.remove("val1", "val2"); - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); info.remove("val2", "val2"); - assertEquals(0, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).isEmpty(); } @Test @@ -60,9 +61,9 @@ public void testSet() throws IOException { .labelNames("service.version") .build(); info.setLabelValues("1.0.0"); - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); info.setLabelValues("2.0.0"); - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); assertTextFormat( "target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info); @@ -75,18 +76,22 @@ public void testConstLabelsOnly() throws IOException { .name("target_info") .constLabels(Labels.of("service.name", "test", "service.instance.id", "123")) .build(); - assertEquals(1, info.collect().getDataPoints().size()); + assertThat(info.collect().getDataPoints()).hasSize(1); assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); } - @Test(expected = IllegalArgumentException.class) + @Test public void testConstLabelsDuplicate1() { - Info.builder().constLabels(Labels.of("a_1", "val1")).labelNames("a.1").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> Info.builder().constLabels(Labels.of("a_1", "val1")).labelNames("a.1").build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testConstLabelsDuplicate2() { - Info.builder().labelNames("a_1").constLabels(Labels.of("a.1", "val1")).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> Info.builder().labelNames("a_1").constLabels(Labels.of("a.1", "val1")).build()); } private void assertTextFormat(String expected, Info info) throws IOException { diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java index 54639e7b6..334724a81 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java @@ -1,14 +1,14 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class SlidingWindowTest { +class SlidingWindowTest { class Observer { @@ -19,19 +19,19 @@ public void observe(double value) { } void assertValues(double... expectedValues) { - List expectedList = new ArrayList<>(); + ArrayList expectedList = new ArrayList<>(); for (double expectedValue : expectedValues) { expectedList.add(expectedValue); } - assertEquals( - "Start time: " - + startTime - + ", current time: " - + currentTimeMillis.get() - + ", elapsed time: " - + (currentTimeMillis.get() - startTime), - expectedList, - values); + assertThat(values) + .as( + "Start time: " + + startTime + + ", current time: " + + currentTimeMillis.get() + + ", elapsed time: " + + (currentTimeMillis.get() - startTime)) + .isEqualTo(expectedList); } } @@ -42,7 +42,7 @@ void assertValues(double... expectedValues) { private final int ageBuckets = 5; private final long timeBetweenRotateMillis = maxAgeSeconds * 1000 / ageBuckets + 2; - @Before + @BeforeEach public void setUp() { startTime = System.currentTimeMillis(); currentTimeMillis.set(startTime); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java index ddb2c4e9b..a419e876c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java @@ -1,16 +1,14 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import java.util.Arrays; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class StateSetTest { +class StateSetTest { enum MyFeatureFlag { EXPERIMENTAL_FEATURE_1 { @@ -39,30 +37,30 @@ public void testEnumStateSet() { stateSet.labelValues("dev").setTrue(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); stateSet.labelValues("prod").setFalse(MyFeatureFlag.EXPERIMENTAL_FEATURE_2); StateSetSnapshot snapshot = stateSet.collect(); - assertEquals(2, snapshot.getDataPoints().size()); - assertEquals(2, getData(stateSet, "environment", "dev").size()); - assertEquals("feature1", getData(stateSet, "environment", "dev").getName(0)); - assertFalse(getData(stateSet, "environment", "dev").isTrue(0)); - assertEquals("feature2", getData(stateSet, "environment", "dev").getName(1)); - assertTrue(getData(stateSet, "environment", "dev").isTrue(1)); - assertEquals(2, getData(stateSet, "environment", "prod").size()); - assertEquals("feature1", getData(stateSet, "environment", "prod").getName(0)); - Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(0)); - assertEquals("feature2", getData(stateSet, "environment", "prod").getName(1)); - Assert.assertFalse(getData(stateSet, "environment", "prod").isTrue(1)); + assertThat(snapshot.getDataPoints()).hasSize(2); + assertThat(getData(stateSet, "environment", "dev").size()).isEqualTo(2); + assertThat(getData(stateSet, "environment", "dev").getName(0)).isEqualTo("feature1"); + assertThat(getData(stateSet, "environment", "dev").isTrue(0)).isFalse(); + assertThat(getData(stateSet, "environment", "dev").getName(1)).isEqualTo("feature2"); + assertThat(getData(stateSet, "environment", "dev").isTrue(1)).isTrue(); + assertThat(getData(stateSet, "environment", "prod").size()).isEqualTo(2); + assertThat(getData(stateSet, "environment", "prod").getName(0)).isEqualTo("feature1"); + assertThat(getData(stateSet, "environment", "prod").isTrue(0)).isFalse(); + assertThat(getData(stateSet, "environment", "prod").getName(1)).isEqualTo("feature2"); + assertThat(getData(stateSet, "environment", "prod").isTrue(1)).isFalse(); } @Test public void testDefaultFalse() { StateSet stateSet = StateSet.builder().name("test").states("state1", "state2", "state3").build(); - assertEquals(3, getData(stateSet).size()); - assertEquals("state1", getData(stateSet).getName(0)); - Assert.assertFalse(getData(stateSet).isTrue(0)); - assertEquals("state2", getData(stateSet).getName(1)); - Assert.assertFalse(getData(stateSet).isTrue(1)); - assertEquals("state3", getData(stateSet).getName(2)); - Assert.assertFalse(getData(stateSet).isTrue(2)); + assertThat(getData(stateSet).size()).isEqualTo(3); + assertThat(getData(stateSet).getName(0)).isEqualTo("state1"); + assertThat(getData(stateSet).isTrue(0)).isFalse(); + assertThat(getData(stateSet).getName(1)).isEqualTo("state2"); + assertThat(getData(stateSet).isTrue(1)).isFalse(); + assertThat(getData(stateSet).getName(2)).isEqualTo("state3"); + assertThat(getData(stateSet).isTrue(2)).isFalse(); } private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) { @@ -75,8 +73,9 @@ private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, St "stateset with labels " + Arrays.toString(labels) + " not found")); } - @Test(expected = IllegalStateException.class) + @Test public void testStatesCannotBeEmpty() { - StateSet.builder().name("invalid").build(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> StateSet.builder().name("invalid").build()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index a3ddbcc84..d05cf145a 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -1,13 +1,13 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import java.lang.reflect.Field; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class StatefulMetricTest { +class StatefulMetricTest { @Test public void testLabelRemoveWhileCollecting() throws Exception { @@ -30,8 +30,8 @@ public void testLabelRemoveWhileCollecting() throws Exception { counter.remove("c", "d"); counter.remove("e", "f"); } - assertNotNull(entry.getKey()); - assertNotNull(entry.getValue()); + assertThat(entry.getKey()).isNotNull(); + assertThat(entry.getValue()).isNotNull(); } } @@ -41,31 +41,31 @@ public void testClear() { counter.labelValues("a", "b").inc(3.0); counter.labelValues("c", "d").inc(3.0); counter.labelValues("a", "b").inc(); - assertEquals(2, counter.collect().getDataPoints().size()); + assertThat(counter.collect().getDataPoints()).hasSize(2); counter.clear(); - assertEquals(0, counter.collect().getDataPoints().size()); + assertThat(counter.collect().getDataPoints()).isEmpty(); counter.labelValues("a", "b").inc(); - assertEquals(1, counter.collect().getDataPoints().size()); + assertThat(counter.collect().getDataPoints()).hasSize(1); } @Test public void testClearNoLabels() { Counter counter = Counter.builder().name("test").build(); counter.inc(); - assertEquals(1, counter.collect().getDataPoints().size()); - assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertThat(counter.collect().getDataPoints()).hasSize(1); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(1.0, offset(0.0)); counter.clear(); // No labels is always present, but as no value has been observed after clear() the value should // be 0.0 - assertEquals(1, counter.collect().getDataPoints().size()); - assertEquals(0.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertThat(counter.collect().getDataPoints()).hasSize(1); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(0.0, offset(0.0)); // Making inc() works correctly after clear() counter.inc(); - assertEquals(1, counter.collect().getDataPoints().size()); - assertEquals(1.0, counter.collect().getDataPoints().get(0).getValue(), 0.0); + assertThat(counter.collect().getDataPoints()).hasSize(1); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(1.0, offset(0.0)); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java index 365ff1824..dbabb1a93 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java @@ -1,7 +1,9 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.datapoints.Timer; import io.prometheus.metrics.model.registry.PrometheusRegistry; @@ -12,10 +14,10 @@ import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.Unit; import java.util.List; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class SummaryTest { +class SummaryTest { private final Label label = new Label("name", "value"); private final Labels labels = Labels.builder().label(label.getName(), label.getValue()).build(); @@ -26,7 +28,7 @@ public class SummaryTest { private Summary withLabelsAndQuantiles; private Summary noLabelsAndQuantiles; - @Before + @BeforeEach public void setUp() { registry = new PrometheusRegistry(); noLabels = @@ -62,27 +64,27 @@ public void setUp() { @Test public void testObserve() { noLabels.observe(2); - assertEquals(1, getCount(noLabels, Labels.EMPTY)); - assertEquals(2.0, getSum(noLabels, Labels.EMPTY), .001); + assertThat(getCount(noLabels, Labels.EMPTY)).isOne(); + assertThat(getSum(noLabels, Labels.EMPTY)).isCloseTo(2.0, offset(.001)); noLabels.observe(3); - assertEquals(2, getCount(noLabels, Labels.EMPTY)); - assertEquals(5.0, getSum(noLabels, Labels.EMPTY), .001); + assertThat(getCount(noLabels, Labels.EMPTY)).isEqualTo(2); + assertThat(getSum(noLabels, Labels.EMPTY)).isCloseTo(5.0, offset(.001)); withLabels.labelValues(label.getValue()).observe(4); - assertEquals(1, getCount(withLabels, labels)); - assertEquals(4.0, getSum(withLabels, labels), .001); + assertThat(getCount(withLabels, labels)).isOne(); + assertThat(getSum(withLabels, labels)).isCloseTo(4.0, offset(.001)); withLabels.labelValues(label.getValue()).observeWithExemplar(6, labels); - assertEquals(2, getCount(withLabels, labels)); - assertEquals(10.0, getSum(withLabels, labels), .001); + assertThat(getCount(withLabels, labels)).isEqualTo(2); + assertThat(getSum(withLabels, labels)).isCloseTo(10.0, offset(.001)); } @Test public void testNegativeAmount() { noLabels.observe(-1); noLabels.observe(-3); - assertEquals(2, getCount(noLabels, Labels.EMPTY)); - assertEquals(-4.0, getSum(noLabels, Labels.EMPTY), .001); + assertThat(getCount(noLabels, Labels.EMPTY)).isEqualTo(2); + assertThat(getSum(noLabels, Labels.EMPTY)).isCloseTo(-4.0, offset(.001)); } @Test @@ -95,17 +97,19 @@ public void testQuantiles() { withLabelsAndQuantiles.labelValues(label.getValue()).observe(i); noLabelsAndQuantiles.observe(i); } - assertEquals( - getQuantile(noLabelsAndQuantiles, 0.5, Labels.EMPTY), 0.5 * nSamples, 0.05 * nSamples); - assertEquals( - getQuantile(noLabelsAndQuantiles, 0.9, Labels.EMPTY), 0.9 * nSamples, 0.01 * nSamples); - assertEquals( - getQuantile(noLabelsAndQuantiles, 0.99, Labels.EMPTY), 0.99 * nSamples, 0.001 * nSamples); - - assertEquals(getQuantile(withLabelsAndQuantiles, 0.5, labels), 0.5 * nSamples, 0.05 * nSamples); - assertEquals(getQuantile(withLabelsAndQuantiles, 0.9, labels), 0.9 * nSamples, 0.01 * nSamples); - assertEquals( - getQuantile(withLabelsAndQuantiles, 0.99, labels), 0.99 * nSamples, 0.001 * nSamples); + assertThat(0.5 * nSamples) + .isCloseTo(getQuantile(noLabelsAndQuantiles, 0.5, Labels.EMPTY), offset(0.05 * nSamples)); + assertThat(0.9 * nSamples) + .isCloseTo(getQuantile(noLabelsAndQuantiles, 0.9, Labels.EMPTY), offset(0.01 * nSamples)); + assertThat(0.99 * nSamples) + .isCloseTo(getQuantile(noLabelsAndQuantiles, 0.99, Labels.EMPTY), offset(0.001 * nSamples)); + + assertThat(0.5 * nSamples) + .isCloseTo(getQuantile(withLabelsAndQuantiles, 0.5, labels), offset(0.05 * nSamples)); + assertThat(0.9 * nSamples) + .isCloseTo(getQuantile(withLabelsAndQuantiles, 0.9, labels), offset(0.01 * nSamples)); + assertThat(0.99 * nSamples) + .isCloseTo(getQuantile(withLabelsAndQuantiles, 0.99, labels), offset(0.001 * nSamples)); } @Test @@ -119,52 +123,56 @@ public void testMaxAge() throws InterruptedException { .help("help") .register(registry); summary.observe(8.0); - assertEquals(8.0, getQuantile(summary, 0.99, Labels.EMPTY), 0.0); // From bucket 1. + assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) + .isCloseTo(8.0, offset(0.0)); // From bucket 1. Thread.sleep(600); - assertEquals(8.0, getQuantile(summary, 0.99, Labels.EMPTY), 0.0); // From bucket 2. + assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) + .isCloseTo(8.0, offset(0.0)); // From bucket 2. Thread.sleep(600); - assertEquals( - Double.NaN, - getQuantile(summary, 0.99, Labels.EMPTY), - 0.0); // Bucket 1 again, now it is empty. + assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) + .isCloseTo(Double.NaN, offset(0.0)); // Bucket 1 again, now it is empty. } @Test public void testTimer() { int result = noLabels.time(() -> 123); - assertEquals(123, result); - assertEquals(1, getCount(noLabels, Labels.EMPTY)); + assertThat(result).isEqualTo(123); + assertThat(getCount(noLabels, Labels.EMPTY)).isOne(); try (Timer timer = noLabels.startTimer()) { timer.observeDuration(); - assertEquals(2, getCount(noLabels, Labels.EMPTY), .001); + assertThat(getCount(noLabels, Labels.EMPTY)).isEqualTo(2); } } @Test public void noLabelsDefaultZeroValue() { - assertEquals(0.0, getCount(noLabels, Labels.EMPTY), .001); - assertEquals(0.0, getSum(noLabels, Labels.EMPTY), .001); + assertThat(getCount(noLabels, Labels.EMPTY)).isZero(); + assertThat(getSum(noLabels, Labels.EMPTY)).isCloseTo(0.0, offset(.001)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testBuilderInvalidNumberOfAgeBuckets() { - Summary.builder().name("name").numberOfAgeBuckets(-1).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Summary.builder().name("name").numberOfAgeBuckets(-1).build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testBuilderInvalidMaxAge() { - Summary.builder().name("name").maxAgeSeconds(-1).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Summary.builder().name("name").maxAgeSeconds(-1).build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testBuilderInvalidQuantile() { - Summary.builder().name("name").quantile(42).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Summary.builder().name("name").quantile(42).build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testBuilderInvalidQuantileError() { - Summary.builder().name("name").quantile(0.5, 20).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Summary.builder().name("name").quantile(0.5, 20).build()); } private double getQuantile(Summary summary, double quantile, Labels labels) { @@ -182,9 +190,9 @@ private double getQuantile(Summary summary, double quantile, Labels labels) { private SummarySnapshot.SummaryDataPointSnapshot getDatapoint(Summary summary, Labels labels) { SummarySnapshot snapshot = summary.collect(); List datapoints = snapshot.getDataPoints(); - assertEquals(1, datapoints.size()); + assertThat(datapoints.size()).isOne(); SummarySnapshot.SummaryDataPointSnapshot datapoint = datapoints.get(0); - assertEquals(labels, datapoint.getLabels()); + assertThat((Iterable) datapoint.getLabels()).isEqualTo(labels); return datapoint; } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java index ba1df05ff..929efc597 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryWithCallbackTest.java @@ -1,6 +1,8 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.model.snapshots.Quantile; import io.prometheus.metrics.model.snapshots.Quantiles; @@ -8,9 +10,9 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class SummaryWithCallbackTest { +class SummaryWithCallbackTest { @Test public void testGauge() { @@ -30,24 +32,26 @@ public void testGauge() { .build(); SummarySnapshot snapshot = gauge.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); SummarySnapshot.SummaryDataPointSnapshot datapoint = snapshot.getDataPoints().get(0); - assertEquals(count.get(), datapoint.getCount()); - assertEquals(sum.doubleValue(), datapoint.getSum(), 0.1); - assertEquals(quantiles, datapoint.getQuantiles()); - assertEquals(labelValues.size(), datapoint.getLabels().size()); + assertThat(datapoint.getCount()).isEqualTo(count.get()); + assertThat(datapoint.getSum()).isCloseTo(sum.doubleValue(), offset(0.1)); + assertThat(datapoint.getQuantiles()).isEqualTo(quantiles); + assertThat(datapoint.getLabels().size()).isEqualTo(labelValues.size()); count.incrementAndGet(); sum.incrementAndGet(); snapshot = gauge.collect(); - assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); datapoint = snapshot.getDataPoints().get(0); - assertEquals(count.get(), datapoint.getCount()); - assertEquals(sum.doubleValue(), datapoint.getSum(), 0.1); + assertThat(datapoint.getCount()).isEqualTo(count.get()); + assertThat(datapoint.getSum()).isCloseTo(sum.doubleValue(), offset(0.1)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testSummaryNoCallback() { - SummaryWithCallback.builder().name("summary").labelNames("l1", "l2").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> SummaryWithCallback.builder().name("summary").labelNames("l1", "l2").build()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java index 6a242a8be..8d9a5bd0f 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java @@ -1,14 +1,16 @@ package io.prometheus.metrics.core.metrics; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Label; -public class TestUtil { +class TestUtil { public static void assertExemplarEquals(Exemplar expected, Exemplar actual) { // ignore timestamp - assertEquals(expected.getValue(), actual.getValue(), 0.00001); - assertEquals(expected.getLabels(), actual.getLabels()); + assertThat(actual.getValue()).isCloseTo(expected.getValue(), offset(0.00001)); + assertThat((Iterable) actual.getLabels()).isEqualTo(expected.getLabels()); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java index be6d17784..417226b94 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TodoTest.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.core.metrics; -public class TodoTest { +class TodoTest { // if a metric with labels is created but never used it has no data. // The registry's collect() method should skip those metrics to avoid illegal protobuf or text diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 448390bb2..0247be420 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -51,12 +51,6 @@ - - junit - junit - 4.13.2 - test - org.wiremock wiremock diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java index 5af5193f6..def62834f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java @@ -5,13 +5,15 @@ import static com.github.tomakehurst.wiremock.client.WireMock.ok; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.awaitility.Awaitility.await; import com.github.tomakehurst.wiremock.http.Request; -import com.github.tomakehurst.wiremock.junit.WireMockRule; +import com.github.tomakehurst.wiremock.junit5.WireMockTest; import com.github.tomakehurst.wiremock.matching.MatchResult; import com.github.tomakehurst.wiremock.matching.ValueMatcher; import com.google.protobuf.InvalidProtocolBufferException; @@ -28,12 +30,12 @@ import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.model.registry.PrometheusRegistry; import org.awaitility.core.ConditionTimeoutException; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class ExemplarTest { +@WireMockTest(httpPort = 4317) +class ExemplarTest { private static final String ENDPOINT_PATH = "/v1/metrics"; private static final int TIMEOUT = 3; private static final String INSTRUMENTATION_SCOPE_NAME = "testInstrumentationScope"; @@ -41,9 +43,8 @@ public class ExemplarTest { public static final String TEST_COUNTER_NAME = "test_counter"; private Counter testCounter; private OpenTelemetryExporter openTelemetryExporter; - @Rule public WireMockRule wireMockRule = new WireMockRule(4317); - @Before + @BeforeEach public void setUp() { openTelemetryExporter = OpenTelemetryExporter.builder() @@ -54,7 +55,7 @@ public void setUp() { testCounter = Counter.builder().name(TEST_COUNTER_NAME).withExemplars().register(); - wireMockRule.stubFor( + stubFor( post(ENDPOINT_PATH) .withHeader("Content-Type", containing("application/x-protobuf")) .willReturn( @@ -62,7 +63,7 @@ public void setUp() { .withBody("{\"partialSuccess\":{}}"))); } - @After + @AfterEach public void tearDown() { PrometheusRegistry.defaultRegistry.unregister(testCounter); openTelemetryExporter.close(); @@ -93,7 +94,7 @@ public void sampledExemplarIsForwarded() { }); } - @Test(expected = ConditionTimeoutException.class) + @Test public void notSampledExemplarIsNotForwarded() { try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().setSampler(Sampler.alwaysOff()).build()) { @@ -105,17 +106,21 @@ public void notSampledExemplarIsNotForwarded() { } } - await() - .atMost(TIMEOUT, SECONDS) - .ignoreException(com.github.tomakehurst.wiremock.client.VerificationException.class) - .until( - () -> { - verify( - postRequestedFor(urlEqualTo(ENDPOINT_PATH)) - .withHeader("Content-Type", equalTo("application/x-protobuf")) - .andMatching(getExemplarCountMatcher(1))); - return true; - }); + assertThatExceptionOfType(ConditionTimeoutException.class) + .isThrownBy( + () -> + await() + .atMost(TIMEOUT, SECONDS) + .ignoreException( + com.github.tomakehurst.wiremock.client.VerificationException.class) + .until( + () -> { + verify( + postRequestedFor(urlEqualTo(ENDPOINT_PATH)) + .withHeader("Content-Type", equalTo("application/x-protobuf")) + .andMatching(getExemplarCountMatcher(1))); + return true; + })); } private static ValueMatcher getExemplarCountMatcher(int expectedCount) { diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 8b6e22525..8272ac9d7 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -29,12 +30,12 @@ - + brian-brazil Brian Brazil brian.brazil@boxever.com - - + + fstab Fabian Stäber fabian@fstab.de @@ -47,21 +48,9 @@ prometheus-metrics-exporter-common ${project.version} - - junit - junit - 4.13.2 - test - - - org.mock-server - mockserver-netty - 5.15.0 - test - org.mock-server - mockserver-junit-rule-no-dependencies + mockserver-netty-no-dependencies 5.15.0 test diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java index 7fbb32b10..598172eaa 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java @@ -6,34 +6,38 @@ import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.IOException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockserver.client.MockServerClient; -import org.mockserver.junit.MockServerRule; +import org.mockserver.integration.ClientAndServer; -public class BasicAuthPushGatewayTest { - - @Rule public MockServerRule mockServerRule = new MockServerRule(this); +class BasicAuthPushGatewayTest { private MockServerClient mockServerClient; PrometheusRegistry registry; Gauge gauge; PushGateway pushGateway; - @Before + @BeforeEach public void setUp() { + mockServerClient = ClientAndServer.startClientAndServer(0); registry = new PrometheusRegistry(); gauge = Gauge.builder().name("g").help("help").build(); pushGateway = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .basicAuth("testUser", "testPwd") .registry(registry) .job("j") .build(); } + @AfterEach + void tearDown() { + mockServerClient.stop(); + } + @Test public void testAuthorizedPush() throws IOException { mockServerClient diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java index 144a0f24f..09e6ff5e9 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BearerTokenPushGatewayTest.java @@ -6,34 +6,39 @@ import io.prometheus.metrics.core.metrics.Gauge; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.IOException; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockserver.client.MockServerClient; -import org.mockserver.junit.MockServerRule; +import org.mockserver.integration.ClientAndServer; -public class BearerTokenPushGatewayTest { +class BearerTokenPushGatewayTest { - @Rule public MockServerRule mockServerRule = new MockServerRule(this); private MockServerClient mockServerClient; PrometheusRegistry registry; Gauge gauge; PushGateway pushGateway; - @Before + @BeforeEach public void setUp() { + mockServerClient = ClientAndServer.startClientAndServer(0); registry = new PrometheusRegistry(); gauge = Gauge.builder().name("g").help("help").build(); pushGateway = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .bearerToken("xxx") .registry(registry) .job("j") .build(); } + @AfterEach + void tearDown() { + mockServerClient.stop(); + } + @Test public void testAuthorizedPush() throws IOException { mockServerClient diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java index ce88300db..27617913b 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.exporter.pushgateway; -import static org.junit.rules.ExpectedException.none; +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; @@ -10,35 +11,40 @@ import java.lang.reflect.Field; import java.net.InetAddress; import java.net.URL; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockserver.client.MockServerClient; -import org.mockserver.junit.MockServerRule; +import org.mockserver.integration.ClientAndServer; -public class PushGatewayTest { +class PushGatewayTest { - @Rule public final ExpectedException thrown = none(); - - @Rule public MockServerRule mockServerRule = new MockServerRule(this); private MockServerClient mockServerClient; PrometheusRegistry registry; Gauge gauge; - @Before + @BeforeEach public void setUp() { + mockServerClient = ClientAndServer.startClientAndServer(0); registry = new PrometheusRegistry(); gauge = Gauge.builder().name("g").help("help").build(); } - @Test(expected = RuntimeException.class) + @AfterEach + void tearDown() { + mockServerClient.stop(); + } + + @Test public void testInvalidURLThrowsRuntimeException() { - PushGateway.builder() - .address("::") - .build(); // ":" is interpreted as port number, so parsing fails + assertThatExceptionOfType(RuntimeException.class) + .isThrownBy( + () -> { + PushGateway.builder() + .address("::") + .build(); // ":" is interpreted as port number, so parsing fails + }); } @Test @@ -46,8 +52,8 @@ public void testMultipleSlashesAreStrippedFromURL() throws NoSuchFieldException, IllegalAccessException { final PushGateway pushGateway = PushGateway.builder().address("example.com:1234/context///path//").job("test").build(); - Assert.assertEquals( - "http://example.com:1234/context/path/metrics/job/test", getUrl(pushGateway).toString()); + assertThat(getUrl(pushGateway)) + .hasToString("http://example.com:1234/context/path/metrics/job/test"); } private URL getUrl(PushGateway pushGateway) throws IllegalAccessException, NoSuchFieldException { @@ -63,7 +69,7 @@ public void testPush() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .build(); @@ -77,7 +83,7 @@ public void testPush200Response() throws IOException { .respond(response().withStatusCode(200)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .build(); @@ -85,22 +91,25 @@ public void testPush200Response() throws IOException { } @Test - public void testNon202ResponseThrows() throws IOException { + public void testNon202ResponseThrows() { mockServerClient .when(request().withMethod("PUT").withPath("/metrics/job/j")) .respond(response().withStatusCode(500)); - thrown.expect(IOException.class); - thrown.expectMessage( - "Response code from http://localhost:" - + mockServerRule.getPort() - + "/metrics/job/j was 500"); - PushGateway pg = - PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) - .registry(registry) - .job("j") - .build(); - pg.push(); + assertThatExceptionOfType(IOException.class) + .isThrownBy( + () -> { + PushGateway pg = + PushGateway.builder() + .address("localhost:" + mockServerClient.getPort()) + .registry(registry) + .job("j") + .build(); + pg.push(); + }) + .withMessageContaining( + "Response code from http://localhost:" + + mockServerClient.getPort() + + "/metrics/job/j was 500"); } @Test @@ -110,7 +119,7 @@ public void testPushCollector() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .build(); @@ -124,7 +133,7 @@ public void testPushWithGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .groupingKey("l", "v") @@ -139,7 +148,7 @@ public void testPushWithMultiGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .groupingKey("l", "v") @@ -155,7 +164,7 @@ public void testPushWithEmptyLabelGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .groupingKey("l", "v") @@ -172,7 +181,7 @@ public void testPushWithGroupingKeyWithSlashes() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("a/b") .groupingKey("l", "v") @@ -188,7 +197,7 @@ public void testPushCollectorWithGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .groupingKey("l", "v") @@ -203,7 +212,7 @@ public void testPushAdd() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .job("j") .build(); @@ -216,7 +225,7 @@ public void testPushAddCollector() throws IOException { .when(request().withMethod("POST").withPath("/metrics/job/j")) .respond(response().withStatusCode(202)); PushGateway pg = - PushGateway.builder().address("localhost:" + mockServerRule.getPort()).job("j").build(); + PushGateway.builder().address("localhost:" + mockServerClient.getPort()).job("j").build(); pg.pushAdd(gauge); } @@ -227,7 +236,7 @@ public void testPushAddWithGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .groupingKey("l", "v") .job("j") @@ -242,7 +251,7 @@ public void testPushAddCollectorWithGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .registry(registry) .groupingKey("l", "v") .job("j") @@ -256,7 +265,7 @@ public void testDelete() throws IOException { .when(request().withMethod("DELETE").withPath("/metrics/job/j")) .respond(response().withStatusCode(202)); PushGateway pg = - PushGateway.builder().address("localhost:" + mockServerRule.getPort()).job("j").build(); + PushGateway.builder().address("localhost:" + mockServerClient.getPort()).job("j").build(); pg.delete(); } @@ -267,7 +276,7 @@ public void testDeleteWithGroupingKey() throws IOException { .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .job("j") .groupingKey("l", "v") .build(); @@ -277,13 +286,13 @@ public void testDeleteWithGroupingKey() throws IOException { @Test public void testInstanceIpGroupingKey() throws IOException { String ip = InetAddress.getLocalHost().getHostAddress(); - Assert.assertFalse(ip.isEmpty()); + assertThat(ip).isNotEmpty(); mockServerClient .when(request().withMethod("DELETE").withPath("/metrics/job/j/instance/" + ip + "/l/v")) .respond(response().withStatusCode(202)); PushGateway pg = PushGateway.builder() - .address("localhost:" + mockServerRule.getPort()) + .address("localhost:" + mockServerClient.getPort()) .job("j") .groupingKey("l", "v") .instanceIpGroupingKey() diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index b745e62cc..e7de1e28b 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -53,14 +53,6 @@ 1.3.1 - - - - junit - junit - 4.13.2 - test - diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 1ce3f2840..307b88938 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.expositionformats; +import static org.assertj.core.api.Assertions.assertThat; + import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; import io.prometheus.metrics.model.snapshots.*; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; @@ -9,10 +11,9 @@ import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ExpositionFormatsTest { +class ExpositionFormatsTest { private final String exemplar1String = "{env=\"prod\",span_id=\"12345\",trace_id=\"abcde\"} 1.7 1672850685.829"; @@ -80,8 +81,7 @@ public class ExpositionFormatsTest { @Test public void testCounterComplete() throws IOException { String openMetricsText = - "" - + "# TYPE service_time_seconds counter\n" + "# TYPE service_time_seconds counter\n" + "# UNIT service_time_seconds seconds\n" + "# HELP service_time_seconds total time spent serving\n" + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " @@ -106,8 +106,7 @@ public void testCounterComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP service_time_seconds_total total time spent serving\n" + "# HELP service_time_seconds_total total time spent serving\n" + "# TYPE service_time_seconds_total counter\n" + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s @@ -128,8 +127,7 @@ public void testCounterComplete() throws IOException { + scrapeTimestamp2s + "\n"; String openMetricsTextWithoutCreated = - "" - + "# TYPE service_time_seconds counter\n" + "# TYPE service_time_seconds counter\n" + "# UNIT service_time_seconds seconds\n" + "# HELP service_time_seconds total time spent serving\n" + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " @@ -144,8 +142,7 @@ public void testCounterComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = - "" - + "# HELP service_time_seconds_total total time spent serving\n" + "# HELP service_time_seconds_total total time spent serving\n" + "# TYPE service_time_seconds_total counter\n" + "service_time_seconds_total{path=\"/hello\",status=\"200\"} 0.8 " + scrapeTimestamp1s @@ -154,10 +151,8 @@ public void testCounterComplete() throws IOException { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"service_time_seconds_total\" " + // @formatter:off + "name: \"service_time_seconds_total\" " + "help: \"total time spent serving\" " + "type: COUNTER " + "metric { " @@ -213,11 +208,10 @@ public void testCounterComplete() throws IOException { @Test public void testCounterMinimal() throws IOException { - String openMetricsText = - "" + "# TYPE my_counter counter\n" + "my_counter_total 1.1\n" + "# EOF\n"; - String prometheusText = "" + "# TYPE my_counter_total counter\n" + "my_counter_total 1.1\n"; + String openMetricsText = "# TYPE my_counter counter\n" + "my_counter_total 1.1\n" + "# EOF\n"; + String prometheusText = "# TYPE my_counter_total counter\n" + "my_counter_total 1.1\n"; String prometheusProtobuf = - "" + "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; + "name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }"; CounterSnapshot counter = CounterSnapshot.builder() .name("my_counter") @@ -233,21 +227,17 @@ public void testCounterMinimal() throws IOException { @Test public void testCounterWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_request_count counter\n" + "# TYPE my_request_count counter\n" + "my_request_count_total{http_path=\"/hello\"} 3.0 # " + exemplarWithDotsString + "\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE my_request_count_total counter\n" + "# TYPE my_request_count_total counter\n" + "my_request_count_total{http_path=\"/hello\"} 3.0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_request_count_total\" " + // @formatter:off + "name: \"my_request_count_total\" " + "type: COUNTER " + "metric { " + "label { name: \"http_path\" value: \"/hello\" } " @@ -277,8 +267,7 @@ public void testCounterWithDots() throws IOException { @Test public void testGaugeComplete() throws IOException { String openMetricsText = - "" - + "# TYPE disk_usage_ratio gauge\n" + "# TYPE disk_usage_ratio gauge\n" + "# UNIT disk_usage_ratio ratio\n" + "# HELP disk_usage_ratio percentage used\n" + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " @@ -289,8 +278,7 @@ public void testGaugeComplete() throws IOException { + "\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE disk_usage_ratio gauge\n" + "# TYPE disk_usage_ratio gauge\n" + "# UNIT disk_usage_ratio ratio\n" + "# HELP disk_usage_ratio percentage used\n" + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " @@ -305,8 +293,7 @@ public void testGaugeComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP disk_usage_ratio percentage used\n" + "# HELP disk_usage_ratio percentage used\n" + "# TYPE disk_usage_ratio gauge\n" + "disk_usage_ratio{device=\"/dev/sda1\"} 0.2 " + scrapeTimestamp1s @@ -315,10 +302,8 @@ public void testGaugeComplete() throws IOException { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"disk_usage_ratio\" " + // @formatter:off + "name: \"disk_usage_ratio\" " + "help: \"percentage used\" " + "type: GAUGE " + "metric { " @@ -363,11 +348,11 @@ public void testGaugeComplete() throws IOException { @Test public void testGaugeMinimal() throws IOException { String openMetricsText = - "" + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n" + "# EOF\n"; + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n" + "# EOF\n"; String prometheusText = - "" + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n"; + "# TYPE temperature_centigrade gauge\n" + "temperature_centigrade 22.3\n"; String prometheusProtobuf = - "" + "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; + "name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }"; GaugeSnapshot gauge = GaugeSnapshot.builder() .name("temperature_centigrade") @@ -383,15 +368,13 @@ public void testGaugeMinimal() throws IOException { @Test public void testGaugeWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_temperature_celsius gauge\n" + "# TYPE my_temperature_celsius gauge\n" + "# UNIT my_temperature_celsius celsius\n" + "# HELP my_temperature_celsius Temperature\n" + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE my_temperature_celsius gauge\n" + "# TYPE my_temperature_celsius gauge\n" + "# UNIT my_temperature_celsius celsius\n" + "# HELP my_temperature_celsius Temperature\n" + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0 # " @@ -399,15 +382,12 @@ public void testGaugeWithDots() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP my_temperature_celsius Temperature\n" + "# HELP my_temperature_celsius Temperature\n" + "# TYPE my_temperature_celsius gauge\n" + "my_temperature_celsius{location_id=\"data-center-1\"} 23.0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_temperature_celsius\" " + // @formatter:off + "name: \"my_temperature_celsius\" " + "help: \"Temperature\" " + "type: GAUGE " + "metric { " @@ -440,8 +420,7 @@ public void testGaugeWithDots() throws IOException { @Test public void testSummaryComplete() throws IOException { String openMetricsText = - "" - + "# TYPE http_request_duration_seconds summary\n" + "# TYPE http_request_duration_seconds summary\n" + "# UNIT http_request_duration_seconds seconds\n" + "# HELP http_request_duration_seconds request duration\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " @@ -486,8 +465,7 @@ public void testSummaryComplete() throws IOException { + "\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE http_request_duration_seconds summary\n" + "# TYPE http_request_duration_seconds summary\n" + "# UNIT http_request_duration_seconds seconds\n" + "# HELP http_request_duration_seconds request duration\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " @@ -548,8 +526,7 @@ public void testSummaryComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP http_request_duration_seconds request duration\n" + "# HELP http_request_duration_seconds request duration\n" + "# TYPE http_request_duration_seconds summary\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s @@ -594,8 +571,7 @@ public void testSummaryComplete() throws IOException { + scrapeTimestamp2s + "\n"; String openMetricsTextWithoutCreated = - "" - + "# TYPE http_request_duration_seconds summary\n" + "# TYPE http_request_duration_seconds summary\n" + "# UNIT http_request_duration_seconds seconds\n" + "# HELP http_request_duration_seconds request duration\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " @@ -630,8 +606,7 @@ public void testSummaryComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = - "" - + "# HELP http_request_duration_seconds request duration\n" + "# HELP http_request_duration_seconds request duration\n" + "# TYPE http_request_duration_seconds summary\n" + "http_request_duration_seconds{status=\"200\",quantile=\"0.5\"} 225.3 " + scrapeTimestamp1s @@ -664,10 +639,8 @@ public void testSummaryComplete() throws IOException { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"http_request_duration_seconds\" " + // @formatter:off + "name: \"http_request_duration_seconds\" " + "help: \"request duration\" " + "type: SUMMARY " + "metric { " @@ -689,7 +662,6 @@ public void testSummaryComplete() throws IOException { + "quantile { quantile: 0.9 value: 240.7 } " + "quantile { quantile: 0.95 value: 245.1 } " + "} " - + "" + "timestamp_ms: 1672850585820 " + "}"; // @formatter:on @@ -741,24 +713,20 @@ public void testSummaryComplete() throws IOException { @Test public void testSummaryWithoutQuantiles() throws IOException { String openMetricsText = - "" - + "# TYPE latency_seconds summary\n" + "# TYPE latency_seconds summary\n" + "# UNIT latency_seconds seconds\n" + "# HELP latency_seconds latency\n" + "latency_seconds_count 3\n" + "latency_seconds_sum 1.2\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP latency_seconds latency\n" + "# HELP latency_seconds latency\n" + "# TYPE latency_seconds summary\n" + "latency_seconds_count 3\n" + "latency_seconds_sum 1.2\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "help: \"latency\" " + "type: SUMMARY " + "metric { " @@ -785,17 +753,14 @@ public void testSummaryWithoutQuantiles() throws IOException { @Test public void testSummaryNoCountAndSum() throws IOException { String openMetricsText = - "" - + "# TYPE latency_seconds summary\n" + "# TYPE latency_seconds summary\n" + "latency_seconds{quantile=\"0.95\"} 200.0\n" + "# EOF\n"; String prometheusText = - "" + "# TYPE latency_seconds summary\n" + "latency_seconds{quantile=\"0.95\"} 200.0\n"; + "# TYPE latency_seconds summary\n" + "latency_seconds{quantile=\"0.95\"} 200.0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "type: SUMMARY " + "metric { " + "summary { " @@ -821,13 +786,11 @@ public void testSummaryNoCountAndSum() throws IOException { @Test public void testSummaryJustCount() throws IOException { String openMetricsText = - "" + "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n" + "# EOF\n"; - String prometheusText = "" + "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n"; + "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n" + "# EOF\n"; + String prometheusText = "# TYPE latency_seconds summary\n" + "latency_seconds_count 1\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "type: SUMMARY " + "metric { " + "summary { " @@ -850,13 +813,11 @@ public void testSummaryJustCount() throws IOException { @Test public void testSummaryJustSum() throws IOException { String openMetricsText = - "" + "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n" + "# EOF\n"; - String prometheusText = "" + "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n"; + "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n" + "# EOF\n"; + String prometheusText = "# TYPE latency_seconds summary\n" + "latency_seconds_sum 12.3\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "type: SUMMARY " + "metric { " + "summary { " @@ -897,21 +858,17 @@ public void testSummaryEmptyData() throws IOException { @Test public void testSummaryEmptyAndNonEmpty() throws IOException { String openMetricsText = - "" - + "# TYPE latency_seconds summary\n" + "# TYPE latency_seconds summary\n" + "latency_seconds_count{path=\"/v2\"} 2\n" + "latency_seconds_sum{path=\"/v2\"} 10.7\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE latency_seconds summary\n" + "# TYPE latency_seconds summary\n" + "latency_seconds_count{path=\"/v2\"} 2\n" + "latency_seconds_sum{path=\"/v2\"} 10.7\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "type: SUMMARY " + "metric { " + "label { name: \"path\" value: \"/v2\" } " @@ -943,16 +900,14 @@ public void testSummaryEmptyAndNonEmpty() throws IOException { @Test public void testSummaryWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_request_duration_seconds summary\n" + "# TYPE my_request_duration_seconds summary\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE my_request_duration_seconds summary\n" + "# TYPE my_request_duration_seconds summary\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 1 # " @@ -961,16 +916,13 @@ public void testSummaryWithDots() throws IOException { + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# TYPE my_request_duration_seconds summary\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 1\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.03\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_request_duration_seconds\" " + // @formatter:off + "name: \"my_request_duration_seconds\" " + "help: \"Request duration in seconds\" " + "type: SUMMARY " + "metric { " @@ -1002,8 +954,7 @@ public void testSummaryWithDots() throws IOException { @Test public void testClassicHistogramComplete() throws Exception { String openMetricsText = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " @@ -1053,8 +1004,7 @@ public void testClassicHistogramComplete() throws Exception { + "\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " @@ -1108,8 +1058,7 @@ public void testClassicHistogramComplete() throws Exception { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP response_size_bytes help\n" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s @@ -1151,8 +1100,7 @@ public void testClassicHistogramComplete() throws Exception { + scrapeTimestamp2s + "\n"; String openMetricsTextWithoutCreated = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " @@ -1192,8 +1140,7 @@ public void testClassicHistogramComplete() throws Exception { + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = - "" - + "# HELP response_size_bytes help\n" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + "response_size_bytes_bucket{status=\"200\",le=\"2.2\"} 2 " + scrapeTimestamp1s @@ -1223,10 +1170,8 @@ public void testClassicHistogramComplete() throws Exception { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"response_size_bytes\" " + // @formatter:off + "name: \"response_size_bytes\" " + "help: \"help\" " + "type: HISTOGRAM " + "metric { " @@ -1317,20 +1262,16 @@ public void testClassicHistogramMinimal() throws Exception { // In OpenMetrics a histogram can have a _count if and only if it has a _sum. // In Prometheus format, a histogram can have a _count without a _sum. String openMetricsText = - "" - + "# TYPE request_latency_seconds histogram\n" + "# TYPE request_latency_seconds histogram\n" + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE request_latency_seconds histogram\n" + "# TYPE request_latency_seconds histogram\n" + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + "request_latency_seconds_count 2\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"request_latency_seconds\" " + // @formatter:off + "name: \"request_latency_seconds\" " + "type: HISTOGRAM " + "metric { " + "histogram { " @@ -1363,23 +1304,19 @@ public void testClassicHistogramMinimal() throws Exception { @Test public void testClassicHistogramCountAndSum() throws Exception { String openMetricsText = - "" - + "# TYPE request_latency_seconds histogram\n" + "# TYPE request_latency_seconds histogram\n" + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + "request_latency_seconds_count 2\n" + "request_latency_seconds_sum 3.2\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE request_latency_seconds histogram\n" + "# TYPE request_latency_seconds histogram\n" + "request_latency_seconds_bucket{le=\"+Inf\"} 2\n" + "request_latency_seconds_count 2\n" + "request_latency_seconds_sum 3.2\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"request_latency_seconds\" " + // @formatter:off + "name: \"request_latency_seconds\" " + "type: HISTOGRAM " + "metric { " + "histogram { " @@ -1414,8 +1351,7 @@ public void testClassicHistogramCountAndSum() throws Exception { @Test public void testClassicGaugeHistogramComplete() throws IOException { String openMetricsText = - "" - + "# TYPE cache_size_bytes gaugehistogram\n" + "# TYPE cache_size_bytes gaugehistogram\n" + "# UNIT cache_size_bytes bytes\n" + "# HELP cache_size_bytes number of bytes in the cache\n" + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " @@ -1462,8 +1398,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE cache_size_bytes gaugehistogram\n" + "# TYPE cache_size_bytes gaugehistogram\n" + "# UNIT cache_size_bytes bytes\n" + "# HELP cache_size_bytes number of bytes in the cache\n" + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " @@ -1514,8 +1449,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP cache_size_bytes number of bytes in the cache\n" + "# HELP cache_size_bytes number of bytes in the cache\n" + "# TYPE cache_size_bytes histogram\n" + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s @@ -1558,8 +1492,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { + scrapeTimestamp2s + "\n"; String openMetricsTextWithoutCreated = - "" - + "# TYPE cache_size_bytes gaugehistogram\n" + "# TYPE cache_size_bytes gaugehistogram\n" + "# UNIT cache_size_bytes bytes\n" + "# HELP cache_size_bytes number of bytes in the cache\n" + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " @@ -1596,8 +1529,7 @@ public void testClassicGaugeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = - "" - + "# HELP cache_size_bytes number of bytes in the cache\n" + "# HELP cache_size_bytes number of bytes in the cache\n" + "# TYPE cache_size_bytes histogram\n" + "cache_size_bytes_bucket{db=\"items\",le=\"2.0\"} 3 " + scrapeTimestamp1s @@ -1628,10 +1560,8 @@ public void testClassicGaugeHistogramComplete() throws IOException { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"cache_size_bytes\" " + // @formatter:off + "name: \"cache_size_bytes\" " + "help: \"number of bytes in the cache\" " + "type: GAUGE_HISTOGRAM " + "metric { " @@ -1719,21 +1649,17 @@ public void testClassicGaugeHistogramMinimal() throws IOException { // In OpenMetrics a histogram can have a _count if and only if it has a _sum. // In Prometheus format, a histogram can have a _count without a _sum. String openMetricsText = - "" - + "# TYPE queue_size_bytes gaugehistogram\n" + "# TYPE queue_size_bytes gaugehistogram\n" + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE queue_size_bytes histogram\n" + "# TYPE queue_size_bytes histogram\n" + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + "# TYPE queue_size_bytes_gcount gauge\n" + "queue_size_bytes_gcount 130\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"queue_size_bytes\" " + // @formatter:off + "name: \"queue_size_bytes\" " + "type: GAUGE_HISTOGRAM " + "metric { " + "histogram { " @@ -1767,25 +1693,21 @@ public void testClassicGaugeHistogramMinimal() throws IOException { @Test public void testClassicGaugeHistogramCountAndSum() throws IOException { String openMetricsText = - "" - + "# TYPE queue_size_bytes gaugehistogram\n" + "# TYPE queue_size_bytes gaugehistogram\n" + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + "queue_size_bytes_gcount 130\n" + "queue_size_bytes_gsum 27000.0\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE queue_size_bytes histogram\n" + "# TYPE queue_size_bytes histogram\n" + "queue_size_bytes_bucket{le=\"+Inf\"} 130\n" + "# TYPE queue_size_bytes_gcount gauge\n" + "queue_size_bytes_gcount 130\n" + "# TYPE queue_size_bytes_gsum gauge\n" + "queue_size_bytes_gsum 27000.0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"queue_size_bytes\" " + // @formatter:off + "name: \"queue_size_bytes\" " + "type: GAUGE_HISTOGRAM " + "metric { " + "histogram { " @@ -1821,8 +1743,7 @@ public void testClassicGaugeHistogramCountAndSum() throws IOException { @Test public void testClassicHistogramWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_request_duration_seconds histogram\n" + "# TYPE my_request_duration_seconds histogram\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " @@ -1832,8 +1753,7 @@ public void testClassicHistogramWithDots() throws IOException { + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE my_request_duration_seconds histogram\n" + "# TYPE my_request_duration_seconds histogram\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130 # " @@ -1845,17 +1765,14 @@ public void testClassicHistogramWithDots() throws IOException { + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# TYPE my_request_duration_seconds histogram\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 130\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 130\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 0.01\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_request_duration_seconds\" " + // @formatter:off + "name: \"my_request_duration_seconds\" " + "help: \"Request duration in seconds\" " + "type: HISTOGRAM " + "metric { " @@ -1896,8 +1813,7 @@ public void testClassicHistogramWithDots() throws IOException { @Test public void testNativeHistogramComplete() throws IOException { String openMetricsText = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " @@ -1934,8 +1850,7 @@ public void testNativeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " @@ -1976,8 +1891,7 @@ public void testNativeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP response_size_bytes help\n" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s @@ -2010,8 +1924,7 @@ public void testNativeHistogramComplete() throws IOException { + scrapeTimestamp2s + "\n"; String openMetricsTextWithoutCreated = - "" - + "# TYPE response_size_bytes histogram\n" + "# TYPE response_size_bytes histogram\n" + "# UNIT response_size_bytes bytes\n" + "# HELP response_size_bytes help\n" + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " @@ -2038,8 +1951,7 @@ public void testNativeHistogramComplete() throws IOException { + "\n" + "# EOF\n"; String prometheusTextWithoutCreated = - "" - + "# HELP response_size_bytes help\n" + "# HELP response_size_bytes help\n" + "# TYPE response_size_bytes histogram\n" + "response_size_bytes_bucket{status=\"200\",le=\"+Inf\"} 2 " + scrapeTimestamp1s @@ -2060,10 +1972,8 @@ public void testNativeHistogramComplete() throws IOException { + scrapeTimestamp2s + "\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"response_size_bytes\" " + // @formatter:off + "name: \"response_size_bytes\" " + "help: \"help\" " + "type: HISTOGRAM " + "metric { " @@ -2214,20 +2124,16 @@ public void testNativeHistogramComplete() throws IOException { @Test public void testNativeHistogramMinimal() throws IOException { String openMetricsText = - "" - + "# TYPE latency_seconds histogram\n" + "# TYPE latency_seconds histogram\n" + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + "# EOF\n"; String prometheusText = - "" - + "# TYPE latency_seconds histogram\n" + "# TYPE latency_seconds histogram\n" + "latency_seconds_bucket{le=\"+Inf\"} 0\n" + "latency_seconds_count 0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"latency_seconds\" " + // @formatter:off + "name: \"latency_seconds\" " + "type: HISTOGRAM " + "metric { " + "histogram { " @@ -2252,8 +2158,7 @@ public void testNativeHistogramMinimal() throws IOException { @Test public void testNativeHistogramWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_request_duration_seconds histogram\n" + "# TYPE my_request_duration_seconds histogram\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " @@ -2263,8 +2168,7 @@ public void testNativeHistogramWithDots() throws IOException { + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + "# EOF\n"; String openMetricsTextWithExemplarsOnAllTimeSeries = - "" - + "# TYPE my_request_duration_seconds histogram\n" + "# TYPE my_request_duration_seconds histogram\n" + "# UNIT my_request_duration_seconds seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4 # " @@ -2276,17 +2180,14 @@ public void testNativeHistogramWithDots() throws IOException { + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# HELP my_request_duration_seconds Request duration in seconds\n" + "# TYPE my_request_duration_seconds histogram\n" + "my_request_duration_seconds_bucket{http_path=\"/hello\",le=\"+Inf\"} 4\n" + "my_request_duration_seconds_count{http_path=\"/hello\"} 4\n" + "my_request_duration_seconds_sum{http_path=\"/hello\"} 3.2\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_request_duration_seconds\" " + // @formatter:off + "name: \"my_request_duration_seconds\" " + "help: \"Request duration in seconds\" " + "type: HISTOGRAM " + "metric { " @@ -2334,14 +2235,12 @@ public void testNativeHistogramWithDots() throws IOException { @Test public void testInfo() throws IOException { String openMetrics = - "" - + "# TYPE version info\n" + "# TYPE version info\n" + "# HELP version version information\n" + "version_info{version=\"1.2.3\"} 1\n" + "# EOF\n"; String prometheus = - "" - + "# HELP version_info version information\n" + "# HELP version_info version information\n" + "# TYPE version_info gauge\n" + "version_info{version=\"1.2.3\"} 1\n"; InfoSnapshot info = @@ -2362,25 +2261,20 @@ public void testInfo() throws IOException { @Test public void testInfoWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE jvm_status info\n" + "# TYPE jvm_status info\n" + "# HELP jvm_status JVM status info\n" + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP jvm_status_info JVM status info\n" + "# HELP jvm_status_info JVM status info\n" + "# TYPE jvm_status_info gauge\n" + "jvm_status_info{jvm_version=\"1.2.3\"} 1\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"jvm_status_info\" " + // @formatter:off + "name: \"jvm_status_info\" " + "help: \"JVM status info\" " + "type: GAUGE " + "metric { " - + "" + "label { name: \"jvm_version\" value: \"1.2.3\" } " + "gauge { value: 1.0 } " + "}"; @@ -2402,8 +2296,7 @@ public void testInfoWithDots() throws IOException { @Test public void testStateSetComplete() throws IOException { String openMetrics = - "" - + "# TYPE state stateset\n" + "# TYPE state stateset\n" + "# HELP state complete state set example\n" + "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s @@ -2419,8 +2312,7 @@ public void testStateSetComplete() throws IOException { + "\n" + "# EOF\n"; String prometheus = - "" - + "# HELP state complete state set example\n" + "# HELP state complete state set example\n" + "# TYPE state gauge\n" + "state{env=\"dev\",state=\"state1\"} 1 " + scrapeTimestamp1s @@ -2462,13 +2354,12 @@ public void testStateSetComplete() throws IOException { @Test public void testStateSetMinimal() throws IOException { String openMetrics = - "" - + "# TYPE state stateset\n" + "# TYPE state stateset\n" + "state{state=\"a\"} 1\n" + "state{state=\"bb\"} 0\n" + "# EOF\n"; String prometheus = - "" + "# TYPE state gauge\n" + "state{state=\"a\"} 1\n" + "state{state=\"bb\"} 0\n"; + "# TYPE state gauge\n" + "state{state=\"a\"} 1\n" + "state{state=\"bb\"} 0\n"; StateSetSnapshot stateSet = StateSetSnapshot.builder() .name("state") @@ -2487,23 +2378,19 @@ public void testStateSetMinimal() throws IOException { @Test public void testStateSetWithDots() throws IOException { String openMetricsText = - "" - + "# TYPE my_application_state stateset\n" + "# TYPE my_application_state stateset\n" + "# HELP my_application_state My application state\n" + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n" + "# EOF\n"; String prometheusText = - "" - + "# HELP my_application_state My application state\n" + "# HELP my_application_state My application state\n" + "# TYPE my_application_state gauge\n" + "my_application_state{data_center=\"us east\",my_application_state=\"feature.enabled\"} 1\n" + "my_application_state{data_center=\"us east\",my_application_state=\"is.alpha.version\"} 0\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"my_application_state\" " + // @formatter:off + "name: \"my_application_state\" " + "help: \"My application state\" " + "type: GAUGE " + "metric { " @@ -2535,8 +2422,7 @@ public void testStateSetWithDots() throws IOException { @Test public void testUnknownComplete() throws IOException { String openMetrics = - "" - + "# TYPE my_special_thing_bytes unknown\n" + "# TYPE my_special_thing_bytes unknown\n" + "# UNIT my_special_thing_bytes bytes\n" + "# HELP my_special_thing_bytes help message\n" + "my_special_thing_bytes{env=\"dev\"} 0.2 " @@ -2547,8 +2433,7 @@ public void testUnknownComplete() throws IOException { + "\n" + "# EOF\n"; String openMetricsWithExemplarsOnAllTimeSeries = - "" - + "# TYPE my_special_thing_bytes unknown\n" + "# TYPE my_special_thing_bytes unknown\n" + "# UNIT my_special_thing_bytes bytes\n" + "# HELP my_special_thing_bytes help message\n" + "my_special_thing_bytes{env=\"dev\"} 0.2 " @@ -2563,8 +2448,7 @@ public void testUnknownComplete() throws IOException { + "\n" + "# EOF\n"; String prometheus = - "" - + "# HELP my_special_thing_bytes help message\n" + "# HELP my_special_thing_bytes help message\n" + "# TYPE my_special_thing_bytes untyped\n" + "my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s @@ -2602,8 +2486,8 @@ public void testUnknownComplete() throws IOException { @Test public void testUnknownMinimal() throws IOException { - String openMetrics = "" + "# TYPE other unknown\n" + "other 22.3\n" + "# EOF\n"; - String prometheus = "" + "# TYPE other untyped\n" + "other 22.3\n"; + String openMetrics = "# TYPE other unknown\n" + "other 22.3\n" + "# EOF\n"; + String prometheus = "# TYPE other untyped\n" + "other 22.3\n"; UnknownSnapshot unknown = UnknownSnapshot.builder() .name("other") @@ -2618,15 +2502,13 @@ public void testUnknownMinimal() throws IOException { @Test public void testUnknownWithDots() throws IOException { String openMetrics = - "" - + "# TYPE some_unknown_metric_bytes unknown\n" + "# TYPE some_unknown_metric_bytes unknown\n" + "# UNIT some_unknown_metric_bytes bytes\n" + "# HELP some_unknown_metric_bytes help message\n" + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n" + "# EOF\n"; String openMetricsWithExemplarsOnAllTimeSeries = - "" - + "# TYPE some_unknown_metric_bytes unknown\n" + "# TYPE some_unknown_metric_bytes unknown\n" + "# UNIT some_unknown_metric_bytes bytes\n" + "# HELP some_unknown_metric_bytes help message\n" + "some_unknown_metric_bytes{test_env=\"7\"} 0.7 # " @@ -2634,15 +2516,12 @@ public void testUnknownWithDots() throws IOException { + "\n" + "# EOF\n"; String prometheus = - "" - + "# HELP some_unknown_metric_bytes help message\n" + "# HELP some_unknown_metric_bytes help message\n" + "# TYPE some_unknown_metric_bytes untyped\n" + "some_unknown_metric_bytes{test_env=\"7\"} 0.7\n"; String prometheusProtobuf = - "" - + - // @formatter:off - "name: \"some_unknown_metric_bytes\" " + // @formatter:off + "name: \"some_unknown_metric_bytes\" " + "help: \"help message\" " + "type: UNTYPED " + "metric { " @@ -2672,14 +2551,12 @@ public void testUnknownWithDots() throws IOException { @Test public void testHelpEscape() throws IOException { String openMetrics = - "" - + "# TYPE test counter\n" + "# TYPE test counter\n" + "# HELP test Some text and \\n some \\\" escaping\n" + "test_total 1.0\n" + "# EOF\n"; String prometheus = - "" - + "# HELP test_total Some text and \\n some \" escaping\n" + "# HELP test_total Some text and \\n some \" escaping\n" + "# TYPE test_total counter\n" + "test_total 1.0\n"; CounterSnapshot counter = @@ -2697,14 +2574,11 @@ public void testHelpEscape() throws IOException { @Test public void testLabelValueEscape() throws IOException { String openMetrics = - "" - + "# TYPE test counter\n" + "# TYPE test counter\n" + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n" + "# EOF\n"; String prometheus = - "" - + "# TYPE test_total counter\n" - + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; + "# TYPE test_total counter\n" + "test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n"; CounterSnapshot counter = CounterSnapshot.builder() .name("test") @@ -2723,7 +2597,7 @@ private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) thr ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); + assertThat(out).hasToString(expected); } private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( @@ -2731,7 +2605,7 @@ private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); + assertThat(out).hasToString(expected); } private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) @@ -2739,14 +2613,14 @@ private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); + assertThat(out).hasToString(expected); } private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); + assertThat(out).hasToString(expected); } private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) @@ -2754,13 +2628,13 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot ByteArrayOutputStream out = new ByteArrayOutputStream(); PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); writer.write(out, MetricSnapshots.of(snapshot)); - Assert.assertEquals(expected, out.toString()); + assertThat(out).hasToString(expected); } private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); Metrics.MetricFamily protobufData = writer.convert(snapshot); String actual = TextFormat.printer().shortDebugString(protobufData); - Assert.assertEquals(expected, actual); + assertThat(actual).isEqualTo(expected); } } diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index a1b560251..a12f26918 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -54,28 +54,8 @@ 3.1.8 provided - - - - junit - junit - 4.13.2 - test - - - - org.mockito - mockito-core - 5.12.0 - test - - - org.assertj - assertj-core - 3.26.3 - test - + io.prometheus prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java index acbfe3e1e..f74d5d041 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.caffeine; -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -20,26 +20,15 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; -import java.util.concurrent.Executor; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class CacheMetricsCollectorTest { +class CacheMetricsCollectorTest { @Test public void cacheExposesMetricsForHitMissAndEviction() { + // Run cleanup in same thread, to remove async behavior with evictions final Cache cache = - Caffeine.newBuilder() - .maximumSize(2) - .recordStats() - .executor( - new Executor() { - @Override - public void execute(Runnable command) { - // Run cleanup in same thread, to remove async behavior with evictions - command.run(); - } - }) - .build(); + Caffeine.newBuilder().maximumSize(2).recordStats().executor(Runnable::run).build(); final CacheMetricsCollector collector = new CacheMetricsCollector(); collector.addCache("users", cache); @@ -83,7 +72,7 @@ public void execute(Runnable command) { + "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(registry)); + assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected); } @SuppressWarnings("unchecked") @@ -122,7 +111,7 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot(registry, "caffeine_cache_load_duration_seconds", "loadingusers"); - assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getCount()).isEqualTo(3); assertThat(loadDuration.getSum()).isGreaterThan(0); } @@ -131,7 +120,7 @@ private void assertCounterMetric( final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); - assertEquals(value, dataPointSnapshot.getValue(), 0); + assertThat(dataPointSnapshot.getValue()).isCloseTo(value, offset(0.0)); } private DataPointSnapshot getDataPointSnapshot( diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 085e6de74..8de53d0f0 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -54,26 +54,7 @@ 5.0.0 provided - - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.25.3 - test - - - org.mockito - mockito-core - 5.12.0 - test - - + io.prometheus prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java index 0473329ce..11402fa7e 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExportsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.dropwizard5; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import io.dropwizard.metrics5.*; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; @@ -13,16 +13,15 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class DropwizardExportsTest { +class DropwizardExportsTest { private PrometheusRegistry registry = new PrometheusRegistry(); private MetricRegistry metricRegistry; - @Before + @BeforeEach public void setUp() { metricRegistry = new MetricRegistry(); DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(registry); @@ -37,11 +36,12 @@ public void testCounter() { + "foo_bar_total 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } @Test public void testGauge() { + // don't convert to lambda, as we need to test the type Gauge integerGauge = new Gauge() { @Override @@ -102,41 +102,29 @@ public Boolean getValue() { + "long_gauge 1234.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } @Test public void testInvalidGaugeType() { - Gauge invalidGauge = - new Gauge() { - @Override - public String getValue() { - return "foobar"; - } - }; + Gauge invalidGauge = () -> "foobar"; metricRegistry.register("invalid_gauge", invalidGauge); String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } @Test public void testGaugeReturningNullValue() { - Gauge invalidGauge = - new Gauge() { - @Override - public String getValue() { - return null; - } - }; + Gauge invalidGauge = () -> null; metricRegistry.register("invalid_gauge", invalidGauge); String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } @Test - public void testHistogram() throws IOException { + public void testHistogram() { // just test the standard mapper final MetricRegistry metricRegistry = new MetricRegistry(); PrometheusRegistry pmRegistry = new PrometheusRegistry(); @@ -181,31 +169,31 @@ public void testHistogram() throws IOException { // The following asserts the values, but allows an error of 1.0 for quantile values. MetricSnapshots snapshots = pmRegistry.scrape(name -> name.equals("hist")); - Assert.assertEquals(1, snapshots.size()); + assertThat(snapshots.size()).isOne(); SummarySnapshot snapshot = (SummarySnapshot) snapshots.get(0); - Assert.assertEquals("hist", snapshot.getMetadata().getName()); - Assert.assertEquals( - "Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)", - snapshot.getMetadata().getHelp()); - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getMetadata().getName()).isEqualTo("hist"); + assertThat(snapshot.getMetadata().getHelp()) + .isEqualTo( + "Generated from Dropwizard metric import (metric=hist, type=io.dropwizard.metrics5.Histogram)"); + assertThat(snapshot.getDataPoints().size()).isOne(); SummarySnapshot.SummaryDataPointSnapshot dataPoint = snapshot.getDataPoints().get(0); - Assert.assertTrue(dataPoint.hasCount()); - Assert.assertEquals(100, dataPoint.getCount()); - Assert.assertFalse(dataPoint.hasSum()); + assertThat(dataPoint.hasCount()).isTrue(); + assertThat(dataPoint.getCount()).isEqualTo(100); + assertThat(dataPoint.hasSum()).isFalse(); Quantiles quantiles = dataPoint.getQuantiles(); - Assert.assertEquals(6, quantiles.size()); - Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0.0); - Assert.assertEquals(49.0, quantiles.get(0).getValue(), 1.0); - Assert.assertEquals(0.75, quantiles.get(1).getQuantile(), 0.0); - Assert.assertEquals(74.0, quantiles.get(1).getValue(), 1.0); - Assert.assertEquals(0.95, quantiles.get(2).getQuantile(), 0.0); - Assert.assertEquals(94.0, quantiles.get(2).getValue(), 1.0); - Assert.assertEquals(0.98, quantiles.get(3).getQuantile(), 0.0); - Assert.assertEquals(97.0, quantiles.get(3).getValue(), 1.0); - Assert.assertEquals(0.99, quantiles.get(4).getQuantile(), 0.0); - Assert.assertEquals(98.0, quantiles.get(4).getValue(), 1.0); - Assert.assertEquals(0.999, quantiles.get(5).getQuantile(), 0.0); - Assert.assertEquals(99.0, quantiles.get(5).getValue(), 1.0); + assertThat(quantiles.size()).isEqualTo(6); + assertThat(quantiles.get(0).getQuantile()).isCloseTo(0.5, offset(0.0)); + assertThat(quantiles.get(0).getValue()).isCloseTo(49.0, offset(1.0)); + assertThat(quantiles.get(1).getQuantile()).isCloseTo(0.75, offset(0.0)); + assertThat(quantiles.get(1).getValue()).isCloseTo(74.0, offset(1.0)); + assertThat(quantiles.get(2).getQuantile()).isCloseTo(0.95, offset(0.0)); + assertThat(quantiles.get(2).getValue()).isCloseTo(94.0, offset(1.0)); + assertThat(quantiles.get(3).getQuantile()).isCloseTo(0.98, offset(0.0)); + assertThat(quantiles.get(3).getValue()).isCloseTo(97.0, offset(1.0)); + assertThat(quantiles.get(4).getQuantile()).isCloseTo(0.99, offset(0.0)); + assertThat(quantiles.get(4).getValue()).isCloseTo(98.0, offset(1.0)); + assertThat(quantiles.get(5).getQuantile()).isCloseTo(0.999, offset(0.0)); + assertThat(quantiles.get(5).getValue()).isCloseTo(99.0, offset(1.0)); } @Test @@ -219,7 +207,7 @@ public void testMeter() { + "# HELP meter Generated from Dropwizard metric import (metric=meter_total, type=io.dropwizard.metrics5.Meter)\n" + "meter_total 2.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } @Test @@ -237,15 +225,15 @@ public void testTimer() throws InterruptedException { (SummarySnapshot.SummaryDataPointSnapshot) exports.collect().stream().flatMap(i -> i.getDataPoints().stream()).findFirst().get(); // We slept for 1Ms so we ensure that all timers are above 1ms: - assertTrue(dataPointSnapshot.getQuantiles().size() > 1); + assertThat(dataPointSnapshot.getQuantiles().size()).isGreaterThan(1); dataPointSnapshot .getQuantiles() .forEach( i -> { System.out.println(i.getQuantile() + " : " + i.getValue()); - assertTrue(i.getValue() > timeSpentMillis / 1000d); + assertThat(i.getValue()).isGreaterThan(timeSpentMillis / 1000d); }); - assertEquals(1, dataPointSnapshot.getCount()); + assertThat(dataPointSnapshot.getCount()).isOne(); } @Test @@ -286,7 +274,7 @@ public void testThatMetricHelpUsesOriginalDropwizardName() { + "my_application_namedTimer1{quantile=\"0.999\"} 0.0\n" + "my_application_namedTimer1_count 0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat()); + assertThat(convertToOpenMetricsFormat()).isEqualTo(expected); } private static class ExampleDoubleGauge implements Gauge { diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java index 5d1950111..ac0b0a328 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/CustomLabelMapperTest.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.dropwizard.metrics5.MetricFilter; import io.dropwizard.metrics5.MetricRegistry; @@ -11,21 +12,21 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class CustomLabelMapperTest { +class CustomLabelMapperTest { private MetricRegistry metricRegistry; - @Before + @BeforeEach public void setUp() { metricRegistry = new MetricRegistry(); } - @Test(expected = IllegalArgumentException.class) + @Test public void test_WHEN_EmptyConfig_THEN_Fail() { - final CustomLabelMapper converter = - new CustomLabelMapper(Collections.emptyList()); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new CustomLabelMapper(Collections.emptyList())); } @Test @@ -48,7 +49,7 @@ public void test_WHEN_NoMatches_THEN_ShouldReturnDefaultSample() { + "app_okhttpclient_client_HttpClient_service_total 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } @Test @@ -76,12 +77,12 @@ public void test_WHEN_OneMatch_THEN_ShouldReturnConverted() { + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } @Test public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() { - final Map labels = new HashMap(); + final Map labels = new HashMap<>(); labels.put("service", "${0}"); final MapperConfig mapperConfig = new MapperConfig( @@ -105,12 +106,12 @@ public void test_WHEN_MoreMatches_THEN_ShouldReturnFirstOne() { + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.total, type=io.dropwizard.metrics5.Counter)\n" + "app_okhttpclient_client_HttpClient_total{service=\"greatService\"} 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } @Test public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { - final Map labels = new LinkedHashMap(); + final Map labels = new LinkedHashMap<>(); labels.put("service", "${0}"); labels.put("status", "${1}"); final MapperConfig mapperConfig = @@ -140,12 +141,12 @@ public void test_WHEN_MoreMatchesReverseOrder_THEN_ShouldReturnFirstOne() { + "# HELP app_okhttpclient_client_HttpClient Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + "app_okhttpclient_client_HttpClient_total{service=\"greatService\",status=\"400\"} 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } @Test public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample() { - final Map labels = new LinkedHashMap(); + final Map labels = new LinkedHashMap<>(); labels.put("service", "${0}_${1}"); labels.put("status", "s_${1}"); final MapperConfig mapperConfig = @@ -171,12 +172,12 @@ public void test_WHEN_MoreToFormatInLabelsAndName_THEN_ShouldReturnCorrectSample + "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + "app_okhttpclient_client_HttpClient_greatService_total{service=\"greatService_400\",status=\"s_400\"} 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } @Test public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() { - final Map labels = new LinkedHashMap(); + final Map labels = new LinkedHashMap<>(); labels.put("service", "${0}"); labels.put("status", "s_${1}"); labels.put("client", "sampleClient"); @@ -198,7 +199,7 @@ public void test_WHEN_AdditionalLabels_THEN_ShouldReturnCorrectSample() { + "# HELP app_okhttpclient_client_HttpClient_greatService Generated from Dropwizard metric import (metric=app.okhttpclient.client.HttpClient.greatService.400, type=io.dropwizard.metrics5.Counter)\n" + "app_okhttpclient_client_HttpClient_greatService_total{client=\"sampleClient\",service=\"greatService\",status=\"s_400\"} 1.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(dropwizardExports.collect())); + assertThat(convertToOpenMetricsFormat(dropwizardExports.collect())).isEqualTo(expected); } private String convertToOpenMetricsFormat(MetricSnapshots snapshots) { diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java index 9e8316d0b..ed27d7f22 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/GraphiteNamePatternTest.java @@ -1,18 +1,20 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.assertj.core.api.Assertions; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class GraphiteNamePatternTest { +class GraphiteNamePatternTest { - @Test(expected = IllegalArgumentException.class) + @Test public void createNew_WHEN_InvalidPattern_THEN_ShouldThrowException() { - final List invalidPatterns = + List invalidPatterns = Arrays.asList( "", "a", @@ -29,15 +31,10 @@ public void createNew_WHEN_InvalidPattern_THEN_ShouldThrowException() { "org.com*pany.*", "org.test.contr.oller.gather.status..400", "org.test.controller.gather.status..400"); - final GraphiteNamePattern graphiteNamePattern = new GraphiteNamePattern(""); for (String pattern : invalidPatterns) { - try { - new GraphiteNamePattern(pattern); - - Assertions.failBecauseExceptionWasNotThrown(IllegalArgumentException.class); - } catch (IllegalArgumentException e) { - Assertions.assertThat(e).hasMessageContaining(pattern); - } + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new GraphiteNamePattern(pattern)) + .withMessageContaining(pattern); } } diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java index 7bf7b6520..a17963e0d 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/test/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfigTest.java @@ -1,48 +1,50 @@ package io.prometheus.metrics.instrumentation.dropwizard5.labels; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class MapperConfigTest { +class MapperConfigTest { @Test public void setMatch_WHEN_ExpressionMatchesPattern_AllGood() { final MapperConfig mapperConfig = new MapperConfig(); mapperConfig.setMatch("com.company.meter.*"); - assertEquals("com.company.meter.*", mapperConfig.getMatch()); + assertThat(mapperConfig.getMatch()).isEqualTo("com.company.meter.*"); } - @Test(expected = IllegalArgumentException.class) + @Test public void setMatch_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { - final MapperConfig mapperConfig = new MapperConfig(); - mapperConfig.setMatch("com.company.meter.**.yay"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MapperConfig().setMatch("com.company.meter.**.yay")); } @Test public void setLabels_WHEN_ExpressionMatchesPattern_AllGood() { final MapperConfig mapperConfig = new MapperConfig(); - final Map labels = new HashMap(); + final Map labels = new HashMap<>(); labels.put("valid", "${0}"); mapperConfig.setLabels(labels); - assertEquals(labels, mapperConfig.getLabels()); + assertThat(mapperConfig.getLabels()).isEqualTo(labels); } - @Test(expected = IllegalArgumentException.class) + @Test public void setLabels_WHEN_ExpressionDoesnNotMatchPattern_ThrowException() { final MapperConfig mapperConfig = new MapperConfig(); - final Map labels = new HashMap(); + final Map labels = new HashMap<>(); labels.put("valid", "${0}"); labels.put("not valid", "${0}"); - mapperConfig.setLabels(labels); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> mapperConfig.setLabels(labels)); } @Test public void toString_WHEN_EmptyConfig_AllGood() { final MapperConfig mapperConfig = new MapperConfig(); - assertEquals("MapperConfig{match=null, name=null, labels={}}", mapperConfig.toString()); + assertThat(mapperConfig).hasToString("MapperConfig{match=null, name=null, labels={}}"); } @Test @@ -51,8 +53,7 @@ public void toString_WHEN_FullyConfigured_AllGood() { mapperConfig.setMatch("com.company.meter.*.foo"); mapperConfig.setName("foo"); mapperConfig.setLabels(Collections.singletonMap("type", "${0}")); - assertEquals( - "MapperConfig{match=com.company.meter.*.foo, name=foo, labels={type=${0}}}", - mapperConfig.toString()); + assertThat(mapperConfig) + .hasToString("MapperConfig{match=com.company.meter.*.foo, name=foo, labels={type=${0}}}"); } } diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index a4103e051..a93bc7960 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -54,28 +54,6 @@ 33.2.1-jre provided - - - - junit - junit - 4.13.2 - test - - - - org.mockito - mockito-core - 5.12.0 - test - - - org.assertj - assertj-core - 3.26.3 - test - - io.prometheus prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java index 96de845a8..3931520ff 100644 --- a/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-guava/src/test/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollectorTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.guava; -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -20,9 +20,9 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class CacheMetricsCollectorTest { +class CacheMetricsCollectorTest { @Test public void cacheExposesMetricsForHitMissAndEviction() { @@ -68,7 +68,7 @@ public void cacheExposesMetricsForHitMissAndEviction() { + "guava_cache_size{cache=\"users\"} 2.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(registry)); + assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected); } @SuppressWarnings("unchecked") @@ -107,7 +107,7 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { (SummarySnapshot.SummaryDataPointSnapshot) getDataPointSnapshot(registry, "guava_cache_load_duration_seconds", "loadingusers"); - assertEquals(3, loadDuration.getCount()); + assertThat(loadDuration.getCount()).isEqualTo(3); assertThat(loadDuration.getSum()).isGreaterThan(0); } @@ -116,7 +116,7 @@ private void assertCounterMetric( final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = (CounterSnapshot.CounterDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); - assertEquals(value, dataPointSnapshot.getValue(), 0); + assertThat(dataPointSnapshot.getValue()).isCloseTo(value, offset(0.0)); } private DataPointSnapshot getDataPointSnapshot( diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index c847500db..c0a847509 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -49,18 +49,6 @@ - - junit - junit - 4.13.2 - test - - - org.mockito - mockito-core - 5.12.0 - test - io.prometheus prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java index b3d1c8169..0bea87baf 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ExampleExporterForManualTesting.java @@ -3,7 +3,7 @@ import io.prometheus.metrics.exporter.httpserver.HTTPServer; import java.io.IOException; -public class ExampleExporterForManualTesting { +class ExampleExporterForManualTesting { public static void main(String[] args) throws IOException, InterruptedException { diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java index cad2e8eb5..5d4523351 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -12,16 +12,16 @@ import java.io.IOException; import java.lang.management.BufferPoolMXBean; import java.util.Arrays; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmBufferPoolMetricsTest { +class JvmBufferPoolMetricsTest { private final BufferPoolMXBean directBuffer = Mockito.mock(BufferPoolMXBean.class); private final BufferPoolMXBean mappedBuffer = Mockito.mock(BufferPoolMXBean.class); - @Before + @BeforeEach public void setUp() { when(directBuffer.getName()).thenReturn("direct"); when(directBuffer.getCount()).thenReturn(2L); @@ -42,8 +42,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + "# TYPE jvm_buffer_pool_capacity_bytes gauge\n" + "# UNIT jvm_buffer_pool_capacity_bytes bytes\n" + "# HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool.\n" + "jvm_buffer_pool_capacity_bytes{pool=\"direct\"} 3456.0\n" @@ -59,7 +58,7 @@ public void testGoodCase() throws IOException { + "jvm_buffer_pool_used_bytes{pool=\"mapped\"} 2345.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java index 0d8d77b51..6070aebba 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -11,15 +11,15 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshots; import java.io.IOException; import java.lang.management.ClassLoadingMXBean; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmClassLoadingMetricsTest { +class JvmClassLoadingMetricsTest { private final ClassLoadingMXBean mockClassLoadingBean = Mockito.mock(ClassLoadingMXBean.class); - @Before + @BeforeEach public void setUp() { when(mockClassLoadingBean.getLoadedClassCount()).thenReturn(1000); when(mockClassLoadingBean.getTotalLoadedClassCount()).thenReturn(2000L); @@ -33,8 +33,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_classes_currently_loaded gauge\n" + "# TYPE jvm_classes_currently_loaded gauge\n" + "# HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM\n" + "jvm_classes_currently_loaded 1000.0\n" + "# TYPE jvm_classes_loaded counter\n" @@ -45,7 +44,7 @@ public void testGoodCase() throws IOException { + "jvm_classes_unloaded_total 500.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java index e966d0c11..caddb89ea 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.internal.verification.VerificationModeFactory.times; @@ -11,15 +11,15 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshots; import java.io.IOException; import java.lang.management.CompilationMXBean; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmCompilationMetricsTest { +class JvmCompilationMetricsTest { private final CompilationMXBean mockCompilationBean = Mockito.mock(CompilationMXBean.class); - @Before + @BeforeEach public void setUp() { when(mockCompilationBean.getTotalCompilationTime()).thenReturn(10000L); when(mockCompilationBean.isCompilationTimeMonitoringSupported()).thenReturn(true); @@ -32,14 +32,13 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_compilation_time_seconds counter\n" + "# TYPE jvm_compilation_time_seconds counter\n" + "# UNIT jvm_compilation_time_seconds seconds\n" + "# HELP jvm_compilation_time_seconds The total time in seconds taken for HotSpot class compilation\n" + "jvm_compilation_time_seconds_total 10.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -54,6 +53,6 @@ public void testIgnoredMetricNotScraped() { MetricSnapshots snapshots = registry.scrape(filter); verify(mockCompilationBean, times(0)).getTotalCompilationTime(); - assertEquals(0, snapshots.size()); + assertThat(snapshots.size()).isZero(); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java index 5bbf3a427..3a09b4ef0 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -13,16 +13,16 @@ import java.lang.management.GarbageCollectorMXBean; import java.util.Arrays; import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmGarbageCollectorMetricsTest { +class JvmGarbageCollectorMetricsTest { private final GarbageCollectorMXBean mockGcBean1 = Mockito.mock(GarbageCollectorMXBean.class); private final GarbageCollectorMXBean mockGcBean2 = Mockito.mock(GarbageCollectorMXBean.class); - @Before + @BeforeEach public void setUp() { when(mockGcBean1.getName()).thenReturn("MyGC1"); when(mockGcBean1.getCollectionCount()).thenReturn(100L); @@ -41,8 +41,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_gc_collection_seconds summary\n" + "# TYPE jvm_gc_collection_seconds summary\n" + "# UNIT jvm_gc_collection_seconds seconds\n" + "# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.\n" + "jvm_gc_collection_seconds_count{gc=\"MyGC1\"} 100\n" @@ -51,7 +50,7 @@ public void testGoodCase() throws IOException { + "jvm_gc_collection_seconds_sum{gc=\"MyGC2\"} 20.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -67,6 +66,6 @@ public void testIgnoredMetricNotScraped() { verify(mockGcBean1, times(0)).getCollectionTime(); verify(mockGcBean1, times(0)).getCollectionCount(); - assertEquals(0, snapshots.size()); + assertThat(snapshots.size()).isZero(); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java index 94bdbbee3..a10bb1b7b 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -14,11 +14,11 @@ import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryUsage; import java.util.Arrays; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmMemoryMetricsTest { +class JvmMemoryMetricsTest { private final MemoryMXBean mockMemoryBean = Mockito.mock(MemoryMXBean.class); private final MemoryPoolMXBean mockPoolsBeanEdenSpace = Mockito.mock(MemoryPoolMXBean.class); @@ -30,7 +30,7 @@ public class JvmMemoryMetricsTest { private final MemoryUsage memoryUsagePoolCollectionEdenSpace = Mockito.mock(MemoryUsage.class); private final MemoryUsage memoryUsagePoolCollectionOldGen = Mockito.mock(MemoryUsage.class); - @Before + @BeforeEach public void setUp() { when(mockMemoryBean.getHeapMemoryUsage()).thenReturn(memoryUsageHeap); when(mockMemoryBean.getNonHeapMemoryUsage()).thenReturn(memoryUsageNonHeap); @@ -88,8 +88,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_memory_committed_bytes gauge\n" + "# TYPE jvm_memory_committed_bytes gauge\n" + "# UNIT jvm_memory_committed_bytes bytes\n" + "# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.\n" + "jvm_memory_committed_bytes{area=\"heap\"} 4.0\n" @@ -154,7 +153,7 @@ public void testGoodCase() throws IOException { + "jvm_memory_used_bytes{area=\"nonheap\"} 6.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java index 9a75e9e15..d9714e30c 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java @@ -1,7 +1,8 @@ package io.prometheus.metrics.instrumentation.jvm; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.metrics.Counter; import io.prometheus.metrics.instrumentation.jvm.JvmMemoryPoolAllocationMetrics.AllocationCountingNotificationListener; @@ -9,9 +10,9 @@ import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshot; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class JvmMemoryPoolAllocationMetricsTest { +class JvmMemoryPoolAllocationMetricsTest { @Test public void testListenerLogic() { @@ -22,31 +23,31 @@ public void testListenerLogic() { // Increase by 123 listener.handleMemoryPool("TestPool", 0, 123); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(123, offset(0.0)); // No increase listener.handleMemoryPool("TestPool", 123, 123); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(123, offset(0.0)); // No increase, then decrease to 0 listener.handleMemoryPool("TestPool", 123, 0); - assertEquals(123, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(123, offset(0.0)); // No increase, then increase by 7 listener.handleMemoryPool("TestPool", 0, 7); - assertEquals(130, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(130, offset(0.0)); // Increase by 10, then decrease to 10 listener.handleMemoryPool("TestPool", 17, 10); - assertEquals(140, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(140, offset(0.0)); // Increase by 7, then increase by 3 listener.handleMemoryPool("TestPool", 17, 20); - assertEquals(150, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(150, offset(0.0)); // Decrease to 17, then increase by 3 listener.handleMemoryPool("TestPool", 17, 20); - assertEquals(153, getCountByPool("test", "TestPool", registry.scrape()), 0.0); + assertThat(getCountByPool("test", "TestPool", registry.scrape())).isCloseTo(153, offset(0.0)); } private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) { diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java index f0df40538..ab8b0d61d 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java @@ -1,19 +1,18 @@ package io.prometheus.metrics.instrumentation.jvm; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class JvmMetricsTest { +class JvmMetricsTest { @Test public void testRegisterIdempotent() { PrometheusRegistry registry = new PrometheusRegistry(); - assertEquals(0, registry.scrape().size()); + assertThat(registry.scrape().size()).isZero(); JvmMetrics.builder().register(registry); - assertTrue(registry.scrape().size() > 0); + assertThat(registry.scrape().size()).isGreaterThan(0); JvmMetrics.builder().register(registry); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java index e5a90e38d..3bc424985 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java @@ -1,17 +1,17 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import java.io.IOException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmNativeMemoryMetricsTest { +class JvmNativeMemoryMetricsTest { @Test public void testNativeMemoryTrackingFail() throws IOException { @@ -27,7 +27,7 @@ public void testNativeMemoryTrackingFail() throws IOException { String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -44,7 +44,7 @@ public void testNativeMemoryTrackingEmpty() throws IOException { String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -62,7 +62,7 @@ public void testNativeMemoryTrackingDisabled() throws IOException { String expected = "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -172,8 +172,7 @@ public void testNativeMemoryTrackingEnabled() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_native_memory_committed_bytes gauge\n" + "# TYPE jvm_native_memory_committed_bytes gauge\n" + "# UNIT jvm_native_memory_committed_bytes bytes\n" + "# HELP jvm_native_memory_committed_bytes Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.\n" + "jvm_native_memory_committed_bytes{pool=\"Arena Chunk\"} 503216.0\n" @@ -225,6 +224,6 @@ public void testNativeMemoryTrackingEnabled() throws IOException { + "jvm_native_memory_reserved_bytes{pool=\"Tracing\"} 33097.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java index 1dcaff2d9..35057bd51 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetricTest.java @@ -1,14 +1,14 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import java.io.IOException; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class JvmRuntimeInfoMetricTest { +class JvmRuntimeInfoMetricTest { @Test public void testGoodCase() throws IOException { @@ -21,12 +21,11 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_runtime info\n" + "# TYPE jvm_runtime info\n" + "# HELP jvm_runtime JVM runtime info\n" + "jvm_runtime_info{runtime=\"OpenJDK Runtime Environment\",vendor=\"Oracle Corporation\",version=\"1.8.0_382-b05\"} 1\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index 3aaa5b94b..effd79117 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -18,18 +18,18 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class JvmThreadsMetricsTest { +class JvmThreadsMetricsTest { private final ThreadMXBean mockThreadsBean = Mockito.mock(ThreadMXBean.class); private final ThreadInfo mockThreadInfoBlocked = Mockito.mock(ThreadInfo.class); private final ThreadInfo mockThreadInfoRunnable1 = Mockito.mock(ThreadInfo.class); private final ThreadInfo mockThreadInfoRunnable2 = Mockito.mock(ThreadInfo.class); - @Before + @BeforeEach public void setUp() { when(mockThreadsBean.getThreadCount()).thenReturn(300); when(mockThreadsBean.getDaemonThreadCount()).thenReturn(200); @@ -55,8 +55,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE jvm_threads_current gauge\n" + "# TYPE jvm_threads_current gauge\n" + "# HELP jvm_threads_current Current thread count of a JVM\n" + "jvm_threads_current 300.0\n" + "# TYPE jvm_threads_daemon gauge\n" @@ -85,7 +84,7 @@ public void testGoodCase() throws IOException { + "jvm_threads_state{state=\"WAITING\"} 0.0\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -134,9 +133,9 @@ public void testInvalidThreadIds() { Map actual = getCountByState(registry.scrape()); - assertEquals(expected.size(), actual.size()); + assertThat(actual).hasSameSizeAs(expected); for (String threadState : expected.keySet()) { - assertEquals(expected.get(threadState), actual.get(threadState), 0.0); + assertThat(actual.get(threadState)).isCloseTo(expected.get(threadState), offset(0.0)); } } finally { for (int i = 0; i < numberOfInvalidThreadIds; i++) { @@ -152,7 +151,7 @@ private Map getCountByState(MetricSnapshots snapshots) { for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { String state = data.getLabels().get("state"); - assertNotNull(state); + assertThat(state).isNotNull(); result.put(state, data.getValue()); } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java index 6dafa1fb3..2a447a5ec 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetricsTest.java @@ -1,7 +1,7 @@ package io.prometheus.metrics.instrumentation.jvm; import static io.prometheus.metrics.instrumentation.jvm.TestUtil.convertToOpenMetricsFormat; -import static org.junit.Assert.assertEquals; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; @@ -15,11 +15,11 @@ import java.io.IOException; import java.lang.management.RuntimeMXBean; import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; -public class ProcessMetricsTest { +class ProcessMetricsTest { private final com.sun.management.UnixOperatingSystemMXBean sunOsBean = Mockito.mock(com.sun.management.UnixOperatingSystemMXBean.class); @@ -29,7 +29,7 @@ public class ProcessMetricsTest { private final ProcessMetrics.Grepper windowsGrepper = Mockito.mock(ProcessMetrics.Grepper.class); private final RuntimeMXBean runtimeBean = Mockito.mock(RuntimeMXBean.class); - @Before + @BeforeEach public void setUp() throws IOException { when(sunOsBean.getProcessCpuTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(72)); when(sunOsBean.getOpenFileDescriptorCount()).thenReturn(127L); @@ -52,8 +52,7 @@ public void testGoodCase() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE process_cpu_seconds counter\n" + "# TYPE process_cpu_seconds counter\n" + "# UNIT process_cpu_seconds seconds\n" + "# HELP process_cpu_seconds Total user and system CPU time spent in seconds.\n" + "process_cpu_seconds_total 0.072\n" @@ -66,30 +65,27 @@ public void testGoodCase() throws IOException { // To allow running this test in non-linux environments if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { expected += - "" - + "# TYPE process_resident_memory_bytes gauge\n" + "# TYPE process_resident_memory_bytes gauge\n" + "# UNIT process_resident_memory_bytes bytes\n" + "# HELP process_resident_memory_bytes Resident memory size in bytes.\n" + "process_resident_memory_bytes 1036288.0\n"; } expected += - "" - + "# TYPE process_start_time_seconds gauge\n" + "# TYPE process_start_time_seconds gauge\n" + "# UNIT process_start_time_seconds seconds\n" + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + "process_start_time_seconds 37.1\n"; // To allow running this test in non-linux environments if (ProcessMetrics.PROC_SELF_STATUS.canRead()) { expected += - "" - + "# TYPE process_virtual_memory_bytes gauge\n" + "# TYPE process_virtual_memory_bytes gauge\n" + "# UNIT process_virtual_memory_bytes bytes\n" + "# HELP process_virtual_memory_bytes Virtual memory size in bytes.\n" + "process_virtual_memory_bytes 6180864.0\n"; } expected += "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test @@ -103,14 +99,13 @@ public void testMinimal() throws IOException { MetricSnapshots snapshots = registry.scrape(); String expected = - "" - + "# TYPE process_start_time_seconds gauge\n" + "# TYPE process_start_time_seconds gauge\n" + "# UNIT process_start_time_seconds seconds\n" + "# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.\n" + "process_start_time_seconds 37.1\n" + "# EOF\n"; - assertEquals(expected, convertToOpenMetricsFormat(snapshots)); + assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } @Test diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java index a86517368..70a093f4b 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/TestUtil.java @@ -6,7 +6,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -public class TestUtil { +class TestUtil { static String convertToOpenMetricsFormat(MetricSnapshots snapshots) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 8d3051dfe..82bbf96cf 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -35,14 +35,4 @@ fabian@fstab.de - - - - - junit - junit - 4.13.2 - test - - 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 6c7917bda..0dc9cdee1 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 @@ -1,21 +1,16 @@ package io.prometheus.metrics.model.registry; +import static org.assertj.core.api.Assertions.assertThat; + import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; 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; - -public class MetricNameFilterTest { +import org.junit.jupiter.api.Test; - private PrometheusRegistry registry; +class MetricNameFilterTest { - @Before - public void setUp() { - registry = new PrometheusRegistry(); - } + private final PrometheusRegistry registry = new PrometheusRegistry(); @Test public void testCounter() { @@ -44,28 +39,28 @@ public void testCounter() { .build()); MetricNameFilter filter = MetricNameFilter.builder().build(); - Assert.assertEquals(2, registry.scrape(filter).size()); + assertThat(registry.scrape(filter).size()).isEqualTo(2); filter = MetricNameFilter.builder().nameMustStartWith("counter1").build(); MetricSnapshots snapshots = registry.scrape(filter); - Assert.assertEquals(1, snapshots.size()); - Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName()); + assertThat(snapshots.size()).isOne(); + assertThat(snapshots.get(0).getMetadata().getName()).isEqualTo("counter1"); filter = MetricNameFilter.builder().nameMustNotStartWith("counter1").build(); snapshots = registry.scrape(filter); - Assert.assertEquals(1, snapshots.size()); - Assert.assertEquals("counter2", snapshots.get(0).getMetadata().getName()); + assertThat(snapshots.size()).isOne(); + assertThat(snapshots.get(0).getMetadata().getName()).isEqualTo("counter2"); filter = MetricNameFilter.builder().nameMustBeEqualTo("counter2_total", "counter1_total").build(); snapshots = registry.scrape(filter); - Assert.assertEquals(2, snapshots.size()); + assertThat(snapshots.size()).isEqualTo(2); filter = MetricNameFilter.builder() .nameMustBeEqualTo("counter1_total") .nameMustNotBeEqualTo("counter1_total") .build(); - Assert.assertEquals(0, registry.scrape(filter).size()); + assertThat(registry.scrape(filter).size()).isZero(); } } 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 b302f4508..b8810316f 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 @@ -1,100 +1,89 @@ package io.prometheus.metrics.model.registry; +import static org.assertj.core.api.Assertions.assertThat; + 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.MetricSnapshots; -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 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; - } - }); +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.Test; + +class MultiCollectorNameFilterTest { + + private static class Registry extends PrometheusRegistry { + private final AtomicBoolean collectCalled = new AtomicBoolean(); + + public Registry(List prometheusNames) { + register( + new MultiCollector() { + @Override + public MetricSnapshots collect() { + collectCalled.set(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; + } + }); + } + + public boolean collectCalled() { + return collectCalled.get(); + } } @Test public void testPartialFilter() { - - 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()); + Registry registry = new Registry(Collections.emptyList()); + MetricSnapshots snapshots = registry.scrape(name -> name.equals("counter_1")); + assertThat(registry.collectCalled()).isTrue(); + assertThat(snapshots.size()).isOne(); + assertThat(snapshots.get(0).getMetadata().getName()).isEqualTo("counter_1"); } @Test public void testPartialFilterWithPrometheusNames() { + Registry registry = new Registry(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(name -> name.equals("counter_1")); + assertThat(registry.collectCalled()).isTrue(); + assertThat(snapshots.size()).isOne(); + assertThat(snapshots.get(0).getMetadata().getName()).isEqualTo("counter_1"); } @Test public void testCompleteFilter_CollectCalled() { - - includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2"); - - MetricSnapshots snapshots = registry.scrape(includedNames); - Assert.assertTrue(collectCalled[0]); - Assert.assertEquals(0, snapshots.size()); + Registry registry = new Registry(Collections.emptyList()); + MetricSnapshots snapshots = + registry.scrape(name -> !name.equals("counter_1") && !name.equals("gauge_2")); + assertThat(registry.collectCalled()).isTrue(); + assertThat(snapshots.size()).isZero(); } @Test public void testCompleteFilter_CollectNotCalled() { - - 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()); + Registry registry = new Registry(Arrays.asList("counter_1", "gauge_2")); + MetricSnapshots snapshots = + registry.scrape(name -> !name.equals("counter_1") && !name.equals("gauge_2")); + assertThat(registry.collectCalled()).isFalse(); + assertThat(snapshots.size()).isZero(); } } 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 c5dd287d7..55e8b0be4 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 @@ -1,15 +1,18 @@ package io.prometheus.metrics.model.registry; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.fail; + import io.prometheus.metrics.model.snapshots.CounterSnapshot; 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; +import org.junit.jupiter.api.Test; -public class PrometheusRegistryTest { +class PrometheusRegistryTest { Collector noName = () -> GaugeSnapshot.builder().name("no_name_gauge").build(); @@ -90,18 +93,19 @@ public void registerNoName() { try { registry.scrape(); } catch (IllegalStateException e) { - Assert.assertTrue( - e.getMessage().contains("duplicate") && e.getMessage().contains("no_name_gauge")); + assertThat(e.getMessage().contains("duplicate") && e.getMessage().contains("no_name_gauge")) + .isTrue(); return; } - Assert.fail("Expected duplicate name exception"); + fail("Expected duplicate name exception"); } - @Test(expected = IllegalStateException.class) + @Test public void registerDuplicateName() { PrometheusRegistry registry = new PrometheusRegistry(); registry.register(counterA1); - registry.register(counterA2); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> registry.register(counterA2)); } @Test @@ -111,22 +115,23 @@ public void registerOk() { registry.register(counterB); registry.register(gaugeA); MetricSnapshots snapshots = registry.scrape(); - Assert.assertEquals(3, snapshots.size()); + assertThat(snapshots.size()).isEqualTo(3); registry.unregister(counterB); snapshots = registry.scrape(); - Assert.assertEquals(2, snapshots.size()); + assertThat(snapshots.size()).isEqualTo(2); registry.register(counterB); snapshots = registry.scrape(); - Assert.assertEquals(3, snapshots.size()); + assertThat(snapshots.size()).isEqualTo(3); } - @Test(expected = IllegalStateException.class) + @Test public void registerDuplicateMultiCollector() { PrometheusRegistry registry = new PrometheusRegistry(); registry.register(multiCollector); - registry.register(multiCollector); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> registry.register(multiCollector)); } @Test @@ -134,10 +139,10 @@ public void registerOkMultiCollector() { PrometheusRegistry registry = new PrometheusRegistry(); registry.register(multiCollector); MetricSnapshots snapshots = registry.scrape(); - Assert.assertEquals(2, snapshots.size()); + assertThat(snapshots.size()).isEqualTo(2); registry.unregister(multiCollector); snapshots = registry.scrape(); - Assert.assertEquals(0, snapshots.size()); + assertThat(snapshots.size()).isZero(); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java index 082981431..278a8fafc 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java @@ -1,10 +1,13 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ClassicHistogramBucketsTest { +class ClassicHistogramBucketsTest { @Test public void testGoodCase() { @@ -15,7 +18,7 @@ public void testGoodCase() { .bucket(1024, 3) .bucket(Double.POSITIVE_INFINITY, 8) .build(); - Assert.assertEquals(4, buckets.size()); + assertThat(buckets.size()).isEqualTo(4); } @Test @@ -26,64 +29,80 @@ public void testSort() { .bucket(2, 0) .bucket(Double.POSITIVE_INFINITY, 3) .build(); - Assert.assertEquals(3, buckets.size()); - Assert.assertEquals(2, buckets.getUpperBound(0), 0.0); - Assert.assertEquals(7, buckets.getUpperBound(1), 0.0); - Assert.assertEquals(Double.POSITIVE_INFINITY, buckets.getUpperBound(2), 0.0); - Assert.assertEquals(0, buckets.getCount(0)); - Assert.assertEquals(2, buckets.getCount(1)); - Assert.assertEquals(3, buckets.getCount(2)); + assertThat(buckets.size()).isEqualTo(3); + assertThat(buckets.getUpperBound(0)).isCloseTo(2, offset(0.0)); + assertThat(buckets.getUpperBound(1)).isCloseTo(7, offset(0.0)); + assertThat(buckets.getUpperBound(2)).isCloseTo(Double.POSITIVE_INFINITY, offset(0.0)); + assertThat(buckets.getCount(0)).isZero(); + assertThat(buckets.getCount(1)).isEqualTo(2); + assertThat(buckets.getCount(2)).isEqualTo(3); } @Test public void testMinimalBuckets() { ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder().bucket(Double.POSITIVE_INFINITY, 0).build(); - Assert.assertEquals(1, buckets.size()); + assertThat(buckets.size()).isOne(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testInfBucketMissing() { - ClassicHistogramBuckets.builder().bucket(Double.NEGATIVE_INFINITY, 0).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> ClassicHistogramBuckets.builder().bucket(Double.NEGATIVE_INFINITY, 0).build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNegativeCount() { - ClassicHistogramBuckets.builder().bucket(0.0, 10).bucket(Double.POSITIVE_INFINITY, -1).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + ClassicHistogramBuckets.builder() + .bucket(0.0, 10) + .bucket(Double.POSITIVE_INFINITY, -1) + .build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNaNBoundary() { - ClassicHistogramBuckets.builder() - .bucket(0.0, 1) - .bucket(Double.NaN, 2) - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + ClassicHistogramBuckets.builder() + .bucket(0.0, 1) + .bucket(Double.NaN, 2) + .bucket(Double.POSITIVE_INFINITY, 0) + .build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicateBoundary() { - ClassicHistogramBuckets.builder() - .bucket(1.0, 1) - .bucket(2.0, 2) - .bucket(1.0, 2) - .bucket(Double.POSITIVE_INFINITY, 0) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + ClassicHistogramBuckets.builder() + .bucket(1.0, 1) + .bucket(2.0, 2) + .bucket(1.0, 2) + .bucket(Double.POSITIVE_INFINITY, 0) + .build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyBuckets() { - ClassicHistogramBuckets.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> ClassicHistogramBuckets.builder().build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDifferentLength() { double[] upperBounds = new double[] {0.7, 1.3, Double.POSITIVE_INFINITY}; long[] counts = new long[] {13, 178, 1024, 3000}; - ClassicHistogramBuckets.of(upperBounds, counts); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> ClassicHistogramBuckets.of(upperBounds, counts)); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testImmutable() { ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder() @@ -93,6 +112,6 @@ public void testImmutable() { .build(); Iterator iterator = buckets.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java index 96e8df4c9..e381e5903 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/CounterSnapshotTest.java @@ -1,12 +1,15 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; import java.util.Iterator; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class CounterSnapshotTest { +class CounterSnapshotTest { @Test public void testCompleteGoodCase() { @@ -47,22 +50,22 @@ public void testCompleteGoodCase() { .build(); SnapshotTestUtil.assertMetadata( snapshot, "http_server_requests_seconds", "total time spent serving requests", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); CounterDataPointSnapshot data = snapshot .getDataPoints() .get(0); // data is sorted by labels, so the first one should be path="/hello" - Assert.assertEquals(Labels.of("path", "/hello"), data.getLabels()); - Assert.assertEquals(2.0, data.getValue(), 0.0); - Assert.assertEquals(4.0, data.getExemplar().getValue(), 0.0); - Assert.assertEquals(createdTimestamp2, data.getCreatedTimestampMillis()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("path", "/hello")); + assertThat(data.getValue()).isCloseTo(2.0, offset(0.0)); + assertThat(data.getExemplar().getValue()).isCloseTo(4.0, offset(0.0)); + assertThat(data.getCreatedTimestampMillis()).isEqualTo(createdTimestamp2); + assertThat(data.hasScrapeTimestamp()).isFalse(); data = snapshot.getDataPoints().get(1); - Assert.assertEquals(Labels.of("path", "/world"), data.getLabels()); - Assert.assertEquals(1.0, data.getValue(), 0.0); - Assert.assertEquals(3.0, data.getExemplar().getValue(), 0.0); - Assert.assertEquals(createdTimestamp1, data.getCreatedTimestampMillis()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("path", "/world")); + assertThat(data.getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(data.getExemplar().getValue()).isCloseTo(3.0, offset(0.0)); + assertThat(data.getCreatedTimestampMillis()).isEqualTo(createdTimestamp1); + assertThat(data.hasScrapeTimestamp()).isFalse(); } @Test @@ -73,32 +76,34 @@ public void testMinimalGoodCase() { .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "events", null, null); - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(1); CounterDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.EMPTY, data.getLabels()); - Assert.assertEquals(1.0, data.getValue(), 0.0); - Assert.assertNull(data.getExemplar()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEmpty(); + assertThat(data.getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(data.getExemplar()).isNull(); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); } @Test public void testEmptyCounter() { CounterSnapshot snapshot = CounterSnapshot.builder().name("events").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).isEmpty(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTotalSuffixPresent() { - CounterSnapshot.builder().name("test_total").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CounterSnapshot.builder().name("test_total").build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testValueMissing() { - CounterDataPointSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CounterDataPointSnapshot.builder().build()); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testDataImmutable() { CounterSnapshot snapshot = CounterSnapshot.builder() @@ -110,6 +115,6 @@ public void testDataImmutable() { .build(); Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java index 1a94b12f1..ebc875d5f 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarTest.java @@ -1,9 +1,13 @@ package io.prometheus.metrics.model.snapshots; -import org.junit.Assert; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; -public class ExemplarTest { +import org.assertj.core.api.IterableAssert; +import org.junit.jupiter.api.Test; + +class ExemplarTest { @Test public void testGoodCaseComplete() { @@ -16,47 +20,52 @@ public void testGoodCaseComplete() { .timestampMillis(timestamp) .labels(Labels.of("path", "/", "error", "none")) .build(); - Assert.assertEquals(2.2, exemplar.getValue(), 0.0); - Assert.assertEquals( - Labels.of( - Exemplar.TRACE_ID, - "abc123abc123", - Exemplar.SPAN_ID, - "def456def456", - "path", - "/", - "error", - "none"), - exemplar.getLabels()); - Assert.assertTrue(exemplar.hasTimestamp()); - Assert.assertEquals(timestamp, exemplar.getTimestampMillis()); + assertThat(exemplar.getValue()).isCloseTo(2.2, offset(0.0)); + assertLabels(exemplar.getLabels()) + .isEqualTo( + Labels.of( + Exemplar.TRACE_ID, + "abc123abc123", + Exemplar.SPAN_ID, + "def456def456", + "path", + "/", + "error", + "none")); + assertThat(exemplar.hasTimestamp()).isTrue(); + assertThat(exemplar.getTimestampMillis()).isEqualTo(timestamp); } - @Test(expected = IllegalStateException.class) + @Test public void testValueMissing() { - Exemplar.builder().build(); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> Exemplar.builder().build()); } @Test public void testMinimal() { Exemplar exemplar = Exemplar.builder().value(0.0).build(); - Assert.assertEquals(0.0, exemplar.getValue(), 0.0); - Assert.assertEquals(Labels.EMPTY, exemplar.getLabels()); - Assert.assertFalse(exemplar.hasTimestamp()); + assertThat(exemplar.getValue()).isCloseTo(0.0, offset(0.0)); + assertLabels(exemplar.getLabels()).isEqualTo(Labels.EMPTY); + assertThat(exemplar.hasTimestamp()).isFalse(); } @Test public void testLabelsMergeTraceId() { Exemplar exemplar = Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).traceId("abc").build(); - Assert.assertEquals(Labels.of("a", "b", "trace_id", "abc"), exemplar.getLabels()); + assertLabels(exemplar.getLabels()).isEqualTo(Labels.of("a", "b", "trace_id", "abc")); + } + + private static IterableAssert assertLabels(Labels labels) { + return assertThat((Iterable) labels); } @Test public void testLabelsMergeSpanId() { Exemplar exemplar = Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).spanId("abc").build(); - Assert.assertEquals(Labels.of("a", "b", "span_id", "abc"), exemplar.getLabels()); + assertLabels(exemplar.getLabels()).isEqualTo(Labels.of("a", "b", "span_id", "abc")); } @Test @@ -68,13 +77,13 @@ public void testLabelsMergeTraceIdAndSpanId() { .spanId("abc") .traceId("def") .build(); - Assert.assertEquals( - Labels.of("span_id", "abc", "a", "b", "trace_id", "def"), exemplar.getLabels()); + assertLabels(exemplar.getLabels()) + .isEqualTo(Labels.of("span_id", "abc", "a", "b", "trace_id", "def")); } @Test public void testLabelsMergeNone() { Exemplar exemplar = Exemplar.builder().value(0.0).labels(Labels.of("a", "b")).build(); - Assert.assertEquals(Labels.of("a", "b"), exemplar.getLabels()); + assertLabels(exemplar.getLabels()).isEqualTo(Labels.of("a", "b")); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java index 93a1c1efa..74a3fbe8a 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -1,10 +1,13 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class ExemplarsTest { +class ExemplarsTest { @Test public void testUpperBound() { @@ -13,19 +16,19 @@ public void testUpperBound() { Exemplar.builder().value(1.0).build(), Exemplar.builder().value(3.0).build(), Exemplar.builder().value(2.0).build()); - Assert.assertEquals(3, exemplars.size()); - Assert.assertEquals(1.0, exemplars.get(0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(1).getValue(), 0.0); - Assert.assertEquals(2.0, exemplars.get(2).getValue(), 0.0); - Assert.assertEquals(1.0, exemplars.get(0.0, Double.POSITIVE_INFINITY).getValue(), 0.0); - Assert.assertEquals(1.0, exemplars.get(0.0, 1.0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(1.0, 4.0).getValue(), 0.0); - Assert.assertEquals(3.0, exemplars.get(2.0, 3.0).getValue(), 0.0); - Assert.assertEquals(2.0, exemplars.get(1.0, 2.1).getValue(), 0.0); - Assert.assertNull(exemplars.get(2.0, 2.1)); + assertThat(exemplars.size()).isEqualTo(3); + assertThat(exemplars.get(0).getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(exemplars.get(1).getValue()).isCloseTo(3.0, offset(0.0)); + assertThat(exemplars.get(2).getValue()).isCloseTo(2.0, offset(0.0)); + assertThat(exemplars.get(0.0, Double.POSITIVE_INFINITY).getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(exemplars.get(0.0, 1.0).getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(exemplars.get(1.0, 4.0).getValue()).isCloseTo(3.0, offset(0.0)); + assertThat(exemplars.get(2.0, 3.0).getValue()).isCloseTo(3.0, offset(0.0)); + assertThat(exemplars.get(1.0, 2.1).getValue()).isCloseTo(2.0, offset(0.0)); + assertThat(exemplars.get(2.0, 2.1)).isNull(); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testImmutable() { Exemplars exemplars = Exemplars.of( @@ -34,7 +37,7 @@ public void testImmutable() { Exemplar.builder().value(2.0).build()); Iterator iterator = exemplars.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } @Test @@ -47,8 +50,8 @@ public void testGet() { Exemplar.builder().timestampMillis(System.currentTimeMillis()).value(1.0).build(); Exemplars exemplars = Exemplars.of(oldest, newest, middle); Exemplar result = exemplars.get(1.1, 1.9); // newest is not within these bounds - Assert.assertSame(result, middle); + assertThat(middle).isSameAs(result); result = exemplars.get(0.9, Double.POSITIVE_INFINITY); - Assert.assertSame(result, newest); + assertThat(newest).isSameAs(result); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java index fe7f386ba..1fd55d67e 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/GaugeSnapshotTest.java @@ -1,12 +1,15 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class GaugeSnapshotTest { +class GaugeSnapshotTest { @Test public void testCompleteGoodCase() { @@ -42,22 +45,22 @@ public void testCompleteGoodCase() { .build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "cache_size_bytes", "cache size in Bytes", "bytes"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); GaugeDataPointSnapshot data = snapshot .getDataPoints() .get(0); // data is sorted by labels, so the first one should be path="/hello" - Assert.assertEquals(Labels.of("env", "dev"), data.getLabels()); - Assert.assertEquals(128.0, data.getValue(), 0.0); - Assert.assertEquals(128.0, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("env", "dev")); + assertThat(data.getValue()).isCloseTo(128.0, offset(0.0)); + assertThat(data.getExemplar().getValue()).isCloseTo(128.0, offset(0.0)); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); data = snapshot.getDataPoints().get(1); - Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); - Assert.assertEquals(1024.0, data.getValue(), 0.0); - Assert.assertEquals(1024.0, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("env", "prod")); + assertThat(data.getValue()).isCloseTo(1024.0, offset(0.0)); + assertThat(data.getExemplar().getValue()).isCloseTo(1024.0, offset(0.0)); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); } @Test @@ -68,37 +71,40 @@ public void testMinimalGoodCase() { .dataPoint(GaugeDataPointSnapshot.builder().value(23.0).build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "temperature", null, null); - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isOne(); GaugeDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.EMPTY, data.getLabels()); - Assert.assertEquals(23.0, data.getValue(), 0.0); - Assert.assertNull(data.getExemplar()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEmpty(); + assertThat(data.getValue()).isCloseTo(23.0, offset(0.0)); + assertThat(data.getExemplar()).isNull(); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); } @Test public void testEmptyGauge() { GaugeSnapshot snapshot = GaugeSnapshot.builder().name("temperature").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isZero(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTotalSuffixPresent() { - CounterSnapshot.builder().name("test_total").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CounterSnapshot.builder().name("test_total").build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testTotalSuffixPresentDot() { - CounterSnapshot.builder().name("test.total").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CounterSnapshot.builder().name("test.total").build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testValueMissing() { - CounterDataPointSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> CounterDataPointSnapshot.builder().build()); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testDataImmutable() { GaugeSnapshot snapshot = GaugeSnapshot.builder() @@ -110,6 +116,6 @@ public void testDataImmutable() { .build(); Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } } 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 e8e53e219..2f8aeb730 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,12 +1,15 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import io.prometheus.metrics.model.snapshots.HistogramSnapshot.HistogramDataPointSnapshot; import java.util.Iterator; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class HistogramSnapshotTest { +class HistogramSnapshotTest { @Test public void testGoodCaseComplete() { @@ -82,94 +85,94 @@ public void testGoodCaseComplete() { SnapshotTestUtil.assertMetadata( snapshot, "request_size_bytes", "request sizes in bytes", "bytes"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); 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()); + assertThat(data.hasSum()).isTrue(); + assertThat(data.hasCount()).isTrue(); + assertThat(data.hasCreatedTimestamp()).isTrue(); + assertThat(data.hasScrapeTimestamp()).isTrue(); + assertThat(data.getCount()).isEqualTo(22); + assertThat(data.getSum()).isCloseTo(27000.0, offset(0.0)); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("path", "/")); + assertThat(data.getExemplars().get(128.0, 1024.0).getValue()) + .isCloseTo(exemplar1.getValue(), offset(0.0)); + assertThat(data.getCreatedTimestampMillis()).isEqualTo(createdTimestamp); + assertThat(data.getScrapeTimestampMillis()).isEqualTo(scrapeTimestamp); // 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()); + assertThat(bucket.getUpperBound()).isCloseTo(128.0, offset(0.0)); + assertThat(bucket.getCount()).isEqualTo(7); break; case 1: - Assert.assertEquals(1024.0, bucket.getUpperBound(), 0.0); - Assert.assertEquals(15, bucket.getCount()); + assertThat(bucket.getUpperBound()).isCloseTo(1024.0, offset(0.0)); + assertThat(bucket.getCount()).isEqualTo(15); break; case 2: - Assert.assertEquals(Double.POSITIVE_INFINITY, bucket.getUpperBound(), 0.0); - Assert.assertEquals(0, bucket.getCount()); + assertThat(bucket.getUpperBound()).isCloseTo(Double.POSITIVE_INFINITY, offset(0.0)); + assertThat(bucket.getCount()).isZero(); break; } } - Assert.assertEquals("expecting 3 classic histogram buckets", 3, i); + assertThat(i).as("expecting 3 classic histogram buckets").isEqualTo(3); // 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()); + assertThat(data.getNativeSchema()).isEqualTo(5); + assertThat(data.getNativeZeroCount()).isEqualTo(2); + assertThat(data.getNativeZeroThreshold()).isCloseTo(0.0000001, offset(0.0000001)); + assertThat(data.getNativeBucketsForPositiveValues().size()).isEqualTo(3); i = 0; for (NativeHistogramBucket bucket : data.getNativeBucketsForPositiveValues()) { switch (i++) { case 0: - Assert.assertEquals(1, bucket.getBucketIndex()); - Assert.assertEquals(12, bucket.getCount()); + assertThat(bucket.getBucketIndex()).isOne(); + assertThat(bucket.getCount()).isEqualTo(12); break; case 1: - Assert.assertEquals(2, bucket.getBucketIndex()); - Assert.assertEquals(3, bucket.getCount()); + assertThat(bucket.getBucketIndex()).isEqualTo(2); + assertThat(bucket.getCount()).isEqualTo(3); break; case 2: - Assert.assertEquals(4, bucket.getBucketIndex()); - Assert.assertEquals(2, bucket.getCount()); + assertThat(bucket.getBucketIndex()).isEqualTo(4); + assertThat(bucket.getCount()).isEqualTo(2); break; } } - Assert.assertEquals("expecting 3 native buckets for positive values", 3, i); + assertThat(i).as("expecting 3 native buckets for positive values").isEqualTo(3); i = 0; - Assert.assertEquals(2, data.getNativeBucketsForNegativeValues().size()); + assertThat(data.getNativeBucketsForNegativeValues().size()).isEqualTo(2); for (NativeHistogramBucket bucket : data.getNativeBucketsForNegativeValues()) { switch (i++) { case 0: - Assert.assertEquals(-1, bucket.getBucketIndex()); - Assert.assertEquals(1, bucket.getCount()); + assertThat(bucket.getBucketIndex()).isEqualTo(-1); + assertThat(bucket.getCount()).isOne(); break; case 1: - Assert.assertEquals(0, bucket.getBucketIndex()); - Assert.assertEquals(2, bucket.getCount()); + assertThat(bucket.getBucketIndex()).isZero(); + assertThat(bucket.getCount()).isEqualTo(2); break; } } - Assert.assertEquals("expecting 2 native buckets for positive values", 2, i); + assertThat(i).as("expecting 2 native buckets for positive values").isEqualTo(2); // 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()); + assertThat(data.getCount()).isEqualTo(6); // 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); + assertThat(data.getNativeSchema()).isEqualTo(5); + assertThat(data.getNativeZeroCount()).isZero(); + assertThat(data.getNativeZeroThreshold()).isZero(); } @Test public void testEmptyHistogram() { HistogramSnapshot snapshot = HistogramSnapshot.builder().name("empty_histogram").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).isEmpty(); } @Test @@ -185,8 +188,8 @@ public void testMinimalClassicHistogram() { .build()) .build(); HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertFalse(data.hasSum()); - Assert.assertEquals(1, snapshot.getDataPoints().get(0).getClassicBuckets().size()); + assertThat(data.hasSum()).isFalse(); + assertThat(snapshot.getDataPoints().get(0).getClassicBuckets().size()).isOne(); } @Test @@ -196,17 +199,17 @@ public void testMinimalNativeHistogram() { .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()); + assertThat(snapshot.getMetadata().getName()).isEqualTo("hist"); + assertThat(snapshot.getMetadata().hasUnit()).isFalse(); + assertThat(snapshot.getDataPoints().size()).isOne(); 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()); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); + assertThat(data.hasCount()).isTrue(); + assertThat(data.getCount()).isZero(); + assertThat(data.hasSum()).isFalse(); + assertThat(data.getNativeBucketsForNegativeValues().size()).isZero(); + assertThat(data.getNativeBucketsForPositiveValues().size()).isZero(); } @Test @@ -225,25 +228,26 @@ public void testClassicCount() { .build()) .build(); HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertFalse(data.hasSum()); - Assert.assertTrue(data.hasCount()); - Assert.assertEquals(5, data.getCount()); + assertThat(data.hasSum()).isFalse(); + assertThat(data.hasCount()).isTrue(); + assertThat(data.getCount()).isEqualTo(5); } - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyData() { // This will fail because one of nativeSchema and classicHistogramBuckets is required - HistogramDataPointSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> HistogramDataPointSnapshot.builder().build()); } @Test public void testEmptyNativeData() { HistogramDataPointSnapshot data = HistogramDataPointSnapshot.builder().nativeSchema(5).build(); - Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size()); - Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size()); + assertThat(data.getNativeBucketsForNegativeValues().size()).isZero(); + assertThat(data.getNativeBucketsForPositiveValues().size()).isZero(); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testDataImmutable() { HistogramSnapshot snapshot = HistogramSnapshot.builder() @@ -265,13 +269,16 @@ public void testDataImmutable() { .build(); Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyClassicBuckets() { - new HistogramDataPointSnapshot( - ClassicHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + new HistogramDataPointSnapshot( + ClassicHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L)); } @Test diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java index 78e26d100..423b57da7 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java @@ -1,10 +1,12 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class InfoSnapshotTest { +class InfoSnapshotTest { @Test public void testCompleteGoodCase() { @@ -17,19 +19,19 @@ public void testCompleteGoodCase() { .labels(Labels.of("instance_id", "127.0.0.1:9100", "service_name", "gateway")) .build()) .build(); - Assert.assertEquals("target", snapshot.getMetadata().getName()); - Assert.assertEquals("Target info", snapshot.getMetadata().getHelp()); - Assert.assertFalse(snapshot.getMetadata().hasUnit()); - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getMetadata().getName()).isEqualTo("target"); + assertThat(snapshot.getMetadata().getHelp()).isEqualTo("Target info"); + assertThat(snapshot.getMetadata().hasUnit()).isFalse(); + assertThat(snapshot.getDataPoints().size()).isOne(); } @Test public void testEmptyInfo() { InfoSnapshot snapshot = InfoSnapshot.builder().name("target").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).isEmpty(); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testDataImmutable() { InfoSnapshot snapshot = InfoSnapshot.builder() @@ -47,16 +49,18 @@ public void testDataImmutable() { .build(); Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNameMustNotIncludeSuffix() { - InfoSnapshot.builder().name("jvm_info").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> InfoSnapshot.builder().name("jvm_info").build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNameMustNotIncludeSuffixDot() { - InfoSnapshot.builder().name("jvm.info").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> InfoSnapshot.builder().name("jvm.info").build()); } } 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 e7ae37723..4d68b82a8 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,18 +1,19 @@ package io.prometheus.metrics.model.snapshots; -import static org.junit.Assert.assertNotEquals; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.junit.Assert; -import org.junit.Test; +import org.assertj.core.api.IterableAssert; +import org.junit.jupiter.api.Test; -public class LabelsTest { +class LabelsTest { private > void assertLessThan(T a, T b) { - Assert.assertTrue(a.compareTo(b) < 0); + assertThat(a).isLessThan(b); } private > void assertGreaterThan(T a, T b) { - Assert.assertTrue(a.compareTo(b) > 0); + assertThat(a).isGreaterThan(b); } @Test @@ -21,8 +22,12 @@ public void testCompareDifferentLabelNames() { Labels labels2 = Labels.of("env", "prod", "status1", "200"); assertGreaterThan(labels1, labels2); assertLessThan(labels2, labels1); - assertNotEquals(labels1, labels2); - assertNotEquals(labels2, labels1); + assertLabels(labels2).isNotEqualTo(labels1); + assertLabels(labels1).isNotEqualTo(labels2); + } + + private static IterableAssert assertLabels(Labels labels) { + return assertThat((Iterable) labels); } @Test @@ -32,8 +37,8 @@ public void testCompareSameLabelNames() { Labels labels2 = Labels.of("env", "prod", "status", "500"); assertLessThan(labels1, labels2); assertGreaterThan(labels2, labels1); - assertNotEquals(labels1, labels2); - assertNotEquals(labels2, labels1); + assertLabels(labels2).isNotEqualTo(labels1); + assertLabels(labels1).isNotEqualTo(labels2); } @Test @@ -42,8 +47,8 @@ public void testCompareDifferentNumberOfLabels() { Labels labels2 = Labels.of("env", "prod", "status", "200", "x_code", "none"); assertLessThan(labels1, labels2); assertGreaterThan(labels2, labels1); - assertNotEquals(labels1, labels2); - assertNotEquals(labels2, labels1); + assertLabels(labels2).isNotEqualTo(labels1); + assertLabels(labels1).isNotEqualTo(labels2); } @Test @@ -57,51 +62,54 @@ public void testComparePrometheusNames() { 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()); + assertLabels(labels2).isEqualTo(labels1).hasSameHashCodeAs(labels1); } + @SuppressWarnings({"unchecked", "rawtypes"}) @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); + assertThat((Comparable) labels1).isEqualByComparingTo(labels2); + assertThat((Comparable) labels2).isEqualByComparingTo(labels1); + assertLabels(labels2).isEqualTo(labels1); + assertLabels(labels1).isEqualTo(labels2); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalLabelName() { - Labels.of("my_service/status", "200"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Labels.of("my_service/status", "200")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testReservedLabelName() { - Labels.of("__name__", "requests_total"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Labels.of("__name__", "requests_total")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicateLabelName() { - Labels.of("name1", "value1", "name2", "value2", "name1", "value3"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> 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); + assertThat(prometheusNames).isSameAs(names); names = new String[] {"no_dots", "at_all"}; prometheusNames = Labels.makePrometheusNames(names); - Assert.assertSame(names, prometheusNames); + assertThat(prometheusNames).isSameAs(names); 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]); + assertThat(prometheusNames).isNotSameAs(names); + assertThat(prometheusNames[0]).isSameAs(names[0]); + assertThat(names[1]).isEqualTo("here.it.is"); + assertThat(prometheusNames[1]).isEqualTo("here_it_is"); } @Test @@ -109,20 +117,22 @@ 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)); + assertThat(merged.getName(0)).isEqualTo("key.1"); + assertThat(merged.getName(1)).isEqualTo("key_2"); + assertThat(merged.getName(2)).isEqualTo("key.3"); } - @Test(expected = IllegalArgumentException.class) + @Test public void testMergeDuplicateName() { Labels labels1 = Labels.of("key_one", "v1"); Labels labels2 = Labels.of("key.one", "v2"); - labels2.merge(labels1); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> labels2.merge(labels1)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicateName() { - Labels.of("key_one", "v1", "key.one", "v2"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> 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 9a3a980bc..fab885488 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,26 +1,33 @@ package io.prometheus.metrics.model.snapshots; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class MetricMetadataTest { +class MetricMetadataTest { - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyName() { - new MetricMetadata(""); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MetricMetadata("")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNullName() { - new MetricMetadata(null); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MetricMetadata(null)); } - @Test(expected = IllegalArgumentException.class) + @Test public void testIllegalName() { - new MetricMetadata( - "my_namespace/http_server_duration"); // let's see when we decide to allow slashes :) + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + new MetricMetadata( + "my_namespace/http_server_duration")); // let's see when we decide to allow + // slashes :) } @Test @@ -30,38 +37,40 @@ public void testSanitizationIllegalCharacters() { 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()); + assertThat(metadata.getName()).isEqualTo("my_namespace_http.server.duration_seconds"); + assertThat(metadata.getPrometheusName()).isEqualTo("my_namespace_http_server_duration_seconds"); + assertThat(metadata.getHelp()).isEqualTo("help string"); + assertThat(metadata.getUnit().toString()).isEqualTo("seconds"); } @Test public void testSanitizationCounter() { MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("my_events_total")); - Assert.assertEquals("my_events", metadata.getName()); + assertThat(metadata.getName()).isEqualTo("my_events"); } @Test public void testSanitizationInfo() { MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("target_info")); - Assert.assertEquals("target", metadata.getName()); + assertThat(metadata.getName()).isEqualTo("target"); } @Test public void testSanitizationWeirdCornerCase() { MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("_total_created")); - Assert.assertEquals("total", metadata.getName()); + assertThat(metadata.getName()).isEqualTo("total"); } - @Test(expected = IllegalArgumentException.class) + @Test public void testSanitizeEmptyString() { - sanitizeMetricName(""); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> sanitizeMetricName("")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testUnitSuffixRequired() { - new MetricMetadata("my_counter", "help", Unit.SECONDS); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MetricMetadata("my_counter", "help", Unit.SECONDS)); } @Test @@ -71,6 +80,6 @@ public void testUnitSuffixAdded() { @Test public void testUnitNotDuplicated() { - Assert.assertEquals("my_counter_bytes", sanitizeMetricName("my_counter_bytes", Unit.BYTES)); + assertThat(sanitizeMetricName("my_counter_bytes", Unit.BYTES)).isEqualTo("my_counter_bytes"); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java index e387d7155..fc0c24bfc 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -1,40 +1,46 @@ package io.prometheus.metrics.model.snapshots; -import org.junit.Assert; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -public class MetricSnapshotTest { +import org.junit.jupiter.api.Test; - @Test(expected = IllegalArgumentException.class) +class MetricSnapshotTest { + + @Test public void testDuplicateLabels() { - CounterSnapshot.builder() - .name("events") - .dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("path", "/hello", "status", "200")) - .value(1.0) - .build()) - .dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("path", "/world", "status", "200")) - .value(2.0) - .build()) - .dataPoint( - CounterSnapshot.CounterDataPointSnapshot.builder() - .labels(Labels.of("status", "200", "path", "/hello")) - .value(3.0) - .build()) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + CounterSnapshot.builder() + .name("events") + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/hello", "status", "200")) + .value(1.0) + .build()) + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("path", "/world", "status", "200")) + .value(2.0) + .build()) + .dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(Labels.of("status", "200", "path", "/hello")) + .value(3.0) + .build()) + .build()); } @Test public void testNoData() { MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints().size()).isEqualTo(0); } - @Test(expected = NullPointerException.class) + @Test public void testNullData() { - new CounterSnapshot(new MetricMetadata("test"), null); + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> new CounterSnapshot(new MetricMetadata("test"), null)); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java index b85fe629f..ed2f66fec 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java @@ -1,15 +1,17 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class MetricSnapshotsTest { +class MetricSnapshotsTest { @Test public void testEmpty() { MetricSnapshots snapshots = MetricSnapshots.builder().build(); - Assert.assertFalse(snapshots.stream().findAny().isPresent()); + assertThat(snapshots.stream().findAny().isPresent()).isFalse(); } @Test @@ -30,13 +32,13 @@ public void testSort() { .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); - Assert.assertEquals(3, snapshots.size()); - Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName()); - Assert.assertEquals("counter2", snapshots.get(1).getMetadata().getName()); - Assert.assertEquals("counter3", snapshots.get(2).getMetadata().getName()); + assertThat(snapshots.size()).isEqualTo(3); + assertThat(snapshots.get(0).getMetadata().getName()).isEqualTo("counter1"); + assertThat(snapshots.get(1).getMetadata().getName()).isEqualTo("counter2"); + assertThat(snapshots.get(2).getMetadata().getName()).isEqualTo("counter3"); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicateName() { // Q: What if you have a counter named "foo" and a gauge named "foo"? // A: Great question. You might think this is a valid scenario, because the counter will produce @@ -55,7 +57,8 @@ public void testDuplicateName() { .name("my_metric") .dataPoint(GaugeSnapshot.GaugeDataPointSnapshot.builder().value(1.0).build()) .build(); - new MetricSnapshots(c, g); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> new MetricSnapshots(c, g)); } @Test @@ -66,12 +69,12 @@ public void testBuilder() { .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); MetricSnapshots.Builder builder = MetricSnapshots.builder(); - Assert.assertFalse(builder.containsMetricName("my_metric")); + assertThat(builder.containsMetricName("my_metric")).isFalse(); builder.metricSnapshot(counter); - Assert.assertTrue(builder.containsMetricName("my_metric")); + assertThat(builder.containsMetricName("my_metric")).isTrue(); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testImmutable() { CounterSnapshot c1 = CounterSnapshot.builder() @@ -91,6 +94,6 @@ public void testImmutable() { MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); Iterator iterator = snapshots.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java index 1aa7a1023..32c7f3eb3 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/NativeHistogramBucketsTest.java @@ -1,54 +1,57 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class NativeHistogramBucketsTest { +class NativeHistogramBucketsTest { @Test public void testGoodCase() { NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().bucket(-10, 12).bucket(120, 17).build(); - Assert.assertEquals(2, buckets.size()); - Assert.assertEquals(-10, buckets.getBucketIndex(0)); - Assert.assertEquals(12, buckets.getCount(0)); - Assert.assertEquals(120, buckets.getBucketIndex(1)); - Assert.assertEquals(17, buckets.getCount(1)); + assertThat(buckets.size()).isEqualTo(2); + assertThat(buckets.getBucketIndex(0)).isEqualTo(-10); + assertThat(buckets.getCount(0)).isEqualTo(12); + assertThat(buckets.getBucketIndex(1)).isEqualTo(120); + assertThat(buckets.getCount(1)).isEqualTo(17); } @Test public void testEmpty() { NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().build(); - Assert.assertEquals(0, buckets.size()); + assertThat(buckets.size()).isZero(); } @Test public void testSort() { NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().bucket(7, 4).bucket(2, 0).bucket(5, 3).build(); - Assert.assertEquals(3, buckets.size()); - Assert.assertEquals(2, buckets.getBucketIndex(0)); - Assert.assertEquals(5, buckets.getBucketIndex(1)); - Assert.assertEquals(7, buckets.getBucketIndex(2)); - Assert.assertEquals(0, buckets.getCount(0)); - Assert.assertEquals(3, buckets.getCount(1)); - Assert.assertEquals(4, buckets.getCount(2)); + assertThat(buckets.size()).isEqualTo(3); + assertThat(buckets.getBucketIndex(0)).isEqualTo(2); + assertThat(buckets.getBucketIndex(1)).isEqualTo(5); + assertThat(buckets.getBucketIndex(2)).isEqualTo(7); + assertThat(buckets.getCount(0)).isZero(); + assertThat(buckets.getCount(1)).isEqualTo(3); + assertThat(buckets.getCount(2)).isEqualTo(4); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDifferentLength() { int[] bucketIndexes = new int[] {0, 1, 2}; long[] cumulativeCounts = new long[] {13, 178, 1024, 3000}; - NativeHistogramBuckets.of(bucketIndexes, cumulativeCounts); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> NativeHistogramBuckets.of(bucketIndexes, cumulativeCounts)); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testImmutable() { NativeHistogramBuckets buckets = NativeHistogramBuckets.builder().bucket(1, 1).bucket(2, 1).build(); Iterator iterator = buckets.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java index 62f2fc2c8..fad55e0ac 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java @@ -1,95 +1,99 @@ package io.prometheus.metrics.model.snapshots; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class PrometheusNamingTest { +class PrometheusNamingTest { @Test public void testSanitizeMetricName() { - Assert.assertEquals("_abc_def", prometheusName(sanitizeMetricName("0abc.def"))); - Assert.assertEquals("___ab__c0", prometheusName(sanitizeMetricName("___ab.:c0"))); - Assert.assertEquals("my_prefix_my_metric", sanitizeMetricName("my_prefix/my_metric")); - Assert.assertEquals("my_counter", prometheusName(sanitizeMetricName("my_counter_total"))); - Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); - Assert.assertEquals("jvm", sanitizeMetricName("jvm_info")); - Assert.assertEquals("jvm", sanitizeMetricName("jvm.info")); - Assert.assertEquals("a.b", sanitizeMetricName("a.b")); - Assert.assertEquals("total", sanitizeMetricName("_total")); - Assert.assertEquals("total", sanitizeMetricName("total")); + assertThat(prometheusName(sanitizeMetricName("0abc.def"))).isEqualTo("_abc_def"); + assertThat(prometheusName(sanitizeMetricName("___ab.:c0"))).isEqualTo("___ab__c0"); + assertThat(sanitizeMetricName("my_prefix/my_metric")).isEqualTo("my_prefix_my_metric"); + assertThat(prometheusName(sanitizeMetricName("my_counter_total"))).isEqualTo("my_counter"); + assertThat(sanitizeMetricName("jvm.info")).isEqualTo("jvm"); + assertThat(sanitizeMetricName("jvm_info")).isEqualTo("jvm"); + assertThat(sanitizeMetricName("jvm.info")).isEqualTo("jvm"); + assertThat(sanitizeMetricName("a.b")).isEqualTo("a.b"); + assertThat(sanitizeMetricName("_total")).isEqualTo("total"); + assertThat(sanitizeMetricName("total")).isEqualTo("total"); } @Test public void testSanitizeMetricNameWithUnit() { - Assert.assertEquals( - "_abc_def_" + Unit.RATIO, prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO))); - Assert.assertEquals( - "___ab__c0_" + Unit.RATIO, prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO))); - Assert.assertEquals( - "my_prefix_my_metric_" + Unit.RATIO, sanitizeMetricName("my_prefix/my_metric", Unit.RATIO)); - Assert.assertEquals( - "my_counter_" + Unit.RATIO, - prometheusName(sanitizeMetricName("my_counter_total", Unit.RATIO))); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm_info", Unit.RATIO)); - Assert.assertEquals("jvm_" + Unit.RATIO, sanitizeMetricName("jvm.info", Unit.RATIO)); - Assert.assertEquals("a.b_" + Unit.RATIO, sanitizeMetricName("a.b", Unit.RATIO)); - Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("_total", Unit.RATIO)); - Assert.assertEquals("total_" + Unit.RATIO, sanitizeMetricName("total", Unit.RATIO)); + assertThat(prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO))) + .isEqualTo("_abc_def_" + Unit.RATIO); + assertThat(prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO))) + .isEqualTo("___ab__c0_" + Unit.RATIO); + assertThat(sanitizeMetricName("my_prefix/my_metric", Unit.RATIO)) + .isEqualTo("my_prefix_my_metric_" + Unit.RATIO); + assertThat(prometheusName(sanitizeMetricName("my_counter_total", Unit.RATIO))) + .isEqualTo("my_counter_" + Unit.RATIO); + assertThat(sanitizeMetricName("jvm.info", Unit.RATIO)).isEqualTo("jvm_" + Unit.RATIO); + assertThat(sanitizeMetricName("jvm_info", Unit.RATIO)).isEqualTo("jvm_" + Unit.RATIO); + assertThat(sanitizeMetricName("jvm.info", Unit.RATIO)).isEqualTo("jvm_" + Unit.RATIO); + assertThat(sanitizeMetricName("a.b", Unit.RATIO)).isEqualTo("a.b_" + Unit.RATIO); + assertThat(sanitizeMetricName("_total", Unit.RATIO)).isEqualTo("total_" + Unit.RATIO); + assertThat(sanitizeMetricName("total", Unit.RATIO)).isEqualTo("total_" + Unit.RATIO); } @Test public void testSanitizeLabelName() { - Assert.assertEquals("_abc_def", prometheusName(sanitizeLabelName("0abc.def"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("__abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("___abc"))); - Assert.assertEquals("_abc", prometheusName(sanitizeLabelName("_.abc"))); - Assert.assertEquals("abc.def", sanitizeLabelName("abc.def")); - Assert.assertEquals("abc.def2", sanitizeLabelName("abc.def2")); + assertThat(prometheusName(sanitizeLabelName("0abc.def"))).isEqualTo("_abc_def"); + assertThat(prometheusName(sanitizeLabelName("_abc"))).isEqualTo("_abc"); + assertThat(prometheusName(sanitizeLabelName("__abc"))).isEqualTo("_abc"); + assertThat(prometheusName(sanitizeLabelName("___abc"))).isEqualTo("_abc"); + assertThat(prometheusName(sanitizeLabelName("_.abc"))).isEqualTo("_abc"); + assertThat(sanitizeLabelName("abc.def")).isEqualTo("abc.def"); + assertThat(sanitizeLabelName("abc.def2")).isEqualTo("abc.def2"); } @Test public void testValidateUnitName() { - Assert.assertNotNull(validateUnitName("secondstotal")); - Assert.assertNotNull(validateUnitName("total")); - Assert.assertNotNull(validateUnitName("seconds_total")); - Assert.assertNotNull(validateUnitName("_total")); - Assert.assertNotNull(validateUnitName("")); + assertThat(validateUnitName("secondstotal")).isNotNull(); + assertThat(validateUnitName("total")).isNotNull(); + assertThat(validateUnitName("seconds_total")).isNotNull(); + assertThat(validateUnitName("_total")).isNotNull(); + assertThat(validateUnitName("")).isNotNull(); - Assert.assertNull(validateUnitName("seconds")); - Assert.assertNull(validateUnitName("2")); + assertThat(validateUnitName("seconds")).isNull(); + assertThat(validateUnitName("2")).isNull(); } @Test public void testSanitizeUnitName() { - Assert.assertEquals("seconds", sanitizeUnitName("seconds")); - Assert.assertEquals("seconds", sanitizeUnitName("seconds_total")); - Assert.assertEquals("seconds", sanitizeUnitName("seconds_total_total")); - Assert.assertEquals("m_s", sanitizeUnitName("m/s")); - Assert.assertEquals("seconds", sanitizeUnitName("secondstotal")); - Assert.assertEquals("2", sanitizeUnitName("2")); + assertThat(sanitizeUnitName("seconds")).isEqualTo("seconds"); + assertThat(sanitizeUnitName("seconds_total")).isEqualTo("seconds"); + assertThat(sanitizeUnitName("seconds_total_total")).isEqualTo("seconds"); + assertThat(sanitizeUnitName("m/s")).isEqualTo("m_s"); + assertThat(sanitizeUnitName("secondstotal")).isEqualTo("seconds"); + assertThat(sanitizeUnitName("2")).isEqualTo("2"); } - @Test(expected = IllegalArgumentException.class) + @Test public void testInvalidUnitName1() { - sanitizeUnitName("total"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> sanitizeUnitName("total")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testInvalidUnitName2() { - sanitizeUnitName("_total"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> sanitizeUnitName("_total")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testInvalidUnitName3() { - sanitizeUnitName("%"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> sanitizeUnitName("%")); } - @Test(expected = IllegalArgumentException.class) + @Test public void testEmptyUnitName() { - sanitizeUnitName(""); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> sanitizeUnitName("")); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java index 0d66d5632..4179cf630 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/QuantilesTest.java @@ -1,40 +1,50 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; + import java.util.Iterator; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class QuantilesTest { +class QuantilesTest { @Test public void testSort() { Quantiles quantiles = Quantiles.builder().quantile(0.99, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); - Assert.assertEquals(3, quantiles.size()); - Assert.assertEquals(0.5, quantiles.get(0).getQuantile(), 0); - Assert.assertEquals(0.2, quantiles.get(0).getValue(), 0); - Assert.assertEquals(0.95, quantiles.get(1).getQuantile(), 0); - Assert.assertEquals(0.22, quantiles.get(1).getValue(), 0); - Assert.assertEquals(0.99, quantiles.get(2).getQuantile(), 0); - Assert.assertEquals(0.23, quantiles.get(2).getValue(), 0); + assertThat(quantiles.size()).isEqualTo(3); + assertThat(quantiles.get(0).getQuantile()).isCloseTo(0.5, offset(0.0)); + assertThat(quantiles.get(0).getValue()).isCloseTo(0.2, offset(0.0)); + assertThat(quantiles.get(1).getQuantile()).isCloseTo(0.95, offset(0.0)); + assertThat(quantiles.get(1).getValue()).isCloseTo(0.22, offset(0.0)); + assertThat(quantiles.get(2).getQuantile()).isCloseTo(0.99, offset(0.0)); + assertThat(quantiles.get(2).getValue()).isCloseTo(0.23, offset(0.0)); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testImmutable() { Quantiles quantiles = Quantiles.builder().quantile(0.99, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); Iterator iterator = quantiles.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } @Test public void testEmpty() { - Assert.assertEquals(0, Quantiles.EMPTY.size()); + assertThat(Quantiles.EMPTY.size()).isZero(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicate() { - Quantiles.builder().quantile(0.95, 0.23).quantile(0.5, 0.2).quantile(0.95, 0.22).build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + Quantiles.builder() + .quantile(0.95, 0.23) + .quantile(0.5, 0.2) + .quantile(0.95, 0.22) + .build()); } } 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 1a531b5fd..d8e8d33e4 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 org.junit.Assert; +import static org.assertj.core.api.Assertions.assertThat; -public class SnapshotTestUtil { +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()); + assertThat(snapshot.getMetadata().getName()).isEqualTo(name); + assertThat(snapshot.getMetadata().getHelp()).isEqualTo(help); if (unit != null) { - Assert.assertEquals(unit, snapshot.getMetadata().getUnit().toString()); + assertThat(snapshot.getMetadata().getUnit()).hasToString(unit); } else { - Assert.assertNull(snapshot.getMetadata().getUnit()); + assertThat(snapshot.getMetadata().getUnit()).isNull(); } } } 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 ccc159b30..cb3c70f8d 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,11 +1,13 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + import java.util.Iterator; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class StateSetSnapshotTest { +class StateSetSnapshotTest { @Test public void testCompleteGoodCase() { @@ -29,20 +31,21 @@ public void testCompleteGoodCase() { .build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "my_feature_flags", "Feature Flags", null); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); 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()); + assertThat((Iterable) data.getLabels()) + .isEqualTo(Labels.of("entity", "controller")); + assertThat(data.size()).isEqualTo(2); + assertThat(data.getName(0)).isEqualTo("feature1"); + assertThat(data.isTrue(0)).isTrue(); + assertThat(data.getName(1)).isEqualTo("feature2"); + assertThat(data.isTrue(1)).isFalse(); + assertThat(data.hasScrapeTimestamp()).isTrue(); + assertThat(data.getScrapeTimestampMillis()).isEqualTo(scrapeTimestamp); + assertThat(data.hasCreatedTimestamp()).isFalse(); } @Test @@ -54,21 +57,22 @@ public void testStateSetDataSorted() { .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)); + assertThat(data.size()).isEqualTo(4); + assertThat(data.getName(0)).isEqualTo("a"); + assertThat(data.isTrue(0)).isFalse(); + assertThat(data.getName(1)).isEqualTo("b"); + assertThat(data.isTrue(1)).isTrue(); + assertThat(data.getName(2)).isEqualTo("c"); + assertThat(data.isTrue(2)).isTrue(); + assertThat(data.getName(3)).isEqualTo("d"); + assertThat(data.isTrue(3)).isFalse(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testMustHaveState() { // Must have at least one state. - StateSetSnapshot.StateSetDataPointSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> StateSetSnapshot.StateSetDataPointSnapshot.builder().build()); } @Test @@ -79,16 +83,16 @@ public void testMinimal() { .dataPoint( StateSetSnapshot.StateSetDataPointSnapshot.builder().state("flag", true).build()) .build(); - Assert.assertEquals(1, snapshot.dataPoints.size()); + assertThat(snapshot.dataPoints.size()).isOne(); } @Test public void testEmpty() { StateSetSnapshot snapshot = StateSetSnapshot.builder().name("my_flag").build(); - Assert.assertEquals(0, snapshot.dataPoints.size()); + assertThat(snapshot.dataPoints).isEmpty(); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testDataImmutable() { StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder() @@ -98,19 +102,22 @@ public void testDataImmutable() { .build(); Iterator iterator = data.iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } - @Test(expected = IllegalArgumentException.class) + @Test public void testDuplicateState() { - StateSetSnapshot.StateSetDataPointSnapshot.builder() - .state("a", true) - .state("b", true) - .state("a", true) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + StateSetSnapshot.StateSetDataPointSnapshot.builder() + .state("a", true) + .state("b", true) + .state("a", true) + .build()); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testStateSetImmutable() { StateSetSnapshot snapshot = StateSetSnapshot.builder() @@ -129,17 +136,24 @@ public void testStateSetImmutable() { Iterator iterator = snapshot.getDataPoints().iterator(); iterator.next(); - iterator.remove(); + assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } - @Test(expected = IllegalArgumentException.class) + @Test public void testLabelsUnique() { - StateSetSnapshot.builder() - .name("flags") - .dataPoint( - StateSetSnapshot.StateSetDataPointSnapshot.builder().state("feature", true).build()) - .dataPoint( - StateSetSnapshot.StateSetDataPointSnapshot.builder().state("feature", true).build()) - .build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + 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/SummarySnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java index 4a4a2a355..a57b5f4e0 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SummarySnapshotTest.java @@ -1,10 +1,12 @@ package io.prometheus.metrics.model.snapshots; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.data.Offset.offset; + import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class SummarySnapshotTest { +class SummarySnapshotTest { @Test public void testCompleteGoodCase() { @@ -55,28 +57,28 @@ public void testCompleteGoodCase() { .build()) .build(); SnapshotTestUtil.assertMetadata(snapshot, "latency_seconds", "latency in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); SummarySnapshot.SummaryDataPointSnapshot data = snapshot.getDataPoints().get(0); - Assert.assertEquals(Labels.of("endpoint", "/"), data.getLabels()); - Assert.assertTrue(data.hasCount()); - Assert.assertEquals(1093, data.getCount()); - Assert.assertTrue(data.hasSum()); - Assert.assertEquals(218.6, data.getSum(), 0); - Assert.assertTrue(data.hasCreatedTimestamp()); - Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis()); - Assert.assertTrue(data.hasScrapeTimestamp()); - Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("endpoint", "/")); + assertThat(data.hasCount()).isTrue(); + assertThat(data.getCount()).isEqualTo(1093); + assertThat(data.hasSum()).isTrue(); + assertThat(data.getSum()).isCloseTo(218.6, offset(0.0)); + assertThat(data.hasCreatedTimestamp()).isTrue(); + assertThat(data.getCreatedTimestampMillis()).isEqualTo(createdTimestamp); + assertThat(data.hasScrapeTimestamp()).isTrue(); + assertThat(data.getScrapeTimestampMillis()).isEqualTo(scrapeTimestamp); Quantiles quantiles = data.getQuantiles(); - Assert.assertEquals(3, quantiles.size()); + assertThat(quantiles.size()).isEqualTo(3); // quantiles are tested in QuantilesTest already, skipping here. - Assert.assertEquals(2, data.getExemplars().size()); + assertThat(data.getExemplars().size()).isEqualTo(2); // exemplars are tested in ExemplarsTest already, skipping here. data = snapshot.getDataPoints().get(1); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - Assert.assertTrue(data.hasCount()); - Assert.assertTrue(data.hasSum()); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); + assertThat(data.hasCount()).isTrue(); + assertThat(data.hasSum()).isTrue(); } @Test @@ -87,25 +89,26 @@ public void testMinimal() { .dataPoint( SummarySnapshot.SummaryDataPointSnapshot.builder().count(10).sum(12.0).build()) .build(); - Assert.assertEquals(1, snapshot.getDataPoints().size()); - Assert.assertEquals(Labels.EMPTY, snapshot.getDataPoints().get(0).getLabels()); + assertThat(snapshot.getDataPoints()).hasSize(1); + assertThat((Iterable) snapshot.getDataPoints().get(0).getLabels()) + .isEqualTo(Labels.EMPTY); } @Test public void testEmptySnapshot() { SummarySnapshot snapshot = SummarySnapshot.builder().name("empty_summary").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).isEmpty(); } @Test public void testEmptyData() { SummarySnapshot.SummaryDataPointSnapshot data = SummarySnapshot.SummaryDataPointSnapshot.builder().build(); - Assert.assertEquals(0, data.getQuantiles().size()); - Assert.assertFalse(data.hasCount()); - Assert.assertFalse(data.hasSum()); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); - Assert.assertEquals(0, data.getExemplars().size()); + assertThat(data.getQuantiles().size()).isZero(); + assertThat(data.hasCount()).isFalse(); + assertThat(data.hasSum()).isFalse(); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); + assertThat(data.getExemplars().size()).isZero(); } } 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 1f70f6520..4585e7281 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 @@ -1,13 +1,15 @@ package io.prometheus.metrics.model.snapshots; -import org.junit.Assert; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -public class UnitTest { +import org.junit.jupiter.api.Test; - @Test(expected = IllegalArgumentException.class) +class UnitTest { + + @Test public void testEmpty() { - new Unit(" "); + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> new Unit(" ")); } @Test @@ -15,7 +17,7 @@ public void testEquals1() { Unit unit1 = Unit.BYTES; Unit unit2 = new Unit("bytes"); - Assert.assertEquals(unit2, unit1); + assertThat(unit1).isEqualTo(unit2); } @Test @@ -23,7 +25,7 @@ public void testEquals2() { Unit unit1 = new Unit("bytes "); Unit unit2 = new Unit("bytes"); - Assert.assertEquals(unit2, unit1); + assertThat(unit1).isEqualTo(unit2); } @Test @@ -31,7 +33,7 @@ public void testEquals3() { Unit unit1 = new Unit(" bytes"); Unit unit2 = new Unit("bytes"); - Assert.assertEquals(unit2, unit1); + assertThat(unit1).isEqualTo(unit2); } @Test @@ -39,6 +41,6 @@ public void testEquals4() { Unit unit1 = new Unit(" bytes "); Unit unit2 = new Unit("bytes"); - Assert.assertEquals(unit2, unit1); + assertThat(unit1).isEqualTo(unit2); } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java index cdb81c9dc..a8c266b07 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnknownSnapshotTest.java @@ -1,9 +1,12 @@ package io.prometheus.metrics.model.snapshots; -import org.junit.Assert; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.data.Offset.offset; -public class UnknownSnapshotTest { +import org.junit.jupiter.api.Test; + +class UnknownSnapshotTest { @Test public void testCompleteGoodCase() { @@ -33,13 +36,13 @@ public void testCompleteGoodCase() { .build(); SnapshotTestUtil.assertMetadata( snapshot, "my_unknown_seconds", "something in seconds", "seconds"); - Assert.assertEquals(2, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(2); UnknownSnapshot.UnknownDataPointSnapshot data = snapshot.getDataPoints().get(1); // env="prod" - Assert.assertEquals(Labels.of("env", "prod"), data.getLabels()); - Assert.assertEquals(0.3, data.getValue(), 0.0); - Assert.assertEquals(0.12, data.getExemplar().getValue(), 0.0); - Assert.assertFalse(data.hasCreatedTimestamp()); - Assert.assertFalse(data.hasScrapeTimestamp()); + assertThat((Iterable) data.getLabels()).isEqualTo(Labels.of("env", "prod")); + assertThat(data.getValue()).isCloseTo(0.3, offset(0.0)); + assertThat(data.getExemplar().getValue()).isCloseTo(0.12, offset(0.0)); + assertThat(data.hasCreatedTimestamp()).isFalse(); + assertThat(data.hasScrapeTimestamp()).isFalse(); } @Test @@ -49,23 +52,25 @@ public void testMinimal() { .name("test") .dataPoint(UnknownSnapshot.UnknownDataPointSnapshot.builder().value(1.0).build()) .build(); - Assert.assertEquals(1, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).hasSize(1); } @Test public void testEmpty() { UnknownSnapshot snapshot = UnknownSnapshot.builder().name("test").build(); - Assert.assertEquals(0, snapshot.getDataPoints().size()); + assertThat(snapshot.getDataPoints()).isEmpty(); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNameMissing() { - UnknownSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> UnknownSnapshot.builder().build()); } - @Test(expected = IllegalArgumentException.class) + @Test public void testValueMissing() { - UnknownSnapshot.UnknownDataPointSnapshot.builder().build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> UnknownSnapshot.UnknownDataPointSnapshot.builder().build()); } @Test @@ -75,13 +80,13 @@ public void testUnknownDataPointSnapshot() { UnknownSnapshot.UnknownDataPointSnapshot data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar); - Assert.assertEquals(1.0, data.getValue(), 0.1); - Assert.assertEquals(labels, data.getLabels()); - Assert.assertEquals(exemplar, data.getExemplar()); + assertThat(data.getValue()).isCloseTo(1.0, offset(0.1)); + assertThat((Iterable) data.getLabels()).isEqualTo(labels); + assertThat(data.getExemplar()).isEqualTo(exemplar); data = new UnknownSnapshot.UnknownDataPointSnapshot(1.0, labels, exemplar, 0L); - Assert.assertEquals(1.0, data.getValue(), 0.1); - Assert.assertEquals(labels, data.getLabels()); - Assert.assertEquals(exemplar, data.getExemplar()); + assertThat(data.getValue()).isCloseTo(1.0, offset(0.1)); + assertThat((Iterable) data.getLabels()).isEqualTo(labels); + assertThat(data.getExemplar()).isEqualTo(exemplar); } } diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index ba88815f7..0cc2e8cfc 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -55,12 +55,6 @@ - - junit - junit - 4.13.2 - test - io.prometheus prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java index 83e28d982..a678bed93 100644 --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.simpleclient.bridge; +import static org.assertj.core.api.Assertions.assertThat; + import io.prometheus.client.Collector; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Counter; @@ -18,16 +20,15 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class SimpleclientCollectorTest { +class SimpleclientCollectorTest { private CollectorRegistry origRegistry; private PrometheusRegistry newRegistry; - @Before + @BeforeEach public void setUp() { origRegistry = new CollectorRegistry(); newRegistry = new PrometheusRegistry(); @@ -46,14 +47,14 @@ public void testCounterComplete() throws IOException, InterruptedException { Thread.sleep(3); // make timestamps a bit different counter.labels("/hello", "500").incWithExemplar(2.4, "trace_id", "23446", "span_id", "bcdef"); - Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixTimestamps(sort(origOpenMetrics()))); } @Test public void testCounterMinimal() throws IOException { Counter.build().name("events").help("total number of events").register(origRegistry); - Assert.assertEquals(fixTimestamps(sort(origOpenMetrics())), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixTimestamps(sort(origOpenMetrics()))); } @Test @@ -69,7 +70,7 @@ public void testGaugeComplete() throws IOException, InterruptedException { Thread.sleep(3); gauge.labels("/dev/sda2").set(0.7); - Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(sort(origOpenMetrics())); } @Test @@ -82,7 +83,7 @@ public void testGaugeMinimal() throws IOException, InterruptedException { .register(origRegistry); gauge.set(22.3); - Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(sort(origOpenMetrics())); } @Test @@ -102,14 +103,14 @@ public void testHistogramComplete() throws IOException, InterruptedException { Thread.sleep(3); // make timestamps a bit different histogram.labels("500").observeWithExemplar(10000, "trace_id", "11", "span_id", "12"); - Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); } @Test public void testHistogramMinimal() throws IOException, InterruptedException { Histogram.build().name("request_latency").help("request latency").register(origRegistry); - Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); } @Test @@ -133,7 +134,7 @@ public void testSummaryComplete() throws IOException, InterruptedException { summary.labels("/", "500").observe(0.31); summary.labels("/", "500").observe(0.32); - Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); } @Test @@ -141,7 +142,7 @@ public void testSummaryMinimal() throws IOException, InterruptedException { Summary summary = Summary.build().name("request_size").help("request size").register(origRegistry); - Assert.assertEquals(fixCounts(fixTimestamps(sort(origOpenMetrics()))), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); } @Test @@ -156,7 +157,7 @@ public void testInfoComplete() throws IOException, InterruptedException { Thread.sleep(3); info.labels("dev").info("major_version", "13", "minor_version", "1"); - Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixBoolean(sort(origOpenMetrics()))); } @Test @@ -164,7 +165,7 @@ public void testInfoMinimal() throws IOException, InterruptedException { Info info = Info.build().name("jvm").help("JVM info").register(origRegistry); info.info("version", "17"); - Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixBoolean(sort(origOpenMetrics()))); } @Test @@ -187,7 +188,7 @@ public List collect() { }; origRegistry.register(stateSet); - Assert.assertEquals(fixBoolean(sort(origOpenMetrics())), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(fixBoolean(sort(origOpenMetrics()))); } @Test @@ -220,7 +221,7 @@ public List collect() { }; origRegistry.register(unknown); - Assert.assertEquals(sort(origOpenMetrics()), sort(newOpenMetrics())); + assertThat(sort(newOpenMetrics())).isEqualTo(sort(origOpenMetrics())); } private String fixBoolean(String s) { diff --git a/simpleclient-archive/simpleclient_graphite_bridge/pom.xml b/simpleclient-archive/simpleclient_graphite_bridge/pom.xml index e9f432cc1..babc6814b 100644 --- a/simpleclient-archive/simpleclient_graphite_bridge/pom.xml +++ b/simpleclient-archive/simpleclient_graphite_bridge/pom.xml @@ -39,12 +39,5 @@ simpleclient ${project.version} - - - junit - junit - 4.13.2 - test - diff --git a/simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java b/simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java index d0f00bc49..15eb7c60c 100644 --- a/simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java +++ b/simpleclient-archive/simpleclient_graphite_bridge/src/test/java/io/prometheus/client/bridge/GraphiteTest.java @@ -14,7 +14,7 @@ import java.net.ServerSocket; import java.net.Socket; -public class GraphiteTest { +class GraphiteTest { @Test public void testPush() throws Exception { // Create a metric. diff --git a/simpleclient-archive/simpleclient_hibernate/pom.xml b/simpleclient-archive/simpleclient_hibernate/pom.xml index ca99206a4..605d06989 100644 --- a/simpleclient-archive/simpleclient_hibernate/pom.xml +++ b/simpleclient-archive/simpleclient_hibernate/pom.xml @@ -33,7 +33,7 @@ - + io.prometheus simpleclient @@ -47,20 +47,5 @@ 6.1.0.Final provided - - - - junit - junit - 4.13.2 - test - - - org.mockito - mockito-core - 4.6.1 - test - - diff --git a/simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java b/simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java index 32f07f8f9..6ab9e2c42 100644 --- a/simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java +++ b/simpleclient-archive/simpleclient_hibernate/src/main/java/io/prometheus/client/hibernate/HibernateStatisticsCollector.java @@ -40,7 +40,7 @@ * * @author Christian Kaltepoth */ -public class HibernateStatisticsCollector extends Collector { +class HibernaTestatisticsCollector extends Collector { private static final List LABEL_NAMES = Collections.singletonList("unit"); diff --git a/simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java index b148ee108..b990988d4 100644 --- a/simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java +++ b/simpleclient-archive/simpleclient_hibernate/src/test/java/io/prometheus/client/hibernate/HibernateStatisticsCollectorTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -public class HibernateStatisticsCollectorTest { +class HibernateStatisticsCollectorTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @@ -240,4 +240,4 @@ private Double getSampleForQuery(String metric, String factory, String query) { ); } -} \ No newline at end of file +} diff --git a/simpleclient-archive/simpleclient_httpserver/pom.xml b/simpleclient-archive/simpleclient_httpserver/pom.xml index d34088965..1635375c0 100644 --- a/simpleclient-archive/simpleclient_httpserver/pom.xml +++ b/simpleclient-archive/simpleclient_httpserver/pom.xml @@ -44,18 +44,6 @@ ${project.version} - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - javax.xml.bind jaxb-api diff --git a/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java index aaddd5e22..466ede1d0 100644 --- a/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java +++ b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestDaemonFlags.java @@ -9,7 +9,7 @@ import static org.assertj.core.api.Java6Assertions.assertThat; -public class TestDaemonFlags { +class TestDaemonFlags { @Test public void testDefaultIsNotDaemon() throws IOException, ExecutionException, InterruptedException { diff --git a/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java index 2b18f4e82..7e012ca97 100644 --- a/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java +++ b/simpleclient-archive/simpleclient_httpserver/src/test/java/io/prometheus/client/exporter/TestHTTPServer.java @@ -35,7 +35,7 @@ import static org.assertj.core.api.Java6Assertions.assertThat; -public class TestHTTPServer { +class TestHTTPServer { CollectorRegistry registry; diff --git a/simpleclient-archive/simpleclient_jetty/pom.xml b/simpleclient-archive/simpleclient_jetty/pom.xml index 24aa35902..2d263c7d2 100644 --- a/simpleclient-archive/simpleclient_jetty/pom.xml +++ b/simpleclient-archive/simpleclient_jetty/pom.xml @@ -51,12 +51,6 @@ ${jetty.version} - - junit - junit - 4.13.2 - test - org.hamcrest hamcrest-all diff --git a/simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java index dcf6b8c7c..1686bcd2b 100644 --- a/simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java +++ b/simpleclient-archive/simpleclient_jetty/src/test/java/io/prometheus/client/jetty/JettyStatisticsCollectorTest.java @@ -19,7 +19,7 @@ import org.junit.Before; import org.junit.Test; -public class JettyStatisticsCollectorTest { +class JettyStatisticsCollectorTest { private final Server server = new Server(); private final ServerConnector connector = new ServerConnector(server); diff --git a/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml index c696d7236..f75003907 100644 --- a/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml @@ -47,12 +47,6 @@ 11.0.9 - - junit - junit - 4.13.2 - test - org.hamcrest hamcrest-all diff --git a/simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java b/simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java index 326a1c45c..23101a42c 100644 --- a/simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java +++ b/simpleclient-archive/simpleclient_jetty_jdk8/src/test/java/io/prometheus/client/jetty/QueuedThreadPoolStatisticsCollectorTest.java @@ -14,7 +14,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -public class QueuedThreadPoolStatisticsCollectorTest { +class QueuedThreadPoolStatisticsCollectorTest { private static final String[] LABEL_NAMES = {"unit"}; diff --git a/simpleclient-archive/simpleclient_log4j/pom.xml b/simpleclient-archive/simpleclient_log4j/pom.xml index bfe2be75a..3651fe107 100644 --- a/simpleclient-archive/simpleclient_log4j/pom.xml +++ b/simpleclient-archive/simpleclient_log4j/pom.xml @@ -50,19 +50,5 @@ 2.17.2 provided - - - junit - junit - 4.13.2 - test - - - - org.mockito - mockito-core - 4.6.1 - test - diff --git a/simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java index 39c50029c..7a6b2d282 100644 --- a/simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java +++ b/simpleclient-archive/simpleclient_log4j/src/test/java/io/prometheus/client/log4j/InstrumentedAppenderTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.Test; -public class InstrumentedAppenderTest { +class InstrumentedAppenderTest { private InstrumentedAppender appender; private LoggingEvent event; diff --git a/simpleclient-archive/simpleclient_log4j2/pom.xml b/simpleclient-archive/simpleclient_log4j2/pom.xml index c8afc9da1..909ecb220 100644 --- a/simpleclient-archive/simpleclient_log4j2/pom.xml +++ b/simpleclient-archive/simpleclient_log4j2/pom.xml @@ -44,19 +44,5 @@ 2.17.2 provided - - - junit - junit - 4.13.2 - test - - - - org.mockito - mockito-core - 4.6.1 - test - diff --git a/simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java index 08b91e6ce..74b4882a5 100644 --- a/simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java +++ b/simpleclient-archive/simpleclient_log4j2/src/test/java/io/prometheus/client/log4j2/InstrumentedAppenderTest.java @@ -12,7 +12,7 @@ import static org.apache.logging.log4j.Level.*; -public class InstrumentedAppenderTest { +class InstrumentedAppenderTest { private InstrumentedAppender appender; private LogEvent event; diff --git a/simpleclient-archive/simpleclient_logback/pom.xml b/simpleclient-archive/simpleclient_logback/pom.xml index 96f4fb34d..195aa19a8 100644 --- a/simpleclient-archive/simpleclient_logback/pom.xml +++ b/simpleclient-archive/simpleclient_logback/pom.xml @@ -43,20 +43,5 @@ logback-classic 1.2.11 - - - - junit - junit - 4.13.2 - test - - - - org.mockito - mockito-core - 4.6.1 - test - diff --git a/simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java b/simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java index af3bd1610..2534825b5 100644 --- a/simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java +++ b/simpleclient-archive/simpleclient_logback/src/test/java/io/prometheus/client/logback/InstrumentedAppenderTest.java @@ -11,7 +11,7 @@ import org.junit.Before; import org.junit.Test; -public class InstrumentedAppenderTest { +class InstrumentedAppenderTest { private CollectorRegistry registry; private InstrumentedAppender appender; private InstrumentedAppender defaultAppender; diff --git a/simpleclient-archive/simpleclient_servlet/pom.xml b/simpleclient-archive/simpleclient_servlet/pom.xml index 7f6b843de..402ab351c 100644 --- a/simpleclient-archive/simpleclient_servlet/pom.xml +++ b/simpleclient-archive/simpleclient_servlet/pom.xml @@ -59,30 +59,12 @@ provided - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - org.eclipse.jetty jetty-servlet 8.2.0.v20160908 test - - org.mockito - mockito-core - 4.6.1 - test - diff --git a/simpleclient-archive/simpleclient_servlet_common/pom.xml b/simpleclient-archive/simpleclient_servlet_common/pom.xml index 31d477e71..dd8f9fb6d 100644 --- a/simpleclient-archive/simpleclient_servlet_common/pom.xml +++ b/simpleclient-archive/simpleclient_servlet_common/pom.xml @@ -47,18 +47,5 @@ simpleclient_common ${project.version} - - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - diff --git a/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java index 3143a55d8..85e3054a2 100644 --- a/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java +++ b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/exporter/ExporterTest.java @@ -15,7 +15,7 @@ import static org.assertj.core.api.Java6Assertions.assertThat; import static org.assertj.core.api.Java6Assertions.fail; -public class ExporterTest { +class ExporterTest { private HttpServletRequestAdapter mockHttpServletRequest() { return mockHttpServletRequest(null, false); diff --git a/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java index 583b6f1c9..fd845fa20 100644 --- a/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java +++ b/simpleclient-archive/simpleclient_servlet_common/src/test/java/io/prometheus/client/servlet/common/filter/FilterTest.java @@ -17,7 +17,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -public class FilterTest { +class FilterTest { public static final String GET = "GET"; public static final String POST = "POST"; diff --git a/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml b/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml index 186dd0526..336a18a19 100644 --- a/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml +++ b/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml @@ -59,29 +59,11 @@ provided - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - org.eclipse.jetty jetty-servlet 11.0.9 test - - org.mockito - mockito-core - 4.6.1 - test - diff --git a/simpleclient-archive/simpleclient_spring_web/pom.xml b/simpleclient-archive/simpleclient_spring_web/pom.xml index 7591085fa..38440f814 100644 --- a/simpleclient-archive/simpleclient_spring_web/pom.xml +++ b/simpleclient-archive/simpleclient_spring_web/pom.xml @@ -85,12 +85,6 @@ - - junit - junit - 4.13.2 - test - org.springframework spring-test diff --git a/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java index 5de999178..c787338e3 100644 --- a/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java +++ b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerAppTest.java @@ -8,7 +8,7 @@ @ContextConfiguration @EnablePrometheusTiming -public class MethodTimerAppTest { +class MethodTimerAppTest { @Controller public static class MyController { @@ -23,4 +23,4 @@ public void waitJustAGoshDarnSecond() throws Exception { public static class MyConfig { } -} \ No newline at end of file +} diff --git a/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java index 2a1957f38..77fa5943d 100644 --- a/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java +++ b/simpleclient-archive/simpleclient_spring_web/src/test/java/io/prometheus/client/spring/web/MethodTimerTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -public class MethodTimerTest { +class MethodTimerTest { private interface Timeable { void timeMe() throws Exception; } diff --git a/simpleclient-archive/simpleclient_vertx/pom.xml b/simpleclient-archive/simpleclient_vertx/pom.xml index 2a91f20c8..5b8180d25 100644 --- a/simpleclient-archive/simpleclient_vertx/pom.xml +++ b/simpleclient-archive/simpleclient_vertx/pom.xml @@ -53,18 +53,5 @@ 3.9.13 provided - - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - diff --git a/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java b/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java index d4d51a5fc..02b7ec42a 100644 --- a/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java +++ b/simpleclient-archive/simpleclient_vertx/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class MetricsHandlerTest { +class MetricsHandlerTest { private static Vertx vertx; private static Integer port; diff --git a/simpleclient-archive/simpleclient_vertx4/pom.xml b/simpleclient-archive/simpleclient_vertx4/pom.xml index 5e365bd2a..2374cad9f 100644 --- a/simpleclient-archive/simpleclient_vertx4/pom.xml +++ b/simpleclient-archive/simpleclient_vertx4/pom.xml @@ -53,18 +53,5 @@ 4.3.1 provided - - - junit - junit - 4.13.2 - test - - - org.assertj - assertj-core - 3.23.1 - test - diff --git a/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java b/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java index 6e71b55c6..889877e2c 100644 --- a/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java +++ b/simpleclient-archive/simpleclient_vertx4/src/test/java/io/prometheus/client/vertx/MetricsHandlerTest.java @@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class MetricsHandlerTest { +class MetricsHandlerTest { private static Vertx vertx; private static Integer port; From c8562166be8746925228064f96a0a1bfd61152e1 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 7 Oct 2024 16:11:40 +0200 Subject: [PATCH 391/980] update Wrapper, dependabot (#1097) * update maven wrapper Signed-off-by: Gregor Zeitlinger * update dependabot Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/dependabot.yml | 27 +- .mvn/wrapper/MavenWrapperDownloader.java | 117 ------ .mvn/wrapper/maven-wrapper.jar | Bin 50710 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 21 +- mvnw | 451 ++++++++++------------- mvnw.cmd | 281 +++++++------- 6 files changed, 348 insertions(+), 549 deletions(-) delete mode 100644 .mvn/wrapper/MavenWrapperDownloader.java delete mode 100644 .mvn/wrapper/maven-wrapper.jar diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e6d0d3adc..27283d4ae 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,28 +5,11 @@ updates: schedule: interval: weekly - package-ecosystem: maven - open-pull-requests-limit: 1 # Limit to 1 open PR at a time until https://github.com/dependabot/dependabot-core/issues/10415 is fixed # excluding simpleclient_archive from the update is not possible, only includes are supported - directories: - - prometheus-metrics-bom - - prometheus-metrics-core - - prometheus-metrics-config - - prometheus-metrics-model - - prometheus-metrics-tracer - - prometheus-metrics-exposition-formats - - prometheus-metrics-exporter-common - - prometheus-metrics-exporter-servlet-jakarta - - prometheus-metrics-exporter-servlet-javax - - prometheus-metrics-exporter-httpserver - - prometheus-metrics-exporter-opentelemetry - - prometheus-metrics-exporter-pushgateway - - prometheus-metrics-instrumentation-caffeine - - prometheus-metrics-instrumentation-jvm - - prometheus-metrics-instrumentation-dropwizard5 - - prometheus-metrics-instrumentation-guava - - prometheus-metrics-simpleclient-bridge - - examples - - benchmarks - - integration-tests + # when we use includes, we run into https://github.com/dependabot/dependabot-core/issues/10415 - + # even if we limit to 1 PR at a time + # therefore we just ignore the simpleclient_archive update for now + # if this becomes a problem, we can move to renovate + directory: "/" schedule: interval: daily diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index b901097f2..000000000 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50710 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 EfAhh=DF6Tf diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index ffdc10e59..d58dfb70b 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,19 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/mvnw b/mvnw index 41c0f0c23..19529ddf8 100755 --- a/mvnw +++ b/mvnw @@ -19,292 +19,241 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.3.2 # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac -fi +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 fi fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" +} - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" done + printf %x\\n $h +} - saveddir=`pwd` +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - M2_HOME=`dirname "$PRG"`/.. +die() { + printf %s\\n "$1" >&2 + exit 1 +} - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" fi -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; fi -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 86115719e..249bdf382 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,3 +1,4 @@ +<# : batch portion @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @@ -18,165 +19,131 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir +@REM Apache Maven Wrapper startup batch script, version 3.3.2 @REM @REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output @REM ---------------------------------------------------------------------------- -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) ) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" From a392b0639a0cf11e84d00d2e434e9e27819edad7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:51:52 +0200 Subject: [PATCH 392/980] Bump org.apache.maven.plugins:maven-site-plugin from 3.3 to 3.20.0 (#1118) Bumps [org.apache.maven.plugins:maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.3 to 3.20.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.3...maven-site-plugin-3.20.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 75f31709f..66459c13b 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,7 @@ maven-site-plugin - 3.3 + 3.20.0 From 082d1a8a15b2912532745356e3b184807d58097c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:01:00 +0200 Subject: [PATCH 393/980] Bump org.apache.maven.plugins:maven-shade-plugin from 3.2.4 to 3.6.0 (#1116) Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.2.4 to 3.6.0. - [Release notes](https://github.com/apache/maven-shade-plugin/releases) - [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.2.4...maven-shade-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-shade-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 66459c13b..28a8aeebd 100644 --- a/pom.xml +++ b/pom.xml @@ -155,7 +155,7 @@ maven-shade-plugin - 3.2.4 + 3.6.0 maven-failsafe-plugin From a8b793ba26408fb4203abfad1398611a39ca1747 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:04:48 +0200 Subject: [PATCH 394/980] Bump org.apache.maven.plugins:maven-deploy-plugin from 2.7 to 3.1.3 (#1115) Bumps [org.apache.maven.plugins:maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 2.7 to 3.1.3. - [Release notes](https://github.com/apache/maven-deploy-plugin/releases) - [Commits](https://github.com/apache/maven-deploy-plugin/compare/maven-deploy-plugin-2.7...maven-deploy-plugin-3.1.3) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-deploy-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 28a8aeebd..80731c204 100644 --- a/pom.xml +++ b/pom.xml @@ -142,7 +142,7 @@ maven-deploy-plugin - 2.7 + 3.1.3 maven-clean-plugin From 2c3e258f42b11dbe462ab9e446c9e8acffc37894 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:11:43 +0200 Subject: [PATCH 395/980] Bump org.mockito:mockito-core from 5.12.0 to 5.14.1 (#1114) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.12.0 to 5.14.1. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.12.0...v5.14.1) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 80731c204..58ecae430 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,7 @@ org.mockito mockito-core - 5.12.0 + 5.14.1 test From b6e58656074e28147200c70708db6c8706d3b7ac Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 7 Oct 2024 17:21:05 +0200 Subject: [PATCH 396/980] Junit cleanup (#1119) * exclude hamcrest Signed-off-by: Gregor Zeitlinger * simplify assertj Signed-off-by: Gregor Zeitlinger * simplify assertj Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- integration-tests/it-common/pom.xml | 8 --- .../it-exporter/it-exporter-test/pom.xml | 5 -- integration-tests/it-pushgateway/pom.xml | 6 +- .../metrics/it/pushgateway/PushGatewayIT.java | 11 ++- integration-tests/pom.xml | 27 ++++--- .../metrics/core/metrics/HistogramTest.java | 4 +- .../core/metrics/StatefulMetricTest.java | 7 +- .../metrics/core/metrics/SummaryTest.java | 8 +-- .../pom.xml | 71 ++++++++++--------- .../caffeine/CacheMetricsCollectorTest.java | 3 +- .../dropwizard5/DropwizardExportsTest.java | 12 ++-- .../guava/CacheMetricsCollectorTest.java | 3 +- .../JvmMemoryPoolAllocationMetricsTest.java | 15 ++-- .../jvm/JvmThreadsMetricsTest.java | 3 +- .../ClassicHistogramBucketsTest.java | 7 +- .../model/snapshots/CounterSnapshotTest.java | 11 ++- .../metrics/model/snapshots/ExemplarTest.java | 5 +- .../model/snapshots/ExemplarsTest.java | 17 +++-- .../model/snapshots/GaugeSnapshotTest.java | 11 ++- .../snapshots/HistogramSnapshotTest.java | 11 ++- .../model/snapshots/QuantilesTest.java | 13 ++-- .../model/snapshots/SummarySnapshotTest.java | 3 +- .../model/snapshots/UnknownSnapshotTest.java | 4 +- 23 files changed, 122 insertions(+), 143 deletions(-) diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 195a10caa..0cf030857 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -24,14 +24,6 @@ - - - org.testcontainers - testcontainers - test - - - diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 5135e35e1..0fe5ccbdd 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -42,11 +42,6 @@ prometheus-metrics-exposition-formats ${project.version} - - org.testcontainers - testcontainers - test - commons-io commons-io diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 1956f1dad..d10f34398 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -47,11 +47,7 @@ prometheus-metrics-exporter-pushgateway ${project.version} - - org.testcontainers - testcontainers - test - + io.prometheus it-common diff --git a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java index cf11671f3..beb83d7d9 100644 --- a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java +++ b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.data.Offset.offset; import com.jayway.jsonpath.Criteria; import com.jayway.jsonpath.Filter; @@ -180,13 +179,13 @@ public void testProtobuf() throws IOException, InterruptedException { private void assertMetrics() throws IOException, InterruptedException { double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app"); - assertThat(value).isCloseTo(0.5, offset(0.0)); + assertThat(value).isEqualTo(0.5); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512"); - assertThat(value).isCloseTo(0.0, offset(0.0)); + assertThat(value).isEqualTo(0.0); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024"); - assertThat(value).isCloseTo(2.0, offset(0.0)); + assertThat(value).isEqualTo(2.0); value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf"); - assertThat(value).isCloseTo(3.0, offset(0.0)); + assertThat(value).isEqualTo(3.0); } private double getValue(String name, String... labels) throws IOException, InterruptedException { @@ -204,7 +203,7 @@ private double getValue(String name, String... labels) throws IOException, Inter private void assertNativeHistogram() throws IOException, InterruptedException { double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app"); - assertThat(count).isCloseTo(3, offset(0.0)); + assertThat(count).isEqualTo(3); } private double getNativeHistogramCount(String name, String job) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 2ed77b95d..dfc366b07 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -49,14 +50,18 @@ - - - - org.testcontainers - testcontainers - 1.19.8 - test - - - + + + org.testcontainers + junit-jupiter + 1.20.2 + test + + + org.hamcrest + hamcrest-core + + + + diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 1eb1121ad..ca484bf47 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1152,7 +1152,7 @@ private void assertExemplar(Histogram histogram, double value, String... labels) assertThat(exemplar) .as("No exemplar found in bucket [" + lowerBound + ", " + upperBound + "]") .isNotNull(); - assertThat(exemplar.getValue()).isCloseTo(value, offset(0.0)); + assertThat(exemplar.getValue()).isEqualTo(value); assertThat(exemplar.getLabels().size()) .as("" + exemplar.getLabels()) .isEqualTo(labels.length / 2); @@ -1354,7 +1354,7 @@ public void testNoLabelsDefaultZeroValue() { Histogram noLabels = Histogram.builder().name("test").build(); assertThat(getBucket(noLabels, 0.005).getCount()).isZero(); assertThat(getData(noLabels).getCount()).isZero(); - assertThat(getData(noLabels).getSum()).isCloseTo(0.0, offset(0.0)); + assertThat(getData(noLabels).getSum()).isEqualTo(0.0); } private ClassicHistogramBucket getBucket(Histogram histogram, double le, String... labels) { diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index d05cf145a..1120b06a3 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -1,7 +1,6 @@ package io.prometheus.metrics.core.metrics; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.data.Offset.offset; import java.lang.reflect.Field; import java.util.Map; @@ -55,17 +54,17 @@ public void testClearNoLabels() { Counter counter = Counter.builder().name("test").build(); counter.inc(); assertThat(counter.collect().getDataPoints()).hasSize(1); - assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isEqualTo(1.0); counter.clear(); // No labels is always present, but as no value has been observed after clear() the value should // be 0.0 assertThat(counter.collect().getDataPoints()).hasSize(1); - assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(0.0, offset(0.0)); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isEqualTo(0.0); // Making inc() works correctly after clear() counter.inc(); assertThat(counter.collect().getDataPoints()).hasSize(1); - assertThat(counter.collect().getDataPoints().get(0).getValue()).isCloseTo(1.0, offset(0.0)); + assertThat(counter.collect().getDataPoints().get(0).getValue()).isEqualTo(1.0); } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java index dbabb1a93..b369ed8fb 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java @@ -123,14 +123,12 @@ public void testMaxAge() throws InterruptedException { .help("help") .register(registry); summary.observe(8.0); - assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) - .isCloseTo(8.0, offset(0.0)); // From bucket 1. + assertThat(getQuantile(summary, 0.99, Labels.EMPTY)).isEqualTo(8.0); // From bucket 1. Thread.sleep(600); - assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) - .isCloseTo(8.0, offset(0.0)); // From bucket 2. + assertThat(getQuantile(summary, 0.99, Labels.EMPTY)).isEqualTo(8.0); // From bucket 2. Thread.sleep(600); assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) - .isCloseTo(Double.NaN, offset(0.0)); // Bucket 1 again, now it is empty. + .isEqualTo(Double.NaN); // Bucket 1 again, now it is empty. } @Test diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 0247be420..89cc01221 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -56,6 +57,12 @@ wiremock 3.5.4 test + + + org.hamcrest + hamcrest-core + + org.awaitility @@ -88,37 +95,37 @@ - - org.apache.maven.plugins - maven-dependency-plugin - 3.6.0 - - - copy - package - - copy - - - - - - - io.opentelemetry - opentelemetry-api - ${otel.version} - ${project.basedir}/src/main/resources/lib/ - - - io.opentelemetry - opentelemetry-context - ${otel.version} - ${project.basedir}/src/main/resources/lib/ - - - - - + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.0 + + + copy + package + + copy + + + + + + + io.opentelemetry + opentelemetry-api + ${otel.version} + ${project.basedir}/src/main/resources/lib/ + + + io.opentelemetry + opentelemetry-context + ${otel.version} + ${project.basedir}/src/main/resources/lib/ + + + + + - - io.prometheus - prometheus-metrics-shaded-opentelemetry - ${prometheus.metrics.shaded.dependencies.version} - - diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 147ae67ab..86d58ca30 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -18,7 +18,6 @@ - 1.42.1 io.prometheus.metrics.exporter.opentelemetry @@ -29,10 +28,19 @@ ${project.version} - io.prometheus - prometheus-metrics-shaded-opentelemetry - 1.3.1 - + io.opentelemetry + opentelemetry-api + ${otel.version} + + + io.opentelemetry + opentelemetry-sdk + ${otel.version} + + + io.opentelemetry + opentelemetry-exporter-otlp + ${otel.version} @@ -80,41 +88,28 @@ - org.apache.maven.plugins - maven-dependency-plugin + org.codehaus.mojo + build-helper-maven-plugin 3.6.0 - copy - package + regex-property - copy + regex-property + + otel.string-version + ${otel.version} + \. + _ + true + - - - - io.opentelemetry - opentelemetry-api - ${otel.version} - ${project.basedir}/src/main/resources/lib/ - - - io.opentelemetry - opentelemetry-context - ${otel.version} - ${project.basedir}/src/main/resources/lib/ - - - - - diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index fb674e351..c462a9d59 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -1,17 +1,17 @@ package io.prometheus.metrics.exporter.opentelemetry; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; +import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; +import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.MetricExporter; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.PeriodicMetricReader; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; import java.time.Duration; import java.util.HashMap; import java.util.Map; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java index fae9a2984..a8c43e7f9 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import java.util.Properties; class PrometheusInstrumentationScope { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 8d3fb2469..4b8b5591f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -1,5 +1,12 @@ package io.prometheus.metrics.exporter.opentelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.CollectionRegistration; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.resources.ResourceBuilder; import io.prometheus.metrics.exporter.opentelemetry.otelmodel.MetricDataFactory; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.CounterSnapshot; @@ -12,13 +19,6 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.export.CollectionRegistration; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.ResourceBuilder; import java.util.ArrayList; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java index 12b7c7acd..043635977 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/DoublePointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.DoublePointData; import java.util.List; class DoublePointDataImpl extends PointDataImpl implements DoublePointData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java index 798e9b5df..3ec73c21d 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramBucketsImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java index 3c5a893e2..70be47b82 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ExponentialHistogramPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; import java.util.List; public class ExponentialHistogramPointDataImpl extends PointDataImpl diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java index 19b141b04..22b98850b 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/HistogramPointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; import java.util.List; public class HistogramPointDataImpl extends PointDataImpl implements HistogramPointData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 95cb59546..a09490cc6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -1,5 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; @@ -7,9 +10,6 @@ import io.prometheus.metrics.model.snapshots.StateSetSnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; public class MetricDataFactory { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java index d1ba082e5..bf4b8e4d7 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PointDataImpl.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.PointData; import java.util.List; abstract class PointDataImpl implements PointData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index 3434dc467..fc31e6333 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -1,11 +1,11 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.HistogramData; +import io.opentelemetry.sdk.metrics.data.HistogramPointData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.HistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.ArrayList; import java.util.Collection; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java index f730fb97d..e44ce901c 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusCounter.java @@ -1,10 +1,10 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.SumData; import io.prometheus.metrics.model.snapshots.CounterSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index 7e09a483e..64b82bd8b 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -1,16 +1,16 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.metrics.data.Data; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.PointData; +import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import io.prometheus.metrics.model.snapshots.*; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.AttributesBuilder; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.SpanContext; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.TraceFlags; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.trace.TraceState; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.Data; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.PointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.internal.data.ImmutableDoubleExemplarData; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java index 872d569e6..ecdc7ab75 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusGauge.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.GaugeData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index eb5ae48f6..33e4c158d 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -1,10 +1,10 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.SumData; import io.prometheus.metrics.model.snapshots.InfoSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import java.util.Collection; import java.util.Collections; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java index 5d86000b8..4995b98d6 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -1,13 +1,13 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.SumData; +import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.model.snapshots.MetricMetadata; import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.common.InstrumentationScopeInfo; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.resources.Resource; class PrometheusMetricData> implements MetricData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java index eb2a6555e..c452ec1ad 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusNativeHistogram.java @@ -1,12 +1,12 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramBuckets; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramData; +import io.opentelemetry.sdk.metrics.data.ExponentialHistogramPointData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramBuckets; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ExponentialHistogramPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; import java.util.Objects; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java index 68fec8dd9..b0bb39841 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java @@ -1,11 +1,11 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.AggregationTemporality; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.SumData; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.StateSetSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.AggregationTemporality; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SumData; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java index 709b819af..f1a81c83f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusSummary.java @@ -1,10 +1,10 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.MetricDataType; +import io.opentelemetry.sdk.metrics.data.SummaryData; +import io.opentelemetry.sdk.metrics.data.SummaryPointData; import io.prometheus.metrics.model.snapshots.Quantile; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java index 39c8f508f..d52ea0942 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusUnknown.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import io.opentelemetry.sdk.metrics.data.DoublePointData; +import io.opentelemetry.sdk.metrics.data.GaugeData; +import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.prometheus.metrics.model.snapshots.UnknownSnapshot; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoublePointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.GaugeData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.MetricDataType; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java index eab7da588..baa0ea782 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/SummaryPointDataImpl.java @@ -1,9 +1,9 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.api.common.Attributes; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.DoubleExemplarData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.SummaryPointData; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ValueAtQuantile; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.metrics.data.DoubleExemplarData; +import io.opentelemetry.sdk.metrics.data.SummaryPointData; +import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; import java.util.ArrayList; import java.util.List; diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java index 13b39d3aa..1b6363a05 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/ValueAtQuantileImpl.java @@ -1,6 +1,6 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; -import io.prometheus.metrics.shaded.io_opentelemetry_1_38_0.sdk.metrics.data.ValueAtQuantile; +import io.opentelemetry.sdk.metrics.data.ValueAtQuantile; public class ValueAtQuantileImpl implements ValueAtQuantile { diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml index 0f1e588ae..1fb820cc3 100644 --- a/prometheus-metrics-shaded-dependencies/pom.xml +++ b/prometheus-metrics-shaded-dependencies/pom.xml @@ -17,7 +17,6 @@ - prometheus-metrics-shaded-opentelemetry prometheus-metrics-shaded-protobuf diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml deleted file mode 100644 index cce47a5b3..000000000 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/pom.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - 4.0.0 - - - io.prometheus - prometheus-metrics-shaded-dependencies - 1.4.0-SNAPSHOT - - - prometheus-metrics-shaded-opentelemetry - - Shaded OpenTelemetry - - Shaded (reolocated to another package) dependencies for the OpenTelemetry exporter module. - - - - 1.42.1 - 1_42_1 - - - - - io.opentelemetry - opentelemetry-api - ${otel.version} - - - io.opentelemetry - opentelemetry-sdk - ${otel.version} - - - io.opentelemetry - opentelemetry-exporter-otlp - ${otel.version} - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - - - io.opentelemetry - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string} - - - okhttp3 - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.okhttp3 - - - kotlin - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.kotlin - - - org.intellij - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.org.intellij - - - org.jetbrains - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.org.jetbrains - - - okio - io.prometheus.metrics.shaded.io_opentelemetry_${otel.version.string}.okio - - - - - - - - - *:* - - META-INF/maven/org.jctools/** - META-INF/maven/org.jetbrains/** - META-INF/versions/** - META-INF/native-image/** - META-INF/proguard/** - META-INF/*.kotlin_module - META-INF/MANIFEST.MF - - - - - - - - - - diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java deleted file mode 100644 index ca831e691..000000000 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/src/main/java/io/prometheus/metrics/shaded/io_opentelemetry/PrometheusMetricsShadedOpenTelemetry.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.prometheus.metrics.shaded.io_opentelemetry; - -/** - * This module does not need any source code, however, in order to publish it to Maven central it - * needs JavaDoc. - * - *

      I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. - */ -public class PrometheusMetricsShadedOpenTelemetry {} diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-opentelemetry/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index bd44b18bd..68e169524 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -21,7 +21,7 @@ io.opentelemetry opentelemetry-api - 1.42.1 + ${otel.version} From cdcf2d27959dea01c2c7ac31d00ddf44f58b9c59 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 9 Oct 2024 14:26:45 +0200 Subject: [PATCH 407/980] update benchmarks (#1129) Signed-off-by: Gregor Zeitlinger --- .../metrics/benchmarks/CounterBenchmark.java | 23 ++++++++++--------- .../benchmarks/HistogramBenchmark.java | 12 +++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index 6730e1bab..8ccf6a40d 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -21,17 +21,18 @@ * Results on a machine with dedicated 8 vCPU cores: * *

      - * Benchmark                                                                  Mode  Cnt      Score     Error  Units
      - * i.p.metrics.benchmarks.CounterBenchmark.codahaleIncNoLabels               thrpt   25  30978.055 ± 424.088  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryAdd                  thrpt   25  12682.744 ± 162.425  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryInc                  thrpt   25  14434.710 ±  99.809  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.openTelemetryIncNoLabels          thrpt   25  16634.416 ±  13.098  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.prometheusAdd                     thrpt   25  37317.024 ± 283.064  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.prometheusInc                     thrpt   25  39436.278 ± 458.583  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.prometheusNoLabelsInc             thrpt   25  34752.910 ± 293.979  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.simpleclientAdd                   thrpt   25   9520.592 ± 245.787  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.simpleclientInc                   thrpt   25   9057.637 ±  67.761  ops/s
      - * i.p.metrics.benchmarks.CounterBenchmark.simpleclientNoLabelsInc           thrpt   25   8993.471 ±  49.581  ops/s
      + *
      + * Benchmark                                     Mode  Cnt      Score     Error  Units
      + * CounterBenchmark.codahaleIncNoLabels         thrpt   25  25761.677 ± 122.947  ops/s
      + * CounterBenchmark.openTelemetryAdd            thrpt   25    545.026 ±  33.913  ops/s
      + * CounterBenchmark.openTelemetryInc            thrpt   25    550.577 ±  45.415  ops/s
      + * CounterBenchmark.openTelemetryIncNoLabels    thrpt   25    527.638 ±  32.020  ops/s
      + * CounterBenchmark.prometheusAdd               thrpt   25  20341.474 ±  40.973  ops/s
      + * CounterBenchmark.prometheusInc               thrpt   25  26414.616 ±  96.666  ops/s
      + * CounterBenchmark.prometheusNoLabelsInc       thrpt   25  26177.676 ± 120.342  ops/s
      + * CounterBenchmark.simpleclientAdd             thrpt   25   5503.867 ± 161.313  ops/s
      + * CounterBenchmark.simpleclientInc             thrpt   25   5568.125 ±  53.291  ops/s
      + * CounterBenchmark.simpleclientNoLabelsInc     thrpt   25   5394.692 ± 130.531  ops/s
        * 
      * * Prometheus counters are faster than counters of other libraries. For example, incrementing a diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java index 07b5e8445..1bebec573 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java @@ -20,12 +20,12 @@ * Results on a machine with dedicated 8 vCPU cores: * *
      - * Benchmark                                                                  Mode  Cnt      Score     Error  Units
      - * i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryClassic            thrpt   25   1908.715 ± 114.050  ops/s
      - * i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryExponential        thrpt   25   1009.785 ±  12.965  ops/s
      - * i.p.metrics.benchmarks.HistogramBenchmark.prometheusClassic               thrpt   25   6451.533 ± 326.265  ops/s
      - * i.p.metrics.benchmarks.HistogramBenchmark.prometheusNative                thrpt   25   3372.789 ± 339.328  ops/s
      - * i.p.metrics.benchmarks.HistogramBenchmark.simpleclient                    thrpt   25   6488.252 ±  96.737  ops/s
      + * Benchmark                                     Mode  Cnt      Score     Error  Units
      + * HistogramBenchmark.openTelemetryClassic      thrpt   25    258.660 ±   6.736  ops/s
      + * HistogramBenchmark.openTelemetryExponential  thrpt   25    210.963 ±  11.288  ops/s
      + * HistogramBenchmark.prometheusClassic         thrpt   25   1528.871 ±  43.598  ops/s
      + * HistogramBenchmark.prometheusNative          thrpt   25   1282.643 ± 110.210  ops/s
      + * HistogramBenchmark.simpleclient              thrpt   25   3376.016 ± 173.545  ops/s
        * 
      * * The simpleclient (i.e. client_java version 0.16.0 and older) histograms perform about the same as From c9bb30bd361870ff412c1d817c41f573e457670e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 9 Oct 2024 14:30:32 +0200 Subject: [PATCH 408/980] include shaded protobuf directly (#1063) * include shaded protobuf directly Signed-off-by: Gregor Zeitlinger * include shaded protobuf directly Signed-off-by: Gregor Zeitlinger  Conflicts:  prometheus-metrics-shaded-dependencies/pom.xml * remove shaded deps Signed-off-by: Gregor Zeitlinger * format Signed-off-by: Gregor Zeitlinger * fix shading Signed-off-by: Gregor Zeitlinger * fix shading Signed-off-by: Gregor Zeitlinger * fix shading Signed-off-by: Gregor Zeitlinger * re-enable shading Signed-off-by: Gregor Zeitlinger * re-enable shading Signed-off-by: Gregor Zeitlinger * only build proto on CI Signed-off-by: Gregor Zeitlinger * only build proto on CI Signed-off-by: Gregor Zeitlinger * update protobuf Signed-off-by: Gregor Zeitlinger * update protobuf Signed-off-by: Gregor Zeitlinger * update protobuf Signed-off-by: Gregor Zeitlinger * update protobuf Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/workflows/build.yml | 12 +- .github/workflows/github-pages.yaml | 22 +- MAINTAINER_NOTES.md | 4 + .../metrics/it/exporter/test/ExporterIT.java | 2 +- pom.xml | 1 - prometheus-metrics-bom/pom.xml | 12 - prometheus-metrics-core/pom.xml | 3 +- .../metrics/core/metrics/CounterTest.java | 4 +- .../metrics/core/metrics/HistogramTest.java | 4 +- .../metrics/core/metrics/InfoTest.java | 4 +- .../generate-protobuf.sh | 34 +- prometheus-metrics-exposition-formats/pom.xml | 100 +- .../src/main/.gitignore | 1 + .../Metrics.java | 4404 ++++++++--------- .../PrometheusProtobufWriter.java | 4 +- .../expositionformats/ProtobufUtil.java | 2 +- .../src/main/protobuf/metrics.proto | 157 - .../ExpositionFormatsTest.java | 4 +- .../pom.xml | 23 - .../pom.xml | 75 - .../PrometheusMetricsShadedProtobuf.java | 9 - .../version-rules.xml | 6 - 22 files changed, 2114 insertions(+), 2773 deletions(-) create mode 100644 prometheus-metrics-exposition-formats/src/main/.gitignore rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_3_25_3 => com_google_protobuf_4_28_2}/Metrics.java (71%) delete mode 100644 prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto delete mode 100644 prometheus-metrics-shaded-dependencies/pom.xml delete mode 100644 prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml delete mode 100644 prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java delete mode 100644 prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2500b8df..0ac4d429e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,11 +17,15 @@ jobs: java-version: 17 distribution: temurin cache: 'maven' - - name: Shaded dependencies - run: | - cd prometheus-metrics-shaded-dependencies - ../mvnw clean install + - name: Install Protoc + run: | + VERSION=28.2 + curl -sL -o protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v$VERSION/protoc-$VERSION-linux-x86_64.zip + sudo unzip protoc.zip -d /usr/local - name: Run the Maven verify phase + env: + PROTO_GENERATION: true + REQUIRE_PROTO_UP_TO_DATE: true run: | ./mvnw clean install ./mvnw javadoc:javadoc diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index e7a17ff36..d78e6d4a3 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -34,20 +34,14 @@ jobs: HUGO_VERSION: 0.115.4 JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 steps: - - name: Install OpenJDK 17 - run: sudo apt-get -q install -y openjdk-17-jdk - - name: Make 17 the default java version - run: sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java - - name: Make 17 the default javadoc version - run: sudo update-alternatives --set javadoc /usr/lib/jvm/java-17-openjdk-amd64/bin/javadoc - - name: Print java and javadoc versions - run: | - echo 'java --version' && \ - java --version && \ - echo 'javadoc --version' && \ - javadoc --version && \ - echo 'echo $JAVA_HOME' && \ - echo $JAVA_HOME + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: 'maven' + - name: Install Protoc + uses: zchee/setup-protoc@v1 - name: Install Hugo CLI run: | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md index e273f7ea3..495fab6cf 100644 --- a/MAINTAINER_NOTES.md +++ b/MAINTAINER_NOTES.md @@ -65,3 +65,7 @@ Create a commit to remove dependencies from the build (undoing the first step): * Comment out the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`. * Change the versions of the shaded dependencies to the latest released version on Maven Central in `prometheus-metrics-exporter-opentelemetry`, `prometheus-metrics-exposition-formats`, and `prometheus-metrics-bom`. + +## Notes + +- `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index b0e319190..6bce50718 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -6,7 +6,7 @@ import io.prometheus.client.it.common.LogConsumer; import io.prometheus.client.it.common.Volume; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/pom.xml b/pom.xml index 09421f582..f41bb926f 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,6 @@ prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-instrumentation-guava prometheus-metrics-simpleclient-bridge - examples benchmarks integration-tests diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index b751f65c4..ccd57519e 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -112,18 +112,6 @@ prometheus-metrics-tracer-otel-agent ${project.version}
      - - io.prometheus - prometheus-metrics-shaded-dependencies - ${prometheus.metrics.shaded.dependencies.version} - - - - io.prometheus - prometheus-metrics-shaded-protobuf - ${prometheus.metrics.shaded.dependencies.version} - - diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 9274be552..1f1079992 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 087b230d2..3e87d378c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -7,13 +7,13 @@ import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import java.util.Arrays; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index ca484bf47..ad514e9d0 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -9,14 +9,14 @@ import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import java.io.ByteArrayOutputStream; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index efdf211bb..4ea61a801 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -5,10 +5,10 @@ import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat; +import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index c68ce46c9..da2efe5af 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -1,17 +1,31 @@ #!/bin/bash -set -e +set -euo pipefail # We use the shaded protobuf JAR from the protobuf-shaded module. # I could not figure out how to use a protoc Maven plugin to use the shaded module, so I ran this command to generate the sources manually. -# The version string must be the same as in protobuf-shaded/pom.xml. -#export PROTOBUF_VERSION_STRING="3_21_7" -export PROTOBUF_VERSION_STRING="3_25_3" +TARGET_DIR=$1 +PROTO_DIR=src/main/protobuf +PROTOBUF_VERSION_STRING=$2 -rm -rf src/main/protobuf/* -curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/prometheus/client/metrics.proto -o src/main/protobuf/metrics.proto -sed -i "s/java_package = \"io.prometheus.client\"/java_package = \"io.prometheus.metrics.expositionformats.generated.com_google_protobuf_${PROTOBUF_VERSION_STRING}\"/" src/main/protobuf/metrics.proto -rm -rf src/main/generated/* -protoc --java_out src/main/generated src/main/protobuf/metrics.proto -sed -i "s/com\\.google\\.protobuf/io.prometheus.metrics.shaded.com_google_protobuf_${PROTOBUF_VERSION_STRING}/g" "src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_${PROTOBUF_VERSION_STRING}/Metrics.java" +echo "Generating protobuf sources for version $PROTOBUF_VERSION_STRING in $TARGET_DIR" + +rm -rf TARGET_DIR || true +mkdir -p $TARGET_DIR +rm -rf $PROTO_DIR || true +mkdir -p $PROTO_DIR + +curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/prometheus/client/metrics.proto -o $PROTO_DIR/metrics.proto +sed -i "s/java_package = \"io.prometheus.client\"/java_package = \"io.prometheus.metrics.expositionformats.generated.com_google_protobuf_${PROTOBUF_VERSION_STRING}\"/" $PROTO_DIR/metrics.proto +protoc --java_out $TARGET_DIR $PROTO_DIR/metrics.proto + +# stop the build if there class is not up-to-date +# show local changes +DIFF=$(git diff) +if [[ ${REQUIRE_PROTO_UP_TO_DATE:-false} == "true" && -n "$DIFF" ]]; then + echo "Generated protobuf sources are not up-to-date. Please run 'PROTO_GENERATION=true mvn clean install' and commit the changes." + echo "Local changes:" + echo "$DIFF" + exit 1 +fi diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 88b18e538..b8c8bf508 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -18,6 +19,7 @@ io.prometheus.metrics.expositionformats + 4.28.2 @@ -32,15 +34,69 @@ ${project.version}
      - io.prometheus - prometheus-metrics-shaded-protobuf - 1.3.1 - + com.google.protobuf + protobuf-java + ${protobuf-java.version} + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + regex-property + + regex-property + + + protobuf-java.string-version + ${protobuf-java.version} + \. + _ + true + + + + negate-prop + initialize + + bsh-property + + + skip.protobuf.generation = !"true".equals(System.getenv("PROTO_GENERATION")); + + skip.protobuf.generation + + + + + + + exec-maven-plugin + org.codehaus.mojo + 3.4.1 + + + Generate Protobuf + generate-sources + + exec + + + ${skip.protobuf.generation} + ${project.basedir}/generate-protobuf.sh + + ${project.basedir}/src/main/generated + ${protobuf-java.string-version} + + + + + org.codehaus.mojo build-helper-maven-plugin @@ -66,6 +122,40 @@ src/main/java;src/main/generated + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + true + true + + + com.google.protobuf + + io.prometheus.metrics.shaded.com_google_protobuf_${protobuf-java.string-version} + + + + + + com.google.protobuf:protobuf-java + + META-INF/maven/com.google.protobuf/** + **/*.proto + META-INF/MANIFEST.MF + + + + + + + diff --git a/prometheus-metrics-exposition-formats/src/main/.gitignore b/prometheus-metrics-exposition-formats/src/main/.gitignore new file mode 100644 index 000000000..6de9f67ab --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/.gitignore @@ -0,0 +1 @@ +protobuf/ diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_2/Metrics.java similarity index 71% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_2/Metrics.java index 3b821ba09..8567f1268 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_3_25_3/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_2/Metrics.java @@ -1,25 +1,35 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! +// NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto +// Protobuf Java Version: 4.28.2 -// Protobuf Java Version: 3.25.3 -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3; +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2; public final class Metrics { private Metrics() {} + static { + com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( + com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, + /* major= */ 4, + /* minor= */ 28, + /* patch= */ 2, + /* suffix= */ "", + Metrics.class.getName()); + } public static void registerAllExtensions( - io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite registry) { + com.google.protobuf.ExtensionRegistryLite registry) { } public static void registerAllExtensions( - io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistry registry) { + com.google.protobuf.ExtensionRegistry registry) { registerAllExtensions( - (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite) registry); + (com.google.protobuf.ExtensionRegistryLite) registry); } /** * Protobuf enum {@code io.prometheus.client.MetricType} */ public enum MetricType - implements io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ProtocolMessageEnum { + implements com.google.protobuf.ProtocolMessageEnum { /** *
            * COUNTER must use the Metric field "counter".
      @@ -70,6 +80,15 @@ public enum MetricType
           GAUGE_HISTOGRAM(5),
           ;
       
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        MetricType.class.getName());
      +    }
           /**
            * 
            * COUNTER must use the Metric field "counter".
      @@ -150,35 +169,35 @@ public static MetricType forNumber(int value) {
             }
           }
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap
      +    public static com.google.protobuf.Internal.EnumLiteMap
               internalGetValueMap() {
             return internalValueMap;
           }
      -    private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap<
      +    private static final com.google.protobuf.Internal.EnumLiteMap<
               MetricType> internalValueMap =
      -          new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.EnumLiteMap() {
      +          new com.google.protobuf.Internal.EnumLiteMap() {
                   public MetricType findValueByNumber(int number) {
                     return MetricType.forNumber(number);
                   }
                 };
       
      -    public final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumValueDescriptor
      +    public final com.google.protobuf.Descriptors.EnumValueDescriptor
               getValueDescriptor() {
             return getDescriptor().getValues().get(ordinal());
           }
      -    public final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumDescriptor
      +    public final com.google.protobuf.Descriptors.EnumDescriptor
               getDescriptorForType() {
             return getDescriptor();
           }
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumDescriptor
      +    public static final com.google.protobuf.Descriptors.EnumDescriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.getDescriptor().getEnumTypes().get(0);
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.getDescriptor().getEnumTypes().get(0);
           }
       
           private static final MetricType[] VALUES = values();
       
           public static MetricType valueOf(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.EnumValueDescriptor desc) {
      +        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
             if (desc.getType() != getDescriptor()) {
               throw new java.lang.IllegalArgumentException(
                 "EnumValueDescriptor is not for this type.");
      @@ -197,7 +216,7 @@ private MetricType(int value) {
       
         public interface LabelPairOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.LabelPair)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional string name = 1;
      @@ -213,7 +232,7 @@ public interface LabelPairOrBuilder extends
            * optional string name = 1;
            * @return The bytes for name.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    com.google.protobuf.ByteString
               getNameBytes();
       
           /**
      @@ -230,19 +249,28 @@ public interface LabelPairOrBuilder extends
            * optional string value = 2;
            * @return The bytes for value.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    com.google.protobuf.ByteString
               getValueBytes();
         }
         /**
          * Protobuf type {@code io.prometheus.client.LabelPair}
          */
         public static final class LabelPair extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.LabelPair)
             LabelPairOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        LabelPair.class.getName());
      +    }
           // Use LabelPair.newBuilder() to construct.
      -    private LabelPair(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private LabelPair(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private LabelPair() {
      @@ -250,24 +278,17 @@ private LabelPair() {
             value_ = "";
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new LabelPair();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder.class);
           }
       
           private int bitField0_;
      @@ -292,8 +313,8 @@ public java.lang.String getName() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        com.google.protobuf.ByteString bs = 
      +            (com.google.protobuf.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
      @@ -306,17 +327,17 @@ public java.lang.String getName() {
            * @return The bytes for name.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    public com.google.protobuf.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +        com.google.protobuf.ByteString b = 
      +            com.google.protobuf.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        return (com.google.protobuf.ByteString) ref;
             }
           }
       
      @@ -341,8 +362,8 @@ public java.lang.String getValue() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        com.google.protobuf.ByteString bs = 
      +            (com.google.protobuf.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 value_ = s;
      @@ -355,17 +376,17 @@ public java.lang.String getValue() {
            * @return The bytes for value.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    public com.google.protobuf.ByteString
               getValueBytes() {
             java.lang.Object ref = value_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +        com.google.protobuf.ByteString b = 
      +            com.google.protobuf.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               value_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        return (com.google.protobuf.ByteString) ref;
             }
           }
       
      @@ -381,13 +402,13 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 1, name_);
      +        com.google.protobuf.GeneratedMessage.writeString(output, 1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 2, value_);
      +        com.google.protobuf.GeneratedMessage.writeString(output, 2, value_);
             }
             getUnknownFields().writeTo(output);
           }
      @@ -399,10 +420,10 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(1, name_);
      +        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(2, value_);
      +        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, value_);
             }
             size += getUnknownFields().getSerializedSize();
             memoizedSize = size;
      @@ -414,10 +435,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -453,75 +474,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -530,7 +551,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -541,7 +562,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -549,29 +570,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.LabelPair}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -585,19 +606,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -605,14 +626,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -627,49 +648,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -692,8 +681,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -724,7 +713,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -748,8 +737,8 @@ public boolean hasName() {
             public java.lang.String getName() {
               java.lang.Object ref = name_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          com.google.protobuf.ByteString bs =
      +              (com.google.protobuf.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   name_ = s;
      @@ -763,17 +752,17 @@ public java.lang.String getName() {
              * optional string name = 1;
              * @return The bytes for name.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +      public com.google.protobuf.ByteString
                 getNameBytes() {
               java.lang.Object ref = name_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +          com.google.protobuf.ByteString b = 
      +              com.google.protobuf.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 name_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          return (com.google.protobuf.ByteString) ref;
               }
             }
             /**
      @@ -805,7 +794,7 @@ public Builder clearName() {
              * @return This builder for chaining.
              */
             public Builder setNameBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +          com.google.protobuf.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               name_ = value;
               bitField0_ |= 0x00000001;
      @@ -828,8 +817,8 @@ public boolean hasValue() {
             public java.lang.String getValue() {
               java.lang.Object ref = value_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          com.google.protobuf.ByteString bs =
      +              (com.google.protobuf.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   value_ = s;
      @@ -843,17 +832,17 @@ public java.lang.String getValue() {
              * optional string value = 2;
              * @return The bytes for value.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +      public com.google.protobuf.ByteString
                 getValueBytes() {
               java.lang.Object ref = value_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +          com.google.protobuf.ByteString b = 
      +              com.google.protobuf.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 value_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          return (com.google.protobuf.ByteString) ref;
               }
             }
             /**
      @@ -885,72 +874,60 @@ public Builder clearValue() {
              * @return This builder for chaining.
              */
             public Builder setValueBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +          com.google.protobuf.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               value_ = value;
               bitField0_ |= 0x00000002;
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.LabelPair)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public LabelPair parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -958,7 +935,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface GaugeOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Gauge)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -975,35 +952,37 @@ public interface GaugeOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Gauge}
          */
         public static final class Gauge extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Gauge)
             GaugeOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Gauge.class.getName());
      +    }
           // Use Gauge.newBuilder() to construct.
      -    private Gauge(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Gauge(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Gauge() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Gauge();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder.class);
           }
       
           private int bitField0_;
      @@ -1038,7 +1017,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -1053,7 +1032,7 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -1066,10 +1045,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1090,7 +1069,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -1098,75 +1077,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -1175,7 +1154,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1186,7 +1165,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -1194,29 +1173,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Gauge}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -1229,19 +1208,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1249,14 +1228,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1267,49 +1246,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1325,8 +1272,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -1352,7 +1299,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -1400,65 +1347,53 @@ public Builder clearValue() {
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Gauge)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Gauge parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1466,7 +1401,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface CounterOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Counter)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -1488,11 +1423,11 @@ public interface CounterOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
       
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
      @@ -1503,45 +1438,47 @@ public interface CounterOrBuilder extends
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
      +    com.google.protobuf.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Counter}
          */
         public static final class Counter extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Counter)
             CounterOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Counter.class.getName());
      +    }
           // Use Counter.newBuilder() to construct.
      -    private Counter(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Counter(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Counter() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Counter();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder.class);
           }
       
           private int bitField0_;
      @@ -1565,7 +1502,7 @@ public double getValue() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return Whether the exemplar field is set.
      @@ -1579,19 +1516,19 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +    private com.google.protobuf.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            * @return Whether the createdTimestamp field is set.
      @@ -1605,15 +1542,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -1628,7 +1565,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -1649,15 +1586,15 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(2, getExemplar());
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, getCreatedTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -1670,10 +1607,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1704,7 +1641,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             if (hasExemplar()) {
      @@ -1720,75 +1657,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -1797,7 +1734,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1808,7 +1745,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -1816,34 +1753,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Counter}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getExemplarFieldBuilder();
                 getCreatedTimestampFieldBuilder();
      @@ -1868,19 +1805,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1888,14 +1825,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1918,49 +1855,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1982,8 +1887,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -2023,7 +1928,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -2072,9 +1977,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar exemplar_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return Whether the exemplar field is set.
      @@ -2086,9 +1991,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -2096,7 +2001,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2113,7 +2018,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -2126,11 +2031,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -2160,7 +2065,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -2168,23 +2073,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
      -          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>(
      +          exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -2193,9 +2098,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return exemplarBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
      +      private com.google.protobuf.Timestamp createdTimestamp_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              * @return Whether the createdTimestamp field is set.
      @@ -2207,9 +2112,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      public com.google.protobuf.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -2217,7 +2122,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder setCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2234,7 +2139,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
      +          com.google.protobuf.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -2247,11 +2152,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -2281,7 +2186,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -2289,23 +2194,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -2313,65 +2218,53 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilde
               }
               return createdTimestampBuilder_;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Counter)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Counter parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2379,7 +2272,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface QuantileOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Quantile)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional double quantile = 1;
      @@ -2407,35 +2300,37 @@ public interface QuantileOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Quantile}
          */
         public static final class Quantile extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Quantile)
             QuantileOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Quantile.class.getName());
      +    }
           // Use Quantile.newBuilder() to construct.
      -    private Quantile(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Quantile(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Quantile() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Quantile();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder.class);
           }
       
           private int bitField0_;
      @@ -2489,7 +2384,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, quantile_);
      @@ -2507,11 +2402,11 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(1, quantile_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(2, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -2524,10 +2419,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile) obj;
       
             if (hasQuantile() != other.hasQuantile()) return false;
             if (hasQuantile()) {
      @@ -2554,12 +2449,12 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasQuantile()) {
               hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getQuantile()));
             }
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -2567,75 +2462,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -2644,7 +2539,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -2655,7 +2550,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -2663,29 +2558,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Quantile}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -2699,19 +2594,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -2719,14 +2614,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -2741,49 +2636,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.getDefaultInstance()) return this;
               if (other.hasQuantile()) {
                 setQuantile(other.getQuantile());
               }
      @@ -2802,8 +2665,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -2834,7 +2697,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -2922,65 +2785,53 @@ public Builder clearValue() {
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Quantile)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Quantile parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2988,7 +2839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface SummaryOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Summary)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional uint64 sample_count = 1;
      @@ -3015,12 +2866,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getQuantile(int index);
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      @@ -3028,12 +2879,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileOrBuilderList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index);
       
           /**
      @@ -3045,46 +2896,48 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
      +    com.google.protobuf.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Summary}
          */
         public static final class Summary extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Summary)
             SummaryOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Summary.class.getName());
      +    }
           // Use Summary.newBuilder() to construct.
      -    private Summary(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Summary(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Summary() {
             quantile_ = java.util.Collections.emptyList();
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Summary();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder.class);
           }
       
           private int bitField0_;
      @@ -3128,19 +2981,19 @@ public double getSampleSum() {
       
           public static final int QUANTILE_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List quantile_;
      +    private java.util.List quantile_;
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List getQuantileList() {
      +    public java.util.List getQuantileList() {
             return quantile_;
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getQuantileOrBuilderList() {
             return quantile_;
           }
      @@ -3155,20 +3008,20 @@ public int getQuantileCount() {
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getQuantile(int index) {
             return quantile_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index) {
             return quantile_.get(index);
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +    private com.google.protobuf.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            * @return Whether the createdTimestamp field is set.
      @@ -3182,15 +3035,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -3205,7 +3058,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeUInt64(1, sampleCount_);
      @@ -3229,19 +3082,19 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeUInt64Size(1, sampleCount_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(2, sampleSum_);
             }
             for (int i = 0; i < quantile_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, quantile_.get(i));
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(4, getCreatedTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -3254,10 +3107,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -3290,12 +3143,12 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasSampleCount()) {
               hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   getSampleCount());
             }
             if (hasSampleSum()) {
               hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getSampleSum()));
             }
             if (getQuantileCount() > 0) {
      @@ -3311,75 +3164,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -3388,7 +3241,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -3399,7 +3252,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -3407,34 +3260,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Summary}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getQuantileFieldBuilder();
                 getCreatedTimestampFieldBuilder();
      @@ -3462,19 +3315,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -3482,15 +3335,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary result) {
               if (quantileBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0)) {
                   quantile_ = java.util.Collections.unmodifiableList(quantile_);
      @@ -3502,7 +3355,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -3523,49 +3376,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -3591,7 +3412,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     quantile_ = other.quantile_;
                     bitField0_ = (bitField0_ & ~0x00000004);
                     quantileBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getQuantileFieldBuilder() : null;
                   } else {
                     quantileBuilder_.addAllMessages(other.quantile_);
      @@ -3613,8 +3434,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -3638,9 +3459,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.parser(),
                               extensionRegistry);
                       if (quantileBuilder_ == null) {
                         ensureQuantileIsMutable();
      @@ -3665,7 +3486,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -3754,22 +3575,22 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List quantile_ =
      +      private java.util.List quantile_ =
               java.util.Collections.emptyList();
             private void ensureQuantileIsMutable() {
               if (!((bitField0_ & 0x00000004) != 0)) {
      -          quantile_ = new java.util.ArrayList(quantile_);
      +          quantile_ = new java.util.ArrayList(quantile_);
                 bitField0_ |= 0x00000004;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder> quantileBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder> quantileBuilder_;
       
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List getQuantileList() {
      +      public java.util.List getQuantileList() {
               if (quantileBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(quantile_);
               } else {
      @@ -3789,7 +3610,7 @@ public int getQuantileCount() {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile getQuantile(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile getQuantile(int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);
               } else {
      @@ -3800,7 +3621,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3817,7 +3638,7 @@ public Builder setQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.set(index, builderForValue.build());
      @@ -3830,7 +3651,7 @@ public Builder setQuantile(
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
      +      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3847,7 +3668,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3864,7 +3685,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(builderForValue.build());
      @@ -3878,7 +3699,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(index, builderForValue.build());
      @@ -3892,10 +3713,10 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addAllQuantile(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, quantile_);
                 onChanged();
               } else {
      @@ -3932,14 +3753,14 @@ public Builder removeQuantile(int index) {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder getQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder getQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
                 int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);  } else {
      @@ -3949,7 +3770,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileOrBuilderList() {
               if (quantileBuilder_ != null) {
                 return quantileBuilder_.getMessageOrBuilderList();
      @@ -3960,31 +3781,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder addQuantileBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder addQuantileBuilder() {
               return getQuantileFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder addQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder addQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileBuilderList() {
               return getQuantileFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder> 
                 getQuantileFieldBuilder() {
               if (quantileBuilder_ == null) {
      -          quantileBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.QuantileOrBuilder>(
      +          quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.QuantileOrBuilder>(
                         quantile_,
                         ((bitField0_ & 0x00000004) != 0),
                         getParentForChildren(),
      @@ -3994,9 +3815,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return quantileBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
      +      private com.google.protobuf.Timestamp createdTimestamp_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              * @return Whether the createdTimestamp field is set.
      @@ -4008,9 +3829,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      public com.google.protobuf.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -4018,7 +3839,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder setCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -4035,7 +3856,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
      +          com.google.protobuf.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -4048,11 +3869,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -4082,7 +3903,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -4090,23 +3911,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 4;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -4114,65 +3935,53 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilde
               }
               return createdTimestampBuilder_;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Summary)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Summary parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4180,7 +3989,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface UntypedOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Untyped)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional double value = 1;
      @@ -4197,35 +4006,37 @@ public interface UntypedOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Untyped}
          */
         public static final class Untyped extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Untyped)
             UntypedOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Untyped.class.getName());
      +    }
           // Use Untyped.newBuilder() to construct.
      -    private Untyped(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Untyped(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Untyped() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Untyped();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder.class);
           }
       
           private int bitField0_;
      @@ -4260,7 +4071,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeDouble(1, value_);
      @@ -4275,7 +4086,7 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(1, value_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -4288,10 +4099,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -4312,7 +4123,7 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -4320,75 +4131,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -4397,7 +4208,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -4408,7 +4219,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -4416,29 +4227,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Untyped}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -4451,19 +4262,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -4471,14 +4282,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -4489,49 +4300,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -4547,8 +4326,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -4574,7 +4353,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -4622,65 +4401,53 @@ public Builder clearValue() {
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Untyped)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Untyped parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4688,7 +4455,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface HistogramOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Histogram)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional uint64 sample_count = 1;
      @@ -4738,7 +4505,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketList();
           /**
            * 
      @@ -4747,7 +4514,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4763,7 +4530,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4772,7 +4539,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4784,11 +4551,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            * @return The createdTimestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp();
      +    com.google.protobuf.Timestamp getCreatedTimestamp();
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder();
      +    com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder();
       
           /**
            * 
      @@ -4881,7 +4648,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4890,7 +4657,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4906,7 +4673,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4915,7 +4682,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4992,7 +4759,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -5004,7 +4771,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5026,7 +4793,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -5038,7 +4805,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -5112,7 +4879,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -5121,7 +4888,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5137,7 +4904,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -5146,19 +4913,28 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
          * Protobuf type {@code io.prometheus.client.Histogram}
          */
         public static final class Histogram extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Histogram)
             HistogramOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Histogram.class.getName());
      +    }
           // Use Histogram.newBuilder() to construct.
      -    private Histogram(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Histogram(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Histogram() {
      @@ -5172,24 +4948,17 @@ private Histogram() {
             exemplars_ = java.util.Collections.emptyList();
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Histogram();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5260,7 +5029,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5269,7 +5038,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5280,7 +5049,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5303,7 +5072,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5314,13 +5083,13 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 15;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      +    private com.google.protobuf.Timestamp createdTimestamp_;
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            * @return Whether the createdTimestamp field is set.
      @@ -5334,15 +5103,15 @@ public boolean hasCreatedTimestamp() {
            * @return The createdTimestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.Timestamp getCreatedTimestamp() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 15;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      -      return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +    public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
           }
       
           public static final int SCHEMA_FIELD_NUMBER = 5;
      @@ -5463,7 +5232,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5472,7 +5241,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5483,7 +5252,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5506,7 +5275,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5517,14 +5286,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
       
           public static final int NEGATIVE_DELTA_FIELD_NUMBER = 10;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList negativeDelta_ =
      +    private com.google.protobuf.Internal.LongList negativeDelta_ =
               emptyLongList();
           /**
            * 
      @@ -5571,7 +5340,7 @@ public long getNegativeDelta(int index) {
       
           public static final int NEGATIVE_COUNT_FIELD_NUMBER = 11;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList negativeCount_ =
      +    private com.google.protobuf.Internal.DoubleList negativeCount_ =
               emptyDoubleList();
           /**
            * 
      @@ -5612,7 +5381,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5624,7 +5393,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5638,7 +5407,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5667,7 +5436,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5681,14 +5450,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
       
           public static final int POSITIVE_DELTA_FIELD_NUMBER = 13;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList positiveDelta_ =
      +    private com.google.protobuf.Internal.LongList positiveDelta_ =
               emptyLongList();
           /**
            * 
      @@ -5735,7 +5504,7 @@ public long getPositiveDelta(int index) {
       
           public static final int POSITIVE_COUNT_FIELD_NUMBER = 14;
           @SuppressWarnings("serial")
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList positiveCount_ =
      +    private com.google.protobuf.Internal.DoubleList positiveCount_ =
               emptyDoubleList();
           /**
            * 
      @@ -5776,7 +5545,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5785,7 +5554,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5796,7 +5565,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5819,7 +5588,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5830,7 +5599,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5847,7 +5616,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeUInt64(1, sampleCount_);
      @@ -5907,45 +5676,45 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeUInt64Size(1, sampleCount_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(2, sampleSum_);
             }
             for (int i = 0; i < bucket_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, bucket_.get(i));
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(4, sampleCountFloat_);
             }
             if (((bitField0_ & 0x00000010) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeSInt32Size(5, schema_);
             }
             if (((bitField0_ & 0x00000020) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(6, zeroThreshold_);
             }
             if (((bitField0_ & 0x00000040) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeUInt64Size(7, zeroCount_);
             }
             if (((bitField0_ & 0x00000080) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(8, zeroCountFloat_);
             }
             for (int i = 0; i < negativeSpan_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(9, negativeSpan_.get(i));
             }
             {
               int dataSize = 0;
               for (int i = 0; i < negativeDelta_.size(); i++) {
      -          dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +          dataSize += com.google.protobuf.CodedOutputStream
                   .computeSInt64SizeNoTag(negativeDelta_.getLong(i));
               }
               size += dataSize;
      @@ -5958,13 +5727,13 @@ public int getSerializedSize() {
               size += 1 * getNegativeCountList().size();
             }
             for (int i = 0; i < positiveSpan_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(12, positiveSpan_.get(i));
             }
             {
               int dataSize = 0;
               for (int i = 0; i < positiveDelta_.size(); i++) {
      -          dataSize += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +          dataSize += com.google.protobuf.CodedOutputStream
                   .computeSInt64SizeNoTag(positiveDelta_.getLong(i));
               }
               size += dataSize;
      @@ -5977,11 +5746,11 @@ public int getSerializedSize() {
               size += 1 * getPositiveCountList().size();
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(15, getCreatedTimestamp());
             }
             for (int i = 0; i < exemplars_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(16, exemplars_.get(i));
             }
             size += getUnknownFields().getSerializedSize();
      @@ -5994,10 +5763,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -6072,17 +5841,17 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasSampleCount()) {
               hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   getSampleCount());
             }
             if (hasSampleCountFloat()) {
               hash = (37 * hash) + SAMPLE_COUNT_FLOAT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getSampleCountFloat()));
             }
             if (hasSampleSum()) {
               hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getSampleSum()));
             }
             if (getBucketCount() > 0) {
      @@ -6099,17 +5868,17 @@ public int hashCode() {
             }
             if (hasZeroThreshold()) {
               hash = (37 * hash) + ZERO_THRESHOLD_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getZeroThreshold()));
             }
             if (hasZeroCount()) {
               hash = (37 * hash) + ZERO_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   getZeroCount());
             }
             if (hasZeroCountFloat()) {
               hash = (37 * hash) + ZERO_COUNT_FLOAT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getZeroCountFloat()));
             }
             if (getNegativeSpanCount() > 0) {
      @@ -6145,75 +5914,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -6222,7 +5991,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6233,7 +6002,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -6241,34 +6010,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Histogram}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getBucketFieldBuilder();
                 getCreatedTimestampFieldBuilder();
      @@ -6329,19 +6098,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6349,15 +6118,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6396,7 +6165,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6453,49 +6222,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6524,7 +6261,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bucket_ = other.bucket_;
                     bitField0_ = (bitField0_ & ~0x00000008);
                     bucketBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getBucketFieldBuilder() : null;
                   } else {
                     bucketBuilder_.addAllMessages(other.bucket_);
      @@ -6565,7 +6302,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     negativeSpan_ = other.negativeSpan_;
                     bitField0_ = (bitField0_ & ~0x00000200);
                     negativeSpanBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getNegativeSpanFieldBuilder() : null;
                   } else {
                     negativeSpanBuilder_.addAllMessages(other.negativeSpan_);
      @@ -6613,7 +6350,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     positiveSpan_ = other.positiveSpan_;
                     bitField0_ = (bitField0_ & ~0x00001000);
                     positiveSpanBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getPositiveSpanFieldBuilder() : null;
                   } else {
                     positiveSpanBuilder_.addAllMessages(other.positiveSpan_);
      @@ -6661,7 +6398,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     exemplars_ = other.exemplars_;
                     bitField0_ = (bitField0_ & ~0x00008000);
                     exemplarsBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getExemplarsFieldBuilder() : null;
                   } else {
                     exemplarsBuilder_.addAllMessages(other.exemplars_);
      @@ -6680,8 +6417,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -6705,9 +6442,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6743,9 +6480,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6789,9 +6526,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6842,9 +6579,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6862,7 +6599,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -7007,17 +6744,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder> bucketBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -7026,7 +6763,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -7054,7 +6791,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -7069,7 +6806,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7090,7 +6827,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -7107,7 +6844,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7128,7 +6865,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7149,7 +6886,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -7167,7 +6904,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -7185,10 +6922,10 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, bucket_);
                 onChanged();
               } else {
      @@ -7237,7 +6974,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().getBuilder(index);
             }
      @@ -7248,7 +6985,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7262,7 +6999,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7277,9 +7014,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder addBucketBuilder() {
               return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7288,10 +7025,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7300,16 +7037,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return getBucketFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder> 
                 getBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
      -          bucketBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder>(
      +          bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7319,9 +7056,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return bucketBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp createdTimestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> createdTimestampBuilder_;
      +      private com.google.protobuf.Timestamp createdTimestamp_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createdTimestampBuilder_;
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              * @return Whether the createdTimestamp field is set.
      @@ -7333,9 +7070,9 @@ public boolean hasCreatedTimestamp() {
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              * @return The createdTimestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCreatedTimestamp() {
      +      public com.google.protobuf.Timestamp getCreatedTimestamp() {
               if (createdTimestampBuilder_ == null) {
      -          return createdTimestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +          return createdTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               } else {
                 return createdTimestampBuilder_.getMessage();
               }
      @@ -7343,7 +7080,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getCrea
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder setCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7360,7 +7097,7 @@ public Builder setCreatedTimestamp(io.prometheus.metrics.shaded.com_google_proto
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
             public Builder setCreatedTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
      +          com.google.protobuf.Timestamp.Builder builderForValue) {
               if (createdTimestampBuilder_ == null) {
                 createdTimestamp_ = builderForValue.build();
               } else {
      @@ -7373,11 +7110,11 @@ public Builder setCreatedTimestamp(
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public Builder mergeCreatedTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder mergeCreatedTimestamp(com.google.protobuf.Timestamp value) {
               if (createdTimestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   createdTimestamp_ != null &&
      -            createdTimestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
      +            createdTimestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
                   getCreatedTimestampBuilder().mergeFrom(value);
                 } else {
                   createdTimestamp_ = value;
      @@ -7407,7 +7144,7 @@ public Builder clearCreatedTimestamp() {
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getCreatedTimestampBuilder() {
      +      public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getCreatedTimestampFieldBuilder().getBuilder();
      @@ -7415,23 +7152,23 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getCreatedTimestampOrBuilder() {
      +      public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
               if (createdTimestampBuilder_ != null) {
                 return createdTimestampBuilder_.getMessageOrBuilder();
               } else {
                 return createdTimestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : createdTimestamp_;
      +              com.google.protobuf.Timestamp.getDefaultInstance() : createdTimestamp_;
               }
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
                 getCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
      -          createdTimestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
      +          createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                         getCreatedTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -7680,17 +7417,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7699,7 +7436,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7727,7 +7464,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7742,7 +7479,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7763,7 +7500,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7780,7 +7517,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7801,7 +7538,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7822,7 +7559,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7840,7 +7577,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7858,10 +7595,10 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, negativeSpan_);
                 onChanged();
               } else {
      @@ -7910,7 +7647,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7921,7 +7658,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7935,7 +7672,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7950,9 +7687,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7961,10 +7698,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7973,16 +7710,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return getNegativeSpanFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder> 
                 getNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
      -          negativeSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder>(
      +          negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7992,7 +7729,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return negativeSpanBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList negativeDelta_ = emptyLongList();
      +      private com.google.protobuf.Internal.LongList negativeDelta_ = emptyLongList();
             private void ensureNegativeDeltaIsMutable() {
               if (!negativeDelta_.isModifiable()) {
                 negativeDelta_ = makeMutableCopy(negativeDelta_);
      @@ -8095,7 +7832,7 @@ public Builder addNegativeDelta(long value) {
             public Builder addAllNegativeDelta(
                 java.lang.Iterable values) {
               ensureNegativeDeltaIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +        com.google.protobuf.AbstractMessageLite.Builder.addAll(
                   values, negativeDelta_);
               bitField0_ |= 0x00000400;
               onChanged();
      @@ -8118,7 +7855,7 @@ public Builder clearNegativeDelta() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList negativeCount_ = emptyDoubleList();
      +      private com.google.protobuf.Internal.DoubleList negativeCount_ = emptyDoubleList();
             private void ensureNegativeCountIsMutable() {
               if (!negativeCount_.isModifiable()) {
                 negativeCount_ = makeMutableCopy(negativeCount_);
      @@ -8215,7 +7952,7 @@ public Builder addNegativeCount(double value) {
             public Builder addAllNegativeCount(
                 java.lang.Iterable values) {
               ensureNegativeCountIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +        com.google.protobuf.AbstractMessageLite.Builder.addAll(
                   values, negativeCount_);
               bitField0_ |= 0x00000800;
               onChanged();
      @@ -8236,17 +7973,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -8258,7 +7995,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8292,7 +8029,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8310,7 +8047,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8334,7 +8071,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8354,7 +8091,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8378,7 +8115,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8402,7 +8139,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8423,7 +8160,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8444,10 +8181,10 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, positiveSpan_);
                 onChanged();
               } else {
      @@ -8505,7 +8242,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8519,7 +8256,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8536,7 +8273,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8554,9 +8291,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8568,10 +8305,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8583,16 +8320,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return getPositiveSpanFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder> 
                 getPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
      -          positiveSpanBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder>(
      +          positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8602,7 +8339,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return positiveSpanBuilder_;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.LongList positiveDelta_ = emptyLongList();
      +      private com.google.protobuf.Internal.LongList positiveDelta_ = emptyLongList();
             private void ensurePositiveDeltaIsMutable() {
               if (!positiveDelta_.isModifiable()) {
                 positiveDelta_ = makeMutableCopy(positiveDelta_);
      @@ -8705,7 +8442,7 @@ public Builder addPositiveDelta(long value) {
             public Builder addAllPositiveDelta(
                 java.lang.Iterable values) {
               ensurePositiveDeltaIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +        com.google.protobuf.AbstractMessageLite.Builder.addAll(
                   values, positiveDelta_);
               bitField0_ |= 0x00002000;
               onChanged();
      @@ -8728,7 +8465,7 @@ public Builder clearPositiveDelta() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.DoubleList positiveCount_ = emptyDoubleList();
      +      private com.google.protobuf.Internal.DoubleList positiveCount_ = emptyDoubleList();
             private void ensurePositiveCountIsMutable() {
               if (!positiveCount_.isModifiable()) {
                 positiveCount_ = makeMutableCopy(positiveCount_);
      @@ -8825,7 +8562,7 @@ public Builder addPositiveCount(double value) {
             public Builder addAllPositiveCount(
                 java.lang.Iterable values) {
               ensurePositiveCountIsMutable();
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +        com.google.protobuf.AbstractMessageLite.Builder.addAll(
                   values, positiveCount_);
               bitField0_ |= 0x00004000;
               onChanged();
      @@ -8846,17 +8583,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8865,7 +8602,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8893,7 +8630,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8908,7 +8645,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8929,7 +8666,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8946,7 +8683,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8967,7 +8704,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8988,7 +8725,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -9006,7 +8743,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -9024,10 +8761,10 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, exemplars_);
                 onChanged();
               } else {
      @@ -9076,7 +8813,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -9087,7 +8824,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -9101,7 +8838,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -9116,9 +8853,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return getExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -9127,10 +8864,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -9139,16 +8876,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return getExemplarsFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> 
                 getExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
      -          exemplarsBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>(
      +          exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -9157,65 +8894,53 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               }
               return exemplarsBuilder_;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Histogram)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Histogram parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9223,7 +8948,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface BucketOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Bucket)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * 
      @@ -9291,11 +9016,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9306,35 +9031,37 @@ public interface BucketOrBuilder extends
          * Protobuf type {@code io.prometheus.client.Bucket}
          */
         public static final class Bucket extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Bucket)
             BucketOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Bucket.class.getName());
      +    }
           // Use Bucket.newBuilder() to construct.
      -    private Bucket(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Bucket(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Bucket() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Bucket();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9420,7 +9147,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9434,15 +9161,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9457,7 +9184,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeUInt64(1, cumulativeCount_);
      @@ -9481,19 +9208,19 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeUInt64Size(1, cumulativeCount_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(2, upperBound_);
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, getExemplar());
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(4, cumulativeCountFloat_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -9506,10 +9233,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9546,17 +9273,17 @@ public int hashCode() {
             hash = (19 * hash) + getDescriptor().hashCode();
             if (hasCumulativeCount()) {
               hash = (37 * hash) + CUMULATIVE_COUNT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   getCumulativeCount());
             }
             if (hasCumulativeCountFloat()) {
               hash = (37 * hash) + CUMULATIVE_COUNT_FLOAT_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getCumulativeCountFloat()));
             }
             if (hasUpperBound()) {
               hash = (37 * hash) + UPPER_BOUND_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getUpperBound()));
             }
             if (hasExemplar()) {
      @@ -9568,75 +9295,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -9645,7 +9372,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9656,7 +9383,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -9669,34 +9396,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Bucket}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getExemplarFieldBuilder();
               }
      @@ -9717,19 +9444,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9737,14 +9464,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9769,49 +9496,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9836,8 +9531,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -9880,7 +9575,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -10057,9 +9752,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar exemplar_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar exemplar_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -10071,9 +9766,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -10081,7 +9776,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -10098,7 +9793,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -10111,11 +9806,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -10145,7 +9840,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -10153,23 +9848,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
      -          exemplarBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder>(
      +          exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -10177,65 +9872,53 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               }
               return exemplarBuilder_;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Bucket)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Bucket parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10243,7 +9926,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface BucketSpanOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.BucketSpan)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * 
      @@ -10296,35 +9979,37 @@ public interface BucketSpanOrBuilder extends
          * Protobuf type {@code io.prometheus.client.BucketSpan}
          */
         public static final class BucketSpan extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.BucketSpan)
             BucketSpanOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        BucketSpan.class.getName());
      +    }
           // Use BucketSpan.newBuilder() to construct.
      -    private BucketSpan(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private BucketSpan(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private BucketSpan() {
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new BucketSpan();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10394,7 +10079,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
               output.writeSInt32(1, offset_);
      @@ -10412,11 +10097,11 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeSInt32Size(1, offset_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeUInt32Size(2, length_);
             }
             size += getUnknownFields().getSerializedSize();
      @@ -10429,10 +10114,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10468,75 +10153,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -10545,7 +10230,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10556,7 +10241,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -10573,29 +10258,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.BucketSpan}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpanOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpanOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -10609,19 +10294,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10629,14 +10314,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10651,49 +10336,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10712,8 +10365,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -10744,7 +10397,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -10864,65 +10517,53 @@ public Builder clearLength() {
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.BucketSpan)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public BucketSpan parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10930,17 +10571,17 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface ExemplarOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Exemplar)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10948,12 +10589,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10984,7 +10625,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .google.protobuf.Timestamp timestamp = 3;
            * @return The timestamp.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp();
      +    com.google.protobuf.Timestamp getTimestamp();
           /**
            * 
            * OpenMetrics-style.
      @@ -10992,60 +10633,62 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            *
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder();
      +    com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder();
         }
         /**
          * Protobuf type {@code io.prometheus.client.Exemplar}
          */
         public static final class Exemplar extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Exemplar)
             ExemplarOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Exemplar.class.getName());
      +    }
           // Use Exemplar.newBuilder() to construct.
      -    private Exemplar(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Exemplar(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Exemplar() {
             label_ = java.util.Collections.emptyList();
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Exemplar();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11060,14 +10703,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -11092,7 +10735,7 @@ public double getValue() {
           }
       
           public static final int TIMESTAMP_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp timestamp_;
      +    private com.google.protobuf.Timestamp timestamp_;
           /**
            * 
            * OpenMetrics-style.
      @@ -11114,8 +10757,8 @@ public boolean hasTimestamp() {
            * @return The timestamp.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp() {
      -      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
      +    public com.google.protobuf.Timestamp getTimestamp() {
      +      return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
           }
           /**
            * 
      @@ -11125,8 +10768,8 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTime
            * optional .google.protobuf.Timestamp timestamp = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder() {
      -      return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
      +    public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
      +      return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -11141,7 +10784,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             for (int i = 0; i < label_.size(); i++) {
               output.writeMessage(1, label_.get(i));
      @@ -11162,15 +10805,15 @@ public int getSerializedSize() {
       
             size = 0;
             for (int i = 0; i < label_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(1, label_.get(i));
             }
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeDoubleSize(2, value_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, getTimestamp());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -11183,10 +10826,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -11218,7 +10861,7 @@ public int hashCode() {
             }
             if (hasValue()) {
               hash = (37 * hash) + VALUE_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   java.lang.Double.doubleToLongBits(getValue()));
             }
             if (hasTimestamp()) {
      @@ -11230,75 +10873,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -11307,7 +10950,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -11318,7 +10961,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -11326,34 +10969,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Exemplar}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.ExemplarOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.ExemplarOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getLabelFieldBuilder();
                 getTimestampFieldBuilder();
      @@ -11380,19 +11023,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11400,15 +11043,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11420,7 +11063,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11437,49 +11080,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11499,7 +11110,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     label_ = other.label_;
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
      @@ -11524,8 +11135,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -11539,9 +11150,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11571,7 +11182,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -11580,22 +11191,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11615,7 +11226,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11626,7 +11237,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11643,7 +11254,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11656,7 +11267,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11673,7 +11284,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11690,7 +11301,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11704,7 +11315,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11718,10 +11329,10 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, label_);
                 onChanged();
               } else {
      @@ -11758,14 +11369,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11775,7 +11386,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11786,31 +11397,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
      -          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder>(
      +          labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11860,9 +11471,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp timestamp_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> timestampBuilder_;
      +      private com.google.protobuf.Timestamp timestamp_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> timestampBuilder_;
             /**
              * 
              * OpenMetrics-style.
      @@ -11882,9 +11493,9 @@ public boolean hasTimestamp() {
              * optional .google.protobuf.Timestamp timestamp = 3;
              * @return The timestamp.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTimestamp() {
      +      public com.google.protobuf.Timestamp getTimestamp() {
               if (timestampBuilder_ == null) {
      -          return timestamp_ == null ? io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
      +          return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
               } else {
                 return timestampBuilder_.getMessage();
               }
      @@ -11896,7 +11507,7 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp getTime
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder setTimestamp(com.google.protobuf.Timestamp value) {
               if (timestampBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11917,7 +11528,7 @@ public Builder setTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_2
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
             public Builder setTimestamp(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder builderForValue) {
      +          com.google.protobuf.Timestamp.Builder builderForValue) {
               if (timestampBuilder_ == null) {
                 timestamp_ = builderForValue.build();
               } else {
      @@ -11934,11 +11545,11 @@ public Builder setTimestamp(
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public Builder mergeTimestamp(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp value) {
      +      public Builder mergeTimestamp(com.google.protobuf.Timestamp value) {
               if (timestampBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   timestamp_ != null &&
      -            timestamp_ != io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance()) {
      +            timestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
                   getTimestampBuilder().mergeFrom(value);
                 } else {
                   timestamp_ = value;
      @@ -11976,7 +11587,7 @@ public Builder clearTimestamp() {
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder getTimestampBuilder() {
      +      public com.google.protobuf.Timestamp.Builder getTimestampBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getTimestampFieldBuilder().getBuilder();
      @@ -11988,12 +11599,12 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder getTimestampOrBuilder() {
      +      public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
               if (timestampBuilder_ != null) {
                 return timestampBuilder_.getMessageOrBuilder();
               } else {
                 return timestamp_ == null ?
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.getDefaultInstance() : timestamp_;
      +              com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
               }
             }
             /**
      @@ -12003,12 +11614,12 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilde
              *
              * optional .google.protobuf.Timestamp timestamp = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
                 getTimestampFieldBuilder() {
               if (timestampBuilder_ == null) {
      -          timestampBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp.Builder, io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilder>(
      +          timestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                         getTimestamp(),
                         getParentForChildren(),
                         isClean());
      @@ -12016,65 +11627,53 @@ public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampOrBuilde
               }
               return timestampBuilder_;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Exemplar)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Exemplar parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -12082,17 +11681,17 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface MetricOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.Metric)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -12100,12 +11699,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -12117,11 +11716,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -12132,11 +11731,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -12147,11 +11746,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -12162,11 +11761,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -12177,11 +11776,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -12198,54 +11797,56 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
          * Protobuf type {@code io.prometheus.client.Metric}
          */
         public static final class Metric extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.Metric)
             MetricOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        Metric.class.getName());
      +    }
           // Use Metric.newBuilder() to construct.
      -    private Metric(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private Metric(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private Metric() {
             label_ = java.util.Collections.emptyList();
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new Metric();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -12260,20 +11861,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -12287,19 +11888,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -12313,19 +11914,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -12339,19 +11940,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -12365,19 +11966,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -12391,15 +11992,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12433,7 +12034,7 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             for (int i = 0; i < label_.size(); i++) {
               output.writeMessage(1, label_.get(i));
      @@ -12466,31 +12067,31 @@ public int getSerializedSize() {
       
             size = 0;
             for (int i = 0; i < label_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(1, label_.get(i));
             }
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(2, getGauge());
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(3, getCounter());
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(4, getSummary());
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(5, getUntyped());
             }
             if (((bitField0_ & 0x00000020) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeInt64Size(6, timestampMs_);
             }
             if (((bitField0_ & 0x00000010) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(7, getHistogram());
             }
             size += getUnknownFields().getSerializedSize();
      @@ -12503,10 +12104,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12577,7 +12178,7 @@ public int hashCode() {
             }
             if (hasTimestampMs()) {
               hash = (37 * hash) + TIMESTAMP_MS_FIELD_NUMBER;
      -        hash = (53 * hash) + io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Internal.hashLong(
      +        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
                   getTimestampMs());
             }
             hash = (29 * hash) + getUnknownFields().hashCode();
      @@ -12585,75 +12186,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -12662,7 +12263,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12673,7 +12274,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -12681,34 +12282,34 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.Metric}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
               maybeForceBuilderInitialization();
             }
             private void maybeForceBuilderInitialization() {
      -        if (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +        if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
                 getLabelFieldBuilder();
                 getGaugeFieldBuilder();
      @@ -12759,19 +12360,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12779,15 +12380,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12799,7 +12400,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12840,49 +12441,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12902,7 +12471,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     label_ = other.label_;
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
      @@ -12939,8 +12508,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -12954,9 +12523,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -13014,7 +12583,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -13023,22 +12592,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -13058,7 +12627,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -13069,7 +12638,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13086,7 +12655,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -13099,7 +12668,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +12685,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13133,7 +12702,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -13147,7 +12716,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -13161,10 +12730,10 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, label_);
                 onChanged();
               } else {
      @@ -13201,14 +12770,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -13218,7 +12787,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -13229,31 +12798,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
      -          labelBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.LabelPairOrBuilder>(
      +          labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -13263,9 +12832,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge gauge_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge gauge_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -13277,9 +12846,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -13287,7 +12856,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13304,7 +12873,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -13317,11 +12886,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -13351,7 +12920,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getGaugeFieldBuilder().getBuilder();
      @@ -13359,23 +12928,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder> 
                 getGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
      -          gaugeBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.GaugeOrBuilder>(
      +          gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -13384,9 +12953,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter counter_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder> counterBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter counter_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -13398,9 +12967,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -13408,7 +12977,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13425,7 +12994,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13438,11 +13007,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13472,7 +13041,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCounterFieldBuilder().getBuilder();
      @@ -13480,23 +13049,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder> 
                 getCounterFieldBuilder() {
               if (counterBuilder_ == null) {
      -          counterBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.CounterOrBuilder>(
      +          counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13505,9 +13074,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary summary_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder> summaryBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary summary_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13519,9 +13088,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13529,7 +13098,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13546,7 +13115,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13559,11 +13128,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13593,7 +13162,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getSummaryFieldBuilder().getBuilder();
      @@ -13601,23 +13170,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder> 
                 getSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
      -          summaryBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.SummaryOrBuilder>(
      +          summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13626,9 +13195,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped untyped_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder> untypedBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped untyped_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13640,9 +13209,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13650,7 +13219,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13667,7 +13236,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13680,11 +13249,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13714,7 +13283,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getUntypedFieldBuilder().getBuilder();
      @@ -13722,23 +13291,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder> 
                 getUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
      -          untypedBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.UntypedOrBuilder>(
      +          untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13747,9 +13316,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram histogram_;
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder> histogramBuilder_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram histogram_;
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13761,9 +13330,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13771,7 +13340,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13788,7 +13357,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13801,11 +13370,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13835,7 +13404,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return getHistogramFieldBuilder().getBuilder();
      @@ -13843,23 +13412,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder> 
      +      private com.google.protobuf.SingleFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder> 
                 getHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
      -          histogramBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.SingleFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.HistogramOrBuilder>(
      +          histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13907,65 +13476,53 @@ public Builder clearTimestampMs() {
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.Metric)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public Metric parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13973,7 +13530,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
       
         public interface MetricFamilyOrBuilder extends
             // @@protoc_insertion_point(interface_extends:io.prometheus.client.MetricFamily)
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.MessageOrBuilder {
      +      com.google.protobuf.MessageOrBuilder {
       
           /**
            * optional string name = 1;
      @@ -13989,7 +13546,7 @@ public interface MetricFamilyOrBuilder extends
            * optional string name = 1;
            * @return The bytes for name.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    com.google.protobuf.ByteString
               getNameBytes();
       
           /**
      @@ -14006,7 +13563,7 @@ public interface MetricFamilyOrBuilder extends
            * optional string help = 2;
            * @return The bytes for help.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    com.google.protobuf.ByteString
               getHelpBytes();
       
           /**
      @@ -14018,17 +13575,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -14036,12 +13593,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -14058,19 +13615,28 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Met
            * optional string unit = 5;
            * @return The bytes for unit.
            */
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    com.google.protobuf.ByteString
               getUnitBytes();
         }
         /**
          * Protobuf type {@code io.prometheus.client.MetricFamily}
          */
         public static final class MetricFamily extends
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3 implements
      +      com.google.protobuf.GeneratedMessage implements
             // @@protoc_insertion_point(message_implements:io.prometheus.client.MetricFamily)
             MetricFamilyOrBuilder {
         private static final long serialVersionUID = 0L;
      +    static {
      +      com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
      +        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
      +        /* major= */ 4,
      +        /* minor= */ 28,
      +        /* patch= */ 2,
      +        /* suffix= */ "",
      +        MetricFamily.class.getName());
      +    }
           // Use MetricFamily.newBuilder() to construct.
      -    private MetricFamily(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder builder) {
      +    private MetricFamily(com.google.protobuf.GeneratedMessage.Builder builder) {
             super(builder);
           }
           private MetricFamily() {
      @@ -14081,24 +13647,17 @@ private MetricFamily() {
             unit_ = "";
           }
       
      -    @java.lang.Override
      -    @SuppressWarnings({"unused"})
      -    protected java.lang.Object newInstance(
      -        UnusedPrivateParameter unused) {
      -      return new MetricFamily();
      -    }
      -
      -    public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +    public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
      -    protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -14123,8 +13682,8 @@ public java.lang.String getName() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        com.google.protobuf.ByteString bs = 
      +            (com.google.protobuf.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 name_ = s;
      @@ -14137,17 +13696,17 @@ public java.lang.String getName() {
            * @return The bytes for name.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    public com.google.protobuf.ByteString
               getNameBytes() {
             java.lang.Object ref = name_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +        com.google.protobuf.ByteString b = 
      +            com.google.protobuf.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               name_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        return (com.google.protobuf.ByteString) ref;
             }
           }
       
      @@ -14172,8 +13731,8 @@ public java.lang.String getHelp() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        com.google.protobuf.ByteString bs = 
      +            (com.google.protobuf.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 help_ = s;
      @@ -14186,17 +13745,17 @@ public java.lang.String getHelp() {
            * @return The bytes for help.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    public com.google.protobuf.ByteString
               getHelpBytes() {
             java.lang.Object ref = help_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +        com.google.protobuf.ByteString b = 
      +            com.google.protobuf.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               help_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        return (com.google.protobuf.ByteString) ref;
             }
           }
       
      @@ -14213,26 +13772,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -14247,14 +13806,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -14280,8 +13839,8 @@ public java.lang.String getUnit() {
             if (ref instanceof java.lang.String) {
               return (java.lang.String) ref;
             } else {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs = 
      -            (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        com.google.protobuf.ByteString bs = 
      +            (com.google.protobuf.ByteString) ref;
               java.lang.String s = bs.toStringUtf8();
               if (bs.isValidUtf8()) {
                 unit_ = s;
      @@ -14294,17 +13853,17 @@ public java.lang.String getUnit() {
            * @return The bytes for unit.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +    public com.google.protobuf.ByteString
               getUnitBytes() {
             java.lang.Object ref = unit_;
             if (ref instanceof java.lang.String) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -            io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +        com.google.protobuf.ByteString b = 
      +            com.google.protobuf.ByteString.copyFromUtf8(
                       (java.lang.String) ref);
               unit_ = b;
               return b;
             } else {
      -        return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +        return (com.google.protobuf.ByteString) ref;
             }
           }
       
      @@ -14320,13 +13879,13 @@ public final boolean isInitialized() {
           }
       
           @java.lang.Override
      -    public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream output)
      +    public void writeTo(com.google.protobuf.CodedOutputStream output)
                               throws java.io.IOException {
             if (((bitField0_ & 0x00000001) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 1, name_);
      +        com.google.protobuf.GeneratedMessage.writeString(output, 1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 2, help_);
      +        com.google.protobuf.GeneratedMessage.writeString(output, 2, help_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
               output.writeEnum(3, type_);
      @@ -14335,7 +13894,7 @@ public void writeTo(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Code
               output.writeMessage(4, metric_.get(i));
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.writeString(output, 5, unit_);
      +        com.google.protobuf.GeneratedMessage.writeString(output, 5, unit_);
             }
             getUnknownFields().writeTo(output);
           }
      @@ -14347,21 +13906,21 @@ public int getSerializedSize() {
       
             size = 0;
             if (((bitField0_ & 0x00000001) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(1, name_);
      +        size += com.google.protobuf.GeneratedMessage.computeStringSize(1, name_);
             }
             if (((bitField0_ & 0x00000002) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(2, help_);
      +        size += com.google.protobuf.GeneratedMessage.computeStringSize(2, help_);
             }
             if (((bitField0_ & 0x00000004) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeEnumSize(3, type_);
             }
             for (int i = 0; i < metric_.size(); i++) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedOutputStream
      +        size += com.google.protobuf.CodedOutputStream
                 .computeMessageSize(4, metric_.get(i));
             }
             if (((bitField0_ & 0x00000008) != 0)) {
      -        size += io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.computeStringSize(5, unit_);
      +        size += com.google.protobuf.GeneratedMessage.computeStringSize(5, unit_);
             }
             size += getUnknownFields().getSerializedSize();
             memoizedSize = size;
      @@ -14373,10 +13932,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -14435,75 +13994,75 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
      +        com.google.protobuf.ByteString data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
      +        com.google.protobuf.ByteString data,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(byte[] data)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(byte[] data)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
               byte[] data,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -        throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +        throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
      +        com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily parseFrom(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily parseFrom(
      +        com.google.protobuf.CodedInputStream input,
      +        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      -      return io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3
      +      return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      @@ -14512,7 +14071,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14523,7 +14082,7 @@ public Builder toBuilder() {
       
           @java.lang.Override
           protected Builder newBuilderForType(
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
             Builder builder = new Builder(parent);
             return builder;
           }
      @@ -14531,29 +14090,29 @@ protected Builder newBuilderForType(
            * Protobuf type {@code io.prometheus.client.MetricFamily}
            */
           public static final class Builder extends
      -        io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.Builder implements
      +        com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamilyOrBuilder {
      -      public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamilyOrBuilder {
      +      public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      protected io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
       
             private Builder(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.BuilderParent parent) {
      +          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
               super(parent);
       
             }
      @@ -14576,19 +14135,19 @@ public Builder clear() {
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +      public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14596,15 +14155,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14616,7 +14175,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14639,49 +14198,17 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
             }
       
             @java.lang.Override
      -      public Builder clone() {
      -        return super.clone();
      -      }
      -      @java.lang.Override
      -      public Builder setField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.setField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder clearField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field) {
      -        return super.clearField(field);
      -      }
      -      @java.lang.Override
      -      public Builder clearOneof(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.OneofDescriptor oneof) {
      -        return super.clearOneof(oneof);
      -      }
      -      @java.lang.Override
      -      public Builder setRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          int index, java.lang.Object value) {
      -        return super.setRepeatedField(field, index, value);
      -      }
      -      @java.lang.Override
      -      public Builder addRepeatedField(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FieldDescriptor field,
      -          java.lang.Object value) {
      -        return super.addRepeatedField(field, value);
      -      }
      -      @java.lang.Override
      -      public Builder mergeFrom(io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily)other);
      +      public Builder mergeFrom(com.google.protobuf.Message other) {
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14714,7 +14241,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     metric_ = other.metric_;
                     bitField0_ = (bitField0_ & ~0x00000008);
                     metricBuilder_ = 
      -                io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.alwaysUseFieldBuilders ?
      +                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                          getMetricFieldBuilder() : null;
                   } else {
                     metricBuilder_.addAllMessages(other.metric_);
      @@ -14738,8 +14265,8 @@ public final boolean isInitialized() {
       
             @java.lang.Override
             public Builder mergeFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                 throws java.io.IOException {
               if (extensionRegistry == null) {
                 throw new java.lang.NullPointerException();
      @@ -14764,8 +14291,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14775,9 +14302,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.PARSER,
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14800,7 +14327,7 @@ public Builder mergeFrom(
                     } // default:
                   } // switch (tag)
                 } // while (!done)
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.unwrapIOException();
               } finally {
                 onChanged();
      @@ -14824,8 +14351,8 @@ public boolean hasName() {
             public java.lang.String getName() {
               java.lang.Object ref = name_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          com.google.protobuf.ByteString bs =
      +              (com.google.protobuf.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   name_ = s;
      @@ -14839,17 +14366,17 @@ public java.lang.String getName() {
              * optional string name = 1;
              * @return The bytes for name.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +      public com.google.protobuf.ByteString
                 getNameBytes() {
               java.lang.Object ref = name_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +          com.google.protobuf.ByteString b = 
      +              com.google.protobuf.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 name_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          return (com.google.protobuf.ByteString) ref;
               }
             }
             /**
      @@ -14881,7 +14408,7 @@ public Builder clearName() {
              * @return This builder for chaining.
              */
             public Builder setNameBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +          com.google.protobuf.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               name_ = value;
               bitField0_ |= 0x00000001;
      @@ -14904,8 +14431,8 @@ public boolean hasHelp() {
             public java.lang.String getHelp() {
               java.lang.Object ref = help_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          com.google.protobuf.ByteString bs =
      +              (com.google.protobuf.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   help_ = s;
      @@ -14919,17 +14446,17 @@ public java.lang.String getHelp() {
              * optional string help = 2;
              * @return The bytes for help.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +      public com.google.protobuf.ByteString
                 getHelpBytes() {
               java.lang.Object ref = help_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +          com.google.protobuf.ByteString b = 
      +              com.google.protobuf.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 help_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          return (com.google.protobuf.ByteString) ref;
               }
             }
             /**
      @@ -14961,7 +14488,7 @@ public Builder clearHelp() {
              * @return This builder for chaining.
              */
             public Builder setHelpBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +          com.google.protobuf.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               help_ = value;
               bitField0_ |= 0x00000002;
      @@ -14982,16 +14509,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -15011,22 +14538,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder> metricBuilder_;
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -15046,7 +14573,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -15057,7 +14584,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -15074,7 +14601,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -15087,7 +14614,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -15104,7 +14631,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -15121,7 +14648,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -15135,7 +14662,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -15149,10 +14676,10 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractMessageLite.Builder.addAll(
      +          com.google.protobuf.AbstractMessageLite.Builder.addAll(
                     values, metric_);
                 onChanged();
               } else {
      @@ -15189,14 +14716,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -15206,7 +14733,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -15217,31 +14744,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder addMetricBuilder() {
               return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return getMetricFieldBuilder().getBuilderList();
             }
      -      private io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder> 
      +      private com.google.protobuf.RepeatedFieldBuilder<
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder> 
                 getMetricFieldBuilder() {
               if (metricBuilder_ == null) {
      -          metricBuilder_ = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.RepeatedFieldBuilderV3<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricOrBuilder>(
      +          metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -15266,8 +14793,8 @@ public boolean hasUnit() {
             public java.lang.String getUnit() {
               java.lang.Object ref = unit_;
               if (!(ref instanceof java.lang.String)) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString bs =
      -              (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          com.google.protobuf.ByteString bs =
      +              (com.google.protobuf.ByteString) ref;
                 java.lang.String s = bs.toStringUtf8();
                 if (bs.isValidUtf8()) {
                   unit_ = s;
      @@ -15281,17 +14808,17 @@ public java.lang.String getUnit() {
              * optional string unit = 5;
              * @return The bytes for unit.
              */
      -      public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString
      +      public com.google.protobuf.ByteString
                 getUnitBytes() {
               java.lang.Object ref = unit_;
               if (ref instanceof String) {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString b = 
      -              io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString.copyFromUtf8(
      +          com.google.protobuf.ByteString b = 
      +              com.google.protobuf.ByteString.copyFromUtf8(
                         (java.lang.String) ref);
                 unit_ = b;
                 return b;
               } else {
      -          return (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString) ref;
      +          return (com.google.protobuf.ByteString) ref;
               }
             }
             /**
      @@ -15323,143 +14850,131 @@ public Builder clearUnit() {
              * @return This builder for chaining.
              */
             public Builder setUnitBytes(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ByteString value) {
      +          com.google.protobuf.ByteString value) {
               if (value == null) { throw new NullPointerException(); }
               unit_ = value;
               bitField0_ |= 0x00000010;
               onChanged();
               return this;
             }
      -      @java.lang.Override
      -      public final Builder setUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.setUnknownFields(unknownFields);
      -      }
      -
      -      @java.lang.Override
      -      public final Builder mergeUnknownFields(
      -          final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UnknownFieldSet unknownFields) {
      -        return super.mergeUnknownFields(unknownFields);
      -      }
      -
       
             // @@protoc_insertion_point(builder_scope:io.prometheus.client.MetricFamily)
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      -    @java.lang.Deprecated public static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser
      -        PARSER = new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.AbstractParser() {
      +    private static final com.google.protobuf.Parser
      +        PARSER = new com.google.protobuf.AbstractParser() {
             @java.lang.Override
             public MetricFamily parsePartialFrom(
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.CodedInputStream input,
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.ExtensionRegistryLite extensionRegistry)
      -          throws io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException {
      +          com.google.protobuf.CodedInputStream input,
      +          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      +          throws com.google.protobuf.InvalidProtocolBufferException {
               Builder builder = newBuilder();
               try {
                 builder.mergeFrom(input, extensionRegistry);
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException e) {
      +        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                 throw e.setUnfinishedMessage(builder.buildPartial());
      -        } catch (io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.UninitializedMessageException e) {
      +        } catch (com.google.protobuf.UninitializedMessageException e) {
                 throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
               } catch (java.io.IOException e) {
      -          throw new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.InvalidProtocolBufferException(e)
      +          throw new com.google.protobuf.InvalidProtocolBufferException(e)
                     .setUnfinishedMessage(builder.buildPartial());
               }
               return builder.buildPartial();
             }
           };
       
      -    public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser parser() {
      +    public static com.google.protobuf.Parser parser() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Parser getParserForType() {
      +    public com.google.protobuf.Parser getParserForType() {
             return PARSER;
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
         }
       
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_LabelPair_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_LabelPair_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Gauge_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Gauge_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Counter_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Counter_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Quantile_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Quantile_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Summary_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Summary_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Untyped_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Untyped_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Histogram_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Histogram_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Bucket_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Bucket_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_BucketSpan_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Exemplar_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Exemplar_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_Metric_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_Metric_fieldAccessorTable;
      -  private static final io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.Descriptor
      +  private static final com.google.protobuf.Descriptors.Descriptor
           internal_static_io_prometheus_client_MetricFamily_descriptor;
         private static final 
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable
      +    com.google.protobuf.GeneratedMessage.FieldAccessorTable
             internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable;
       
      -  public static io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
      +  public static com.google.protobuf.Descriptors.FileDescriptor
             getDescriptor() {
           return descriptor;
         }
      -  private static  io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
      +  private static  com.google.protobuf.Descriptors.FileDescriptor
             descriptor;
         static {
           java.lang.String[] descriptorData = {
      @@ -15513,87 +15028,88 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_2
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_3_25_3Z:github.com/prometheus/clien" +
      +      "obuf_4_28_2Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
      -    descriptor = io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor
      +    descriptor = com.google.protobuf.Descriptors.FileDescriptor
             .internalBuildGeneratedFileFrom(descriptorData,
      -        new io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Descriptors.FileDescriptor[] {
      -          io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampProto.getDescriptor(),
      +        new com.google.protobuf.Descriptors.FileDescriptor[] {
      +          com.google.protobuf.TimestampProto.getDescriptor(),
               });
           internal_static_io_prometheus_client_LabelPair_descriptor =
             getDescriptor().getMessageTypes().get(0);
           internal_static_io_prometheus_client_LabelPair_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_LabelPair_descriptor,
               new java.lang.String[] { "Name", "Value", });
           internal_static_io_prometheus_client_Gauge_descriptor =
             getDescriptor().getMessageTypes().get(1);
           internal_static_io_prometheus_client_Gauge_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Gauge_descriptor,
               new java.lang.String[] { "Value", });
           internal_static_io_prometheus_client_Counter_descriptor =
             getDescriptor().getMessageTypes().get(2);
           internal_static_io_prometheus_client_Counter_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Counter_descriptor,
               new java.lang.String[] { "Value", "Exemplar", "CreatedTimestamp", });
           internal_static_io_prometheus_client_Quantile_descriptor =
             getDescriptor().getMessageTypes().get(3);
           internal_static_io_prometheus_client_Quantile_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Quantile_descriptor,
               new java.lang.String[] { "Quantile", "Value", });
           internal_static_io_prometheus_client_Summary_descriptor =
             getDescriptor().getMessageTypes().get(4);
           internal_static_io_prometheus_client_Summary_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Summary_descriptor,
               new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", "CreatedTimestamp", });
           internal_static_io_prometheus_client_Untyped_descriptor =
             getDescriptor().getMessageTypes().get(5);
           internal_static_io_prometheus_client_Untyped_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Untyped_descriptor,
               new java.lang.String[] { "Value", });
           internal_static_io_prometheus_client_Histogram_descriptor =
             getDescriptor().getMessageTypes().get(6);
           internal_static_io_prometheus_client_Histogram_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Histogram_descriptor,
               new java.lang.String[] { "SampleCount", "SampleCountFloat", "SampleSum", "Bucket", "CreatedTimestamp", "Schema", "ZeroThreshold", "ZeroCount", "ZeroCountFloat", "NegativeSpan", "NegativeDelta", "NegativeCount", "PositiveSpan", "PositiveDelta", "PositiveCount", "Exemplars", });
           internal_static_io_prometheus_client_Bucket_descriptor =
             getDescriptor().getMessageTypes().get(7);
           internal_static_io_prometheus_client_Bucket_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Bucket_descriptor,
               new java.lang.String[] { "CumulativeCount", "CumulativeCountFloat", "UpperBound", "Exemplar", });
           internal_static_io_prometheus_client_BucketSpan_descriptor =
             getDescriptor().getMessageTypes().get(8);
           internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_BucketSpan_descriptor,
               new java.lang.String[] { "Offset", "Length", });
           internal_static_io_prometheus_client_Exemplar_descriptor =
             getDescriptor().getMessageTypes().get(9);
           internal_static_io_prometheus_client_Exemplar_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Exemplar_descriptor,
               new java.lang.String[] { "Label", "Value", "Timestamp", });
           internal_static_io_prometheus_client_Metric_descriptor =
             getDescriptor().getMessageTypes().get(10);
           internal_static_io_prometheus_client_Metric_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_Metric_descriptor,
               new java.lang.String[] { "Label", "Gauge", "Counter", "Summary", "Untyped", "Histogram", "TimestampMs", });
           internal_static_io_prometheus_client_MetricFamily_descriptor =
             getDescriptor().getMessageTypes().get(11);
           internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable = new
      -      io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.GeneratedMessageV3.FieldAccessorTable(
      +      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_io_prometheus_client_MetricFamily_descriptor,
               new java.lang.String[] { "Name", "Help", "Type", "Metric", "Unit", });
      -    io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TimestampProto.getDescriptor();
      +    descriptor.resolveAllFeaturesImmutable();
      +    com.google.protobuf.TimestampProto.getDescriptor();
         }
       
         // @@protoc_insertion_point(outer_class_scope)
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      index 1c1535de3..7e722b056 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java
      @@ -2,7 +2,8 @@
       
       import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
      +import com.google.protobuf.TextFormat;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      @@ -20,7 +21,6 @@
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
       import java.io.IOException;
       import java.io.OutputStream;
       
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      index fee5d8eb1..5b192c23d 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java
      @@ -1,6 +1,6 @@
       package io.prometheus.metrics.expositionformats;
       
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.Timestamp;
      +import com.google.protobuf.Timestamp;
       
       public class ProtobufUtil {
       
      diff --git a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto b/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
      deleted file mode 100644
      index 724f96643..000000000
      --- a/prometheus-metrics-exposition-formats/src/main/protobuf/metrics.proto
      +++ /dev/null
      @@ -1,157 +0,0 @@
      -// Copyright 2013 Prometheus Team
      -// Licensed under the Apache License, Version 2.0 (the "License");
      -// you may not use this file except in compliance with the License.
      -// You may obtain a copy of the License at
      -//
      -// http://www.apache.org/licenses/LICENSE-2.0
      -//
      -// Unless required by applicable law or agreed to in writing, software
      -// distributed under the License is distributed on an "AS IS" BASIS,
      -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      -// See the License for the specific language governing permissions and
      -// limitations under the License.
      -
      -syntax = "proto2";
      -
      -package io.prometheus.client;
      -option java_package = "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3";
      -option go_package = "github.com/prometheus/client_model/go;io_prometheus_client";
      -
      -import "google/protobuf/timestamp.proto";
      -
      -message LabelPair {
      -  optional string name  = 1;
      -  optional string value = 2;
      -}
      -
      -enum MetricType {
      -  // COUNTER must use the Metric field "counter".
      -  COUNTER = 0;
      -  // GAUGE must use the Metric field "gauge".
      -  GAUGE = 1;
      -  // SUMMARY must use the Metric field "summary".
      -  SUMMARY = 2;
      -  // UNTYPED must use the Metric field "untyped".
      -  UNTYPED = 3;
      -  // HISTOGRAM must use the Metric field "histogram".
      -  HISTOGRAM = 4;
      -  // GAUGE_HISTOGRAM must use the Metric field "histogram".
      -  GAUGE_HISTOGRAM = 5;
      -}
      -
      -message Gauge {
      -  optional double value = 1;
      -}
      -
      -message Counter {
      -  optional double   value    = 1;
      -  optional Exemplar exemplar = 2;
      -
      -  optional google.protobuf.Timestamp  created_timestamp = 3;
      -}
      -
      -message Quantile {
      -  optional double quantile = 1;
      -  optional double value    = 2;
      -}
      -
      -message Summary {
      -  optional uint64   sample_count = 1;
      -  optional double   sample_sum   = 2;
      -  repeated Quantile quantile     = 3;
      -
      -  optional google.protobuf.Timestamp  created_timestamp = 4;
      -}
      -
      -message Untyped {
      -  optional double value = 1;
      -}
      -
      -message Histogram {
      -  optional uint64 sample_count       = 1;
      -  optional double sample_count_float = 4; // Overrides sample_count if > 0.
      -  optional double sample_sum         = 2;
      -  // Buckets for the conventional histogram.
      -  repeated Bucket bucket             = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
      -
      -  optional google.protobuf.Timestamp created_timestamp = 15;
      -
      -  // Everything below here is for native histograms (also known as sparse histograms).
      -  // Native histograms are an experimental feature without stability guarantees.
      -
      -  // schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
      -  // They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
      -  // then each power of two is divided into 2^n logarithmic buckets.
      -  // Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
      -  // In the future, more bucket schemas may be added using numbers < -4 or > 8.
      -  optional sint32 schema           = 5;
      -  optional double zero_threshold   = 6; // Breadth of the zero bucket.
      -  optional uint64 zero_count       = 7; // Count in zero bucket.
      -  optional double zero_count_float = 8; // Overrides sb_zero_count if > 0.
      -
      -  // Negative buckets for the native histogram.
      -  repeated BucketSpan negative_span =  9;
      -  // Use either "negative_delta" or "negative_count", the former for
      -  // regular histograms with integer counts, the latter for float
      -  // histograms.
      -  repeated sint64 negative_delta    = 10; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
      -  repeated double negative_count    = 11; // Absolute count of each bucket.
      -
      -  // Positive buckets for the native histogram.
      -  // Use a no-op span (offset 0, length 0) for a native histogram without any
      -  // observations yet and with a zero_threshold of 0. Otherwise, it would be
      -  // indistinguishable from a classic histogram.
      -  repeated BucketSpan positive_span = 12;
      -  // Use either "positive_delta" or "positive_count", the former for
      -  // regular histograms with integer counts, the latter for float
      -  // histograms.
      -  repeated sint64 positive_delta    = 13; // Count delta of each bucket compared to previous one (or to zero for 1st bucket).
      -  repeated double positive_count    = 14; // Absolute count of each bucket.
      -
      -  // Only used for native histograms. These exemplars MUST have a timestamp.
      -  repeated Exemplar exemplars = 16;
      -}
      -
      -// A Bucket of a conventional histogram, each of which is treated as
      -// an individual counter-like time series by Prometheus.
      -message Bucket {
      -  optional uint64   cumulative_count       = 1; // Cumulative in increasing order.
      -  optional double   cumulative_count_float = 4; // Overrides cumulative_count if > 0.
      -  optional double   upper_bound            = 2; // Inclusive.
      -  optional Exemplar exemplar               = 3;
      -}
      -
      -// A BucketSpan defines a number of consecutive buckets in a native
      -// histogram with their offset. Logically, it would be more
      -// straightforward to include the bucket counts in the Span. However,
      -// the protobuf representation is more compact in the way the data is
      -// structured here (with all the buckets in a single array separate
      -// from the Spans).
      -message BucketSpan {
      -  optional sint32 offset = 1; // Gap to previous span, or starting point for 1st span (which can be negative).
      -  optional uint32 length = 2; // Length of consecutive buckets.
      -}
      -
      -message Exemplar {
      -  repeated LabelPair                 label     = 1;
      -  optional double                    value     = 2;
      -  optional google.protobuf.Timestamp timestamp = 3; // OpenMetrics-style.
      -}
      -
      -message Metric {
      -  repeated LabelPair label        = 1;
      -  optional Gauge     gauge        = 2;
      -  optional Counter   counter      = 3;
      -  optional Summary   summary      = 4;
      -  optional Untyped   untyped      = 5;
      -  optional Histogram histogram    = 7;
      -  optional int64     timestamp_ms = 6;
      -}
      -
      -message MetricFamily {
      -  optional string     name   = 1;
      -  optional string     help   = 2;
      -  optional MetricType type   = 3;
      -  repeated Metric     metric = 4;
      -  optional string     unit   = 5;
      -}
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      index 307b88938..5174b2d8e 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      @@ -2,13 +2,13 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
      +import com.google.protobuf.TextFormat;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics;
       import io.prometheus.metrics.model.snapshots.*;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
       import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot;
      -import io.prometheus.metrics.shaded.com_google_protobuf_3_25_3.TextFormat;
       import java.io.ByteArrayOutputStream;
       import java.io.IOException;
       import org.junit.jupiter.api.Test;
      diff --git a/prometheus-metrics-shaded-dependencies/pom.xml b/prometheus-metrics-shaded-dependencies/pom.xml
      deleted file mode 100644
      index 1fb820cc3..000000000
      --- a/prometheus-metrics-shaded-dependencies/pom.xml
      +++ /dev/null
      @@ -1,23 +0,0 @@
      -
      -
      -    4.0.0
      -
      -    
      -        io.prometheus
      -        client_java
      -        1.4.0-SNAPSHOT
      -    
      -
      -    prometheus-metrics-shaded-dependencies
      -    pom
      -
      -    Shaded Dependencies
      -    
      -        Shaded (relocated to another packagage) dependencies.
      -    
      -
      -    
      -        prometheus-metrics-shaded-protobuf
      -    
      -
      -
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      deleted file mode 100644
      index dc65c892c..000000000
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/pom.xml
      +++ /dev/null
      @@ -1,75 +0,0 @@
      -
      -
      -    4.0.0
      -
      -    
      -        io.prometheus
      -        prometheus-metrics-shaded-dependencies
      -        1.4.0-SNAPSHOT
      -    
      -
      -    prometheus-metrics-shaded-protobuf
      -
      -    Shaded Protobuf
      -    
      -        Shaded (reolocated to another package) dependencies for the Protobuf library used to create the Prometheus
      -        Protobuf format
      -    
      -
      -
      -    
      -        
      -        
      -        3.25.5
      -        
      -        3_25_3
      -    
      -
      -    
      -        
      -            com.google.protobuf
      -            protobuf-java
      -            ${protobuf.version}
      -        
      -    
      -
      -    
      -        
      -            
      -                org.apache.maven.plugins
      -                maven-shade-plugin
      -                
      -                    
      -                        package
      -                        
      -                            shade
      -                        
      -                        
      -                            true
      -                            true
      -                            
      -                                
      -                                    com.google.protobuf
      -                                    io.prometheus.metrics.shaded.com_google_protobuf_${protobuf.version.string}
      -                                
      -                            
      -                            
      -                                
      -                            
      -                            
      -                                
      -                                    *:*
      -                                    
      -                                        META-INF/maven/com.google.protobuf/**
      -                                        **/*.proto
      -                                        META-INF/MANIFEST.MF
      -                                    
      -                                
      -                            
      -                        
      -                    
      -                
      -            
      -        
      -    
      -
      diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java
      deleted file mode 100644
      index 9d78ee8e1..000000000
      --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/src/main/java/io/prometheus/metrics/shaded/com_google_protobuf/PrometheusMetricsShadedProtobuf.java
      +++ /dev/null
      @@ -1,9 +0,0 @@
      -package io.prometheus.metrics.shaded.com_google_protobuf;
      -
      -/**
      - * This module does not need any source code, however, in order to publish it to Maven central it
      - * needs JavaDoc.
      - *
      - * 

      I'm adding this dummy class here to get JavaDoc so I can publish this module to Maven central. - */ -public class PrometheusMetricsShadedProtobuf {} diff --git a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml b/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml deleted file mode 100644 index 76f8da4fd..000000000 --- a/prometheus-metrics-shaded-dependencies/prometheus-metrics-shaded-protobuf/version-rules.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file From 9581eeb0e8098e3017fa167f5c32e51ea07d4619 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 9 Oct 2024 15:13:59 +0200 Subject: [PATCH 409/980] fix gh pages (#1130) Signed-off-by: Gregor Zeitlinger --- .github/workflows/github-pages.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index d78e6d4a3..43a6fd94d 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -32,16 +32,14 @@ jobs: runs-on: ubuntu-latest env: HUGO_VERSION: 0.115.4 - JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64 steps: + - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin cache: 'maven' - - name: Install Protoc - uses: zchee/setup-protoc@v1 - name: Install Hugo CLI run: | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ From 740969400000c642704581cd0734f280633feb97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:07:39 +0200 Subject: [PATCH 410/980] Bump org.codehaus.mojo:versions-maven-plugin from 2.10.0 to 2.17.1 (#1131) Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.10.0 to 2.17.1. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/versions-maven-plugin-2.10.0...2.17.1) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41bb926f..a3c5ceb1a 100644 --- a/pom.xml +++ b/pom.xml @@ -277,7 +277,7 @@ org.codehaus.mojo versions-maven-plugin - 2.10.0 + 2.17.1 file://${project.basedir}/version-rules.xml From cdb753333406e2291a537f01394b941564949d36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:15:38 +0200 Subject: [PATCH 411/980] Bump org.apache.maven.plugins:maven-clean-plugin from 2.5 to 3.4.0 (#1135) Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 2.5 to 3.4.0. - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-2.5...maven-clean-plugin-3.4.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a3c5ceb1a..c9f9b59e0 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ maven-clean-plugin - 2.5 + 3.4.0 maven-site-plugin From 7805ed2bb971efbc76c51250fd2eb64dd1ab514f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:35:04 +0200 Subject: [PATCH 412/980] Bump commons-io:commons-io from 2.16.1 to 2.17.0 (#1134) Bumps commons-io:commons-io from 2.16.1 to 2.17.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 5f798cc1b..97748af84 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -29,7 +29,7 @@ commons-io commons-io - 2.16.1 + 2.17.0 test From a0bf173a2a3ed38847ff3022f8d085b45e14aa2e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 9 Oct 2024 17:45:23 +0200 Subject: [PATCH 413/980] fix bug (that should have shown before) (#1136) Signed-off-by: Gregor Zeitlinger --- CONTRIBUTING.md | 6 ++++++ .../io/prometheus/metrics/core/metrics/CounterTest.java | 2 +- .../io/prometheus/metrics/core/metrics/HistogramTest.java | 4 ++-- .../java/io/prometheus/metrics/core/metrics/InfoTest.java | 2 +- .../io/prometheus/metrics/core/metrics/SummaryTest.java | 2 +- .../metrics/expositionformats/ExpositionFormatsTest.java | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e1eb867c..dbac64dd5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,3 +16,9 @@ Prometheus uses GitHub to manage reviews of pull requests. 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. + +## Running Tests + +If you're getting errors when running tests: + +- Make sure that the IDE uses only the "Maven Shade" dependency of "prometheus-metrics-exposition-formats" and the "prometheus-metrics-tracer*" dependencies. diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 3e87d378c..9dfe8af7e 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -113,7 +113,7 @@ public void testTotalStrippedFromName() { }) { Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build(); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormat.printer().printToString(protobufData)) .isEqualTo( "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }"); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index ad514e9d0..46b755907 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -92,7 +92,7 @@ private void run() throws NoSuchFieldException, IllegalAccessException { new PrometheusProtobufWriter().convert(histogram.collect()); String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormat.printer().printToString(protobufData)) .as("test \"" + name + "\" failed") .isEqualTo(expectedWithMetadata); } @@ -941,7 +941,7 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - assertThat(TextFormat.printer().shortDebugString(protobufData)).isEqualTo(expectedProtobuf); + assertThat(TextFormat.printer().printToString(protobufData)).isEqualTo(expectedProtobuf); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 4ea61a801..3728f8eee 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -27,7 +27,7 @@ public void testInfoStrippedFromName() { Info info = Info.builder().name(name).labelNames(labelName).build(); info.addLabelValues("value"); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormat.printer().printToString(protobufData)) .isEqualTo( "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }"); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java index b369ed8fb..642340e13 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SummaryTest.java @@ -128,7 +128,7 @@ public void testMaxAge() throws InterruptedException { assertThat(getQuantile(summary, 0.99, Labels.EMPTY)).isEqualTo(8.0); // From bucket 2. Thread.sleep(600); assertThat(getQuantile(summary, 0.99, Labels.EMPTY)) - .isEqualTo(Double.NaN); // Bucket 1 again, now it is empty. + .isNaN(); // Bucket 1 again, now it is empty. } @Test diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 5174b2d8e..61d8fbb64 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2634,7 +2634,7 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = TextFormat.printer().shortDebugString(protobufData); + String actual = TextFormat.printer().printToString(protobufData); assertThat(actual).isEqualTo(expected); } } From 9af5f2821259ecf4db63539b3e9accbdea432cc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:45:42 +0200 Subject: [PATCH 414/980] Bump org.apache.maven.plugins:maven-dependency-plugin (#1133) Bumps [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.1.2 to 3.8.0. - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.1.2...maven-dependency-plugin-3.8.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c9f9b59e0..f448a4811 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@ maven-dependency-plugin - 3.1.2 + 3.8.0 maven-javadoc-plugin From 8d887a0f9773133050fd241efb2e7cd0ef287979 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 18:19:18 +0200 Subject: [PATCH 415/980] Bump org.apache.maven.plugins:maven-surefire-plugin from 2.12.4 to 3.5.1 (#1132) * Bump org.apache.maven.plugins:maven-surefire-plugin from 2.12.4 to 3.5.1 Bumps [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) from 2.12.4 to 3.5.1. - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.12.4...surefire-3.5.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix build Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- .../metrics/core/metrics/CounterTest.java | 2 +- .../metrics/core/metrics/HistogramTest.java | 4 +-- .../metrics/core/metrics/InfoTest.java | 2 +- prometheus-metrics-exposition-formats/pom.xml | 31 +++++++------------ .../ExpositionFormatsTest.java | 2 +- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index f448a4811..3e8a2809a 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ maven-surefire-plugin - 2.12.4 + 3.5.1 maven-jar-plugin diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 9dfe8af7e..3e87d378c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -113,7 +113,7 @@ public void testTotalStrippedFromName() { }) { Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build(); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertThat(TextFormat.printer().printToString(protobufData)) + assertThat(TextFormat.printer().shortDebugString(protobufData)) .isEqualTo( "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }"); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 46b755907..ad514e9d0 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -92,7 +92,7 @@ private void run() throws NoSuchFieldException, IllegalAccessException { new PrometheusProtobufWriter().convert(histogram.collect()); String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; - assertThat(TextFormat.printer().printToString(protobufData)) + assertThat(TextFormat.printer().shortDebugString(protobufData)) .as("test \"" + name + "\" failed") .isEqualTo(expectedWithMetadata); } @@ -941,7 +941,7 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - assertThat(TextFormat.printer().printToString(protobufData)).isEqualTo(expectedProtobuf); + assertThat(TextFormat.printer().shortDebugString(protobufData)).isEqualTo(expectedProtobuf); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 3728f8eee..4ea61a801 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -27,7 +27,7 @@ public void testInfoStrippedFromName() { Info info = Info.builder().name(name).labelNames(labelName).build(); info.addLabelValues("value"); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertThat(TextFormat.printer().printToString(protobufData)) + assertThat(TextFormat.printer().shortDebugString(protobufData)) .isEqualTo( "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }"); } diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index b8c8bf508..b5d9f75bd 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -73,6 +73,18 @@ + + add-source + generate-sources + + add-source + + + + src/main/generated/ + + + @@ -97,25 +109,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.0 - - - add-source - generate-sources - - add-source - - - - src/main/generated/ - - - - - maven-javadoc-plugin diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 61d8fbb64..5174b2d8e 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2634,7 +2634,7 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = TextFormat.printer().printToString(protobufData); + String actual = TextFormat.printer().shortDebugString(protobufData); assertThat(actual).isEqualTo(expected); } } From 68849a8ef68605ad0af0c6b9129e09a2e8b6e746 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 10 Oct 2024 07:23:34 +0200 Subject: [PATCH 416/980] fix shading (#1137) Signed-off-by: Gregor Zeitlinger --- .../io/prometheus/metrics/core/metrics/CounterTest.java | 4 ++-- .../io/prometheus/metrics/core/metrics/HistogramTest.java | 6 +++--- .../java/io/prometheus/metrics/core/metrics/InfoTest.java | 4 ++-- prometheus-metrics-exposition-formats/pom.xml | 5 +++++ .../metrics/expositionformats/TextFormatUtil.java | 6 ++++++ .../metrics/expositionformats/ExpositionFormatsTest.java | 3 +-- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 3e87d378c..a87153ec6 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -7,13 +7,13 @@ import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Label; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.Unit; -import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import java.util.Arrays; @@ -113,7 +113,7 @@ public void testTotalStrippedFromName() { }) { Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build(); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormatUtil.shortDebugString(protobufData)) .isEqualTo( "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }"); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index ad514e9d0..4d55c3236 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -9,6 +9,7 @@ import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; import io.prometheus.metrics.model.snapshots.Exemplar; @@ -16,7 +17,6 @@ import io.prometheus.metrics.model.snapshots.HistogramSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.initializer.SpanContextSupplier; import java.io.ByteArrayOutputStream; @@ -92,7 +92,7 @@ private void run() throws NoSuchFieldException, IllegalAccessException { new PrometheusProtobufWriter().convert(histogram.collect()); String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormatUtil.shortDebugString(protobufData)) .as("test \"" + name + "\" failed") .isEqualTo(expectedWithMetadata); } @@ -941,7 +941,7 @@ public void testDefaults() throws IOException { // protobuf Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - assertThat(TextFormat.printer().shortDebugString(protobufData)).isEqualTo(expectedProtobuf); + assertThat(TextFormatUtil.shortDebugString(protobufData)).isEqualTo(expectedProtobuf); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 4ea61a801..e3b06ecc8 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -5,10 +5,10 @@ import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; +import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import io.prometheus.metrics.shaded.com_google_protobuf_4_28_2.TextFormat; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -27,7 +27,7 @@ public void testInfoStrippedFromName() { Info info = Info.builder().name(name).labelNames(labelName).build(); info.addLabelValues("value"); Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertThat(TextFormat.printer().shortDebugString(protobufData)) + assertThat(TextFormatUtil.shortDebugString(protobufData)) .isEqualTo( "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }"); } diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index b5d9f75bd..4f2f35422 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -127,6 +127,11 @@ true true + + + com.google.protobuf:protobuf-java + + com.google.protobuf diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index 54daaaa3e..da64f30bb 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -1,5 +1,7 @@ package io.prometheus.metrics.expositionformats; +import com.google.protobuf.MessageOrBuilder; +import com.google.protobuf.TextFormat; import io.prometheus.metrics.model.snapshots.Labels; import java.io.IOException; import java.io.OutputStreamWriter; @@ -81,4 +83,8 @@ static void writeLabels( } writer.write('}'); } + + public static String shortDebugString(MessageOrBuilder protobufData) { + return TextFormat.printer().shortDebugString(protobufData); + } } diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 5174b2d8e..7a7a0ea7e 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.google.protobuf.TextFormat; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.*; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; @@ -2634,7 +2633,7 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = TextFormat.printer().shortDebugString(protobufData); + String actual = TextFormatUtil.shortDebugString(protobufData); assertThat(actual).isEqualTo(expected); } } From eb48f5d1ea6de3e8833f8c3898191ef6bc7844a3 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 10 Oct 2024 08:58:01 +0200 Subject: [PATCH 417/980] fix all warnings (#1138) * fix warnings Signed-off-by: Gregor Zeitlinger * fix warnings Signed-off-by: Gregor Zeitlinger * fix warnings Signed-off-by: Gregor Zeitlinger * fix warnings Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .../example-greeting-service/pom.xml | 13 +++++++++++ .../greeting/GreetingServlet.java | 2 ++ .../example-hello-world-app/pom.xml | 13 +++++++++++ .../otel_exemplars/app/HelloWorldServlet.java | 2 ++ .../multitarget/SampleMultiCollector.java | 5 ++--- .../example-exporter-servlet-tomcat/pom.xml | 13 +++++++++++ .../tomcat_servlet/HelloWorldServlet.java | 2 ++ .../it-exporter-servlet-tomcat-sample/pom.xml | 13 +++++++++++ pom.xml | 12 +++++++--- .../config/PrometheusPropertiesException.java | 2 ++ .../metrics/core/datapoints/TimerApi.java | 9 +++++--- .../metrics/core/metrics/Metric.java | 2 +- .../metrics/core/metrics/SlidingWindow.java | 1 + .../metrics/core/metrics/StatefulMetric.java | 5 +++-- .../metrics/core/metrics/GaugeTest.java | 3 ++- .../PrometheusMetricProducer.java | 10 ++++----- .../exporter/opentelemetry/ExemplarTest.java | 6 +++-- .../pom.xml | 21 +++++++++++++++++- .../jakarta/PrometheusMetricsServlet.java | 2 ++ .../javax/PrometheusMetricsServlet.java | 2 ++ .../OpenMetricsTextFormatWriter.java | 2 +- .../PrometheusProtobufWriter.java | 6 ++--- .../PrometheusTextFormatWriter.java | 7 +++--- .../expositionformats/TextFormatUtil.java | 2 +- .../ExpositionFormatsTest.java | 14 +++++++----- .../caffeine/CacheMetricsCollector.java | 13 ++++++----- .../dropwizard5/DropwizardExports.java | 15 +++++++------ .../guava/CacheMetricsCollector.java | 14 ++++++------ .../JvmMemoryPoolAllocationMetricsTest.java | 2 +- .../jvm/JvmThreadsMetricsTest.java | 2 +- .../metrics/model/registry/Collector.java | 12 +++++----- .../model/registry/MultiCollector.java | 2 +- .../model/registry/PrometheusRegistry.java | 8 +++---- .../model/snapshots/CounterSnapshot.java | 4 ++-- .../snapshots/DuplicateLabelsException.java | 2 ++ .../model/snapshots/GaugeSnapshot.java | 4 ++-- .../model/snapshots/HistogramSnapshot.java | 5 +++-- .../metrics/model/snapshots/InfoSnapshot.java | 4 ++-- .../model/snapshots/MetricSnapshot.java | 18 +++++---------- .../model/snapshots/MetricSnapshots.java | 22 +++++++++---------- .../model/snapshots/StateSetSnapshot.java | 5 +++-- .../model/snapshots/SummarySnapshot.java | 5 +++-- .../model/snapshots/UnknownSnapshot.java | 5 +++-- .../registry/PrometheusRegistryTest.java | 8 +++---- .../model/snapshots/MetricSnapshotTest.java | 2 +- .../model/snapshots/MetricSnapshotsTest.java | 2 +- .../model/snapshots/SnapshotTestUtil.java | 2 +- .../bridge/SimpleclientCollector.java | 14 ++++++------ 48 files changed, 220 insertions(+), 119 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 530c74cea..fc329b061 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -41,6 +41,19 @@ ${project.artifactId} + + maven-compiler-plugin + + 17 + 17 + 17 + true + + -Xlint:all + -Werror + + + org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java index af1652f76..45b2c8a79 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -13,6 +13,8 @@ /** Hello World REST servlet, with an example counter and an example histogram. */ public class GreetingServlet extends HttpServlet { + private static final long serialVersionUID = 0L; + private final Random random = new Random(0); private final Histogram histogram; diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 88ad9c667..e7ab8cbd6 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -41,6 +41,19 @@ ${project.artifactId} + + maven-compiler-plugin + + 17 + 17 + 17 + true + + -Xlint:all + -Werror + + + org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java index fbe293d50..f5a90d977 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -20,6 +20,8 @@ /** Hello World REST servlet, with an example counter and an example histogram. */ public class HelloWorldServlet extends HttpServlet { + private static final long serialVersionUID = 0L; + private final Random random = new Random(0); private final Histogram histogram; diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java index 7a05f0a8b..f9cea3f87 100644 --- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java @@ -71,11 +71,10 @@ protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeR gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); } } - Collection snaps = new ArrayList(); + Collection> snaps = new ArrayList<>(); snaps.add(counterBuilder.build()); snaps.add(gaugeBuilder.build()); - MetricSnapshots msnaps = new MetricSnapshots(snaps); - return msnaps; + return new MetricSnapshots(snaps); } public List getPrometheusNames() { diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index b253d7c50..357dd3118 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -41,6 +41,19 @@ ${project.artifactId} + + maven-compiler-plugin + + 17 + 17 + 17 + true + + -Xlint:all + -Werror + + + org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index eb2fa4f19..e2b654f34 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -14,6 +14,8 @@ /** Hello World REST servlet, with an example counter and an example histogram. */ public class HelloWorldServlet extends HttpServlet { + private static final long serialVersionUID = 0L; + private final Random random = new Random(0); // Note: The requests_total counter is not a great example, because the diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 606be4c2a..e9ebcb583 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -36,6 +36,19 @@ exporter-servlet-tomcat-sample + + maven-compiler-plugin + + 17 + 17 + 17 + true + + -Xlint:all + -Werror + + + org.apache.maven.plugins maven-shade-plugin diff --git a/pom.xml b/pom.xml index 3e8a2809a..6ae53a26b 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ maven-compiler-plugin - 3.1 + 3.13.0 maven-surefire-plugin @@ -270,8 +270,14 @@ maven-compiler-plugin - 1.8 - 1.8 + 8 + 8 + 8 + true + + -Xlint:all + -Werror + diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java index 5024cc45a..bdb024514 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesException.java @@ -2,6 +2,8 @@ public class PrometheusPropertiesException extends RuntimeException { + private static final long serialVersionUID = 0L; + public PrometheusPropertiesException(String msg) { super(msg); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java index d4266c04c..8267f7f78 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/TimerApi.java @@ -57,22 +57,25 @@ public interface TimerApi { * must use base units (e.g. seconds, bytes) and leave converting them to something more readable * to graphing tools". */ + @SuppressWarnings("try") default void time(Runnable func) { - try (Timer timer = startTimer()) { + try (Timer ignored = startTimer()) { func.run(); } } /** Like {@link #time(Runnable)}, but returns the return value of {@code func}. */ + @SuppressWarnings("try") default T time(Supplier func) { - try (Timer timer = startTimer()) { + try (Timer ignored = startTimer()) { return func.get(); } } /** Like {@link #time(Supplier)}, but {@code func} may throw a checked {@code Exception}. */ + @SuppressWarnings("try") default T timeChecked(Callable func) throws Exception { - try (Timer timer = startTimer()) { + try (Timer ignored = startTimer()) { return func.call(); } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java index d3c00eca0..4821e93cd 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Metric.java @@ -19,7 +19,7 @@ protected Metric(Builder builder) { } @Override - public abstract MetricSnapshot collect(); + public abstract MetricSnapshot collect(); protected abstract static class Builder, M extends Metric> { diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java index 93fa20d0e..c9586e179 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java @@ -39,6 +39,7 @@ public class SlidingWindow { * @param maxAgeSeconds after this amount of time an instance of T gets evicted. * @param ageBuckets number of age buckets. */ + @SuppressWarnings("unchecked") public SlidingWindow( Class clazz, Supplier constructor, diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index dc61b943d..1d2bfe02e 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -45,9 +45,9 @@ protected StatefulMetric(Builder builder) { /** * labels and metricData have the same size. labels.get(i) are the labels for metricData.get(i). */ - protected abstract MetricSnapshot collect(List labels, List metricData); + protected abstract MetricSnapshot collect(List labels, List metricData); - public MetricSnapshot collect() { + public MetricSnapshot collect() { if (labelNames.length == 0 && data.isEmpty()) { // This is a metric without labels that has not been used yet. Initialize the data on the fly. labelValues(); @@ -129,6 +129,7 @@ public void clear() { protected abstract T newDataPoint(); + @SuppressWarnings("unchecked") protected T getNoLabels() { if (noLabels == null) { // Note that this will throw an IllegalArgumentException if labelNames is not empty. diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java index 1e48d63c0..9aa0b04b3 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java @@ -80,8 +80,9 @@ public void testSet() { } @Test + @SuppressWarnings("try") public void testTimer() throws InterruptedException { - try (Timer timer = noLabels.startTimer()) { + try (Timer ignored = noLabels.startTimer()) { Thread.sleep(12); } assertThat(getValue(noLabels)) diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 4b8b5591f..a3022289a 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -51,7 +51,7 @@ public Collection collectAllMetrics() { resourceWithTargetInfo, scopeFromInfo != null ? scopeFromInfo : instrumentationScopeInfo, System.currentTimeMillis()); - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot instanceof CounterSnapshot) { addUnlessNull(result, factory.create((CounterSnapshot) snapshot)); } else if (snapshot instanceof GaugeSnapshot) { @@ -78,10 +78,10 @@ public Collection collectAllMetrics() { private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { ResourceBuilder result = Resource.builder(); - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) { InfoSnapshot targetInfo = (InfoSnapshot) snapshot; - if (targetInfo.getDataPoints().size() > 0) { + if (!targetInfo.getDataPoints().isEmpty()) { InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getDataPoints().get(0); Labels labels = data.getLabels(); for (int i = 0; i < labels.size(); i++) { @@ -95,11 +95,11 @@ private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo( MetricSnapshots snapshots) { - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") && snapshot instanceof InfoSnapshot) { InfoSnapshot scopeInfo = (InfoSnapshot) snapshot; - if (scopeInfo.getDataPoints().size() > 0) { + if (!scopeInfo.getDataPoints().isEmpty()) { Labels labels = scopeInfo.getDataPoints().get(0).getLabels(); String name = null; String version = null; diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java index def62834f..48054b192 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExemplarTest.java @@ -70,13 +70,14 @@ public void tearDown() { } @Test + @SuppressWarnings("try") public void sampledExemplarIsForwarded() { try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().setSampler(Sampler.alwaysOn()).build()) { Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); Span span = test.spanBuilder(SPAN_NAME).startSpan(); - try (Scope scope = span.makeCurrent()) { + try (Scope ignored = span.makeCurrent()) { testCounter.inc(2); } } @@ -95,13 +96,14 @@ public void sampledExemplarIsForwarded() { } @Test + @SuppressWarnings("try") public void notSampledExemplarIsNotForwarded() { try (SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().setSampler(Sampler.alwaysOff()).build()) { Tracer test = sdkTracerProvider.get(INSTRUMENTATION_SCOPE_NAME); Span span = test.spanBuilder(SPAN_NAME).startSpan(); - try (Scope scope = span.makeCurrent()) { + try (Scope ignored = span.makeCurrent()) { testCounter.inc(2); } } diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 02e225888..d135fb36d 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -34,4 +35,22 @@ + + + + maven-compiler-plugin + + 17 + 17 + 17 + true + + -Xlint:all + -Werror + + + + + + diff --git a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java index 28728dc94..5e22fc3fd 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java +++ b/prometheus-metrics-exporter-servlet-jakarta/src/main/java/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.java @@ -16,6 +16,8 @@ */ public class PrometheusMetricsServlet extends HttpServlet { + private static final long serialVersionUID = 0L; + private final PrometheusScrapeHandler handler; public PrometheusMetricsServlet() { diff --git a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java index fe81fe96b..a486aec93 100644 --- a/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java +++ b/prometheus-metrics-exporter-servlet-javax/src/main/java/io/prometheus/metrics/exporter/servlet/javax/PrometheusMetricsServlet.java @@ -15,6 +15,8 @@ */ public class PrometheusMetricsServlet extends HttpServlet { + private static final long serialVersionUID = 0L; + private final PrometheusScrapeHandler handler; /** Default constructor. Uses the default PrometheusProperties and PrometheusRegistry. */ diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index 00ac6b9fc..10f54848b 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -65,7 +65,7 @@ public String getContentType() { public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); - for (MetricSnapshot snapshot : metricSnapshots) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index 7e722b056..87e50ed8b 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -52,7 +52,7 @@ public String getContentType() { public String toDebugString(MetricSnapshots metricSnapshots) { StringBuilder stringBuilder = new StringBuilder(); - for (MetricSnapshot snapshot : metricSnapshots) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); } @@ -62,14 +62,14 @@ public String toDebugString(MetricSnapshots metricSnapshots) { @Override public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { - for (MetricSnapshot snapshot : metricSnapshots) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { convert(snapshot).writeDelimitedTo(out); } } } - public Metrics.MetricFamily convert(MetricSnapshot snapshot) { + public Metrics.MetricFamily convert(MetricSnapshot snapshot) { Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder(); if (snapshot instanceof CounterSnapshot) { for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index 28d049f25..786e1d9bd 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -59,7 +59,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and // "summary". OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); - for (MetricSnapshot snapshot : metricSnapshots) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); @@ -79,7 +79,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx } } if (writeCreatedTimestamps) { - for (MetricSnapshot snapshot : metricSnapshots) { + for (MetricSnapshot snapshot : metricSnapshots) { if (snapshot.getDataPoints().size() > 0) { if (snapshot instanceof CounterSnapshot) { writeCreated(writer, snapshot); @@ -94,7 +94,8 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx writer.flush(); } - public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException { + public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) + throws IOException { boolean metadataWritten = false; MetricMetadata metadata = snapshot.getMetadata(); for (DataPointSnapshot data : snapshot.getDataPoints()) { diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index da64f30bb..c61a8f1b6 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -85,6 +85,6 @@ static void writeLabels( } public static String shortDebugString(MessageOrBuilder protobufData) { - return TextFormat.printer().shortDebugString(protobufData); + return TextFormat.printer().emittingSingleLine(true).printToString(protobufData); } } diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 7a7a0ea7e..a5e427a89 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2592,7 +2592,8 @@ public void testLabelValueEscape() throws IOException { assertPrometheusText(prometheus, counter); } - private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { + private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) + throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); writer.write(out, MetricSnapshots.of(snapshot)); @@ -2600,14 +2601,14 @@ private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) thr } private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( - String expected, MetricSnapshot snapshot) throws IOException { + String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); writer.write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } - private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) + private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); @@ -2615,14 +2616,15 @@ private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot assertThat(out).hasToString(expected); } - private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { + private void assertPrometheusText(String expected, MetricSnapshot snapshot) + throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); writer.write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } - private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) + private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); @@ -2630,7 +2632,7 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot assertThat(out).hasToString(expected); } - private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { + private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); Metrics.MetricFamily protobufData = writer.convert(snapshot); String actual = TextFormatUtil.shortDebugString(protobufData); diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java index 69b852a41..c195ae77c 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java @@ -11,6 +11,7 @@ import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -53,7 +54,7 @@ public class CacheMetricsCollector implements MultiCollector { private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; - protected final ConcurrentMap children = new ConcurrentHashMap(); + protected final ConcurrentMap> children = new ConcurrentHashMap<>(); /** * Add or replace the cache with the given name. @@ -63,7 +64,7 @@ public class CacheMetricsCollector implements MultiCollector { * @param cacheName The name of the cache, will be the metrics label value * @param cache The cache being monitored */ - public void addCache(String cacheName, Cache cache) { + public void addCache(String cacheName, Cache cache) { children.put(cacheName, cache); } @@ -75,7 +76,7 @@ public void addCache(String cacheName, Cache cache) { * @param cacheName The name of the cache, will be the metrics label value * @param cache The cache being monitored */ - public void addCache(String cacheName, AsyncCache cache) { + public void addCache(String cacheName, AsyncCache cache) { children.put(cacheName, cache.synchronous()); } @@ -86,7 +87,7 @@ public void addCache(String cacheName, AsyncCache cache) { * * @param cacheName cache to be removed */ - public Cache removeCache(String cacheName) { + public Cache nremoveCache(String cacheName) { return children.remove(cacheName); } @@ -141,8 +142,8 @@ public MetricSnapshots collect() { .name("caffeine_cache_load_duration_seconds") .help("Cache load duration: both success and failures"); - for (final Map.Entry c : children.entrySet()) { - final List cacheName = Arrays.asList(c.getKey()); + for (final Map.Entry> c : children.entrySet()) { + final List cacheName = Collections.singletonList(c.getKey()); final Labels labels = Labels.of(labelNames, cacheName); final CacheStats stats = c.getValue().stats(); diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java index c87f4aa90..6d99c176d 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java @@ -70,7 +70,7 @@ private MetricMetadata getMetricMetaData(String metricName, Metric metric) { * Export counter as Prometheus Gauge. */ - MetricSnapshot fromCounter(String dropwizardName, Counter counter) { + MetricSnapshot fromCounter(String dropwizardName, Counter counter) { MetricMetadata metadata = getMetricMetaData(dropwizardName, counter); CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder() @@ -84,7 +84,7 @@ MetricSnapshot fromCounter(String dropwizardName, Counter counter) { } /** Export gauge as a prometheus gauge. */ - MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { + MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { Object obj = gauge.getValue(); double value; if (obj instanceof Number) { @@ -119,7 +119,7 @@ MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { * @param count the total sample count for this snapshot. * @param factor a factor to apply to histogram values. */ - MetricSnapshot fromSnapshotAndCount( + MetricSnapshot fromSnapshotAndCount( String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) { Quantiles quantiles = Quantiles.builder() @@ -144,7 +144,7 @@ MetricSnapshot fromSnapshotAndCount( } /** Convert histogram snapshot. */ - MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) { + MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) { return fromSnapshotAndCount( dropwizardName, histogram.getSnapshot(), @@ -154,7 +154,7 @@ MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) { } /** Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit. */ - MetricSnapshot fromTimer(String dropwizardName, Timer timer) { + MetricSnapshot fromTimer(String dropwizardName, Timer timer) { return fromSnapshotAndCount( dropwizardName, timer.getSnapshot(), @@ -164,7 +164,7 @@ MetricSnapshot fromTimer(String dropwizardName, Timer timer) { } /** Export a Meter as a prometheus COUNTER. */ - MetricSnapshot fromMeter(String dropwizardName, Meter meter) { + MetricSnapshot fromMeter(String dropwizardName, Meter meter) { MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter); CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount()); @@ -179,7 +179,8 @@ MetricSnapshot fromMeter(String dropwizardName, Meter meter) { @Override public MetricSnapshots collect() { MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder(); - for (SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) { + for (@SuppressWarnings("rawtypes") + SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) { Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue())) .map(metricSnapshots::metricSnapshot); } diff --git a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java index 5e17338b7..e1da20071 100644 --- a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java @@ -9,7 +9,7 @@ import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -53,7 +53,7 @@ public class CacheMetricsCollector implements MultiCollector { private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; - protected final ConcurrentMap children = new ConcurrentHashMap<>(); + protected final ConcurrentMap> children = new ConcurrentHashMap<>(); /** * Add or replace the cache with the given name. @@ -63,7 +63,7 @@ public class CacheMetricsCollector implements MultiCollector { * @param cacheName The name of the cache, will be the metrics label value * @param cache The cache being monitored */ - public void addCache(String cacheName, Cache cache) { + public void addCache(String cacheName, Cache cache) { children.put(cacheName, cache); } @@ -74,7 +74,7 @@ public void addCache(String cacheName, Cache cache) { * * @param cacheName cache to be removed */ - public Cache removeCache(String cacheName) { + public Cache removeCache(String cacheName) { return children.remove(cacheName); } @@ -90,7 +90,7 @@ public void clear() { @Override public MetricSnapshots collect() { final MetricSnapshots.Builder metricSnapshotsBuilder = MetricSnapshots.builder(); - final List labelNames = Arrays.asList("cache"); + final List labelNames = Collections.singletonList("cache"); final CounterSnapshot.Builder cacheHitTotal = CounterSnapshot.builder().name("guava_cache_hit").help("Cache hit totals"); @@ -122,8 +122,8 @@ public MetricSnapshots collect() { .name("guava_cache_load_duration_seconds") .help("Cache load duration: both success and failures"); - for (final Map.Entry c : children.entrySet()) { - final List cacheName = Arrays.asList(c.getKey()); + for (final Map.Entry> c : children.entrySet()) { + final List cacheName = Collections.singletonList(c.getKey()); final Labels labels = Labels.of(labelNames, cacheName); final CacheStats stats = c.getValue().stats(); diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java index 67dd6f2e6..6aeacb13f 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetricsTest.java @@ -50,7 +50,7 @@ public void testListenerLogic() { } private double getCountByPool(String metricName, String poolName, MetricSnapshots snapshots) { - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getPrometheusName().equals(metricName)) { for (CounterSnapshot.CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) { diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index 16e04b76c..fe97561aa 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -145,7 +145,7 @@ public void testInvalidThreadIds() { private Map getCountByState(MetricSnapshots snapshots) { Map result = new HashMap<>(); - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getName().equals("jvm_threads_state")) { for (GaugeSnapshot.GaugeDataPointSnapshot data : ((GaugeSnapshot) snapshot).getDataPoints()) { 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 57b2b640f..fad461548 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 @@ -11,13 +11,13 @@ public interface Collector { /** Called when the Prometheus server scrapes metrics. */ - MetricSnapshot collect(); + 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) { + default MetricSnapshot collect(PrometheusScrapeRequest scrapeRequest) { return collect(); } @@ -28,8 +28,8 @@ default MetricSnapshot collect(PrometheusScrapeRequest scrapeRequest) { *

      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(); + default MetricSnapshot collect(Predicate includedNames) { + MetricSnapshot result = collect(); if (includedNames.test(result.getMetadata().getPrometheusName())) { return result; } else { @@ -43,9 +43,9 @@ default MetricSnapshot collect(Predicate includedNames) { *

      Override this if there is a more efficient way than first collecting the snapshot and then * discarding it. */ - default MetricSnapshot collect( + default MetricSnapshot collect( Predicate includedNames, PrometheusScrapeRequest scrapeRequest) { - MetricSnapshot result = collect(scrapeRequest); + MetricSnapshot result = collect(scrapeRequest); if (includedNames.test(result.getMetadata().getPrometheusName())) { return result; } else { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java index a4f52746e..8f44239fb 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/MultiCollector.java @@ -42,7 +42,7 @@ default MetricSnapshots collect( Predicate includedNames, PrometheusScrapeRequest scrapeRequest) { MetricSnapshots allSnapshots = scrapeRequest == null ? collect() : collect(scrapeRequest); MetricSnapshots.Builder result = MetricSnapshots.builder(); - for (MetricSnapshot snapshot : allSnapshots) { + for (MetricSnapshot snapshot : allSnapshots) { if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { result.metricSnapshot(snapshot); } 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 00a19d9f6..026560bb9 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 @@ -63,7 +63,7 @@ public MetricSnapshots scrape() { public MetricSnapshots scrape(PrometheusScrapeRequest scrapeRequest) { MetricSnapshots.Builder result = MetricSnapshots.builder(); for (Collector collector : collectors) { - MetricSnapshot snapshot = + MetricSnapshot snapshot = scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest); if (snapshot != null) { if (result.containsMetricName(snapshot.getMetadata().getName())) { @@ -76,7 +76,7 @@ public MetricSnapshots scrape(PrometheusScrapeRequest scrapeRequest) { for (MultiCollector collector : multiCollectors) { MetricSnapshots snapshots = scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest); - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (result.containsMetricName(snapshot.getMetadata().getName())) { throw new IllegalStateException( snapshot.getMetadata().getPrometheusName() + ": duplicate metric name."); @@ -105,7 +105,7 @@ public MetricSnapshots scrape( // 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 = + MetricSnapshot snapshot = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest); @@ -132,7 +132,7 @@ public MetricSnapshots scrape( scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest); - for (MetricSnapshot snapshot : snapshots) { + for (MetricSnapshot snapshot : snapshots) { if (snapshot != null) { result.metricSnapshot(snapshot); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java index fa807af19..45be6f0f1 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -5,7 +5,7 @@ import java.util.List; /** Immutable snapshot of a Counter. */ -public class CounterSnapshot extends MetricSnapshot { +public class CounterSnapshot extends MetricSnapshot { /** * To create a new {@link CounterSnapshot}, you can either call the constructor directly or use @@ -21,7 +21,7 @@ public CounterSnapshot(MetricMetadata metadata, Collection getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static class CounterDataPointSnapshot extends DataPointSnapshot { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java index d1f3f3414..721655105 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DuplicateLabelsException.java @@ -6,6 +6,8 @@ */ public class DuplicateLabelsException extends IllegalArgumentException { + private static final long serialVersionUID = 0L; + private final MetricMetadata metadata; private final Labels labels; diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java index c94faf8dd..795323271 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/GaugeSnapshot.java @@ -5,7 +5,7 @@ import java.util.List; /** Immutable snapshot of a Gauge. */ -public final class GaugeSnapshot extends MetricSnapshot { +public final class GaugeSnapshot extends MetricSnapshot { /** * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use the @@ -20,7 +20,7 @@ public GaugeSnapshot(MetricMetadata metadata, Collection @Override public List getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static final class GaugeDataPointSnapshot extends DataPointSnapshot { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index 5988cce3d..6966552a7 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -5,7 +5,8 @@ import java.util.List; /** Immutable snapshot of a Histogram. */ -public final class HistogramSnapshot extends MetricSnapshot { +public final class HistogramSnapshot + extends MetricSnapshot { private final boolean gaugeHistogram; public static final int CLASSIC_HISTOGRAM = Integer.MIN_VALUE; @@ -41,7 +42,7 @@ public boolean isGaugeHistogram() { @Override public List getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static final class HistogramDataPointSnapshot extends DistributionDataPointSnapshot { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java index c7f180d9f..ec8ece23c 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/InfoSnapshot.java @@ -5,7 +5,7 @@ import java.util.List; /** Immutable snapshot of an Info metric. */ -public final class InfoSnapshot extends MetricSnapshot { +public final class InfoSnapshot extends MetricSnapshot { /** * To create a new {@link InfoSnapshot}, you can either call the constructor directly or use the @@ -24,7 +24,7 @@ public InfoSnapshot(MetricMetadata metadata, Collection d @Override public List getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static class InfoDataPointSnapshot extends DataPointSnapshot { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java index d44e54ff9..420feeced 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -1,24 +1,18 @@ package io.prometheus.metrics.model.snapshots; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; /** Base class for metric snapshots. */ -public abstract class MetricSnapshot { +public abstract class MetricSnapshot { private final MetricMetadata metadata; - protected final List dataPoints; + protected final List dataPoints; - protected MetricSnapshot(MetricMetadata metadata, DataPointSnapshot... dataPoints) { - this(metadata, Arrays.asList(dataPoints)); - } - - protected MetricSnapshot( - MetricMetadata metadata, Collection dataPoints) { + protected MetricSnapshot(MetricMetadata metadata, Collection dataPoints) { if (metadata == null) { throw new NullPointerException("metadata"); } @@ -26,7 +20,7 @@ protected MetricSnapshot( throw new NullPointerException("dataPoints"); } this.metadata = metadata; - List dataCopy = new ArrayList<>(dataPoints); + List dataCopy = new ArrayList<>(dataPoints); dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); this.dataPoints = Collections.unmodifiableList(dataCopy); validateLabels(); @@ -36,7 +30,7 @@ public MetricMetadata getMetadata() { return metadata; } - public abstract List getDataPoints(); + public abstract List getDataPoints(); protected void validateLabels() { // Verify that labels are unique (the same set of names/values must not be used multiple times @@ -76,7 +70,7 @@ public T unit(Unit unit) { return self(); } - public abstract MetricSnapshot build(); + public abstract MetricSnapshot build(); protected MetricMetadata buildMetadata() { return new MetricMetadata(name, help, unit); diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java index ecee897e4..f56976e9e 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshots.java @@ -14,12 +14,12 @@ import java.util.stream.Stream; /** Immutable list of metric snapshots. */ -public class MetricSnapshots implements Iterable { +public class MetricSnapshots implements Iterable> { - private final List snapshots; + private final List> snapshots; /** See {@link #MetricSnapshots(Collection)} */ - public MetricSnapshots(MetricSnapshot... snapshots) { + public MetricSnapshots(MetricSnapshot... snapshots) { this(Arrays.asList(snapshots)); } @@ -33,8 +33,8 @@ public MetricSnapshots(MetricSnapshot... snapshots) { * Builder#containsMetricName(String)} before calling {@link * Builder#metricSnapshot(MetricSnapshot)}. */ - public MetricSnapshots(Collection snapshots) { - List list = new ArrayList<>(snapshots); + public MetricSnapshots(Collection> snapshots) { + List> list = new ArrayList<>(snapshots); list.sort(comparing(s -> s.getMetadata().getPrometheusName())); for (int i = 0; i < snapshots.size() - 1; i++) { if (list.get(i) @@ -48,12 +48,12 @@ public MetricSnapshots(Collection snapshots) { this.snapshots = unmodifiableList(list); } - public static MetricSnapshots of(MetricSnapshot... snapshots) { + public static MetricSnapshots of(MetricSnapshot... snapshots) { return new MetricSnapshots(snapshots); } @Override - public Iterator iterator() { + public Iterator> iterator() { return snapshots.iterator(); } @@ -61,11 +61,11 @@ public int size() { return snapshots.size(); } - public MetricSnapshot get(int i) { + public MetricSnapshot get(int i) { return snapshots.get(i); } - public Stream stream() { + public Stream> stream() { return snapshots.stream(); } @@ -75,7 +75,7 @@ public static Builder builder() { public static class Builder { - private final List snapshots = new ArrayList<>(); + private final List> snapshots = new ArrayList<>(); private final Set prometheusNames = new HashSet<>(); private Builder() {} @@ -89,7 +89,7 @@ public boolean containsMetricName(String name) { } /** Add a metric snapshot. Call multiple times to add multiple metric snapshots. */ - public Builder metricSnapshot(MetricSnapshot snapshot) { + public Builder metricSnapshot(MetricSnapshot snapshot) { snapshots.add(snapshot); prometheusNames.add(snapshot.getMetadata().getPrometheusName()); return this; 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 591732137..7c6e49d19 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 @@ -9,7 +9,8 @@ import java.util.stream.Stream; /** Immutable snapshot of a StateSet metric. */ -public final class StateSetSnapshot extends MetricSnapshot { +public final class StateSetSnapshot + extends MetricSnapshot { /** * To create a new {@link StateSetSnapshot}, you can either call the constructor directly or use @@ -37,7 +38,7 @@ private void validate() { @Override public List getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static class StateSetDataPointSnapshot extends DataPointSnapshot diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java index 7bc575ef8..26bd0f602 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/SummarySnapshot.java @@ -5,7 +5,8 @@ import java.util.List; /** Immutable snapshot of a Summary metric. */ -public final class SummarySnapshot extends MetricSnapshot { +public final class SummarySnapshot + extends MetricSnapshot { /** * To create a new {@link SummarySnapshot}, you can either call the constructor directly or use @@ -20,7 +21,7 @@ public SummarySnapshot(MetricMetadata metadata, Collection getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static final class SummaryDataPointSnapshot extends DistributionDataPointSnapshot { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java index 3fe01c9df..30ec564cb 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/UnknownSnapshot.java @@ -5,7 +5,8 @@ import java.util.List; /** Immutable snapshot of an Unknown (Untyped) metric. */ -public final class UnknownSnapshot extends MetricSnapshot { +public final class UnknownSnapshot + extends MetricSnapshot { /** * To create a new {@link UnknownSnapshot}, you can either call the constructor directly or use @@ -21,7 +22,7 @@ public UnknownSnapshot(MetricMetadata metadata, Collection getDataPoints() { - return (List) dataPoints; + return dataPoints; } public static final class UnknownDataPointSnapshot extends DataPointSnapshot { 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 55e8b0be4..6557c0ecf 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 @@ -19,7 +19,7 @@ class PrometheusRegistryTest { Collector counterA1 = new Collector() { @Override - public MetricSnapshot collect() { + public MetricSnapshot collect() { return CounterSnapshot.builder().name("counter_a").build(); } @@ -32,7 +32,7 @@ public String getPrometheusName() { Collector counterA2 = new Collector() { @Override - public MetricSnapshot collect() { + public MetricSnapshot collect() { return CounterSnapshot.builder().name("counter.a").build(); } @@ -45,7 +45,7 @@ public String getPrometheusName() { Collector counterB = new Collector() { @Override - public MetricSnapshot collect() { + public MetricSnapshot collect() { return CounterSnapshot.builder().name("counter_b").build(); } @@ -58,7 +58,7 @@ public String getPrometheusName() { Collector gaugeA = new Collector() { @Override - public MetricSnapshot collect() { + public MetricSnapshot collect() { return GaugeSnapshot.builder().name("gauge_a").build(); } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java index fc0c24bfc..25cd6a4ec 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -34,7 +34,7 @@ public void testDuplicateLabels() { @Test public void testNoData() { - MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); + MetricSnapshot snapshot = CounterSnapshot.builder().name("test").build(); assertThat(snapshot.getDataPoints().size()).isEqualTo(0); } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java index ed2f66fec..09d63d4d9 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotsTest.java @@ -92,7 +92,7 @@ public void testImmutable() { .dataPoint(CounterSnapshot.CounterDataPointSnapshot.builder().value(1.0).build()) .build(); MetricSnapshots snapshots = new MetricSnapshots(c2, c3, c1); - Iterator iterator = snapshots.iterator(); + Iterator> iterator = snapshots.iterator(); iterator.next(); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } 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 d8e8d33e4..a69bba499 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 @@ -5,7 +5,7 @@ class SnapshotTestUtil { public static void assertMetadata( - MetricSnapshot snapshot, String name, String help, String unit) { + MetricSnapshot snapshot, String name, String help, String unit) { assertThat(snapshot.getMetadata().getName()).isEqualTo(name); assertThat(snapshot.getMetadata().getHelp()).isEqualTo(help); if (unit != null) { diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index f1b592eaa..e68ebd968 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -101,7 +101,7 @@ private MetricSnapshots convert(Enumeration sampl return result.build(); } - private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) { CounterSnapshot.Builder counter = CounterSnapshot.builder() .name(sanitizeMetricName(samples.name)) @@ -128,7 +128,7 @@ private MetricSnapshot convertCounter(Collector.MetricFamilySamples samples) { return counter.build(); } - private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) { GaugeSnapshot.Builder gauge = GaugeSnapshot.builder() .name(sanitizeMetricName(samples.name)) @@ -148,7 +148,7 @@ private MetricSnapshot convertGauge(Collector.MetricFamilySamples samples) { return gauge.build(); } - private MetricSnapshot convertHistogram( + private MetricSnapshot convertHistogram( Collector.MetricFamilySamples samples, boolean isGaugeHistogram) { HistogramSnapshot.Builder histogram = HistogramSnapshot.builder() @@ -192,7 +192,7 @@ private MetricSnapshot convertHistogram( return histogram.build(); } - private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) { SummarySnapshot.Builder summary = SummarySnapshot.builder() .name(sanitizeMetricName(samples.name)) @@ -242,7 +242,7 @@ private MetricSnapshot convertSummary(Collector.MetricFamilySamples samples) { return summary.build(); } - private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) { StateSetSnapshot.Builder stateSet = StateSetSnapshot.builder().name(sanitizeMetricName(samples.name)).help(samples.help); Map dataPoints = new HashMap<>(); @@ -271,7 +271,7 @@ private MetricSnapshot convertStateSet(Collector.MetricFamilySamples samples) { return stateSet.build(); } - private MetricSnapshot convertUnknown(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertUnknown(Collector.MetricFamilySamples samples) { UnknownSnapshot.Builder unknown = UnknownSnapshot.builder() .name(sanitizeMetricName(samples.name)) @@ -353,7 +353,7 @@ private Labels labelsWithout( return labels.build(); } - private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) { + private MetricSnapshot convertInfo(Collector.MetricFamilySamples samples) { InfoSnapshot.Builder info = InfoSnapshot.builder().name(sanitizeMetricName(samples.name)).help(samples.help); for (Collector.MetricFamilySamples.Sample sample : samples.samples) { From 8226348a5962c48084f32f49e39f7245278736e3 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 10 Oct 2024 11:16:09 +0200 Subject: [PATCH 418/980] add Errorprone (#1139) * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .mvn/jvm.config | 10 +++++++++ .../multitarget/SampleMultiCollector.java | 5 +++-- .../metrics/it/exporter/test/ExporterIT.java | 10 +++++---- .../it/pushgateway/PushGatewayTestApp.java | 1 + pom.xml | 21 ++++++++++++++++++ .../config/ExporterFilterProperties.java | 14 +----------- .../config/PrometheusPropertiesLoader.java | 1 + .../io/prometheus/metrics/config/Util.java | 2 +- .../datapoints/DistributionDataPoint.java | 2 +- .../core/datapoints/GaugeDataPoint.java | 2 +- .../core/exemplars/ExemplarSampler.java | 12 +++++----- .../metrics/core/metrics/Buffer.java | 1 + .../metrics/core/metrics/CKMSQuantiles.java | 1 + .../metrics/core/metrics/Counter.java | 21 +++++------------- .../metrics/core/metrics/Gauge.java | 11 ---------- .../metrics/core/metrics/Histogram.java | 9 ++++---- .../prometheus/metrics/core/metrics/Info.java | 1 - .../core/metrics/MetricWithFixedMetadata.java | 1 + .../metrics/core/metrics/StateSet.java | 5 ----- .../metrics/core/metrics/StatefulMetric.java | 7 +++--- .../metrics/core/metrics/Summary.java | 5 ----- .../metrics/core/util/Scheduler.java | 2 ++ .../core/exemplars/ExemplarSamplerTest.java | 7 ++---- .../metrics/core/metrics/HistogramTest.java | 7 ++++-- .../common/PrometheusHttpRequest.java | 1 + .../exporter/httpserver/HTTPServer.java | 1 + .../exporter/httpserver/HTTPServerTest.java | 4 ++-- .../opentelemetry/OpenTelemetryExporter.java | 5 ++++- .../ResourceAttributesFromOtelAgent.java | 1 + .../otelmodel/PrometheusClassicHistogram.java | 2 +- .../exporter/pushgateway/PushGateway.java | 8 ++----- .../OpenMetricsTextFormatWriter.java | 3 ++- .../PrometheusTextFormatWriter.java | 1 + .../caffeine/CacheMetricsCollectorTest.java | 1 + .../dropwizard5/DropwizardExports.java | 22 +++++++++---------- .../dropwizard5/labels/MapperConfig.java | 2 +- .../jvm/JvmMemoryPoolAllocationMetrics.java | 16 +++++--------- .../instrumentation/jvm/ProcessMetrics.java | 13 +++++++++-- .../jvm/JvmThreadsMetricsTest.java | 1 + .../snapshots/ClassicHistogramBuckets.java | 6 ++--- .../metrics/model/snapshots/Labels.java | 3 ++- .../metrics/model/snapshots/Unit.java | 4 ++-- .../bridge/SimpleclientCollector.java | 16 +++----------- .../bridge/SimpleclientCollectorTest.java | 11 +++++----- 44 files changed, 137 insertions(+), 142 deletions(-) create mode 100644 .mvn/jvm.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 000000000..32599cefe --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java index f9cea3f87..dba3b1b9e 100644 --- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java +++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java @@ -3,7 +3,6 @@ import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; import io.prometheus.metrics.model.snapshots.CounterSnapshot; -import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot.Builder; import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshot; @@ -46,7 +45,8 @@ protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeR } else { targetName = targetNames[0]; } - Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); + CounterSnapshot.CounterDataPointSnapshot.Builder counterDataPointBuilder = + CounterSnapshot.CounterDataPointSnapshot.builder(); io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); Labels lbls = Labels.of("target", targetName); @@ -77,6 +77,7 @@ protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeR return new MetricSnapshots(snaps); } + @Override public List getPrometheusNames() { List names = new ArrayList(); names.add("x_calls_total"); diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 6bce50718..3e0caf954 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; @@ -67,7 +68,7 @@ public void testOpenMetricsTextFormat() throws IOException { assertThat(response.getHeader("Transfer-Encoding")).isNull(); assertThat(response.getHeader("Content-Length")) .isEqualTo(Integer.toString(response.body.length)); - String bodyString = new String(response.body); + String bodyString = new String(response.body, UTF_8); assertThat(bodyString) .contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1") .contains("temperature_celsius{location=\"inside\"} 23.0") @@ -90,7 +91,7 @@ public void testPrometheusTextFormat() throws IOException { assertThat(response.getHeader("Transfer-Encoding")).isNull(); assertThat(response.getHeader("Content-Length")) .isEqualTo(Integer.toString(response.body.length)); - String bodyString = new String(response.body); + String bodyString = new String(response.body, UTF_8); assertThat(bodyString) .contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1") .contains("temperature_celsius{location=\"inside\"} 23.0") @@ -370,6 +371,7 @@ private Response scrape(String method, String queryString, String... requestHead try { Thread.sleep(100); } catch (InterruptedException ignored) { + // ignore } } } @@ -392,14 +394,14 @@ private Response(int status, Map> headers, byte[] body) { for (Map.Entry> entry : headers.entrySet()) { if (entry.getKey() != null) { // HttpUrlConnection uses pseudo key "null" for the status line - this.headers.put(entry.getKey().toLowerCase(), entry.getValue().get(0)); + this.headers.put(entry.getKey().toLowerCase(Locale.ROOT), entry.getValue().get(0)); } } } private String getHeader(String name) { // HTTP headers are case-insensitive - return headers.get(name.toLowerCase()); + return headers.get(name.toLowerCase(Locale.ROOT)); } } } diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java index 61032600b..5c8605617 100644 --- a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java +++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java @@ -79,6 +79,7 @@ private static void runSslTest() throws IOException { static TrustManager insecureTrustManager = new X509TrustManager() { + @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } diff --git a/pom.xml b/pom.xml index 6ae53a26b..3105a1b22 100644 --- a/pom.xml +++ b/pom.xml @@ -277,7 +277,28 @@ -Xlint:all -Werror + -XDcompilePolicy=simple + + -Xplugin:ErrorProne + -Xep:AlmostJavadoc:OFF + -Xep:MissingSummary:OFF + -Xep:LongDoubleConversion:OFF + -Xep:StringSplitter:OFF + -XepExcludedPaths:.*/generated/.* + + + + com.google.errorprone + error_prone_core + 2.33.0 + + + diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java index 4758a48fe..7a408bb58 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -24,15 +24,6 @@ private ExporterFilterProperties( List excludedNames, List allowedPrefixes, List excludedPrefixes) { - this(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, ""); - } - - private ExporterFilterProperties( - List allowedNames, - List excludedNames, - List allowedPrefixes, - List excludedPrefixes, - String prefix) { this.allowedNames = allowedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedNames)); this.excludedNames = @@ -45,7 +36,6 @@ private ExporterFilterProperties( excludedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedPrefixes)); - validate(prefix); } public List getAllowedMetricNames() { @@ -64,8 +54,6 @@ public List getExcludedMetricNamePrefixes() { return excludedPrefixes; } - private void validate(String prefix) throws PrometheusPropertiesException {} - /** * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. @@ -81,7 +69,7 @@ static ExporterFilterProperties load(String prefix, Map properti List excludedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); return new ExporterFilterProperties( - allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix); + allowedNames, excludedNames, allowedPrefixes, excludedPrefixes); } public static Builder builder() { diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java index 9d1fde4ab..e29f93036 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java @@ -113,6 +113,7 @@ private static Properties loadPropertiesFromClasspath() { .getResourceAsStream("prometheus.properties")) { properties.load(stream); } catch (Exception ignored) { + // No properties file found on the classpath. } return properties; } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java index 66d6b2d92..8adcd0af7 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java @@ -91,7 +91,7 @@ static Map loadMap(String name, Map properties) if (keyValue.length == 2) { String key = keyValue[0].trim(); String value = keyValue[1].trim(); - if (key.length() > 0 && value.length() > 0) { + if (!key.isEmpty() && !value.isEmpty()) { result.putIfAbsent(key, value); } } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java index 57e7a3e86..82e42a892 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/DistributionDataPoint.java @@ -25,7 +25,7 @@ public interface DistributionDataPoint extends DataPoint, TimerApi { /** Observe {@code value}, and create a custom exemplar with the given labels. */ void observeWithExemplar(double value, Labels labels); - /** {@inheritDoc} */ + @Override default Timer startTimer() { return new Timer(this::observe); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java index 003e3e5e8..eec0304c7 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/GaugeDataPoint.java @@ -56,7 +56,7 @@ default void decWithExemplar(double amount, Labels labels) { /** Set the gauge to {@code value}, and create a custom exemplar with the given labels. */ void setWithExemplar(double value, Labels labels); - /** {@inheritDoc} */ + @Override default Timer startTimer() { return new Timer(this::set); } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java index 0d4a71f63..0e1c49f8c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -98,7 +98,7 @@ public void observe(double value) { return; // This is the hot path in a high-throughput application and should be as efficient as // possible. } - rateLimitedObserve(acceptingNewExemplars, value, exemplars, () -> doObserve(value)); + rateLimitedObserve(acceptingNewExemplars, value, () -> doObserve(value)); } public void observeWithExemplar(double value, Labels labels) { @@ -107,10 +107,7 @@ public void observeWithExemplar(double value, Labels labels) { // possible. } rateLimitedObserve( - acceptingNewCustomExemplars, - value, - customExemplars, - () -> doObserveWithExemplar(value, labels)); + acceptingNewCustomExemplars, value, () -> doObserveWithExemplar(value, labels)); } private long doObserve(double value) { @@ -278,8 +275,8 @@ private long doObserveWithExemplarWithoutUpperBounds(double amount, Labels label *

      To avoid performance issues, we rate limit observing exemplars to {@link * ExemplarSamplerConfig#getSampleIntervalMillis()} milliseconds. */ - private void rateLimitedObserve( - AtomicBoolean accepting, double value, Exemplar[] exemplars, LongSupplier observeFunc) { + @SuppressWarnings("FutureReturnValueIgnored") + private void rateLimitedObserve(AtomicBoolean accepting, double value, LongSupplier observeFunc) { if (Double.isNaN(value)) { return; } @@ -352,6 +349,7 @@ private Labels doSampleExemplar() { } } } catch (NoClassDefFoundError ignored) { + // ignore } return Labels.EMPTY; } diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java index 720c8228c..69f6de86f 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -48,6 +48,7 @@ void reset() { reset = true; } + @SuppressWarnings("ThreadPriorityCheck") T run( Function complete, Supplier runnable, Consumer observeFunction) { double[] buffer; diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java index adfd5c6d8..9fc1e9634 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java @@ -38,6 +38,7 @@ final class CKMSQuantiles { int n = 0; /** List of sampled observations, ordered by Sample.value. */ + @SuppressWarnings("JdkObsolete") final LinkedList samples = new LinkedList<>(); /** diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index 5e435f695..2e84b6ade 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -47,41 +47,36 @@ private Counter(Builder builder, PrometheusProperties prometheusProperties) { } } - /** {@inheritDoc} */ @Override public void inc(long amount) { getNoLabels().inc(amount); } - /** {@inheritDoc} */ @Override public void inc(double amount) { getNoLabels().inc(amount); } - /** {@inheritDoc} */ @Override public void incWithExemplar(long amount, Labels labels) { getNoLabels().incWithExemplar(amount, labels); } - /** {@inheritDoc} */ @Override public void incWithExemplar(double amount, Labels labels) { getNoLabels().incWithExemplar(amount, labels); } - /** {@inheritDoc} */ + @Override public double get() { return getNoLabels().get(); } - /** {@inheritDoc} */ + @Override public long getLongValue() { return getNoLabels().getLongValue(); } - /** {@inheritDoc} */ @Override public CounterSnapshot collect() { return (CounterSnapshot) super.collect(); @@ -131,26 +126,24 @@ private DataPoint(ExemplarSampler exemplarSampler) { this.exemplarSampler = exemplarSampler; } - /** {@inheritDoc} */ + @Override public double get() { return longValue.sum() + doubleValue.sum(); } - /** {@inheritDoc} */ + @Override public long getLongValue() { return longValue.sum() + (long) doubleValue.sum(); } - /** {@inheritDoc} */ @Override public void inc(long amount) { validateAndAdd(amount); if (isExemplarsEnabled()) { - exemplarSampler.observe(amount); + exemplarSampler.observe((double) amount); } } - /** {@inheritDoc} */ @Override public void inc(double amount) { validateAndAdd(amount); @@ -159,16 +152,14 @@ public void inc(double amount) { } } - /** {@inheritDoc} */ @Override public void incWithExemplar(long amount, Labels labels) { validateAndAdd(amount); if (isExemplarsEnabled()) { - exemplarSampler.observeWithExemplar(amount, labels); + exemplarSampler.observeWithExemplar((double) amount, labels); } } - /** {@inheritDoc} */ @Override public void incWithExemplar(double amount, Labels labels) { validateAndAdd(amount); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java index a3f7e290d..4ba5d5ed3 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Gauge.java @@ -54,37 +54,31 @@ private Gauge(Builder builder, PrometheusProperties prometheusProperties) { } } - /** {@inheritDoc} */ @Override public void inc(double amount) { getNoLabels().inc(amount); } - /** {@inheritDoc} */ @Override public double get() { return getNoLabels().get(); } - /** {@inheritDoc} */ @Override public void incWithExemplar(double amount, Labels labels) { getNoLabels().incWithExemplar(amount, labels); } - /** {@inheritDoc} */ @Override public void set(double value) { getNoLabels().set(value); } - /** {@inheritDoc} */ @Override public void setWithExemplar(double value, Labels labels) { getNoLabels().setWithExemplar(value, labels); } - /** {@inheritDoc} */ @Override public GaugeSnapshot collect() { return (GaugeSnapshot) super.collect(); @@ -123,7 +117,6 @@ private DataPoint(ExemplarSampler exemplarSampler) { private final AtomicLong value = new AtomicLong(Double.doubleToRawLongBits(0)); - /** {@inheritDoc} */ @Override public void inc(double amount) { long next = @@ -133,7 +126,6 @@ public void inc(double amount) { } } - /** {@inheritDoc} */ @Override public void incWithExemplar(double amount, Labels labels) { long next = @@ -143,7 +135,6 @@ public void incWithExemplar(double amount, Labels labels) { } } - /** {@inheritDoc} */ @Override public void set(double value) { this.value.set(Double.doubleToRawLongBits(value)); @@ -152,13 +143,11 @@ public void set(double value) { } } - /** {@inheritDoc} */ @Override public double get() { return Double.longBitsToDouble(value.get()); } - /** {@inheritDoc} */ @Override public void setWithExemplar(double value, Labels labels) { this.value.set(Double.doubleToRawLongBits(value)); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index 2952222c6..bf70bec7c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -165,13 +165,11 @@ private Histogram(Histogram.Builder builder, PrometheusProperties prometheusProp : new ExemplarSamplerConfig(exemplarsProperties, classicUpperBounds); } - /** {@inheritDoc} */ @Override public void observe(double amount) { getNoLabels().observe(amount); } - /** {@inheritDoc} */ @Override public void observeWithExemplar(double amount, Labels labels) { getNoLabels().observeWithExemplar(amount, labels); @@ -212,7 +210,6 @@ private DataPoint() { maybeScheduleNextReset(); } - /** {@inheritDoc} */ @Override public void observe(double value) { if (Double.isNaN(value)) { @@ -227,7 +224,6 @@ public void observe(double value) { } } - /** {@inheritDoc} */ @Override public void observeWithExemplar(double value, Labels labels) { if (Double.isNaN(value)) { @@ -574,6 +570,7 @@ private int findSmallestIndex(Map nativeBuckets) { // doubleBucketWidth is called in the synchronized block while new observations go into the // buffer. + @SuppressWarnings("NonAtomicVolatileUpdate") private void doubleBucketWidth() { doubleBucketWidth(nativeBucketsForPositiveValues); doubleBucketWidth(nativeBucketsForNegativeValues); @@ -609,6 +606,7 @@ private NativeHistogramBuckets toBucketList(ConcurrentHashMap 0) { Scheduler.schedule( @@ -617,7 +615,6 @@ private void maybeScheduleNextReset() { } } - /** {@inheritDoc} */ @Override public HistogramSnapshot collect() { return (HistogramSnapshot) super.collect(); @@ -667,8 +664,10 @@ public static Builder builder(PrometheusProperties config) { public static class Builder extends StatefulMetric.Builder { + @SuppressWarnings("MutablePublicArray") public static final double[] DEFAULT_CLASSIC_UPPER_BOUNDS = new double[] {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}; + private final double DEFAULT_NATIVE_MIN_ZERO_THRESHOLD = Math.pow(2.0, -128); private final double DEFAULT_NATIVE_MAX_ZERO_THRESHOLD = Math.pow(2.0, -128); private final int DEFAULT_NATIVE_INITIAL_SCHEMA = 5; diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java index 49f8a1eb5..aac918943 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Info.java @@ -91,7 +91,6 @@ public void remove(String... labelValues) { labels.remove(toBeRemoved); } - /** {@inheritDoc} */ @Override public InfoSnapshot collect() { List data = new ArrayList<>(labels.size()); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index c121d0c56..056ef792c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -91,6 +91,7 @@ public B labelNames(String... labelNames) { return self(); } + @Override public B constLabels(Labels constLabels) { for (String labelName : labelNames) { if (constLabels.contains(labelName)) { // Labels.contains() treats dots like underscores diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java index e4d9eff88..20eb1783e 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StateSet.java @@ -71,19 +71,16 @@ private StateSet(Builder builder, PrometheusProperties prometheusProperties) { } } - /** {@inheritDoc} */ @Override public StateSetSnapshot collect() { return (StateSetSnapshot) super.collect(); } - /** {@inheritDoc} */ @Override public void setTrue(String state) { getNoLabels().setTrue(state); } - /** {@inheritDoc} */ @Override public void setFalse(String state) { getNoLabels().setFalse(state); @@ -116,13 +113,11 @@ class DataPoint implements StateSetDataPoint { private DataPoint() {} - /** {@inheritDoc} */ @Override public void setTrue(String state) { set(state, true); } - /** {@inheritDoc} */ @Override public void setFalse(String state) { set(state, false); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 1d2bfe02e..67523eeee 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -47,6 +47,7 @@ protected StatefulMetric(Builder builder) { */ protected abstract MetricSnapshot collect(List labels, List metricData); + @Override public MetricSnapshot collect() { if (labelNames.length == 0 && data.isEmpty()) { // This is a metric without labels that has not been used yet. Initialize the data on the fly. @@ -157,9 +158,9 @@ protected MetricsProperties[] getMetricProperties( } } - protected T getConfigProperty( - MetricsProperties[] properties, Function getter) { - T result; + protected

      P getConfigProperty( + MetricsProperties[] properties, Function getter) { + P result; for (MetricsProperties props : properties) { result = getter.apply(props); if (result != null) { diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java index 126626799..ddb3eb7f2 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Summary.java @@ -82,19 +82,16 @@ protected boolean isExemplarsEnabled() { return exemplarsEnabled; } - /** {@inheritDoc} */ @Override public void observe(double amount) { getNoLabels().observe(amount); } - /** {@inheritDoc} */ @Override public void observeWithExemplar(double amount, Labels labels) { getNoLabels().observeWithExemplar(amount, labels); } - /** {@inheritDoc} */ @Override public SummarySnapshot collect() { return (SummarySnapshot) super.collect(); @@ -144,7 +141,6 @@ private DataPoint() { } } - /** {@inheritDoc} */ @Override public void observe(double value) { if (Double.isNaN(value)) { @@ -158,7 +154,6 @@ public void observe(double value) { } } - /** {@inheritDoc} */ @Override public void observeWithExemplar(double value, Labels labels) { if (Double.isNaN(value)) { diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java index 6af7fa54a..96e0643c5 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java @@ -14,6 +14,7 @@ public class Scheduler { private static class DaemonThreadFactory implements ThreadFactory { + @Override public Thread newThread(Runnable runnable) { Thread thread = new Thread(runnable); thread.setDaemon(true); @@ -29,6 +30,7 @@ public static ScheduledFuture schedule(Runnable command, long delay, TimeUnit } /** For unit test. Wait until the executor Thread is running. */ + @SuppressWarnings("FutureReturnValueIgnored") public static void awaitInitialization() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); Scheduler.schedule(latch::countDown, 0, TimeUnit.MILLISECONDS); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java index 1572eb645..059929c22 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/exemplars/ExemplarSamplerTest.java @@ -31,11 +31,10 @@ private static class SpanContext implements io.prometheus.metrics.tracer.common. int callCount = 0; boolean isSampled = true; - boolean isExemplar = false; @Override public String getCurrentTraceId() { - return "" + (callCount++); + return "" + callCount++; } @Override @@ -49,9 +48,7 @@ public boolean isCurrentSpanSampled() { } @Override - public void markCurrentSpanAsExemplar() { - isExemplar = true; - } + public void markCurrentSpanAsExemplar() {} } @Test diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 4d55c3236..53280ba72 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -1498,7 +1498,7 @@ public void testObserveMultithreaded() } } assertThat(maxCount) - .isEqualTo(nThreads * 10_000); // the last collect() has seen all observations + .isEqualTo(nThreads * 10_000L); // the last collect() has seen all observations assertThat(nThreads * 10_000).isEqualTo(getBucket(histogram, 2.5, "status", "200").getCount()); executor.shutdown(); assertThat(executor.awaitTermination(5, TimeUnit.SECONDS)).isTrue(); @@ -1509,6 +1509,9 @@ private HistogramSnapshot.HistogramDataPointSnapshot getData( return histogram.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) .findAny() - .orElseThrow(() -> new RuntimeException("histogram with labels " + labels + " not found")); + .orElseThrow( + () -> + new RuntimeException( + "histogram with labels " + Arrays.toString(labels) + " not found")); } } diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java index 954facfef..6dc632cd9 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusHttpRequest.java @@ -38,6 +38,7 @@ default String getParameter(String name) { } /** See {@code jakarta.servlet.ServletRequest.getParameterValues(String)} */ + @Override default String[] getParameterValues(String name) { try { ArrayList result = new ArrayList<>(); diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 54e71d769..46c719bc1 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -326,6 +326,7 @@ public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolEx try { threadPoolExecutor.getQueue().put(runnable); } catch (InterruptedException ignored) { + // ignore } } } diff --git a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java index fc7df1dc9..ccc99bd01 100644 --- a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java +++ b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java @@ -22,7 +22,7 @@ public void testSubjectDoAs() throws Exception { final String user = "joe"; final Subject subject = new Subject(); - subject.getPrincipals().add(() -> (user)); + subject.getPrincipals().add(() -> user); Authenticator authenticator = new Authenticator() { @@ -68,7 +68,7 @@ public Result authenticate(HttpExchange exchange) { byte[] resp = new byte[500]; int read = socket.getInputStream().read(resp, 0, resp.length); if (read > 0) { - actualResponse = new String(resp, 0, read); + actualResponse = new String(resp, 0, read, StandardCharsets.UTF_8); } assertThat(actualResponse).contains("204"); diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index c462a9d59..82f503ac9 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -14,6 +14,7 @@ import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.time.Duration; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -58,6 +59,7 @@ private OpenTelemetryExporter( reader.register(prometheusMetricProducer); } + @Override public void close() { reader.shutdown(); } @@ -445,7 +447,8 @@ private static Map getResourceAttributes( } private static String getString(String otelPropertyName) { - String otelEnvVarName = otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(); + String otelEnvVarName = + otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(Locale.ROOT); if (System.getenv(otelEnvVarName) != null) { return System.getenv(otelEnvVarName); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java index 698db602f..ce6baafe2 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java @@ -63,6 +63,7 @@ public static void addIfAbsent(Map result, String instrumentatio deleteTempDir(tmpDir.toFile()); } } catch (Exception ignored) { + // ignore } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java index fc31e6333..18e0151b2 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusClassicHistogram.java @@ -58,7 +58,7 @@ private HistogramPointData toOtelDataPoint( } private long calculateCount(ClassicHistogramBuckets buckets) { - int result = 0; + long result = 0; for (int i = 0; i < buckets.size(); i++) { result += buckets.getCount(i); } diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index d879c3105..2b986adb4 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -391,7 +391,7 @@ private String getJob(ExporterPushgatewayProperties properties) { } } - private Format getFormat(ExporterPushgatewayProperties properties) { + private Format getFormat() { // currently not configurable via properties if (this.format != null) { return this.format; @@ -434,11 +434,7 @@ public PushGateway build() { config == null ? null : config.getExporterPushgatewayProperties(); try { return new PushGateway( - registry, - getFormat(properties), - makeUrl(properties), - connectionFactory, - requestHeaders); + registry, getFormat(), makeUrl(properties), connectionFactory, requestHeaders); } catch (MalformedURLException e) { throw new PrometheusPropertiesException( address + ": Invalid address. Expecting :"); diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index 10f54848b..3d3eb862a 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -63,10 +63,11 @@ public String getContentType() { return CONTENT_TYPE; } + @Override public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); } else if (snapshot instanceof GaugeSnapshot) { diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index 786e1d9bd..cdc02c26b 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -54,6 +54,7 @@ public String getContentType() { return CONTENT_TYPE; } + @Override public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { // See https://prometheus.io/docs/instrumenting/exposition_formats/ // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java index 4416c3e49..37f5f3670 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.Test; +@SuppressWarnings("CheckReturnValue") class CacheMetricsCollectorTest { @Test diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java index 6d99c176d..c4418b432 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java @@ -75,7 +75,7 @@ MetricSnapshot fromCounter(String dropwizardName, Counter counter) { CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder() .value(Long.valueOf(counter.getCount()).doubleValue()); - labelMapper.map( + labelMapper.ifPresent( mapper -> dataPointBuilder.labels( mapper.getLabels( @@ -103,7 +103,7 @@ MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { MetricMetadata metadata = getMetricMetaData(dropwizardName, gauge); GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder().value(value); - labelMapper.map( + labelMapper.ifPresent( mapper -> dataPointBuilder.labels( mapper.getLabels( @@ -135,7 +135,7 @@ MetricSnapshot fromSnapshotAndCount( new MetricMetadata(PrometheusNaming.sanitizeMetricName(dropwizardName), helpMessage); SummarySnapshot.SummaryDataPointSnapshot.Builder dataPointBuilder = SummarySnapshot.SummaryDataPointSnapshot.builder().quantiles(quantiles).count(count); - labelMapper.map( + labelMapper.ifPresent( mapper -> dataPointBuilder.labels( mapper.getLabels( @@ -168,7 +168,7 @@ MetricSnapshot fromMeter(String dropwizardName, Meter meter) { MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter); CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount()); - labelMapper.map( + labelMapper.ifPresent( mapper -> dataPointBuilder.labels( mapper.getLabels( @@ -180,22 +180,20 @@ MetricSnapshot fromMeter(String dropwizardName, Meter meter) { public MetricSnapshots collect() { MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder(); for (@SuppressWarnings("rawtypes") - SortedMap.Entry entry : registry.getGauges(metricFilter).entrySet()) { + Map.Entry entry : registry.getGauges(metricFilter).entrySet()) { Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue())) - .map(metricSnapshots::metricSnapshot); + .ifPresent(metricSnapshots::metricSnapshot); } - for (SortedMap.Entry entry : - registry.getCounters(metricFilter).entrySet()) { + for (Map.Entry entry : registry.getCounters(metricFilter).entrySet()) { metricSnapshots.metricSnapshot(fromCounter(entry.getKey().getKey(), entry.getValue())); } - for (SortedMap.Entry entry : - registry.getHistograms(metricFilter).entrySet()) { + for (Map.Entry entry : registry.getHistograms(metricFilter).entrySet()) { metricSnapshots.metricSnapshot(fromHistogram(entry.getKey().getKey(), entry.getValue())); } - for (SortedMap.Entry entry : registry.getTimers(metricFilter).entrySet()) { + for (Map.Entry entry : registry.getTimers(metricFilter).entrySet()) { metricSnapshots.metricSnapshot(fromTimer(entry.getKey().getKey(), entry.getValue())); } - for (SortedMap.Entry entry : registry.getMeters(metricFilter).entrySet()) { + for (Map.Entry entry : registry.getMeters(metricFilter).entrySet()) { metricSnapshots.metricSnapshot(fromMeter(entry.getKey().getKey(), entry.getValue())); } return metricSnapshots.build(); diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java index 19e52d788..f69a27944 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java @@ -14,7 +14,7 @@ *

      Dropwizard metrics that match the "match" pattern will be further processed to have a new name * and new labels based on this config. */ -public class MapperConfig { +public final class MapperConfig { // each part of the metric name between dots private static final String METRIC_PART_REGEX = "[a-zA-Z_0-9](-?[a-zA-Z0-9_])+"; // Simplified GLOB: we can have "*." at the beginning and "*" only at the end diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java index 3bd39a59f..671c36c97 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java @@ -51,8 +51,7 @@ public class JvmMemoryPoolAllocationMetrics { private final List garbageCollectorBeans; - private JvmMemoryPoolAllocationMetrics( - List garbageCollectorBeans, PrometheusProperties config) { + private JvmMemoryPoolAllocationMetrics(List garbageCollectorBeans) { this.garbageCollectorBeans = garbageCollectorBeans; } @@ -142,21 +141,18 @@ private static long getAndSet(Map map, String key, long value) { } public static Builder builder() { - return new Builder(PrometheusProperties.get()); + return new Builder(); } + @SuppressWarnings("unused") public static Builder builder(PrometheusProperties config) { - return new Builder(config); + return new Builder(); } public static class Builder { - - private final PrometheusProperties config; private List garbageCollectorBeans; - private Builder(PrometheusProperties config) { - this.config = config; - } + private Builder() {} /** Package private. For testing only. */ Builder withGarbageCollectorBeans(List garbageCollectorBeans) { @@ -173,7 +169,7 @@ public void register(PrometheusRegistry registry) { if (garbageCollectorBeans == null) { garbageCollectorBeans = ManagementFactory.getGarbageCollectorMXBeans(); } - new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans, config).register(registry); + new JvmMemoryPoolAllocationMetrics(garbageCollectorBeans).register(registry); } } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java index bd7fb14b1..a854f5e89 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java @@ -7,13 +7,15 @@ import io.prometheus.metrics.model.snapshots.Unit; import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; /** * Process metrics. @@ -112,6 +114,7 @@ private void register(PrometheusRegistry registry) { callback.call(Unit.nanosToSeconds(processCpuTime)); } } catch (Exception ignored) { + // Ignored } }) .register(registry); @@ -134,6 +137,7 @@ private void register(PrometheusRegistry registry) { callback.call(openFds); } } catch (Exception ignored) { + // Ignored } }) .register(registry); @@ -149,6 +153,7 @@ private void register(PrometheusRegistry registry) { callback.call(maxFds); } } catch (Exception ignored) { + // Ignored } }) .register(registry); @@ -165,6 +170,7 @@ private void register(PrometheusRegistry registry) { String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmSize:"); callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); } catch (Exception ignored) { + // Ignored } }) .register(registry); @@ -179,6 +185,7 @@ private void register(PrometheusRegistry registry) { String line = grepper.lineStartingWith(PROC_SELF_STATUS, "VmRSS:"); callback.call(Unit.kiloBytesToBytes(Double.parseDouble(line.split("\\s+")[1]))); } catch (Exception ignored) { + // Ignored } }) .register(registry); @@ -235,7 +242,9 @@ private static class FileGrepper implements Grepper { @Override public String lineStartingWith(File file, String prefix) throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + try (BufferedReader reader = + new BufferedReader( + new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { String line = reader.readLine(); while (line != null) { if (line.startsWith(prefix)) { diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java index fe97561aa..9c9e069b6 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetricsTest.java @@ -109,6 +109,7 @@ public void testInvalidThreadIds() { return; } } catch (NumberFormatException ignored) { + // ignore } PrometheusRegistry registry = new PrometheusRegistry(); JvmThreadsMetrics.builder().register(registry); diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java index 6b5d4dea6..09e75181b 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBuckets.java @@ -35,7 +35,7 @@ private ClassicHistogramBuckets(double[] upperBounds, long[] counts) { * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is - * the count for the {@code upperBound} at index {@code i}. For each count, {@link + * the count for the {@code upperBounds} at index {@code i}. For each count, {@link * Number#longValue()} is called to get the value. Counts are not cumulative. Counts * must not be negative. */ @@ -63,7 +63,7 @@ public static ClassicHistogramBuckets of( * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is - * the count for the {@code upperBound} at index {@code i}. For each count, {@link + * the count for the {@code upperBounds} at index {@code i}. For each count, {@link * Number#longValue()} is called to get the value. Counts are not cumulative. Counts * must not be negative. */ @@ -87,7 +87,7 @@ public static ClassicHistogramBuckets of(double[] upperBounds, Number[] counts) * contain at least {@link Double#POSITIVE_INFINITY} for the {@code +Inf} bucket. An upper * bound must not be {@link Double#NaN}. The upperBounds array does not need to be sorted. * @param counts must have the same length as {@code upperBounds}. The entry at index {@code i} is - * the count for the {@code upperBound} at index {@code i}. Counts are not cumulative. + * the count for the {@code upperBounds} at index {@code i}. Counts are not cumulative. * Counts must not be negative. */ public static ClassicHistogramBuckets of(double[] upperBounds, long[] counts) { 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 170ec4fc2..dcb32f3bc 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 @@ -11,7 +11,7 @@ import java.util.stream.Stream; /** Immutable set of name/value pairs, sorted by name. */ -public class Labels implements Comparable, Iterable

      * * Note that in Prometheus, units are largely based on SI base units (seconds, bytes, joules, grams, - * meters, ratio, volts, amperes, and celsius). + * meters, ratio, volts, amperes, and Celsius). */ -public class Unit { +public final class Unit { private final String name; diff --git a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java index e68ebd968..c11d69e26 100644 --- a/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java +++ b/prometheus-metrics-simpleclient-bridge/src/main/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollector.java @@ -291,14 +291,6 @@ private MetricSnapshot convertUnknown(Collector.MetricFamilySamples samples) return unknown.build(); } - private String stripSuffix(String name, String suffix) { - if (name.endsWith(suffix)) { - return name.substring(0, name.length() - suffix.length()); - } else { - return name; - } - } - private Unit convertUnit(Collector.MetricFamilySamples samples) { if (samples.unit != null && !samples.unit.isEmpty()) { return new Unit(samples.unit); @@ -385,8 +377,9 @@ private Exemplar convertExemplar(io.prometheus.client.exemplars.Exemplar exempla * follow the pattern to pass the config everywhere so that we can introduce config options later * without the need for API changes. */ + @SuppressWarnings("unused") public static Builder builder(PrometheusProperties config) { - return new Builder(config); + return new Builder(); } public static Builder builder() { @@ -395,12 +388,9 @@ public static Builder builder() { public static class Builder { - private final PrometheusProperties config; private CollectorRegistry collectorRegistry; - private Builder(PrometheusProperties config) { - this.config = config; - } + private Builder() {} public Builder collectorRegistry(CollectorRegistry registry) { this.collectorRegistry = registry; diff --git a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java index a678bed93..89cae65ba 100644 --- a/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java +++ b/prometheus-metrics-simpleclient-bridge/src/test/java/io/prometheus/metrics/simpleclient/bridge/SimpleclientCollectorTest.java @@ -74,7 +74,7 @@ public void testGaugeComplete() throws IOException, InterruptedException { } @Test - public void testGaugeMinimal() throws IOException, InterruptedException { + public void testGaugeMinimal() throws IOException { Gauge gauge = Gauge.build() .name("temperature_centigrade") @@ -107,7 +107,7 @@ public void testHistogramComplete() throws IOException, InterruptedException { } @Test - public void testHistogramMinimal() throws IOException, InterruptedException { + public void testHistogramMinimal() throws IOException { Histogram.build().name("request_latency").help("request latency").register(origRegistry); assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); @@ -138,9 +138,8 @@ public void testSummaryComplete() throws IOException, InterruptedException { } @Test - public void testSummaryMinimal() throws IOException, InterruptedException { - Summary summary = - Summary.build().name("request_size").help("request size").register(origRegistry); + public void testSummaryMinimal() throws IOException { + Summary.build().name("request_size").help("request size").register(origRegistry); assertThat(sort(newOpenMetrics())).isEqualTo(fixCounts(fixTimestamps(sort(origOpenMetrics())))); } @@ -161,7 +160,7 @@ public void testInfoComplete() throws IOException, InterruptedException { } @Test - public void testInfoMinimal() throws IOException, InterruptedException { + public void testInfoMinimal() throws IOException { Info info = Info.build().name("jvm").help("JVM info").register(origRegistry); info.info("version", "17"); From 434c84c3d63b68ddd5d62a4886e66b320d6b3d3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:14:45 +0200 Subject: [PATCH 419/980] Bump org.wiremock:wiremock from 3.5.4 to 3.9.1 (#1143) Bumps [org.wiremock:wiremock](https://github.com/wiremock/wiremock) from 3.5.4 to 3.9.1. - [Release notes](https://github.com/wiremock/wiremock/releases) - [Commits](https://github.com/wiremock/wiremock/compare/3.5.4...3.9.1) --- updated-dependencies: - dependency-name: org.wiremock:wiremock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 86d58ca30..4bb66dc1d 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -47,7 +47,7 @@ org.wiremock wiremock - 3.5.4 + 3.9.1 test From 850628087666a7678356696e45ca44f96053d324 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:14:59 +0200 Subject: [PATCH 420/980] Bump org.apache.maven.plugins:maven-project-info-reports-plugin (#1141) Bumps [org.apache.maven.plugins:maven-project-info-reports-plugin](https://github.com/apache/maven-project-info-reports-plugin) from 2.9 to 3.7.0. - [Commits](https://github.com/apache/maven-project-info-reports-plugin/compare/maven-project-info-reports-plugin-2.9...maven-project-info-reports-plugin-3.7.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-project-info-reports-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3105a1b22..9d4d95195 100644 --- a/pom.xml +++ b/pom.xml @@ -317,7 +317,7 @@ maven-project-info-reports-plugin - 2.9 + 3.7.0 maven-javadoc-plugin From 77226ce9f84ec947fc184ee04ceb3d7fae673daf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:15:22 +0200 Subject: [PATCH 421/980] Bump org.apache.maven.plugins:maven-release-plugin from 2.5.3 to 3.1.1 (#1140) Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 2.5.3 to 3.1.1. - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-2.5.3...maven-release-3.1.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d4d95195..9dcbcb98b 100644 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,7 @@ maven-release-plugin - 2.5.3 + 3.1.1 maven-dependency-plugin From d921935f7e3c5e8ea3826e1bd332ec1553d969f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:15:34 +0200 Subject: [PATCH 422/980] Bump com.google.guava:guava from 33.2.1-jre to 33.3.1-jre (#1144) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.2.1-jre to 33.3.1-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-instrumentation-guava/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 55c45f233..c3450c48b 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -37,7 +37,7 @@ com.google.guava guava - 33.2.1-jre + 33.3.1-jre provided From daf36286d4aadb4225cdc1eaffb3d9878645f7cc Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 11 Oct 2024 07:48:48 +0200 Subject: [PATCH 423/980] clean up maven (#1145) * clean up maven Signed-off-by: Gregor Zeitlinger * clean up maven Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .../example-greeting-service/pom.xml | 17 ++++------------ .../greeting/GreetingServlet.java | 2 +- .../example-hello-world-app/pom.xml | 17 ++++------------ .../otel_exemplars/app/HelloWorldServlet.java | 2 +- .../example-exemplars-tail-sampling/pom.xml | 16 ++++----------- .../example-exporter-servlet-tomcat/pom.xml | 17 ++++------------ .../tomcat_servlet/HelloWorldServlet.java | 2 +- .../it-exporter-servlet-tomcat-sample/pom.xml | 17 ++++------------ pom.xml | 7 ++++--- .../pom.xml | 20 +------------------ 10 files changed, 28 insertions(+), 89 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index fc329b061..fd0750e6e 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -15,6 +15,10 @@ Part of a distributed "Hello, World" REST service to show Exemplars with OpenTelemetry's distributed tracing + + 17 + + io.prometheus @@ -41,19 +45,6 @@ ${project.artifactId} - - maven-compiler-plugin - - 17 - 17 - 17 - true - - -Xlint:all - -Werror - - - org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java index 45b2c8a79..a2b16f5f5 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java @@ -34,7 +34,7 @@ public GreetingServlet() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { long start = System.nanoTime(); try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + Thread.sleep((long) Math.abs((random.nextGaussian() + 1.0) * 100.0)); resp.setStatus(200); resp.setContentType("text/plain"); resp.getWriter().println("Hello, World!"); diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index e7ab8cbd6..3e51aee99 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -15,6 +15,10 @@ Part of a distributed "Hello, World" REST service to show Exemplars with OpenTelemetry's distributed tracing + + 17 + + io.prometheus @@ -41,19 +45,6 @@ ${project.artifactId} - - maven-compiler-plugin - - 17 - 17 - 17 - true - - -Xlint:all - -Werror - - - org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java index f5a90d977..988f63819 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java @@ -41,7 +41,7 @@ public HelloWorldServlet() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { long start = System.nanoTime(); try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + Thread.sleep((long) Math.abs((random.nextGaussian() + 1.0) * 100.0)); String greeting = executeGreetingServiceRequest(); resp.setStatus(200); resp.setContentType("text/plain"); diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 6fc7c9c2f..84117e965 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -16,20 +16,12 @@ Example project showing Examplars with OpenTelemetry's Tail Sampling. + + 11 + + example-greeting-service example-hello-world-app - - - - - maven-compiler-plugin - - 11 - 11 - - - - diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 357dd3118..81b81aa15 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -15,6 +15,10 @@ Prometheus Metrics Example using Embedded Tomcat and the Exporter Servlet + + 17 + + io.prometheus @@ -41,19 +45,6 @@ ${project.artifactId} - - maven-compiler-plugin - - 17 - 17 - 17 - true - - -Xlint:all - -Werror - - - org.apache.maven.plugins maven-shade-plugin diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java index e2b654f34..309cc5ba4 100644 --- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java +++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java @@ -44,7 +44,7 @@ public HelloWorldServlet() { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { long start = System.nanoTime(); try { - Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0))); + Thread.sleep((long) Math.abs((random.nextGaussian() + 1.0) * 100.0)); resp.setStatus(200); resp.setContentType("text/plain"); resp.getWriter().println("Hello, World!"); diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index e9ebcb583..67b6fa0c3 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -15,6 +15,10 @@ Tomcat Sample for the Exporter Integration Test + + 17 + + io.prometheus @@ -36,19 +40,6 @@ exporter-servlet-tomcat-sample - - maven-compiler-plugin - - 17 - 17 - 17 - true - - -Xlint:all - -Werror - - - org.apache.maven.plugins maven-shade-plugin diff --git a/pom.xml b/pom.xml index 9dcbcb98b..8665f90be 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ --module-name-need-to-be-overriden-- 5.11.2 1.42.1 + 8 @@ -270,9 +271,9 @@ maven-compiler-plugin - 8 - 8 - 8 + ${java.version} + ${java.version} + ${java.version} true -Xlint:all diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index d135fb36d..c8852f597 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -19,6 +19,7 @@ io.prometheus.metrics.exporter.servlet.jakarta + 17 @@ -34,23 +35,4 @@ provided - - - - - maven-compiler-plugin - - 17 - 17 - 17 - true - - -Xlint:all - -Werror - - - - - - From 47ad01208703e2f5445b47bf8bb3c77547eb44f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 07:59:48 +0200 Subject: [PATCH 424/980] Bump org.eclipse.jetty:jetty-server from 11.0.21 to 12.0.14 (#1142) * Bump org.eclipse.jetty:jetty-server from 11.0.21 to 12.0.14 Bumps org.eclipse.jetty:jetty-server from 11.0.21 to 12.0.14. --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix jetty Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../it-exporter-servlet-jetty-sample/pom.xml | 12 ++++++++---- .../servlet/jetty/ExporterServletJettySample.java | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index add87bf93..91b6c39e0 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -14,6 +14,10 @@ Jetty Sample for the Exporter Integration Test + + 12.0.14 + 17 + @@ -29,12 +33,12 @@ org.eclipse.jetty jetty-server - 11.0.21 + ${jetty-server.version} - org.eclipse.jetty - jetty-servlet - 11.0.21 + org.eclipse.jetty.ee10 + jetty-ee10-servlet + ${jetty-server.version} diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java index 1cc16ee4b..8c899b4ad 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java @@ -7,10 +7,10 @@ import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.Unit; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.servlet.ServletHandler; /** Sample application using the {@link PrometheusMetricsServlet} in Jetty. */ public class ExporterServletJettySample { @@ -73,8 +73,8 @@ public static void main(String[] args) throws Exception { server.setConnectors(new Connector[] {connector}); // register servlet - ServletHandler servletHandler = new ServletHandler(); - servletHandler.addServletWithMapping(PrometheusMetricsServlet.class, "/metrics"); + ServletContextHandler servletHandler = new ServletContextHandler("/"); + servletHandler.addServlet(PrometheusMetricsServlet.class, "/metrics"); server.setHandler(servletHandler); System.out.println("Running on http://localhost:" + port + "/metrics"); From 31c428846790f2b2f78fa23da7747d5fbf416887 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 11 Oct 2024 08:30:02 +0200 Subject: [PATCH 425/980] fix buffer sync logic using modern concurrency primitives (#991) * fix buffer sync logic using modern concurrency primitives Signed-off-by: Gregor Zeitlinger * format Signed-off-by: Gregor Zeitlinger * update benchmarks Signed-off-by: Gregor Zeitlinger * add errorprone Signed-off-by: Gregor Zeitlinger * update benchmarks Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- benchmarks/pom.xml | 31 ++++++-- .../metrics/benchmarks/CounterBenchmark.java | 22 +++--- .../benchmarks/HistogramBenchmark.java | 12 +-- pom.xml | 5 ++ .../metrics/core/metrics/Buffer.java | 75 +++++++++++++------ 5 files changed, 101 insertions(+), 44 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 90e5800d2..2bb1c15a6 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -51,9 +52,9 @@ ${simpleclient.version} - com.codahale.metrics - metrics-core - ${codahale.version} + com.codahale.metrics + metrics-core + ${codahale.version} io.opentelemetry @@ -74,6 +75,25 @@ ${project.artifactId} + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + -parameters + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + + org.apache.maven.plugins maven-shade-plugin @@ -86,7 +106,8 @@ benchmarks - + io.prometheus.metrics.benchmarks.BenchmarkRunner diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java index 8ccf6a40d..f3c1e9309 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java @@ -18,21 +18,21 @@ import org.openjdk.jmh.annotations.Threads; /** - * Results on a machine with dedicated 8 vCPU cores: + * Results on a machine with dedicated Core i7 1265U: * *
        *
        * Benchmark                                     Mode  Cnt      Score     Error  Units
      - * CounterBenchmark.codahaleIncNoLabels         thrpt   25  25761.677 ± 122.947  ops/s
      - * CounterBenchmark.openTelemetryAdd            thrpt   25    545.026 ±  33.913  ops/s
      - * CounterBenchmark.openTelemetryInc            thrpt   25    550.577 ±  45.415  ops/s
      - * CounterBenchmark.openTelemetryIncNoLabels    thrpt   25    527.638 ±  32.020  ops/s
      - * CounterBenchmark.prometheusAdd               thrpt   25  20341.474 ±  40.973  ops/s
      - * CounterBenchmark.prometheusInc               thrpt   25  26414.616 ±  96.666  ops/s
      - * CounterBenchmark.prometheusNoLabelsInc       thrpt   25  26177.676 ± 120.342  ops/s
      - * CounterBenchmark.simpleclientAdd             thrpt   25   5503.867 ± 161.313  ops/s
      - * CounterBenchmark.simpleclientInc             thrpt   25   5568.125 ±  53.291  ops/s
      - * CounterBenchmark.simpleclientNoLabelsInc     thrpt   25   5394.692 ± 130.531  ops/s
      + * CounterBenchmark.codahaleIncNoLabels         thrpt   25  32969.795 ± 1547.775  ops/s
      + * CounterBenchmark.openTelemetryAdd            thrpt   25    747.068 ±   93.128  ops/s
      + * CounterBenchmark.openTelemetryInc            thrpt   25    760.784 ±   47.595  ops/s
      + * CounterBenchmark.openTelemetryIncNoLabels    thrpt   25    824.346 ±   45.131  ops/s
      + * CounterBenchmark.prometheusAdd               thrpt   25  28403.000 ±  250.774  ops/s
      + * CounterBenchmark.prometheusInc               thrpt   25  38368.142 ±  361.914  ops/s
      + * CounterBenchmark.prometheusNoLabelsInc       thrpt   25  35558.069 ± 4020.926  ops/s
      + * CounterBenchmark.simpleclientAdd             thrpt   25   4081.152 ±  620.094  ops/s
      + * CounterBenchmark.simpleclientInc             thrpt   25   5735.644 ± 1205.329  ops/s
      + * CounterBenchmark.simpleclientNoLabelsInc     thrpt   25   6852.563 ±  544.481  ops/s
        * 
      * * Prometheus counters are faster than counters of other libraries. For example, incrementing a diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java index 1bebec573..a8e6bddb1 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java @@ -17,15 +17,15 @@ import org.openjdk.jmh.annotations.Threads; /** - * Results on a machine with dedicated 8 vCPU cores: + * Results on a machine with dedicated Core i7 1265U: * *
        * Benchmark                                     Mode  Cnt      Score     Error  Units
      - * HistogramBenchmark.openTelemetryClassic      thrpt   25    258.660 ±   6.736  ops/s
      - * HistogramBenchmark.openTelemetryExponential  thrpt   25    210.963 ±  11.288  ops/s
      - * HistogramBenchmark.prometheusClassic         thrpt   25   1528.871 ±  43.598  ops/s
      - * HistogramBenchmark.prometheusNative          thrpt   25   1282.643 ± 110.210  ops/s
      - * HistogramBenchmark.simpleclient              thrpt   25   3376.016 ± 173.545  ops/s
      + * HistogramBenchmark.openTelemetryClassic      thrpt   25    390.982 ±   16.058  ops/s
      + * HistogramBenchmark.openTelemetryExponential  thrpt   25    320.160 ±   18.056  ops/s
      + * HistogramBenchmark.prometheusClassic         thrpt   25   2385.862 ±   34.766  ops/s
      + * HistogramBenchmark.prometheusNative          thrpt   25   1947.371 ±   48.193  ops/s
      + * HistogramBenchmark.simpleclient              thrpt   25   4324.961 ±   50.938  ops/s
        * 
      * * The simpleclient (i.e. client_java version 0.16.0 and older) histograms perform about the same as diff --git a/pom.xml b/pom.xml index 8665f90be..479a06133 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,11 @@ Gregor Zeitlinger gregor.zeitlinger@grafana.com + + dhoard + Doug Hoard + doug.hoard@gmail.com + diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java index 69f6de86f..135b09044 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -3,6 +3,8 @@ import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import java.util.Arrays; import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -15,17 +17,19 @@ */ class Buffer { - private static final long signBit = 1L << 63; + private static final long bufferActiveBit = 1L << 63; private final AtomicLong observationCount = new AtomicLong(0); private double[] observationBuffer = new double[0]; private int bufferPos = 0; private boolean reset = false; - private final Object appendLock = new Object(); - private final Object runLock = new Object(); + + ReentrantLock appendLock = new ReentrantLock(); + ReentrantLock runLock = new ReentrantLock(); + Condition bufferFilled = appendLock.newCondition(); boolean append(double value) { long count = observationCount.incrementAndGet(); - if ((count & signBit) == 0) { + if ((count & bufferActiveBit) == 0) { return false; // sign bit not set -> buffer not active. } else { doAppend(value); @@ -34,12 +38,17 @@ boolean append(double value) { } private void doAppend(double amount) { - synchronized (appendLock) { + appendLock.lock(); + try { if (bufferPos >= observationBuffer.length) { observationBuffer = Arrays.copyOf(observationBuffer, observationBuffer.length + 128); } observationBuffer[bufferPos] = amount; bufferPos++; + + bufferFilled.signalAll(); + } finally { + appendLock.unlock(); } } @@ -48,33 +57,55 @@ void reset() { reset = true; } - @SuppressWarnings("ThreadPriorityCheck") T run( - Function complete, Supplier runnable, Consumer observeFunction) { + Function complete, + Supplier createResult, + Consumer observeFunction) { double[] buffer; int bufferSize; T result; - synchronized (runLock) { - long count = observationCount.getAndAdd(signBit); - while (!complete.apply(count)) { - Thread.yield(); - } - result = runnable.get(); - int expectedBufferSize; - if (reset) { - expectedBufferSize = (int) ((observationCount.getAndSet(0) & ~signBit) - count); - reset = false; - } else { - expectedBufferSize = (int) (observationCount.addAndGet(signBit) - count); - } - while (bufferPos != expectedBufferSize) { - Thread.yield(); + + runLock.lock(); + try { + // Signal that the buffer is active. + Long expectedCount = observationCount.getAndAdd(bufferActiveBit); + + appendLock.lock(); + try { + while (!complete.apply(expectedCount)) { + // Wait until all in-flight threads have added their observations to the buffer. + bufferFilled.await(); + } + result = createResult.get(); + + // Signal that the buffer is inactive. + int expectedBufferSize; + if (reset) { + expectedBufferSize = + (int) ((observationCount.getAndSet(0) & ~bufferActiveBit) - expectedCount); + reset = false; + } else { + expectedBufferSize = (int) (observationCount.addAndGet(bufferActiveBit) - expectedCount); + } + + while (bufferPos < expectedBufferSize) { + // Wait until all in-flight threads have added their observations to the buffer. + bufferFilled.await(); + } + } finally { + appendLock.unlock(); } + buffer = observationBuffer; bufferSize = bufferPos; observationBuffer = new double[0]; bufferPos = 0; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } finally { + runLock.unlock(); } + for (int i = 0; i < bufferSize; i++) { observeFunction.accept(buffer[i]); } From b8ff9853961dfa18e784eb75dacaf6d2a2f9b012 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 08:50:03 +0200 Subject: [PATCH 426/980] Bump org.eclipse.jetty:jetty-server (#1149) Bumps org.eclipse.jetty:jetty-server from 10.0.10 to 10.0.24. --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- simpleclient-archive/simpleclient_jetty/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient-archive/simpleclient_jetty/pom.xml b/simpleclient-archive/simpleclient_jetty/pom.xml index db2dab617..85d7b49b3 100644 --- a/simpleclient-archive/simpleclient_jetty/pom.xml +++ b/simpleclient-archive/simpleclient_jetty/pom.xml @@ -17,7 +17,7 @@ - 10.0.10 + 10.0.24 From a133d761e14a25e62be7c66bf166004b63973ac5 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 15 Oct 2024 18:30:01 +0200 Subject: [PATCH 427/980] fix deadlock (#1152) * fix deadlock Signed-off-by: Gregor Zeitlinger * fix deadlock Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .../metrics/core/metrics/Buffer.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java index 135b09044..35c1fbe08 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -57,6 +57,7 @@ void reset() { reset = true; } + @SuppressWarnings("ThreadPriorityCheck") T run( Function complete, Supplier createResult, @@ -70,24 +71,26 @@ T run( // Signal that the buffer is active. Long expectedCount = observationCount.getAndAdd(bufferActiveBit); - appendLock.lock(); - try { - while (!complete.apply(expectedCount)) { - // Wait until all in-flight threads have added their observations to the buffer. - bufferFilled.await(); - } - result = createResult.get(); + while (!complete.apply(expectedCount)) { + // Wait until all in-flight threads have added their observations to the histogram + // we can't use a condition here, because the other thread doesn't have a lock as it's on + // the fast path. + Thread.yield(); + } + result = createResult.get(); - // Signal that the buffer is inactive. - int expectedBufferSize; - if (reset) { - expectedBufferSize = - (int) ((observationCount.getAndSet(0) & ~bufferActiveBit) - expectedCount); - reset = false; - } else { - expectedBufferSize = (int) (observationCount.addAndGet(bufferActiveBit) - expectedCount); - } + // Signal that the buffer is inactive. + int expectedBufferSize; + if (reset) { + expectedBufferSize = + (int) ((observationCount.getAndSet(0) & ~bufferActiveBit) - expectedCount); + reset = false; + } else { + expectedBufferSize = (int) (observationCount.addAndGet(bufferActiveBit) - expectedCount); + } + appendLock.lock(); + try { while (bufferPos < expectedBufferSize) { // Wait until all in-flight threads have added their observations to the buffer. bufferFilled.await(); From c9ff46b7162a3169a8e29c2bacc955884f556542 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:30:44 +0200 Subject: [PATCH 428/980] Bump org.mockito:mockito-core from 5.14.1 to 5.14.2 (#1151) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.14.1 to 5.14.2. - [Release notes](https://github.com/mockito/mockito/releases) - [Commits](https://github.com/mockito/mockito/compare/v5.14.1...v5.14.2) --- updated-dependencies: - dependency-name: org.mockito:mockito-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 479a06133..ede38b014 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,7 @@ org.mockito mockito-core - 5.14.1 + 5.14.2 test From 0f32c6753489a1901b9c7091039187712592ce1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:10:59 +0200 Subject: [PATCH 429/980] Bump org.apache.tomcat.embed:tomcat-embed-core from 10.1.30 to 11.0.0 (#1146) * Bump org.apache.tomcat.embed:tomcat-embed-core from 10.1.30 to 11.0.0 Bumps org.apache.tomcat.embed:tomcat-embed-core from 10.1.30 to 11.0.0. --- updated-dependencies: - dependency-name: org.apache.tomcat.embed:tomcat-embed-core dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix tomcat Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter-servlet-tomcat-sample/pom.xml | 2 +- .../metrics/it/exporter/test/ExporterIT.java | 10 +++++++++- .../prometheus/metrics/it/exporter/test/TomcatIT.java | 7 +++++++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index fd0750e6e..f0d2a6a46 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.30 + 11.0.0 diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 3e51aee99..299cb7656 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.30 + 11.0.0
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 81b81aa15..f41ba92f4 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.30 + 11.0.0
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 67b6fa0c3..8cb9faa81 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -33,7 +33,7 @@ org.apache.tomcat.embed tomcat-embed-core - 10.1.30 + 11.0.0
      diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 3e0caf954..852b7cd0d 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -176,6 +176,10 @@ public void testErrorHandling() throws IOException { assertThat(new String(response.body, UTF_8)).contains("Simulating an error."); } + protected boolean headReturnsContentLength() { + return true; + } + @Test public void testHeadRequest() throws IOException { sampleAppContainer @@ -186,7 +190,11 @@ public void testHeadRequest() throws IOException { assertThat(size > 0).isTrue(); Response headResponse = scrape("HEAD", ""); assertThat(headResponse.status).isEqualTo(200); - assertThat(headResponse.getHeader("Content-Length")).isEqualTo(Integer.toString(size)); + if (headReturnsContentLength()) { + assertThat(headResponse.getHeader("Content-Length")).isEqualTo(Integer.toString(size)); + } else { + assertThat(headResponse.getHeader("Content-Length")).isNull(); + } assertThat(headResponse.body.length).isZero(); } diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java index ea5e6b69d..731e7fa3a 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java @@ -7,4 +7,11 @@ class TomcatIT extends ExporterIT { public TomcatIT() throws IOException, URISyntaxException { super("exporter-servlet-tomcat-sample"); } + + @Override + protected boolean headReturnsContentLength() { + // not any more since + // https://tomcat.apache.org/tomcat-11.0-doc/changelog.html#Tomcat_11.0.0-M3_(markt) + return false; + } } From c06da1a364823daeb5627973c1fbcd5602727a10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:21:22 +0200 Subject: [PATCH 430/980] Bump org.eclipse.jetty:jetty-server (#1153) Bumps org.eclipse.jetty:jetty-server from 11.0.10 to 11.0.24. --- updated-dependencies: - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- simpleclient-archive/simpleclient_jetty_jdk8/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml index 9ac30461d..a2e1027c7 100644 --- a/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml +++ b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml @@ -25,7 +25,7 @@ org.eclipse.jetty jetty-server - 11.0.10 + 11.0.24 org.eclipse.jetty From 8963973aad31e93b6ad6ce4f5b1716479aed6035 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 16 Oct 2024 16:39:10 +0200 Subject: [PATCH 431/980] Release automation (#1154) * release automation Signed-off-by: Gregor Zeitlinger * release automation Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * release Signed-off-by: Gregor Zeitlinger * secrets are not available for prs Signed-off-by: Gregor Zeitlinger * secrets are not available for prs Signed-off-by: Gregor Zeitlinger * secrets are not available for prs Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/workflows/build.yml | 2 +- .github/workflows/github-pages.yaml | 11 +- .github/workflows/release.yml | 48 ++++++++ CONTRIBUTING.md | 4 + MAINTAINER_NOTES.md | 71 ----------- RELEASING.md | 25 ++++ benchmarks/pom.xml | 3 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- .../example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- .../example-exporter-multi-target/pom.xml | 2 +- .../example-exporter-opentelemetry/pom.xml | 2 +- .../example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- .../example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 6 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter-servlet-tomcat-sample/pom.xml | 2 +- .../it-exporter/it-exporter-test/pom.xml | 6 +- integration-tests/it-exporter/pom.xml | 2 +- integration-tests/it-pushgateway/pom.xml | 6 +- integration-tests/pom.xml | 6 +- pom.xml | 114 +++++++++--------- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- .../pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 48 files changed, 179 insertions(+), 195 deletions(-) create mode 100644 .github/workflows/release.yml delete mode 100644 MAINTAINER_NOTES.md create mode 100644 RELEASING.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ac4d429e..108ad6529 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,4 +28,4 @@ jobs: REQUIRE_PROTO_UP_TO_DATE: true run: | ./mvnw clean install - ./mvnw javadoc:javadoc + ./mvnw javadoc:javadoc -P release # just to check if javadoc is generated diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 43a6fd94d..56380ec7f 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -44,17 +44,10 @@ jobs: run: | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ && sudo dpkg -i ${{ runner.temp }}/hugo.deb - #- name: Install Dart Sass - # run: sudo snap install dart-sass - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - name: Build client_java - run: ./mvnw -B clean install -DskipTests + run: ./mvnw -B clean install -DskipTests -P release - name: Make Javadoc - run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate + run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate -P release - name: Move the Javadoc to docs/static/api/ run: mv ./target/reports/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api - name: Setup Pages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..dde83081a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,48 @@ +name: Deploy to Maven Central + +#on: +# push: +# tags: +# - v* +on: + push: + branches: [ "main" ] +# pull_request: +# branches: [ "main" ] + +jobs: + deploy: + if: ${{ github.repository == 'prometheus/client_java' }} + runs-on: ubuntu-latest + + steps: + - name: Checkout Plugin Repository + uses: actions/checkout@v4 + + - name: Set Up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: 'maven' + + - name: Build with Maven + run: mvn -B package -P release -Dmaven.test.skip=true + + - name: Set up Apache Maven Central + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_CENTRAL_TOKEN + gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + + - name: Publish to Apache Maven Central + run: mvn deploy -P release + env: + MAVEN_USERNAME: ${{ secrets.SONATYPE_MAVEN_REPOSITORY_USERNAME }} + MAVEN_CENTRAL_TOKEN: ${{ secrets.SONATYPE_MAVEN_REPOSITORY_PASSWORD }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSPHRASE }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dbac64dd5..d9e3d5779 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,3 +22,7 @@ Run `./mvnw spotless:apply` to format the code (only changed files) before commi If you're getting errors when running tests: - Make sure that the IDE uses only the "Maven Shade" dependency of "prometheus-metrics-exposition-formats" and the "prometheus-metrics-tracer*" dependencies. + +## Updating the Protobuf Java Classes + +Use `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. diff --git a/MAINTAINER_NOTES.md b/MAINTAINER_NOTES.md deleted file mode 100644 index 495fab6cf..000000000 --- a/MAINTAINER_NOTES.md +++ /dev/null @@ -1,71 +0,0 @@ -# Maintainer Notes - -## Update Dependency Versions - -Use the [Versions Maven Plugin](https://www.mojohaus.org/versions-maven-plugin/index.html). Rules are configured in [version-rules.xml](version-rules.xml). - -``` -./mvnw versions:use-latest-releases -``` - -The versions plugin does not catch the `otel.version` in `prometheus-metrics-exporter-opentelemetry`. This needs to be updated manually. - -## Update Shaded Dependencies - -There are two modules for shaded dependencies: -* `prometheus-metrics-shaded-protobuf`: Google's protobuf library. - -The shaded modules are commented out in the root `pom.xml`. Instead of using the shaded dependencies from the project, we use the latest shaded dependencies from Maven central (or from the local Maven repository in `~/.m2/repository/`). This way we can `include` the shaded package name directly. We find this easier than importing the original package name and have it renamed at build time. - -In order to update dependencies of the shaded modules (like Google's protobuf library or the OpenTelemetry library), do the following: - -Step 1: Install updated versions of the shaded dependencies in your local Maven repository. - -* Update the dependency versions in the shaded modules (both `*.version` and `*.version.string`). -* `cd ./prometheus-metrics-shaded-dependencies ; ../mvnw install ; cd ..` - -Step 2: Update `prometheus-metrics-expositon-formats` - -* Change the version of the `prometheus-metrics-shaded-protobuf` dependency in `pom.xml` to `${project.version}`. -* Update `PROTOBUF_VERSION_STRING` in `generate-protobuf.sh` and run the script to update the source code. -* Use find-and-replace to update the version numbers in the imported package names in the source code of `prometheus-metrics-exposition-formats` and `prometheus-metrics-core`. - -Step 3: Update `prometheus-metrics-exporter-opentelemetry` - -* Change the version of the `prometheus-metrics-shaded-opentelemetry` dependency in `pom.xml` to `${project.version}`. -* Use find-and-replace to update the version numbers in the imported package names in the source code of `prometheus-metrics-exporter-opentelemetry`. - -Step 4: Update `prometheus-metrics-bom` - -* Set the shaded dependency version property to `${project.version}` in `prometheus-metrics-bom/pom.xml` - -Step 5: Release - -_see below_ - -## Release - -Create a commit to temporarily add shaded dependencies to the project: - -* Add the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`. -* Change the versions of the shaded dependencies to `${project.version}` in `prometheus-metrics-exporter-opentelemetry`, `prometheus-metrics-exposition-formats`, and `prometheus-metrics-bom`. - -Release: - -``` -./mvnw release:prepare -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT -./mvnw release:perform -DreleaseVersion=1.2.0 -DdevelopmentVersion=1.3.0-SNAPSHOT -``` - -`release:prepare` does GitHub tags and commits, while `release:perform` signs the artifacts and uploads them to the staging repositoring on [https://oss.sonatype.org](https://oss.sonatype.org). - -After that, manually verify the uploaded artifacts on [https://oss.sonatype.org/#stagingRepositories](https://oss.sonatype.org/#stagingRepositories), click `Close` to trigger Sonatype's verification, and then `Release`. - -Create a commit to remove dependencies from the build (undoing the first step): - -* Comment out the `prometheus-metrics-shaded-dependencies` module to the root `pom.xml`. -* Change the versions of the shaded dependencies to the latest released version on Maven Central in `prometheus-metrics-exporter-opentelemetry`, `prometheus-metrics-exposition-formats`, and `prometheus-metrics-bom`. - -## Notes - -- `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 000000000..c7b195c8b --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,25 @@ +## Update Version + +In a new PR, update the version in `pom.xml` using + +```shell +mvn versions:set -DnewVersion= +``` + +Commit the changes and open a PR. + +## Publish Release via Github Workflow + +On main branch, create a tag for the new version to trigger the release workflow. + +```sh +git tag -a v -m "Release v" +git push origin v +``` + +## Create a Release + +1. Go to https://github.com/prometheus/client_java/releases +2. Click on "Choose a tag", enter the tag name (e.g. `v0.1.0`), and click "Create a new tag". +3. Click on "Generate release notes" to auto-generate the release notes based on the commits since the last release. +4. Click on "Publish release". diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 2bb1c15a6..4b7d53b79 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 benchmarks @@ -20,7 +20,6 @@ 1.37 0.16.0 3.0.2 - true diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index f0d2a6a46..bb152565a 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 299cb7656..0a62eee13 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 84117e965..85cecfeb2 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 575cc479a..97a53e64c 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 8b7382275..23ee8b63c 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 057022269..a1cd6c28f 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index f41ba92f4..520141b58 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 0d17251ae..ed97c5e46 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 0c910483f..ad68ab386 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 0e2607f1c..e80429b30 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 3a24e5724..def095f43 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 examples @@ -16,10 +16,6 @@ Example projects for the Prometheus Metrics Library. - - true - - example-exemplars-tail-sampling example-exporter-servlet-tomcat diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 0b779da40..ecf5f9cb2 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index e44f4396a..16aa565e4 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 91b6c39e0..105f43f90 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 8cb9faa81..15c8e89e3 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 97748af84..8b7465d52 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-exporter-test @@ -16,10 +16,6 @@ Integration Tests for Exporters - - true - - io.prometheus diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 1c7066298..cd143e911 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-exporter diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 15177eeb6..95ef595bd 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 it-pushgateway @@ -16,10 +16,6 @@ Integration tests for the Pushgateway Exporter - - true - - io.prometheus diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 89315a227..dbd6754c6 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 integration-tests @@ -18,10 +18,6 @@ Integration tests for the Exporter modules - - true - - it-common it-exporter diff --git a/pom.xml b/pom.xml index ede38b014..5735d8581 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 Prometheus Metrics Library http://github.com/prometheus/client_java @@ -73,22 +73,8 @@ prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-instrumentation-guava prometheus-metrics-simpleclient-bridge - examples - benchmarks - integration-tests - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - org.junit.jupiter @@ -162,10 +148,6 @@ maven-failsafe-plugin 3.5.1
      - - maven-release-plugin - 3.1.1 - maven-dependency-plugin 3.8.0 @@ -231,21 +213,6 @@ - - org.apache.maven.plugins - maven-release-plugin - - true - false - release - deploy - v${project.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - org.apache.felix maven-bundle-plugin @@ -261,18 +228,6 @@ org.apache.maven.plugins maven-surefire-plugin - - maven-javadoc-plugin - - UTF-8 - UTF-8 - true - all - public - io.prometheus.metrics.expositionformats.generated.* - 8 - - maven-compiler-plugin @@ -347,10 +302,42 @@ + + default + + true + + + examples + benchmarks + integration-tests + + release + + maven-javadoc-plugin + + UTF-8 + UTF-8 + true + all + public + io.prometheus.metrics.expositionformats.generated.* + + 8 + + + + attach-javadocs + + jar + + + + org.apache.maven.plugins maven-gpg-plugin @@ -361,6 +348,12 @@ sign + + + --pinentry-mode + loopback + + @@ -377,19 +370,28 @@ - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - + org.sonatype.central + central-publishing-maven-plugin + 0.5.0 + true + + ossrh + false + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index ccd57519e..b175c9cb1 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index a6c8e008f..2a77f617e 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 1f1079992..4da7c366e 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index e4ef51b74..c4269458c 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 1dd7b36fe..35a0c24e3 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 4bb66dc1d..3e293ad39 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index aa02be7c6..889089997 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index c8852f597..7cc114f8f 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index b173a3b07..2877f0518 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 4f2f35422..3abc67b96 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index 026c1fec7..d8fe77578 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-instrumentation-caffeine diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 714da9a9e..bcedc6446 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index c3450c48b..19b07a944 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-instrumentation-guava diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index fb3458df4..767c0fe61 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 3c6af3fe3..7d8c0c960 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-model diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index be74a4dec..c5fd6089b 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 68e169524..84938cff4 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index 40c3d566f..f16f47f4b 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index c32ab9aed..51066bd41 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 3ab18baf1..85c0a8d8e 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 68dd6c81a..83788e746 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.4.0-SNAPSHOT + 0.0.1-releasetest1 prometheus-metrics-tracer-otel From e69c5b514a2973fe3cf21a23093f3b991c00a367 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 16 Oct 2024 17:33:36 +0200 Subject: [PATCH 432/980] release automation (#1155) * release automation Signed-off-by: Gregor Zeitlinger * release automation Signed-off-by: Gregor Zeitlinger * release automation Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/workflows/build.yml | 2 +- .github/workflows/github-pages.yaml | 4 +--- .github/workflows/release.yml | 4 ++++ pom.xml | 13 ++++++++++++- .../io/prometheus/metrics/core/metrics/Buffer.java | 3 ++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 108ad6529..10a46622a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,4 +28,4 @@ jobs: REQUIRE_PROTO_UP_TO_DATE: true run: | ./mvnw clean install - ./mvnw javadoc:javadoc -P release # just to check if javadoc is generated + ./mvnw javadoc:javadoc -P javadoc # just to check if javadoc is generated diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 56380ec7f..4e91f37f9 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -44,10 +44,8 @@ jobs: run: | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - name: Build client_java - run: ./mvnw -B clean install -DskipTests -P release - name: Make Javadoc - run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate -P release + run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate -P javadoc - name: Move the Javadoc to docs/static/api/ run: mv ./target/reports/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api - name: Setup Pages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dde83081a..a890367c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,10 @@ jobs: runs-on: ubuntu-latest steps: + - name: Debug gpg key - remove after debugging + run: | + echo "$GPG_SIGNING_KEY" | wc -c + echo "$GPG_SIGNING_KEY" | gpg --batch --import-options import-show --import - name: Checkout Plugin Repository uses: actions/checkout@v4 diff --git a/pom.xml b/pom.xml index 5735d8581..4b62d968f 100644 --- a/pom.xml +++ b/pom.xml @@ -314,7 +314,7 @@ - release + javadoc @@ -329,6 +329,17 @@ 8 + + + + + + release + + + + org.apache.maven.plugins + maven-javadoc-plugin attach-javadocs diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java index 35c1fbe08..d4ff33a37 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Buffer.java @@ -72,7 +72,8 @@ T run( Long expectedCount = observationCount.getAndAdd(bufferActiveBit); while (!complete.apply(expectedCount)) { - // Wait until all in-flight threads have added their observations to the histogram + // Wait until all in-flight threads have added their observations to the histogram / + // summary. // we can't use a condition here, because the other thread doesn't have a lock as it's on // the fast path. Thread.yield(); From 6f4793cbfcdf08d9ceefd0888f61aa94aaefb51a Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 16 Oct 2024 17:46:39 +0200 Subject: [PATCH 433/980] release automation (#1156) Signed-off-by: Gregor Zeitlinger --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a890367c8..f637bc517 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,8 @@ jobs: steps: - name: Debug gpg key - remove after debugging + env: + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} run: | echo "$GPG_SIGNING_KEY" | wc -c echo "$GPG_SIGNING_KEY" | gpg --batch --import-options import-show --import From 38188b92676ba25258cb67e27eac3ca5576ace77 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 17 Oct 2024 12:26:55 +0200 Subject: [PATCH 434/980] use otel autoconfigure (#1147) * use otel autoconfig Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * add oats test Signed-off-by: Gregor Zeitlinger * extra project for otel resource attributes Signed-off-by: Gregor Zeitlinger * extra project for otel resource attributes Signed-off-by: Gregor Zeitlinger * extra project for otel resource attributes Signed-off-by: Gregor Zeitlinger * add otel tests Signed-off-by: Gregor Zeitlinger * release automation Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .github/workflows/acceptance-tests.yml | 41 +++ CONTRIBUTING.md | 2 + benchmarks/pom.xml | 15 +- .../oats-tests/agent/Dockerfile | 9 + .../oats-tests/agent/docker-compose.yml | 13 + .../oats-tests/agent/oats.yaml | 12 + .../agent/service-instance-id-check.py | 33 ++ .../oats-tests/http/Dockerfile | 5 + .../oats-tests/http/docker-compose.yml | 13 + .../oats-tests/http/oats.yaml | 10 + .../metrics/examples/opentelemetry/Main.java | 2 + otel-agent-resources/pom.xml | 67 ++++ .../ResourceAttributesFromOtelAgent.java | 16 +- .../src/main/resources/lib/.gitignore | 0 pom.xml | 11 +- .../ExporterOpenTelemetryProperties.java | 72 ++-- .../io/prometheus/metrics/config/Util.java | 12 +- .../pom.xml | 73 ++-- .../opentelemetry/OpenTelemetryExporter.java | 337 +----------------- .../opentelemetry/OtelAutoConfig.java | 117 ++++++ .../PropertiesResourceProvider.java | 35 ++ .../opentelemetry/PropertyMapper.java | 112 ++++++ .../opentelemetry/ResourceAttributes.java | 36 -- .../ResourceAttributesDefaults.java | 14 - .../ResourceAttributesFromJarFileName.java | 60 ---- .../opentelemetry/OtelAutoConfigTest.java | 296 +++++++++++++++ prometheus-metrics-tracer/pom.xml | 18 +- scripts/run-acceptance-tests.sh | 10 + 28 files changed, 932 insertions(+), 509 deletions(-) create mode 100644 .github/workflows/acceptance-tests.yml create mode 100644 examples/example-exporter-opentelemetry/oats-tests/agent/Dockerfile create mode 100644 examples/example-exporter-opentelemetry/oats-tests/agent/docker-compose.yml create mode 100644 examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml create mode 100755 examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py create mode 100644 examples/example-exporter-opentelemetry/oats-tests/http/Dockerfile create mode 100644 examples/example-exporter-opentelemetry/oats-tests/http/docker-compose.yml create mode 100644 examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml create mode 100644 otel-agent-resources/pom.xml rename {prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry => otel-agent-resources/src/main/java/io/prometheus/otelagent}/ResourceAttributesFromOtelAgent.java (88%) rename {prometheus-metrics-exporter-opentelemetry => otel-agent-resources}/src/main/resources/lib/.gitignore (100%) create mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfig.java create mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertiesResourceProvider.java create mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertyMapper.java delete mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java delete mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java delete mode 100644 prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java create mode 100644 prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java create mode 100755 scripts/run-acceptance-tests.sh diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml new file mode 100644 index 000000000..590c12946 --- /dev/null +++ b/.github/workflows/acceptance-tests.yml @@ -0,0 +1,41 @@ +name: OpenTelemetry Acceptance Tests + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + acceptance-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check out oats + uses: actions/checkout@v4 + with: + repository: grafana/oats + ref: 7cd5ca42fff009fd67ea986d42c79134ac99ae48 + path: oats + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: 'maven' + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache-dependency-path: oats/go.sum + - name: Run the Maven verify phase + run: | + ./mvnw clean install -DskipTests + - name: Run acceptance tests + run: ./scripts/run-acceptance-tests.sh + - name: upload log file + uses: actions/upload-artifact@v4 + if: failure() + with: + name: docker-compose.log + path: oats/yaml/build/**/*.log diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9e3d5779..79cd4b6ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,6 +17,8 @@ This repository uses [Google Java Format](https://github.com/google/google-java- Run `./mvnw spotless:apply` to format the code (only changed files) before committing. +Use `-Dspotless.check.skip=true` to skip the formatting check during development. + ## Running Tests If you're getting errors when running tests: diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 4b7d53b79..99c4ecee8 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -22,6 +22,18 @@ 3.0.2 + + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-bom-alpha + ${otel.instrumentation.version} + pom + import + + + + org.openjdk.jmh @@ -58,17 +70,14 @@ io.opentelemetry opentelemetry-api - ${otel.version} io.opentelemetry opentelemetry-sdk - ${otel.version} io.opentelemetry opentelemetry-sdk-testing - ${otel.version} diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/Dockerfile b/examples/example-exporter-opentelemetry/oats-tests/agent/Dockerfile new file mode 100644 index 000000000..23f980005 --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/Dockerfile @@ -0,0 +1,9 @@ +FROM eclipse-temurin:21-jre + +COPY target/example-exporter-opentelemetry.jar ./app.jar +# check that the resource attributs from the agent are used, epsecially the service.instance.id should be the same +ADD --chmod=644 https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.8.0/opentelemetry-javaagent.jar /usr/src/app/opentelemetry-javaagent.jar +ENV JAVA_TOOL_OPTIONS=-javaagent:/usr/src/app/opentelemetry-javaagent.jar + +#ENTRYPOINT [ "java", "-Dotel.javaagent.debug=true","-jar", "./app.jar" ] # for debugging +ENTRYPOINT [ "java", "-jar", "./app.jar" ] diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/docker-compose.yml b/examples/example-exporter-opentelemetry/oats-tests/agent/docker-compose.yml new file mode 100644 index 000000000..9c0fc66fb --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/docker-compose.yml @@ -0,0 +1,13 @@ +# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml +version: '3.4' + +services: + java: + build: + context: ../.. + dockerfile: oats-tests/agent/Dockerfile + environment: + OTEL_SERVICE_NAME: "rolldice" + OTEL_EXPORTER_OTLP_ENDPOINT: http://lgtm:4317 + OTEL_EXPORTER_OTLP_PROTOCOL: grpc + OTEL_METRIC_EXPORT_INTERVAL: "5000" # so we don't have to wait 60s for metrics diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml b/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml new file mode 100644 index 000000000..08e4d8d3f --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml @@ -0,0 +1,12 @@ +# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml +docker-compose: + generator: docker-lgtm + files: + - ./docker-compose.yml +expected: + custom-checks: + - script: ./service-instance-id-check.py + metrics: + - promql: 'uptime_seconds_total{}' + value: '>= 0' + diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py b/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py new file mode 100755 index 000000000..196c629c9 --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +# This script is used to check if the service instance id is present in the exported data +# The script will return 0 if the service instance id is present in the exported data + +from urllib.request import urlopen +import urllib.parse +import json + +url = ' http://localhost:9090/api/v1/label/instance/values' +res = json.loads(urlopen(url).read().decode('utf-8')) + +values = list(res['data']) +print(values) + +if "localhost:8888" in values: + values.remove("localhost:8888") + +# both the agent and the exporter should report the same instance id +assert len(values) == 1 + +path = 'target_info{instance="%s"}' % values[0] +path = urllib.parse.quote_plus(path) +url = 'http://localhost:9090/api/v1/query?query=%s' % path +res = json.loads(urlopen(url).read().decode('utf-8')) + +infos = res['data']['result'] +print(infos) + +# they should not have the same target info +# e.g. only the agent has telemetry_distro_name +assert len(infos) == 2 + diff --git a/examples/example-exporter-opentelemetry/oats-tests/http/Dockerfile b/examples/example-exporter-opentelemetry/oats-tests/http/Dockerfile new file mode 100644 index 000000000..22191f07e --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/http/Dockerfile @@ -0,0 +1,5 @@ +FROM eclipse-temurin:21-jre + +COPY target/example-exporter-opentelemetry.jar ./app.jar + +ENTRYPOINT [ "java", "-jar", "./app.jar" ] diff --git a/examples/example-exporter-opentelemetry/oats-tests/http/docker-compose.yml b/examples/example-exporter-opentelemetry/oats-tests/http/docker-compose.yml new file mode 100644 index 000000000..cec15bf19 --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/http/docker-compose.yml @@ -0,0 +1,13 @@ +# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml +version: '3.4' + +services: + java: + build: + context: ../.. + dockerfile: oats-tests/http/Dockerfile + environment: + OTEL_SERVICE_NAME: "rolldice" + OTEL_EXPORTER_OTLP_ENDPOINT: http://lgtm:4318 + OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf + OTEL_METRIC_EXPORT_INTERVAL: "5000" # so we don't have to wait 60s for metrics diff --git a/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml b/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml new file mode 100644 index 000000000..a3af9ffc2 --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml @@ -0,0 +1,10 @@ +# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml +docker-compose: + generator: docker-lgtm + files: + - ./docker-compose.yml +expected: + metrics: + - promql: 'uptime_seconds_total{}' + value: '>= 0' + diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java index defe85074..b1aa440b1 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java @@ -9,6 +9,7 @@ public class Main { public static void main(String[] args) throws Exception { + System.out.println("Starting example application"); // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions. // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry @@ -34,6 +35,7 @@ public static void main(String[] args) throws Exception { while (true) { Thread.sleep(1000); + System.out.println("Incrementing counter"); counter.inc(); } } diff --git a/otel-agent-resources/pom.xml b/otel-agent-resources/pom.xml new file mode 100644 index 000000000..176c2c6eb --- /dev/null +++ b/otel-agent-resources/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + + io.prometheus + client_java + 0.0.1-releasetest1 + + + otel-agent-resources + bundle + + OpenTelemetry Agent Resource Extractor + + Reads the OpenTelemetry Agent resources the GlobalOpenTelemetry instance + + + + io.prometheus.otel.resource.attributes + + 1.29.0 + + + + + + + + + src/main/resources + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + validate + + copy + + + + + + + io.opentelemetry + opentelemetry-api + ${otel-dynamic-load.version} + ${project.basedir}/src/main/resources/lib/ + + + io.opentelemetry + opentelemetry-context + ${otel-dynamic-load.version} + ${project.basedir}/src/main/resources/lib/ + + + + + + + diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java b/otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java similarity index 88% rename from prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java rename to otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java index ce6baafe2..215b79de5 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromOtelAgent.java +++ b/otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.exporter.opentelemetry; +package io.prometheus.otelagent; import static java.nio.file.Files.createTempDirectory; @@ -11,6 +11,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.Collections; +import java.util.HashMap; import java.util.Map; public class ResourceAttributesFromOtelAgent { @@ -31,8 +33,11 @@ public class ResourceAttributesFromOtelAgent { * *

      After that we discard the class loader so that all OTel specific classes are unloaded. No * runtime dependency on any OTel version remains. + * + *

      The test for this class is in + * examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py */ - public static void addIfAbsent(Map result, String instrumentationScopeName) { + public static Map getResourceAttributes(String instrumentationScopeName) { try { Path tmpDir = createTempDirectory(instrumentationScopeName + "-"); try { @@ -43,7 +48,7 @@ public static void addIfAbsent(Map result, String instrumentatio classLoader.loadClass("io.opentelemetry.api.GlobalOpenTelemetry"); Object globalOpenTelemetry = globalOpenTelemetryClass.getMethod("get").invoke(null); if (globalOpenTelemetry.getClass().getSimpleName().contains("ApplicationOpenTelemetry")) { - // GlobalOpenTelemetry is injected by the OTel Java aqent + // GlobalOpenTelemetry is injected by the OTel Java agent Object applicationMeterProvider = callMethod("getMeterProvider", globalOpenTelemetry); Object agentMeterProvider = getField("agentMeterProvider", applicationMeterProvider); Object sdkMeterProvider = getField("delegate", agentMeterProvider); @@ -52,11 +57,13 @@ public static void addIfAbsent(Map result, String instrumentatio Object attributes = callMethod("getAttributes", resource); Map attributeMap = (Map) callMethod("asMap", attributes); + Map result = new HashMap<>(); for (Map.Entry entry : attributeMap.entrySet()) { if (entry.getKey() != null && entry.getValue() != null) { - result.putIfAbsent(entry.getKey().toString(), entry.getValue().toString()); + result.put(entry.getKey().toString(), entry.getValue().toString()); } } + return Collections.unmodifiableMap(result); } } } finally { @@ -65,6 +72,7 @@ public static void addIfAbsent(Map result, String instrumentatio } catch (Exception ignored) { // ignore } + return Collections.emptyMap(); } private static Object getField(String name, Object obj) throws Exception { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/resources/lib/.gitignore b/otel-agent-resources/src/main/resources/lib/.gitignore similarity index 100% rename from prometheus-metrics-exporter-opentelemetry/src/main/resources/lib/.gitignore rename to otel-agent-resources/src/main/resources/lib/.gitignore diff --git a/pom.xml b/pom.xml index 4b62d968f..273f97881 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- 5.11.2 - 1.42.1 + 2.8.0-alpha 8 @@ -73,6 +73,7 @@ prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-instrumentation-guava prometheus-metrics-simpleclient-bridge + otel-agent-resources @@ -100,6 +101,12 @@ 3.26.3 test + + org.slf4j + slf4j-simple + 1.7.36 + test + @@ -236,7 +243,7 @@ ${java.version} true - -Xlint:all + -Xlint:all,-serial,-processing -Werror -XDcompilePolicy=simple diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java index b8498d6c5..d009d2603 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java @@ -8,22 +8,23 @@ public class ExporterOpenTelemetryProperties { // See // https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md - private static String PROTOCOL = "protocol"; // otel.exporter.otlp.protocol - private static String ENDPOINT = "endpoint"; // otel.exporter.otlp.endpoint - private static String HEADERS = "headers"; // otel.exporter.otlp.headers - private static String INTERVAL_SECONDS = "intervalSeconds"; // otel.metric.export.interval - private static String TIMEOUT_SECONDS = "timeoutSeconds"; // otel.exporter.otlp.timeout - private static String SERVICE_NAME = "serviceName"; // otel.service.name - private static String SERVICE_NAMESPACE = "serviceNamespace"; - private static String SERVICE_INSTANCE_ID = "serviceInstanceId"; - private static String SERVICE_VERSION = "serviceVersion"; - private static String RESOURCE_ATTRIBUTES = "resourceAttributes"; // otel.resource.attributes + private static final String PROTOCOL = "protocol"; // otel.exporter.otlp.protocol + private static final String ENDPOINT = "endpoint"; // otel.exporter.otlp.endpoint + private static final String HEADERS = "headers"; // otel.exporter.otlp.headers + private static final String INTERVAL_SECONDS = "intervalSeconds"; // otel.metric.export.interval + private static final String TIMEOUT_SECONDS = "timeoutSeconds"; // otel.exporter.otlp.timeout + private static final String SERVICE_NAME = "serviceName"; // otel.service.name + private static final String SERVICE_NAMESPACE = "serviceNamespace"; + private static final String SERVICE_INSTANCE_ID = "serviceInstanceId"; + private static final String SERVICE_VERSION = "serviceVersion"; + private static final String RESOURCE_ATTRIBUTES = + "resourceAttributes"; // otel.resource.attributes private final String protocol; private final String endpoint; private final Map headers; - private final Integer intervalSeconds; - private final Integer timeoutSeconds; + private final String interval; + private final String timeout; private final String serviceName; private final String serviceNamespace; private final String serviceInstanceId; @@ -34,8 +35,8 @@ private ExporterOpenTelemetryProperties( String protocol, String endpoint, Map headers, - Integer intervalSeconds, - Integer timeoutSeconds, + String interval, + String timeout, String serviceName, String serviceNamespace, String serviceInstanceId, @@ -44,8 +45,8 @@ private ExporterOpenTelemetryProperties( this.protocol = protocol; this.endpoint = endpoint; this.headers = headers; - this.intervalSeconds = intervalSeconds; - this.timeoutSeconds = timeoutSeconds; + this.interval = interval; + this.timeout = timeout; this.serviceName = serviceName; this.serviceNamespace = serviceNamespace; this.serviceInstanceId = serviceInstanceId; @@ -65,12 +66,12 @@ public Map getHeaders() { return headers; } - public Integer getIntervalSeconds() { - return intervalSeconds; + public String getInterval() { + return interval; } - public Integer getTimeoutSeconds() { - return timeoutSeconds; + public String getTimeout() { + return timeout; } public String getServiceName() { @@ -102,27 +103,20 @@ static ExporterOpenTelemetryProperties load(String prefix, Map p String protocol = Util.loadString(prefix + "." + PROTOCOL, properties); String endpoint = Util.loadString(prefix + "." + ENDPOINT, properties); Map headers = Util.loadMap(prefix + "." + HEADERS, properties); - Integer intervalSeconds = Util.loadInteger(prefix + "." + INTERVAL_SECONDS, properties); - Integer timeoutSeconds = Util.loadInteger(prefix + "." + TIMEOUT_SECONDS, properties); + String interval = Util.loadStringAddSuffix(prefix + "." + INTERVAL_SECONDS, properties, "s"); + String timeout = Util.loadStringAddSuffix(prefix + "." + TIMEOUT_SECONDS, properties, "s"); String serviceName = Util.loadString(prefix + "." + SERVICE_NAME, properties); String serviceNamespace = Util.loadString(prefix + "." + SERVICE_NAMESPACE, properties); String serviceInstanceId = Util.loadString(prefix + "." + SERVICE_INSTANCE_ID, properties); String serviceVersion = Util.loadString(prefix + "." + SERVICE_VERSION, properties); Map resourceAttributes = Util.loadMap(prefix + "." + RESOURCE_ATTRIBUTES, properties); - Util.assertValue(intervalSeconds, t -> t > 0, "Expecting value > 0", prefix, INTERVAL_SECONDS); - Util.assertValue(timeoutSeconds, t -> t > 0, "Expecting value > 0", prefix, TIMEOUT_SECONDS); - if (protocol != null && !protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new PrometheusPropertiesException( - protocol - + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf"); - } return new ExporterOpenTelemetryProperties( protocol, endpoint, headers, - intervalSeconds, - timeoutSeconds, + interval, + timeout, serviceName, serviceNamespace, serviceInstanceId, @@ -138,14 +132,14 @@ public static class Builder { private String protocol; private String endpoint; - private Map headers = new HashMap<>(); - private Integer intervalSeconds; - private Integer timeoutSeconds; + private final Map headers = new HashMap<>(); + private String interval; + private String timeout; private String serviceName; private String serviceNamespace; private String serviceInstanceId; private String serviceVersion; - private Map resourceAttributes = new HashMap<>(); + private final Map resourceAttributes = new HashMap<>(); private Builder() {} @@ -173,7 +167,7 @@ public Builder intervalSeconds(int intervalSeconds) { if (intervalSeconds <= 0) { throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); } - this.intervalSeconds = intervalSeconds; + this.interval = intervalSeconds + "s"; return this; } @@ -181,7 +175,7 @@ public Builder timeoutSeconds(int timeoutSeconds) { if (timeoutSeconds <= 0) { throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); } - this.timeoutSeconds = timeoutSeconds; + this.timeout = timeoutSeconds + "s"; return this; } @@ -215,8 +209,8 @@ public ExporterOpenTelemetryProperties build() { protocol, endpoint, headers, - intervalSeconds, - timeoutSeconds, + interval, + timeout, serviceName, serviceNamespace, serviceInstanceId, diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java index 8adcd0af7..15a61f7fe 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java @@ -9,7 +9,7 @@ class Util { - private static String getProperty(String name, Map properties) { + static String getProperty(String name, Map properties) { Object object = properties.remove(name); if (object != null) { return object.toString(); @@ -46,6 +46,14 @@ static String loadString(String name, Map properties) return getProperty(name, properties); } + static String loadStringAddSuffix(String name, Map properties, String suffix) { + Object object = properties.remove(name); + if (object != null) { + return object + suffix; + } + return null; + } + static List loadStringList(String name, Map properties) throws PrometheusPropertiesException { String property = getProperty(name, properties); @@ -87,7 +95,7 @@ static Map loadMap(String name, Map properties) String[] pairs = property.split(","); for (String pair : pairs) { if (pair.contains("=")) { - String[] keyValue = pair.split("=", 1); + String[] keyValue = pair.split("=", 2); if (keyValue.length == 2) { String key = keyValue[0].trim(); String value = keyValue[1].trim(); diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 3e293ad39..d9ecaaa1c 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -21,26 +21,52 @@ io.prometheus.metrics.exporter.opentelemetry + + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-bom-alpha + ${otel.instrumentation.version} + pom + import + + + + io.prometheus prometheus-metrics-core ${project.version} + + io.prometheus + otel-agent-resources + ${project.version} + io.opentelemetry opentelemetry-api - ${otel.version} io.opentelemetry opentelemetry-sdk - ${otel.version} io.opentelemetry opentelemetry-exporter-otlp - ${otel.version} + + + io.opentelemetry + opentelemetry-sdk-extension-autoconfigure + + + io.opentelemetry + opentelemetry-sdk-extension-incubator + + + io.opentelemetry.instrumentation + opentelemetry-resources @@ -68,19 +94,10 @@ 1.7.1-alpha test - - io.opentelemetry - opentelemetry-sdk-trace - ${otel.version} - test - - - src/main/resources - src/main/resources-filtered true @@ -98,9 +115,9 @@ regex-property - otel.string-version - ${otel.version} - \. + otel.instrumentation.string-version + ${otel.instrumentation.version} + [\.-] _ true @@ -120,6 +137,8 @@ io.opentelemetry:* + io.opentelemetry.semconv:* + io.opentelemetry.instrumentation:* com.squareup.*:* org.jetbrains:* org.jetbrains.*:* @@ -129,37 +148,49 @@ io.opentelemetry - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version} + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version} + + + + io.opentelemetry.instrumentation + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.instrumentation + + + + io.opentelemetry.semconv + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.semconv okhttp3 - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version}.okhttp3 + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okhttp3 kotlin - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version}.kotlin + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.kotlin org.intellij - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version}.org.intellij + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.intellij org.jetbrains - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version}.org.jetbrains + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.jetbrains okio - io.prometheus.metrics.shaded.io_opentelemetry_${otel.string-version}.okio + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okio diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java index 82f503ac9..a00b2ef85 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.java @@ -1,62 +1,16 @@ package io.prometheus.metrics.exporter.opentelemetry; -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.metrics.export.MetricExporter; -import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.resources.ResourceBuilder; -import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; +import io.opentelemetry.sdk.metrics.export.MetricReader; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import java.time.Duration; import java.util.HashMap; -import java.util.Locale; import java.util.Map; -import java.util.concurrent.TimeUnit; public class OpenTelemetryExporter implements AutoCloseable { - private final PeriodicMetricReader reader; + private final MetricReader reader; - private OpenTelemetryExporter( - Builder builder, PrometheusProperties config, PrometheusRegistry registry) { - InstrumentationScopeInfo instrumentationScopeInfo = - PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); - ExporterOpenTelemetryProperties properties = config.getExporterOpenTelemetryProperties(); - Resource resource = initResourceAttributes(builder, properties, instrumentationScopeInfo); - MetricExporter exporter; - if (ConfigHelper.getProtocol(builder, properties).equals("grpc")) { - OtlpGrpcMetricExporterBuilder exporterBuilder = - OtlpGrpcMetricExporter.builder() - .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) - .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); - for (Map.Entry header : - ConfigHelper.getHeaders(builder, properties).entrySet()) { - exporterBuilder.addHeader(header.getKey(), header.getValue()); - } - exporter = exporterBuilder.build(); - } else { - OtlpHttpMetricExporterBuilder exporterBuilder = - OtlpHttpMetricExporter.builder() - .setTimeout(Duration.ofSeconds(ConfigHelper.getTimeoutSeconds(builder, properties))) - .setEndpoint(ConfigHelper.getEndpoint(builder, properties)); - for (Map.Entry header : - ConfigHelper.getHeaders(builder, properties).entrySet()) { - exporterBuilder.addHeader(header.getKey(), header.getValue()); - } - exporter = exporterBuilder.build(); - } - reader = - PeriodicMetricReader.builder(exporter) - .setInterval(Duration.ofSeconds(ConfigHelper.getIntervalSeconds(builder, properties))) - .build(); - - PrometheusMetricProducer prometheusMetricProducer = - new PrometheusMetricProducer(registry, instrumentationScopeInfo, resource); - reader.register(prometheusMetricProducer); + public OpenTelemetryExporter(MetricReader reader) { + this.reader = reader; } @Override @@ -64,29 +18,6 @@ public void close() { reader.shutdown(); } - private Resource initResourceAttributes( - Builder builder, - ExporterOpenTelemetryProperties properties, - InstrumentationScopeInfo instrumentationScopeInfo) { - String serviceName = ConfigHelper.getServiceName(builder, properties); - String serviceNamespace = ConfigHelper.getServiceNamespace(builder, properties); - String serviceInstanceId = ConfigHelper.getServiceInstanceId(builder, properties); - String serviceVersion = ConfigHelper.getServiceVersion(builder, properties); - Map resourceAttributes = - ResourceAttributes.get( - instrumentationScopeInfo.getName(), - serviceName, - serviceNamespace, - serviceInstanceId, - serviceVersion, - ConfigHelper.getResourceAttributes(builder, properties)); - ResourceBuilder resourceBuilder = Resource.builder(); - for (Map.Entry entry : resourceAttributes.entrySet()) { - resourceBuilder.put(entry.getKey(), entry.getValue()); - } - return resourceBuilder.build(); - } - public static Builder builder() { return new Builder(PrometheusProperties.get()); } @@ -99,16 +30,16 @@ public static class Builder { private final PrometheusProperties config; private PrometheusRegistry registry = null; - private String protocol; - private String endpoint; - private final Map headers = new HashMap<>(); - private Integer intervalSeconds; - private Integer timeoutSeconds; - private String serviceName; - private String serviceNamespace; - private String serviceInstanceId; - private String serviceVersion; - private final Map resourceAttributes = new HashMap<>(); + String protocol; + String endpoint; + final Map headers = new HashMap<>(); + String interval; + String timeout; + String serviceName; + String serviceNamespace; + String serviceInstanceId; + String serviceVersion; + final Map resourceAttributes = new HashMap<>(); private Builder(PrometheusProperties config) { this.config = config; @@ -181,7 +112,7 @@ public Builder intervalSeconds(int intervalSeconds) { if (intervalSeconds <= 0) { throw new IllegalStateException(intervalSeconds + ": expecting a push interval > 0s"); } - this.intervalSeconds = intervalSeconds; + this.interval = intervalSeconds + "s"; return this; } @@ -196,7 +127,7 @@ public Builder timeoutSeconds(int timeoutSeconds) { if (timeoutSeconds <= 0) { throw new IllegalStateException(timeoutSeconds + ": expecting a push interval > 0s"); } - this.timeoutSeconds = timeoutSeconds; + this.timeout = timeoutSeconds + "s"; return this; } @@ -266,241 +197,7 @@ public OpenTelemetryExporter buildAndStart() { if (registry == null) { registry = PrometheusRegistry.defaultRegistry; } - return new OpenTelemetryExporter(this, config, registry); - } - } - - private static class ConfigHelper { - - private static String getProtocol( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String protocol = config.getProtocol(); - if (protocol != null) { - return protocol; - } - protocol = getString("otel.exporter.otlp.protocol"); - if (protocol != null) { - if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { - throw new IllegalStateException( - protocol - + ": Unsupported OpenTelemetry exporter protocol. Expecting grpc or http/protobuf."); - } - return protocol; - } - if (builder.protocol != null) { - return builder.protocol; - } - return "grpc"; - } - - private static String getEndpoint( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String endpoint = config.getEndpoint(); - if (endpoint == null) { - endpoint = getString("otel.exporter.otlp.metrics.endpoint"); - } - if (endpoint == null) { - endpoint = getString("otel.exporter.otlp.endpoint"); - } - if (endpoint == null) { - endpoint = builder.endpoint; - } - if (endpoint == null) { - if (getProtocol(builder, config).equals("grpc")) { - endpoint = "http://localhost:4317"; - } else { // http/protobuf - endpoint = "http://localhost:4318/v1/metrics"; - } - } - if (getProtocol(builder, config).equals("grpc")) { - return endpoint; - } else { // http/protobuf - if (!endpoint.endsWith("v1/metrics")) { - if (!endpoint.endsWith("/")) { - return endpoint + "/v1/metrics"; - } else { - return endpoint + "v1/metrics"; - } - } else { - return endpoint; - } - } - } - - private static Map getHeaders( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Map headers = config.getHeaders(); - if (!headers.isEmpty()) { - return headers; - } - headers = getMap("otel.exporter.otlp.headers"); - if (!headers.isEmpty()) { - return headers; - } - if (!builder.headers.isEmpty()) { - return builder.headers; - } - return new HashMap<>(); - } - - private static int getIntervalSeconds( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Integer intervalSeconds = config.getIntervalSeconds(); - if (intervalSeconds != null) { - return intervalSeconds; - } - intervalSeconds = getPositiveInteger("otel.metric.export.interval"); - if (intervalSeconds != null) { - return (int) TimeUnit.MILLISECONDS.toSeconds(intervalSeconds); - } - if (builder.intervalSeconds != null) { - return builder.intervalSeconds; - } - return 60; - } - - private static int getTimeoutSeconds( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Integer timeoutSeconds = config.getTimeoutSeconds(); - if (timeoutSeconds != null) { - return timeoutSeconds; - } - Integer timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.metrics.timeout"); - if (timeoutMilliseconds == null) { - timeoutMilliseconds = getPositiveInteger("otel.exporter.otlp.timeout"); - } - if (timeoutMilliseconds != null) { - return (int) TimeUnit.MILLISECONDS.toSeconds(timeoutMilliseconds); - } - if (builder.timeoutSeconds != null) { - return builder.timeoutSeconds; - } - return 10; - } - - private static String getServiceName( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceName = config.getServiceName(); - if (serviceName != null) { - return serviceName; - } - serviceName = getString("otel.service.name"); - if (serviceName != null) { - return serviceName; - } - if (builder.serviceName != null) { - return builder.serviceName; - } - return null; - } - - private static String getServiceNamespace( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceNamespace = config.getServiceNamespace(); - if (serviceNamespace != null) { - return serviceNamespace; - } - if (builder.serviceNamespace != null) { - return builder.serviceNamespace; - } - return null; - } - - private static String getServiceInstanceId( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceInstanceId = config.getServiceInstanceId(); - if (serviceInstanceId != null) { - return serviceInstanceId; - } - if (builder.serviceInstanceId != null) { - return builder.serviceInstanceId; - } - return null; - } - - private static String getServiceVersion( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - String serviceVersion = config.getServiceVersion(); - if (serviceVersion != null) { - return serviceVersion; - } - if (builder.serviceVersion != null) { - return builder.serviceVersion; - } - return null; - } - - private static Map getResourceAttributes( - OpenTelemetryExporter.Builder builder, ExporterOpenTelemetryProperties config) { - Map resourceAttributes = config.getResourceAttributes(); - if (!resourceAttributes.isEmpty()) { - return resourceAttributes; - } - resourceAttributes = getMap("otel.resource.attributes"); - if (!resourceAttributes.isEmpty()) { - return resourceAttributes; - } - if (!builder.resourceAttributes.isEmpty()) { - return builder.resourceAttributes; - } - return new HashMap<>(); - } - - private static String getString(String otelPropertyName) { - String otelEnvVarName = - otelPropertyName.replace(".", "_").replace("-", "_").toUpperCase(Locale.ROOT); - if (System.getenv(otelEnvVarName) != null) { - return System.getenv(otelEnvVarName); - } - if (System.getProperty(otelPropertyName) != null) { - return System.getProperty(otelPropertyName); - } - return null; - } - - private static Integer getInteger(String otelPropertyName) { - String result = getString(otelPropertyName); - if (result == null) { - return null; - } else { - try { - return Integer.parseInt(result); - } catch (NumberFormatException e) { - throw new IllegalStateException(otelPropertyName + "=" + result + " - illegal value."); - } - } - } - - private static Integer getPositiveInteger(String otelPropertyName) { - Integer result = getInteger(otelPropertyName); - if (result == null) { - return null; - } - if (result <= 0) { - throw new IllegalStateException(otelPropertyName + "=" + result + ": Expecting value > 0."); - } - return result; - } - - private static Map getMap(String otelPropertyName) { - Map result = new HashMap<>(); - String property = getString(otelPropertyName); - if (property != null) { - String[] pairs = property.split(","); - for (String pair : pairs) { - if (pair.contains("=")) { - String[] keyValue = pair.split("=", 1); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - if (key.length() > 0 && value.length() > 0) { - result.putIfAbsent(key, value); - } - } - } - } - } - return result; + return new OpenTelemetryExporter(OtelAutoConfig.createReader(this, config, registry)); } } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfig.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfig.java new file mode 100644 index 000000000..fb6ebff7e --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfig.java @@ -0,0 +1,117 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.resources.Resource; +import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.otelagent.ResourceAttributesFromOtelAgent; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +public class OtelAutoConfig { + + private static final String SERVICE_INSTANCE_ID = "service.instance.id"; + + static MetricReader createReader( + OpenTelemetryExporter.Builder builder, + PrometheusProperties config, + PrometheusRegistry registry) { + AtomicReference readerRef = new AtomicReference<>(); + InstrumentationScopeInfo instrumentationScopeInfo = + PrometheusInstrumentationScope.loadInstrumentationScopeInfo(); + + AutoConfiguredOpenTelemetrySdk sdk = + createAutoConfiguredOpenTelemetrySdk( + builder, + readerRef, + config.getExporterOpenTelemetryProperties(), + instrumentationScopeInfo); + + MetricReader reader = readerRef.get(); + reader.register( + new PrometheusMetricProducer(registry, instrumentationScopeInfo, getResourceField(sdk))); + return reader; + } + + static AutoConfiguredOpenTelemetrySdk createAutoConfiguredOpenTelemetrySdk( + OpenTelemetryExporter.Builder builder, + AtomicReference readerRef, + ExporterOpenTelemetryProperties properties, + InstrumentationScopeInfo instrumentationScopeInfo) { + PropertyMapper propertyMapper = PropertyMapper.create(properties, builder); + + return AutoConfiguredOpenTelemetrySdk.builder() + .addPropertiesSupplier(() -> propertyMapper.configLowPriority) + .addPropertiesCustomizer( + c -> PropertyMapper.customizeProperties(propertyMapper.configHighPriority, c)) + .addMetricReaderCustomizer( + (reader, unused) -> { + readerRef.set(reader); + return reader; + }) + .addResourceCustomizer( + (resource, c) -> + getResource(builder, resource, instrumentationScopeInfo, c, properties)) + .build(); + } + + private static Resource getResource( + OpenTelemetryExporter.Builder builder, + Resource resource, + InstrumentationScopeInfo instrumentationScopeInfo, + ConfigProperties configProperties, + ExporterOpenTelemetryProperties properties) { + return resource + .merge( + PropertiesResourceProvider.mergeResource( + builder.resourceAttributes, + builder.serviceName, + builder.serviceNamespace, + builder.serviceInstanceId, + builder.serviceVersion)) + .merge(ResourceConfiguration.createEnvironmentResource(configProperties)) + .merge( + PropertiesResourceProvider.mergeResource( + properties.getResourceAttributes(), + properties.getServiceName(), + properties.getServiceNamespace(), + properties.getServiceInstanceId(), + properties.getServiceVersion())) + .merge(Resource.create(otelResourceAttributes(instrumentationScopeInfo))); + } + + /** + * Only copy the service instance id from the Otel agent resource attributes. + * + *

      All other attributes are calculated from the configuration using OTel SDK AutoConfig. + */ + private static Attributes otelResourceAttributes( + InstrumentationScopeInfo instrumentationScopeInfo) { + AttributesBuilder builder = Attributes.builder(); + Map attributes = + ResourceAttributesFromOtelAgent.getResourceAttributes(instrumentationScopeInfo.getName()); + String id = attributes.get(SERVICE_INSTANCE_ID); + if (id != null) { + builder.put(SERVICE_INSTANCE_ID, id); + } + return builder.build(); + } + + static Resource getResourceField(AutoConfiguredOpenTelemetrySdk sdk) { + try { + Method method = AutoConfiguredOpenTelemetrySdk.class.getDeclaredMethod("getResource"); + method.setAccessible(true); + return (Resource) method.invoke(sdk); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertiesResourceProvider.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertiesResourceProvider.java new file mode 100644 index 000000000..1bb6b19bf --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertiesResourceProvider.java @@ -0,0 +1,35 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.sdk.resources.Resource; +import java.util.HashMap; +import java.util.Map; + +final class PropertiesResourceProvider { + + static Resource mergeResource( + Map resourceAttributes, + String serviceName, + String serviceNamespace, + String serviceInstanceId, + String serviceVersion) { + Map resource = new HashMap<>(resourceAttributes); + if (serviceName != null) { + resource.put("service.name", serviceName); + } + if (serviceNamespace != null) { + resource.put("service.namespace", serviceNamespace); + } + if (serviceInstanceId != null) { + resource.put("service.instance.id", serviceInstanceId); + } + if (serviceVersion != null) { + resource.put("service.version", serviceVersion); + } + + AttributesBuilder builder = Attributes.builder(); + resource.forEach(builder::put); + return Resource.create(builder.build()); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertyMapper.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertyMapper.java new file mode 100644 index 000000000..be30197fa --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PropertyMapper.java @@ -0,0 +1,112 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; +import io.prometheus.metrics.config.PrometheusPropertiesException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +class PropertyMapper { + + private static final String METRICS_ENDPOINT = "otel.exporter.otlp.metrics.endpoint"; + Map configLowPriority = new HashMap<>(); + Map configHighPriority = new HashMap<>(); + + static PropertyMapper create( + ExporterOpenTelemetryProperties properties, OpenTelemetryExporter.Builder builder) + throws PrometheusPropertiesException { + return new PropertyMapper() + .addString( + builder.protocol, properties.getProtocol(), "otel.exporter.otlp.metrics.protocol") + .addString(builder.endpoint, properties.getEndpoint(), METRICS_ENDPOINT) + .addString( + mapToOtelString(builder.headers), + mapToOtelString(properties.getHeaders()), + "otel.exporter.otlp.metrics.headers") + .addString(builder.interval, properties.getInterval(), "otel.metric.export.interval") + .addString(builder.timeout, properties.getTimeout(), "otel.exporter.otlp.metrics.timeout") + .addString(builder.serviceName, properties.getServiceName(), "otel.service.name"); + } + + PropertyMapper addString(String builderValue, String propertyValue, String otelKey) { + if (builderValue != null) { + // the low priority config should not be used for the metrics settings, so that both general + // and metrics settings + // can be used to override the values + configLowPriority.put(otelKey.replace("otlp.metrics", "otlp"), builderValue); + } + if (propertyValue != null) { + configHighPriority.put(otelKey, propertyValue); + } + return this; + } + + private static String mapToOtelString(Map map) { + if (map.isEmpty()) { + return null; + } + StringBuilder sb = new StringBuilder(); + for (Map.Entry entry : map.entrySet()) { + sb.append(entry.getKey()).append("=").append(entry.getValue()).append(","); + } + return sb.substring(0, sb.length() - 1); + } + + static Map customizeProperties(Map result, ConfigProperties c) { + Map map = fixEndpointPaths(result, c); + map.put("otel.logs.exporter", "none"); + map.put("otel.traces.exporter", "none"); + return map; + } + + static Map fixEndpointPaths(Map result, ConfigProperties c) { + transformEndpointPath( + result, + c, + METRICS_ENDPOINT, + endpoint -> { + if (!endpoint.endsWith("v1/metrics")) { + if (!endpoint.endsWith("/")) { + return endpoint + "/v1/metrics"; + } else { + return endpoint + "v1/metrics"; + } + } + return endpoint; + }); + + transformEndpointPath( + result, + c, + "otel.exporter.otlp.endpoint", + endpoint -> { + if (endpoint.endsWith("v1/metrics")) { + return endpoint.substring(0, endpoint.length() - "v1/metrics".length()); + } + return endpoint; + }); + + return result; + } + + static void transformEndpointPath( + Map result, + ConfigProperties c, + String key, + Function valueMapper) { + String endpoint = c.getString(key); + if (endpoint == null) { + return; + } + String protocol = c.getString("otel.exporter.otlp.metrics.protocol"); + if (protocol == null) { + protocol = c.getString("otel.exporter.otlp.protocol"); + } + + if (!"grpc".equals(protocol)) { // http/protobuf + endpoint = valueMapper.apply(endpoint); + result.put(key, endpoint); + } + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java deleted file mode 100644 index 2c88badfc..000000000 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributes.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.prometheus.metrics.exporter.opentelemetry; - -import java.util.HashMap; -import java.util.Map; - -public class ResourceAttributes { - - // TODO: The OTel Java instrumentation also has a SpringBootServiceNameDetector, we should port - // this over. - public static Map get( - String instrumentationScopeName, - String serviceName, - String serviceNamespace, - String serviceInstanceId, - String serviceVersion, - Map configuredResourceAttributes) { - Map result = new HashMap<>(); - ResourceAttributesFromOtelAgent.addIfAbsent(result, instrumentationScopeName); - putIfAbsent(result, "service.name", serviceName); - putIfAbsent(result, "service.namespace", serviceNamespace); - putIfAbsent(result, "service.instance.id", serviceInstanceId); - putIfAbsent(result, "service.version", serviceVersion); - for (Map.Entry attribute : configuredResourceAttributes.entrySet()) { - putIfAbsent(result, attribute.getKey(), attribute.getValue()); - } - ResourceAttributesFromJarFileName.addIfAbsent(result); - ResourceAttributesDefaults.addIfAbsent(result); - return result; - } - - private static void putIfAbsent(Map result, String key, String value) { - if (value != null) { - result.putIfAbsent(key, value); - } - } -} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java deleted file mode 100644 index 19328fd73..000000000 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesDefaults.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.prometheus.metrics.exporter.opentelemetry; - -import java.util.Map; -import java.util.UUID; - -public class ResourceAttributesDefaults { - - private static final String instanceId = UUID.randomUUID().toString(); - - public static void addIfAbsent(Map result) { - result.putIfAbsent("service.instance.id", instanceId); - result.putIfAbsent("service.name", "unknown_service:java"); - } -} diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java deleted file mode 100644 index 7cf7a51aa..000000000 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/ResourceAttributesFromJarFileName.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.prometheus.metrics.exporter.opentelemetry; - -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; - -// See io.opentelemetry.instrumentation.resources.JarServiceNameDetector -public class ResourceAttributesFromJarFileName { - - public static void addIfAbsent(Map result) { - if (result.containsKey("service.name")) { - return; - } - Path jarPath = getJarPathFromSunCommandLine(); - if (jarPath == null) { - return; - } - String serviceName = getServiceName(jarPath); - result.putIfAbsent("service.name", serviceName); - } - - private static Path getJarPathFromSunCommandLine() { - String programArguments = System.getProperty("sun.java.command"); - if (programArguments == null) { - return null; - } - // Take the path until the first space. If the path doesn't exist extend it up to the next - // space. Repeat until a path that exists is found or input runs out. - int next = 0; - while (true) { - int nextSpace = programArguments.indexOf(' ', next); - if (nextSpace == -1) { - return pathIfExists(programArguments); - } - Path path = pathIfExists(programArguments.substring(0, nextSpace)); - next = nextSpace + 1; - if (path != null) { - return path; - } - } - } - - private static Path pathIfExists(String programArguments) { - Path candidate; - try { - candidate = Paths.get(programArguments); - } catch (InvalidPathException e) { - return null; - } - return Files.isRegularFile(candidate) ? candidate : null; - } - - private static String getServiceName(Path jarPath) { - String jarName = jarPath.getFileName().toString(); - int dotIndex = jarName.lastIndexOf("."); - return dotIndex == -1 ? jarName : jarName.substring(0, dotIndex); - } -} diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java new file mode 100644 index 000000000..9b9b12420 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java @@ -0,0 +1,296 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.prometheus.metrics.config.ExporterOpenTelemetryProperties; +import io.prometheus.metrics.config.PrometheusPropertiesLoader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.stream.Stream; +import org.assertj.core.api.AbstractStringAssert; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class OtelAutoConfigTest { + + static class TestCase { + Map systemProperties = new HashMap<>(); + Map> expectedProperties = Collections.emptyMap(); + Map expectedResourceAttributes = Collections.emptyMap(); + Consumer exporterBuilder; + Consumer propertiesBuilder; + + public TestCase() {} + + public TestCase expectedProperties(Map> expectedProperties) { + this.expectedProperties = expectedProperties; + return this; + } + + public TestCase expectedResourceAttributes(Map expectedResourceAttributes) { + this.expectedResourceAttributes = expectedResourceAttributes; + return this; + } + + public TestCase systemProperties(Map systemProperties) { + this.systemProperties.putAll(systemProperties); + return this; + } + + public TestCase exporterBuilder(Consumer exporterBuilder) { + this.exporterBuilder = exporterBuilder; + return this; + } + + public TestCase propertiesBuilder( + Consumer propertiesBuilder) { + this.propertiesBuilder = propertiesBuilder; + return this; + } + } + + public static Stream testCases() { + return Stream.of( + Arguments.of( + "values from builder", + new TestCase() + .expectedProperties( + ImmutableMap.>builder() + .put("otel.exporter.otlp.protocol", Optional.of("http/protobuf")) + .put("otel.exporter.otlp.endpoint", Optional.of("http://builder:4318")) + .put("otel.exporter.otlp.headers", Optional.of("h=builder-v")) + .put("otel.metric.export.interval", Optional.of("2s")) + .put("otel.exporter.otlp.timeout", Optional.of("3s")) + .put("otel.service.name", Optional.of("builder-service")) + .build()) + .expectedResourceAttributes( + ImmutableMap.of( + "key", + "builder-value", + "service.name", + "builder-service", + "service.namespace", + "builder-namespace", + "service.instance.id", + "builder-instance", + "service.version", + "builder-version")) + .exporterBuilder(OtelAutoConfigTest::setBuilderValues)), + Arguments.of( + "builder endpoint with path", + new TestCase() + .expectedProperties( + ImmutableMap.of( + "otel.exporter.otlp.endpoint", Optional.of("http://builder:4318/"))) + .exporterBuilder(builder -> builder.endpoint("http://builder:4318/v1/metrics"))), + Arguments.of( + "values from otel have precedence over builder", + new TestCase() + .expectedProperties( + ImmutableMap.>builder() + .put("otel.exporter.otlp.protocol", Optional.of("grpc")) + .put("otel.exporter.otlp.metrics.protocol", Optional.empty()) + .put("otel.exporter.otlp.endpoint", Optional.of("http://otel:4317")) + .put("otel.exporter.otlp.metrics.endpoint", Optional.empty()) + .put("otel.exporter.otlp.headers", Optional.of("h=otel-v")) + .put("otel.exporter.otlp.metrics.headers", Optional.empty()) + .put("otel.metric.export.interval", Optional.of("12s")) + .put("otel.exporter.otlp.timeout", Optional.of("13s")) + .put("otel.exporter.otlp.metrics.timeout", Optional.empty()) + .put("otel.service.name", Optional.of("otel-service")) + .build()) + .expectedResourceAttributes( + ImmutableMap.of( + "key", + "otel-value", + "service.name", + "otel-service", + "service.namespace", + "otel-namespace", + "service.instance.id", + "otel-instance", + "service.version", + "otel-version")) + .exporterBuilder(OtelAutoConfigTest::setBuilderValues) + .systemProperties(otelOverrides())), + Arguments.of( + "values from prom properties have precedence over builder and otel", + new TestCase() + .expectedProperties( + ImmutableMap.>builder() + .put("otel.exporter.otlp.metrics.protocol", Optional.of("http/protobuf")) + .put("otel.exporter.otlp.protocol", Optional.of("grpc")) + .put("otel.exporter.otlp.metrics.endpoint", Optional.of("http://prom:4317")) + .put("otel.exporter.otlp.endpoint", Optional.of("http://otel:4317")) + .put("otel.exporter.otlp.metrics.headers", Optional.of("h=prom-v")) + .put("otel.exporter.otlp.headers", Optional.of("h=otel-v")) + .put("otel.metric.export.interval", Optional.of("22s")) + .put("otel.exporter.otlp.metrics.timeout", Optional.of("23s")) + .put("otel.exporter.otlp.timeout", Optional.of("13s")) + .put("otel.service.name", Optional.of("prom-service")) + .build()) + .expectedResourceAttributes( + ImmutableMap.of( + "key", + "prom-value", + "service.name", + "prom-service", + "service.namespace", + "prom-namespace", + "service.instance.id", + "prom-instance", + "service.version", + "prom-version")) + .exporterBuilder(OtelAutoConfigTest::setBuilderValues) + .systemProperties(otelOverrides()) + .systemProperties( + ImmutableMap.builder() + .put("io.prometheus.exporter.opentelemetry.protocol", "http/protobuf") + .put("io.prometheus.exporter.opentelemetry.endpoint", "http://prom:4317") + .put("io.prometheus.exporter.opentelemetry.headers", "h=prom-v") + .put("io.prometheus.exporter.opentelemetry.intervalSeconds", "22") + .put("io.prometheus.exporter.opentelemetry.timeoutSeconds", "23") + .put("io.prometheus.exporter.opentelemetry.serviceName", "prom-service") + .put( + "io.prometheus.exporter.opentelemetry.serviceNamespace", + "prom-namespace") + .put( + "io.prometheus.exporter.opentelemetry.serviceInstanceId", + "prom-instance") + .put("io.prometheus.exporter.opentelemetry.serviceVersion", "prom-version") + .put( + "io.prometheus.exporter.opentelemetry.resourceAttributes", + "key=prom-value") + .build())), + Arguments.of( + "values from prom properties builder have precedence over builder and otel", + new TestCase() + .expectedProperties( + ImmutableMap.>builder() + .put("otel.exporter.otlp.metrics.protocol", Optional.of("http/protobuf")) + .put("otel.exporter.otlp.protocol", Optional.of("grpc")) + .put("otel.exporter.otlp.metrics.endpoint", Optional.of("http://prom:4317")) + .put("otel.exporter.otlp.endpoint", Optional.of("http://otel:4317")) + .put("otel.exporter.otlp.metrics.headers", Optional.of("h=prom-v")) + .put("otel.exporter.otlp.headers", Optional.of("h=otel-v")) + .put("otel.metric.export.interval", Optional.of("22s")) + .put("otel.exporter.otlp.metrics.timeout", Optional.of("23s")) + .put("otel.exporter.otlp.timeout", Optional.of("13s")) + .put("otel.service.name", Optional.of("prom-service")) + .build()) + .expectedResourceAttributes( + ImmutableMap.of( + "key", + "prom-value", + "service.name", + "prom-service", + "service.namespace", + "prom-namespace", + "service.instance.id", + "prom-instance", + "service.version", + "prom-version")) + .exporterBuilder(OtelAutoConfigTest::setBuilderValues) + .systemProperties(otelOverrides()) + .propertiesBuilder( + builder -> + builder + .protocol("http/protobuf") + .endpoint("http://prom:4317") + .header("h", "prom-v") + .intervalSeconds(22) + .timeoutSeconds(23) + .serviceName("prom-service") + .serviceNamespace("prom-namespace") + .serviceInstanceId("prom-instance") + .serviceVersion("prom-version") + .resourceAttribute("key", "prom-value")))); + } + + private static ImmutableMap otelOverrides() { + return ImmutableMap.builder() + .put("otel.exporter.otlp.protocol", "grpc") + .put("otel.exporter.otlp.endpoint", "http://otel:4317") + .put("otel.exporter.otlp.headers", "h=otel-v") + .put("otel.metric.export.interval", "12s") + .put("otel.exporter.otlp.timeout", "13s") + .put("otel.service.name", "otel-service") + .put( + "otel.resource.attributes", + "key=otel-value,service.namespace=otel-namespace,service.instance.id=otel-instance,service.version=otel-version") + .build(); + } + + private static void setBuilderValues(OpenTelemetryExporter.Builder builder) { + builder + .protocol("http/protobuf") + .endpoint("http://builder:4318") + .header("h", "builder-v") + .intervalSeconds(2) + .timeoutSeconds(3) + .serviceName("builder-service") + .serviceNamespace("builder-namespace") + .serviceInstanceId("builder-instance") + .serviceVersion("builder-version") + .resourceAttribute("key", "builder-value"); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("testCases") + void properties(String name, TestCase testCase) { + testCase.systemProperties.forEach(System::setProperty); + + try { + OpenTelemetryExporter.Builder builder = OpenTelemetryExporter.builder(); + if (testCase.exporterBuilder != null) { + testCase.exporterBuilder.accept(builder); + } + AutoConfiguredOpenTelemetrySdk sdk = + OtelAutoConfig.createAutoConfiguredOpenTelemetrySdk( + builder, + new AtomicReference<>(), + getExporterOpenTelemetryProperties(testCase), + PrometheusInstrumentationScope.loadInstrumentationScopeInfo()); + + ConfigProperties config = AutoConfigureUtil.getConfig(sdk); + Map, Object> map = + OtelAutoConfig.getResourceField(sdk).getAttributes().asMap(); + testCase.expectedProperties.forEach( + (key, value) -> { + AbstractStringAssert o = assertThat(config.getString(key)).describedAs("key=" + key); + if (value.isPresent()) { + o.isEqualTo(value.get()); + } else { + o.isNull(); + } + }); + testCase.expectedResourceAttributes.forEach( + (key, value) -> + assertThat(map.get(AttributeKey.stringKey(key))) + .describedAs("key=" + key) + .hasToString(value)); + } finally { + testCase.systemProperties.keySet().forEach(System::clearProperty); + } + } + + private static ExporterOpenTelemetryProperties getExporterOpenTelemetryProperties( + TestCase testCase) { + if (testCase.propertiesBuilder == null) { + return PrometheusPropertiesLoader.load().getExporterOpenTelemetryProperties(); + } + ExporterOpenTelemetryProperties.Builder builder = ExporterOpenTelemetryProperties.builder(); + testCase.propertiesBuilder.accept(builder); + return builder.build(); + } +} diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 84938cff4..953b09dc5 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -17,14 +17,16 @@ - - - io.opentelemetry - opentelemetry-api - ${otel.version} - - - + + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-bom-alpha + ${otel.instrumentation.version} + pom + import + + + prometheus-metrics-tracer-common diff --git a/scripts/run-acceptance-tests.sh b/scripts/run-acceptance-tests.sh new file mode 100755 index 000000000..151783f77 --- /dev/null +++ b/scripts/run-acceptance-tests.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd oats/yaml +go install github.com/onsi/ginkgo/v2/ginkgo +export TESTCASE_SKIP_BUILD=true +export TESTCASE_TIMEOUT=5m +export TESTCASE_BASE_PATH=../../examples +ginkgo -r # is parallel causing problems? -p From 413f88940565d4fc4da6443894f9dae5904975ff Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 17 Oct 2024 15:29:19 +0200 Subject: [PATCH 435/980] Add clear() method into PrometheusRegistry to unregister all collectors (#1158) * Add clear() method into PrometheusRegistry to unregister all collectors Signed-off-by: Petr Holubec * format Signed-off-by: Gregor Zeitlinger * test Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger Co-authored-by: Petr Holubec --- .../metrics/model/registry/PrometheusRegistry.java | 6 ++++++ .../model/registry/PrometheusRegistryTest.java | 12 ++++++++++++ 2 files changed, 18 insertions(+) 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 026560bb9..5038da894 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 @@ -56,6 +56,12 @@ public void unregister(MultiCollector collector) { } } + public void clear() { + collectors.clear(); + multiCollectors.clear(); + prometheusNames.clear(); + } + public MetricSnapshots scrape() { return scrape((PrometheusScrapeRequest) null); } 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 6557c0ecf..e0f22a9dc 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 @@ -145,4 +145,16 @@ public void registerOkMultiCollector() { snapshots = registry.scrape(); assertThat(snapshots.size()).isZero(); } + + @Test + public void clearOk() { + PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(counterA1); + registry.register(counterB); + registry.register(gaugeA); + assertThat(registry.scrape().size()).isEqualTo(3); + + registry.clear(); + assertThat(registry.scrape().size()).isZero(); + } } From 27ffb91a0e090aa30c5e1e53de1861f03c5af27b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 17 Oct 2024 15:57:21 +0200 Subject: [PATCH 436/980] add test Coverage check (#1159) * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger * add coverage check Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- benchmarks/pom.xml | 1 + examples/pom.xml | 4 + integration-tests/pom.xml | 4 + otel-agent-resources/pom.xml | 3 - pom.xml | 66 ++++++++ .../metrics/config/ExemplarsProperties.java | 21 +-- .../config/ExporterFilterProperties.java | 11 +- .../config/ExporterHttpServerProperties.java | 7 +- .../ExporterOpenTelemetryProperties.java | 23 +-- .../metrics/config/ExporterProperties.java | 7 +- .../config/ExporterPushgatewayProperties.java | 13 +- .../metrics/config/MetricsProperties.java | 10 +- .../config/PrometheusPropertiesLoader.java | 15 +- .../io/prometheus/metrics/config/Util.java | 6 +- .../config/ExemplarsPropertiesTest.java | 60 +++++++ .../config/ExporterFilterPropertiesTest.java | 45 +++++ .../ExporterHttpServerPropertiesTest.java | 31 ++++ .../ExporterOpenTelemetryPropertiesTest.java | 70 ++++++++ .../config/ExporterPropertiesTest.java | 58 +++++++ .../ExporterPushgatewayPropertiesTest.java | 35 ++++ .../metrics/config/MetricsPropertiesTest.java | 154 ++++++++++++++++++ ...va => PrometheusPropertiesLoaderTest.java} | 16 +- .../core/metrics/MetricWithFixedMetadata.java | 5 +- .../core/datapoints/CounterDataPointTest.java | 39 +++++ .../metrics/core/datapoints/TimerApiTest.java | 28 +++- .../core/metrics/CallbackMetricTest.java | 46 ++++++ .../metrics/core/metrics/CounterTest.java | 41 ++++- .../metrics/core/metrics/GaugeTest.java | 38 ++++- .../metrics/core/metrics/InfoTest.java | 23 +++ .../metrics/core/metrics/StateSetTest.java | 8 + .../pom.xml | 2 + .../pom.xml | 2 + .../PrometheusInstrumentationScope.java | 26 +-- .../PrometheusInstrumentationScopeTest.java | 38 +++++ .../exporter/pushgateway/SchemeTest.java | 18 ++ .../ExpositionFormatsTest.java | 29 +++- .../pom.xml | 4 +- .../pom.xml | 1 - .../pom.xml | 1 + .../instrumentation/jvm/JvmMetricsTest.java | 22 +++ .../jvm/JvmNativeMemoryMetricsTest.java | 8 + .../model/snapshots/PrometheusNaming.java | 2 +- .../metrics/model/registry/CollectorTest.java | 29 ++++ .../ClassicHistogramBucketsTest.java | 14 ++ .../model/snapshots/ExemplarsTest.java | 2 + .../snapshots/HistogramSnapshotTest.java | 8 +- .../model/snapshots/InfoSnapshotTest.java | 7 + .../metrics/model/snapshots/LabelTest.java | 32 ++++ .../model/snapshots/MetricSnapshotTest.java | 10 +- .../model/snapshots/StateSetSnapshotTest.java | 13 +- 50 files changed, 1071 insertions(+), 85 deletions(-) create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java create mode 100644 prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/MetricsPropertiesTest.java rename prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/{PrometheusPropertiesLoaderTests.java => PrometheusPropertiesLoaderTest.java} (74%) create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/CounterDataPointTest.java create mode 100644 prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CallbackMetricTest.java create mode 100644 prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScopeTest.java create mode 100644 prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/SchemeTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/CollectorTest.java create mode 100644 prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelTest.java diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 99c4ecee8..11e24c3bd 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -20,6 +20,7 @@ 1.37 0.16.0 3.0.2 + 0.0 diff --git a/examples/pom.xml b/examples/pom.xml index def095f43..e1fd7ceb4 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -16,6 +16,10 @@ Example projects for the Prometheus Metrics Library. + + 0.0 + + example-exemplars-tail-sampling example-exporter-servlet-tomcat diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index dbd6754c6..ad98ba538 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -18,6 +18,10 @@ Integration tests for the Exporter modules + + 0.0 + + it-common it-exporter diff --git a/otel-agent-resources/pom.xml b/otel-agent-resources/pom.xml index 176c2c6eb..b18153b7c 100644 --- a/otel-agent-resources/pom.xml +++ b/otel-agent-resources/pom.xml @@ -23,9 +23,6 @@ 1.29.0 - - - diff --git a/pom.xml b/pom.xml index 273f97881..b84550bf1 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ 5.11.2 2.8.0-alpha 8 + 0.70 @@ -76,6 +77,16 @@ otel-agent-resources + + + + com.google.guava + guava + 33.3.1-jre + + + + org.junit.jupiter @@ -101,12 +112,23 @@ 3.26.3 test + + com.google.guava + guava + test + org.slf4j slf4j-simple 1.7.36 test + + org.junit-pioneer + junit-pioneer + 2.3.0 + test + @@ -200,6 +222,50 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + **/generated/** + + + + + + prepare-agent + + + + report + test + + report + + + + check + + check + + + + + CLASS + + + LINE + COVEREDRATIO + ${jacoco.line-coverage} + + + + + + + + org.apache.maven.plugins maven-enforcer-plugin diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java index f660725bf..017d67909 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java @@ -5,6 +5,7 @@ /** Properties starting with io.prometheus.exemplars */ public class ExemplarsProperties { + private static final String PREFIX = "io.prometheus.exemplars"; private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds"; private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds"; private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds"; @@ -55,42 +56,42 @@ public Integer getSampleIntervalMilliseconds() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExemplarsProperties load(String prefix, Map properties) + static ExemplarsProperties load(Map properties) throws PrometheusPropertiesException { Integer minRetentionPeriodSeconds = - Util.loadInteger(prefix + "." + MIN_RETENTION_PERIOD_SECONDS, properties); + Util.loadInteger(PREFIX + "." + MIN_RETENTION_PERIOD_SECONDS, properties); Integer maxRetentionPeriodSeconds = - Util.loadInteger(prefix + "." + MAX_RETENTION_PERIOD_SECONDS, properties); + Util.loadInteger(PREFIX + "." + MAX_RETENTION_PERIOD_SECONDS, properties); Integer sampleIntervalMilliseconds = - Util.loadInteger(prefix + "." + SAMPLE_INTERVAL_MILLISECONDS, properties); + Util.loadInteger(PREFIX + "." + SAMPLE_INTERVAL_MILLISECONDS, properties); Util.assertValue( minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", - prefix, + PREFIX, MIN_RETENTION_PERIOD_SECONDS); Util.assertValue( - minRetentionPeriodSeconds, + maxRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", - prefix, + PREFIX, MAX_RETENTION_PERIOD_SECONDS); Util.assertValue( sampleIntervalMilliseconds, t -> t > 0, "Expecting value > 0.", - prefix, + PREFIX, SAMPLE_INTERVAL_MILLISECONDS); if (minRetentionPeriodSeconds != null && maxRetentionPeriodSeconds != null) { if (minRetentionPeriodSeconds > maxRetentionPeriodSeconds) { throw new PrometheusPropertiesException( - prefix + PREFIX + "." + MIN_RETENTION_PERIOD_SECONDS + " must not be greater than " - + prefix + + PREFIX + "." + MAX_RETENTION_PERIOD_SECONDS + "."); diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java index 7a408bb58..c2c3d48d3 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterFilterProperties.java @@ -13,6 +13,7 @@ public class ExporterFilterProperties { public static final String METRIC_NAME_MUST_NOT_BE_EQUAL_TO = "metricNameMustNotBeEqualTo"; public static final String METRIC_NAME_MUST_START_WITH = "metricNameMustStartWith"; public static final String METRIC_NAME_MUST_NOT_START_WITH = "metricNameMustNotStartWith"; + private static final String PREFIX = "io.prometheus.exporter.filter"; private final List allowedNames; private final List excludedNames; @@ -58,16 +59,16 @@ public List getExcludedMetricNamePrefixes() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExporterFilterProperties load(String prefix, Map properties) + static ExporterFilterProperties load(Map properties) throws PrometheusPropertiesException { List allowedNames = - Util.loadStringList(prefix + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties); + Util.loadStringList(PREFIX + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties); List excludedNames = - Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties); + Util.loadStringList(PREFIX + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties); List allowedPrefixes = - Util.loadStringList(prefix + "." + METRIC_NAME_MUST_START_WITH, properties); + Util.loadStringList(PREFIX + "." + METRIC_NAME_MUST_START_WITH, properties); List excludedPrefixes = - Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); + Util.loadStringList(PREFIX + "." + METRIC_NAME_MUST_NOT_START_WITH, properties); return new ExporterFilterProperties( allowedNames, excludedNames, allowedPrefixes, excludedPrefixes); } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java index fe048ac6b..6618ab88e 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterHttpServerProperties.java @@ -6,6 +6,7 @@ public class ExporterHttpServerProperties { private static final String PORT = "port"; + private static final String PREFIX = "io.prometheus.exporter.httpServer"; private final Integer port; private ExporterHttpServerProperties(Integer port) { @@ -20,10 +21,10 @@ public Integer getPort() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExporterHttpServerProperties load(String prefix, Map properties) + static ExporterHttpServerProperties load(Map properties) throws PrometheusPropertiesException { - Integer port = Util.loadInteger(prefix + "." + PORT, properties); - Util.assertValue(port, t -> t > 0, "Expecting value > 0", prefix, PORT); + Integer port = Util.loadInteger(PREFIX + "." + PORT, properties); + Util.assertValue(port, t -> t > 0, "Expecting value > 0.", PREFIX, PORT); return new ExporterHttpServerProperties(port); } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java index d009d2603..53acb6b14 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.java @@ -19,6 +19,7 @@ public class ExporterOpenTelemetryProperties { private static final String SERVICE_VERSION = "serviceVersion"; private static final String RESOURCE_ATTRIBUTES = "resourceAttributes"; // otel.resource.attributes + private static final String PREFIX = "io.prometheus.exporter.opentelemetry"; private final String protocol; private final String endpoint; @@ -98,19 +99,19 @@ public Map getResourceAttributes() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExporterOpenTelemetryProperties load(String prefix, Map properties) + static ExporterOpenTelemetryProperties load(Map properties) throws PrometheusPropertiesException { - String protocol = Util.loadString(prefix + "." + PROTOCOL, properties); - String endpoint = Util.loadString(prefix + "." + ENDPOINT, properties); - Map headers = Util.loadMap(prefix + "." + HEADERS, properties); - String interval = Util.loadStringAddSuffix(prefix + "." + INTERVAL_SECONDS, properties, "s"); - String timeout = Util.loadStringAddSuffix(prefix + "." + TIMEOUT_SECONDS, properties, "s"); - String serviceName = Util.loadString(prefix + "." + SERVICE_NAME, properties); - String serviceNamespace = Util.loadString(prefix + "." + SERVICE_NAMESPACE, properties); - String serviceInstanceId = Util.loadString(prefix + "." + SERVICE_INSTANCE_ID, properties); - String serviceVersion = Util.loadString(prefix + "." + SERVICE_VERSION, properties); + String protocol = Util.loadString(PREFIX + "." + PROTOCOL, properties); + String endpoint = Util.loadString(PREFIX + "." + ENDPOINT, properties); + Map headers = Util.loadMap(PREFIX + "." + HEADERS, properties); + String interval = Util.loadStringAddSuffix(PREFIX + "." + INTERVAL_SECONDS, properties, "s"); + String timeout = Util.loadStringAddSuffix(PREFIX + "." + TIMEOUT_SECONDS, properties, "s"); + String serviceName = Util.loadString(PREFIX + "." + SERVICE_NAME, properties); + String serviceNamespace = Util.loadString(PREFIX + "." + SERVICE_NAMESPACE, properties); + String serviceInstanceId = Util.loadString(PREFIX + "." + SERVICE_INSTANCE_ID, properties); + String serviceVersion = Util.loadString(PREFIX + "." + SERVICE_VERSION, properties); Map resourceAttributes = - Util.loadMap(prefix + "." + RESOURCE_ATTRIBUTES, properties); + Util.loadMap(PREFIX + "." + RESOURCE_ATTRIBUTES, properties); return new ExporterOpenTelemetryProperties( protocol, endpoint, diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java index dd0606e6d..72c04c33b 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -7,6 +7,7 @@ public class ExporterProperties { private static final String INCLUDE_CREATED_TIMESTAMPS = "includeCreatedTimestamps"; private static final String EXEMPLARS_ON_ALL_METRIC_TYPES = "exemplarsOnAllMetricTypes"; + private static final String PREFIX = "io.prometheus.exporter"; private final Boolean includeCreatedTimestamps; private final Boolean exemplarsOnAllMetricTypes; @@ -33,12 +34,12 @@ public boolean getExemplarsOnAllMetricTypes() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExporterProperties load(String prefix, Map properties) + static ExporterProperties load(Map properties) throws PrometheusPropertiesException { Boolean includeCreatedTimestamps = - Util.loadBoolean(prefix + "." + INCLUDE_CREATED_TIMESTAMPS, properties); + Util.loadBoolean(PREFIX + "." + INCLUDE_CREATED_TIMESTAMPS, properties); Boolean exemplarsOnAllMetricTypes = - Util.loadBoolean(prefix + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); + Util.loadBoolean(PREFIX + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java index 4a794eba2..8aafba3a4 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java @@ -7,6 +7,7 @@ public class ExporterPushgatewayProperties { private static final String ADDRESS = "address"; private static final String JOB = "job"; private static final String SCHEME = "scheme"; + private static final String PREFIX = "io.prometheus.exporter.pushgateway"; private final String scheme; private final String address; private final String job; @@ -42,15 +43,17 @@ public String getScheme() { * Note that this will remove entries from {@code properties}. This is because we want to know if * there are unused properties remaining after all properties have been loaded. */ - static ExporterPushgatewayProperties load(String prefix, Map properties) + static ExporterPushgatewayProperties load(Map properties) throws PrometheusPropertiesException { - String address = Util.loadString(prefix + "." + ADDRESS, properties); - String job = Util.loadString(prefix + "." + JOB, properties); - String scheme = Util.loadString(prefix + "." + SCHEME, properties); + String address = Util.loadString(PREFIX + "." + ADDRESS, properties); + String job = Util.loadString(PREFIX + "." + JOB, properties); + String scheme = Util.loadString(PREFIX + "." + SCHEME, properties); if (scheme != null) { if (!scheme.equals("http") && !scheme.equals("https")) { throw new PrometheusPropertiesException( - prefix + "." + SCHEME + "=" + scheme + ": Illegal value. Expecting 'http' or 'https'."); + String.format( + "%s.%s: Illegal value. Expecting 'http' or 'https'. Found: %s", + PREFIX, SCHEME, scheme)); } } return new ExporterPushgatewayProperties(address, job, scheme); diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java index 744822005..7667fadce 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/MetricsProperties.java @@ -164,11 +164,11 @@ private void validate(String prefix) throws PrometheusPropertiesException { prefix, HISTOGRAM_NATIVE_RESET_DURATION_SECONDS); Util.assertValue( - summaryMaxAgeSeconds, t -> t > 0, "Expecting value > 0", prefix, SUMMARY_MAX_AGE_SECONDS); + summaryMaxAgeSeconds, t -> t > 0, "Expecting value > 0.", prefix, SUMMARY_MAX_AGE_SECONDS); Util.assertValue( summaryNumberOfAgeBuckets, t -> t > 0, - "Expecting value > 0", + "Expecting value > 0.", prefix, SUMMARY_NUMBER_OF_AGE_BUCKETS); @@ -201,7 +201,11 @@ private void validate(String prefix) throws PrometheusPropertiesException { for (double quantile : summaryQuantiles) { if (quantile < 0 || quantile > 1) { throw new PrometheusPropertiesException( - prefix + "." + SUMMARY_QUANTILES + ": Expecting 0.0 <= quantile <= 1.0"); + prefix + + "." + + SUMMARY_QUANTILES + + ": Expecting 0.0 <= quantile <= 1.0. Found: " + + quantile); } } } diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java index e29f93036..82170cf49 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/PrometheusPropertiesLoader.java @@ -33,18 +33,15 @@ public static PrometheusProperties load(Map externalProperties) Map metricsConfigs = loadMetricsConfigs(properties); MetricsProperties defaultMetricsProperties = MetricsProperties.load("io.prometheus.metrics", properties); - ExemplarsProperties exemplarConfig = - ExemplarsProperties.load("io.prometheus.exemplars", properties); - ExporterProperties exporterProperties = - ExporterProperties.load("io.prometheus.exporter", properties); - ExporterFilterProperties exporterFilterProperties = - ExporterFilterProperties.load("io.prometheus.exporter.filter", properties); + ExemplarsProperties exemplarConfig = ExemplarsProperties.load(properties); + ExporterProperties exporterProperties = ExporterProperties.load(properties); + ExporterFilterProperties exporterFilterProperties = ExporterFilterProperties.load(properties); ExporterHttpServerProperties exporterHttpServerProperties = - ExporterHttpServerProperties.load("io.prometheus.exporter.httpServer", properties); + ExporterHttpServerProperties.load(properties); ExporterPushgatewayProperties exporterPushgatewayProperties = - ExporterPushgatewayProperties.load("io.prometheus.exporter.pushgateway", properties); + ExporterPushgatewayProperties.load(properties); ExporterOpenTelemetryProperties exporterOpenTelemetryProperties = - ExporterOpenTelemetryProperties.load("io.prometheus.exporter.opentelemetry", properties); + ExporterOpenTelemetryProperties.load(properties); validateAllPropertiesProcessed(properties); return new PrometheusProperties( defaultMetricsProperties, diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java index 15a61f7fe..7092df068 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/Util.java @@ -23,7 +23,7 @@ static Boolean loadBoolean(String name, Map properties) if (property != null) { if (!"true".equalsIgnoreCase(property) && !"false".equalsIgnoreCase(property)) { throw new PrometheusPropertiesException( - name + "=" + property + ": Expecting 'true' or 'false'"); + String.format("%s: Expecting 'true' or 'false'. Found: %s", name, property)); } return Boolean.parseBoolean(property); } @@ -154,7 +154,9 @@ static void assertValue( throws PrometheusPropertiesException { if (number != null && !predicate.test(number)) { String fullMessage = - prefix == null ? name + ": " + message : prefix + "." + name + ": " + message; + prefix == null + ? name + ": " + message + : String.format("%s.%s: %s Found: %s", prefix, name, message, number); throw new PrometheusPropertiesException(fullMessage); } } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java new file mode 100644 index 000000000..55be3086e --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java @@ -0,0 +1,60 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExemplarsPropertiesTest { + + @Test + void load() { + ExemplarsProperties properties = + load( + ImmutableMap.of( + "io.prometheus.exemplars.minRetentionPeriodSeconds", "1", + "io.prometheus.exemplars.maxRetentionPeriodSeconds", "2", + "io.prometheus.exemplars.sampleIntervalMilliseconds", "3")); + assertThat(properties.getMinRetentionPeriodSeconds()).isOne(); + assertThat(properties.getMaxRetentionPeriodSeconds()).isEqualTo(2); + assertThat(properties.getSampleIntervalMilliseconds()).isEqualTo(3); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> load(ImmutableMap.of("io.prometheus.exemplars.minRetentionPeriodSeconds", "-1"))) + .withMessage( + "io.prometheus.exemplars.minRetentionPeriodSeconds: Expecting value > 0. Found: -1"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> load(ImmutableMap.of("io.prometheus.exemplars.maxRetentionPeriodSeconds", "0"))) + .withMessage( + "io.prometheus.exemplars.maxRetentionPeriodSeconds: Expecting value > 0. Found: 0"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> load(ImmutableMap.of("io.prometheus.exemplars.sampleIntervalMilliseconds", "-1"))) + .withMessage( + "io.prometheus.exemplars.sampleIntervalMilliseconds: Expecting value > 0. Found: -1"); + } + + private static ExemplarsProperties load(Map map) { + return ExemplarsProperties.load(new HashMap<>(map)); + } + + @Test + void builder() { + ExemplarsProperties properties = + ExemplarsProperties.builder() + .minRetentionPeriodSeconds(1) + .maxRetentionPeriodSeconds(2) + .sampleIntervalMilliseconds(3) + .build(); + assertThat(properties.getMinRetentionPeriodSeconds()).isOne(); + assertThat(properties.getMaxRetentionPeriodSeconds()).isEqualTo(2); + assertThat(properties.getSampleIntervalMilliseconds()).isEqualTo(3); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java new file mode 100644 index 000000000..273b058a7 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java @@ -0,0 +1,45 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExporterFilterPropertiesTest { + + @Test + void load() { + ExporterFilterProperties properties = + load( + ImmutableMap.of( + "io.prometheus.exporter.filter.metricNameMustBeEqualTo", "a,b,c", + "io.prometheus.exporter.filter.metricNameMustNotBeEqualTo", "d,e,f", + "io.prometheus.exporter.filter.metricNameMustStartWith", "g,h,i", + "io.prometheus.exporter.filter.metricNameMustNotStartWith", "j,k,l")); + assertThat(properties.getAllowedMetricNames()).containsExactly("a", "b", "c"); + assertThat(properties.getExcludedMetricNames()).containsExactly("d", "e", "f"); + assertThat(properties.getAllowedMetricNamePrefixes()).containsExactly("g", "h", "i"); + assertThat(properties.getExcludedMetricNamePrefixes()).containsExactly("j", "k", "l"); + } + + private static ExporterFilterProperties load(Map map) { + return ExporterFilterProperties.load(new HashMap<>(map)); + } + + @Test + void builder() { + ExporterFilterProperties properties = + ExporterFilterProperties.builder() + .allowedNames("a", "b", "c") + .excludedNames("d", "e", "f") + .allowedPrefixes("g", "h", "i") + .excludedPrefixes("j", "k", "l") + .build(); + assertThat(properties.getAllowedMetricNames()).containsExactly("a", "b", "c"); + assertThat(properties.getExcludedMetricNames()).containsExactly("d", "e", "f"); + assertThat(properties.getAllowedMetricNamePrefixes()).containsExactly("g", "h", "i"); + assertThat(properties.getExcludedMetricNamePrefixes()).containsExactly("j", "k", "l"); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java new file mode 100644 index 000000000..5da84fed2 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java @@ -0,0 +1,31 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExporterHttpServerPropertiesTest { + @Test + void load() { + ExporterHttpServerProperties properties = + load(ImmutableMap.of("io.prometheus.exporter.httpServer.port", "1")); + assertThat(properties.getPort()).isOne(); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> load(ImmutableMap.of("io.prometheus.exporter.httpServer.port", "0"))) + .withMessage("io.prometheus.exporter.httpServer.port: Expecting value > 0. Found: 0"); + } + + @Test + void builder() { + assertThat(ExporterHttpServerProperties.builder().port(1).build().getPort()).isOne(); + } + + private static ExporterHttpServerProperties load(Map map) { + return ExporterHttpServerProperties.load(new HashMap<>(map)); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java new file mode 100644 index 000000000..b6a67c3c1 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java @@ -0,0 +1,70 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExporterOpenTelemetryPropertiesTest { + + @Test + void load() { + ExporterOpenTelemetryProperties properties = + load( + ImmutableMap.of( + "io.prometheus.exporter.opentelemetry.protocol", "grpc", + "io.prometheus.exporter.opentelemetry.endpoint", "http://localhost:8080", + "io.prometheus.exporter.opentelemetry.headers", "key1=value1,key2=value2", + "io.prometheus.exporter.opentelemetry.intervalSeconds", "10", + "io.prometheus.exporter.opentelemetry.timeoutSeconds", "5", + "io.prometheus.exporter.opentelemetry.serviceName", "serviceName", + "io.prometheus.exporter.opentelemetry.serviceNamespace", "serviceNamespace", + "io.prometheus.exporter.opentelemetry.serviceInstanceId", "serviceInstanceId", + "io.prometheus.exporter.opentelemetry.serviceVersion", "serviceVersion", + "io.prometheus.exporter.opentelemetry.resourceAttributes", + "key1=value1,key2=value2")); + + assertValues(properties); + } + + private static void assertValues(ExporterOpenTelemetryProperties properties) { + assertThat(properties.getProtocol()).isEqualTo("grpc"); + assertThat(properties.getEndpoint()).isEqualTo("http://localhost:8080"); + assertThat(properties.getHeaders()) + .containsExactlyInAnyOrderEntriesOf(ImmutableMap.of("key1", "value1", "key2", "value2")); + assertThat(properties.getInterval()).isEqualTo("10s"); + assertThat(properties.getTimeout()).isEqualTo("5s"); + assertThat(properties.getServiceName()).isEqualTo("serviceName"); + assertThat(properties.getServiceNamespace()).isEqualTo("serviceNamespace"); + assertThat(properties.getServiceInstanceId()).isEqualTo("serviceInstanceId"); + assertThat(properties.getServiceVersion()).isEqualTo("serviceVersion"); + assertThat(properties.getResourceAttributes()) + .containsExactlyInAnyOrderEntriesOf(ImmutableMap.of("key1", "value1", "key2", "value2")); + } + + private static ExporterOpenTelemetryProperties load(Map map) { + return ExporterOpenTelemetryProperties.load(new HashMap<>(map)); + } + + @Test + void builder() { + ExporterOpenTelemetryProperties properties = + ExporterOpenTelemetryProperties.builder() + .protocol("grpc") + .endpoint("http://localhost:8080") + .header("key1", "value1") + .header("key2", "value2") + .intervalSeconds(10) + .timeoutSeconds(5) + .serviceName("serviceName") + .serviceNamespace("serviceNamespace") + .serviceInstanceId("serviceInstanceId") + .serviceVersion("serviceVersion") + .resourceAttribute("key1", "value1") + .resourceAttribute("key2", "value2") + .build(); + assertValues(properties); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java new file mode 100644 index 000000000..8da66da11 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java @@ -0,0 +1,58 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExporterPropertiesTest { + + @Test + void load() { + ExporterProperties properties = + load( + new HashMap<>( + ImmutableMap.of( + "io.prometheus.exporter.includeCreatedTimestamps", "true", + "io.prometheus.exporter.exemplarsOnAllMetricTypes", "true"))); + assertThat(properties.getIncludeCreatedTimestamps()).isTrue(); + assertThat(properties.getExemplarsOnAllMetricTypes()).isTrue(); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + load( + new HashMap<>( + ImmutableMap.of( + "io.prometheus.exporter.includeCreatedTimestamps", "invalid")))) + .withMessage( + "io.prometheus.exporter.includeCreatedTimestamps: Expecting 'true' or 'false'. Found: invalid"); + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + load( + new HashMap<>( + ImmutableMap.of( + "io.prometheus.exporter.exemplarsOnAllMetricTypes", "invalid")))) + .withMessage( + "io.prometheus.exporter.exemplarsOnAllMetricTypes: Expecting 'true' or 'false'. Found: invalid"); + } + + private static ExporterProperties load(Map map) { + return ExporterProperties.load(new HashMap<>(map)); + } + + @Test + void builder() { + ExporterProperties properties = + ExporterProperties.builder() + .includeCreatedTimestamps(true) + .exemplarsOnAllMetricTypes(true) + .build(); + assertThat(properties.getIncludeCreatedTimestamps()).isTrue(); + assertThat(properties.getExemplarsOnAllMetricTypes()).isTrue(); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java new file mode 100644 index 000000000..d5600e770 --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java @@ -0,0 +1,35 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ExporterPushgatewayPropertiesTest { + + @Test + void load() { + ExporterPushgatewayProperties properties = + load( + ImmutableMap.of( + "io.prometheus.exporter.pushgateway.address", "http://localhost", + "io.prometheus.exporter.pushgateway.job", "job", + "io.prometheus.exporter.pushgateway.scheme", "http")); + + assertThat(properties.getAddress()).isEqualTo("http://localhost"); + assertThat(properties.getJob()).isEqualTo("job"); + assertThat(properties.getScheme()).isEqualTo("http"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> load(ImmutableMap.of("io.prometheus.exporter.pushgateway.scheme", "foo"))) + .withMessage( + "io.prometheus.exporter.pushgateway.scheme: Illegal value. Expecting 'http' or 'https'. Found: foo"); + } + + private static ExporterPushgatewayProperties load(Map map) { + return ExporterPushgatewayProperties.load(new HashMap<>(map)); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/MetricsPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/MetricsPropertiesTest.java new file mode 100644 index 000000000..83cca06eb --- /dev/null +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/MetricsPropertiesTest.java @@ -0,0 +1,154 @@ +package io.prometheus.metrics.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import org.junit.jupiter.api.Test; + +class MetricsPropertiesTest { + @Test + void builder() { + assertThat(MetricsProperties.builder().exemplarsEnabled(true).build().getExemplarsEnabled()) + .isTrue(); + assertThat( + MetricsProperties.builder().histogramNativeOnly(true).build().getHistogramNativeOnly()) + .isTrue(); + assertThat( + MetricsProperties.builder() + .histogramClassicOnly(true) + .build() + .getHistogramClassicOnly()) + .isTrue(); + assertThat( + MetricsProperties.builder() + .histogramClassicUpperBounds(1.0, 2.0) + .build() + .getHistogramClassicUpperBounds()) + .containsExactly(1.0, 2.0); + + assertThat(MetricsProperties.builder().summaryQuantiles(0.1, 0.2).build().getSummaryQuantiles()) + .containsExactly(0.1, 0.2); + assertThat( + MetricsProperties.builder().summaryMaxAgeSeconds(1L).build().getSummaryMaxAgeSeconds()) + .isOne(); + assertThat( + MetricsProperties.builder() + .summaryQuantiles(0.2) + .summaryQuantileErrors(1.0) + .build() + .getSummaryQuantileErrors()) + .containsExactly(1.0); + assertThat( + MetricsProperties.builder() + .summaryNumberOfAgeBuckets(1) + .build() + .getSummaryNumberOfAgeBuckets()) + .isOne(); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().summaryNumberOfAgeBuckets(0).build()) + .withMessage(".summaryNumberOfAgeBuckets: Expecting value > 0. Found: 0"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().summaryQuantiles(2L).build()) + .withMessage(".summaryQuantiles: Expecting 0.0 <= quantile <= 1.0. Found: 2.0"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().summaryQuantileErrors(0.9).build()) + .withMessage( + ".summaryQuantileErrors: Can't configure summaryQuantileErrors without configuring summaryQuantiles"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + MetricsProperties.builder() + .summaryQuantiles(0.1) + .summaryQuantileErrors(0.1, 0.9) + .build()) + .withMessage(".summaryQuantileErrors: must have the same length as summaryQuantiles"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + MetricsProperties.builder() + .summaryQuantiles(0.1) + .summaryQuantileErrors(-0.9) + .build()) + .withMessage(".summaryQuantileErrors: Expecting 0.0 <= error <= 1.0"); + } + + @Test + void nativeBuilder() { + assertThat( + MetricsProperties.builder() + .histogramNativeInitialSchema(1) + .build() + .getHistogramNativeInitialSchema()) + .isOne(); + assertThat( + MetricsProperties.builder() + .histogramNativeMinZeroThreshold(.1) + .build() + .getHistogramNativeMinZeroThreshold()) + .isEqualTo(.1); + assertThat( + MetricsProperties.builder() + .histogramNativeMaxZeroThreshold(.1) + .build() + .getHistogramNativeMaxZeroThreshold()) + .isEqualTo(.1); + assertThat( + MetricsProperties.builder() + .histogramNativeMaxNumberOfBuckets(1) + .build() + .getHistogramNativeMaxNumberOfBuckets()) + .isOne(); + assertThat( + MetricsProperties.builder() + .histogramNativeResetDurationSeconds(1L) + .build() + .getHistogramNativeResetDurationSeconds()) + .isOne(); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().histogramNativeInitialSchema(10).build()) + .withMessage( + ".histogramNativeInitialSchema: Expecting number between -4 and +8. Found: 10"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().histogramNativeMinZeroThreshold(-1.0).build()) + .withMessage(".histogramNativeMinZeroThreshold: Expecting value >= 0. Found: -1.0"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().histogramNativeMaxZeroThreshold(-1.0).build()) + .withMessage(".histogramNativeMaxZeroThreshold: Expecting value >= 0. Found: -1.0"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy(() -> MetricsProperties.builder().histogramNativeMaxNumberOfBuckets(-1).build()) + .withMessage(".histogramNativeMaxNumberOfBuckets: Expecting value >= 0. Found: -1"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> MetricsProperties.builder().histogramNativeResetDurationSeconds(-1L).build()) + .withMessage(".histogramNativeResetDurationSeconds: Expecting value >= 0. Found: -1"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + MetricsProperties.builder() + .histogramNativeOnly(true) + .histogramClassicOnly(true) + .build()) + .withMessage(".histogramNativeOnly and .histogramClassicOnly cannot both be true"); + + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> + MetricsProperties.builder() + .histogramNativeMinZeroThreshold(0.1) + .histogramNativeMaxZeroThreshold(0.01) + .build()) + .withMessage( + ".histogramNativeMinZeroThreshold cannot be greater than .histogramNativeMaxZeroThreshold"); + } +} diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTest.java similarity index 74% rename from prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java rename to prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTest.java index 9da800c27..f0a2d5d3e 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTests.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/PrometheusPropertiesLoaderTest.java @@ -1,12 +1,14 @@ package io.prometheus.metrics.config; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.Properties; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.SetSystemProperty; /** Tests for {@link PrometheusPropertiesLoader}. */ -class PrometheusPropertiesLoaderTests { +class PrometheusPropertiesLoaderTest { @Test public void propertiesShouldBeLoadedFromPropertiesFile() { @@ -22,6 +24,18 @@ public void propertiesShouldBeLoadedFromPropertiesFile() { .isTrue(); } + @Test + @SetSystemProperty(key = "prometheus.config", value = "nonexistent.properties") + void cantLoadPropertiesFile() { + assertThatExceptionOfType(PrometheusPropertiesException.class) + .isThrownBy( + () -> { + PrometheusPropertiesLoader.load(new Properties()); + }) + .withMessage( + "Failed to read Prometheus properties from nonexistent.properties: nonexistent.properties"); + } + @Test public void externalPropertiesShouldOverridePropertiesFile() { Properties properties = new Properties(); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java index 056ef792c..9b213a85d 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/MetricWithFixedMetadata.java @@ -57,8 +57,9 @@ protected Builder(List illegalLabelNames, PrometheusProperties propertie } public B name(String name) { - if (!PrometheusNaming.isValidMetricName(name)) { - throw new IllegalArgumentException("'" + name + "': Illegal metric name."); + String error = PrometheusNaming.validateMetricName(name); + if (error != null) { + throw new IllegalArgumentException("'" + name + "': Illegal metric name: " + error); } this.name = name; return self(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/CounterDataPointTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/CounterDataPointTest.java new file mode 100644 index 000000000..3e70ef199 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/CounterDataPointTest.java @@ -0,0 +1,39 @@ +package io.prometheus.metrics.core.datapoints; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.prometheus.metrics.model.snapshots.Labels; +import org.junit.jupiter.api.Test; + +class CounterDataPointTest { + + private double value = 0; + + @Test + void inc() { + CounterDataPoint counterDataPoint = + new CounterDataPoint() { + @Override + public void inc(double value) { + CounterDataPointTest.this.value += value; + } + + @Override + public void incWithExemplar(double amount, Labels labels) {} + + @Override + public long getLongValue() { + return 0; + } + + @Override + public double get() { + return 0; + } + }; + counterDataPoint.inc(1); + assertThat(value).isOne(); + counterDataPoint.incWithExemplar(1, null); + assertThat(value).isEqualTo(2); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java index 70755b938..b7c9ea836 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/datapoints/TimerApiTest.java @@ -1,6 +1,32 @@ package io.prometheus.metrics.core.datapoints; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + class TimerApiTest { - // TODO: Port this from the simpleclient SimpleTimerTest + private double time = 0; + + private io.prometheus.metrics.core.datapoints.Timer timer = + new io.prometheus.metrics.core.datapoints.Timer(t -> time = t) {}; + private TimerApi api = () -> timer; + + @Test + void runnable() { + api.time(() -> {}); + assertThat(time).isPositive(); + } + + @Test + void supplier() { + assertThat(api.time(() -> "foo")).isEqualTo("foo"); + assertThat(time).isPositive(); + } + + @Test + void callable() throws Exception { + assertThat(api.timeChecked(() -> "foo")).isEqualTo("foo"); + assertThat(time).isPositive(); + } } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CallbackMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CallbackMetricTest.java new file mode 100644 index 000000000..16cd443d9 --- /dev/null +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CallbackMetricTest.java @@ -0,0 +1,46 @@ +package io.prometheus.metrics.core.metrics; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import org.junit.jupiter.api.Test; + +class CallbackMetricTest { + + @Test + void makeLabels() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + CounterWithCallback.builder() + .name("c") + .callback(callback -> {}) + .labelNames("label1", "label2") + .build() + .makeLabels("foo")) + .withMessage( + "CounterWithCallback was created with 2 label names, but the callback was called with 1 label values."); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + CounterWithCallback.builder() + .name("c") + .callback(callback -> {}) + .labelNames("label1", "label2") + .build() + .makeLabels((String[]) null)) + .withMessage( + "CounterWithCallback was created with label names, but the callback was called without label values."); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy( + () -> + CounterWithCallback.builder() + .name("c") + .callback(callback -> {}) + .build() + .makeLabels("foo")) + .withMessage( + "Cannot pass label values to a CounterWithCallback that was created without label names."); + } +} diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index a87153ec6..a9d83c6af 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.core.metrics; import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; @@ -198,16 +198,17 @@ private void assertExemplar(Counter counter, double value, String... labels) { @Test public void testExemplarSampler() throws Exception { - final Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build(); - final Exemplar exemplar2 = Exemplar.builder().value(1.0).traceId("def").spanId("456").build(); - final Exemplar exemplar3 = Exemplar.builder().value(1.0).traceId("123").spanId("abc").build(); - final Exemplar customExemplar = + Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build(); + Exemplar exemplar2 = Exemplar.builder().value(1.0).traceId("def").spanId("456").build(); + Exemplar exemplar3 = Exemplar.builder().value(1.0).traceId("123").spanId("abc").build(); + Exemplar customExemplar = Exemplar.builder() .value(1.0) .traceId("bab") .spanId("cdc") .labels(Labels.of("test", "test")) .build(); + SpanContext spanContext = new SpanContext() { private int callNumber = 0; @@ -293,6 +294,36 @@ public void markCurrentSpanAsExemplar() {} assertExemplarEquals(customExemplar, getData(counter).getExemplar()); } + @Test + void inc() { + Counter counter = Counter.builder().name("count_total").build(); + counter.inc(2.0); + + assertThat(getData(counter).getValue()).isCloseTo(2.0, offset(0.0001)); + assertThat(counter.get()).isEqualTo(2.0); + assertThat(counter.getLongValue()).isEqualTo(2L); + } + + @Test + void incWithExemplar() { + Counter counter = Counter.builder().name("count_total").build(); + counter.incWithExemplar(Labels.of("test", "test2")); + + assertExemplarEquals( + Exemplar.builder().value(1.0).labels(Labels.of("test", "test2")).build(), + getData(counter).getExemplar()); + } + + @Test + void incWithExemplar2() { + Counter counter = Counter.builder().name("count_total").build(); + counter.incWithExemplar(1.0, Labels.of("test", "test2")); + + assertExemplarEquals( + Exemplar.builder().value(1.0).labels(Labels.of("test", "test2")).build(), + getData(counter).getExemplar()); + } + @Test public void testExemplarSamplerDisabled() { Counter counter = diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java index 9aa0b04b3..11ec60c5b 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/GaugeTest.java @@ -104,10 +104,10 @@ public void testLabels() { @Test public void testExemplarSampler() throws Exception { - final Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build(); - final Exemplar exemplar2 = Exemplar.builder().value(6.5).traceId("def").spanId("456").build(); - final Exemplar exemplar3 = Exemplar.builder().value(7.0).traceId("123").spanId("abc").build(); - final Exemplar customExemplar = + Exemplar exemplar1 = Exemplar.builder().value(2.0).traceId("abc").spanId("123").build(); + Exemplar exemplar2 = Exemplar.builder().value(6.5).traceId("def").spanId("456").build(); + Exemplar exemplar3 = Exemplar.builder().value(7.0).traceId("123").spanId("abc").build(); + Exemplar customExemplar = Exemplar.builder() .value(8.0) .traceId("bab") @@ -199,6 +199,36 @@ public void markCurrentSpanAsExemplar() {} assertExemplarEquals(customExemplar, getData(gauge).getExemplar()); } + @Test + void incWithExemplar() { + Gauge gauge = Gauge.builder().name("count").build(); + gauge.incWithExemplar(1.0, Labels.of("test", "test2")); + + assertExemplarEquals( + Exemplar.builder().value(1.0).labels(Labels.of("test", "test2")).build(), + getData(gauge).getExemplar()); + } + + @Test + void dec() { + Gauge gauge = Gauge.builder().name("count").build(); + gauge.decWithExemplar(Labels.of("test", "test2")); + + assertExemplarEquals( + Exemplar.builder().value(-1.0).labels(Labels.of("test", "test2")).build(), + getData(gauge).getExemplar()); + } + + @Test + void decWithExemplar() { + Gauge gauge = Gauge.builder().name("count").build(); + gauge.decWithExemplar(1.0, Labels.of("test", "test2")); + + assertExemplarEquals( + Exemplar.builder().value(-1.0).labels(Labels.of("test", "test2")).build(), + getData(gauge).getExemplar()); + } + @Test public void testExemplarSamplerDisabled() { Gauge gauge = Gauge.builder().name("test").withoutExemplars().build(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index e3b06ecc8..dfdc16be0 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -9,6 +9,7 @@ import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.Unit; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -50,6 +51,11 @@ public void testAddAndRemove() { assertThat(info.collect().getDataPoints()).hasSize(1); info.remove("val2", "val2"); assertThat(info.collect().getDataPoints()).isEmpty(); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> info.addLabelValues("val1", "val2", "extra")) + .withMessage( + "Info test was created with 2 label names, but you called addLabelValues() with 3 label values."); } @Test @@ -67,6 +73,16 @@ public void testSet() throws IOException { assertTextFormat( "target_info{service_instance_id=\"123\",service_name=\"test\",service_version=\"2.0.0\"} 1\n", info); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> info.setLabelValues("2.0.0", "extra")) + .withMessage( + "Info target was created with 1 label names, but you called setLabelValues() with 2 label values."); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> info.remove("2.0.0", "extra")) + .withMessage( + "Info target was created with 1 label names, but you called remove() with 2 label values."); } @Test @@ -80,6 +96,13 @@ public void testConstLabelsOnly() throws IOException { assertTextFormat("target_info{service_instance_id=\"123\",service_name=\"test\"} 1\n", info); } + @Test + void unit() { + assertThatExceptionOfType(UnsupportedOperationException.class) + .isThrownBy(() -> Info.builder().unit(Unit.BYTES).build()) + .withMessage("Info metrics cannot have a unit."); + } + @Test public void testConstLabelsDuplicate1() { assertThatExceptionOfType(IllegalArgumentException.class) diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java index a419e876c..09678874a 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StateSetTest.java @@ -63,6 +63,14 @@ public void testDefaultFalse() { assertThat(getData(stateSet).isTrue(2)).isFalse(); } + @Test + void illegalName() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> StateSet.builder().name("state1").states("state1", "state2").build()) + .withMessage( + "Label name state1 is illegal (can't use the metric name as label name in state set metrics)"); + } + private StateSetSnapshot.StateSetDataPointSnapshot getData(StateSet stateSet, String... labels) { return stateSet.collect().getDataPoints().stream() .filter(d -> d.getLabels().equals(Labels.of(labels))) diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 35a0c24e3..ccc68fc07 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -18,6 +18,8 @@ io.prometheus.metrics.exporter.httpserver + + 0.0 diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index d9ecaaa1c..04790be25 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -19,6 +19,8 @@ io.prometheus.metrics.exporter.opentelemetry + + 0.0 diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java index a8c43e7f9..5f02d38cc 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScope.java @@ -11,28 +11,34 @@ class PrometheusInstrumentationScope { private static final String instrumentationScopeVersionKey = "instrumentationScope.version"; public static InstrumentationScopeInfo loadInstrumentationScopeInfo() { + return loadInstrumentationScopeInfo( + instrumentationScopePropertiesFile, + instrumentationScopeNameKey, + instrumentationScopeVersionKey); + } + + static InstrumentationScopeInfo loadInstrumentationScopeInfo( + String path, String nameKey, String versionKey) { try { Properties properties = new Properties(); properties.load( - PrometheusInstrumentationScope.class - .getClassLoader() - .getResourceAsStream(instrumentationScopePropertiesFile)); - String instrumentationScopeName = properties.getProperty(instrumentationScopeNameKey); + PrometheusInstrumentationScope.class.getClassLoader().getResourceAsStream(path)); + String instrumentationScopeName = properties.getProperty(nameKey); if (instrumentationScopeName == null) { throw new IllegalStateException( "Prometheus metrics library initialization error: " - + instrumentationScopeNameKey + + nameKey + " not found in " - + instrumentationScopePropertiesFile + + path + " in classpath."); } - String instrumentationScopeVersion = properties.getProperty(instrumentationScopeVersionKey); + String instrumentationScopeVersion = properties.getProperty(versionKey); if (instrumentationScopeVersion == null) { throw new IllegalStateException( "Prometheus metrics library initialization error: " - + instrumentationScopeVersionKey + + versionKey + " not found in " - + instrumentationScopePropertiesFile + + path + " in classpath."); } return InstrumentationScopeInfo.builder(instrumentationScopeName) @@ -41,7 +47,7 @@ public static InstrumentationScopeInfo loadInstrumentationScopeInfo() { } catch (Exception e) { throw new IllegalStateException( "Prometheus metrics library initialization error: Failed to read " - + instrumentationScopePropertiesFile + + path + " from classpath.", e); } diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScopeTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScopeTest.java new file mode 100644 index 000000000..e1b97e04d --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusInstrumentationScopeTest.java @@ -0,0 +1,38 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class PrometheusInstrumentationScopeTest { + + @Test + void loadInstrumentationScopeInfo() { + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy( + () -> + PrometheusInstrumentationScope.loadInstrumentationScopeInfo( + "path", "name", "version")) + .withMessage( + "Prometheus metrics library initialization error: Failed to read path from classpath."); + + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy( + () -> + PrometheusInstrumentationScope.loadInstrumentationScopeInfo( + "instrumentationScope.properties", "name", "version")) + .havingRootCause() + .withMessage( + "Prometheus metrics library initialization error: name not found in instrumentationScope.properties in classpath."); + + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy( + () -> + PrometheusInstrumentationScope.loadInstrumentationScopeInfo( + "instrumentationScope.properties", "instrumentationScope.name", "version")) + .havingRootCause() + .withMessage( + "Prometheus metrics library initialization error: version not found in instrumentationScope.properties in classpath."); + } +} diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/SchemeTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/SchemeTest.java new file mode 100644 index 000000000..6695a2911 --- /dev/null +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/SchemeTest.java @@ -0,0 +1,18 @@ +package io.prometheus.metrics.exporter.pushgateway; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import org.junit.jupiter.api.Test; + +class SchemeTest { + + @Test + void fromString() { + assertThat(Scheme.HTTP).hasToString("http"); + assertThat(Scheme.HTTPS).hasToString("https"); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> Scheme.fromString("ftp")) + .withMessage("ftp: Unsupported scheme. Expecting 'http' or 'https'."); + } +} diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index a5e427a89..cdcfd5f0b 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -3,10 +3,26 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_2.Metrics; -import io.prometheus.metrics.model.snapshots.*; +import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.HistogramSnapshot; +import io.prometheus.metrics.model.snapshots.InfoSnapshot; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.StateSetSnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -77,6 +93,17 @@ class ExpositionFormatsTest { .timestampMillis(1690298864383L) .build(); + @Test + void init() { + ExpositionFormats formats = ExpositionFormats.init(); + assertThat(formats.findWriter("application/openmetrics-text")).isNotNull(); + assertThat(formats.findWriter("application/vnd.google.protobuf")).isNotNull(); + assertThat(formats.findWriter("text/plain")).isNotNull(); + assertThat(formats.getOpenMetricsTextFormatWriter()).isNotNull(); + assertThat(formats.getPrometheusProtobufWriter()).isNotNull(); + assertThat(formats.getPrometheusTextFormatWriter()).isNotNull(); + } + @Test public void testCounterComplete() throws IOException { String openMetricsText = diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index bcedc6446..9779c036f 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -18,6 +19,7 @@ io.prometheus.metrics.instrumentation.dropwizard5 + 0.50 diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 19b07a944..304bff254 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -37,7 +37,6 @@ com.google.guava guava - 33.3.1-jre provided diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 767c0fe61..225572b49 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -18,6 +18,7 @@ io.prometheus.metrics.instrumentation.jvm + 0.55 diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java index ab8b0d61d..2bb908a37 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmMetricsTest.java @@ -2,11 +2,19 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; +import java.lang.management.ManagementFactory; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class JvmMetricsTest { + @BeforeEach + void setUp() { + PrometheusRegistry.defaultRegistry.clear(); + } + @Test public void testRegisterIdempotent() { PrometheusRegistry registry = new PrometheusRegistry(); @@ -15,4 +23,18 @@ public void testRegisterIdempotent() { assertThat(registry.scrape().size()).isGreaterThan(0); JvmMetrics.builder().register(registry); } + + @Test + void pool() { + // for coverage + JvmMemoryPoolAllocationMetrics.builder(PrometheusProperties.get()) + .withGarbageCollectorBeans(ManagementFactory.getGarbageCollectorMXBeans()) + .register(); + } + + @Test + void testJvmMetrics() { + JvmMetrics.builder(PrometheusProperties.get()).register(); + JvmMetrics.builder().register(); + } } diff --git a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java index 3bc424985..9e4256d60 100644 --- a/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java +++ b/prometheus-metrics-instrumentation-jvm/src/test/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetricsTest.java @@ -30,6 +30,14 @@ public void testNativeMemoryTrackingFail() throws IOException { assertThat(convertToOpenMetricsFormat(snapshots)).isEqualTo(expected); } + @Test + void nativeMemoryTrackingNotEnabled() { + assertThat( + new JvmNativeMemoryMetrics.DefaultPlatformMBeanServerAdapter() + .vmNativeMemorySummaryInBytes()) + .isEqualTo("Native memory tracking is not enabled\n"); + } + @Test public void testNativeMemoryTrackingEmpty() throws IOException { JvmNativeMemoryMetrics.isEnabled.set(true); diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java index d4f9db699..5cb1604d1 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java @@ -70,7 +70,7 @@ public static boolean isValidMetricName(String name) { * *

      The name is valid if the error message is {@code null}. */ - static String validateMetricName(String name) { + public static String validateMetricName(String name) { for (String reservedSuffix : RESERVED_METRIC_NAME_SUFFIXES) { if (name.endsWith(reservedSuffix)) { return "The metric name must not include the '" + reservedSuffix + "' suffix."; diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/CollectorTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/CollectorTest.java new file mode 100644 index 000000000..65102c17b --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/CollectorTest.java @@ -0,0 +1,29 @@ +package io.prometheus.metrics.model.registry; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import org.junit.jupiter.api.Test; + +class CollectorTest { + + Collector collector = () -> CounterSnapshot.builder().name("counter_a").build(); + + @Test + void predicate() { + PrometheusScrapeRequest request = + new PrometheusScrapeRequest() { + @Override + public String getRequestPath() { + return "/metrics"; + } + + @Override + public String[] getParameterValues(String name) { + return new String[0]; + } + }; + assertThat(collector.collect(name -> false, request)).isNull(); + assertThat(collector.collect(name -> true, request)).isNotNull(); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java index e832e1d13..d39b32436 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ClassicHistogramBucketsTest.java @@ -4,6 +4,8 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; class ClassicHistogramBucketsTest { @@ -113,4 +115,16 @@ public void testImmutable() { iterator.next(); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } + + @Test + public void compare() { + ClassicHistogramBuckets buckets = + ClassicHistogramBuckets.builder() + .bucket(1.0, 7) + .bucket(2.0, 8) + .bucket(Double.POSITIVE_INFINITY, 0) + .build(); + List list = buckets.stream().collect(Collectors.toList()); + assertThat(list.get(0)).isNotEqualByComparingTo(list.get(1)); + } } diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java index ea179641b..b26eaf84a 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/ExemplarsTest.java @@ -52,5 +52,7 @@ public void testGet() { assertThat(middle).isSameAs(result); result = exemplars.get(0.9, Double.POSITIVE_INFINITY); assertThat(newest).isSameAs(result); + + assertThat(exemplars.getLatest()).isSameAs(newest); } } 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 05841c4cc..8867c73e3 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 @@ -5,6 +5,7 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.model.snapshots.HistogramSnapshot.HistogramDataPointSnapshot; +import java.util.Collections; import java.util.Iterator; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; @@ -170,8 +171,13 @@ public void testGoodCaseComplete() { @Test public void testEmptyHistogram() { - HistogramSnapshot snapshot = HistogramSnapshot.builder().name("empty_histogram").build(); + assertThat(HistogramSnapshot.builder().name("empty_histogram").build().getDataPoints()) + .isEmpty(); + HistogramSnapshot snapshot = + new HistogramSnapshot( + new MetricMetadata("empty_bytes", "help", Unit.BYTES), Collections.emptyList()); assertThat(snapshot.getDataPoints()).isEmpty(); + assertThat(snapshot.isGaugeHistogram()).isFalse(); } @Test diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java index 423b57da7..983450181 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/InfoSnapshotTest.java @@ -25,6 +25,13 @@ public void testCompleteGoodCase() { assertThat(snapshot.getDataPoints().size()).isOne(); } + @Test + void create() { + InfoSnapshot.InfoDataPointSnapshot snapshot = + new InfoSnapshot.InfoDataPointSnapshot(Labels.EMPTY); + assertThat(snapshot.getScrapeTimestampMillis()).isZero(); + } + @Test public void testEmptyInfo() { InfoSnapshot snapshot = InfoSnapshot.builder().name("target").build(); diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelTest.java new file mode 100644 index 000000000..386f29f15 --- /dev/null +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelTest.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.model.snapshots; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class LabelTest { + + private static final Label LABEL = new Label("name", "value"); + private static final Label SAME = new Label("name", "value"); + private static final Label LABEL2 = new Label("name", "value2"); + + @Test + void compareTo() { + assertThat(LABEL).isEqualByComparingTo(SAME).isLessThan(LABEL2); + } + + @Test + void testToString() { + assertThat(LABEL).hasToString("Label{name='name', value='value'}"); + } + + @Test + void testEquals() { + assertThat(LABEL).isEqualTo(SAME).isNotEqualTo(LABEL2); + } + + @Test + void testHashCode() { + assertThat(LABEL).hasSameHashCodeAs(SAME).doesNotHaveSameHashCodeAs(LABEL2); + } +} diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java index 25cd6a4ec..581ba6599 100644 --- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java +++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricSnapshotTest.java @@ -9,7 +9,7 @@ class MetricSnapshotTest { @Test public void testDuplicateLabels() { - assertThatExceptionOfType(IllegalArgumentException.class) + assertThatExceptionOfType(DuplicateLabelsException.class) .isThrownBy( () -> CounterSnapshot.builder() @@ -29,7 +29,13 @@ public void testDuplicateLabels() { .labels(Labels.of("status", "200", "path", "/hello")) .value(3.0) .build()) - .build()); + .build()) + .satisfies( + e -> { + assertThat(e.getMetadata().getName()).isEqualTo("events"); + assertThat((Iterable) e.getLabels()) + .isEqualTo(Labels.of("path", "/hello", "status", "200")); + }); } @Test 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 cb3c70f8d..05e102b9d 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 @@ -100,8 +100,13 @@ public void testDataImmutable() { .state("b", true) .state("c", true) .build(); + assertThat(data.iterator().next()) + .usingRecursiveComparison() + .isEqualTo(data.stream().iterator().next()); Iterator iterator = data.iterator(); - iterator.next(); + StateSetSnapshot.State state = iterator.next(); + assertThat(state.getName()).isEqualTo("a"); + assertThat(state.isTrue()).isTrue(); assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(iterator::remove); } @@ -117,6 +122,12 @@ public void testDuplicateState() { .build()); } + @Test + public void noUnit() { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> StateSetSnapshot.builder().name("flags").unit(Unit.BYTES).build()); + } + @Test public void testStateSetImmutable() { StateSetSnapshot snapshot = From 247f1a688da6001d7b58f41eaf2a989ebe4a2f3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:57:39 +0200 Subject: [PATCH 437/980] Bump org.sonatype.central:central-publishing-maven-plugin (#1160) Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.5.0 to 0.6.0. - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits) --- updated-dependencies: - dependency-name: org.sonatype.central:central-publishing-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b84550bf1..d80b89efe 100644 --- a/pom.xml +++ b/pom.xml @@ -456,7 +456,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.5.0 + 0.6.0 true ossrh From f8e61b6a231096c10deed76b45a9c22a836357c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:57:57 +0200 Subject: [PATCH 438/980] Bump org.slf4j:slf4j-simple from 1.7.36 to 2.0.16 (#1161) Bumps org.slf4j:slf4j-simple from 1.7.36 to 2.0.16. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-simple dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d80b89efe..79130011c 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ org.slf4j slf4j-simple - 1.7.36 + 2.0.16 test From 28b40484bcdc8b2bf32b1c1c37e8852f775f31b8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 18 Oct 2024 07:48:58 +0200 Subject: [PATCH 439/980] add coverage check (#1162) Signed-off-by: Gregor Zeitlinger --- CONTRIBUTING.md | 10 +- benchmarks/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 7 +- .../pom.xml | 7 +- .../otelmodel/PrometheusInfo.java | 1 + .../otelmodel/PrometheusMetricData.java | 2 +- .../otelmodel/PrometheusStateSet.java | 1 + .../exporter/opentelemetry/ExportTest.java | 312 ++++++++++++++++++ .../otelmodel/PrometheusMetricDataTest.java | 47 +++ .../model/snapshots/CounterSnapshot.java | 1 + .../model/snapshots/DataPointSnapshot.java | 1 + .../model/snapshots/MetricSnapshot.java | 5 +- 14 files changed, 387 insertions(+), 13 deletions(-) create mode 100644 prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java create mode 100644 prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 79cd4b6ca..3d8c766ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,14 +17,18 @@ This repository uses [Google Java Format](https://github.com/google/google-java- Run `./mvnw spotless:apply` to format the code (only changed files) before committing. -Use `-Dspotless.check.skip=true` to skip the formatting check during development. - ## Running Tests If you're getting errors when running tests: - Make sure that the IDE uses only the "Maven Shade" dependency of "prometheus-metrics-exposition-formats" and the "prometheus-metrics-tracer*" dependencies. - + +### Avoid failures while running tests + +- Use `-Dspotless.check.skip=true` to skip the formatting check during development. +- Use `-Dcoverage.skip=true` to skip the coverage check during development. +- Use `-Dwarnings=-nowarn` to skip the warnings during development. + ## Updating the Protobuf Java Classes Use `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 11e24c3bd..64a929953 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -20,7 +20,7 @@ 1.37 0.16.0 3.0.2 - 0.0 + true diff --git a/examples/pom.xml b/examples/pom.xml index e1fd7ceb4..079ceb982 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -17,7 +17,7 @@ - 0.0 + true diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ad98ba538..ce13424df 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -19,7 +19,7 @@ - 0.0 + true diff --git a/pom.xml b/pom.xml index 79130011c..f7f9dd3fe 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,8 @@ 2.8.0-alpha 8 0.70 + false + -Werror @@ -227,6 +229,7 @@ jacoco-maven-plugin 0.8.12 + ${coverage.skip} **/generated/** @@ -309,8 +312,8 @@ ${java.version} true - -Xlint:all,-serial,-processing - -Werror + -Xlint:all,-serial,-processing,-options + ${warnings} -XDcompilePolicy=simple -Xplugin:ErrorProne diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 04790be25..a603302c7 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -19,8 +19,6 @@ io.prometheus.metrics.exporter.opentelemetry - - 0.0 @@ -96,6 +94,11 @@ 1.7.1-alpha test + + io.opentelemetry + opentelemetry-sdk-testing + test + diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java index 33e4c158d..2a7b8110f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusInfo.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.stream.Collectors; +@SuppressWarnings("this-escape") public class PrometheusInfo extends PrometheusData implements SumData { diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java index 4995b98d6..baca70774 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java @@ -48,7 +48,7 @@ private String getNameWithoutUnit(MetricMetadata metricMetadata) { // See // https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/6cf4dec6cb42d87d8840e9f67d4acf66d4eb8fda/pkg/translator/prometheus/normalize_name.go#L19 - private String convertUnit(Unit unit) { + static String convertUnit(Unit unit) { if (unit == null) { return null; } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java index b0bb39841..10417afc7 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusStateSet.java @@ -16,6 +16,7 @@ public class PrometheusStateSet extends PrometheusData private final List points; + @SuppressWarnings("this-escape") public PrometheusStateSet(StateSetSnapshot snapshot, long currentTimeMillis) { super(MetricDataType.DOUBLE_SUM); this.points = new ArrayList<>(); diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java new file mode 100644 index 000000000..55589ce84 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java @@ -0,0 +1,312 @@ +package io.prometheus.metrics.exporter.opentelemetry; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.metrics.data.MetricData; +import io.opentelemetry.sdk.metrics.export.MetricReader; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.assertj.MetricAssert; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; +import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension; +import io.prometheus.metrics.core.metrics.Counter; +import io.prometheus.metrics.core.metrics.Gauge; +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.core.metrics.Info; +import io.prometheus.metrics.core.metrics.StateSet; +import io.prometheus.metrics.core.metrics.Summary; +import io.prometheus.metrics.model.registry.Collector; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.Unit; +import io.prometheus.metrics.model.snapshots.UnknownSnapshot; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +public class ExportTest { + + private static final Attributes ATTRIBUTES = + Attributes.of(AttributeKey.stringKey("label"), "val", AttributeKey.stringKey("key"), "value"); + @RegisterExtension OpenTelemetryExtension testing = OpenTelemetryExtension.create(); + + private final PrometheusRegistry registry = new PrometheusRegistry(); + + @BeforeEach + void setUp() throws IllegalAccessException, NoSuchFieldException { + Field field = testing.getClass().getDeclaredField("metricReader"); + field.setAccessible(true); + MetricReader reader = (MetricReader) field.get(testing); + + PrometheusMetricProducer prometheusMetricProducer = + new PrometheusMetricProducer( + registry, + InstrumentationScopeInfo.create("test"), + Resource.create(Attributes.builder().put("staticRes", "value").build())); + + reader.register(prometheusMetricProducer); + } + + @Test + void targetInfo() { + Info.builder().name("target").constLabels(Labels.of("res", "value")).register(registry); + Labels scope = Labels.of("otel_scope_name", "scope", "otel_scope_version", "1"); + Info.builder() + .name("otel_scope") + .constLabels(scope.add("scopeKey", "value")) + .register(registry); + Counter counter = Counter.builder().name("name").constLabels(scope).register(registry); + counter.inc(); + metricAssert() + .hasResource( + Resource.create( + Attributes.builder().put("res", "value").put("staticRes", "value").build())) + .hasInstrumentationScope( + InstrumentationScopeInfo.builder("scope") + .setAttributes(Attributes.of(AttributeKey.stringKey("scopeKey"), "value")) + .setVersion("1") + .build()); + } + + @Test + void counter() { + Counter counter = + Counter.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .unit(Unit.BYTES) + .withExemplars() + .register(registry); + counter.labelValues("val").inc(); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasDoubleSumSatisfying( + sum -> + sum.isMonotonic() + .isCumulative() + .hasPointsSatisfying(points -> points.hasValue(1.0).hasAttributes(ATTRIBUTES))); + } + + @Test + void histogram() { + Histogram histogram = + Histogram.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .unit(Unit.BYTES) + .classicOnly() + .classicUpperBounds(1, 2, 3) + .register(registry); + histogram.labelValues("val").observe(1); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasHistogramSatisfying( + hist -> + hist.hasPointsSatisfying( + points -> + points + .hasAttributes(ATTRIBUTES) + .hasCount(1) + .hasSum(1.0) + .satisfies( + p -> { + assertThat(p.getMin()).isNaN(); + assertThat(p.getMax()).isNaN(); + assertThat(p.getStartEpochNanos()).isPositive(); + assertThat(p.getEpochNanos()).isPositive(); + }) + .hasExemplars() + .hasBucketBoundaries(1, 2, 3, Double.POSITIVE_INFINITY) + .hasBucketCounts(1, 0, 0, 0))); + } + + @Test + void exponentialHistogram() { + Histogram histogram = + Histogram.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .unit(Unit.BYTES) + .nativeOnly() + .register(registry); + histogram.labelValues("val").observe(1); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasExponentialHistogramSatisfying( + hist -> + hist.isCumulative() + .hasPointsSatisfying( + points -> + points + .hasAttributes(ATTRIBUTES) + .hasCount(1) + .hasScale(5) + .hasZeroCount(0) + .hasSum(1.0) + .satisfies( + p -> { + assertThat(p.getMin()).isNaN(); + assertThat(p.getMax()).isNaN(); + assertThat(p.getStartEpochNanos()).isPositive(); + assertThat(p.getEpochNanos()).isPositive(); + }) + .hasExemplars() + .hasPositiveBucketsSatisfying( + buckets -> + buckets + .hasOffset(-1) + .hasTotalCount(1) + .hasCounts(Collections.singletonList(1L))))); + } + + @Test + void summary() { + Summary summary = + Summary.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .unit(Unit.BYTES) + .quantile(0.5, 0.1) + .register(registry); + summary.labelValues("val").observe(1); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasSummarySatisfying( + sum -> + sum.hasPointsSatisfying( + points -> + points + .hasAttributes(ATTRIBUTES) + .hasCount(1) + .hasSum(1.0) + .satisfies( + p -> { + assertThat(p.getStartEpochNanos()).isPositive(); + assertThat(p.getEpochNanos()).isPositive(); + }) + .hasValuesSatisfying(values -> values.hasQuantile(0.5).hasValue(1.0)))); + } + + @Test + void gauge() { + Gauge gauge = + Gauge.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .unit(Unit.BYTES) + .register(registry); + gauge.labelValues("val").set(1); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasDoubleGaugeSatisfying( + gaugeData -> + gaugeData.hasPointsSatisfying( + points -> points.hasValue(1.0).hasExemplars().hasAttributes(ATTRIBUTES))); + } + + @Test + void stateSet() { + StateSet stateSet = + StateSet.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .states("state") + .register(registry); + stateSet.labelValues("val").setTrue("state"); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasDoubleSumSatisfying( + sum -> + sum.isNotMonotonic() + .isCumulative() + .hasPointsSatisfying( + points -> + points + .hasValue(1.0) + .hasAttributes( + ATTRIBUTES.toBuilder().put("name", "state").build()))); + } + + @Test + void info() { + Info info = + Info.builder() + .name("name") + .help("help") + .constLabels(Labels.of("key", "value")) + .labelNames("label") + .register(registry); + info.addLabelValues("val"); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasDoubleSumSatisfying( + sum -> + sum.isCumulative() + .isNotMonotonic() + .hasPointsSatisfying(points -> points.hasAttributes(ATTRIBUTES).hasValue(1.0))); + } + + @Test + void unknown() { + Collector collector = + () -> + UnknownSnapshot.builder() + .name("name_bytes") + .help("help") + .unit(Unit.BYTES) + .dataPoint( + UnknownSnapshot.UnknownDataPointSnapshot.builder() + .value(1.0) + .labels(Labels.of("label", "val")) + .build()) + .build(); + registry.register(collector); + metricAssert() + .hasName("name") + .hasDescription("help") + .hasUnit("By") + .hasDoubleGaugeSatisfying( + gaugeData -> + gaugeData.hasPointsSatisfying( + points -> + points + .hasValue(1.0) + .hasExemplars() + .hasAttributes(Attributes.of(AttributeKey.stringKey("label"), "val")))); + } + + private MetricAssert metricAssert() { + List metrics = testing.getMetrics(); + assertThat(metrics).hasSize(1); + return OpenTelemetryAssertions.assertThat(metrics.get(0)); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java new file mode 100644 index 000000000..2c84b1e37 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java @@ -0,0 +1,47 @@ +package io.prometheus.metrics.exporter.opentelemetry.otelmodel; + +import static org.junit.jupiter.api.Assertions.*; + +import com.google.common.collect.ImmutableMap; +import io.prometheus.metrics.model.snapshots.Unit; +import org.junit.jupiter.api.Test; + +class PrometheusMetricDataTest { + + ImmutableMap translations = + ImmutableMap.builder() + .put("days", "d") + .put("hours", "h") + .put("minutes", "min") + .put("seconds", "s") + .put("milliseconds", "ms") + .put("microseconds", "us") + .put("nanoseconds", "ns") + .put("bytes", "By") + .put("kibibytes", "KiBy") + .put("mebibytes", "MiBy") + .put("gibibytes", "GiBy") + .put("tibibytes", "TiBy") + .put("kilobytes", "KBy") + .put("megabytes", "MBy") + .put("gigabytes", "GBy") + .put("terabytes", "TBy") + .put("meters", "m") + .put("volts", "V") + .put("amperes", "A") + .put("joules", "J") + .put("watts", "W") + .put("grams", "g") + .put("celsius", "Cel") + .put("hertz", "Hz") + .put("percent", "%") + .build(); + + @Test + void convertUnit() { + translations.forEach( + (unit, expected) -> { + assertEquals(expected, PrometheusMetricData.convertUnit(new Unit(unit.toString()))); + }); + } +} diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java index 45be6f0f1..c74a68e39 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/CounterSnapshot.java @@ -50,6 +50,7 @@ public CounterDataPointSnapshot( * scrape timestamp is usually set by the Prometheus server during scraping. Exceptions include * mirroring metrics with given timestamps from other metric sources. */ + @SuppressWarnings("this-escape") public CounterDataPointSnapshot( double value, Labels labels, diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java index 47ad4486b..4c2d57e8e 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java @@ -1,5 +1,6 @@ package io.prometheus.metrics.model.snapshots; +@SuppressWarnings("this-escape") public abstract class DataPointSnapshot { private final Labels labels; private final long createdTimestampMillis; diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java index 420feeced..5d4c15461 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricSnapshot.java @@ -23,7 +23,7 @@ protected MetricSnapshot(MetricMetadata metadata, Collection dataPoints) { List dataCopy = new ArrayList<>(dataPoints); dataCopy.sort(Comparator.comparing(DataPointSnapshot::getLabels)); this.dataPoints = Collections.unmodifiableList(dataCopy); - validateLabels(); + validateLabels(this.dataPoints, metadata); } public MetricMetadata getMetadata() { @@ -32,7 +32,8 @@ public MetricMetadata getMetadata() { public abstract List getDataPoints(); - protected void validateLabels() { + private static void validateLabels( + List dataPoints, MetricMetadata metadata) { // Verify that labels are unique (the same set of names/values must not be used multiple times // for the same metric). for (int i = 0; i < dataPoints.size() - 1; i++) { From a2d3b209fc10d570ba50a4eb933c3b987a931322 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 18 Oct 2024 15:16:52 +0200 Subject: [PATCH 440/980] add tests (#1163) * allow java 17 in tests Signed-off-by: Gregor Zeitlinger * allow java 17 in tests Signed-off-by: Gregor Zeitlinger * add coverage Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- .tool-versions | 1 + pom.xml | 4 + .../config/ExemplarsPropertiesTest.java | 12 +-- .../config/ExporterFilterPropertiesTest.java | 3 +- .../ExporterHttpServerPropertiesTest.java | 5 +- .../ExporterOpenTelemetryPropertiesTest.java | 7 +- .../config/ExporterPropertiesTest.java | 9 +- .../ExporterPushgatewayPropertiesTest.java | 5 +- .../pom.xml | 3 +- .../BlockingRejectedExecutionHandler.java | 18 ++++ .../exporter/httpserver/HTTPServer.java | 15 ---- .../exporter/httpserver/HTTPServerTest.java | 86 +++++++++++++++++-- .../httpserver/MetricsHandlerTest.java | 36 ++++++++ .../opentelemetry/OtelAutoConfigTest.java | 23 +++-- .../otelmodel/PrometheusMetricDataTest.java | 58 ++++++------- 15 files changed, 197 insertions(+), 88 deletions(-) create mode 100644 .tool-versions create mode 100644 prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java create mode 100644 prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/MetricsHandlerTest.java diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..cc92f91ec --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +java temurin-17.0.7+7 diff --git a/pom.xml b/pom.xml index f7f9dd3fe..09c999861 100644 --- a/pom.xml +++ b/pom.xml @@ -232,6 +232,7 @@ ${coverage.skip} **/generated/** + **/*BlockingRejectedExecutionHandler* @@ -310,6 +311,9 @@ ${java.version} ${java.version} ${java.version} + 17 + 17 + 17 true -Xlint:all,-serial,-processing,-options diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java index 55be3086e..53f7ae072 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExemplarsPropertiesTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -14,7 +13,7 @@ class ExemplarsPropertiesTest { void load() { ExemplarsProperties properties = load( - ImmutableMap.of( + Map.of( "io.prometheus.exemplars.minRetentionPeriodSeconds", "1", "io.prometheus.exemplars.maxRetentionPeriodSeconds", "2", "io.prometheus.exemplars.sampleIntervalMilliseconds", "3")); @@ -23,20 +22,17 @@ void load() { assertThat(properties.getSampleIntervalMilliseconds()).isEqualTo(3); assertThatExceptionOfType(PrometheusPropertiesException.class) - .isThrownBy( - () -> load(ImmutableMap.of("io.prometheus.exemplars.minRetentionPeriodSeconds", "-1"))) + .isThrownBy(() -> load(Map.of("io.prometheus.exemplars.minRetentionPeriodSeconds", "-1"))) .withMessage( "io.prometheus.exemplars.minRetentionPeriodSeconds: Expecting value > 0. Found: -1"); assertThatExceptionOfType(PrometheusPropertiesException.class) - .isThrownBy( - () -> load(ImmutableMap.of("io.prometheus.exemplars.maxRetentionPeriodSeconds", "0"))) + .isThrownBy(() -> load(Map.of("io.prometheus.exemplars.maxRetentionPeriodSeconds", "0"))) .withMessage( "io.prometheus.exemplars.maxRetentionPeriodSeconds: Expecting value > 0. Found: 0"); assertThatExceptionOfType(PrometheusPropertiesException.class) - .isThrownBy( - () -> load(ImmutableMap.of("io.prometheus.exemplars.sampleIntervalMilliseconds", "-1"))) + .isThrownBy(() -> load(Map.of("io.prometheus.exemplars.sampleIntervalMilliseconds", "-1"))) .withMessage( "io.prometheus.exemplars.sampleIntervalMilliseconds: Expecting value > 0. Found: -1"); } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java index 273b058a7..0b30fbd43 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterFilterPropertiesTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -13,7 +12,7 @@ class ExporterFilterPropertiesTest { void load() { ExporterFilterProperties properties = load( - ImmutableMap.of( + Map.of( "io.prometheus.exporter.filter.metricNameMustBeEqualTo", "a,b,c", "io.prometheus.exporter.filter.metricNameMustNotBeEqualTo", "d,e,f", "io.prometheus.exporter.filter.metricNameMustStartWith", "g,h,i", diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java index 5da84fed2..07b00a2a4 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterHttpServerPropertiesTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -12,11 +11,11 @@ class ExporterHttpServerPropertiesTest { @Test void load() { ExporterHttpServerProperties properties = - load(ImmutableMap.of("io.prometheus.exporter.httpServer.port", "1")); + load(Map.of("io.prometheus.exporter.httpServer.port", "1")); assertThat(properties.getPort()).isOne(); assertThatExceptionOfType(PrometheusPropertiesException.class) - .isThrownBy(() -> load(ImmutableMap.of("io.prometheus.exporter.httpServer.port", "0"))) + .isThrownBy(() -> load(Map.of("io.prometheus.exporter.httpServer.port", "0"))) .withMessage("io.prometheus.exporter.httpServer.port: Expecting value > 0. Found: 0"); } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java index b6a67c3c1..7ba275570 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterOpenTelemetryPropertiesTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -13,7 +12,7 @@ class ExporterOpenTelemetryPropertiesTest { void load() { ExporterOpenTelemetryProperties properties = load( - ImmutableMap.of( + Map.of( "io.prometheus.exporter.opentelemetry.protocol", "grpc", "io.prometheus.exporter.opentelemetry.endpoint", "http://localhost:8080", "io.prometheus.exporter.opentelemetry.headers", "key1=value1,key2=value2", @@ -33,7 +32,7 @@ private static void assertValues(ExporterOpenTelemetryProperties properties) { assertThat(properties.getProtocol()).isEqualTo("grpc"); assertThat(properties.getEndpoint()).isEqualTo("http://localhost:8080"); assertThat(properties.getHeaders()) - .containsExactlyInAnyOrderEntriesOf(ImmutableMap.of("key1", "value1", "key2", "value2")); + .containsExactlyInAnyOrderEntriesOf(Map.of("key1", "value1", "key2", "value2")); assertThat(properties.getInterval()).isEqualTo("10s"); assertThat(properties.getTimeout()).isEqualTo("5s"); assertThat(properties.getServiceName()).isEqualTo("serviceName"); @@ -41,7 +40,7 @@ private static void assertValues(ExporterOpenTelemetryProperties properties) { assertThat(properties.getServiceInstanceId()).isEqualTo("serviceInstanceId"); assertThat(properties.getServiceVersion()).isEqualTo("serviceVersion"); assertThat(properties.getResourceAttributes()) - .containsExactlyInAnyOrderEntriesOf(ImmutableMap.of("key1", "value1", "key2", "value2")); + .containsExactlyInAnyOrderEntriesOf(Map.of("key1", "value1", "key2", "value2")); } private static ExporterOpenTelemetryProperties load(Map map) { diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java index 8da66da11..c09bc12c3 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -15,7 +14,7 @@ void load() { ExporterProperties properties = load( new HashMap<>( - ImmutableMap.of( + Map.of( "io.prometheus.exporter.includeCreatedTimestamps", "true", "io.prometheus.exporter.exemplarsOnAllMetricTypes", "true"))); assertThat(properties.getIncludeCreatedTimestamps()).isTrue(); @@ -26,8 +25,7 @@ void load() { () -> load( new HashMap<>( - ImmutableMap.of( - "io.prometheus.exporter.includeCreatedTimestamps", "invalid")))) + Map.of("io.prometheus.exporter.includeCreatedTimestamps", "invalid")))) .withMessage( "io.prometheus.exporter.includeCreatedTimestamps: Expecting 'true' or 'false'. Found: invalid"); assertThatExceptionOfType(PrometheusPropertiesException.class) @@ -35,8 +33,7 @@ void load() { () -> load( new HashMap<>( - ImmutableMap.of( - "io.prometheus.exporter.exemplarsOnAllMetricTypes", "invalid")))) + Map.of("io.prometheus.exporter.exemplarsOnAllMetricTypes", "invalid")))) .withMessage( "io.prometheus.exporter.exemplarsOnAllMetricTypes: Expecting 'true' or 'false'. Found: invalid"); } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java index d5600e770..9e0ed0dbf 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPushgatewayPropertiesTest.java @@ -3,7 +3,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import com.google.common.collect.ImmutableMap; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -14,7 +13,7 @@ class ExporterPushgatewayPropertiesTest { void load() { ExporterPushgatewayProperties properties = load( - ImmutableMap.of( + Map.of( "io.prometheus.exporter.pushgateway.address", "http://localhost", "io.prometheus.exporter.pushgateway.job", "job", "io.prometheus.exporter.pushgateway.scheme", "http")); @@ -24,7 +23,7 @@ void load() { assertThat(properties.getScheme()).isEqualTo("http"); assertThatExceptionOfType(PrometheusPropertiesException.class) - .isThrownBy(() -> load(ImmutableMap.of("io.prometheus.exporter.pushgateway.scheme", "foo"))) + .isThrownBy(() -> load(Map.of("io.prometheus.exporter.pushgateway.scheme", "foo"))) .withMessage( "io.prometheus.exporter.pushgateway.scheme: Illegal value. Expecting 'http' or 'https'. Found: foo"); } diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index ccc68fc07..174022d9d 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -18,8 +18,7 @@ io.prometheus.metrics.exporter.httpserver - - 0.0 + 0.45 diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java new file mode 100644 index 000000000..023d3f2f0 --- /dev/null +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/BlockingRejectedExecutionHandler.java @@ -0,0 +1,18 @@ +package io.prometheus.metrics.exporter.httpserver; + +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; + +class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { + if (!threadPoolExecutor.isShutdown()) { + try { + threadPoolExecutor.getQueue().put(runnable); + } catch (InterruptedException ignored) { + // ignore + } + } + } +} diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 46c719bc1..5702a0b21 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -18,7 +18,6 @@ import java.security.PrivilegedExceptionAction; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -317,18 +316,4 @@ private void assertNull(Object o, String msg) { } } } - - private static class BlockingRejectedExecutionHandler implements RejectedExecutionHandler { - - @Override - public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) { - if (!threadPoolExecutor.isShutdown()) { - try { - threadPoolExecutor.getQueue().put(runnable); - } catch (InterruptedException ignored) { - // ignore - } - } - } - } } diff --git a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java index ccc99bd01..06ab75b24 100644 --- a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java +++ b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/HTTPServerTest.java @@ -1,23 +1,33 @@ package io.prometheus.metrics.exporter.httpserver; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import com.sun.net.httpserver.Authenticator; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpPrincipal; +import com.sun.net.httpserver.HttpsConfigurator; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import io.prometheus.metrics.model.registry.PrometheusScrapeRequest; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.security.AccessController; +import java.security.NoSuchAlgorithmException; import java.security.Principal; +import java.util.concurrent.Executors; +import javax.net.ssl.SSLContext; import javax.security.auth.Subject; import org.junit.jupiter.api.Test; public class HTTPServerTest { @Test + @SuppressWarnings({"removal"}) public void testSubjectDoAs() throws Exception { final String user = "joe"; @@ -56,11 +66,16 @@ public Result authenticate(HttpExchange exchange) { .authenticatedSubjectAttributeName("aa") .buildAndStart(); - Socket socket = new Socket(); - try { + run(server, "204", "/"); + } + + private static void run(HTTPServer server, String expected, String path) throws IOException { + try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress("localhost", server.getPort())); - socket.getOutputStream().write("GET / HTTP/1.1 \r\n".getBytes(StandardCharsets.UTF_8)); + socket + .getOutputStream() + .write(("GET " + path + " HTTP/1.1 \r\n").getBytes(StandardCharsets.UTF_8)); socket.getOutputStream().write("HOST: localhost \r\n\r\n".getBytes(StandardCharsets.UTF_8)); socket.getOutputStream().flush(); @@ -70,10 +85,67 @@ public Result authenticate(HttpExchange exchange) { if (read > 0) { actualResponse = new String(resp, 0, read, StandardCharsets.UTF_8); } - assertThat(actualResponse).contains("204"); - - } finally { - socket.close(); + assertThat(actualResponse).contains(expected); } } + + @Test + void defaultHandler() throws IOException { + run(HTTPServer.builder().port(0).buildAndStart(), "200", "/"); + } + + @Test + void metrics() throws IOException { + run( + HTTPServer.builder() + .port(0) + .registry(new PrometheusRegistry()) + .executorService(Executors.newFixedThreadPool(1)) + .buildAndStart(), + "200", + "/metrics"); + } + + @Test + void registryThrows() throws IOException { + HTTPServer server = + HTTPServer.builder() + .port(0) + .registry( + new PrometheusRegistry() { + @Override + public MetricSnapshots scrape(PrometheusScrapeRequest scrapeRequest) { + throw new IllegalStateException("test"); + } + }) + .buildAndStart(); + run(server, "500", "/metrics"); + } + + @Test + void config() throws NoSuchAlgorithmException, IOException { + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy( + () -> + HTTPServer.builder() + .port(0) + .hostname("localhost") + .inetAddress(InetAddress.getByName("localhost")) + .buildAndStart()) + .withMessage("cannot configure 'inetAddress' and 'hostname' at the same time"); + + // ssl doesn't work without in tests + run( + HTTPServer.builder() + .port(0) + .httpsConfigurator(new HttpsConfigurator(SSLContext.getDefault())) + .buildAndStart(), + "", + "/"); + } + + @Test + void health() throws IOException { + run(HTTPServer.builder().port(0).buildAndStart(), "200", "/-/healthy"); + } } diff --git a/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/MetricsHandlerTest.java b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/MetricsHandlerTest.java new file mode 100644 index 000000000..703223861 --- /dev/null +++ b/prometheus-metrics-exporter-httpserver/src/test/java/io/prometheus/metrics/exporter/httpserver/MetricsHandlerTest.java @@ -0,0 +1,36 @@ +package io.prometheus.metrics.exporter.httpserver; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.RETURNS_MOCKS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import io.prometheus.metrics.config.PrometheusProperties; +import io.prometheus.metrics.model.registry.PrometheusRegistry; +import org.junit.jupiter.api.Test; + +class MetricsHandlerTest { + + @Test + void ctor() { + assertThat(new MetricsHandler()) + .extracting("prometheusScrapeHandler") + .extracting("registry") + .isEqualTo(PrometheusRegistry.defaultRegistry); + + PrometheusRegistry registry = new PrometheusRegistry(); + assertThat(new MetricsHandler(registry)) + .extracting("prometheusScrapeHandler") + .extracting("registry") + .isEqualTo(registry); + + PrometheusProperties properties = mock(PrometheusProperties.class, RETURNS_MOCKS); + + assertThat(new MetricsHandler(properties)) + .extracting("prometheusScrapeHandler") + .extracting("registry") + .isEqualTo(PrometheusRegistry.defaultRegistry); + + verify(properties).getExporterProperties(); + } +} diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java index 9b9b12420..5a9103565 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/OtelAutoConfigTest.java @@ -65,16 +65,21 @@ public static Stream testCases() { "values from builder", new TestCase() .expectedProperties( - ImmutableMap.>builder() - .put("otel.exporter.otlp.protocol", Optional.of("http/protobuf")) - .put("otel.exporter.otlp.endpoint", Optional.of("http://builder:4318")) - .put("otel.exporter.otlp.headers", Optional.of("h=builder-v")) - .put("otel.metric.export.interval", Optional.of("2s")) - .put("otel.exporter.otlp.timeout", Optional.of("3s")) - .put("otel.service.name", Optional.of("builder-service")) - .build()) + Map.of( + "otel.exporter.otlp.protocol", + Optional.of("http/protobuf"), + "otel.exporter.otlp.endpoint", + Optional.of("http://builder:4318"), + "otel.exporter.otlp.headers", + Optional.of("h=builder-v"), + "otel.metric.export.interval", + Optional.of("2s"), + "otel.exporter.otlp.timeout", + Optional.of("3s"), + "otel.service.name", + Optional.of("builder-service"))) .expectedResourceAttributes( - ImmutableMap.of( + Map.of( "key", "builder-value", "service.name", diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java index 2c84b1e37..fb5542538 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricDataTest.java @@ -1,41 +1,41 @@ package io.prometheus.metrics.exporter.opentelemetry.otelmodel; +import static java.util.Map.entry; import static org.junit.jupiter.api.Assertions.*; -import com.google.common.collect.ImmutableMap; import io.prometheus.metrics.model.snapshots.Unit; +import java.util.Map; import org.junit.jupiter.api.Test; class PrometheusMetricDataTest { - ImmutableMap translations = - ImmutableMap.builder() - .put("days", "d") - .put("hours", "h") - .put("minutes", "min") - .put("seconds", "s") - .put("milliseconds", "ms") - .put("microseconds", "us") - .put("nanoseconds", "ns") - .put("bytes", "By") - .put("kibibytes", "KiBy") - .put("mebibytes", "MiBy") - .put("gibibytes", "GiBy") - .put("tibibytes", "TiBy") - .put("kilobytes", "KBy") - .put("megabytes", "MBy") - .put("gigabytes", "GBy") - .put("terabytes", "TBy") - .put("meters", "m") - .put("volts", "V") - .put("amperes", "A") - .put("joules", "J") - .put("watts", "W") - .put("grams", "g") - .put("celsius", "Cel") - .put("hertz", "Hz") - .put("percent", "%") - .build(); + Map translations = + Map.ofEntries( + entry("days", "d"), + entry("hours", "h"), + entry("minutes", "min"), + entry("seconds", "s"), + entry("milliseconds", "ms"), + entry("microseconds", "us"), + entry("nanoseconds", "ns"), + entry("bytes", "By"), + entry("kibibytes", "KiBy"), + entry("mebibytes", "MiBy"), + entry("gibibytes", "GiBy"), + entry("tibibytes", "TiBy"), + entry("kilobytes", "KBy"), + entry("megabytes", "MBy"), + entry("gigabytes", "GBy"), + entry("terabytes", "TBy"), + entry("meters", "m"), + entry("volts", "V"), + entry("amperes", "A"), + entry("joules", "J"), + entry("watts", "W"), + entry("grams", "g"), + entry("celsius", "Cel"), + entry("hertz", "Hz"), + entry("percent", "%")); @Test void convertUnit() { From 21bcfacc3c178e3b9abfe19788035b06ec7134b1 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 19 Oct 2024 10:02:42 +0200 Subject: [PATCH 441/980] release (#1166) Signed-off-by: Gregor Zeitlinger --- .github/workflows/release.yml | 9 ++------- RELEASING.md | 4 ++++ benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 2 +- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/pom.xml | 2 +- otel-agent-resources/pom.xml | 2 +- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-instrumentation-caffeine/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-guava/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 45 files changed, 49 insertions(+), 50 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f637bc517..be3f8ca80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,14 +1,9 @@ name: Deploy to Maven Central -#on: -# push: -# tags: -# - v* on: push: - branches: [ "main" ] -# pull_request: -# branches: [ "main" ] + tags: + - "v*.*.*" jobs: deploy: diff --git a/RELEASING.md b/RELEASING.md index c7b195c8b..241717ee2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -17,6 +17,10 @@ git tag -a v -m "Release v" git push origin v ``` +This will trigger the release workflow which will deploy the release to Maven Central. + +Go to https://central.sonatype.com/publishing/deployments to publish the release to Maven Central. + ## Create a Release 1. Go to https://github.com/prometheus/client_java/releases diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 64a929953..4d6a198da 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index bb152565a..b12c21f0f 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 0.0.1-releasetest1 + 1.3.2 example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 0a62eee13..1c3957525 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 0.0.1-releasetest1 + 1.3.2 example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 85cecfeb2..0e03d4c33 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 97a53e64c..0a200658a 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 23ee8b63c..b433db6e2 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index a1cd6c28f..9c8b0f12e 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 520141b58..8803acde8 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index ed97c5e46..8079b9076 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index ad68ab386..4dc3739b7 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index e80429b30..42f53b2bd 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 0.0.1-releasetest1 + 1.3.2 example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 079ceb982..17dbe3611 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index ecf5f9cb2..e3d2b9151 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 0.0.1-releasetest1 + 1.3.2 it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 16aa565e4..14afd612e 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 0.0.1-releasetest1 + 1.3.2 it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index 105f43f90..3cfaac277 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 0.0.1-releasetest1 + 1.3.2 it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 15c8e89e3..9212326f0 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 0.0.1-releasetest1 + 1.3.2 it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 8b7465d52..46a26be73 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 0.0.1-releasetest1 + 1.3.2 it-exporter-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index cd143e911..34a554a73 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 0.0.1-releasetest1 + 1.3.2 it-exporter diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 95ef595bd..4b4351c1a 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 0.0.1-releasetest1 + 1.3.2 it-pushgateway diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ce13424df..c07d02a00 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 integration-tests diff --git a/otel-agent-resources/pom.xml b/otel-agent-resources/pom.xml index b18153b7c..ba9816174 100644 --- a/otel-agent-resources/pom.xml +++ b/otel-agent-resources/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 otel-agent-resources diff --git a/pom.xml b/pom.xml index 09c999861..6a0dc9b6d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 Prometheus Metrics Library http://github.com/prometheus/client_java diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index b175c9cb1..97b8ac913 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 2a77f617e..ede7a64a7 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 4da7c366e..1485a46be 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index c4269458c..383913530 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 174022d9d..9e210993f 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index a603302c7..be437370b 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 889089997..734bd8446 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 7cc114f8f..a46ef36da 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index 2877f0518..963655da3 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 3abc67b96..014b69aa8 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index d8fe77578..6e91f54f5 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-instrumentation-caffeine diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index 9779c036f..6c9f64dd5 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 304bff254..f227c571f 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-instrumentation-guava diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 225572b49..b1f19fe0e 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 7d8c0c960..a85464083 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-model diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index c5fd6089b..4bc85f723 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 953b09dc5..e3f34fb6a 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index f16f47f4b..dcfef35f2 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 51066bd41..e63cc5eac 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 85c0a8d8e..da8ae734d 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 83788e746..86fc0312f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 0.0.1-releasetest1 + 1.3.2 prometheus-metrics-tracer-otel From 333a77d8a054d65b062f3a45793d8568babfc465 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:18:42 -0400 Subject: [PATCH 442/980] Bump junit-jupiter.version from 5.11.2 to 5.11.3 (#1171) Bumps `junit-jupiter.version` from 5.11.2 to 5.11.3. Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.2 to 5.11.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3) Updates `org.junit.jupiter:junit-jupiter-params` from 5.11.2 to 5.11.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3) --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:development update-type: version-update:semver-patch - dependency-name: org.junit.jupiter:junit-jupiter-params dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6a0dc9b6d..a62390e97 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 --module-name-need-to-be-overriden-- - 5.11.2 + 5.11.3 2.8.0-alpha 8 0.70 From 5d8967c085d02c6c08a36d412eee5f813be6d230 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:19:03 -0400 Subject: [PATCH 443/980] Bump org.apache.maven.plugins:maven-site-plugin from 3.20.0 to 3.21.0 (#1170) Bumps [org.apache.maven.plugins:maven-site-plugin](https://github.com/apache/maven-site-plugin) from 3.20.0 to 3.21.0. - [Release notes](https://github.com/apache/maven-site-plugin/releases) - [Commits](https://github.com/apache/maven-site-plugin/compare/maven-site-plugin-3.20.0...maven-site-plugin-3.21.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-site-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a62390e97..a71b37d64 100644 --- a/pom.xml +++ b/pom.xml @@ -168,7 +168,7 @@ maven-site-plugin - 3.20.0 + 3.21.0 From 451acb4d4b17389d9c68199b34a338d219384c77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:19:15 -0400 Subject: [PATCH 444/980] Bump org.apache.maven.plugins:maven-project-info-reports-plugin (#1169) Bumps [org.apache.maven.plugins:maven-project-info-reports-plugin](https://github.com/apache/maven-project-info-reports-plugin) from 3.7.0 to 3.8.0. - [Commits](https://github.com/apache/maven-project-info-reports-plugin/compare/maven-project-info-reports-plugin-3.7.0...maven-project-info-reports-plugin-3.8.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-project-info-reports-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a71b37d64..057064285 100644 --- a/pom.xml +++ b/pom.xml @@ -358,7 +358,7 @@ maven-project-info-reports-plugin - 3.7.0 + 3.8.0 maven-javadoc-plugin From e279fc11817e4b5bc1720b11c7b9d1a36e93d43f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:24:20 -0400 Subject: [PATCH 445/980] Bump com.google.errorprone:error_prone_core from 2.33.0 to 2.35.1 (#1176) Bumps [com.google.errorprone:error_prone_core](https://github.com/google/error-prone) from 2.33.0 to 2.35.1. - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.33.0...v2.35.1) --- updated-dependencies: - dependency-name: com.google.errorprone:error_prone_core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Doug Hoard --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 057064285..f7476cbc3 100644 --- a/pom.xml +++ b/pom.xml @@ -332,7 +332,7 @@ com.google.errorprone error_prone_core - 2.33.0 + 2.35.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 9b58c9707..803fcb1e3 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -57,7 +57,7 @@ - io.prometheus.metrics.examples.otel_exemplars.greeting.Main + io.prometheus.metrics.examples.otel.exemplars.greeting.Main diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/GreetingServlet.java similarity index 95% rename from examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java rename to examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/GreetingServlet.java index a2b16f5f5..8b80268df 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/GreetingServlet.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.examples.otel_exemplars.greeting; +package io.prometheus.metrics.examples.otel.exemplars.greeting; import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/Main.java similarity index 93% rename from examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java rename to examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/Main.java index c0cf09830..99ba1084c 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel/exemplars/greeting/Main.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.examples.otel_exemplars.greeting; +package io.prometheus.metrics.examples.otel.exemplars.greeting; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index deb15f4fe..e89809ff8 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -57,7 +57,7 @@ - io.prometheus.metrics.examples.otel_exemplars.app.Main + io.prometheus.metrics.examples.otel.exemplars.app.Main diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/HelloWorldServlet.java similarity index 97% rename from examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java rename to examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/HelloWorldServlet.java index 988f63819..b770c29fb 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/HelloWorldServlet.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.examples.otel_exemplars.app; +package io.prometheus.metrics.examples.otel.exemplars.app; import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds; import static java.net.http.HttpResponse.BodyHandlers.ofString; diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/Main.java similarity index 94% rename from examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java rename to examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/Main.java index dc58256cb..25ea8a1c6 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel/exemplars/app/Main.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.examples.otel_exemplars.app; +package io.prometheus.metrics.examples.otel.exemplars.app; import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; import io.prometheus.metrics.instrumentation.jvm.JvmMetrics; diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java index 7a2715647..b2aa8950f 100644 --- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java +++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java @@ -59,7 +59,8 @@ public static void main(String[] args) throws Exception { histogram.labelValues("200").observe(random.nextGaussian()); } - // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry + // Explicitly use a classic-only histogram to have an example of a classic + // histogram in OpenTelemetry Histogram classicHistogram = Histogram.newBuilder() .withName("request_size_bytes") .withHelp("Request size in Bytes") diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index 4c665dd81..8490cd64e 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -26,7 +26,10 @@ public static void main(String[] args) throws IOException, InterruptedException int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); + run(mode, port); + } + private static void run(Mode mode, int port) throws IOException, InterruptedException { Counter counter = Counter.builder() .name("uptime_seconds_total") diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java index 8c899b4ad..c694eda02 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java @@ -29,7 +29,10 @@ public static void main(String[] args) throws Exception { int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); + run(mode, port); + } + private static void run(Mode mode, int port) throws Exception { Counter counter = Counter.builder() .name("uptime_seconds_total") diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java index ead2ee88f..fa470b306 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java @@ -32,7 +32,10 @@ public static void main(String[] args) throws LifecycleException, IOException { int port = parsePortOrExit(args[0]); Mode mode = parseModeOrExit(args[1]); + run(mode, port); + } + private static void run(Mode mode, int port) throws IOException, LifecycleException { Counter counter = Counter.builder() .name("uptime_seconds_total") diff --git a/pom.xml b/pom.xml index 37f1fdbfe..dfc5a427e 100644 --- a/pom.xml +++ b/pom.xml @@ -21,6 +21,7 @@ 2.9.0-alpha 8 0.70 + false false -Werror @@ -224,6 +225,28 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.5.0 + + true + google_checks.xml + checkstyle.xml + warning + true + ${checkstyle.skip} + checkstyle-suppressions.xml + **/generated/**,**/jmh_generated/* + + + + + check + + + + org.jacoco jacoco-maven-plugin diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java index 61b458ba8..bf13b5214 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/datapoints/StateSetDataPoint.java @@ -14,12 +14,6 @@ public interface StateSetDataPoint extends DataPoint { */ void setTrue(String state); - /** - * {@code state} must be one of the states from when the {@code StateSet} was created with {@link - * io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. - */ - void setFalse(String state); - /** * {@code state} must be one of the states from when the {@code StateSet} was created with {@link * io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. @@ -28,6 +22,12 @@ default void setTrue(Enum state) { setTrue(state.toString()); } + /** + * {@code state} must be one of the states from when the {@code StateSet} was created with {@link + * io.prometheus.metrics.core.metrics.StateSet.Builder#states(String...)}. + */ + void setFalse(String state); + /** * {@code state} must be one of the states from when the {@code StateSet} was created with {@link * io.prometheus.metrics.core.metrics.StateSet.Builder#states(Class)}. diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java index 0e1c49f8c..15b0355cd 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/exemplars/ExemplarSampler.java @@ -130,6 +130,16 @@ private long doObserveSingleExemplar(double value) { return 0; } + private long doObserveSingleExemplar(double amount, Labels labels) { + long now = System.currentTimeMillis(); + Exemplar current = customExemplars[0]; + if (current == null + || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { + return updateCustomExemplar(0, amount, labels, now); + } + return 0; + } + private long doObserveWithUpperBounds(double value) { long now = System.currentTimeMillis(); double[] upperBounds = config.getHistogramClassicUpperBounds(); @@ -212,16 +222,6 @@ private long doObserveWithExemplar(double amount, Labels labels) { } } - private long doObserveSingleExemplar(double amount, Labels labels) { - long now = System.currentTimeMillis(); - Exemplar current = customExemplars[0]; - if (current == null - || now - current.getTimestampMillis() > config.getMinRetentionPeriodMillis()) { - return updateCustomExemplar(0, amount, labels, now); - } - return 0; - } - private long doObserveWithExemplarWithUpperBounds(double value, Labels labels) { long now = System.currentTimeMillis(); double[] upperBounds = config.getHistogramClassicUpperBounds(); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java index 9fc1e9634..74ce18e72 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CKMSQuantiles.java @@ -26,6 +26,8 @@ import java.util.LinkedList; import java.util.ListIterator; +// CHECKSTYLE:OFF: checkstyle + /** * Algorithm solving the "Targeted Quantile Problem" as described in "Effective Computation of * Biased Quantiles over Data Streams" by Cormode, Korn, Muthukrishnan, and Srivastava. @@ -273,3 +275,5 @@ public String toString() { } } } + +// CHECKSTYLE:ON: checkstyle diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java index cf25e6527..2afaffae7 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CallbackMetric.java @@ -28,7 +28,8 @@ protected Labels makeLabels(String... labelValues) { if (labelValues == null) { throw new IllegalArgumentException( this.getClass().getSimpleName() - + " was created with label names, but the callback was called without label values."); + + " was created with label names, " + + "but the callback was called without label values."); } if (labelValues.length != labelNames.length) { throw new IllegalArgumentException( diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java index 2e84b6ade..8ed9b0001 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Counter.java @@ -82,6 +82,15 @@ public CounterSnapshot collect() { return (CounterSnapshot) super.collect(); } + @Override + protected CounterSnapshot collect(List labels, List metricData) { + List data = new ArrayList<>(labels.size()); + for (int i = 0; i < labels.size(); i++) { + data.add(metricData.get(i).collect(labels.get(i))); + } + return new CounterSnapshot(getMetadata(), data); + } + @Override protected boolean isExemplarsEnabled() { return exemplarsEnabled; @@ -96,15 +105,6 @@ protected DataPoint newDataPoint() { } } - @Override - protected CounterSnapshot collect(List labels, List metricData) { - List data = new ArrayList<>(labels.size()); - for (int i = 0; i < labels.size(); i++) { - data.add(metricData.get(i).collect(labels.get(i))); - } - return new CounterSnapshot(getMetadata(), data); - } - static String stripTotalSuffix(String name) { if (name != null && (name.endsWith("_total") || name.endsWith(".total"))) { name = name.substring(0, name.length() - 6); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java index 5dc533d58..f8c1b162c 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/CounterWithCallback.java @@ -15,7 +15,7 @@ * * CounterWithCallback.builder() * .name("classes_loaded_total") - * .help("The total number of classes that have been loaded since the JVM has started execution") + * .help("The total number of classes since the JVM has started execution") * .callback(callback -> callback.call(classLoadingMXBean.getLoadedClassCount())) * .register(); * }

      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index bf70bec7c..8f76819f1 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -63,7 +63,7 @@ public class Histogram extends StatefulMetric max ? min : max; + max == Builder.DEFAULT_NATIVE_MAX_ZERO_THRESHOLD && min > max ? min : max; nativeMinZeroThreshold = Math.min(min, nativeMaxZeroThreshold); nativeMaxBuckets = getConfigProperty(properties, MetricsProperties::getHistogramNativeMaxNumberOfBuckets); @@ -447,9 +447,9 @@ private void maybeScaleDown(AtomicBoolean wasReset) { // Now we are in the synchronized block while new observations go into the buffer. // Check again if we need to limit the bucket size, because another thread might // have limited it in the meantime. - int nBuckets = + int numBuckets = nativeBucketsForPositiveValues.size() + nativeBucketsForNegativeValues.size(); - if (nBuckets <= nativeMaxBuckets || nativeSchema == -4) { + if (numBuckets <= nativeMaxBuckets || nativeSchema == -4) { return null; } if (maybeReset()) { @@ -668,11 +668,11 @@ public static class Builder extends StatefulMetric.Builder labels, List metricDataList) { List data = new ArrayList<>(labels.size()); @@ -97,6 +87,16 @@ protected StateSetSnapshot collect(List labels, List metricDa return new StateSetSnapshot(getMetadata(), data); } + @Override + public void setTrue(String state) { + getNoLabels().setTrue(state); + } + + @Override + public void setFalse(String state) { + getNoLabels().setFalse(state); + } + @Override protected DataPoint newDataPoint() { return new DataPoint(); diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index 5a838c649..d7fb3afd0 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -105,7 +105,8 @@ public D labelValues(String... labelValues) { getClass().getSimpleName() + " " + getMetadata().getName() - + " was created with label names, so you must call labelValues(...) when using it."); + + " was created with label names, so you must call labelValues(...)" + + " when using it."); } else { throw new IllegalArgumentException( "Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index dee7098fb..f871addfd 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -46,7 +46,6 @@ public PrometheusScrapeHandler(PrometheusProperties config, PrometheusRegistry r public void handleRequest(PrometheusHttpExchange exchange) throws IOException { try { PrometheusHttpRequest request = exchange.getRequest(); - PrometheusHttpResponse response = exchange.getResponse(); MetricSnapshots snapshots = scrape(request); if (writeDebugResponse(snapshots, exchange)) { return; @@ -57,6 +56,7 @@ public void handleRequest(PrometheusHttpExchange exchange) throws IOException { ExpositionFormatWriter writer = expositionFormats.findWriter(acceptHeader); writer.write(responseBuffer, snapshots); lastResponseSize.set(responseBuffer.size()); + PrometheusHttpResponse response = exchange.getResponse(); response.setHeader("Content-Type", writer.getContentType()); if (shouldUseCompression(request)) { @@ -106,16 +106,6 @@ private Predicate makeNameFilter(ExporterFilterProperties props) { } } - private MetricSnapshots scrape(PrometheusHttpRequest request) { - - Predicate filter = makeNameFilter(request.getParameterValues("name[]")); - if (filter != null) { - return registry.scrape(filter, request); - } else { - return registry.scrape(request); - } - } - private Predicate makeNameFilter(String[] includedNames) { Predicate result = null; if (includedNames != null && includedNames.length > 0) { @@ -129,6 +119,16 @@ private Predicate makeNameFilter(String[] includedNames) { return result; } + private MetricSnapshots scrape(PrometheusHttpRequest request) { + + Predicate filter = makeNameFilter(request.getParameterValues("name[]")); + if (filter != null) { + return registry.scrape(filter, request); + } else { + return registry.scrape(request); + } + } + private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExchange exchange) throws IOException { String debugParam = exchange.getRequest().getParameter("debug"); @@ -157,7 +157,8 @@ private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExch body.write( ("debug=" + debugParam - + ": Unsupported query parameter. Valid values are 'openmetrics', 'text', and 'prometheus-protobuf'.") + + ": Unsupported query parameter. Valid values are 'openmetrics', " + + "'text', and 'prometheus-protobuf'.") .getBytes(StandardCharsets.UTF_8)); break; } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java index eeb2f70f6..506da12bc 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/DefaultHandler.java @@ -21,15 +21,19 @@ public DefaultHandler() { + "

      Metrics Path

      \n" + "The metrics path is /metrics.\n" + "

      Name Filter

      \n" - + "If you want to scrape only specific metrics, use the name[] parameter like this:\n" + + "If you want to scrape only specific metrics, " + + "use the name[] parameter like this:\n" + "\n" + "You can also use multiple name[] parameters to query multiple metrics:\n" + "\n" - + "The name[] parameter can be used by the Prometheus server for scraping. Add the following snippet to your scrape job configuration in prometheus.yaml:\n" + + "The name[] parameter can be used by the Prometheus server for scraping. " + + "Add the following snippet to your scrape job configuration in " + + "prometheus.yaml:\n" + "
      \n"
                   + "params:\n"
                   + "    name[]:\n"
      @@ -38,16 +42,28 @@ public DefaultHandler() {
                   + "
      \n" + "

      Debug Parameter

      \n" + "The Prometheus Java metrics library supports multiple exposition formats.\n" - + "The Prometheus server sends the Accept header to indicate which format it accepts.\n" - + "By default, the Prometheus server accepts OpenMetrics text format, unless the Prometheus server is started with feature flag --enable-feature=native-histograms,\n" + + "The Prometheus server sends the Accept header " + + "to indicate which format it accepts.\n" + + "By default, the Prometheus server accepts OpenMetrics text format, " + + "unless the Prometheus server is started with feature flag " + + "--enable-feature=native-histograms,\n" + "in which case the default is Prometheus protobuf.\n" - + "The Prometheus Java metrics library supports a debug query parameter for viewing the different formats in a Web browser:\n" + + "The Prometheus Java metrics library supports a debug query parameter " + + "for viewing the different formats in a Web browser:\n" + "\n" - + "Note that the debug parameter is only for viewing different formats in a Web browser, it should not be used by the Prometheus server for scraping. The Prometheus server uses the Accept header for indicating which format it accepts.\n" + + "Note that the debug parameter is only for viewing different formats in a " + + "Web browser, it should not be used by the Prometheus server for scraping. " + + "The Prometheus server uses the Accept " + + "header for indicating which format it accepts.\n" + "\n" + "\n"; this.responseBytes = responseString.getBytes(StandardCharsets.UTF_8); diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 5702a0b21..90aaf9d42 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -117,7 +117,9 @@ public void handle(HttpExchange exchange) throws IOException { } catch (PrivilegedActionException e) { if (e.getException() != null) { throw new IOException(e.getException()); - } else throw new IOException(e); + } else { + throw new IOException(e); + } } } else { drainInputAndClose(exchange); @@ -130,8 +132,9 @@ public void handle(HttpExchange exchange) throws IOException { private void drainInputAndClose(HttpExchange httpExchange) throws IOException { InputStream inputStream = httpExchange.getRequestBody(); byte[] b = new byte[4096]; - while (inputStream.read(b) != -1) - ; + while (inputStream.read(b) != -1) { + // nop + } inputStream.close(); } diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java index e7d33d310..3e0322309 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HttpExchangeAdapter.java @@ -120,7 +120,8 @@ private void sendErrorResponseWithStackTrace(Exception requestHandlerException) Logger.getLogger(this.getClass().getName()) .log( Level.SEVERE, - "The Prometheus metrics HTTPServer caught an Exception during scrape and failed to send an error response to the client.", + "The Prometheus metrics HTTPServer caught an Exception during scrape and " + + "failed to send an error response to the client.", errorWriterException); Logger.getLogger(this.getClass().getName()) .log( @@ -134,7 +135,8 @@ private void sendErrorResponseWithStackTrace(Exception requestHandlerException) Logger.getLogger(this.getClass().getName()) .log( Level.SEVERE, - "The Prometheus metrics HTTPServer caught an Exception while trying to send the metrics response.", + "The Prometheus metrics HTTPServer caught an Exception while trying to send " + + "the metrics response.", requestHandlerException); } } diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java index 39a293640..ff9be1cf8 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/PrometheusMetricProducer.java @@ -44,7 +44,7 @@ public Collection collectAllMetrics() { // registry.scrape(filter) if a filter is configured, like in the Servlet exporter. MetricSnapshots snapshots = registry.scrape(); Resource resourceWithTargetInfo = resource.merge(resourceFromTargetInfo(snapshots)); - InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOTelScopeInfo(snapshots); + InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOtelScopeInfo(snapshots); List result = new ArrayList<>(snapshots.size()); MetricDataFactory factory = new MetricDataFactory( @@ -93,7 +93,7 @@ private Resource resourceFromTargetInfo(MetricSnapshots snapshots) { return result.build(); } - private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo( + private InstrumentationScopeInfo instrumentationScopeFromOtelScopeInfo( MetricSnapshots snapshots) { for (MetricSnapshot snapshot : snapshots) { if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java index 64b82bd8b..9d2cff6a8 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusData.java @@ -10,7 +10,11 @@ import io.opentelemetry.sdk.metrics.data.MetricDataType; import io.opentelemetry.sdk.metrics.data.PointData; import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoubleExemplarData; -import io.prometheus.metrics.model.snapshots.*; +import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Exemplar; +import io.prometheus.metrics.model.snapshots.Exemplars; +import io.prometheus.metrics.model.snapshots.Label; +import io.prometheus.metrics.model.snapshots.Labels; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index 2b986adb4..2bafc6aa2 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -10,10 +10,24 @@ import io.prometheus.metrics.model.registry.Collector; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import java.io.*; -import java.net.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; +import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; /** * Export metrics via the Prometheus diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index 9e5dd9d09..866da038d 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -29,6 +29,8 @@ curl -sL https://raw.githubusercontent.com/prometheus/client_model/master/io/pro sed -i "s/java_package = \"io.prometheus.client\"/java_package = \"$PACKAGE\"/" $PROTO_DIR/metrics.proto protoc --java_out $TARGET_DIR $PROTO_DIR/metrics.proto +sed -i '1 i\//CHECKSTYLE:OFF: checkstyle' $(find src/main/generated/io -type f) +sed -i -e $'$a\\\n//CHECKSTYLE:ON: checkstyle' $(find src/main/generated/io -type f) GENERATED_WITH=$(grep -oP '\/\/ Protobuf Java Version: \K.*' "$TARGET_DIR/${PACKAGE//\.//}"/Metrics.java) diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java index 0f74014ed..ffa9b1d87 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java @@ -1,3 +1,4 @@ +//CHECKSTYLE:OFF: checkstyle // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto @@ -15114,3 +15115,4 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 // @@protoc_insertion_point(outer_class_scope) } +//CHECKSTYLE:ON: checkstyle diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java index fc5ac874e..fb3b9412d 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -33,7 +33,8 @@ public class PrometheusProtobufWriter implements ExpositionFormatWriter { public static final String CONTENT_TYPE = - "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"; + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; " + + "encoding=delimited"; @Override public boolean accepts(String acceptHeader) { @@ -53,7 +54,7 @@ public String getContentType() { public String toDebugString(MetricSnapshots metricSnapshots) { StringBuilder stringBuilder = new StringBuilder(); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { stringBuilder.append(TextFormat.printer().printToString(convert(snapshot))); } } @@ -63,7 +64,7 @@ public String toDebugString(MetricSnapshots metricSnapshots) { @Override public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { convert(snapshot).writeDelimitedTo(out); } } @@ -122,32 +123,13 @@ public Metrics.MetricFamily convert(MetricSnapshot snapshot) { return builder.build(); } - private void setMetadataUnlessEmpty( - Metrics.MetricFamily.Builder builder, - MetricMetadata metadata, - String nameSuffix, - Metrics.MetricType type) { - if (builder.getMetricCount() == 0) { - return; - } - if (nameSuffix == null) { - builder.setName(metadata.getPrometheusName()); - } else { - builder.setName(metadata.getPrometheusName() + nameSuffix); - } - if (metadata.getHelp() != null) { - builder.setHelp(metadata.getHelp()); - } - builder.setType(type); - } - private Metrics.Metric.Builder convert(CounterDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); Metrics.Counter.Builder counterBuilder = Metrics.Counter.newBuilder(); counterBuilder.setValue(data.getValue()); if (data.getExemplar() != null) { counterBuilder.setExemplar(convert(data.getExemplar())); } + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); addLabels(metricBuilder, data.getLabels()); metricBuilder.setCounter(counterBuilder.build()); setScrapeTimestamp(metricBuilder, data); @@ -155,9 +137,9 @@ private Metrics.Metric.Builder convert(CounterDataPointSnapshot data) { } private Metrics.Metric.Builder convert(GaugeSnapshot.GaugeDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); gaugeBuilder.setValue(data.getValue()); + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); addLabels(metricBuilder, data.getLabels()); metricBuilder.setGauge(gaugeBuilder); setScrapeTimestamp(metricBuilder, data); @@ -219,6 +201,94 @@ private Metrics.Metric.Builder convert(HistogramSnapshot.HistogramDataPointSnaps return metricBuilder; } + private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data) { + Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder(); + if (data.hasCount()) { + summaryBuilder.setSampleCount(data.getCount()); + } + if (data.hasSum()) { + summaryBuilder.setSampleSum(data.getSum()); + } + Quantiles quantiles = data.getQuantiles(); + for (int i = 0; i < quantiles.size(); i++) { + summaryBuilder.addQuantile( + Metrics.Quantile.newBuilder() + .setQuantile(quantiles.get(i).getQuantile()) + .setValue(quantiles.get(i).getValue()) + .build()); + } + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setSummary(summaryBuilder.build()); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + gaugeBuilder.setValue(1); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert( + StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.addLabel( + Metrics.LabelPair.newBuilder().setName(name).setValue(data.getName(i)).build()); + if (data.isTrue(i)) { + gaugeBuilder.setValue(1); + } else { + gaugeBuilder.setValue(0); + } + metricBuilder.setGauge(gaugeBuilder); + setScrapeTimestamp(metricBuilder, data); + return metricBuilder; + } + + private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot data) { + Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); + Metrics.Untyped.Builder untypedBuilder = Metrics.Untyped.newBuilder(); + untypedBuilder.setValue(data.getValue()); + addLabels(metricBuilder, data.getLabels()); + metricBuilder.setUntyped(untypedBuilder); + return metricBuilder; + } + + private Metrics.Exemplar.Builder convert(Exemplar exemplar) { + Metrics.Exemplar.Builder builder = Metrics.Exemplar.newBuilder(); + builder.setValue(exemplar.getValue()); + addLabels(builder, exemplar.getLabels()); + if (exemplar.hasTimestamp()) { + builder.setTimestamp(timestampFromMillis(exemplar.getTimestampMillis())); + } + return builder; + } + + private void setMetadataUnlessEmpty( + Metrics.MetricFamily.Builder builder, + MetricMetadata metadata, + String nameSuffix, + Metrics.MetricType type) { + if (builder.getMetricCount() == 0) { + return; + } + if (nameSuffix == null) { + builder.setName(metadata.getPrometheusName()); + } else { + builder.setName(metadata.getPrometheusName() + nameSuffix); + } + if (metadata.getHelp() != null) { + builder.setHelp(metadata.getHelp()); + } + builder.setType(type); + } + private long getNativeCount(HistogramSnapshot.HistogramDataPointSnapshot data) { if (data.hasCount()) { return data.getCount(); @@ -284,65 +354,6 @@ private void addBuckets( } } - private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder(); - if (data.hasCount()) { - summaryBuilder.setSampleCount(data.getCount()); - } - if (data.hasSum()) { - summaryBuilder.setSampleSum(data.getSum()); - } - Quantiles quantiles = data.getQuantiles(); - for (int i = 0; i < quantiles.size(); i++) { - summaryBuilder.addQuantile( - Metrics.Quantile.newBuilder() - .setQuantile(quantiles.get(i).getQuantile()) - .setValue(quantiles.get(i).getValue()) - .build()); - } - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setSummary(summaryBuilder.build()); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; - } - - private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); - gaugeBuilder.setValue(1); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setGauge(gaugeBuilder); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; - } - - private Metrics.Metric.Builder convert( - StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder(); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.addLabel( - Metrics.LabelPair.newBuilder().setName(name).setValue(data.getName(i)).build()); - if (data.isTrue(i)) { - gaugeBuilder.setValue(1); - } else { - gaugeBuilder.setValue(0); - } - metricBuilder.setGauge(gaugeBuilder); - setScrapeTimestamp(metricBuilder, data); - return metricBuilder; - } - - private Metrics.Metric.Builder convert(UnknownSnapshot.UnknownDataPointSnapshot data) { - Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder(); - Metrics.Untyped.Builder untypedBuilder = Metrics.Untyped.newBuilder(); - untypedBuilder.setValue(data.getValue()); - addLabels(metricBuilder, data.getLabels()); - metricBuilder.setUntyped(untypedBuilder); - return metricBuilder; - } - private void addLabels(Metrics.Metric.Builder metricBuilder, Labels labels) { for (int i = 0; i < labels.size(); i++) { metricBuilder.addLabel( @@ -363,16 +374,6 @@ private void addLabels(Metrics.Exemplar.Builder metricBuilder, Labels labels) { } } - private Metrics.Exemplar.Builder convert(Exemplar exemplar) { - Metrics.Exemplar.Builder builder = Metrics.Exemplar.newBuilder(); - builder.setValue(exemplar.getValue()); - addLabels(builder, exemplar.getLabels()); - if (exemplar.hasTimestamp()) { - builder.setTimestamp(timestampFromMillis(exemplar.getTimestampMillis())); - } - return builder; - } - private void setScrapeTimestamp(Metrics.Metric.Builder metricBuilder, DataPointSnapshot data) { if (data.hasScrapeTimestamp()) { metricBuilder.setTimestampMs(data.getScrapeTimestampMillis()); diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java index ce0318912..bd3a163ac 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java @@ -1,19 +1,36 @@ package io.prometheus.metrics.instrumentation.dropwizard5; -import io.dropwizard.metrics5.*; +import io.dropwizard.metrics5.Counter; +import io.dropwizard.metrics5.Gauge; +import io.dropwizard.metrics5.Histogram; +import io.dropwizard.metrics5.Meter; +import io.dropwizard.metrics5.Metric; +import io.dropwizard.metrics5.MetricFilter; +import io.dropwizard.metrics5.MetricName; +import io.dropwizard.metrics5.MetricRegistry; +import io.dropwizard.metrics5.Snapshot; import io.dropwizard.metrics5.Timer; import io.prometheus.metrics.instrumentation.dropwizard5.labels.CustomLabelMapper; import io.prometheus.metrics.model.registry.MultiCollector; import io.prometheus.metrics.model.registry.PrometheusRegistry; -import io.prometheus.metrics.model.snapshots.*; -import java.util.*; +import io.prometheus.metrics.model.snapshots.CounterSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; +import io.prometheus.metrics.model.snapshots.MetricMetadata; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.PrometheusNaming; +import io.prometheus.metrics.model.snapshots.Quantiles; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; /** Collect Dropwizard metrics from a MetricRegistry. */ public class DropwizardExports implements MultiCollector { - private static final Logger LOGGER = Logger.getLogger(DropwizardExports.class.getName()); + private static final Logger logger = Logger.getLogger(DropwizardExports.class.getName()); private final MetricRegistry registry; private final MetricFilter metricFilter; private final Optional labelMapper; @@ -92,7 +109,7 @@ MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) { } else if (obj instanceof Boolean) { value = ((Boolean) obj) ? 1 : 0; } else { - LOGGER.log( + logger.log( Level.FINE, String.format( "Invalid type for Gauge %s: %s", diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java index f69a27944..22f1c3339 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/labels/MapperConfig.java @@ -127,13 +127,21 @@ private void validateLabels(final Map labels) { @Override public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } final MapperConfig that = (MapperConfig) o; - if (match != null ? !match.equals(that.match) : that.match != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (match != null ? !match.equals(that.match) : that.match != null) { + return false; + } + if (name != null ? !name.equals(that.name) : that.name != null) { + return false; + } return labels != null ? labels.equals(that.labels) : that.labels == null; } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java index f87618f63..ebd0f296c 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.java @@ -67,7 +67,8 @@ private void register(PrometheusRegistry registry) { CounterWithCallback.builder(config) .name(JVM_CLASSES_UNLOADED_TOTAL) .help( - "The total number of classes that have been unloaded since the JVM has started execution") + "The total number of classes that have been unloaded since the JVM has " + + "started execution") .callback(callback -> callback.call(classLoadingBean.getUnloadedClassCount())) .register(registry); } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java index b0672aaf3..0b6a4d993 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.java @@ -309,11 +309,11 @@ public void register() { } public void register(PrometheusRegistry registry) { - MemoryMXBean memoryMXBean = + MemoryMXBean bean = this.memoryBean != null ? this.memoryBean : ManagementFactory.getMemoryMXBean(); List poolBeans = this.poolBeans != null ? this.poolBeans : ManagementFactory.getMemoryPoolMXBeans(); - new JvmMemoryMetrics(poolBeans, memoryMXBean, config).register(registry); + new JvmMemoryMetrics(poolBeans, bean, config).register(registry); } } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java index 671c36c97..a5e7768c8 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.java @@ -56,21 +56,20 @@ private JvmMemoryPoolAllocationMetrics(List garbageColle } private void register(PrometheusRegistry registry) { - Counter allocatedCounter = Counter.builder() .name(JVM_MEMORY_POOL_ALLOCATED_BYTES_TOTAL) .help( - "Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously.") + "Total bytes allocated in a given JVM memory pool. Only updated after GC, " + + "not continuously.") .labelNames("pool") .register(registry); AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter); - for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorBeans) { - if (garbageCollectorMXBean instanceof NotificationEmitter) { - ((NotificationEmitter) garbageCollectorMXBean) - .addNotificationListener(listener, null, null); + for (GarbageCollectorMXBean bean : garbageCollectorBeans) { + if (bean instanceof NotificationEmitter) { + ((NotificationEmitter) bean).addNotificationListener(listener, null, null); } } } diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java index e350568ac..53225edca 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmNativeMemoryMetrics.java @@ -110,7 +110,8 @@ private void register(PrometheusRegistry registry) { GaugeWithCallback.builder(config) .name(JVM_NATIVE_MEMORY_RESERVED_BYTES) .help( - "Reserved bytes of a given JVM. Reserved memory represents the total amount of memory the JVM can potentially use.") + "Reserved bytes of a given JVM. Reserved memory represents the total amount of " + + "memory the JVM can potentially use.") .unit(Unit.BYTES) .labelNames("pool") .callback(makeCallback(true)) @@ -119,7 +120,8 @@ private void register(PrometheusRegistry registry) { GaugeWithCallback.builder(config) .name(JVM_NATIVE_MEMORY_COMMITTED_BYTES) .help( - "Committed bytes of a given JVM. Committed memory represents the amount of memory the JVM is using right now.") + "Committed bytes of a given JVM. Committed memory represents the amount of " + + "memory the JVM is using right now.") .unit(Unit.BYTES) .labelNames("pool") .callback(makeCallback(false)) diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java index 8b6e57ac1..d3d140250 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.java @@ -109,7 +109,8 @@ private void register(PrometheusRegistry registry) { GaugeWithCallback.builder(config) .name(JVM_THREADS_DEADLOCKED) .help( - "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or ownable synchronizers") + "Cycles of JVM-threads that are in deadlock waiting to acquire object monitors or " + + "ownable synchronizers") .callback( callback -> callback.call(nullSafeArrayLength(threadBean.findDeadlockedThreads()))) .register(registry); @@ -148,7 +149,7 @@ private Map getThreadStateCountMap(ThreadMXBean threadBean) { } } - int numberOfInvalidThreadIds = threadIds.length - writePos; + final int numberOfInvalidThreadIds = threadIds.length - writePos; threadIds = Arrays.copyOf(threadIds, writePos); // Get thread information without computing any stack traces diff --git a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java index a854f5e89..e4dabd275 100644 --- a/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java +++ b/prometheus-metrics-instrumentation-jvm/src/main/java/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.java @@ -301,10 +301,10 @@ public void register() { public void register(PrometheusRegistry registry) { OperatingSystemMXBean osBean = this.osBean != null ? this.osBean : ManagementFactory.getOperatingSystemMXBean(); - RuntimeMXBean runtimeMXBean = + RuntimeMXBean bean = this.runtimeBean != null ? this.runtimeBean : ManagementFactory.getRuntimeMXBean(); Grepper grepper = this.grepper != null ? this.grepper : new FileGrepper(); - new ProcessMetrics(osBean, runtimeMXBean, grepper, config).register(registry); + new ProcessMetrics(osBean, bean, grepper, config).register(registry); } } } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java index 4c2d57e8e..6b455bff6 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/DataPointSnapshot.java @@ -21,11 +21,13 @@ private void validate() { } if (createdTimestampMillis < 0) { throw new IllegalArgumentException( - "Created timestamp cannot be negative. Use 0 if the metric doesn't have a created timestamp."); + "Created timestamp cannot be negative. " + + "Use 0 if the metric doesn't have a created timestamp."); } if (scrapeTimestampMillis < 0) { throw new IllegalArgumentException( - "Scrape timestamp cannot be negative. Use 0 to indicate that the Prometheus server should set the scrape timestamp."); + "Scrape timestamp cannot be negative. " + + "Use 0 to indicate that the Prometheus server should set the scrape timestamp."); } if (hasCreatedTimestamp() && hasScrapeTimestamp()) { if (scrapeTimestampMillis < createdTimestampMillis) { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java index eb6213d6b..51b529616 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/HistogramSnapshot.java @@ -270,7 +270,8 @@ private static long calculateCount( nativeZeroCount, nativeBucketsForPositiveValues, nativeBucketsForNegativeValues); if (classicCount != nativeCount) { throw new IllegalArgumentException( - "Inconsistent observation count: If a histogram has both classic and native data the observation count must be the same. Classic count is " + "Inconsistent observation count: If a histogram has both classic and native " + + "data the observation count must be the same. Classic count is " + classicCount + " but native count is " + nativeCount diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java index f14af41ce..45acd56ee 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Label.java @@ -34,8 +34,12 @@ public String toString() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Label label = (Label) o; return Objects.equals(name, label.name) && Objects.equals(value, label.value); } 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 dcb32f3bc..97cbfd43a 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 @@ -70,19 +70,6 @@ public static Labels of(String... keyValuePairs) { } // 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); - } - 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()}. @@ -129,6 +116,19 @@ public static Labels of(String[] names, String[] values) { return new Labels(namesCopy, prometheusNames, valuesCopy); } + 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); + } + prometheusNames[i] = PrometheusNaming.prometheusName(names[i]); + } + } + return prometheusNames; + } + /** * Test if these labels contain a specific label name. * @@ -286,14 +286,6 @@ public Labels merge(Labels other) { 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. @@ -313,6 +305,14 @@ public Labels merge(String[] names, String[] values) { return new Labels(mergedNames, prometheusNames, mergedValues); } + /** + * 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)); + } + public boolean hasSameNames(Labels other) { return Arrays.equals(prometheusNames, other.prometheusNames); } @@ -400,8 +400,12 @@ private void appendEscapedLabelValue(StringBuilder b, String value) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Labels labels = (Labels) o; return labels.hasSameNames(this) && labels.hasSameValues(this); } diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java index 868cdb394..581cb9143 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/MetricMetadata.java @@ -108,7 +108,8 @@ private void validate() { throw new IllegalArgumentException( "'" + name - + "': Illegal metric name. If the unit is non-null, the name must end with the unit: _" + + "': Illegal metric name. If the unit is non-null, " + + "the name must end with the unit: _" + unit + "." + " Call " 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 135af6658..34a9bc048 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 @@ -1,6 +1,11 @@ package io.prometheus.metrics.model.snapshots; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; /** Immutable list of quantiles. */ public class Quantiles implements Iterable { diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java index d95f93195..31a9524e7 100644 --- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java +++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Unit.java @@ -61,8 +61,12 @@ public static double kiloBytesToBytes(double kilobytes) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Unit unit = (Unit) o; return Objects.equals(name, unit.name); } diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java index 11d14ed8f..de8bf24f5 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/src/main/java/io/prometheus/metrics/tracer/initializer/SpanContextSupplier.java @@ -1,8 +1,8 @@ package io.prometheus.metrics.tracer.initializer; +import io.prometheus.metrics.tracer.agent.OpenTelemetryAgentSpanContext; import io.prometheus.metrics.tracer.common.SpanContext; import io.prometheus.metrics.tracer.otel.OpenTelemetrySpanContext; -import io.prometheus.metrics.tracer.otel_agent.OpenTelemetryAgentSpanContext; import java.util.concurrent.atomic.AtomicReference; public class SpanContextSupplier { diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/agent/OpenTelemetryAgentSpanContext.java similarity index 97% rename from prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java rename to prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/agent/OpenTelemetryAgentSpanContext.java index 3c757ed6b..f5f93e6f3 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/otel_agent/OpenTelemetryAgentSpanContext.java +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/src/main/java/io/prometheus/metrics/tracer/agent/OpenTelemetryAgentSpanContext.java @@ -1,4 +1,4 @@ -package io.prometheus.metrics.tracer.otel_agent; +package io.prometheus.metrics.tracer.agent; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanId; From db472756d3f49410188d03357ef79c87b558df64 Mon Sep 17 00:00:00 2001 From: Philipp Trulson Date: Tue, 12 Nov 2024 12:51:32 +0100 Subject: [PATCH 468/980] Add instrumentation for Guava & Caffeine to BOM (#1175) Signed-off-by: Philipp Trulson Co-authored-by: Gregor Zeitlinger --- prometheus-metrics-bom/pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index b56bea193..acdee81fb 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -72,6 +72,16 @@ prometheus-metrics-instrumentation-dropwizard5 ${project.version} + + io.prometheus + prometheus-metrics-instrumentation-caffeine + ${project.version} + + + io.prometheus + prometheus-metrics-instrumentation-guava + ${project.version} + io.prometheus prometheus-metrics-instrumentation-jvm From 8e434c160c8a4e16479c8ca99e452da6055880f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:07:50 +0100 Subject: [PATCH 469/980] Bump org.apache.maven.plugins:maven-checkstyle-plugin (#1202) Bumps [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) from 3.5.0 to 3.6.0. - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.5.0...maven-checkstyle-plugin-3.6.0) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dfc5a427e..e856b4447 100644 --- a/pom.xml +++ b/pom.xml @@ -228,7 +228,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.5.0 + 3.6.0 true google_checks.xml From cafbc1474c681705a7b0700789046112cab3c85c Mon Sep 17 00:00:00 2001 From: Petar Heyken <48122009+pheyken@users.noreply.github.com> Date: Wed, 13 Nov 2024 12:12:37 +0100 Subject: [PATCH 470/980] fix register part of documentation for caffeine & guava instrumentation + fix typo in method name (#1203) Signed-off-by: Petar Heyken --- .../instrumentation/caffeine/CacheMetricsCollector.java | 5 +++-- .../metrics/instrumentation/guava/CacheMetricsCollector.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java index c195ae77c..313e2f48f 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java @@ -25,7 +25,8 @@ *
      {@code
        * // Note that `recordStats()` is required to gather non-zero statistics
        * Cache cache = Caffeine.newBuilder().recordStats().build();
      - * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      + * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector();
      + * PrometheusRegistry.defaultRegistry.register(cacheMetrics);
        * cacheMetrics.addCache("mycache", cache);
        *
        * }
      @@ -87,7 +88,7 @@ public void addCache(String cacheName, AsyncCache cache) { * * @param cacheName cache to be removed */ - public Cache nremoveCache(String cacheName) { + public Cache removeCache(String cacheName) { return children.remove(cacheName); } diff --git a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java index e1da20071..2962b0bf3 100644 --- a/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-guava/src/main/java/io/prometheus/metrics/instrumentation/guava/CacheMetricsCollector.java @@ -23,7 +23,8 @@ *
      {@code
        * // Note that `recordStats()` is required to gather non-zero statistics
        * Cache cache = CacheBuilder.newBuilder().recordStats().build();
      - * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector().register();
      + * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector();
      + * PrometheusRegistry.defaultRegistry.register(cacheMetrics);
        * cacheMetrics.addCache("mycache", cache);
        *
        * }
      From 8461bad07a4a5cff9c67babe568e85e71b2d7a98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 23:27:37 -0500 Subject: [PATCH 471/980] Bump org.codehaus.mojo:versions-maven-plugin from 2.17.1 to 2.18.0 (#1205) Bumps [org.codehaus.mojo:versions-maven-plugin](https://github.com/mojohaus/versions) from 2.17.1 to 2.18.0. - [Release notes](https://github.com/mojohaus/versions/releases) - [Changelog](https://github.com/mojohaus/versions/blob/master/ReleaseNotes.md) - [Commits](https://github.com/mojohaus/versions/compare/2.17.1...2.18.0) --- updated-dependencies: - dependency-name: org.codehaus.mojo:versions-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e856b4447..1a041375a 100644 --- a/pom.xml +++ b/pom.xml @@ -368,7 +368,7 @@ org.codehaus.mojo versions-maven-plugin - 2.17.1 + 2.18.0 file://${project.basedir}/version-rules.xml From c005c0518c3b0c6f65cfe050d397df4d5b50ba77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:14:09 -0500 Subject: [PATCH 472/980] Bump commons-io:commons-io from 2.17.0 to 2.18.0 (#1209) Bumps commons-io:commons-io from 2.17.0 to 2.18.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 98f3d32c9..5adba2699 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -25,7 +25,7 @@ commons-io commons-io - 2.17.0 + 2.18.0 test From e17c0a10d5b55afc107b2e0114a433742b96a0ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 09:16:23 +0100 Subject: [PATCH 473/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha (#1204) Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.9.0-alpha to 2.10.0-alpha. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1a041375a..fb197fabc 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- 5.11.3 - 2.9.0-alpha + 2.10.0-alpha 8 0.70 false From 2f300386388e8da475bc1c5b48a37ed1e32f71ee Mon Sep 17 00:00:00 2001 From: Petar Heyken <48122009+pheyken@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:58:29 +0100 Subject: [PATCH 474/980] [prometheus-metrics-instrumentation-caffeine] implement getPrometheusNames (#1206) Signed-off-by: Petar Heyken --- .../caffeine/CacheMetricsCollector.java | 47 +++++++++++++++---- .../caffeine/CacheMetricsCollectorTest.java | 30 ++++++++++++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java index 313e2f48f..c5c9fef3c 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java @@ -55,6 +55,30 @@ public class CacheMetricsCollector implements MultiCollector { private static final double NANOSECONDS_PER_SECOND = 1_000_000_000.0; + private static final String METRIC_NAME_CACHE_HIT = "caffeine_cache_hit"; + private static final String METRIC_NAME_CACHE_MISS = "caffeine_cache_miss"; + private static final String METRIC_NAME_CACHE_REQUESTS = "caffeine_cache_requests"; + private static final String METRIC_NAME_CACHE_EVICTION = "caffeine_cache_eviction"; + private static final String METRIC_NAME_CACHE_EVICTION_WEIGHT = "caffeine_cache_eviction_weight"; + private static final String METRIC_NAME_CACHE_LOAD_FAILURE = "caffeine_cache_load_failure"; + private static final String METRIC_NAME_CACHE_LOADS = "caffeine_cache_loads"; + private static final String METRIC_NAME_CACHE_ESTIMATED_SIZE = "caffeine_cache_estimated_size"; + private static final String METRIC_NAME_CACHE_LOAD_DURATION_SECONDS = + "caffeine_cache_load_duration_seconds"; + + private static final List ALL_METRIC_NAMES = + Collections.unmodifiableList( + Arrays.asList( + METRIC_NAME_CACHE_HIT, + METRIC_NAME_CACHE_MISS, + METRIC_NAME_CACHE_REQUESTS, + METRIC_NAME_CACHE_EVICTION, + METRIC_NAME_CACHE_EVICTION_WEIGHT, + METRIC_NAME_CACHE_LOAD_FAILURE, + METRIC_NAME_CACHE_LOADS, + METRIC_NAME_CACHE_ESTIMATED_SIZE, + METRIC_NAME_CACHE_LOAD_DURATION_SECONDS)); + protected final ConcurrentMap> children = new ConcurrentHashMap<>(); /** @@ -107,40 +131,40 @@ public MetricSnapshots collect() { final List labelNames = Arrays.asList("cache"); final CounterSnapshot.Builder cacheHitTotal = - CounterSnapshot.builder().name("caffeine_cache_hit").help("Cache hit totals"); + CounterSnapshot.builder().name(METRIC_NAME_CACHE_HIT).help("Cache hit totals"); final CounterSnapshot.Builder cacheMissTotal = - CounterSnapshot.builder().name("caffeine_cache_miss").help("Cache miss totals"); + CounterSnapshot.builder().name(METRIC_NAME_CACHE_MISS).help("Cache miss totals"); final CounterSnapshot.Builder cacheRequestsTotal = CounterSnapshot.builder() - .name("caffeine_cache_requests") + .name(METRIC_NAME_CACHE_REQUESTS) .help("Cache request totals, hits + misses"); final CounterSnapshot.Builder cacheEvictionTotal = CounterSnapshot.builder() - .name("caffeine_cache_eviction") + .name(METRIC_NAME_CACHE_EVICTION) .help("Cache eviction totals, doesn't include manually removed entries"); final GaugeSnapshot.Builder cacheEvictionWeight = GaugeSnapshot.builder() - .name("caffeine_cache_eviction_weight") + .name(METRIC_NAME_CACHE_EVICTION_WEIGHT) .help("Cache eviction weight"); final CounterSnapshot.Builder cacheLoadFailure = - CounterSnapshot.builder().name("caffeine_cache_load_failure").help("Cache load failures"); + CounterSnapshot.builder().name(METRIC_NAME_CACHE_LOAD_FAILURE).help("Cache load failures"); final CounterSnapshot.Builder cacheLoadTotal = CounterSnapshot.builder() - .name("caffeine_cache_loads") + .name(METRIC_NAME_CACHE_LOADS) .help("Cache loads: both success and failures"); final GaugeSnapshot.Builder cacheSize = - GaugeSnapshot.builder().name("caffeine_cache_estimated_size").help("Estimated cache size"); + GaugeSnapshot.builder().name(METRIC_NAME_CACHE_ESTIMATED_SIZE).help("Estimated cache size"); final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() - .name("caffeine_cache_load_duration_seconds") + .name(METRIC_NAME_CACHE_LOAD_DURATION_SECONDS) .help("Cache load duration: both success and failures"); for (final Map.Entry> c : children.entrySet()) { @@ -223,4 +247,9 @@ public MetricSnapshots collect() { .metricSnapshot(cacheLoadSummary.build()) .build(); } + + @Override + public List getPrometheusNames() { + return ALL_METRIC_NAMES; + } } diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java index 37f5f3670..4ffb1d794 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -14,11 +14,13 @@ import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.DataPointSnapshot; import io.prometheus.metrics.model.snapshots.Labels; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; +import java.util.List; import org.junit.jupiter.api.Test; @SuppressWarnings("CheckReturnValue") @@ -115,6 +117,34 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { assertThat(loadDuration.getSum()).isGreaterThan(0); } + @Test + public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping() { + final CacheMetricsCollector collector = new CacheMetricsCollector(); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + final MetricSnapshots metricSnapshots = registry.scrape(); + final List prometheusNames = collector.getPrometheusNames(); + + assertThat(prometheusNames).hasSize(metricSnapshots.size()); + } + + @Test + public void collectedMetricNamesAreKnownPrometheusNames() { + final CacheMetricsCollector collector = new CacheMetricsCollector(); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + final MetricSnapshots metricSnapshots = registry.scrape(); + final List prometheusNames = collector.getPrometheusNames(); + + metricSnapshots.forEach( + metricSnapshot -> + assertThat(prometheusNames).contains(metricSnapshot.getMetadata().getPrometheusName())); + } + private void assertCounterMetric( PrometheusRegistry registry, String name, String cacheName, double value) { final CounterSnapshot.CounterDataPointSnapshot dataPointSnapshot = From 2debe2b49c5023cd5612b0d35b7212b3f710cc50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:58:50 +0100 Subject: [PATCH 475/980] Bump com.google.errorprone:error_prone_core from 2.35.1 to 2.36.0 (#1208) * Bump com.google.errorprone:error_prone_core from 2.35.1 to 2.36.0 Bumps [com.google.errorprone:error_prone_core](https://github.com/google/error-prone) from 2.35.1 to 2.36.0. - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.35.1...v2.36.0) --- updated-dependencies: - dependency-name: com.google.errorprone:error_prone_core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * add flag Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb197fabc..4dc20a62d 100644 --- a/pom.xml +++ b/pom.xml @@ -341,6 +341,7 @@ -Xlint:all,-serial,-processing,-options ${warnings} + --should-stop=ifError=FLOW -XDcompilePolicy=simple -Xplugin:ErrorProne @@ -355,7 +356,7 @@ com.google.errorprone error_prone_core - 2.35.1 + 2.36.0 + + + io.prometheus + it-spring-boot-smoke-test + 1.3.3 + + Integration Test - Spring Smoke Tests + + Spring Smoke Tests + + + 17 + + + + + + io.prometheus + prometheus-metrics-bom + ${project.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + runtime + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.prometheus + it-common + test-jar + ${project.version} + test + + + + + + + org.graalvm.buildtools + native-maven-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + com.diffplug.spotless + spotless-maven-plugin + 2.43.0 + + + + + + + + verify + + check + + + + + + + + diff --git a/integration-tests/it-spring-boot-smoke-test/src/main/java/io/prometheus/metrics/it/springboot/Application.java b/integration-tests/it-spring-boot-smoke-test/src/main/java/io/prometheus/metrics/it/springboot/Application.java new file mode 100644 index 000000000..955ea4033 --- /dev/null +++ b/integration-tests/it-spring-boot-smoke-test/src/main/java/io/prometheus/metrics/it/springboot/Application.java @@ -0,0 +1,12 @@ +package io.prometheus.metrics.it.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/integration-tests/it-spring-boot-smoke-test/src/main/resources/application.yaml b/integration-tests/it-spring-boot-smoke-test/src/main/resources/application.yaml new file mode 100644 index 000000000..fdcf1351d --- /dev/null +++ b/integration-tests/it-spring-boot-smoke-test/src/main/resources/application.yaml @@ -0,0 +1,5 @@ +management: + endpoints: + web: + exposure: + include: '*' diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java new file mode 100644 index 000000000..3d893d894 --- /dev/null +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java @@ -0,0 +1,35 @@ +package io.prometheus.metrics.it.springboot; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.prometheus.client.it.common.ExporterTest; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import java.io.IOException; +import java.net.URL; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.actuate.observability.AutoConfigureObservability; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@AutoConfigureObservability +class ApplicationTest { + @Test + public void testPrometheusProtobufFormat() throws IOException { + ExporterTest.Response response = + ExporterTest.scrape( + "GET", + new URL("http://localhost:8080/actuator/prometheus"), + "Accept", + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited"); + assertThat(response.status).isEqualTo(200); + + List metrics = response.protoBody(); + Optional metric = + metrics.stream() + .filter(m -> m.getName().equals("application_started_time_seconds")) + .findFirst(); + assertThat(metric).isPresent(); + } +} diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 2a75a4942..ece364ae9 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -13,7 +13,6 @@ pom Integration Tests - http://github.com/prometheus/client_java Integration tests for the Exporter modules @@ -26,6 +25,7 @@ it-common it-exporter it-pushgateway + it-spring-boot-smoke-test @@ -46,7 +46,13 @@ + + + commons-io + commons-io + 2.18.0 + org.testcontainers junit-jupiter diff --git a/pom.xml b/pom.xml index 4dc20a62d..ac7d26403 100644 --- a/pom.xml +++ b/pom.xml @@ -66,18 +66,19 @@ prometheus-metrics-model prometheus-metrics-tracer prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats prometheus-metrics-exporter-common prometheus-metrics-exporter-servlet-jakarta prometheus-metrics-exporter-servlet-javax prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry + prometheus-metrics-exporter-opentelemetry-otel-agent-resources prometheus-metrics-exporter-pushgateway prometheus-metrics-instrumentation-caffeine prometheus-metrics-instrumentation-jvm prometheus-metrics-instrumentation-dropwizard5 prometheus-metrics-instrumentation-guava prometheus-metrics-simpleclient-bridge - otel-agent-resources @@ -91,6 +92,14 @@ + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + + org.junit.jupiter junit-jupiter-engine @@ -200,6 +209,16 @@ maven-enforcer-plugin 3.5.0
      + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + org.codehaus.mojo + exec-maven-plugin + 3.5.0 + com.diffplug.spotless spotless-maven-plugin diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index 801876b74..d2bf832d5 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -6,9 +6,9 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; +import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Label; @@ -112,8 +112,9 @@ public void testTotalStrippedFromName() { "my_counter_seconds", "my.counter.seconds" }) { Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build(); - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(counter.collect()); - assertThat(TextFormatUtil.shortDebugString(protobufData)) + Metrics.MetricFamily protobufData = + new PrometheusProtobufWriterImpl().convert(counter.collect()); + assertThat(ProtobufUtil.shortDebugString(protobufData)) .isEqualTo( "name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }"); } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 89a4e853c..5a8d7cda8 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -8,9 +8,9 @@ import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; +import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; import io.prometheus.metrics.model.snapshots.Exemplar; import io.prometheus.metrics.model.snapshots.Exemplars; @@ -89,10 +89,10 @@ private void run() throws NoSuchFieldException, IllegalAccessException { } } Metrics.MetricFamily protobufData = - new PrometheusProtobufWriter().convert(histogram.collect()); + new PrometheusProtobufWriterImpl().convert(histogram.collect()); String expectedWithMetadata = "name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }"; - assertThat(TextFormatUtil.shortDebugString(protobufData)) + assertThat(ProtobufUtil.shortDebugString(protobufData)) .as("test \"" + name + "\" failed") .isEqualTo(expectedWithMetadata); } @@ -940,8 +940,8 @@ public void testDefaults() throws IOException { + "# EOF\n"; // protobuf - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(snapshot); - assertThat(TextFormatUtil.shortDebugString(protobufData)).isEqualTo(expectedProtobuf); + Metrics.MetricFamily protobufData = new PrometheusProtobufWriterImpl().convert(snapshot); + assertThat(ProtobufUtil.shortDebugString(protobufData)).isEqualTo(expectedProtobuf); // text ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 3084cdb10..427b6a55f 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -4,9 +4,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; -import io.prometheus.metrics.expositionformats.TextFormatUtil; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; +import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.Unit; @@ -27,8 +27,9 @@ public void testInfoStrippedFromName() { for (String labelName : new String[] {"my.key", "my_key"}) { Info info = Info.builder().name(name).labelNames(labelName).build(); info.addLabelValues("value"); - Metrics.MetricFamily protobufData = new PrometheusProtobufWriter().convert(info.collect()); - assertThat(TextFormatUtil.shortDebugString(protobufData)) + Metrics.MetricFamily protobufData = + new PrometheusProtobufWriterImpl().convert(info.collect()); + assertThat(ProtobufUtil.shortDebugString(protobufData)) .isEqualTo( "name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value: \"value\" } gauge { value: 1.0 } }"); } diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index 30b2cd9ae..cea87262b 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -26,10 +26,16 @@ prometheus-metrics-model ${project.version}
      + + io.prometheus + prometheus-metrics-exposition-textformats + ${project.version} + io.prometheus prometheus-metrics-exposition-formats ${project.version} + runtime diff --git a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java index f871addfd..f978a9b36 100644 --- a/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java +++ b/prometheus-metrics-exporter-common/src/main/java/io/prometheus/metrics/exporter/common/PrometheusScrapeHandler.java @@ -11,8 +11,10 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.zip.GZIPOutputStream; @@ -23,7 +25,8 @@ public class PrometheusScrapeHandler { private final PrometheusRegistry registry; private final ExpositionFormats expositionFormats; private final Predicate nameFilter; - private AtomicInteger lastResponseSize = new AtomicInteger(2 << 9); // 0.5 MB + private final AtomicInteger lastResponseSize = new AtomicInteger(2 << 9); // 0.5 MB + private final List supportedFormats; public PrometheusScrapeHandler() { this(PrometheusProperties.get(), PrometheusRegistry.defaultRegistry); @@ -41,6 +44,10 @@ public PrometheusScrapeHandler(PrometheusProperties config, PrometheusRegistry r this.expositionFormats = ExpositionFormats.init(config.getExporterProperties()); this.registry = registry; this.nameFilter = makeNameFilter(config.getExporterFilterProperties()); + supportedFormats = new ArrayList<>(Arrays.asList("openmetrics", "text")); + if (expositionFormats.getPrometheusProtobufWriter().isAvailable()) { + supportedFormats.add("prometheus-protobuf"); + } } public void handleRequest(PrometheusHttpExchange exchange) throws IOException { @@ -137,9 +144,7 @@ private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExch return false; } else { response.setHeader("Content-Type", "text/plain; charset=utf-8"); - boolean supportedFormat = - Arrays.asList("openmetrics", "text", "prometheus-protobuf").contains(debugParam); - int responseStatus = supportedFormat ? 200 : 500; + int responseStatus = supportedFormats.contains(debugParam) ? 200 : 500; OutputStream body = response.sendHeadersAndGetBody(responseStatus, 0); switch (debugParam) { case "openmetrics": diff --git a/otel-agent-resources/pom.xml b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml similarity index 96% rename from otel-agent-resources/pom.xml rename to prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml index c4e9a4741..0d6f63623 100644 --- a/otel-agent-resources/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml @@ -9,7 +9,7 @@ 1.3.3 - otel-agent-resources + prometheus-metrics-exporter-opentelemetry-otel-agent-resources bundle OpenTelemetry Agent Resource Extractor diff --git a/otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java similarity index 100% rename from otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java rename to prometheus-metrics-exporter-opentelemetry-otel-agent-resources/src/main/java/io/prometheus/otelagent/ResourceAttributesFromOtelAgent.java diff --git a/otel-agent-resources/src/main/resources/lib/.gitignore b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/src/main/resources/lib/.gitignore similarity index 100% rename from otel-agent-resources/src/main/resources/lib/.gitignore rename to prometheus-metrics-exporter-opentelemetry-otel-agent-resources/src/main/resources/lib/.gitignore diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index e8051258e..462ff19d1 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -41,7 +41,7 @@ io.prometheus - otel-agent-resources + prometheus-metrics-exporter-opentelemetry-otel-agent-resources ${project.version} @@ -112,7 +112,6 @@ org.codehaus.mojo build-helper-maven-plugin - 3.6.0 regex-property diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index 2bafc6aa2..6c89185f1 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -5,6 +5,7 @@ import io.prometheus.metrics.config.ExporterPushgatewayProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.config.PrometheusPropertiesException; +import io.prometheus.metrics.expositionformats.ExpositionFormatWriter; import io.prometheus.metrics.expositionformats.PrometheusProtobufWriter; import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter; import io.prometheus.metrics.model.registry.Collector; @@ -78,7 +79,7 @@ public class PushGateway { private static final int MILLISECONDS_PER_SECOND = 1000; private final URL url; - private final Format format; + private final ExpositionFormatWriter writer; private final Map requestHeaders; private final PrometheusRegistry registry; private final HttpConnectionFactory connectionFactory; @@ -90,10 +91,22 @@ private PushGateway( HttpConnectionFactory connectionFactory, Map requestHeaders) { this.registry = registry; - this.format = format; this.url = url; this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders)); this.connectionFactory = connectionFactory; + writer = getWriter(format); + if (!writer.isAvailable()) { + throw new RuntimeException(writer.getClass() + " is not available"); + } + } + + private ExpositionFormatWriter getWriter(Format format) { + if (format == Format.PROMETHEUS_TEXT) { + return new PrometheusTextFormatWriter(false); + } else { + // use reflection to avoid a compile-time dependency on the expositionformats module + return new PrometheusProtobufWriter(); + } } /** @@ -174,11 +187,7 @@ private void doRequest(PrometheusRegistry registry, String method) throws IOExce try { HttpURLConnection connection = connectionFactory.create(url); requestHeaders.forEach(connection::setRequestProperty); - if (format == Format.PROMETHEUS_TEXT) { - connection.setRequestProperty("Content-Type", PrometheusTextFormatWriter.CONTENT_TYPE); - } else { - connection.setRequestProperty("Content-Type", PrometheusProtobufWriter.CONTENT_TYPE); - } + connection.setRequestProperty("Content-Type", writer.getContentType()); if (!method.equals("DELETE")) { connection.setDoOutput(true); } @@ -191,11 +200,7 @@ private void doRequest(PrometheusRegistry registry, String method) throws IOExce try { if (!method.equals("DELETE")) { OutputStream outputStream = connection.getOutputStream(); - if (format == Format.PROMETHEUS_TEXT) { - new PrometheusTextFormatWriter(false).write(outputStream, registry.scrape()); - } else { - new PrometheusProtobufWriter().write(outputStream, registry.scrape()); - } + writer.write(outputStream, registry.scrape()); outputStream.flush(); outputStream.close(); } diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index 866da038d..db27d9457 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -17,7 +17,7 @@ mkdir -p $TARGET_DIR rm -rf $PROTO_DIR || true mkdir -p $PROTO_DIR -OLD_PACKAGE=$(sed -nE 's/import (io.prometheus.metrics.expositionformats.generated.*).Metrics;/\1/p' src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java) +OLD_PACKAGE=$(sed -nE 's/import (io.prometheus.metrics.expositionformats.generated.*).Metrics;/\1/p' src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java) PACKAGE="io.prometheus.metrics.expositionformats.generated.com_google_protobuf_${PROTOBUF_VERSION_STRING}" if [[ $OLD_PACKAGE != "$PACKAGE" ]]; then diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index a6975525a..e27a73573 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -25,12 +25,7 @@ io.prometheus - prometheus-metrics-model - ${project.version} - - - io.prometheus - prometheus-metrics-config + prometheus-metrics-exposition-textformats ${project.version} @@ -45,7 +40,6 @@ org.codehaus.mojo build-helper-maven-plugin - 3.6.0 regex-property @@ -90,7 +84,6 @@ exec-maven-plugin org.codehaus.mojo - 3.5.0 Generate Protobuf diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java deleted file mode 100644 index e693e0c15..000000000 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.prometheus.metrics.expositionformats; - -import io.prometheus.metrics.model.snapshots.MetricSnapshots; -import java.io.IOException; -import java.io.OutputStream; - -public interface ExpositionFormatWriter { - boolean accepts(String acceptHeader); - - /** Text formats use UTF-8 encoding. */ - void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException; - - String getContentType(); -} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java deleted file mode 100644 index 5b192c23d..000000000 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ProtobufUtil.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.prometheus.metrics.expositionformats; - -import com.google.protobuf.Timestamp; - -public class ProtobufUtil { - - static Timestamp timestampFromMillis(long timestampMillis) { - return Timestamp.newBuilder() - .setSeconds(timestampMillis / 1000L) - .setNanos((int) (timestampMillis % 1000L * 1000000L)) - .build(); - } -} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java similarity index 94% rename from prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java rename to prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java index fb3b9412d..a52a83adf 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java @@ -1,8 +1,9 @@ -package io.prometheus.metrics.expositionformats; +package io.prometheus.metrics.expositionformats.internal; -import static io.prometheus.metrics.expositionformats.ProtobufUtil.timestampFromMillis; +import static io.prometheus.metrics.expositionformats.internal.ProtobufUtil.timestampFromMillis; import com.google.protobuf.TextFormat; +import io.prometheus.metrics.expositionformats.ExpositionFormatWriter; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; @@ -24,33 +25,19 @@ import java.io.IOException; import java.io.OutputStream; -/** - * Write the Prometheus protobuf format as defined in
      github.com/prometheus/client_model. - * - *

      As of today, this is the only exposition format that supports native histograms. - */ -public class PrometheusProtobufWriter implements ExpositionFormatWriter { - - public static final String CONTENT_TYPE = - "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; " - + "encoding=delimited"; +public class PrometheusProtobufWriterImpl implements ExpositionFormatWriter { @Override public boolean accepts(String acceptHeader) { - if (acceptHeader == null) { - return false; - } else { - return acceptHeader.contains("application/vnd.google.protobuf") - && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); - } + throw new IllegalStateException("use PrometheusProtobufWriter instead"); } @Override public String getContentType() { - return CONTENT_TYPE; + throw new IllegalStateException("use PrometheusProtobufWriter instead"); } + @Override public String toDebugString(MetricSnapshots metricSnapshots) { StringBuilder stringBuilder = new StringBuilder(); for (MetricSnapshot snapshot : metricSnapshots) { diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/ProtobufUtil.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/ProtobufUtil.java new file mode 100644 index 000000000..75e3d0ef2 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/ProtobufUtil.java @@ -0,0 +1,19 @@ +package io.prometheus.metrics.expositionformats.internal; + +import com.google.protobuf.MessageOrBuilder; +import com.google.protobuf.TextFormat; +import com.google.protobuf.Timestamp; + +public class ProtobufUtil { + + static Timestamp timestampFromMillis(long timestampMillis) { + return Timestamp.newBuilder() + .setSeconds(timestampMillis / 1000L) + .setNanos((int) (timestampMillis % 1000L * 1000000L)) + .build(); + } + + public static String shortDebugString(MessageOrBuilder protobufData) { + return TextFormat.printer().emittingSingleLine(true).printToString(protobufData); + } +} diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index e5cd3f089..1d98925e3 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -3,6 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; +import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; @@ -2658,9 +2660,9 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot } private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { - PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); + PrometheusProtobufWriterImpl writer = new PrometheusProtobufWriterImpl(); Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = TextFormatUtil.shortDebugString(protobufData); + String actual = ProtobufUtil.shortDebugString(protobufData); assertThat(actual).isEqualTo(expected); } } diff --git a/prometheus-metrics-exposition-textformats/pom.xml b/prometheus-metrics-exposition-textformats/pom.xml new file mode 100644 index 000000000..161fb005f --- /dev/null +++ b/prometheus-metrics-exposition-textformats/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + + io.prometheus + client_java + 1.3.3 + + + prometheus-metrics-exposition-textformats + bundle + + Prometheus Metrics Exposition Text Formats + + Prometheus exposition text formats. + + + + io.prometheus.writer.text + + + + + io.prometheus + prometheus-metrics-model + ${project.version} + + + io.prometheus + prometheus-metrics-config + ${project.version} + + + diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java new file mode 100644 index 000000000..b472af0e1 --- /dev/null +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriter.java @@ -0,0 +1,32 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public interface ExpositionFormatWriter { + boolean accepts(String acceptHeader); + + /** Text formats use UTF-8 encoding. */ + void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException; + + default String toDebugString(MetricSnapshots metricSnapshots) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + write(out, metricSnapshots); + return out.toString("UTF-8"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + String getContentType(); + + /** + * Returns true if the writer is available. If false, the writer will throw an exception if used. + */ + default boolean isAvailable() { + return true; + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java similarity index 100% rename from prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java rename to prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java similarity index 100% rename from prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java rename to prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java new file mode 100644 index 000000000..0572a99a7 --- /dev/null +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriter.java @@ -0,0 +1,73 @@ +package io.prometheus.metrics.expositionformats; + +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import java.io.IOException; +import java.io.OutputStream; +import javax.annotation.Nullable; + +/** + * Write the Prometheus protobuf format as defined in github.com/prometheus/client_model. + * + *

      As of today, this is the only exposition format that supports native histograms. + */ +public class PrometheusProtobufWriter implements ExpositionFormatWriter { + + @Nullable private static final ExpositionFormatWriter DELEGATE = createProtobufWriter(); + + public static final String CONTENT_TYPE = + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; " + + "encoding=delimited"; + + @Nullable + private static ExpositionFormatWriter createProtobufWriter() { + try { + return Class.forName( + "io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl") + .asSubclass(ExpositionFormatWriter.class) + .getDeclaredConstructor() + .newInstance(); + } catch (Exception e) { + // not in classpath + return null; + } + } + + @Override + public boolean accepts(String acceptHeader) { + if (acceptHeader == null) { + return false; + } else { + return acceptHeader.contains("application/vnd.google.protobuf") + && acceptHeader.contains("proto=io.prometheus.client.MetricFamily"); + } + } + + @Override + public String getContentType() { + return CONTENT_TYPE; + } + + @Override + public boolean isAvailable() { + return DELEGATE != null; + } + + @Override + public String toDebugString(MetricSnapshots metricSnapshots) { + checkAvailable(); + return DELEGATE.toDebugString(metricSnapshots); + } + + @Override + public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException { + checkAvailable(); + DELEGATE.write(out, metricSnapshots); + } + + private void checkAvailable() { + if (DELEGATE == null) { + throw new UnsupportedOperationException("Prometheus protobuf writer not available"); + } + } +} diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java similarity index 100% rename from prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java rename to prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java similarity index 90% rename from prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java rename to prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index c61a8f1b6..54daaaa3e 100644 --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -1,7 +1,5 @@ package io.prometheus.metrics.expositionformats; -import com.google.protobuf.MessageOrBuilder; -import com.google.protobuf.TextFormat; import io.prometheus.metrics.model.snapshots.Labels; import java.io.IOException; import java.io.OutputStreamWriter; @@ -83,8 +81,4 @@ static void writeLabels( } writer.write('}'); } - - public static String shortDebugString(MessageOrBuilder protobufData) { - return TextFormat.printer().emittingSingleLine(true).printToString(protobufData); - } } diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index 56a7b1836..41a7a6e62 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -44,7 +44,7 @@ io.prometheus - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats ${project.version} test diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index d75143796..ae0d657bc 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -43,7 +43,7 @@ io.prometheus - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats ${project.version} test diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index c4427df91..6e816ee31 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -41,7 +41,7 @@ io.prometheus - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats ${project.version} test diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index ba433c0b7..a9edf9352 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -37,7 +37,7 @@ io.prometheus - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats ${project.version} test diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 6d9ff2785..3112db2f9 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -41,7 +41,7 @@ io.prometheus - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-textformats ${project.version} test diff --git a/scripts/build-release.sh b/scripts/build-release.sh new file mode 100755 index 000000000..ecbb07b8e --- /dev/null +++ b/scripts/build-release.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -euo pipefail + +TAG=$1 +VERSION=${TAG#v} + +mvn versions:set -DnewVersion=$VERSION +cd integration-tests/it-spring-boot-smoke-test +mvn versions:set -DnewVersion=$VERSION +mvn -B package -P release -Dmaven.test.skip=true diff --git a/scripts/run-native-tests.sh b/scripts/run-native-tests.sh new file mode 100755 index 000000000..535bc136c --- /dev/null +++ b/scripts/run-native-tests.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +./mvnw clean install -DskipTests +cd integration-tests/it-spring-boot-smoke-test +../../mvnw test -PnativeTest From c98423bbecffeaa9a1e0fb0ac8184c823acafb95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:34:10 +0100 Subject: [PATCH 479/980] Bump org.springframework.boot:spring-boot-starter-parent (#1212) Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.3.5 to 3.4.0. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.5...v3.4.0) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot-starter-parent dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 50e9b7669..3982046ee 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.3.5 + 3.4.0 From bdfe25ce9c3ff3c2940b37bc7192b57b2f351df8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 25 Nov 2024 17:03:23 +0100 Subject: [PATCH 480/980] fix release (#1213) Signed-off-by: Gregor Zeitlinger --- RELEASING.md | 2 +- scripts/build-release.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index af5d1b862..a58656474 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,6 +1,6 @@ ## Create a Release -1. Go to https://github.com/prometheus/client_java/releases +1. Go to https://github.com/prometheus/client_java/releases/new 2. Click on "Choose a tag", enter the tag name (e.g. `v0.1.0`), and click "Create a new tag". 3. Click on "Generate release notes" to auto-generate the release notes based on the commits since the last release. 4. Click on "Publish release". diff --git a/scripts/build-release.sh b/scripts/build-release.sh index ecbb07b8e..de3154591 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -6,6 +6,7 @@ TAG=$1 VERSION=${TAG#v} mvn versions:set -DnewVersion=$VERSION +mvn install -DskipTests=true # to find the new version in the next step cd integration-tests/it-spring-boot-smoke-test mvn versions:set -DnewVersion=$VERSION mvn -B package -P release -Dmaven.test.skip=true From d0e2dd35d4885b47954d120cef539c64d10d403d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 25 Nov 2024 18:01:08 +0100 Subject: [PATCH 481/980] fix release (#1214) * set snapshot version Signed-off-by: Gregor Zeitlinger * fix release Signed-off-by: Gregor Zeitlinger * fix release Signed-off-by: Gregor Zeitlinger * fix release Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: Gregor Zeitlinger --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/it-no-protobuf-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 2 +- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- integration-tests/pom.xml | 2 +- pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- .../pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-exposition-textformats/pom.xml | 2 +- prometheus-metrics-instrumentation-caffeine/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-guava/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- scripts/build-release.sh | 3 --- 48 files changed, 47 insertions(+), 50 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 105995a0b..de53b2edd 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 803fcb1e3..9aab1d452 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.3 + 10.0.0-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index e89809ff8..40efc62f1 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 1.3.3 + 10.0.0-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 45886970c..3c62dfb66 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 3a102819b..74124c6bd 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index c69e9a895..8ba600b73 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index 01439da7b..e8546c5a0 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 46c07fc41..355f8e830 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 203fb3af6..3aebe8278 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 2019d69b6..112b775d9 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index 481d8a589..abd461450 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 1.3.3 + 10.0.0-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index e33b1766a..3e7864ff1 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 6c7044978..511cf9a8c 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -6,7 +6,7 @@ io.prometheus integration-tests - 1.3.3 + 10.0.0-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 2b6d6c127..25696a247 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml b/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml index 67e20e8e2..4a0dc8772 100644 --- a/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml +++ b/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-exporter-no-protobuf diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index d52bf4938..4c4670d2f 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 34c77ddb5..78a94b724 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 4e72d1db9..5a6496ba2 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/it-no-protobuf-test/pom.xml b/integration-tests/it-exporter/it-no-protobuf-test/pom.xml index f10cd3e16..8ceda5e8f 100644 --- a/integration-tests/it-exporter/it-no-protobuf-test/pom.xml +++ b/integration-tests/it-exporter/it-no-protobuf-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 1.3.3 + 10.0.0-SNAPSHOT it-no-protobuf-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 4badf828d..4ea63136e 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.3 + 10.0.0-SNAPSHOT it-exporter diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 050d6c37a..15f99ff46 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 1.3.3 + 10.0.0-SNAPSHOT it-pushgateway diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 3982046ee..fc5fc6083 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -13,7 +13,7 @@ io.prometheus it-spring-boot-smoke-test - 1.3.3 + 10.0.0-SNAPSHOT Integration Test - Spring Smoke Tests diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ece364ae9..41adf0e40 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT integration-tests diff --git a/pom.xml b/pom.xml index ac7d26403..7faf167c0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index acdee81fb..d1299470b 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 738991196..420ed8a13 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 18a52afca..7305675bd 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index cea87262b..e54f925fd 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index e6bd442b4..5e639f3f8 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml index 0d6f63623..a1ee03d71 100644 --- a/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry-otel-agent-resources diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 462ff19d1..ff6effb5c 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index 4fb54c66b..a3881f472 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 4d20171b5..3cf77ca86 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index a2918175b..b5657ffb0 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index e27a73573..1811e2c7e 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-exposition-textformats/pom.xml b/prometheus-metrics-exposition-textformats/pom.xml index 161fb005f..6a38dd67b 100644 --- a/prometheus-metrics-exposition-textformats/pom.xml +++ b/prometheus-metrics-exposition-textformats/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-exposition-textformats diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index 41a7a6e62..0de05d99c 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-instrumentation-caffeine diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index ae0d657bc..e79f236ef 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 6e816ee31..08ea80411 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-instrumentation-guava diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index a9edf9352..24758db8c 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index c7b14885f..4e803ee5a 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 3112db2f9..76f0b203d 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index ad5c86b50..885120d4a 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index a7a4ab485..fcdf81d2f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 88689d6db..432fa0dfa 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index 0044ef763..d4efbd099 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index a08bb4daa..72fdb71d6 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 1.3.3 + 10.0.0-SNAPSHOT prometheus-metrics-tracer-otel diff --git a/scripts/build-release.sh b/scripts/build-release.sh index de3154591..8cbc50a61 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -5,8 +5,5 @@ set -euo pipefail TAG=$1 VERSION=${TAG#v} -mvn versions:set -DnewVersion=$VERSION -mvn install -DskipTests=true # to find the new version in the next step -cd integration-tests/it-spring-boot-smoke-test mvn versions:set -DnewVersion=$VERSION mvn -B package -P release -Dmaven.test.skip=true From 28f3cc9f4d10a7aa6a721310c5a613798efb8281 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:29:18 +0100 Subject: [PATCH 482/980] Bump org.wiremock:wiremock from 3.9.2 to 3.10.0 (#1218) Bumps [org.wiremock:wiremock](https://github.com/wiremock/wiremock) from 3.9.2 to 3.10.0. - [Release notes](https://github.com/wiremock/wiremock/releases) - [Commits](https://github.com/wiremock/wiremock/compare/3.9.2...3.10.0) --- updated-dependencies: - dependency-name: org.wiremock:wiremock dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index ff6effb5c..5145d1504 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -73,7 +73,7 @@ org.wiremock wiremock - 3.9.2 + 3.10.0 test From 049a61abc181b71f91ed12ea64f0ce56b6042888 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:29:48 +0100 Subject: [PATCH 483/980] Bump org.apache.felix:maven-bundle-plugin from 5.1.9 to 6.0.0 (#1216) Bumps org.apache.felix:maven-bundle-plugin from 5.1.9 to 6.0.0. --- updated-dependencies: - dependency-name: org.apache.felix:maven-bundle-plugin dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7faf167c0..da02be263 100644 --- a/pom.xml +++ b/pom.xml @@ -335,7 +335,7 @@ org.apache.felix maven-bundle-plugin - 5.1.9 + 6.0.0 true From 99d3dec20372ddd26480bb9405c398b6fb9ab016 Mon Sep 17 00:00:00 2001 From: Doug Hoard Date: Tue, 3 Dec 2024 23:00:49 -0500 Subject: [PATCH 484/980] Changed GitHub action containers (#1221) Signed-off-by: dhoard --- .github/workflows/acceptance-tests.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/github-pages.yaml | 4 ++-- .github/workflows/native-tests.yml | 2 +- .github/workflows/release.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 590c12946..e6a64579e 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -8,7 +8,7 @@ on: jobs: acceptance-tests: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Check out oats diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd0668345..cd607b3eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Setup ASDF diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 7ca7128b5..87daffd26 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -29,7 +29,7 @@ defaults: jobs: # Build job build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 env: HUGO_VERSION: 0.115.4 steps: @@ -82,7 +82,7 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: build steps: - name: Deploy to GitHub Pages diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index f632f730f..9a4ed50a6 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -8,7 +8,7 @@ on: jobs: native-tests: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Set up JDK diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e7d81574..57c7a6f53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ on: jobs: deploy: if: ${{ github.repository == 'prometheus/client_java' }} - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Debug gpg key - remove after debugging From 9a0848d82840b00d5c42f15606f1adda980f4ddf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 08:40:16 -0500 Subject: [PATCH 485/980] Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.1 to 3.11.2 (#1225) Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.1 to 3.11.2. - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.1...maven-javadoc-plugin-3.11.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da02be263..212fe042d 100644 --- a/pom.xml +++ b/pom.xml @@ -195,7 +195,7 @@ maven-javadoc-plugin - 3.11.1 + 3.11.2 maven-gpg-plugin From e486e4d0e4a78203a529eea2036320cd7ebaae66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:54:47 +0100 Subject: [PATCH 486/980] Bump com.google.protobuf:protobuf-java from 4.28.3 to 4.29.1 (#1222) * Bump com.google.protobuf:protobuf-java from 4.28.3 to 4.29.1 Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.28.3 to 4.29.1. - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl) - [Commits](https://github.com/protocolbuffers/protobuf/commits) --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * update protobuf Signed-off-by: Gregor Zeitlinger --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Doug Hoard Co-authored-by: Gregor Zeitlinger --- .tool-versions | 2 +- .../client/it/common/ExporterTest.java | 2 +- .../metrics/it/exporter/test/ExporterIT.java | 2 +- .../it/springboot/ApplicationTest.java | 2 +- .../metrics/core/metrics/CounterTest.java | 2 +- .../metrics/core/metrics/HistogramTest.java | 2 +- .../metrics/core/metrics/InfoTest.java | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- .../Metrics.java | 1838 ++++++++--------- .../PrometheusProtobufWriterImpl.java | 2 +- .../ExpositionFormatsTest.java | 2 +- 11 files changed, 929 insertions(+), 929 deletions(-) rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_28_3 => com_google_protobuf_4_29_1}/Metrics.java (88%) diff --git a/.tool-versions b/.tool-versions index 0847e3abe..a0b8f5ad4 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ java temurin-17.0.13+11 -protoc 28.3 +protoc 29.1 diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java index e1b194d7c..7f8d84715 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 4819ed924..38ebf8f31 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -5,7 +5,7 @@ import com.google.common.io.Resources; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import java.io.IOException; import java.net.URISyntaxException; import java.net.URLEncoder; diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java index 3d893d894..f986b6a24 100644 --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import java.io.IOException; import java.net.URL; import java.util.List; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index d2bf832d5..6ab4e74ca 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.CounterSnapshot; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 5a8d7cda8..fbd89ea15 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -8,7 +8,7 @@ import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 427b6a55f..54f9b6032 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.Labels; diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 1811e2c7e..7a063dc35 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -19,7 +19,7 @@ io.prometheus.metrics.expositionformats - 4.28.3 + 4.29.1 diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java similarity index 88% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java index ffa9b1d87..85e9cbb23 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_28_3/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java @@ -2,9 +2,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto -// Protobuf Java Version: 4.28.3 +// Protobuf Java Version: 4.29.1 -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3; +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1; public final class Metrics { private Metrics() {} @@ -12,8 +12,8 @@ private Metrics() {} com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Metrics.class.getName()); } @@ -85,8 +85,8 @@ public enum MetricType com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", MetricType.class.getName()); } @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.getDescriptor().getEnumTypes().get(0); + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.getDescriptor().getEnumTypes().get(0); } private static final MetricType[] VALUES = values(); @@ -265,8 +265,8 @@ public static final class LabelPair extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", LabelPair.class.getName()); } @@ -281,15 +281,15 @@ private LabelPair() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder.class); } private int bitField0_; @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair) obj; if (hasName() != other.hasName()) return false; if (hasName()) { @@ -475,44 +475,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -573,21 +573,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.newBuilder() private Builder() { } @@ -609,17 +609,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance()) return this; if (other.hasName()) { name_ = other.name_; bitField0_ |= 0x00000001; @@ -887,12 +887,12 @@ public Builder setValueBytes( } // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -961,8 +961,8 @@ public static final class Gauge extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Gauge.class.getName()); } @@ -975,15 +975,15 @@ private Gauge() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder.class); } private int bitField0_; @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1078,44 +1078,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.newBuilder() private Builder() { } @@ -1211,17 +1211,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1353,12 +1353,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar(); /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); /** * optional .google.protobuf.Timestamp created_timestamp = 3; @@ -1457,8 +1457,8 @@ public static final class Counter extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Counter.class.getName()); } @@ -1471,15 +1471,15 @@ private Counter() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder.class); } private int bitField0_; @@ -1503,7 +1503,7 @@ public double getValue() { } public static final int EXEMPLAR_FIELD_NUMBER = 2; - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1517,15 +1517,15 @@ public boolean hasExemplar() { * @return The exemplar. */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3; @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1658,44 +1658,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1808,17 +1808,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1978,9 +1978,9 @@ public Builder clearValue() { return this; } - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_; private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> exemplarBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarBuilder_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1992,9 +1992,9 @@ public boolean hasExemplar() { * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() { if (exemplarBuilder_ == null) { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } else { return exemplarBuilder_.getMessage(); } @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) { + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com * optional .io.prometheus.client.Exemplar exemplar = 2; */ public Builder setExemplar( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) { if (exemplarBuilder_ == null) { exemplar_ = builderForValue.build(); } else { @@ -2032,11 +2032,11 @@ public Builder setExemplar( /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) { + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && exemplar_ != null && - exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance()) { + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) { getExemplarBuilder().mergeFrom(value); } else { exemplar_ = value; @@ -2066,7 +2066,7 @@ public Builder clearExemplar() { /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder getExemplarBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarBuilder() { bitField0_ |= 0x00000002; onChanged(); return getExemplarFieldBuilder().getBuilder(); @@ -2074,23 +2074,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { if (exemplarBuilder_ != null) { return exemplarBuilder_.getMessageOrBuilder(); } else { return exemplar_ == null ? - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> getExemplarFieldBuilder() { if (exemplarBuilder_ == null) { exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>( getExemplar(), getParentForChildren(), isClean()); @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2309,8 +2309,8 @@ public static final class Quantile extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Quantile.class.getName()); } @@ -2323,15 +2323,15 @@ private Quantile() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder.class); } private int bitField0_; @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile) obj; if (hasQuantile() != other.hasQuantile()) return false; if (hasQuantile()) { @@ -2463,44 +2463,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.newBuilder() private Builder() { } @@ -2597,17 +2597,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance()) return this; if (other.hasQuantile()) { setQuantile(other.getQuantile()); } @@ -2791,12 +2791,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getQuantile(int index); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileOrBuilderList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index); /** @@ -2915,8 +2915,8 @@ public static final class Summary extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Summary.class.getName()); } @@ -2930,15 +2930,15 @@ private Summary() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder.class); } private int bitField0_; @@ -2982,19 +2982,19 @@ public double getSampleSum() { public static final int QUANTILE_FIELD_NUMBER = 3; @SuppressWarnings("serial") - private java.util.List quantile_; + private java.util.List quantile_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { return quantile_; } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List + public java.util.List getQuantileOrBuilderList() { return quantile_; } @@ -3009,14 +3009,14 @@ public int getQuantileCount() { * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index) { return quantile_.get(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { return quantile_.get(index); } @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary) obj; if (hasSampleCount() != other.hasSampleCount()) return false; if (hasSampleCount()) { @@ -3165,44 +3165,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3318,17 +3318,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary(this); buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary result) { + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result) { if (quantileBuilder_ == null) { if (((bitField0_ & 0x00000004) != 0)) { quantile_ = java.util.Collections.unmodifiableList(quantile_); @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance()) return this; if (other.hasSampleCount()) { setSampleCount(other.getSampleCount()); } @@ -3460,9 +3460,9 @@ public Builder mergeFrom( break; } // case 17 case 26: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.parser(), + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.parser(), extensionRegistry); if (quantileBuilder_ == null) { ensureQuantileIsMutable(); @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() { return this; } - private java.util.List quantile_ = + private java.util.List quantile_ = java.util.Collections.emptyList(); private void ensureQuantileIsMutable() { if (!((bitField0_ & 0x00000004) != 0)) { - quantile_ = new java.util.ArrayList(quantile_); + quantile_ = new java.util.ArrayList(quantile_); bitField0_ |= 0x00000004; } } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder> quantileBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder> quantileBuilder_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { if (quantileBuilder_ == null) { return java.util.Collections.unmodifiableList(quantile_); } else { @@ -3611,7 +3611,7 @@ public int getQuantileCount() { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3639,7 +3639,7 @@ public Builder setQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.set(index, builderForValue.build()); @@ -3652,7 +3652,7 @@ public Builder setQuantile( /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile value) { + public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3686,7 +3686,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(builderForValue.build()); @@ -3700,7 +3700,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(index, builderForValue.build()); @@ -3714,7 +3714,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addAllQuantile( - java.lang.Iterable values) { + java.lang.Iterable values) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder getQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder getQuantileBuilder( int index) { return getQuantileFieldBuilder().getBuilder(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileOrBuilderList() { if (quantileBuilder_ != null) { return quantileBuilder_.getMessageOrBuilderList(); @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder addQuantileBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder addQuantileBuilder() { return getQuantileFieldBuilder().addBuilder( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.getDefaultInstance()); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder addQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder addQuantileBuilder( int index) { return getQuantileFieldBuilder().addBuilder( - index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.getDefaultInstance()); + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileBuilderList() { return getQuantileFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder> getQuantileFieldBuilder() { if (quantileBuilder_ == null) { quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.QuantileOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder>( quantile_, ((bitField0_ & 0x00000004) != 0), getParentForChildren(), @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser

      getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4015,8 +4015,8 @@ public static final class Untyped extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 28, - /* patch= */ 3, + /* minor= */ 29, + /* patch= */ 1, /* suffix= */ "", Untyped.class.getName()); } @@ -4029,15 +4029,15 @@ private Untyped() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder.class); } private int bitField0_; @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -4132,44 +4132,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.newBuilder() private Builder() { } @@ -4265,17 +4265,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -4407,12 +4407,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends * * repeated .io.prometheus.client.Bucket bucket = 3; */ - java.util.List + java.util.List getBucketList(); /** *
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4929,8 +4929,8 @@ public static final class Histogram extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6580,9 +6580,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,7 +6975,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().getBuilder(index);
             }
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder addBucketBuilder() {
               return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return getBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder> 
                 getBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,7 +7648,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return getNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> 
                 getNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,7 +8243,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return getPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> 
                 getPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,7 +8814,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return getExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return getExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> 
                 getExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9040,8 +9040,8 @@ public static final class Bucket extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,7 +9841,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -9849,23 +9849,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9988,8 +9988,8 @@ public static final class BucketSpan extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10648,8 +10648,8 @@ public static final class Exemplar extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11806,8 +11806,8 @@ public static final class Metric extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,7 +12921,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getGaugeFieldBuilder().getBuilder();
      @@ -12929,23 +12929,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder> 
                 getGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,7 +13042,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCounterFieldBuilder().getBuilder();
      @@ -13050,23 +13050,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder> 
                 getCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,7 +13163,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getSummaryFieldBuilder().getBuilder();
      @@ -13171,23 +13171,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder> 
                 getSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,7 +13284,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getUntypedFieldBuilder().getBuilder();
      @@ -13292,23 +13292,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder> 
                 getUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,7 +13405,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return getHistogramFieldBuilder().getBuilder();
      @@ -13413,23 +13413,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder> 
                 getHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13631,8 +13631,8 @@ public static final class MetricFamily extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 28,
      -        /* patch= */ 3,
      +        /* minor= */ 29,
      +        /* patch= */ 1,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder addMetricBuilder() {
               return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return getMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder> 
                 getMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_28_3Z:github.com/prometheus/clien" +
      +      "obuf_4_29_1Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index a52a83adf..ab86e8bc1 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      index 1d98925e3..de0791599 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_28_3.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
      
      From a9b136c51bf9c00a8b206e61f6183b7eb1159672 Mon Sep 17 00:00:00 2001
      From: Doug Hoard 
      Date: Thu, 12 Dec 2024 00:22:13 -0500
      Subject: [PATCH 487/980] Updated README.md badges (#1229)
      
      Signed-off-by: dhoard 
      ---
       README.md | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/README.md b/README.md
      index 0cf4f3b80..f03a3e2a6 100644
      --- a/README.md
      +++ b/README.md
      @@ -1,6 +1,6 @@
       # Prometheus Java Metrics Library
       
      -[![Build Status](https://circleci.com/gh/prometheus/client_java.svg?style=svg)](https://circleci.com/gh/prometheus/client_java)
      +[![Build](https://github.com/prometheus/client_java/actions/workflows/build.yml/badge.svg)](https://github.com/prometheus/client_java/actions/workflows/build.yml) java 8+ Apache 2.0
       
       # Documentation
       
      
      From 85f78007e6ad8221de5e303b50b65ac3c8a0c5fa Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Thu, 12 Dec 2024 13:48:16 +0100
      Subject: [PATCH 488/980] update docs on new releases (#1227)
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       .github/workflows/github-pages.yaml | 2 ++
       .github/workflows/release.yml       | 2 +-
       2 files changed, 3 insertions(+), 1 deletion(-)
      
      diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml
      index 87daffd26..46fe56c96 100644
      --- a/.github/workflows/github-pages.yaml
      +++ b/.github/workflows/github-pages.yaml
      @@ -5,6 +5,8 @@ on:
         push:
           branches:
             - main
      +    tags:
      +      - "v*.*.*" # updates the version in the docs
       
         # Allows you to run this workflow manually from the Actions tab
         workflow_dispatch:
      diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
      index 57c7a6f53..bf63247f3 100644
      --- a/.github/workflows/release.yml
      +++ b/.github/workflows/release.yml
      @@ -42,7 +42,7 @@ jobs:
                 gpg-passphrase: MAVEN_GPG_PASSPHRASE
       
             - name: Publish to Apache Maven Central
      -        run: mvn deploy -P release
      +        run: mvn deploy -P release -Dmaven.test.skip=true
               env:
                 MAVEN_USERNAME: ${{ secrets.SONATYPE_MAVEN_REPOSITORY_USERNAME }}
                 MAVEN_CENTRAL_TOKEN: ${{ secrets.SONATYPE_MAVEN_REPOSITORY_PASSWORD }}
      
      From 8eea9a9562d2229fc2257118f5d2cf417225d09b Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 12 Dec 2024 13:48:43 +0100
      Subject: [PATCH 489/980] Bump org.apache.tomcat.embed:tomcat-embed-core from
       11.0.1 to 11.0.2 (#1224)
      
      * Bump org.apache.tomcat.embed:tomcat-embed-core from 11.0.1 to 11.0.2
      
      Bumps org.apache.tomcat.embed:tomcat-embed-core from 11.0.1 to 11.0.2.
      
      ---
      updated-dependencies:
      - dependency-name: org.apache.tomcat.embed:tomcat-embed-core
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      
      * tomcat fixed headers
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: dependabot[bot] 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       .../example-greeting-service/pom.xml                   |  2 +-
       .../example-hello-world-app/pom.xml                    |  2 +-
       examples/example-exporter-servlet-tomcat/pom.xml       |  2 +-
       .../it-exporter-servlet-tomcat-sample/pom.xml          |  2 +-
       .../metrics/it/exporter/test/ExporterIT.java           | 10 +---------
       .../prometheus/metrics/it/exporter/test/TomcatIT.java  |  7 -------
       6 files changed, 5 insertions(+), 20 deletions(-)
      
      diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      index 9aab1d452..86f08018c 100644
      --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml
      @@ -38,7 +38,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            11.0.1
      +            11.0.2
               
           
       
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      index 40efc62f1..0b0122cdb 100644
      --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml
      @@ -38,7 +38,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            11.0.1
      +            11.0.2
               
           
       
      diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml
      index 355f8e830..39b505f30 100644
      --- a/examples/example-exporter-servlet-tomcat/pom.xml
      +++ b/examples/example-exporter-servlet-tomcat/pom.xml
      @@ -38,7 +38,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            11.0.1
      +            11.0.2
               
           
       
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      index 78a94b724..2af2a5928 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml
      @@ -33,7 +33,7 @@
               
                   org.apache.tomcat.embed
                   tomcat-embed-core
      -            11.0.1
      +            11.0.2
               
           
       
      diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      index 38ebf8f31..199bc3387 100644
      --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      @@ -142,10 +142,6 @@ public void testErrorHandling() throws IOException {
           assertThat(response.stringBody()).contains("Simulating an error.");
         }
       
      -  protected boolean headReturnsContentLength() {
      -    return true;
      -  }
      -
         @Test
         public void testHeadRequest() throws IOException {
           start();
      @@ -154,11 +150,7 @@ public void testHeadRequest() throws IOException {
           assertThat(size).isGreaterThan(0);
           Response headResponse = scrape("HEAD", "");
           assertThat(headResponse.status).isEqualTo(200);
      -    if (headReturnsContentLength()) {
      -      assertThat(headResponse.getHeader("Content-Length")).isEqualTo(Integer.toString(size));
      -    } else {
      -      assertThat(headResponse.getHeader("Content-Length")).isNull();
      -    }
      +    assertThat(headResponse.getHeader("Content-Length")).isEqualTo(Integer.toString(size));
           assertThat(headResponse.body).isEmpty();
         }
       
      diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java
      index 731e7fa3a..ea5e6b69d 100644
      --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java
      +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/TomcatIT.java
      @@ -7,11 +7,4 @@ class TomcatIT extends ExporterIT {
         public TomcatIT() throws IOException, URISyntaxException {
           super("exporter-servlet-tomcat-sample");
         }
      -
      -  @Override
      -  protected boolean headReturnsContentLength() {
      -    // not any more since
      -    // https://tomcat.apache.org/tomcat-11.0-doc/changelog.html#Tomcat_11.0.0-M3_(markt)
      -    return false;
      -  }
       }
      
      From 3d216b8357f9161f1ced0e4bb4d9e1712ff8e88c Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 12 Dec 2024 08:41:42 -0500
      Subject: [PATCH 490/980] Bump jetty-server.version from 12.0.15 to 12.0.16
       (#1230)
      
      Bumps `jetty-server.version` from 12.0.15 to 12.0.16.
      
      Updates `org.eclipse.jetty:jetty-server` from 12.0.15 to 12.0.16
      
      Updates `org.eclipse.jetty.ee10:jetty-ee10-servlet` from 12.0.15 to 12.0.16
      
      ---
      updated-dependencies:
      - dependency-name: org.eclipse.jetty:jetty-server
        dependency-type: direct:production
        update-type: version-update:semver-patch
      - dependency-name: org.eclipse.jetty.ee10:jetty-ee10-servlet
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml        | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      index 4c4670d2f..fed800096 100644
      --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml
      @@ -15,7 +15,7 @@
               Jetty Sample for the Exporter Integration Test
           
           
      -        12.0.15
      +        12.0.16
               17
           
       
      
      From 5359ba32ffd6de588fb37ed6ab11a5c3e44efeca Mon Sep 17 00:00:00 2001
      From: Kinshuk Bairagi 
      Date: Fri, 13 Dec 2024 15:27:47 +0530
      Subject: [PATCH 491/980] Add support for dw-metrics 4.x (#1228)
      
      * Add support for dw-metrics 4.x
      
      Signed-off-by: Kinshuk Bairagi 
      
      * Update DropwizardExportsTest.java
      
      Signed-off-by: Kinshuk Bairagi 
      
      * cleanup
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: Kinshuk Bairagi 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: Gregor Zeitlinger 
      ---
       pom.xml                                       |   1 +
       .../pom.xml                                   |  79 +++++
       .../dropwizard/DropwizardExports.java         | 274 ++++++++++++++++
       .../dropwizard/DropwizardExportsTest.java     | 302 ++++++++++++++++++
       .../version-rules.xml                         |   6 +
       5 files changed, 662 insertions(+)
       create mode 100644 prometheus-metrics-instrumentation-dropwizard/pom.xml
       create mode 100644 prometheus-metrics-instrumentation-dropwizard/src/main/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExports.java
       create mode 100644 prometheus-metrics-instrumentation-dropwizard/src/test/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExportsTest.java
       create mode 100644 prometheus-metrics-instrumentation-dropwizard/version-rules.xml
      
      diff --git a/pom.xml b/pom.xml
      index 212fe042d..2f9aa6dff 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -77,6 +77,7 @@
               prometheus-metrics-instrumentation-caffeine
               prometheus-metrics-instrumentation-jvm
               prometheus-metrics-instrumentation-dropwizard5
      +        prometheus-metrics-instrumentation-dropwizard
               prometheus-metrics-instrumentation-guava
               prometheus-metrics-simpleclient-bridge
           
      diff --git a/prometheus-metrics-instrumentation-dropwizard/pom.xml b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      new file mode 100644
      index 000000000..d6f6a62ae
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      @@ -0,0 +1,79 @@
      +
      +
      +    4.0.0
      +
      +    
      +        io.prometheus
      +        client_java
      +        10.0.0-SNAPSHOT
      +    
      +
      +    prometheus-metrics-instrumentation-dropwizard
      +    bundle
      +
      +    Prometheus Metrics Instrumentation - Dropwizard 4.x
      +    
      +        Instrumentation library for Dropwizard metrics 4.x
      +    
      +
      +    
      +        io.prometheus.metrics.instrumentation.dropwizard
      +    
      +
      +    
      +        
      +            The Apache Software License, Version 2.0
      +            http://www.apache.org/licenses/LICENSE-2.0.txt
      +            repo
      +        
      +    
      +    
      +        
      +            kingster
      +            Kinshuk Bairagi
      +            hi@kinsh.uk
      +        
      +
      +    
      +
      +    
      +        
      +            io.prometheus
      +            prometheus-metrics-core
      +            ${project.version}
      +        
      +        
      +            io.dropwizard.metrics
      +            metrics-core
      +            4.2.0
      +            provided
      +        
      +
      +        
      +            io.prometheus
      +            prometheus-metrics-exporter-httpserver
      +            ${project.version}
      +            test
      +        
      +        
      +            io.prometheus
      +            prometheus-metrics-exposition-textformats
      +            ${project.version}
      +            test
      +        
      +        
      +            io.prometheus
      +            prometheus-metrics-instrumentation-dropwizard5
      +            ${project.version}
      +            compile
      +            
      +                
      +                    io.dropwizard.metrics5
      +                    metrics-core
      +                
      +            
      +        
      +
      +    
      +
      +
      diff --git a/prometheus-metrics-instrumentation-dropwizard/src/main/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard/src/main/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExports.java
      new file mode 100644
      index 000000000..dff657683
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard/src/main/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExports.java
      @@ -0,0 +1,274 @@
      +package io.prometheus.metrics.instrumentation.dropwizard;
      +
      +import com.codahale.metrics.Counter;
      +import com.codahale.metrics.Gauge;
      +import com.codahale.metrics.Histogram;
      +import com.codahale.metrics.Meter;
      +import com.codahale.metrics.Metric;
      +import com.codahale.metrics.MetricFilter;
      +import com.codahale.metrics.MetricRegistry;
      +import com.codahale.metrics.Snapshot;
      +import com.codahale.metrics.Timer;
      +import io.prometheus.metrics.instrumentation.dropwizard5.labels.CustomLabelMapper;
      +import io.prometheus.metrics.model.registry.MultiCollector;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +import io.prometheus.metrics.model.snapshots.CounterSnapshot;
      +import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
      +import io.prometheus.metrics.model.snapshots.MetricMetadata;
      +import io.prometheus.metrics.model.snapshots.MetricSnapshot;
      +import io.prometheus.metrics.model.snapshots.MetricSnapshots;
      +import io.prometheus.metrics.model.snapshots.PrometheusNaming;
      +import io.prometheus.metrics.model.snapshots.Quantiles;
      +import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      +import java.util.Collections;
      +import java.util.Optional;
      +import java.util.concurrent.TimeUnit;
      +import java.util.logging.Level;
      +import java.util.logging.Logger;
      +
      +/** Collect Dropwizard metrics from a MetricRegistry. */
      +public class DropwizardExports implements MultiCollector {
      +  private static final Logger logger = Logger.getLogger(DropwizardExports.class.getName());
      +  private final MetricRegistry registry;
      +  private final MetricFilter metricFilter;
      +  private final Optional labelMapper;
      +
      +  /**
      +   * Creates a new DropwizardExports and {@link MetricFilter#ALL}.
      +   *
      +   * @param registry a metric registry to export in prometheus.
      +   */
      +  public DropwizardExports(MetricRegistry registry) {
      +    super();
      +    this.registry = registry;
      +    this.metricFilter = MetricFilter.ALL;
      +    this.labelMapper = Optional.empty();
      +  }
      +
      +  /**
      +   * Creates a new DropwizardExports with a custom {@link MetricFilter}.
      +   *
      +   * @param registry a metric registry to export in prometheus.
      +   * @param metricFilter a custom metric filter.
      +   */
      +  public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) {
      +    this.registry = registry;
      +    this.metricFilter = metricFilter;
      +    this.labelMapper = Optional.empty();
      +  }
      +
      +  /**
      +   * @param registry a metric registry to export in prometheus.
      +   * @param metricFilter a custom metric filter.
      +   * @param labelMapper a labelMapper to use to map labels.
      +   */
      +  public DropwizardExports(
      +      MetricRegistry registry, MetricFilter metricFilter, CustomLabelMapper labelMapper) {
      +    this.registry = registry;
      +    this.metricFilter = metricFilter;
      +    this.labelMapper = Optional.ofNullable(labelMapper);
      +  }
      +
      +  private static String getHelpMessage(String metricName, Metric metric) {
      +    return String.format(
      +        "Generated from Dropwizard metric import (metric=%s, type=%s)",
      +        metricName, metric.getClass().getName());
      +  }
      +
      +  private MetricMetadata getMetricMetaData(String metricName, Metric metric) {
      +    String name = labelMapper.isPresent() ? labelMapper.get().getName(metricName) : metricName;
      +    return new MetricMetadata(
      +        PrometheusNaming.sanitizeMetricName(name), getHelpMessage(metricName, metric));
      +  }
      +
      +  /**
      +   * Export counter as Prometheus Gauge.
      +   */
      +  MetricSnapshot fromCounter(String dropwizardName, Counter counter) {
      +    MetricMetadata metadata = getMetricMetaData(dropwizardName, counter);
      +    CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder =
      +        CounterSnapshot.CounterDataPointSnapshot.builder()
      +            .value(Long.valueOf(counter.getCount()).doubleValue());
      +    labelMapper.ifPresent(
      +        mapper ->
      +            dataPointBuilder.labels(
      +                mapper.getLabels(
      +                    dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +    return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +  }
      +
      +  /** Export gauge as a prometheus gauge. */
      +  MetricSnapshot fromGauge(String dropwizardName, Gauge gauge) {
      +    Object obj = gauge.getValue();
      +    double value;
      +    if (obj instanceof Number) {
      +      value = ((Number) obj).doubleValue();
      +    } else if (obj instanceof Boolean) {
      +      value = ((Boolean) obj) ? 1 : 0;
      +    } else {
      +      logger.log(
      +          Level.FINE,
      +          String.format(
      +              "Invalid type for Gauge %s: %s",
      +              PrometheusNaming.sanitizeMetricName(dropwizardName),
      +              obj == null ? "null" : obj.getClass().getName()));
      +      return null;
      +    }
      +    MetricMetadata metadata = getMetricMetaData(dropwizardName, gauge);
      +    GaugeSnapshot.GaugeDataPointSnapshot.Builder dataPointBuilder =
      +        GaugeSnapshot.GaugeDataPointSnapshot.builder().value(value);
      +    labelMapper.ifPresent(
      +        mapper ->
      +            dataPointBuilder.labels(
      +                mapper.getLabels(
      +                    dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +    return new GaugeSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +  }
      +
      +  /**
      +   * Export a histogram snapshot as a prometheus SUMMARY.
      +   *
      +   * @param dropwizardName metric name.
      +   * @param snapshot the histogram snapshot.
      +   * @param count the total sample count for this snapshot.
      +   * @param factor a factor to apply to histogram values.
      +   */
      +  MetricSnapshot fromSnapshotAndCount(
      +      String dropwizardName, Snapshot snapshot, long count, double factor, String helpMessage) {
      +    Quantiles quantiles =
      +        Quantiles.builder()
      +            .quantile(0.5, snapshot.getMedian() * factor)
      +            .quantile(0.75, snapshot.get75thPercentile() * factor)
      +            .quantile(0.95, snapshot.get95thPercentile() * factor)
      +            .quantile(0.98, snapshot.get98thPercentile() * factor)
      +            .quantile(0.99, snapshot.get99thPercentile() * factor)
      +            .quantile(0.999, snapshot.get999thPercentile() * factor)
      +            .build();
      +
      +    MetricMetadata metadata =
      +        new MetricMetadata(PrometheusNaming.sanitizeMetricName(dropwizardName), helpMessage);
      +    SummarySnapshot.SummaryDataPointSnapshot.Builder dataPointBuilder =
      +        SummarySnapshot.SummaryDataPointSnapshot.builder().quantiles(quantiles).count(count);
      +    labelMapper.ifPresent(
      +        mapper ->
      +            dataPointBuilder.labels(
      +                mapper.getLabels(
      +                    dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +    return new SummarySnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +  }
      +
      +  /** Convert histogram snapshot. */
      +  MetricSnapshot fromHistogram(String dropwizardName, Histogram histogram) {
      +    return fromSnapshotAndCount(
      +        dropwizardName,
      +        histogram.getSnapshot(),
      +        histogram.getCount(),
      +        1.0,
      +        getHelpMessage(dropwizardName, histogram));
      +  }
      +
      +  /** Export Dropwizard Timer as a histogram. Use TIME_UNIT as time unit. */
      +  MetricSnapshot fromTimer(String dropwizardName, Timer timer) {
      +    return fromSnapshotAndCount(
      +        dropwizardName,
      +        timer.getSnapshot(),
      +        timer.getCount(),
      +        1.0D / TimeUnit.SECONDS.toNanos(1L),
      +        getHelpMessage(dropwizardName, timer));
      +  }
      +
      +  /** Export a Meter as a prometheus COUNTER. */
      +  MetricSnapshot fromMeter(String dropwizardName, Meter meter) {
      +    MetricMetadata metadata = getMetricMetaData(dropwizardName + "_total", meter);
      +    CounterSnapshot.CounterDataPointSnapshot.Builder dataPointBuilder =
      +        CounterSnapshot.CounterDataPointSnapshot.builder().value(meter.getCount());
      +    labelMapper.ifPresent(
      +        mapper ->
      +            dataPointBuilder.labels(
      +                mapper.getLabels(
      +                    dropwizardName, Collections.emptyList(), Collections.emptyList())));
      +    return new CounterSnapshot(metadata, Collections.singletonList(dataPointBuilder.build()));
      +  }
      +
      +  @Override
      +  public MetricSnapshots collect() {
      +    MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder();
      +
      +    registry
      +        .getGauges(metricFilter)
      +        .forEach(
      +            (name, gauge) -> {
      +              MetricSnapshot snapshot = fromGauge(name, gauge);
      +              if (snapshot != null) {
      +                metricSnapshots.metricSnapshot(snapshot);
      +              }
      +            });
      +
      +    registry
      +        .getCounters(metricFilter)
      +        .forEach((name, counter) -> metricSnapshots.metricSnapshot(fromCounter(name, counter)));
      +    registry
      +        .getHistograms(metricFilter)
      +        .forEach(
      +            (name, histogram) -> metricSnapshots.metricSnapshot(fromHistogram(name, histogram)));
      +    registry
      +        .getTimers(metricFilter)
      +        .forEach((name, timer) -> metricSnapshots.metricSnapshot(fromTimer(name, timer)));
      +    registry
      +        .getMeters(metricFilter)
      +        .forEach((name, meter) -> metricSnapshots.metricSnapshot(fromMeter(name, meter)));
      +
      +    return metricSnapshots.build();
      +  }
      +
      +  public static Builder builder() {
      +    return new Builder();
      +  }
      +
      +  // Builder class for DropwizardExports
      +  public static class Builder {
      +    private MetricRegistry registry;
      +    private MetricFilter metricFilter;
      +    private CustomLabelMapper labelMapper;
      +
      +    private Builder() {
      +      this.metricFilter = MetricFilter.ALL;
      +    }
      +
      +    public Builder dropwizardRegistry(MetricRegistry registry) {
      +      this.registry = registry;
      +      return this;
      +    }
      +
      +    public Builder metricFilter(MetricFilter metricFilter) {
      +      this.metricFilter = metricFilter;
      +      return this;
      +    }
      +
      +    public Builder customLabelMapper(CustomLabelMapper labelMapper) {
      +      this.labelMapper = labelMapper;
      +      return this;
      +    }
      +
      +    DropwizardExports build() {
      +      if (registry == null) {
      +        throw new IllegalArgumentException("MetricRegistry must be set");
      +      }
      +      if (labelMapper == null) {
      +        return new DropwizardExports(registry, metricFilter);
      +      } else {
      +        return new DropwizardExports(registry, metricFilter, labelMapper);
      +      }
      +    }
      +
      +    public void register() {
      +      register(PrometheusRegistry.defaultRegistry);
      +    }
      +
      +    public void register(PrometheusRegistry registry) {
      +      DropwizardExports dropwizardExports = build();
      +      registry.register(dropwizardExports);
      +    }
      +  }
      +}
      diff --git a/prometheus-metrics-instrumentation-dropwizard/src/test/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExportsTest.java b/prometheus-metrics-instrumentation-dropwizard/src/test/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExportsTest.java
      new file mode 100644
      index 000000000..ff658ad41
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard/src/test/java/io/prometheus/metrics/instrumentation/dropwizard/DropwizardExportsTest.java
      @@ -0,0 +1,302 @@
      +package io.prometheus.metrics.instrumentation.dropwizard;
      +
      +import static org.assertj.core.api.Assertions.assertThat;
      +import static org.assertj.core.api.Assertions.assertThatCode;
      +import static org.assertj.core.api.Assertions.assertThatThrownBy;
      +
      +import com.codahale.metrics.*;
      +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      +import io.prometheus.metrics.model.registry.PrometheusRegistry;
      +import io.prometheus.metrics.model.snapshots.SummarySnapshot;
      +import java.io.ByteArrayOutputStream;
      +import java.io.IOException;
      +import java.nio.charset.StandardCharsets;
      +import java.util.concurrent.TimeUnit;
      +import org.junit.jupiter.api.BeforeEach;
      +import org.junit.jupiter.api.Test;
      +
      +class DropwizardExportsTest {
      +
      +  private final PrometheusRegistry registry = new PrometheusRegistry();
      +  private MetricRegistry metricRegistry;
      +
      +  @BeforeEach
      +  public void setUp() {
      +    metricRegistry = new MetricRegistry();
      +    DropwizardExports.builder()
      +        .dropwizardRegistry(metricRegistry)
      +        .metricFilter(MetricFilter.ALL)
      +        .register(registry);
      +  }
      +
      +  @Test
      +  public void testBuilderThrowsErrorOnNullRegistry() {
      +    assertThatThrownBy(
      +            () -> DropwizardExports.builder().dropwizardRegistry(null).register(registry))
      +        .isInstanceOf(IllegalArgumentException.class);
      +  }
      +
      +  @Test
      +  public void testBuilderCreatesOkay() {
      +    assertThatCode(
      +            () -> DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(registry))
      +        .doesNotThrowAnyException();
      +  }
      +
      +  @Test
      +  public void testCounter() {
      +    metricRegistry.counter("foo.bar").inc(1);
      +    String expected =
      +        """
      +        # TYPE foo_bar counter
      +        # HELP foo_bar Generated from Dropwizard metric import (metric=foo.bar, type=com.codahale.metrics.Counter)
      +        foo_bar_total 1.0
      +        # EOF
      +        """;
      +
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  @Test
      +  public void testGauge() {
      +    // don't convert to lambda, as we need to test the type
      +    Gauge integerGauge =
      +        new Gauge() {
      +          @Override
      +          public Integer getValue() {
      +            return 1234;
      +          }
      +        };
      +    Gauge doubleGauge =
      +        new Gauge() {
      +          @Override
      +          public Double getValue() {
      +            return 1.234D;
      +          }
      +        };
      +    Gauge longGauge =
      +        new Gauge() {
      +          @Override
      +          public Long getValue() {
      +            return 1234L;
      +          }
      +        };
      +    Gauge floatGauge =
      +        new Gauge() {
      +          @Override
      +          public Float getValue() {
      +            return 0.1234F;
      +          }
      +        };
      +    Gauge booleanGauge =
      +        new Gauge() {
      +          @Override
      +          public Boolean getValue() {
      +            return true;
      +          }
      +        };
      +
      +    metricRegistry.register("double.gauge", doubleGauge);
      +    metricRegistry.register("long.gauge", longGauge);
      +    metricRegistry.register("integer.gauge", integerGauge);
      +    metricRegistry.register("float.gauge", floatGauge);
      +    metricRegistry.register("boolean.gauge", booleanGauge);
      +
      +    String expected =
      +        """
      +        # TYPE boolean_gauge gauge
      +        # HELP boolean_gauge Generated from Dropwizard metric import (metric=boolean.gauge, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$5)
      +        boolean_gauge 1.0
      +        # TYPE double_gauge gauge
      +        # HELP double_gauge Generated from Dropwizard metric import (metric=double.gauge, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$2)
      +        double_gauge 1.234
      +        # TYPE float_gauge gauge
      +        # HELP float_gauge Generated from Dropwizard metric import (metric=float.gauge, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$4)
      +        float_gauge 0.1234000027179718
      +        # TYPE integer_gauge gauge
      +        # HELP integer_gauge Generated from Dropwizard metric import (metric=integer.gauge, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$1)
      +        integer_gauge 1234.0
      +        # TYPE long_gauge gauge
      +        # HELP long_gauge Generated from Dropwizard metric import (metric=long.gauge, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$3)
      +        long_gauge 1234.0
      +        # EOF
      +        """;
      +
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  @Test
      +  public void testInvalidGaugeType() {
      +    Gauge invalidGauge = () -> "foobar";
      +
      +    metricRegistry.register("invalid_gauge", invalidGauge);
      +
      +    String expected = "# EOF\n";
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  @Test
      +  public void testGaugeReturningNullValue() {
      +    Gauge invalidGauge = () -> null;
      +    metricRegistry.register("invalid_gauge", invalidGauge);
      +    String expected = "# EOF\n";
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  @Test
      +  public void testHistogram() {
      +    // just test the standard mapper
      +    final MetricRegistry metricRegistry = new MetricRegistry();
      +    PrometheusRegistry pmRegistry = new PrometheusRegistry();
      +    DropwizardExports.builder().dropwizardRegistry(metricRegistry).register(pmRegistry);
      +
      +    Histogram hist = metricRegistry.histogram("hist");
      +    int i = 0;
      +    while (i < 100) {
      +      hist.update(i);
      +      i += 1;
      +    }
      +
      +    // The result should look like this
      +    String expected1 =
      +        """
      +        # TYPE hist summary
      +        # HELP hist Generated from Dropwizard metric import (metric=hist, type=com.codahale.metrics.Histogram)
      +        hist{quantile="0.5"} 49.0
      +        hist{quantile="0.75"} 74.0
      +        hist{quantile="0.95"} 94.0
      +        hist{quantile="0.98"} 97.0
      +        hist{quantile="0.99"} 98.0
      +        hist{quantile="0.999"} 99.0
      +        hist_count 100
      +        # EOF
      +        """;
      +
      +    // However, Dropwizard uses a random reservoir sampling algorithm, so the values could as well
      +    // be off-by-one
      +    String expected2 =
      +        """
      +        # TYPE hist summary
      +        # HELP hist Generated from Dropwizard metric import (metric=hist, type=com.codahale.metrics.Histogram)
      +        hist{quantile="0.5"} 50.0
      +        hist{quantile="0.75"} 75.0
      +        hist{quantile="0.95"} 95.0
      +        hist{quantile="0.98"} 98.0
      +        hist{quantile="0.99"} 99.0
      +        hist{quantile="0.999"} 99.0
      +        hist_count 100
      +        # EOF
      +        """;
      +
      +    // The following asserts the values matches either of the expected value.
      +    String textFormat = convertToOpenMetricsFormat(pmRegistry);
      +    assertThat(textFormat)
      +        .satisfiesAnyOf(
      +            text -> assertThat(text).isEqualTo(expected1),
      +            text -> assertThat(text).isEqualTo(expected2));
      +  }
      +
      +  @Test
      +  public void testMeter() {
      +    Meter meter = metricRegistry.meter("meter");
      +    meter.mark();
      +    meter.mark();
      +
      +    String expected =
      +        """
      +        # TYPE meter counter
      +        # HELP meter Generated from Dropwizard metric import (metric=meter_total, type=com.codahale.metrics.Meter)
      +        meter_total 2.0
      +        # EOF
      +        """;
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  @Test
      +  public void testTimer() throws InterruptedException {
      +    final MetricRegistry metricRegistry = new MetricRegistry();
      +    DropwizardExports exports = new DropwizardExports(metricRegistry);
      +    Timer t = metricRegistry.timer("timer");
      +    Timer.Context time = t.time();
      +    Thread.sleep(100L);
      +    long timeSpentNanos = time.stop();
      +    double timeSpentMillis = TimeUnit.NANOSECONDS.toMillis(timeSpentNanos);
      +
      +    assertThat(exports.collect().stream().flatMap(i1 -> i1.getDataPoints().stream()).findFirst())
      +        .containsInstanceOf(SummarySnapshot.SummaryDataPointSnapshot.class)
      +        .hasValueSatisfying(
      +            snapshot -> {
      +              var dataPointSnapshot = (SummarySnapshot.SummaryDataPointSnapshot) snapshot;
      +              // We slept for 1Ms so we ensure that all timers are above 1ms:
      +              assertThat(dataPointSnapshot.getQuantiles().size()).isGreaterThan(1);
      +              dataPointSnapshot
      +                  .getQuantiles()
      +                  .forEach(i -> assertThat(i.getValue()).isGreaterThan(timeSpentMillis / 1000d));
      +              assertThat(dataPointSnapshot.getCount()).isOne();
      +            });
      +  }
      +
      +  @Test
      +  public void testThatMetricHelpUsesOriginalDropwizardName() {
      +    metricRegistry.timer("my.application.namedTimer1");
      +    metricRegistry.counter("my.application.namedCounter1");
      +    metricRegistry.meter("my.application.namedMeter1");
      +    metricRegistry.histogram("my.application.namedHistogram1");
      +    metricRegistry.register("my.application.namedGauge1", new ExampleDoubleGauge());
      +
      +    String expected =
      +        """
      +        # TYPE my_application_namedCounter1 counter
      +        # HELP my_application_namedCounter1 Generated from Dropwizard metric import (metric=my.application.namedCounter1, type=com.codahale.metrics.Counter)
      +        my_application_namedCounter1_total 0.0
      +        # TYPE my_application_namedGauge1 gauge
      +        # HELP my_application_namedGauge1 Generated from Dropwizard metric import (metric=my.application.namedGauge1, type=io.prometheus.metrics.instrumentation.dropwizard.DropwizardExportsTest$ExampleDoubleGauge)
      +        my_application_namedGauge1 0.0
      +        # TYPE my_application_namedHistogram1 summary
      +        # HELP my_application_namedHistogram1 Generated from Dropwizard metric import (metric=my.application.namedHistogram1, type=com.codahale.metrics.Histogram)
      +        my_application_namedHistogram1{quantile="0.5"} 0.0
      +        my_application_namedHistogram1{quantile="0.75"} 0.0
      +        my_application_namedHistogram1{quantile="0.95"} 0.0
      +        my_application_namedHistogram1{quantile="0.98"} 0.0
      +        my_application_namedHistogram1{quantile="0.99"} 0.0
      +        my_application_namedHistogram1{quantile="0.999"} 0.0
      +        my_application_namedHistogram1_count 0
      +        # TYPE my_application_namedMeter1 counter
      +        # HELP my_application_namedMeter1 Generated from Dropwizard metric import (metric=my.application.namedMeter1_total, type=com.codahale.metrics.Meter)
      +        my_application_namedMeter1_total 0.0
      +        # TYPE my_application_namedTimer1 summary
      +        # HELP my_application_namedTimer1 Generated from Dropwizard metric import (metric=my.application.namedTimer1, type=com.codahale.metrics.Timer)
      +        my_application_namedTimer1{quantile="0.5"} 0.0
      +        my_application_namedTimer1{quantile="0.75"} 0.0
      +        my_application_namedTimer1{quantile="0.95"} 0.0
      +        my_application_namedTimer1{quantile="0.98"} 0.0
      +        my_application_namedTimer1{quantile="0.99"} 0.0
      +        my_application_namedTimer1{quantile="0.999"} 0.0
      +        my_application_namedTimer1_count 0
      +        # EOF
      +        """;
      +    assertThat(convertToOpenMetricsFormat()).isEqualTo(expected);
      +  }
      +
      +  private static class ExampleDoubleGauge implements Gauge {
      +    @Override
      +    public Double getValue() {
      +      return 0.0;
      +    }
      +  }
      +
      +  private String convertToOpenMetricsFormat(PrometheusRegistry _registry) {
      +    ByteArrayOutputStream out = new ByteArrayOutputStream();
      +    OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true);
      +    try {
      +      writer.write(out, _registry.scrape());
      +      return out.toString(StandardCharsets.UTF_8);
      +    } catch (IOException e) {
      +      throw new RuntimeException(e);
      +    }
      +  }
      +
      +  private String convertToOpenMetricsFormat() {
      +    return convertToOpenMetricsFormat(registry);
      +  }
      +}
      diff --git a/prometheus-metrics-instrumentation-dropwizard/version-rules.xml b/prometheus-metrics-instrumentation-dropwizard/version-rules.xml
      new file mode 100644
      index 000000000..5c6d39593
      --- /dev/null
      +++ b/prometheus-metrics-instrumentation-dropwizard/version-rules.xml
      @@ -0,0 +1,6 @@
      +
      +    
      +    
      +
      
      From d93618b28fbeaedf86dbebc1f09bda34e85b7f5e Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 13 Dec 2024 15:28:24 +0100
      Subject: [PATCH 492/980] Bump io.dropwizard.metrics:metrics-core from 4.2.0 to
       4.2.29 (#1231)
      
      Bumps [io.dropwizard.metrics:metrics-core](https://github.com/dropwizard/metrics) from 4.2.0 to 4.2.29.
      - [Release notes](https://github.com/dropwizard/metrics/releases)
      - [Commits](https://github.com/dropwizard/metrics/compare/v4.2.0...v4.2.29)
      
      ---
      updated-dependencies:
      - dependency-name: io.dropwizard.metrics:metrics-core
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       prometheus-metrics-instrumentation-dropwizard/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/prometheus-metrics-instrumentation-dropwizard/pom.xml b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      index d6f6a62ae..e17b11e96 100644
      --- a/prometheus-metrics-instrumentation-dropwizard/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      @@ -45,7 +45,7 @@
               
                   io.dropwizard.metrics
                   metrics-core
      -            4.2.0
      +            4.2.29
                   provided
               
       
      
      From e5a0e74acde0abcd98914c41a7593755a7c754c9 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 16 Dec 2024 08:49:53 -0500
      Subject: [PATCH 493/980] Bump junit-jupiter.version from 5.11.3 to 5.11.4
       (#1233)
      
      Bumps `junit-jupiter.version` from 5.11.3 to 5.11.4.
      
      Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.3 to 5.11.4
      - [Release notes](https://github.com/junit-team/junit5/releases)
      - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4)
      
      Updates `org.junit.jupiter:junit-jupiter-params` from 5.11.3 to 5.11.4
      - [Release notes](https://github.com/junit-team/junit5/releases)
      - [Commits](https://github.com/junit-team/junit5/compare/r5.11.3...r5.11.4)
      
      ---
      updated-dependencies:
      - dependency-name: org.junit.jupiter:junit-jupiter-engine
        dependency-type: direct:development
        update-type: version-update:semver-patch
      - dependency-name: org.junit.jupiter:junit-jupiter-params
        dependency-type: direct:development
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 2f9aa6dff..3d96195bb 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -17,7 +17,7 @@
           
               UTF-8
               --module-name-need-to-be-overriden--
      -        5.11.3
      +        5.11.4
               2.10.0-alpha
               8
               0.70
      
      From 21af74ee3d1ac22b97b40cdc4f28bffb76c62eb7 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Tue, 17 Dec 2024 14:46:49 +0100
      Subject: [PATCH 494/980] Bump com.google.guava:guava from 33.3.1-jre to
       33.4.0-jre (#1234)
      
      Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.3.1-jre to 33.4.0-jre.
      - [Release notes](https://github.com/google/guava/releases)
      - [Commits](https://github.com/google/guava/commits)
      
      ---
      updated-dependencies:
      - dependency-name: com.google.guava:guava
        dependency-type: direct:development
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 3d96195bb..a0afdf4dd 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -87,7 +87,7 @@
                   
                       com.google.guava
                       guava
      -                33.3.1-jre
      +                33.4.0-jre
                   
               
           
      
      From efd138d429d3cefa956f7c76ec40ed09e4ae58eb Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Wed, 18 Dec 2024 12:57:04 +0100
      Subject: [PATCH 495/980] update oats (#1236)
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       .github/workflows/acceptance-tests.yml                         | 2 +-
       .../example-exporter-opentelemetry/oats-tests/agent/oats.yaml  | 1 -
       .../example-exporter-opentelemetry/oats-tests/http/oats.yaml   | 1 -
       scripts/run-acceptance-tests.sh                                | 3 +--
       4 files changed, 2 insertions(+), 5 deletions(-)
      
      diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml
      index e6a64579e..857bc5b01 100644
      --- a/.github/workflows/acceptance-tests.yml
      +++ b/.github/workflows/acceptance-tests.yml
      @@ -15,7 +15,7 @@ jobs:
               uses: actions/checkout@v4
               with:
                 repository: grafana/oats
      -          ref: 7cd5ca42fff009fd67ea986d42c79134ac99ae48
      +          ref: v0.1.0
                 path: oats
             - name: Set up JDK
               uses: actions/setup-java@v4
      diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml b/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml
      index 08e4d8d3f..acd85ab11 100644
      --- a/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml
      +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/oats.yaml
      @@ -1,6 +1,5 @@
       # OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml
       docker-compose:
      -  generator: docker-lgtm
         files:
           - ./docker-compose.yml
       expected:
      diff --git a/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml b/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml
      index a3af9ffc2..accca127d 100644
      --- a/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml
      +++ b/examples/example-exporter-opentelemetry/oats-tests/http/oats.yaml
      @@ -1,6 +1,5 @@
       # OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats/tree/main/yaml
       docker-compose:
      -  generator: docker-lgtm
         files:
           - ./docker-compose.yml
       expected:
      diff --git a/scripts/run-acceptance-tests.sh b/scripts/run-acceptance-tests.sh
      index 151783f77..f72b98573 100755
      --- a/scripts/run-acceptance-tests.sh
      +++ b/scripts/run-acceptance-tests.sh
      @@ -4,7 +4,6 @@ set -euo pipefail
       
       cd oats/yaml
       go install github.com/onsi/ginkgo/v2/ginkgo
      -export TESTCASE_SKIP_BUILD=true
       export TESTCASE_TIMEOUT=5m
       export TESTCASE_BASE_PATH=../../examples
      -ginkgo -r # is parallel causing problems? -p
      +ginkgo
      
      From f2329a7b1292458c9243bca3c6860db6e69b5090 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 19 Dec 2024 15:42:19 +0100
      Subject: [PATCH 496/980] Bump
       org.springframework.boot:spring-boot-starter-parent (#1238)
      
      Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.4.0 to 3.4.1.
      - [Release notes](https://github.com/spring-projects/spring-boot/releases)
      - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.0...v3.4.1)
      
      ---
      updated-dependencies:
      - dependency-name: org.springframework.boot:spring-boot-starter-parent
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml
      index fc5fc6083..2121c27c0 100644
      --- a/integration-tests/it-spring-boot-smoke-test/pom.xml
      +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml
      @@ -7,7 +7,7 @@
           
               org.springframework.boot
               spring-boot-starter-parent
      -        3.4.0
      +        3.4.1
                
           
       
      
      From 5139324e58e8f297fd44b0c3023bfecdc4e2e61f Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 19 Dec 2024 18:43:55 +0100
      Subject: [PATCH 497/980] Bump com.google.protobuf:protobuf-java from 4.29.1 to
       4.29.2 (#1237)
      
      * Bump com.google.protobuf:protobuf-java from 4.29.1 to 4.29.2
      
      Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.29.1 to 4.29.2.
      - [Release notes](https://github.com/protocolbuffers/protobuf/releases)
      - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl)
      - [Commits](https://github.com/protocolbuffers/protobuf/commits)
      
      ---
      updated-dependencies:
      - dependency-name: com.google.protobuf:protobuf-java
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      
      * update protobuf
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: dependabot[bot] 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       .github/workflows/acceptance-tests.yml        |    2 +-
       .tool-versions                                |    2 +-
       .../client/it/common/ExporterTest.java        |    2 +-
       .../metrics/it/exporter/test/ExporterIT.java  |    2 +-
       .../it/springboot/ApplicationTest.java        |    2 +-
       .../metrics/core/metrics/CounterTest.java     |    2 +-
       .../metrics/core/metrics/HistogramTest.java   |    2 +-
       .../metrics/core/metrics/InfoTest.java        |    2 +-
       prometheus-metrics-exposition-formats/pom.xml |    2 +-
       .../Metrics.java                              | 1810 ++++++++---------
       .../PrometheusProtobufWriterImpl.java         |    2 +-
       .../ExpositionFormatsTest.java                |    2 +-
       12 files changed, 916 insertions(+), 916 deletions(-)
       rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_29_1 => com_google_protobuf_4_29_2}/Metrics.java (89%)
      
      diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml
      index 857bc5b01..3baa62489 100644
      --- a/.github/workflows/acceptance-tests.yml
      +++ b/.github/workflows/acceptance-tests.yml
      @@ -37,5 +37,5 @@ jobs:
               uses: actions/upload-artifact@v4
               if: failure()
               with:
      -          name: docker-compose.log
      +          name: OATS logs
                 path: oats/yaml/build/**/*.log
      diff --git a/.tool-versions b/.tool-versions
      index a0b8f5ad4..477916d84 100644
      --- a/.tool-versions
      +++ b/.tool-versions
      @@ -1,2 +1,2 @@
       java temurin-17.0.13+11
      -protoc 29.1
      +protoc 29.2
      diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      index 7f8d84715..97d133e8c 100644
      --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      @@ -4,7 +4,7 @@
       import static org.assertj.core.api.Assertions.assertThat;
       import static org.assertj.core.api.Assertions.fail;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import java.io.ByteArrayInputStream;
       import java.io.IOException;
       import java.io.InputStream;
      diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      index 199bc3387..60bd7ab59 100644
      --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      @@ -5,7 +5,7 @@
       
       import com.google.common.io.Resources;
       import io.prometheus.client.it.common.ExporterTest;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import java.io.IOException;
       import java.net.URISyntaxException;
       import java.net.URLEncoder;
      diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      index f986b6a24..7abf16e9d 100644
      --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      @@ -3,7 +3,7 @@
       import static org.assertj.core.api.Assertions.assertThat;
       
       import io.prometheus.client.it.common.ExporterTest;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import java.io.IOException;
       import java.net.URL;
       import java.util.List;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      index 6ab4e74ca..7f6dd20f6 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      @@ -6,7 +6,7 @@
       import static org.assertj.core.data.Offset.offset;
       
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      index fbd89ea15..69453ea13 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      @@ -8,7 +8,7 @@
       import io.prometheus.metrics.core.datapoints.DistributionDataPoint;
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      index 54f9b6032..e4878eb42 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      @@ -4,7 +4,7 @@
       import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
       
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.Labels;
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 7a063dc35..0c2a686a8 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -19,7 +19,7 @@
       
           
               io.prometheus.metrics.expositionformats
      -        4.29.1
      +        4.29.2
           
       
           
      diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java
      similarity index 89%
      rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java
      rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java
      index 85e9cbb23..2e7f28311 100644
      --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_1/Metrics.java
      +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java
      @@ -2,9 +2,9 @@
       // Generated by the protocol buffer compiler.  DO NOT EDIT!
       // NO CHECKED-IN PROTOBUF GENCODE
       // source: src/main/protobuf/metrics.proto
      -// Protobuf Java Version: 4.29.1
      +// Protobuf Java Version: 4.29.2
       
      -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1;
      +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2;
       
       public final class Metrics {
         private Metrics() {}
      @@ -13,7 +13,7 @@ private Metrics() {}
             com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
             /* major= */ 4,
             /* minor= */ 29,
      -      /* patch= */ 1,
      +      /* patch= */ 2,
             /* suffix= */ "",
             Metrics.class.getName());
         }
      @@ -86,7 +86,7 @@ public enum MetricType
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               MetricType.class.getName());
           }
      @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) {
           }
           public static final com.google.protobuf.Descriptors.EnumDescriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.getDescriptor().getEnumTypes().get(0);
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.getDescriptor().getEnumTypes().get(0);
           }
       
           private static final MetricType[] VALUES = values();
      @@ -266,7 +266,7 @@ public static final class LabelPair extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               LabelPair.class.getName());
           }
      @@ -281,15 +281,15 @@ private LabelPair() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder.class);
           }
       
           private int bitField0_;
      @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -475,44 +475,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -573,21 +573,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.newBuilder()
             private Builder() {
       
             }
      @@ -609,17 +609,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -887,12 +887,12 @@ public Builder setValueBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -962,7 +962,7 @@ public static final class Gauge extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Gauge.class.getName());
           }
      @@ -975,15 +975,15 @@ private Gauge() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder.class);
           }
       
           private int bitField0_;
      @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1078,44 +1078,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.newBuilder()
             private Builder() {
       
             }
      @@ -1211,17 +1211,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1353,12 +1353,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
       
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
      @@ -1458,7 +1458,7 @@ public static final class Counter extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Counter.class.getName());
           }
      @@ -1471,15 +1471,15 @@ private Counter() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder.class);
           }
       
           private int bitField0_;
      @@ -1503,7 +1503,7 @@ public double getValue() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return Whether the exemplar field is set.
      @@ -1517,15 +1517,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3;
      @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1658,44 +1658,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -1808,17 +1808,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1978,9 +1978,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return Whether the exemplar field is set.
      @@ -1992,9 +1992,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -2032,11 +2032,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -2066,7 +2066,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -2074,23 +2074,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2310,7 +2310,7 @@ public static final class Quantile extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Quantile.class.getName());
           }
      @@ -2323,15 +2323,15 @@ private Quantile() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder.class);
           }
       
           private int bitField0_;
      @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile) obj;
       
             if (hasQuantile() != other.hasQuantile()) return false;
             if (hasQuantile()) {
      @@ -2463,44 +2463,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.newBuilder()
             private Builder() {
       
             }
      @@ -2597,17 +2597,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance()) return this;
               if (other.hasQuantile()) {
                 setQuantile(other.getQuantile());
               }
      @@ -2791,12 +2791,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index);
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileOrBuilderList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index);
       
           /**
      @@ -2916,7 +2916,7 @@ public static final class Summary extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Summary.class.getName());
           }
      @@ -2930,15 +2930,15 @@ private Summary() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder.class);
           }
       
           private int bitField0_;
      @@ -2982,19 +2982,19 @@ public double getSampleSum() {
       
           public static final int QUANTILE_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List quantile_;
      +    private java.util.List quantile_;
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List getQuantileList() {
      +    public java.util.List getQuantileList() {
             return quantile_;
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getQuantileOrBuilderList() {
             return quantile_;
           }
      @@ -3009,14 +3009,14 @@ public int getQuantileCount() {
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index) {
             return quantile_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index) {
             return quantile_.get(index);
           }
      @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -3165,44 +3165,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -3318,17 +3318,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result) {
               if (quantileBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0)) {
                   quantile_ = java.util.Collections.unmodifiableList(quantile_);
      @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -3460,9 +3460,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.parser(),
                               extensionRegistry);
                       if (quantileBuilder_ == null) {
                         ensureQuantileIsMutable();
      @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List quantile_ =
      +      private java.util.List quantile_ =
               java.util.Collections.emptyList();
             private void ensureQuantileIsMutable() {
               if (!((bitField0_ & 0x00000004) != 0)) {
      -          quantile_ = new java.util.ArrayList(quantile_);
      +          quantile_ = new java.util.ArrayList(quantile_);
                 bitField0_ |= 0x00000004;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder> quantileBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder> quantileBuilder_;
       
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List getQuantileList() {
      +      public java.util.List getQuantileList() {
               if (quantileBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(quantile_);
               } else {
      @@ -3611,7 +3611,7 @@ public int getQuantileCount() {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile getQuantile(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);
               } else {
      @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3639,7 +3639,7 @@ public Builder setQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.set(index, builderForValue.build());
      @@ -3652,7 +3652,7 @@ public Builder setQuantile(
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) {
      +      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3686,7 +3686,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(builderForValue.build());
      @@ -3700,7 +3700,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(index, builderForValue.build());
      @@ -3714,7 +3714,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addAllQuantile(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder getQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder getQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
                 int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);  } else {
      @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileOrBuilderList() {
               if (quantileBuilder_ != null) {
                 return quantileBuilder_.getMessageOrBuilderList();
      @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder addQuantileBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder addQuantileBuilder() {
               return getQuantileFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder addQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder addQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileBuilderList() {
               return getQuantileFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder> 
                 getQuantileFieldBuilder() {
               if (quantileBuilder_ == null) {
                 quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.QuantileOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder>(
                         quantile_,
                         ((bitField0_ & 0x00000004) != 0),
                         getParentForChildren(),
      @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4016,7 +4016,7 @@ public static final class Untyped extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Untyped.class.getName());
           }
      @@ -4029,15 +4029,15 @@ private Untyped() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder.class);
           }
       
           private int bitField0_;
      @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -4132,44 +4132,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.newBuilder()
             private Builder() {
       
             }
      @@ -4265,17 +4265,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -4407,12 +4407,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketList();
           /**
            * 
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4930,7 +4930,7 @@ public static final class Histogram extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6580,9 +6580,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,7 +6975,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().getBuilder(index);
             }
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder addBucketBuilder() {
               return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return getBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder> 
                 getBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,7 +7648,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return getNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> 
                 getNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,7 +8243,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return getPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> 
                 getPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,7 +8814,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return getExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return getExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
                 getExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9041,7 +9041,7 @@ public static final class Bucket extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,7 +9841,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -9849,23 +9849,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9989,7 +9989,7 @@ public static final class BucketSpan extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10649,7 +10649,7 @@ public static final class Exemplar extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11807,7 +11807,7 @@ public static final class Metric extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,7 +12921,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getGaugeFieldBuilder().getBuilder();
      @@ -12929,23 +12929,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder> 
                 getGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,7 +13042,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCounterFieldBuilder().getBuilder();
      @@ -13050,23 +13050,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder> 
                 getCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,7 +13163,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getSummaryFieldBuilder().getBuilder();
      @@ -13171,23 +13171,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder> 
                 getSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,7 +13284,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getUntypedFieldBuilder().getBuilder();
      @@ -13292,23 +13292,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder> 
                 getUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,7 +13405,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return getHistogramFieldBuilder().getBuilder();
      @@ -13413,23 +13413,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder> 
                 getHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13632,7 +13632,7 @@ public static final class MetricFamily extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder addMetricBuilder() {
               return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return getMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder> 
                 getMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_29_1Z:github.com/prometheus/clien" +
      +      "obuf_4_29_2Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index ab86e8bc1..4993cdb87 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      index de0791599..e85c36738 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
      
      From acce049e04a96a5e904b8ea8e860935c9264eed5 Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Fri, 20 Dec 2024 12:27:12 +0100
      Subject: [PATCH 498/980] rename files to avoid dependabot security warnings
       (#1239)
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       .github/dependabot.yml                                          | 2 +-
       .../integration_tests/it_common/{pom.xml => pom.xml.bak}        | 0
       .../it_exemplars_otel_agent/{pom.xml => pom.xml.bak}            | 0
       .../it_exemplars_otel_sdk/{pom.xml => pom.xml.bak}              | 0
       .../integration_tests/it_java_versions/{pom.xml => pom.xml.bak} | 0
       .../integration_tests/it_log4j2/{pom.xml => pom.xml.bak}        | 0
       .../integration_tests/it_pushgateway/{pom.xml => pom.xml.bak}   | 0
       .../it_servlet_jakarta_exporter_webxml/{pom.xml => pom.xml.bak} | 0
       simpleclient-archive/integration_tests/{pom.xml => pom.xml.bak} | 0
       .../simpleclient_graphite_bridge/{pom.xml => pom.xml.bak}       | 0
       .../simpleclient_hibernate/{pom.xml => pom.xml.bak}             | 0
       .../simpleclient_httpserver/{pom.xml => pom.xml.bak}            | 0
       .../simpleclient_jetty/{pom.xml => pom.xml.bak}                 | 0
       .../simpleclient_jetty_jdk8/{pom.xml => pom.xml.bak}            | 0
       .../simpleclient_log4j/{pom.xml => pom.xml.bak}                 | 0
       .../simpleclient_log4j2/{pom.xml => pom.xml.bak}                | 0
       .../simpleclient_logback/{pom.xml => pom.xml.bak}               | 0
       .../simpleclient_servlet/{pom.xml => pom.xml.bak}               | 0
       .../simpleclient_servlet_common/{pom.xml => pom.xml.bak}        | 0
       .../simpleclient_servlet_jakarta/{pom.xml => pom.xml.bak}       | 0
       .../simpleclient_spring_web/{pom.xml => pom.xml.bak}            | 0
       .../simpleclient_vertx/{pom.xml => pom.xml.bak}                 | 0
       .../simpleclient_vertx4/{pom.xml => pom.xml.bak}                | 0
       23 files changed, 1 insertion(+), 1 deletion(-)
       rename simpleclient-archive/integration_tests/it_common/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_exemplars_otel_agent/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_exemplars_otel_sdk/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_java_versions/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_log4j2/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_pushgateway/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/integration_tests/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_graphite_bridge/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_hibernate/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_httpserver/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_jetty/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_jetty_jdk8/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_log4j/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_log4j2/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_logback/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_servlet/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_servlet_common/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_servlet_jakarta/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_spring_web/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_vertx/{pom.xml => pom.xml.bak} (100%)
       rename simpleclient-archive/simpleclient_vertx4/{pom.xml => pom.xml.bak} (100%)
      
      diff --git a/.github/dependabot.yml b/.github/dependabot.yml
      index 27283d4ae..505013ce1 100644
      --- a/.github/dependabot.yml
      +++ b/.github/dependabot.yml
      @@ -8,7 +8,7 @@ updates:
           # excluding simpleclient_archive from the update is not possible, only includes are supported
           # when we use includes, we run into https://github.com/dependabot/dependabot-core/issues/10415 -
           # even if we limit to 1 PR at a time
      -    # therefore we just ignore the simpleclient_archive update for now
      +    # therefore we just rename pom.xml in simpleclient_archive for now
           # if this becomes a problem, we can move to renovate
           directory: "/"
           schedule:
      diff --git a/simpleclient-archive/integration_tests/it_common/pom.xml b/simpleclient-archive/integration_tests/it_common/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_common/pom.xml
      rename to simpleclient-archive/integration_tests/it_common/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml
      rename to simpleclient-archive/integration_tests/it_exemplars_otel_agent/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml b/simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml
      rename to simpleclient-archive/integration_tests/it_exemplars_otel_sdk/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_java_versions/pom.xml b/simpleclient-archive/integration_tests/it_java_versions/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_java_versions/pom.xml
      rename to simpleclient-archive/integration_tests/it_java_versions/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_log4j2/pom.xml b/simpleclient-archive/integration_tests/it_log4j2/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_log4j2/pom.xml
      rename to simpleclient-archive/integration_tests/it_log4j2/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_pushgateway/pom.xml b/simpleclient-archive/integration_tests/it_pushgateway/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_pushgateway/pom.xml
      rename to simpleclient-archive/integration_tests/it_pushgateway/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml b/simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml
      rename to simpleclient-archive/integration_tests/it_servlet_jakarta_exporter_webxml/pom.xml.bak
      diff --git a/simpleclient-archive/integration_tests/pom.xml b/simpleclient-archive/integration_tests/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/integration_tests/pom.xml
      rename to simpleclient-archive/integration_tests/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_graphite_bridge/pom.xml b/simpleclient-archive/simpleclient_graphite_bridge/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_graphite_bridge/pom.xml
      rename to simpleclient-archive/simpleclient_graphite_bridge/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_hibernate/pom.xml b/simpleclient-archive/simpleclient_hibernate/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_hibernate/pom.xml
      rename to simpleclient-archive/simpleclient_hibernate/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_httpserver/pom.xml b/simpleclient-archive/simpleclient_httpserver/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_httpserver/pom.xml
      rename to simpleclient-archive/simpleclient_httpserver/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_jetty/pom.xml b/simpleclient-archive/simpleclient_jetty/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_jetty/pom.xml
      rename to simpleclient-archive/simpleclient_jetty/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml b/simpleclient-archive/simpleclient_jetty_jdk8/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_jetty_jdk8/pom.xml
      rename to simpleclient-archive/simpleclient_jetty_jdk8/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_log4j/pom.xml b/simpleclient-archive/simpleclient_log4j/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_log4j/pom.xml
      rename to simpleclient-archive/simpleclient_log4j/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_log4j2/pom.xml b/simpleclient-archive/simpleclient_log4j2/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_log4j2/pom.xml
      rename to simpleclient-archive/simpleclient_log4j2/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_logback/pom.xml b/simpleclient-archive/simpleclient_logback/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_logback/pom.xml
      rename to simpleclient-archive/simpleclient_logback/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_servlet/pom.xml b/simpleclient-archive/simpleclient_servlet/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_servlet/pom.xml
      rename to simpleclient-archive/simpleclient_servlet/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_servlet_common/pom.xml b/simpleclient-archive/simpleclient_servlet_common/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_servlet_common/pom.xml
      rename to simpleclient-archive/simpleclient_servlet_common/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml b/simpleclient-archive/simpleclient_servlet_jakarta/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_servlet_jakarta/pom.xml
      rename to simpleclient-archive/simpleclient_servlet_jakarta/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_spring_web/pom.xml b/simpleclient-archive/simpleclient_spring_web/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_spring_web/pom.xml
      rename to simpleclient-archive/simpleclient_spring_web/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_vertx/pom.xml b/simpleclient-archive/simpleclient_vertx/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_vertx/pom.xml
      rename to simpleclient-archive/simpleclient_vertx/pom.xml.bak
      diff --git a/simpleclient-archive/simpleclient_vertx4/pom.xml b/simpleclient-archive/simpleclient_vertx4/pom.xml.bak
      similarity index 100%
      rename from simpleclient-archive/simpleclient_vertx4/pom.xml
      rename to simpleclient-archive/simpleclient_vertx4/pom.xml.bak
      
      From aa8cf5f7771cdacd1b8600ebe620b9f83363964d Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 20 Dec 2024 07:02:48 -0500
      Subject: [PATCH 499/980] Bump org.assertj:assertj-core from 3.26.3 to 3.27.0
       (#1240)
      
      Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.26.3 to 3.27.0.
      - [Release notes](https://github.com/assertj/assertj/releases)
      - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.26.3...assertj-build-3.27.0)
      
      ---
      updated-dependencies:
      - dependency-name: org.assertj:assertj-core
        dependency-type: direct:development
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index a0afdf4dd..748de4341 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -122,7 +122,7 @@
               
                   org.assertj
                   assertj-core
      -            3.26.3
      +            3.27.0
                   test
               
               
      
      From 3fdf1e5f055b4f6274a995e68411c3e1d05aa7d3 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 27 Dec 2024 00:07:28 -0500
      Subject: [PATCH 500/980] Bump
       io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha
       (#1243)
      
      Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.10.0-alpha to 2.11.0-alpha.
      - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases)
      - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md)
      - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits)
      
      ---
      updated-dependencies:
      - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha
        dependency-type: direct:production
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 748de4341..81bc9a2a5 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -18,7 +18,7 @@
               UTF-8
               --module-name-need-to-be-overriden--
               5.11.4
      -        2.10.0-alpha
      +        2.11.0-alpha
               8
               0.70
               false
      
      From 436560419d6f3f7f2b930b5ab7d3636e3797383b Mon Sep 17 00:00:00 2001
      From: Stephan Schroevers 
      Date: Fri, 27 Dec 2024 06:18:47 +0100
      Subject: [PATCH 501/980] Fix flaky `SlidingWindowTest` (#1242)
      
      Fixes issue #956.
      
      Signed-off-by: Stephan Schroevers 
      ---
       .../metrics/core/metrics/SlidingWindow.java      | 16 ++++++++++++++--
       .../metrics/core/metrics/SlidingWindowTest.java  |  8 ++++++--
       2 files changed, 20 insertions(+), 4 deletions(-)
      
      diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      index c9586e179..5360e3349 100644
      --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/SlidingWindow.java
      @@ -26,7 +26,7 @@ public class SlidingWindow {
         private int currentBucket;
         private long lastRotateTimestampMillis;
         private final long durationBetweenRotatesMillis;
      -  LongSupplier currentTimeMillis = System::currentTimeMillis; // to be replaced in unit tests
      +  private final LongSupplier currentTimeMillis;
       
         /**
          * Example: If the {@code maxAgeSeconds} is 60 and {@code ageBuckets} is 3, then 3 instances of
      @@ -39,13 +39,24 @@ public class SlidingWindow {
          * @param maxAgeSeconds after this amount of time an instance of T gets evicted.
          * @param ageBuckets number of age buckets.
          */
      -  @SuppressWarnings("unchecked")
         public SlidingWindow(
             Class clazz,
             Supplier constructor,
             ObjDoubleConsumer observeFunction,
             long maxAgeSeconds,
             int ageBuckets) {
      +    this(clazz, constructor, observeFunction, maxAgeSeconds, ageBuckets, System::currentTimeMillis);
      +  }
      +
      +  // VisibleForTesting
      +  @SuppressWarnings("unchecked")
      +  SlidingWindow(
      +      Class clazz,
      +      Supplier constructor,
      +      ObjDoubleConsumer observeFunction,
      +      long maxAgeSeconds,
      +      int ageBuckets,
      +      LongSupplier currentTimeMillis) {
           this.constructor = constructor;
           this.observeFunction = observeFunction;
           this.ringBuffer = (T[]) Array.newInstance(clazz, ageBuckets);
      @@ -55,6 +66,7 @@ public SlidingWindow(
           this.currentBucket = 0;
           this.lastRotateTimestampMillis = currentTimeMillis.getAsLong();
           this.durationBetweenRotatesMillis = TimeUnit.SECONDS.toMillis(maxAgeSeconds) / ageBuckets;
      +    this.currentTimeMillis = currentTimeMillis;
         }
       
         /** Get the currently active instance of {@code T}. */
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      index 334724a81..d85e5637c 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/SlidingWindowTest.java
      @@ -48,8 +48,12 @@ public void setUp() {
           currentTimeMillis.set(startTime);
           ringBuffer =
               new SlidingWindow<>(
      -            Observer.class, Observer::new, Observer::observe, maxAgeSeconds, ageBuckets);
      -    ringBuffer.currentTimeMillis = currentTimeMillis::get;
      +            Observer.class,
      +            Observer::new,
      +            Observer::observe,
      +            maxAgeSeconds,
      +            ageBuckets,
      +            currentTimeMillis::get);
         }
       
         @Test
      
      From dd014fa74e99f8f9993f6c519396eb77df801ae1 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 2 Jan 2025 09:18:16 -0500
      Subject: [PATCH 502/980] Bump org.assertj:assertj-core from 3.27.0 to 3.27.1
       (#1244)
      
      Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.0 to 3.27.1.
      - [Release notes](https://github.com/assertj/assertj/releases)
      - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.0...assertj-build-3.27.1)
      
      ---
      updated-dependencies:
      - dependency-name: org.assertj:assertj-core
        dependency-type: direct:development
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 81bc9a2a5..ce0593ef4 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -122,7 +122,7 @@
               
                   org.assertj
                   assertj-core
      -            3.27.0
      +            3.27.1
                   test
               
               
      
      From 5ee7af372df3fe1b68372adf8424f497cf8d46e3 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 3 Jan 2025 09:03:15 -0500
      Subject: [PATCH 503/980] Bump org.mockito:mockito-core from 5.14.2 to 5.15.2
       (#1245)
      
      Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.14.2 to 5.15.2.
      - [Release notes](https://github.com/mockito/mockito/releases)
      - [Commits](https://github.com/mockito/mockito/compare/v5.14.2...v5.15.2)
      
      ---
      updated-dependencies:
      - dependency-name: org.mockito:mockito-core
        dependency-type: direct:development
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index ce0593ef4..ab261658a 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -116,7 +116,7 @@
               
                   org.mockito
                   mockito-core
      -            5.14.2
      +            5.15.2
                   test
               
               
      
      From 9043b47dd8c7dfa2af5fb1d28b988ec85b896333 Mon Sep 17 00:00:00 2001
      From: Michal Domagala 
      Date: Mon, 6 Jan 2025 09:21:31 +0100
      Subject: [PATCH 504/980] Use buffered writer (#1241)
      
      Without buffered reader, every single output character through given stack goes to "StreamEncoder public void write(int c)" and single element char array is created.
      It makes pressure to GC and CPU
      BufferedReader reduce the pressure
      
      write:130, StreamEncoder (sun.nio.cs)
      write:201, OutputStreamWriter (java.io)
      writeMetadata:338, PrometheusTextFormatWriter (io.prometheus.metrics.expositionformats)
      writeGauge:129, PrometheusTextFormatWriter (io.prometheus.metrics.expositionformats)
      write:68, PrometheusTextFormatWriter (io.prometheus.metrics.expositionformats)
      write:48, PrometheusOutputFormat$1 (org.springframework.boot.actuate.metrics.export.prometheus)
      scrape:87, PrometheusScrapeEndpoint (org.springframework.boot.actuate.metrics.export.prometheus)
      
      StreamEncoder public void write(int c) throws IOException {
        char[] cbuf = new char[1];
        cbuf[0] = (char) c;
      
      Signed-off-by: Michal Domagala 
      Co-authored-by: Michal Domagala 
      ---
       .../PrometheusTextFormatWriter.java           | 38 ++++++++-----------
       .../expositionformats/TextFormatUtil.java     | 12 ++----
       2 files changed, 20 insertions(+), 30 deletions(-)
      
      diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java
      index eb07abc73..8602b0ba5 100644
      --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java
      +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java
      @@ -20,6 +20,7 @@
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      +import java.io.BufferedWriter;
       import java.io.IOException;
       import java.io.OutputStream;
       import java.io.OutputStreamWriter;
      @@ -59,7 +60,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx
           // See https://prometheus.io/docs/instrumenting/exposition_formats/
           // "unknown", "gauge", "counter", "stateset", "info", "histogram", "gaugehistogram", and
           // "summary".
      -    OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
      +    Writer writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
           for (MetricSnapshot snapshot : metricSnapshots) {
             if (snapshot.getDataPoints().size() > 0) {
               if (snapshot instanceof CounterSnapshot) {
      @@ -95,7 +96,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx
           writer.flush();
         }
       
      -  public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) throws IOException {
      +  public void writeCreated(Writer writer, MetricSnapshot snapshot) throws IOException {
           boolean metadataWritten = false;
           MetricMetadata metadata = snapshot.getMetadata();
           for (DataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -111,8 +112,7 @@ public void writeCreated(OutputStreamWriter writer, MetricSnapshot snapshot) thr
           }
         }
       
      -  private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot)
      -      throws IOException {
      +  private void writeCounter(Writer writer, CounterSnapshot snapshot) throws IOException {
           if (snapshot.getDataPoints().size() > 0) {
             MetricMetadata metadata = snapshot.getMetadata();
             writeMetadata(writer, "_total", "counter", metadata);
      @@ -124,7 +124,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot)
           }
         }
       
      -  private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException {
      +  private void writeGauge(Writer writer, GaugeSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "", "gauge", metadata);
           for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -134,8 +134,7 @@ private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throw
           }
         }
       
      -  private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot)
      -      throws IOException {
      +  private void writeHistogram(Writer writer, HistogramSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "", "histogram", metadata);
           for (HistogramSnapshot.HistogramDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -182,8 +181,7 @@ private ClassicHistogramBuckets getClassicBuckets(
         }
       
         private void writeGaugeCountSum(
      -      OutputStreamWriter writer, HistogramSnapshot snapshot, MetricMetadata metadata)
      -      throws IOException {
      +      Writer writer, HistogramSnapshot snapshot, MetricMetadata metadata) throws IOException {
           // Prometheus text format does not support gaugehistogram's _gcount and _gsum.
           // So we append _gcount and _gsum as gauge metrics.
           boolean metadataWritten = false;
      @@ -212,8 +210,7 @@ private void writeGaugeCountSum(
           }
         }
       
      -  private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot)
      -      throws IOException {
      +  private void writeSummary(Writer writer, SummarySnapshot snapshot) throws IOException {
           boolean metadataWritten = false;
           MetricMetadata metadata = snapshot.getMetadata();
           for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -248,7 +245,7 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot)
           }
         }
       
      -  private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException {
      +  private void writeInfo(Writer writer, InfoSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "_info", "gauge", metadata);
           for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -258,8 +255,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws
           }
         }
       
      -  private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot)
      -      throws IOException {
      +  private void writeStateSet(Writer writer, StateSetSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "", "gauge", metadata);
           for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -292,8 +288,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot)
           }
         }
       
      -  private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot)
      -      throws IOException {
      +  private void writeUnknown(Writer writer, UnknownSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "", "untyped", metadata);
           for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -303,13 +298,13 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot)
           }
         }
       
      -  private void writeNameAndLabels(
      -      OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException {
      +  private void writeNameAndLabels(Writer writer, String name, String suffix, Labels labels)
      +      throws IOException {
           writeNameAndLabels(writer, name, suffix, labels, null, 0.0);
         }
       
         private void writeNameAndLabels(
      -      OutputStreamWriter writer,
      +      Writer writer,
             String name,
             String suffix,
             Labels labels,
      @@ -327,8 +322,7 @@ private void writeNameAndLabels(
         }
       
         private void writeMetadata(
      -      OutputStreamWriter writer, String suffix, String typeString, MetricMetadata metadata)
      -      throws IOException {
      +      Writer writer, String suffix, String typeString, MetricMetadata metadata) throws IOException {
           if (metadata.getHelp() != null && !metadata.getHelp().isEmpty()) {
             writer.write("# HELP ");
             writer.write(metadata.getPrometheusName());
      @@ -365,7 +359,7 @@ private void writeEscapedHelp(Writer writer, String s) throws IOException {
           }
         }
       
      -  private void writeScrapeTimestampAndNewline(OutputStreamWriter writer, DataPointSnapshot data)
      +  private void writeScrapeTimestampAndNewline(Writer writer, DataPointSnapshot data)
             throws IOException {
           if (data.hasScrapeTimestamp()) {
             writer.write(' ');
      diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java
      index 54daaaa3e..e48f545c5 100644
      --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java
      +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java
      @@ -2,16 +2,15 @@
       
       import io.prometheus.metrics.model.snapshots.Labels;
       import java.io.IOException;
      -import java.io.OutputStreamWriter;
       import java.io.Writer;
       
       public class TextFormatUtil {
       
      -  static void writeLong(OutputStreamWriter writer, long value) throws IOException {
      +  static void writeLong(Writer writer, long value) throws IOException {
           writer.append(Long.toString(value));
         }
       
      -  static void writeDouble(OutputStreamWriter writer, double d) throws IOException {
      +  static void writeDouble(Writer writer, double d) throws IOException {
           if (d == Double.POSITIVE_INFINITY) {
             writer.write("+Inf");
           } else if (d == Double.NEGATIVE_INFINITY) {
      @@ -22,7 +21,7 @@ static void writeDouble(OutputStreamWriter writer, double d) throws IOException
           }
         }
       
      -  static void writeTimestamp(OutputStreamWriter writer, long timestampMs) throws IOException {
      +  static void writeTimestamp(Writer writer, long timestampMs) throws IOException {
           writer.write(Long.toString(timestampMs / 1000L));
           writer.write(".");
           long ms = timestampMs % 1000;
      @@ -55,10 +54,7 @@ static void writeEscapedLabelValue(Writer writer, String s) throws IOException {
         }
       
         static void writeLabels(
      -      OutputStreamWriter writer,
      -      Labels labels,
      -      String additionalLabelName,
      -      double additionalLabelValue)
      +      Writer writer, Labels labels, String additionalLabelName, double additionalLabelValue)
             throws IOException {
           writer.write('{');
           for (int i = 0; i < labels.size(); i++) {
      
      From 0d3020b9d3b8079dc6cbd59e340b6e138d607553 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 6 Jan 2025 09:25:54 -0500
      Subject: [PATCH 505/980] Bump org.assertj:assertj-core from 3.27.1 to 3.27.2
       (#1247)
      
      Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.1 to 3.27.2.
      - [Release notes](https://github.com/assertj/assertj/releases)
      - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.1...assertj-build-3.27.2)
      
      ---
      updated-dependencies:
      - dependency-name: org.assertj:assertj-core
        dependency-type: direct:development
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index ab261658a..c84af0d57 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -122,7 +122,7 @@
               
                   org.assertj
                   assertj-core
      -            3.27.1
      +            3.27.2
                   test
               
               
      
      From 64f02eaf9f5702ba1ab5f97dcdbf2a886f0e537a Mon Sep 17 00:00:00 2001
      From: Doug Hoard 
      Date: Mon, 6 Jan 2025 12:01:02 -0500
      Subject: [PATCH 506/980] Use buffered writer (#1248)
      
      Signed-off-by: dhoard 
      ---
       .../OpenMetricsTextFormatWriter.java          | 40 +++++++++----------
       1 file changed, 18 insertions(+), 22 deletions(-)
      
      diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java
      index 06850a3d8..0e34934d7 100644
      --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java
      +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java
      @@ -23,9 +23,11 @@
       import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
       import io.prometheus.metrics.model.snapshots.SummarySnapshot;
       import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
      +import java.io.BufferedWriter;
       import java.io.IOException;
       import java.io.OutputStream;
       import java.io.OutputStreamWriter;
      +import java.io.Writer;
       import java.nio.charset.StandardCharsets;
       import java.util.List;
       
      @@ -65,7 +67,7 @@ public String getContentType() {
       
         @Override
         public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOException {
      -    OutputStreamWriter writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
      +    Writer writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
           for (MetricSnapshot snapshot : metricSnapshots) {
             if (!snapshot.getDataPoints().isEmpty()) {
               if (snapshot instanceof CounterSnapshot) {
      @@ -89,8 +91,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx
           writer.flush();
         }
       
      -  private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot)
      -      throws IOException {
      +  private void writeCounter(Writer writer, CounterSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "counter", metadata);
           for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -101,7 +102,7 @@ private void writeCounter(OutputStreamWriter writer, CounterSnapshot snapshot)
           }
         }
       
      -  private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throws IOException {
      +  private void writeGauge(Writer writer, GaugeSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "gauge", metadata);
           for (GaugeSnapshot.GaugeDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -115,8 +116,7 @@ private void writeGauge(OutputStreamWriter writer, GaugeSnapshot snapshot) throw
           }
         }
       
      -  private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapshot)
      -      throws IOException {
      +  private void writeHistogram(Writer writer, HistogramSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           if (snapshot.isGaugeHistogram()) {
             writeMetadata(writer, "gaugehistogram", metadata);
      @@ -128,7 +128,7 @@ private void writeHistogram(OutputStreamWriter writer, HistogramSnapshot snapsho
         }
       
         private void writeClassicHistogramBuckets(
      -      OutputStreamWriter writer,
      +      Writer writer,
             MetricMetadata metadata,
             String countSuffix,
             String sumSuffix,
      @@ -174,8 +174,7 @@ private ClassicHistogramBuckets getClassicBuckets(
           }
         }
       
      -  private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot)
      -      throws IOException {
      +  private void writeSummary(Writer writer, SummarySnapshot snapshot) throws IOException {
           boolean metadataWritten = false;
           MetricMetadata metadata = snapshot.getMetadata();
           for (SummarySnapshot.SummaryDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -215,7 +214,7 @@ private void writeSummary(OutputStreamWriter writer, SummarySnapshot snapshot)
           }
         }
       
      -  private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws IOException {
      +  private void writeInfo(Writer writer, InfoSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "info", metadata);
           for (InfoSnapshot.InfoDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -225,8 +224,7 @@ private void writeInfo(OutputStreamWriter writer, InfoSnapshot snapshot) throws
           }
         }
       
      -  private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot)
      -      throws IOException {
      +  private void writeStateSet(Writer writer, StateSetSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "stateset", metadata);
           for (StateSetSnapshot.StateSetDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -259,8 +257,7 @@ private void writeStateSet(OutputStreamWriter writer, StateSetSnapshot snapshot)
           }
         }
       
      -  private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot)
      -      throws IOException {
      +  private void writeUnknown(Writer writer, UnknownSnapshot snapshot) throws IOException {
           MetricMetadata metadata = snapshot.getMetadata();
           writeMetadata(writer, "unknown", metadata);
           for (UnknownSnapshot.UnknownDataPointSnapshot data : snapshot.getDataPoints()) {
      @@ -275,7 +272,7 @@ private void writeUnknown(OutputStreamWriter writer, UnknownSnapshot snapshot)
         }
       
         private void writeCountAndSum(
      -      OutputStreamWriter writer,
      +      Writer writer,
             MetricMetadata metadata,
             DistributionDataPointSnapshot data,
             String countSuffix,
      @@ -298,8 +295,7 @@ private void writeCountAndSum(
           }
         }
       
      -  private void writeCreated(
      -      OutputStreamWriter writer, MetricMetadata metadata, DataPointSnapshot data)
      +  private void writeCreated(Writer writer, MetricMetadata metadata, DataPointSnapshot data)
             throws IOException {
           if (createdTimestampsEnabled && data.hasCreatedTimestamp()) {
             writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels());
      @@ -312,13 +308,13 @@ private void writeCreated(
           }
         }
       
      -  private void writeNameAndLabels(
      -      OutputStreamWriter writer, String name, String suffix, Labels labels) throws IOException {
      +  private void writeNameAndLabels(Writer writer, String name, String suffix, Labels labels)
      +      throws IOException {
           writeNameAndLabels(writer, name, suffix, labels, null, 0.0);
         }
       
         private void writeNameAndLabels(
      -      OutputStreamWriter writer,
      +      Writer writer,
             String name,
             String suffix,
             Labels labels,
      @@ -336,7 +332,7 @@ private void writeNameAndLabels(
         }
       
         private void writeScrapeTimestampAndExemplar(
      -      OutputStreamWriter writer, DataPointSnapshot data, Exemplar exemplar) throws IOException {
      +      Writer writer, DataPointSnapshot data, Exemplar exemplar) throws IOException {
           if (data.hasScrapeTimestamp()) {
             writer.write(' ');
             writeTimestamp(writer, data.getScrapeTimestampMillis());
      @@ -354,7 +350,7 @@ private void writeScrapeTimestampAndExemplar(
           writer.write('\n');
         }
       
      -  private void writeMetadata(OutputStreamWriter writer, String typeName, MetricMetadata metadata)
      +  private void writeMetadata(Writer writer, String typeName, MetricMetadata metadata)
             throws IOException {
           writer.write("# TYPE ");
           writer.write(metadata.getPrometheusName());
      
      From 3814e483630df62b0ba3a6dba5814d7e3bcfe5a8 Mon Sep 17 00:00:00 2001
      From: Gregor Zeitlinger 
      Date: Tue, 7 Jan 2025 08:16:46 +0100
      Subject: [PATCH 507/980] add dropwizard to bom (#1250)
      
      Signed-off-by: Gregor Zeitlinger 
      ---
       prometheus-metrics-bom/pom.xml | 5 +++++
       1 file changed, 5 insertions(+)
      
      diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml
      index d1299470b..496f2fc4f 100644
      --- a/prometheus-metrics-bom/pom.xml
      +++ b/prometheus-metrics-bom/pom.xml
      @@ -67,6 +67,11 @@
                       prometheus-metrics-exposition-formats
                       ${project.version}
                   
      +            
      +                io.prometheus
      +                prometheus-metrics-instrumentation-dropwizard
      +                ${project.version}
      +            
                   
                       io.prometheus
                       prometheus-metrics-instrumentation-dropwizard5
      
      From 9d04544358bc72ad8f38e582576a300663e4ea6a Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Tue, 7 Jan 2025 12:14:46 -0500
      Subject: [PATCH 508/980] Bump com.diffplug.spotless:spotless-maven-plugin from
       2.43.0 to 2.44.0 (#1252)
      
      * Bump com.diffplug.spotless:spotless-maven-plugin from 2.43.0 to 2.44.0
      
      Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.43.0 to 2.44.0.
      - [Release notes](https://github.com/diffplug/spotless/releases)
      - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
      - [Commits](https://github.com/diffplug/spotless/compare/lib/2.43.0...lib/2.44.0)
      
      ---
      updated-dependencies:
      - dependency-name: com.diffplug.spotless:spotless-maven-plugin
        dependency-type: direct:production
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      
      * format
      
      Signed-off-by: Gregor Zeitlinger 
      
      * format
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: dependabot[bot] 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       checkstyle.xml                                         |  2 --
       integration-tests/it-spring-boot-smoke-test/pom.xml    |  2 +-
       pom.xml                                                |  2 +-
       .../opentelemetry/otelmodel/PrometheusMetricData.java  | 10 +++++-----
       .../instrumentation/dropwizard5/DropwizardExports.java |  6 ++++--
       5 files changed, 11 insertions(+), 11 deletions(-)
      
      diff --git a/checkstyle.xml b/checkstyle.xml
      index ef205414d..fd483abfa 100644
      --- a/checkstyle.xml
      +++ b/checkstyle.xml
      @@ -255,7 +255,6 @@
             
           
      -    
           
           
           
      diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml
      index 2121c27c0..1a421949d 100644
      --- a/integration-tests/it-spring-boot-smoke-test/pom.xml
      +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml
      @@ -77,7 +77,7 @@
                   
                       com.diffplug.spotless
                       spotless-maven-plugin
      -                2.43.0
      +                2.44.0
                       
                           
                               
      diff --git a/pom.xml b/pom.xml
      index c84af0d57..8dc201039 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -223,7 +223,7 @@
                       
                           com.diffplug.spotless
                           spotless-maven-plugin
      -                    2.43.0
      +                    2.44.0
                       
                   
               
      diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      index baca70774..7bf4f5e27 100644
      --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/PrometheusMetricData.java
      @@ -53,7 +53,7 @@ static String convertUnit(Unit unit) {
             return null;
           }
           switch (unit.toString()) {
      -        // Time
      +      // Time
             case "days":
               return "d";
             case "hours":
      @@ -68,7 +68,7 @@ static String convertUnit(Unit unit) {
               return "us";
             case "nanoseconds":
               return "ns";
      -        // Bytes
      +      // Bytes
             case "bytes":
               return "By";
             case "kibibytes":
      @@ -87,7 +87,7 @@ static String convertUnit(Unit unit) {
               return "GBy";
             case "terabytes":
               return "TBy";
      -        // SI
      +      // SI
             case "meters":
               return "m";
             case "volts":
      @@ -100,14 +100,14 @@ static String convertUnit(Unit unit) {
               return "W";
             case "grams":
               return "g";
      -        // Misc
      +      // Misc
             case "celsius":
               return "Cel";
             case "hertz":
               return "Hz";
             case "percent":
               return "%";
      -        // default
      +      // default
             default:
               return unit.toString();
           }
      diff --git a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      index bd3a163ac..c050871ce 100644
      --- a/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      +++ b/prometheus-metrics-instrumentation-dropwizard5/src/main/java/io/prometheus/metrics/instrumentation/dropwizard5/DropwizardExports.java
      @@ -24,6 +24,7 @@
       import java.util.Collections;
       import java.util.Map;
       import java.util.Optional;
      +import java.util.Set;
       import java.util.concurrent.TimeUnit;
       import java.util.logging.Level;
       import java.util.logging.Logger;
      @@ -196,8 +197,9 @@ MetricSnapshot fromMeter(String dropwizardName, Meter meter) {
         @Override
         public MetricSnapshots collect() {
           MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder();
      -    for (@SuppressWarnings("rawtypes")
      -    Map.Entry entry : registry.getGauges(metricFilter).entrySet()) {
      +    @SuppressWarnings("rawtypes")
      +    Set> entries = registry.getGauges(metricFilter).entrySet();
      +    for (@SuppressWarnings("rawtypes") Map.Entry entry : entries) {
             Optional.ofNullable(fromGauge(entry.getKey().getKey(), entry.getValue()))
                 .ifPresent(metricSnapshots::metricSnapshot);
           }
      
      From 45f8def91887d38880ab82097a6e9beba9830678 Mon Sep 17 00:00:00 2001
      From: Doug Hoard 
      Date: Tue, 7 Jan 2025 12:58:33 -0500
      Subject: [PATCH 509/980] Updated com.diffplug.spotless:spotless-maven-plugin
       from 2.44.0 to 2.44.1 (#1253)
      
      Signed-off-by: dhoard 
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 8dc201039..7173c5394 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -223,7 +223,7 @@
                       
                           com.diffplug.spotless
                           spotless-maven-plugin
      -                    2.44.0
      +                    2.44.1
                       
                   
               
      
      From 7d091a7d538c35181eb12130dec9a0832ccf12ef Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 8 Jan 2025 15:01:52 +0100
      Subject: [PATCH 510/980] Bump com.diffplug.spotless:spotless-maven-plugin from
       2.44.0 to 2.44.1 (#1254)
      
      Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.44.0 to 2.44.1.
      - [Release notes](https://github.com/diffplug/spotless/releases)
      - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
      - [Commits](https://github.com/diffplug/spotless/compare/lib/2.44.0...maven/2.44.1)
      
      ---
      updated-dependencies:
      - dependency-name: com.diffplug.spotless:spotless-maven-plugin
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml
      index 1a421949d..9596e716f 100644
      --- a/integration-tests/it-spring-boot-smoke-test/pom.xml
      +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml
      @@ -77,7 +77,7 @@
                   
                       com.diffplug.spotless
                       spotless-maven-plugin
      -                2.44.0
      +                2.44.1
                       
                           
                               
      
      From 5957a103a3309841f7c2fc0d352f2a426350ac62 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 10 Jan 2025 15:12:20 +0100
      Subject: [PATCH 511/980] Bump com.google.protobuf:protobuf-java from 4.29.2 to
       4.29.3 (#1256)
      
      * Bump com.google.protobuf:protobuf-java from 4.29.2 to 4.29.3
      
      Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.29.2 to 4.29.3.
      - [Release notes](https://github.com/protocolbuffers/protobuf/releases)
      - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl)
      - [Commits](https://github.com/protocolbuffers/protobuf/commits)
      
      ---
      updated-dependencies:
      - dependency-name: com.google.protobuf:protobuf-java
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      
      * update protoc
      
      Signed-off-by: Gregor Zeitlinger 
      
      ---------
      
      Signed-off-by: dependabot[bot] 
      Signed-off-by: Gregor Zeitlinger 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      Co-authored-by: Gregor Zeitlinger 
      ---
       .tool-versions                                |    2 +-
       .../client/it/common/ExporterTest.java        |    2 +-
       .../metrics/it/exporter/test/ExporterIT.java  |    2 +-
       .../it/springboot/ApplicationTest.java        |    2 +-
       .../metrics/core/metrics/CounterTest.java     |    2 +-
       .../metrics/core/metrics/HistogramTest.java   |    2 +-
       .../metrics/core/metrics/InfoTest.java        |    2 +-
       prometheus-metrics-exposition-formats/pom.xml |    2 +-
       .../Metrics.java                              | 1810 ++++++++---------
       .../PrometheusProtobufWriterImpl.java         |    2 +-
       .../ExpositionFormatsTest.java                |    2 +-
       11 files changed, 915 insertions(+), 915 deletions(-)
       rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_29_2 => com_google_protobuf_4_29_3}/Metrics.java (89%)
      
      diff --git a/.tool-versions b/.tool-versions
      index 477916d84..58b0b2027 100644
      --- a/.tool-versions
      +++ b/.tool-versions
      @@ -1,2 +1,2 @@
       java temurin-17.0.13+11
      -protoc 29.2
      +protoc 29.3
      diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      index 97d133e8c..93b5b088a 100644
      --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java
      @@ -4,7 +4,7 @@
       import static org.assertj.core.api.Assertions.assertThat;
       import static org.assertj.core.api.Assertions.fail;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import java.io.ByteArrayInputStream;
       import java.io.IOException;
       import java.io.InputStream;
      diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      index 60bd7ab59..67a4eec16 100644
      --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
      @@ -5,7 +5,7 @@
       
       import com.google.common.io.Resources;
       import io.prometheus.client.it.common.ExporterTest;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import java.io.IOException;
       import java.net.URISyntaxException;
       import java.net.URLEncoder;
      diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      index 7abf16e9d..eac8232d8 100644
      --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java
      @@ -3,7 +3,7 @@
       import static org.assertj.core.api.Assertions.assertThat;
       
       import io.prometheus.client.it.common.ExporterTest;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import java.io.IOException;
       import java.net.URL;
       import java.util.List;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      index 7f6dd20f6..d05311307 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java
      @@ -6,7 +6,7 @@
       import static org.assertj.core.data.Offset.offset;
       
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      index 69453ea13..514fd5b34 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java
      @@ -8,7 +8,7 @@
       import io.prometheus.metrics.core.datapoints.DistributionDataPoint;
       import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil;
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket;
      diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      index e4878eb42..f78372545 100644
      --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java
      @@ -4,7 +4,7 @@
       import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
       
       import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.Labels;
      diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml
      index 0c2a686a8..83fb7e3c0 100644
      --- a/prometheus-metrics-exposition-formats/pom.xml
      +++ b/prometheus-metrics-exposition-formats/pom.xml
      @@ -19,7 +19,7 @@
       
           
               io.prometheus.metrics.expositionformats
      -        4.29.2
      +        4.29.3
           
       
           
      diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java
      similarity index 89%
      rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java
      rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java
      index 2e7f28311..c20c4a4ed 100644
      --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_2/Metrics.java
      +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java
      @@ -2,9 +2,9 @@
       // Generated by the protocol buffer compiler.  DO NOT EDIT!
       // NO CHECKED-IN PROTOBUF GENCODE
       // source: src/main/protobuf/metrics.proto
      -// Protobuf Java Version: 4.29.2
      +// Protobuf Java Version: 4.29.3
       
      -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2;
      +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3;
       
       public final class Metrics {
         private Metrics() {}
      @@ -13,7 +13,7 @@ private Metrics() {}
             com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
             /* major= */ 4,
             /* minor= */ 29,
      -      /* patch= */ 2,
      +      /* patch= */ 3,
             /* suffix= */ "",
             Metrics.class.getName());
         }
      @@ -86,7 +86,7 @@ public enum MetricType
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               MetricType.class.getName());
           }
      @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) {
           }
           public static final com.google.protobuf.Descriptors.EnumDescriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.getDescriptor().getEnumTypes().get(0);
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.getDescriptor().getEnumTypes().get(0);
           }
       
           private static final MetricType[] VALUES = values();
      @@ -266,7 +266,7 @@ public static final class LabelPair extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               LabelPair.class.getName());
           }
      @@ -281,15 +281,15 @@ private LabelPair() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder.class);
           }
       
           private int bitField0_;
      @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -475,44 +475,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -573,21 +573,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.newBuilder()
             private Builder() {
       
             }
      @@ -609,17 +609,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -887,12 +887,12 @@ public Builder setValueBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -962,7 +962,7 @@ public static final class Gauge extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Gauge.class.getName());
           }
      @@ -975,15 +975,15 @@ private Gauge() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder.class);
           }
       
           private int bitField0_;
      @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1078,44 +1078,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.newBuilder()
             private Builder() {
       
             }
      @@ -1211,17 +1211,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1353,12 +1353,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
       
           /**
            * optional .google.protobuf.Timestamp created_timestamp = 3;
      @@ -1458,7 +1458,7 @@ public static final class Counter extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Counter.class.getName());
           }
      @@ -1471,15 +1471,15 @@ private Counter() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder.class);
           }
       
           private int bitField0_;
      @@ -1503,7 +1503,7 @@ public double getValue() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            * @return Whether the exemplar field is set.
      @@ -1517,15 +1517,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3;
      @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -1658,44 +1658,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -1808,17 +1808,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -1978,9 +1978,9 @@ public Builder clearValue() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return Whether the exemplar field is set.
      @@ -1992,9 +1992,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -2032,11 +2032,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -2066,7 +2066,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -2074,23 +2074,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2310,7 +2310,7 @@ public static final class Quantile extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Quantile.class.getName());
           }
      @@ -2323,15 +2323,15 @@ private Quantile() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder.class);
           }
       
           private int bitField0_;
      @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile) obj;
       
             if (hasQuantile() != other.hasQuantile()) return false;
             if (hasQuantile()) {
      @@ -2463,44 +2463,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.newBuilder()
             private Builder() {
       
             }
      @@ -2597,17 +2597,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance()) return this;
               if (other.hasQuantile()) {
                 setQuantile(other.getQuantile());
               }
      @@ -2791,12 +2791,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index);
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getQuantileOrBuilderList();
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index);
       
           /**
      @@ -2916,7 +2916,7 @@ public static final class Summary extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Summary.class.getName());
           }
      @@ -2930,15 +2930,15 @@ private Summary() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder.class);
           }
       
           private int bitField0_;
      @@ -2982,19 +2982,19 @@ public double getSampleSum() {
       
           public static final int QUANTILE_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List quantile_;
      +    private java.util.List quantile_;
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List getQuantileList() {
      +    public java.util.List getQuantileList() {
             return quantile_;
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getQuantileOrBuilderList() {
             return quantile_;
           }
      @@ -3009,14 +3009,14 @@ public int getQuantileCount() {
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index) {
             return quantile_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Quantile quantile = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
               int index) {
             return quantile_.get(index);
           }
      @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -3165,44 +3165,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -3318,17 +3318,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result) {
               if (quantileBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0)) {
                   quantile_ = java.util.Collections.unmodifiableList(quantile_);
      @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -3460,9 +3460,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.parser(),
                               extensionRegistry);
                       if (quantileBuilder_ == null) {
                         ensureQuantileIsMutable();
      @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List quantile_ =
      +      private java.util.List quantile_ =
               java.util.Collections.emptyList();
             private void ensureQuantileIsMutable() {
               if (!((bitField0_ & 0x00000004) != 0)) {
      -          quantile_ = new java.util.ArrayList(quantile_);
      +          quantile_ = new java.util.ArrayList(quantile_);
                 bitField0_ |= 0x00000004;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder> quantileBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder> quantileBuilder_;
       
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List getQuantileList() {
      +      public java.util.List getQuantileList() {
               if (quantileBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(quantile_);
               } else {
      @@ -3611,7 +3611,7 @@ public int getQuantileCount() {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile getQuantile(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);
               } else {
      @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3639,7 +3639,7 @@ public Builder setQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder setQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.set(index, builderForValue.build());
      @@ -3652,7 +3652,7 @@ public Builder setQuantile(
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
      +      public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) {
               if (quantileBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -3686,7 +3686,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(builderForValue.build());
      @@ -3700,7 +3700,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addQuantile(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 quantile_.add(index, builderForValue.build());
      @@ -3714,7 +3714,7 @@ public Builder addQuantile(
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
             public Builder addAllQuantile(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (quantileBuilder_ == null) {
                 ensureQuantileIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) {
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder getQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder getQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder getQuantileOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder(
                 int index) {
               if (quantileBuilder_ == null) {
                 return quantile_.get(index);  } else {
      @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileOrBuilderList() {
               if (quantileBuilder_ != null) {
                 return quantileBuilder_.getMessageOrBuilderList();
      @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder addQuantileBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder addQuantileBuilder() {
               return getQuantileFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder addQuantileBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder addQuantileBuilder(
                 int index) {
               return getQuantileFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Quantile quantile = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getQuantileBuilderList() {
               return getQuantileFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder> 
                 getQuantileFieldBuilder() {
               if (quantileBuilder_ == null) {
                 quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.QuantileOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder>(
                         quantile_,
                         ((bitField0_ & 0x00000004) != 0),
                         getParentForChildren(),
      @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4016,7 +4016,7 @@ public static final class Untyped extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Untyped.class.getName());
           }
      @@ -4029,15 +4029,15 @@ private Untyped() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder.class);
           }
       
           private int bitField0_;
      @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped) obj;
       
             if (hasValue() != other.hasValue()) return false;
             if (hasValue()) {
      @@ -4132,44 +4132,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.newBuilder()
             private Builder() {
       
             }
      @@ -4265,17 +4265,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance()) return this;
               if (other.hasValue()) {
                 setValue(other.getValue());
               }
      @@ -4407,12 +4407,12 @@ public Builder clearValue() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketList();
           /**
            * 
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4930,7 +4930,7 @@ public static final class Histogram extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6580,9 +6580,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,7 +6975,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().getBuilder(index);
             }
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder addBucketBuilder() {
               return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return getBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder> 
                 getBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,7 +7648,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return getNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> 
                 getNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,7 +8243,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return getPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> 
                 getPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,7 +8814,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return getExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return getExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return getExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> 
                 getExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9041,7 +9041,7 @@ public static final class Bucket extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,7 +9841,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getExemplarFieldBuilder().getBuilder();
      @@ -9849,23 +9849,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> 
                 getExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9989,7 +9989,7 @@ public static final class BucketSpan extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10649,7 +10649,7 @@ public static final class Exemplar extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11807,7 +11807,7 @@ public static final class Metric extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder() {
               return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return getLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> 
                 getLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,7 +12921,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return getGaugeFieldBuilder().getBuilder();
      @@ -12929,23 +12929,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder> 
                 getGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,7 +13042,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return getCounterFieldBuilder().getBuilder();
      @@ -13050,23 +13050,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder> 
                 getCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,7 +13163,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return getSummaryFieldBuilder().getBuilder();
      @@ -13171,23 +13171,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder> 
                 getSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,7 +13284,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return getUntypedFieldBuilder().getBuilder();
      @@ -13292,23 +13292,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder> 
                 getUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,7 +13405,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return getHistogramFieldBuilder().getBuilder();
      @@ -13413,23 +13413,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder> 
                 getHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13632,7 +13632,7 @@ public static final class MetricFamily extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 29,
      -        /* patch= */ 2,
      +        /* patch= */ 3,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder addMetricBuilder() {
               return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return getMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder> 
                 getMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_29_2Z:github.com/prometheus/clien" +
      +      "obuf_4_29_3Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index 4993cdb87..608a13caa 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      index e85c36738..4c4ae3059 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_2.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
      
      From 244a30b505ab7723789cf98c813a66cb447028c6 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 13 Jan 2025 08:48:37 -0500
      Subject: [PATCH 512/980] Bump
       org.sonatype.central:central-publishing-maven-plugin (#1257)
      
      Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.6.0 to 0.7.0.
      - [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits)
      
      ---
      updated-dependencies:
      - dependency-name: org.sonatype.central:central-publishing-maven-plugin
        dependency-type: direct:production
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 7173c5394..4fd41c1ed 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -507,7 +507,7 @@
                           
                               org.sonatype.central
                               central-publishing-maven-plugin
      -                        0.6.0
      +                        0.7.0
                               true
                               
                                   ossrh
      
      From a20c2a16cafb94ad0d9aa7a20337e82df87e013d Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 15 Jan 2025 14:49:36 +0100
      Subject: [PATCH 513/980] Bump io.dropwizard.metrics:metrics-core from 4.2.29
       to 4.2.30 (#1259)
      
      Bumps [io.dropwizard.metrics:metrics-core](https://github.com/dropwizard/metrics) from 4.2.29 to 4.2.30.
      - [Release notes](https://github.com/dropwizard/metrics/releases)
      - [Commits](https://github.com/dropwizard/metrics/compare/v4.2.29...v4.2.30)
      
      ---
      updated-dependencies:
      - dependency-name: io.dropwizard.metrics:metrics-core
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       prometheus-metrics-instrumentation-dropwizard/pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/prometheus-metrics-instrumentation-dropwizard/pom.xml b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      index e17b11e96..54c5c7ce2 100644
      --- a/prometheus-metrics-instrumentation-dropwizard/pom.xml
      +++ b/prometheus-metrics-instrumentation-dropwizard/pom.xml
      @@ -45,7 +45,7 @@
               
                   io.dropwizard.metrics
                   metrics-core
      -            4.2.29
      +            4.2.30
                   provided
               
       
      
      From e0b96b3fb2b27a1a47c62212fb1f27a8d2acad6e Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Wed, 15 Jan 2025 14:49:50 +0100
      Subject: [PATCH 514/980] Bump com.diffplug.spotless:spotless-maven-plugin from
       2.44.1 to 2.44.2 (#1258)
      
      Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.44.1 to 2.44.2.
      - [Release notes](https://github.com/diffplug/spotless/releases)
      - [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
      - [Commits](https://github.com/diffplug/spotless/compare/maven/2.44.1...maven/2.44.2)
      
      ---
      updated-dependencies:
      - dependency-name: com.diffplug.spotless:spotless-maven-plugin
        dependency-type: direct:production
        update-type: version-update:semver-patch
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +-
       pom.xml                                             | 2 +-
       2 files changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml
      index 9596e716f..3469e621f 100644
      --- a/integration-tests/it-spring-boot-smoke-test/pom.xml
      +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml
      @@ -77,7 +77,7 @@
                   
                       com.diffplug.spotless
                       spotless-maven-plugin
      -                2.44.1
      +                2.44.2
                       
                           
                               
      diff --git a/pom.xml b/pom.xml
      index 4fd41c1ed..9165bd430 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -223,7 +223,7 @@
                       
                           com.diffplug.spotless
                           spotless-maven-plugin
      -                    2.44.1
      +                    2.44.2
                       
                   
               
      
      From 93bcef9c4c0aa6839b47238cdf3ae7e56637befb Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Fri, 17 Jan 2025 15:08:12 +0100
      Subject: [PATCH 515/980] Bump
       io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha
       (#1260)
      
      Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.11.0-alpha to 2.12.0-alpha.
      - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases)
      - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md)
      - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits)
      
      ---
      updated-dependencies:
      - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha
        dependency-type: direct:production
        update-type: version-update:semver-minor
      ...
      
      Signed-off-by: dependabot[bot] 
      Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
      ---
       pom.xml | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/pom.xml b/pom.xml
      index 9165bd430..b9fb611d1 100644
      --- a/pom.xml
      +++ b/pom.xml
      @@ -18,7 +18,7 @@
               UTF-8
               --module-name-need-to-be-overriden--
               5.11.4
      -        2.11.0-alpha
      +        2.12.0-alpha
               8
               0.70
               false
      
      From e05ca38dff91f9497b232837cfc97b84cd03ebc7 Mon Sep 17 00:00:00 2001
      From: Doug Hoard 
      Date: Fri, 17 Jan 2025 17:32:32 -0500
      Subject: [PATCH 516/980] Removed trailing whitespace (#1261)
      
      Signed-off-by: dhoard 
      ---
       RELEASING.md                                       | 2 +-
       docs/README.md                                     | 2 +-
       docs/content/getting-started/multi-target.md       | 4 ++--
       docs/content/getting-started/quickstart.md         | 4 ++--
       examples/example-exporter-servlet-tomcat/README.md | 2 +-
       5 files changed, 7 insertions(+), 7 deletions(-)
      
      diff --git a/RELEASING.md b/RELEASING.md
      index a58656474..eadbb8a76 100644
      --- a/RELEASING.md
      +++ b/RELEASING.md
      @@ -1,4 +1,4 @@
      -## Create a Release 
      +## Create a Release
       
       1. Go to https://github.com/prometheus/client_java/releases/new
       2. Click on "Choose a tag", enter the tag name (e.g. `v0.1.0`), and click "Create a new tag".
      diff --git a/docs/README.md b/docs/README.md
      index 2868196d5..294c9a622 100644
      --- a/docs/README.md
      +++ b/docs/README.md
      @@ -31,7 +31,7 @@ rm -r ./docs/static/api
       mv ./target/site/apidocs ./docs/static/api
       ```
       
      -Github pages are in the `/client_java/` folder, so we link to `/client_java/api` rather than `/api`. 
      +Github pages are in the `/client_java/` folder, so we link to `/client_java/api` rather than `/api`.
       To make JavaDoc work locally, create a link:
       
       ```
      diff --git a/docs/content/getting-started/multi-target.md b/docs/content/getting-started/multi-target.md
      index 6a1c0412c..93e37d9af 100644
      --- a/docs/content/getting-started/multi-target.md
      +++ b/docs/content/getting-started/multi-target.md
      @@ -103,7 +103,7 @@ Sample Prometheus scrape_config
             - source_labels: [__param_target]
               target_label: instance
             - target_label: __address__
      -        replacement: localhost:9401 
      +        replacement: localhost:9401
           static_configs:
             - targets: ["target1", "target2"]
       ```
      @@ -111,4 +111,4 @@ It's up to the specific MultiCollector implementation how to interpret the _targ
       It might be an explicit real target (i.e. via host name/ip address) or as an alias in some internal configuration.
       The latter is more suitable when the MultiCollector implementation is a proxy (see https://github.com/prometheus/snmp_exporter)
       In this case, invoking real target might require extra parameters (e.g. credentials) that might be complex to manage in Prometheus configuration
      -(not considering the case where the proxy might become an "open relay")
      \ No newline at end of file
      +(not considering the case where the proxy might become an "open relay")
      diff --git a/docs/content/getting-started/quickstart.md b/docs/content/getting-started/quickstart.md
      index 59acd0701..27b7c13f5 100644
      --- a/docs/content/getting-started/quickstart.md
      +++ b/docs/content/getting-started/quickstart.md
      @@ -47,9 +47,9 @@ There are alternative exporters as well, for example if you are using a Servlet
       
       {{< hint type=note >}}
       
      -If you do not use the protobuf exposition format, you can 
      +If you do not use the protobuf exposition format, you can
       [exclude](../../exporters/formats#exclude-protobuf-exposition-format)
      -it from the dependencies. 
      +it from the dependencies.
       
       {{< /hint >}}
       
      diff --git a/examples/example-exporter-servlet-tomcat/README.md b/examples/example-exporter-servlet-tomcat/README.md
      index 8d50c0c80..e67f9f56c 100644
      --- a/examples/example-exporter-servlet-tomcat/README.md
      +++ b/examples/example-exporter-servlet-tomcat/README.md
      @@ -64,7 +64,7 @@ The exporter servlet supports a `debug` URL parameter to quickly view other form
          ```shell
          ./prometheus --enable-feature=native-histograms --enable-feature=exemplar-storage
          ```
      -   
      +
       Verify that the `tomcat-servlet-example` target is up on [http://localhost:9090/targets](http://localhost:9090/targets).
       
       Prometheus is now scraping metrics in Protobuf format. If you type the name `request_duration_seconds` you will see a non-human-readable representation of the histogram including the native buckets:
      
      From ec06ab96ed207e565268ae66f825ab2590fdcefb Mon Sep 17 00:00:00 2001
      From: Jean Hominal 
      Date: Mon, 20 Jan 2025 12:55:17 +0100
      Subject: [PATCH 517/980] Caffeine instrumentation: add weighted size metric
       (#1251)
      
      * Change caffeine_cache_eviction_weight from Gauge to Counter
      
      Signed-off-by: Jean Hominal 
      
      * Add caffeine_cache_weighted_size gauge metric to caffeine-instrumentation
      
      Signed-off-by: Jean Hominal 
      
      * Add Builder pattern for caffeine CacheMetricsCollector
      
      Signed-off-by: Jean Hominal 
      
      * Add option collectEvictionWeightAsCounter to collect caffeine_cache_eviction_weight as an incremental counter
      
      Signed-off-by: Jean Hominal 
      
      * Add option collectWeightedSize to enable collection of caffeine_cache_weighted_size
      
      Signed-off-by: Jean Hominal 
      
      ---------
      
      Signed-off-by: Jean Hominal 
      ---
       .../caffeine/CacheMetricsCollector.java       | 102 ++++++++++-
       .../caffeine/CacheMetricsCollectorTest.java   | 162 ++++++++++++++++--
       2 files changed, 247 insertions(+), 17 deletions(-)
      
      diff --git a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java
      index c5c9fef3c..a1b8782a3 100644
      --- a/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java
      +++ b/prometheus-metrics-instrumentation-caffeine/src/main/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollector.java
      @@ -3,6 +3,7 @@
       import com.github.benmanes.caffeine.cache.AsyncCache;
       import com.github.benmanes.caffeine.cache.Cache;
       import com.github.benmanes.caffeine.cache.LoadingCache;
      +import com.github.benmanes.caffeine.cache.Policy;
       import com.github.benmanes.caffeine.cache.stats.CacheStats;
       import io.prometheus.metrics.model.registry.MultiCollector;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
      @@ -14,8 +15,10 @@
       import java.util.Collections;
       import java.util.List;
       import java.util.Map;
      +import java.util.Optional;
       import java.util.concurrent.ConcurrentHashMap;
       import java.util.concurrent.ConcurrentMap;
      +import java.util.stream.Collectors;
       
       /**
        * Collect metrics from Caffeine's com.github.benmanes.caffeine.cache.Cache.
      @@ -25,7 +28,7 @@
        * 
      {@code
        * // Note that `recordStats()` is required to gather non-zero statistics
        * Cache cache = Caffeine.newBuilder().recordStats().build();
      - * CacheMetricsCollector cacheMetrics = new CacheMetricsCollector();
      + * CacheMetricsCollector cacheMetrics = CacheMetricsCollector.builder().build();
        * PrometheusRegistry.defaultRegistry.register(cacheMetrics);
        * cacheMetrics.addCache("mycache", cache);
        *
      @@ -63,6 +66,7 @@ public class CacheMetricsCollector implements MultiCollector {
         private static final String METRIC_NAME_CACHE_LOAD_FAILURE = "caffeine_cache_load_failure";
         private static final String METRIC_NAME_CACHE_LOADS = "caffeine_cache_loads";
         private static final String METRIC_NAME_CACHE_ESTIMATED_SIZE = "caffeine_cache_estimated_size";
      +  private static final String METRIC_NAME_CACHE_WEIGHTED_SIZE = "caffeine_cache_weighted_size";
         private static final String METRIC_NAME_CACHE_LOAD_DURATION_SECONDS =
             "caffeine_cache_load_duration_seconds";
       
      @@ -77,9 +81,38 @@ public class CacheMetricsCollector implements MultiCollector {
                     METRIC_NAME_CACHE_LOAD_FAILURE,
                     METRIC_NAME_CACHE_LOADS,
                     METRIC_NAME_CACHE_ESTIMATED_SIZE,
      +              METRIC_NAME_CACHE_WEIGHTED_SIZE,
                     METRIC_NAME_CACHE_LOAD_DURATION_SECONDS));
       
         protected final ConcurrentMap> children = new ConcurrentHashMap<>();
      +  private final boolean collectEvictionWeightAsCounter;
      +  private final boolean collectWeightedSize;
      +
      +  /**
      +   * Instantiates a {@link CacheMetricsCollector}, with the legacy parameters.
      +   *
      +   * 

      The use of this constructor is discouraged, in favor of a Builder pattern {@link #builder()} + * + *

      Note that the {@link #builder()} API has different default values than this deprecated + * constructor. + */ + @Deprecated + public CacheMetricsCollector() { + this(false, false); + } + + /** + * Instantiate a {@link CacheMetricsCollector} + * + * @param collectEvictionWeightAsCounter If true, {@code caffeine_cache_eviction_weight} will be + * observed as an incrementing counter instead of a gauge. + * @param collectWeightedSize If true, {@code caffeine_cache_weighted_size} will be observed. + */ + protected CacheMetricsCollector( + boolean collectEvictionWeightAsCounter, boolean collectWeightedSize) { + this.collectEvictionWeightAsCounter = collectEvictionWeightAsCounter; + this.collectWeightedSize = collectWeightedSize; + } /** * Add or replace the cache with the given name. @@ -146,10 +179,14 @@ public MetricSnapshots collect() { .name(METRIC_NAME_CACHE_EVICTION) .help("Cache eviction totals, doesn't include manually removed entries"); - final GaugeSnapshot.Builder cacheEvictionWeight = + final CounterSnapshot.Builder cacheEvictionWeight = + CounterSnapshot.builder() + .name(METRIC_NAME_CACHE_EVICTION_WEIGHT) + .help("Weight of evicted cache entries, doesn't include manually removed entries"); + final GaugeSnapshot.Builder cacheEvictionWeightLegacyGauge = GaugeSnapshot.builder() .name(METRIC_NAME_CACHE_EVICTION_WEIGHT) - .help("Cache eviction weight"); + .help("Weight of evicted cache entries, doesn't include manually removed entries"); final CounterSnapshot.Builder cacheLoadFailure = CounterSnapshot.builder().name(METRIC_NAME_CACHE_LOAD_FAILURE).help("Cache load failures"); @@ -162,6 +199,11 @@ public MetricSnapshots collect() { final GaugeSnapshot.Builder cacheSize = GaugeSnapshot.builder().name(METRIC_NAME_CACHE_ESTIMATED_SIZE).help("Estimated cache size"); + final GaugeSnapshot.Builder cacheWeightedSize = + GaugeSnapshot.builder() + .name(METRIC_NAME_CACHE_WEIGHTED_SIZE) + .help("Approximate accumulated weight of cache entries"); + final SummarySnapshot.Builder cacheLoadSummary = SummarySnapshot.builder() .name(METRIC_NAME_CACHE_LOAD_DURATION_SECONDS) @@ -175,6 +217,11 @@ public MetricSnapshots collect() { try { cacheEvictionWeight.dataPoint( + CounterSnapshot.CounterDataPointSnapshot.builder() + .labels(labels) + .value(stats.evictionWeight()) + .build()); + cacheEvictionWeightLegacyGauge.dataPoint( GaugeSnapshot.GaugeDataPointSnapshot.builder() .labels(labels) .value(stats.evictionWeight()) @@ -183,6 +230,17 @@ public MetricSnapshots collect() { // EvictionWeight metric is unavailable, newer version of Caffeine is needed. } + if (collectWeightedSize) { + final Optional> eviction = c.getValue().policy().eviction(); + if (eviction.isPresent() && eviction.get().weightedSize().isPresent()) { + cacheWeightedSize.dataPoint( + GaugeSnapshot.GaugeDataPointSnapshot.builder() + .labels(labels) + .value(eviction.get().weightedSize().getAsLong()) + .build()); + } + } + cacheHitTotal.dataPoint( CounterSnapshot.CounterDataPointSnapshot.builder() .labels(labels) @@ -235,12 +293,19 @@ public MetricSnapshots collect() { } } + if (collectWeightedSize) { + metricSnapshotsBuilder.metricSnapshot(cacheWeightedSize.build()); + } + return metricSnapshotsBuilder .metricSnapshot(cacheHitTotal.build()) .metricSnapshot(cacheMissTotal.build()) .metricSnapshot(cacheRequestsTotal.build()) .metricSnapshot(cacheEvictionTotal.build()) - .metricSnapshot(cacheEvictionWeight.build()) + .metricSnapshot( + collectEvictionWeightAsCounter + ? cacheEvictionWeight.build() + : cacheEvictionWeightLegacyGauge.build()) .metricSnapshot(cacheLoadFailure.build()) .metricSnapshot(cacheLoadTotal.build()) .metricSnapshot(cacheSize.build()) @@ -250,6 +315,35 @@ public MetricSnapshots collect() { @Override public List getPrometheusNames() { + if (!collectWeightedSize) { + return ALL_METRIC_NAMES.stream() + .filter(s -> !METRIC_NAME_CACHE_WEIGHTED_SIZE.equals(s)) + .collect(Collectors.toList()); + } return ALL_METRIC_NAMES; } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private boolean collectEvictionWeightAsCounter = true; + private boolean collectWeightedSize = true; + + public Builder collectEvictionWeightAsCounter(boolean collectEvictionWeightAsCounter) { + this.collectEvictionWeightAsCounter = collectEvictionWeightAsCounter; + return this; + } + + public Builder collectWeightedSize(boolean collectWeightedSize) { + this.collectWeightedSize = collectWeightedSize; + return this; + } + + public CacheMetricsCollector build() { + return new CacheMetricsCollector(collectEvictionWeightAsCounter, collectWeightedSize); + } + } } diff --git a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java index 4ffb1d794..ac5ec9e2a 100644 --- a/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java +++ b/prometheus-metrics-instrumentation-caffeine/src/test/java/io/prometheus/metrics/instrumentation/caffeine/CacheMetricsCollectorTest.java @@ -13,6 +13,7 @@ import io.prometheus.metrics.model.registry.PrometheusRegistry; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.DataPointSnapshot; +import io.prometheus.metrics.model.snapshots.GaugeSnapshot; import io.prometheus.metrics.model.snapshots.Labels; import io.prometheus.metrics.model.snapshots.MetricSnapshots; import io.prometheus.metrics.model.snapshots.SummarySnapshot; @@ -22,17 +23,112 @@ import java.nio.charset.StandardCharsets; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; @SuppressWarnings("CheckReturnValue") class CacheMetricsCollectorTest { + // This enum was added to simplify test parametrization on argument options. + public enum Options { + LEGACY(false, false), + COLLECT_EVICTION_WEIGHT_AS_COUNTER(true, false), + COLLECT_WEIGHTED_SIZE(false, true), + BUILDER_DEFAULT(true, true); + + private final boolean collectEvictionWeightAsCounter; + private final boolean collectWeightedSize; + + Options(boolean collectEvictionWeightAsCounter, boolean collectWeightedSize) { + this.collectEvictionWeightAsCounter = collectEvictionWeightAsCounter; + this.collectWeightedSize = collectWeightedSize; + } + } - @Test - public void cacheExposesMetricsForHitMissAndEviction() { + @ParameterizedTest + @EnumSource + public void cacheExposesMetricsForHitMissAndEviction(Options options) { // Run cleanup in same thread, to remove async behavior with evictions final Cache cache = Caffeine.newBuilder().maximumSize(2).recordStats().executor(Runnable::run).build(); - final CacheMetricsCollector collector = new CacheMetricsCollector(); + final CacheMetricsCollector collector = + CacheMetricsCollector.builder() + .collectEvictionWeightAsCounter(options.collectEvictionWeightAsCounter) + .collectWeightedSize(options.collectWeightedSize) + .build(); + collector.addCache("users", cache); + + final PrometheusRegistry registry = new PrometheusRegistry(); + registry.register(collector); + + cache.getIfPresent("user1"); + cache.getIfPresent("user1"); + cache.put("user1", "First User"); + cache.getIfPresent("user1"); + + // Add to cache to trigger eviction. + cache.put("user2", "Second User"); + cache.put("user3", "Third User"); + cache.put("user4", "Fourth User"); + + assertCounterMetric(registry, "caffeine_cache_hit", "users", 1.0); + assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0); + assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0); + assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0); + String openMetricEvictionWeightExpectedText; + if (options.collectEvictionWeightAsCounter) { + assertCounterMetric(registry, "caffeine_cache_eviction_weight", "users", 2.0); + openMetricEvictionWeightExpectedText = + "# TYPE caffeine_cache_eviction_weight counter\n" + + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_weight_total{cache=\"users\"} 2.0\n"; + } else { + assertGaugeMetric(registry, "caffeine_cache_eviction_weight", "users", 2.0); + openMetricEvictionWeightExpectedText = + "# TYPE caffeine_cache_eviction_weight gauge\n" + + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_weight{cache=\"users\"} 2.0\n"; + } + + final String expected = + "# TYPE caffeine_cache_estimated_size gauge\n" + + "# HELP caffeine_cache_estimated_size Estimated cache size\n" + + "caffeine_cache_estimated_size{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_eviction counter\n" + + "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n" + + openMetricEvictionWeightExpectedText + + "# TYPE caffeine_cache_hit counter\n" + + "# HELP caffeine_cache_hit Cache hit totals\n" + + "caffeine_cache_hit_total{cache=\"users\"} 1.0\n" + + "# TYPE caffeine_cache_miss counter\n" + + "# HELP caffeine_cache_miss Cache miss totals\n" + + "caffeine_cache_miss_total{cache=\"users\"} 2.0\n" + + "# TYPE caffeine_cache_requests counter\n" + + "# HELP caffeine_cache_requests Cache request totals, hits + misses\n" + + "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + + "# EOF\n"; + + assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected); + } + + @ParameterizedTest + @EnumSource + public void weightedCacheExposesMetricsForHitMissAndEvictionWeightedSize(Options options) { + // Run cleanup in same thread, to remove async behavior with evictions + final Cache cache = + Caffeine.newBuilder() + .weigher((String k, String v) -> k.length() + v.length()) + .maximumWeight(35) + .recordStats() + .executor(Runnable::run) + .build(); + + final CacheMetricsCollector collector = + CacheMetricsCollector.builder() + .collectEvictionWeightAsCounter(options.collectEvictionWeightAsCounter) + .collectWeightedSize(options.collectWeightedSize) + .build(); collector.addCache("users", cache); final PrometheusRegistry registry = new PrometheusRegistry(); @@ -52,6 +148,29 @@ public void cacheExposesMetricsForHitMissAndEviction() { assertCounterMetric(registry, "caffeine_cache_miss", "users", 2.0); assertCounterMetric(registry, "caffeine_cache_requests", "users", 3.0); assertCounterMetric(registry, "caffeine_cache_eviction", "users", 2.0); + String openMetricEvictionWeightExpectedText; + if (options.collectEvictionWeightAsCounter) { + assertCounterMetric(registry, "caffeine_cache_eviction_weight", "users", 31.0); + openMetricEvictionWeightExpectedText = + "# TYPE caffeine_cache_eviction_weight counter\n" + + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_weight_total{cache=\"users\"} 31.0\n"; + } else { + assertGaugeMetric(registry, "caffeine_cache_eviction_weight", "users", 31.0); + openMetricEvictionWeightExpectedText = + "# TYPE caffeine_cache_eviction_weight gauge\n" + + "# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries\n" + + "caffeine_cache_eviction_weight{cache=\"users\"} 31.0\n"; + } + String openMetricWeightedSizeExpectedText; + if (options.collectWeightedSize) { + openMetricWeightedSizeExpectedText = + "# TYPE caffeine_cache_weighted_size gauge\n" + + "# HELP caffeine_cache_weighted_size Approximate accumulated weight of cache entries\n" + + "caffeine_cache_weighted_size{cache=\"users\"} 31.0\n"; + } else { + openMetricWeightedSizeExpectedText = ""; + } final String expected = "# TYPE caffeine_cache_estimated_size gauge\n" @@ -60,9 +179,7 @@ public void cacheExposesMetricsForHitMissAndEviction() { + "# TYPE caffeine_cache_eviction counter\n" + "# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries\n" + "caffeine_cache_eviction_total{cache=\"users\"} 2.0\n" - + "# TYPE caffeine_cache_eviction_weight gauge\n" - + "# HELP caffeine_cache_eviction_weight Cache eviction weight\n" - + "caffeine_cache_eviction_weight{cache=\"users\"} 2.0\n" + + openMetricEvictionWeightExpectedText + "# TYPE caffeine_cache_hit counter\n" + "# HELP caffeine_cache_hit Cache hit totals\n" + "caffeine_cache_hit_total{cache=\"users\"} 1.0\n" @@ -72,6 +189,7 @@ public void cacheExposesMetricsForHitMissAndEviction() { + "# TYPE caffeine_cache_requests counter\n" + "# HELP caffeine_cache_requests Cache request totals, hits + misses\n" + "caffeine_cache_requests_total{cache=\"users\"} 3.0\n" + + openMetricWeightedSizeExpectedText + "# EOF\n"; assertThat(convertToOpenMetricsFormat(registry)).isEqualTo(expected); @@ -87,7 +205,7 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { .thenReturn("Third User"); final LoadingCache cache = Caffeine.newBuilder().recordStats().build(loader); - final CacheMetricsCollector collector = new CacheMetricsCollector(); + final CacheMetricsCollector collector = CacheMetricsCollector.builder().build(); collector.addCache("loadingusers", cache); @@ -117,9 +235,14 @@ public void loadingCacheExposesMetricsForLoadsAndExceptions() throws Exception { assertThat(loadDuration.getSum()).isGreaterThan(0); } - @Test - public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping() { - final CacheMetricsCollector collector = new CacheMetricsCollector(); + @ParameterizedTest + @EnumSource + public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping(Options options) { + final CacheMetricsCollector collector = + CacheMetricsCollector.builder() + .collectEvictionWeightAsCounter(options.collectEvictionWeightAsCounter) + .collectWeightedSize(options.collectWeightedSize) + .build(); final PrometheusRegistry registry = new PrometheusRegistry(); registry.register(collector); @@ -130,9 +253,14 @@ public void getPrometheusNamesHasSameSizeAsMetricSizeWhenScraping() { assertThat(prometheusNames).hasSize(metricSnapshots.size()); } - @Test - public void collectedMetricNamesAreKnownPrometheusNames() { - final CacheMetricsCollector collector = new CacheMetricsCollector(); + @ParameterizedTest + @EnumSource + public void collectedMetricNamesAreKnownPrometheusNames(Options options) { + final CacheMetricsCollector collector = + CacheMetricsCollector.builder() + .collectEvictionWeightAsCounter(options.collectEvictionWeightAsCounter) + .collectWeightedSize(options.collectWeightedSize) + .build(); final PrometheusRegistry registry = new PrometheusRegistry(); registry.register(collector); @@ -153,6 +281,14 @@ private void assertCounterMetric( assertThat(dataPointSnapshot.getValue()).isEqualTo(value); } + private void assertGaugeMetric( + PrometheusRegistry registry, String name, String cacheName, double value) { + final GaugeSnapshot.GaugeDataPointSnapshot dataPointSnapshot = + (GaugeSnapshot.GaugeDataPointSnapshot) getDataPointSnapshot(registry, name, cacheName); + + assertThat(dataPointSnapshot.getValue()).isEqualTo(value); + } + private DataPointSnapshot getDataPointSnapshot( PrometheusRegistry registry, String name, String cacheName) { final Labels labels = Labels.of(new String[] {"cache"}, new String[] {cacheName}); From 403a9891f259d7f8fb733463465d61dfc52523cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 09:05:39 -0500 Subject: [PATCH 518/980] Bump org.assertj:assertj-core from 3.27.2 to 3.27.3 (#1263) Bumps [org.assertj:assertj-core](https://github.com/assertj/assertj) from 3.27.2 to 3.27.3. - [Release notes](https://github.com/assertj/assertj/releases) - [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.2...assertj-build-3.27.3) --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b9fb611d1..d85f3883c 100644 --- a/pom.xml +++ b/pom.xml @@ -122,7 +122,7 @@ org.assertj assertj-core - 3.27.2 + 3.27.3 test From 0ee705c68762190c4d3df6ae7b73ec2d25b08c67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 09:05:57 -0500 Subject: [PATCH 519/980] Bump com.github.ben-manes.caffeine:caffeine from 3.1.8 to 3.2.0 (#1264) Bumps [com.github.ben-manes.caffeine:caffeine](https://github.com/ben-manes/caffeine) from 3.1.8 to 3.2.0. - [Release notes](https://github.com/ben-manes/caffeine/releases) - [Commits](https://github.com/ben-manes/caffeine/compare/v3.1.8...v3.2.0) --- updated-dependencies: - dependency-name: com.github.ben-manes.caffeine:caffeine dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-instrumentation-caffeine/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index 0de05d99c..dd471254a 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -37,7 +37,7 @@ com.github.ben-manes.caffeine caffeine - 3.1.8 + 3.2.0 provided From f7681a4a93312b3092016261ad364750210f34b7 Mon Sep 17 00:00:00 2001 From: Jean Hominal Date: Tue, 21 Jan 2025 10:50:47 +0100 Subject: [PATCH 520/980] Add documentation pages for Caffeine and Guava cache instrumentation libraries (#1262) * Add documentation pages for Caffeine and Guava cache instrumentation libraries Signed-off-by: Jean Hominal * Update caffeine.md to take in account modifications from #1251 Signed-off-by: Jean Hominal --------- Signed-off-by: Jean Hominal --- docs/content/instrumentation/caffeine.md | 126 +++++++++++++++++++++++ docs/content/instrumentation/guava.md | 85 +++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 docs/content/instrumentation/caffeine.md create mode 100644 docs/content/instrumentation/guava.md diff --git a/docs/content/instrumentation/caffeine.md b/docs/content/instrumentation/caffeine.md new file mode 100644 index 000000000..dde7e561a --- /dev/null +++ b/docs/content/instrumentation/caffeine.md @@ -0,0 +1,126 @@ +--- +title: Caffeine Cache +weight: 1 +--- + +The Caffeine instrumentation module, added in version 1.3.2, translates observability data +provided by caffeine `Cache` objects into prometheus metrics. + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-instrumentation-caffeine:1.3.2' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-instrumentation-caffeine + 1.3.2 + +``` +{{< /tab >}} +{{< /tabs >}} + +In order to collect metrics: + + * A single `CacheMetricsCollector` instance must be registered with the registry; + * Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; + * The `Cache` object must be instantiated with the `recordStats()` option, and then added to the + `CacheMetricsCollector` instance with a unique name, which will be used as the value of the + `cache` label on the exported metrics; + * If the `recordStats` option is not set, most metrics will only return zero values; + +```java +var cache = Caffeine.newBuilder().recordStats().build(); +var cacheMetrics = CacheMetricsCollector.builder().build(); +PrometheusRegistry.defaultRegistry.register(cacheMetrics); +cacheMetrics.addCache("mycache", cache); +``` + +{{< hint type=note >}} + +In version 1.3.5 and older of the caffeine instrumentation library, `CacheMetricsCollector.builder` +does not exist, i.e. a constructor call `new CacheMetricsCollector()` is the only option. + +{{< /hint >}} + +All example metrics on this page will use the `mycache` label value. + +Generic Cache Metrics +--------------------- + +For all cache instances, the following metrics will be available: + +``` +# TYPE caffeine_cache_hit counter +# HELP caffeine_cache_hit Cache hit totals +caffeine_cache_hit_total{cache="mycache"} 10.0 +# TYPE caffeine_cache_miss counter +# HELP caffeine_cache_miss Cache miss totals +caffeine_cache_miss_total{cache="mycache"} 3.0 +# TYPE caffeine_cache_requests counter +# HELP caffeine_cache_requests Cache request totals, hits + misses +caffeine_cache_requests_total{cache="mycache"} 13.0 +# TYPE caffeine_cache_eviction counter +# HELP caffeine_cache_eviction Cache eviction totals, doesn't include manually removed entries +caffeine_cache_eviction_total{cache="mycache"} 1.0 +# TYPE caffeine_cache_estimated_size +# HELP caffeine_cache_estimated_size Estimated cache size +caffeine_cache_estimated_size{cache="mycache"} 5.0 +``` + +Loading Cache Metrics +--------------------- + +If the cache is an instance of `LoadingCache`, i.e. it is built with a `loader` function that is +managed by the cache library, then metrics for observing load time and load failures become +available: + +``` +# TYPE caffeine_cache_load_failure counter +# HELP caffeine_cache_load_failure Cache load failures +caffeine_cache_load_failure_total{cache="mycache"} 10.0 +# TYPE caffeine_cache_loads counter +# HELP caffeine_cache_loads Cache loads: both success and failures +caffeine_cache_loads_total{cache="mycache"} 3.0 +# TYPE caffeine_cache_load_duration_seconds summary +# HELP caffeine_cache_load_duration_seconds Cache load duration: both success and failures +caffeine_cache_load_duration_seconds_count{cache="mycache"} 7.0 +caffeine_cache_load_duration_seconds_sum{cache="mycache"} 0.0034 +``` + +Weighted Cache Metrics +---------------------- + +Two metrics exist for observability specifically of caches that define a `weigher`: + +``` +# TYPE caffeine_cache_eviction_weight counter +# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries +caffeine_cache_eviction_weight_total{cache="mycache"} 5.0 +# TYPE caffeine_cache_weighted_size gauge +# HELP caffeine_cache_weighted_size Approximate accumulated weight of cache entries +caffeine_cache_weighted_size{cache="mycache"} 30.0 +``` + +{{< hint type=note >}} + +`caffeine_cache_weighted_size` is available only if the cache instance defines a `maximumWeight`. + +{{< /hint >}} + +Up to version 1.3.5 and older, the weighted metrics had a different behavior: + + * `caffeine_cache_weighted_size` was not implemented; + * `caffeine_cache_eviction_weight` was exposed as a `gauge`; + +It is possible to restore the behavior of version 1.3.5 and older, by either: + + * Using the deprecated `new CacheMetricsCollector()` constructor; + * Using the flags provided on the `CacheMetricsCollector.Builder` object to opt-out of each of the + elements of the post-1.3.5 behavior: + * `builder.collectWeightedSize(false)` will disable collection of `caffeine_cache_weighted_size`; + * `builder.collectEvictionWeightAsCounter(false)` will expose `caffeine_cache_eviction_weight` as + a `gauge` metric; diff --git a/docs/content/instrumentation/guava.md b/docs/content/instrumentation/guava.md new file mode 100644 index 000000000..33cadae97 --- /dev/null +++ b/docs/content/instrumentation/guava.md @@ -0,0 +1,85 @@ +--- +title: Guava Cache +weight: 1 +--- + +The Guava instrumentation module, added in version 1.3.2, translates observability data +provided by Guava `Cache` objects into prometheus metrics. + +{{< tabs "uniqueid" >}} +{{< tab "Gradle" >}} +``` +implementation 'io.prometheus:prometheus-metrics-instrumentation-guava:1.3.2' +``` +{{< /tab >}} +{{< tab "Maven" >}} +```xml + + io.prometheus + prometheus-metrics-instrumentation-guava + 1.3.2 + +``` +{{< /tab >}} +{{< /tabs >}} + +In order to collect metrics: + +* A single `CacheMetricsCollector` instance must be registered with the registry; + * Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; +* The `Cache` object must be instantiated with the `recordStats()` option, and then added to the + `CacheMetricsCollector` instance with a unique name, which will be used as the value of the + `cache` label on the exported metrics; + * If the `recordStats` option is not set, most metrics will only return zero values; + +```java +var cache = CacheBuilder.newBuilder().recordStats().build(); +var cacheMetrics = new CacheMetricsCollector(); +PrometheusRegistry.defaultRegistry.register(cacheMetrics); +cacheMetrics.addCache("mycache", cache); +``` + +All example metrics on this page will use the `mycache` label value. + +Generic Cache Metrics +--------------------- + +For all cache instances, the following metrics will be available: + +``` +# TYPE guava_cache_hit counter +# HELP guava_cache_hit Cache hit totals +guava_cache_hit_total{cache="mycache"} 10.0 +# TYPE guava_cache_miss counter +# HELP guava_cache_miss Cache miss totals +guava_cache_miss_total{cache="mycache"} 3.0 +# TYPE guava_cache_requests counter +# HELP guava_cache_requests Cache request totals +guava_cache_requests_total{cache="mycache"} 13.0 +# TYPE guava_cache_eviction counter +# HELP guava_cache_eviction Cache eviction totals, doesn't include manually removed entries +guava_cache_eviction_total{cache="mycache"} 1.0 +# TYPE guava_cache_size +# HELP guava_cache_size Cache size +guava_cache_size{cache="mycache"} 5.0 +``` + +Loading Cache Metrics +--------------------- + +If the cache is an instance of `LoadingCache`, i.e. it is built with a `loader` function that is +managed by the cache library, then metrics for observing load time and load failures become +available: + +``` +# TYPE guava_cache_load_failure counter +# HELP guava_cache_load_failure Cache load failures +guava_cache_load_failure_total{cache="mycache"} 10.0 +# TYPE guava_cache_loads counter +# HELP guava_cache_loads Cache loads: both success and failures +guava_cache_loads_total{cache="mycache"} 3.0 +# TYPE guava_cache_load_duration_seconds summary +# HELP guava_cache_load_duration_seconds Cache load duration: both success and failures +guava_cache_load_duration_seconds_count{cache="mycache"} 7.0 +guava_cache_load_duration_seconds_sum{cache="mycache"} 0.0034 +``` From 31c7b6b80e68004c9fc1f985def46fa3f3be3f69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 15:18:10 +0100 Subject: [PATCH 521/980] Bump org.springframework.boot:spring-boot-starter-parent from 3.4.1 to 3.4.2 (#1267) Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.4.1 to 3.4.2.

      Release notes

      Sourced from org.springframework.boot:spring-boot-starter-parent's releases.

      v3.4.2

      :lady_beetle: Bug Fixes

      • Property metadata for "logging.structured.json.customizer" has incorrect type #43916
      • GraylogExtendedLogFormatProperties throws NullPointerException when only 'logging.structured.gelf.host' is specified #43863
      • Structured logging properties have no effect in a native image #43862
      • Docker Compose support for ClickHouse does not allow an empty password when ALLOW_EMPTY_PASSWORD=yes #43790
      • docker compose ps now fails due to unknown --orphans flag with 2.23 or earlier #43717
      • Build info timestamp is truncated to seconds #43617
      • FileWatcher used for SSL reload does not support symlinks #43604
      • BindableRuntimeHintsRegistrar should handle TypeNotPresentException #43600
      • CapturedOutput is empty when using Log4J2 StatusLogger #43578
      • Spring Boot 3.4 is not compatible with Gson 2.10 #43442
      • NoClassDefFoundError when using JUnit to test a Gradle 7.6.x app that depends on spring-boot-actuator-autoconfigure but not on org.junit.platform:junit-platform-launcher #43340

      :notebook_with_decorative_cover: Documentation

      • Document that the @ConfigurationProperties annotation processor cannot generate description and defaultValue metadata for external types #43929
      • Fix description of management.metrics.graphql.autotime.enabled #43905
      • Document 'base64:' prefix support #43835
      • Document handling of @Fallback beans in ConditionalOnSingleCandidate's javadoc #43826
      • Javadoc of DataSourceBuilder does not reference all supported types #43732
      • Update OpenTelemetry section in Supported Monitoring Systems to refer to OTLP instead #43729
      • Consistently document the minimum supported versions of Gradle #43725
      • Document that system libraries are a reason to customize the builder and switch away from builder-jammy-java-tiny #43716
      • Links to the Javadoc of Jakarta Messaging are invalid #43662
      • Paragraph HTML tags are rendered as-is in Maven Plugin reference documentation #43623
      • Javadoc link for jakarta.xml.bind is invalid #43607
      • Documentation still has references to 'layertools' #43605
      • Javadoc of ConstructorBinding should not use markdown formatting #43599
      • Managed Dependency Coordinates lists Spock and OkHttp dependencies that are not managed #43584

      :hammer: Dependency Upgrades

      • Upgrade to ActiveMQ 6.1.5 #43791
      • Upgrade to Commons Codec 1.17.2 #43720
      • Upgrade to Couchbase Client 3.7.7 #43843
      • Upgrade to FreeMarker 2.3.34 #43721
      • Upgrade to Hibernate 6.6.5.Final #43910
      • Upgrade to HttpCore5 5.3.2 #43792
      • Upgrade to Infinispan 15.0.12.Final #43911
      • Upgrade to Jersey 3.1.10 #43793
      • Upgrade to jOOQ 3.19.18 #43844
      • Upgrade to Lettuce 6.4.2.RELEASE #43609
      • Upgrade to Logback 1.5.16 #43715
      • Upgrade to Micrometer 1.14.3 #43745
      • Upgrade to Micrometer Tracing 1.4.2 #43746
      • Upgrade to Netty 4.1.117.Final #43845
      • Upgrade to Postgresql 42.7.5 #43846
      • Upgrade to Pulsar 3.3.4 #43912

      ... (truncated)

      Commits
      • f775945 Release v3.4.2
      • 068b960 Merge branch '3.3.x' into 3.4.x
      • 34c8353 Next development version (v3.3.9-SNAPSHOT)
      • f184e98 Merge branch '3.3.x' into 3.4.x
      • 390963f Document when defaultValue and description cannot be extracted
      • ef82719 Fix memory comparison in ProcessInfoTests
      • 1e35a0b Correct the type of logging.structured.json.customizer
      • 24e40e8 Upgrade to Spring Pulsar 1.2.2
      • 30dd62a Merge branch '3.3.x' into 3.4.x
      • a3eaafb Upgrade to Spring Pulsar 1.1.8
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot:spring-boot-starter-parent&package-manager=maven&previous-version=3.4.1&new-version=3.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 3469e621f..d7e39b25f 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.1 + 3.4.2 From 07e66ec0bc93f6f9cf178a51ef0cd391b7ee10ca Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 30 Jan 2025 14:09:53 +0100 Subject: [PATCH 522/980] bom should not include guava - it was only for internal code reuse (#1269) fixes https://github.com/prometheus/client_java/issues/1268 Signed-off-by: Gregor Zeitlinger --- pom.xml | 12 ++---------- prometheus-metrics-instrumentation-guava/pom.xml | 1 + 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index d85f3883c..43dba94e8 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ UTF-8 --module-name-need-to-be-overriden-- + 33.4.0-jre 5.11.4 2.12.0-alpha 8 @@ -82,16 +83,6 @@ prometheus-metrics-simpleclient-bridge - - - - com.google.guava - guava - 33.4.0-jre - - - - com.google.code.findbugs @@ -128,6 +119,7 @@ com.google.guava guava + ${guava.version} test diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 08ea80411..06393868d 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -37,6 +37,7 @@ com.google.guava guava + ${guava.version} provided From 49985ddf6b91d48323baa86b531d86eaa2cab4f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:58:17 +0100 Subject: [PATCH 523/980] Bump org.wiremock:wiremock from 3.10.0 to 3.11.0 (#1270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.wiremock:wiremock](https://github.com/wiremock/wiremock) from 3.10.0 to 3.11.0.
      Release notes

      Sourced from org.wiremock:wiremock's releases.

      3.11.0

      🚀 New Features

      🐞 Bug fixes

      📦 Dependency updates

      ✍ Other changes

      Commits
      • dd8e739 Fixed test broken by suppression of HTTPS upgrade by the Apache HTTP Client
      • a7d9ac8 Bumped minor version
      • bd17065 Merge pull request #2918 from ianprime0509/xml-default-instance
      • 63a3a12 Update after-pattern.yaml to fix typo (#2949)
      • 437e3ec Disable problematic protocol update for httpclient 5.4 (#2951)
      • c3f3319 Bump jetty 12 version to 12.0.16 (#2947)
      • 9ccb1c8 improve performance of EqualToXmlPattern. (#2944)
      • f913265 Make EqualToXmlPattern namespace aware by default. (#2945)
      • 6217b77 Merge pull request #2943 from Ashish-CodeJourney/master
      • afe7de8 Merge pull request #1 from Ashish-CodeJourney/Ashish-CodeJourney-patch-1
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.wiremock:wiremock&package-manager=maven&previous-version=3.10.0&new-version=3.11.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 5145d1504..8a5a71988 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -73,7 +73,7 @@ org.wiremock wiremock - 3.10.0 + 3.11.0 test From 5e93f4b2af0321061865bad1f39f531f3d19bd0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 09:12:34 -0500 Subject: [PATCH 524/980] Bump org.wiremock:wiremock from 3.11.0 to 3.12.0 (#1272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.wiremock:wiremock](https://github.com/wiremock/wiremock) from 3.11.0 to 3.12.0.
      Release notes

      Sourced from org.wiremock:wiremock's releases.

      3.12.0

      🚀 New Features

      📦 Dependency updates

      ✍ Other changes

      Commits
      • f208518 bump minor version to 3.12.0
      • ec2e9fa Merge pull request #2962 from wiremock/dependabot/gradle/net.minidev-json-sma...
      • 81a2d8c Bump net.minidev:json-smart from 2.5.1 to 2.5.2
      • ea72722 Support optional removal of null-valued attributes in jsonMerge helper (#2957)
      • 5c220de feat: add namespace parameter to equalToXml. (#2954)
      • c31c9b2 Merge pull request #2950 from wiremock/dependabot/gradle/me.champeau.jmh-0.7.3
      • 658d13f Bump me.champeau.jmh from 0.7.2 to 0.7.3
      • 1859573 Merge pull request #2955 from wiremock/drop-spotless-version
      • d0caac8 Drop to the version of spotless where we didn't have any issues
      • 32a0c00 Merge pull request #2952 from wiremock/dependabot/gradle/org.apache.httpcompo...
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.wiremock:wiremock&package-manager=maven&previous-version=3.11.0&new-version=3.12.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 8a5a71988..fb1561478 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -73,7 +73,7 @@ org.wiremock wiremock - 3.11.0 + 3.12.0 test From 104b3ee0c5a874b3cb7c82039e6e94f619215520 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 17:43:20 +0100 Subject: [PATCH 525/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.12.0-alpha to 2.13.0-alpha (#1275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.12.0-alpha to 2.13.0-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.12.0

      This release targets the OpenTelemetry SDK 1.46.0.

      Note that many artifacts have the -alpha suffix attached to their version number, reflecting that they are still alpha quality and will continue to have breaking changes. Please see the VERSIONING.md for more details.

      Migration notes

      • Some Java agent instrumentation suppression keys have been renamed to match their module names: - elasticsearch-rest-6.0 --> elasticsearch-rest-6.4 - internal-application-logging --> internal-application-logger - javalin-5 -> javalin-5.0 - pulsar-2.8.0 -> pulsar-2.8
      • In preparation for stabilizing HTTP library instrumentation soon: - setCaptured*Headers(List) methods in *TelemetryBuilder classes were changed to setCaptured*Headers(Collection) (#12901) - setKnownMethods(Set) methods in *TelemetryBuilder classes were changed to setKnownMethods(Collection) (#12902)

      📈 Enhancements

      • Support ExtendedTextMapGetter in gRPC instrumentation (#13011)
      • Add database client metrics in DynamoDB instrumentation (#13033)
      • Propagate context into async http client CompletableFuture callbacks (#13041)
      • Exclude spring routing data source from Spring Starter instrumentation (#13054)
      • Instrument jdbc batch queries (#12797)

      🛠️ Bug fixes

      • Fix incorrect dubbo trace caused by using rpcContext.isProviderSide() (#12930)
      • Fix ClickHouse query failing with syntax error (#13020)
      • Fix instrumentation module not loading silently when duplicate helper classnames are detected (#13005)
      • Fix compatibility problem due to DubboHeadersGetter#keys in Dubbo 2.7.6 and 2.7.7 (#12982)
      • Fix appender install for async Logback appenders (#13047)

      🙇 Thank you

      This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

      @​AlbumenJ @​annettejanewilson @​ataraxis @​cleverchuk @​FlorianBruckner @​jamesmoessis @​jaydeluca @​jeanbisutti @​johnbley @​JonasKunz @​laurit @​markAtAthena @​rghugikar @​shalk @​steverao @​SylvainJuge @​trask @​xiepuhuan @​zeitlinger

      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Version 2.13.0 (2025-02-17)

      Migration notes

      • io.opentelemetry.instrumentation.api.incubator.semconv.util.SpanNames has been deprecated, replaced by the stable io.opentelemetry.instrumentation.api.semconv.util.SpanNames
      • In preparation for stabilizing HTTP library instrumentation, the classes and methods that were deprecated in the prior two releases have now been removed (#13135, #13150)
      • Deprecated Dubbo instrumentation method was removed (#13076)

      🌟 New javaagent instrumentation

      • jdk.httpserver instrumentation (#13243)

      🌟 New library instrumentation

      • jdk.httpserver instrumentation (#13243)

      📈 Enhancements

      • Add database client metrics to Lettuce instrumentation (#13032)
      • Stabilize io.opentelemetry.instrumentation.api.semconv.util.SpanNames (#12487)
      • Implement ExtendedTextMapGetter in http server instrumentations (#13053)
      • Implement ExtendedTextMapGetter in kafka-clients instrumentation (#13068)
      • Scrub system property secrets from process resource attribute values (#13225)
      • Add database client metrics to AWS SDK 2.x DynamoDB instrumentation (#13283)
      • Add runtime metrics to Spring boot starter (#13173)

      🛠️ Bug fixes

      • Fix akka shutdown hanging (#13073)
      • Fix MalformedInputException on z/OS (#13042)

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.12.0-alpha&new-version=2.13.0-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 43dba94e8..1ec1fb04b 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ --module-name-need-to-be-overriden-- 33.4.0-jre 5.11.4 - 2.12.0-alpha + 2.13.0-alpha 8 0.70 false From 60dc69d26e2acbc2235fb3e68efb472ae157cd7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 17:43:44 +0100 Subject: [PATCH 526/980] Bump org.apache.tomcat.embed:tomcat-embed-core from 11.0.2 to 11.0.4 (#1274) Bumps org.apache.tomcat.embed:tomcat-embed-core from 11.0.2 to 11.0.4. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.tomcat.embed:tomcat-embed-core&package-manager=maven&previous-version=11.0.2&new-version=11.0.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 86f08018c..2530297a8 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.2 + 11.0.4
      diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 0b0122cdb..7d0f49aff 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.2 + 11.0.4 diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 39b505f30..3632748fb 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.2 + 11.0.4 diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 2af2a5928..f320764a1 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -33,7 +33,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.2 + 11.0.4 From 39a83b96556ee48a5a7271b43be46cbafa80aeca Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Feb 2025 12:21:59 +0100 Subject: [PATCH 527/980] increase coverage (#1276) Signed-off-by: Gregor Zeitlinger --- prometheus-metrics-exposition-formats/pom.xml | 8 +++++ .../ProtobufExpositionFormatsTest.java | 19 ++++++++++ .../pom.xml | 17 +++++++++ .../ExpositionFormatWriterTest.java | 21 +++++++++++ .../ExpositionFormatsTest.java | 10 +----- .../PrometheusProtobufWriterTest.java | 36 +++++++++++++++++++ 6 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java create mode 100644 prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java rename {prometheus-metrics-exposition-formats => prometheus-metrics-exposition-textformats}/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java (99%) create mode 100644 prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriterTest.java diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 83fb7e3c0..90e118072 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -33,6 +33,14 @@ protobuf-java ${protobuf-java.version} + + + io.prometheus + prometheus-metrics-exposition-textformats + ${project.version} + test + test-jar + diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java new file mode 100644 index 000000000..edb28ab67 --- /dev/null +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java @@ -0,0 +1,19 @@ +package io.prometheus.metrics.expositionformats; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; +import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; +import io.prometheus.metrics.model.snapshots.MetricSnapshot; + +class ProtobufExpositionFormatsTest extends ExpositionFormatsTest { + + @Override + protected void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { + PrometheusProtobufWriterImpl writer = new PrometheusProtobufWriterImpl(); + Metrics.MetricFamily protobufData = writer.convert(snapshot); + String actual = ProtobufUtil.shortDebugString(protobufData); + assertThat(actual).isEqualTo(expected); + } +} diff --git a/prometheus-metrics-exposition-textformats/pom.xml b/prometheus-metrics-exposition-textformats/pom.xml index 6a38dd67b..13ab9e5e7 100644 --- a/prometheus-metrics-exposition-textformats/pom.xml +++ b/prometheus-metrics-exposition-textformats/pom.xml @@ -19,6 +19,7 @@ io.prometheus.writer.text + 0.50 @@ -33,4 +34,20 @@ ${project.version} + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java new file mode 100644 index 000000000..7fae4a2fb --- /dev/null +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java @@ -0,0 +1,21 @@ +package io.prometheus.metrics.expositionformats; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import org.junit.jupiter.api.Test; + +class ExpositionFormatWriterTest { + + private final ExpositionFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); + + @Test + void toDebugString() { + assertThat(writer.toDebugString(new MetricSnapshots())).isEqualTo("# EOF\n"); + } + + @Test + void isAvailable() { + assertThat(writer.isAvailable()).isTrue(); + } +} diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java similarity index 99% rename from prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java rename to prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index 4c4ae3059..46f8faac9 100644 --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2,9 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; -import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; -import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot; @@ -2659,10 +2656,5 @@ private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot assertThat(out).hasToString(expected); } - private void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) { - PrometheusProtobufWriterImpl writer = new PrometheusProtobufWriterImpl(); - Metrics.MetricFamily protobufData = writer.convert(snapshot); - String actual = ProtobufUtil.shortDebugString(protobufData); - assertThat(actual).isEqualTo(expected); - } + protected void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot) {} } diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriterTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriterTest.java new file mode 100644 index 000000000..814154325 --- /dev/null +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/PrometheusProtobufWriterTest.java @@ -0,0 +1,36 @@ +package io.prometheus.metrics.expositionformats; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +import org.junit.jupiter.api.Test; + +class PrometheusProtobufWriterTest { + + private final PrometheusProtobufWriter writer = new PrometheusProtobufWriter(); + + @Test + void accepts() { + assertThat(writer.accepts(null)).isFalse(); + } + + @Test + void getContentType() { + assertThat(writer.getContentType()) + .isEqualTo( + "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; " + + "encoding=delimited"); + } + + @Test + void write() { + assertThatCode(() -> writer.write(null, null)) + .isInstanceOf(UnsupportedOperationException.class); + } + + @Test + void toDebugString() { + assertThatCode(() -> writer.toDebugString(null)) + .isInstanceOf(UnsupportedOperationException.class); + } +} From 7016bf7c5749e806ef91a918fdb294d394b83a16 Mon Sep 17 00:00:00 2001 From: Philippe Marschall Date: Tue, 18 Feb 2025 14:56:32 +0100 Subject: [PATCH 528/980] Use bulk string writes for text formats (#1273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Further optimize `TextFormatUtil#writeEscapedLabelValue`. We're seeing `TextFormatUtil#writeEscapedLabelValue` show up in our production traces due to the single `char` writes to `OutputStreamWriter`. We're using `OpenMetricsTextFormatWriter`. #1241 and #1248 should take care of most of these issues but there still remains some optimization potential left. `BufferedWriter#write(int)` has some minimal overhead in terms of locking. If we assume that rarely any characters need to be escaped and instead optimize to write as large of a part of the String as possible in one method call. Before --------- ``` Benchmark Mode Cnt Score Error Units TextFormatUtilBenchmark.openMetricsWriteToByteArray thrpt 25 438485.372 ± 4270.355 ops/s TextFormatUtilBenchmark.openMetricsWriteToNull thrpt 25 440105.281 ± 2891.572 ops/s TextFormatUtilBenchmark.prometheusWriteToByteArray thrpt 25 467213.001 ± 878.780 ops/s TextFormatUtilBenchmark.prometheusWriteToNull thrpt 25 472931.759 ± 976.028 ops/s ``` After ------- ``` Benchmark Mode Cnt Score Error Units TextFormatUtilBenchmark.openMetricsWriteToByteArray thrpt 25 462852.243 ± 5071.696 ops/s TextFormatUtilBenchmark.openMetricsWriteToNull thrpt 25 469910.681 ± 1670.430 ops/s TextFormatUtilBenchmark.prometheusWriteToByteArray thrpt 25 482362.506 ± 2051.684 ops/s TextFormatUtilBenchmark.prometheusWriteToNull thrpt 25 487707.557 ± 3344.881 ops/s ``` About a 5% to 6% gain for `OpenMetricsTextFormatWriter` and around 3% for `PrometheusTextFormatWriter`. Note that this benchmark is actually for `OpenMetricsTextFormatWriter` and `PrometheusTextFormatWriter` since `TextFormatUtil` is not public and can therefore not be benchmarked directly. The relative gains in `#writeEscapedLabelValue` are higher because the benchmark runs the full text format writers. I also added a test for `TextFormatUtil#writeEscapedLabelValue` since the code is now more complicated. --------- Signed-off-by: Philippe Marschall Co-authored-by: Doug Hoard --- benchmarks/pom.xml | 15 +-- .../benchmarks/TextFormatUtilBenchmark.java | 122 ++++++++++++++++++ .../expositionformats/TextFormatUtil.java | 46 ++++++- .../expositionformats/TextFormatUtilTest.java | 24 ++++ 4 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java create mode 100644 prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index de53b2edd..98d084787 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -42,20 +42,13 @@ ${jmh.version} - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - - io.prometheus - prometheus-metrics-core + prometheus-metrics-exposition-textformats ${project.version} diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java new file mode 100644 index 000000000..03dcd0d07 --- /dev/null +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java @@ -0,0 +1,122 @@ +package io.prometheus.metrics.benchmarks; + +import io.prometheus.metrics.expositionformats.ExpositionFormatWriter; +import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; +import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter; +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.MetricSnapshot; +import io.prometheus.metrics.model.snapshots.MetricSnapshots; +import io.prometheus.metrics.model.snapshots.SummarySnapshot; +import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot; +import io.prometheus.metrics.model.snapshots.Unit; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +public class TextFormatUtilBenchmark { + + private static final MetricSnapshots SNAPSHOTS; + + static { + MetricSnapshot gaugeSnapshot = + GaugeSnapshot.builder() + .name("gauge_snapshot_name") + .dataPoint( + GaugeDataPointSnapshot.builder() + .labels(Labels.of("name", "value")) + .scrapeTimestampMillis(1000L) + .value(123.45d) + .build()) + .build(); + + MetricSnapshot summaryDataPointSnapshot = + SummarySnapshot.builder() + .name("summary_snapshot_name_bytes") + .dataPoint( + SummaryDataPointSnapshot.builder() + .count(5) + .labels(Labels.of("name", "value")) + .sum(123456d) + .build()) + .unit(Unit.BYTES) + .build(); + + SNAPSHOTS = MetricSnapshots.of(gaugeSnapshot, summaryDataPointSnapshot); + } + + private static final ExpositionFormatWriter OPEN_METRICS_TEXT_FORMAT_WRITER = + new OpenMetricsTextFormatWriter(false, false); + private static final ExpositionFormatWriter PROMETHEUS_TEXT_FORMAT_WRITER = + new PrometheusTextFormatWriter(false); + + @State(Scope.Benchmark) + public static class WriterState { + + final ByteArrayOutputStream byteArrayOutputStream; + + public WriterState() { + this.byteArrayOutputStream = new ByteArrayOutputStream(); + } + } + + @Benchmark + public OutputStream openMetricsWriteToByteArray(WriterState writerState) throws IOException { + // avoid growing the array + ByteArrayOutputStream byteArrayOutputStream = writerState.byteArrayOutputStream; + byteArrayOutputStream.reset(); + OPEN_METRICS_TEXT_FORMAT_WRITER.write(byteArrayOutputStream, SNAPSHOTS); + return byteArrayOutputStream; + } + + @Benchmark + public OutputStream openMetricsWriteToNull() throws IOException { + OutputStream nullOutputStream = NullOutputStream.INSTANCE; + OPEN_METRICS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS); + return nullOutputStream; + } + + @Benchmark + public OutputStream prometheusWriteToByteArray(WriterState writerState) throws IOException { + // avoid growing the array + ByteArrayOutputStream byteArrayOutputStream = writerState.byteArrayOutputStream; + byteArrayOutputStream.reset(); + PROMETHEUS_TEXT_FORMAT_WRITER.write(byteArrayOutputStream, SNAPSHOTS); + return byteArrayOutputStream; + } + + @Benchmark + public OutputStream prometheusWriteToNull() throws IOException { + OutputStream nullOutputStream = NullOutputStream.INSTANCE; + PROMETHEUS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS); + return nullOutputStream; + } + + static final class NullOutputStream extends OutputStream { + + static final OutputStream INSTANCE = new NullOutputStream(); + + private NullOutputStream() { + super(); + } + + @Override + public void write(int b) {} + + @Override + public void write(byte[] b) {} + + @Override + public void write(byte[] b, int off, int len) {} + + @Override + public void flush() {} + + @Override + public void close() {} + } +} diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index e48f545c5..dffa8ddef 100644 --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -35,21 +35,53 @@ static void writeTimestamp(Writer writer, long timestampMs) throws IOException { } static void writeEscapedLabelValue(Writer writer, String s) throws IOException { - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); + // optimize for the common case where no escaping is needed + int start = 0; + // #indexOf is a vectorized intrinsic + int backslashIndex = s.indexOf('\\', start); + int quoteIndex = s.indexOf('\"', start); + int newlineIndex = s.indexOf('\n', start); + + int allEscapesIndex = backslashIndex & quoteIndex & newlineIndex; + while (allEscapesIndex != -1) { + int escapeStart = Integer.MAX_VALUE; + if (backslashIndex != -1) { + escapeStart = backslashIndex; + } + if (quoteIndex != -1) { + escapeStart = Math.min(escapeStart, quoteIndex); + } + if (newlineIndex != -1) { + escapeStart = Math.min(escapeStart, newlineIndex); + } + + // bulk write up to the first character that needs to be escaped + if (escapeStart > start) { + writer.write(s, start, escapeStart - start); + } + char c = s.charAt(escapeStart); + start = escapeStart + 1; switch (c) { case '\\': - writer.append("\\\\"); + writer.write("\\\\"); + backslashIndex = s.indexOf('\\', start); break; case '\"': - writer.append("\\\""); + writer.write("\\\""); + quoteIndex = s.indexOf('\"', start); break; case '\n': - writer.append("\\n"); + writer.write("\\n"); + newlineIndex = s.indexOf('\n', start); break; - default: - writer.append(c); } + + allEscapesIndex = backslashIndex & quoteIndex & newlineIndex; + } + // up until the end nothing needs to be escaped anymore + int remaining = s.length() - start; + if (remaining > 0) { + writer.write(s, start, remaining); } } diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java new file mode 100644 index 000000000..dece52abb --- /dev/null +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java @@ -0,0 +1,24 @@ +package io.prometheus.metrics.expositionformats; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; +import org.junit.jupiter.api.Test; + +class TextFormatUtilTest { + + @Test + void writeEscapedLabelValue() throws IOException { + assertEquals("aa\\\\bb\\\"cc\\ndd\\nee\\\\ff\\\"gg", escape("aa\\bb\"cc\ndd\nee\\ff\"gg")); + assertEquals("\\\\", escape("\\")); + assertEquals("\\\\\\\\", escape("\\\\")); + assertEquals("text", escape("text")); + } + + private static String escape(String s) throws IOException { + StringWriter writer = new StringWriter(); + TextFormatUtil.writeEscapedLabelValue(writer, s); + return writer.toString(); + } +} From 96f5a4086d854f63ec454b2f86007057b634a706 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 19 Feb 2025 12:33:49 +0100 Subject: [PATCH 529/980] fix gh pages (#1278) Signed-off-by: Gregor Zeitlinger --- prometheus-metrics-exposition-formats/pom.xml | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 90e118072..9643998b2 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 @@ -34,15 +35,34 @@ ${protobuf-java.version} - - io.prometheus - prometheus-metrics-exposition-textformats - ${project.version} - test - test-jar - + + + + javadoc + + + release + + + default + + true + + + + + io.prometheus + prometheus-metrics-exposition-textformats + ${project.version} + test + test-jar + + + + + @@ -69,7 +89,9 @@ bsh-property - skip.protobuf.generation = !"true".equals(System.getenv("PROTO_GENERATION")); + skip.protobuf.generation = + !"true".equals(System.getenv("PROTO_GENERATION")); + skip.protobuf.generation From 629ec3ab9504ecf660bd8c67430d753e9b134833 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 10:19:03 +0100 Subject: [PATCH 530/980] Bump org.apache.maven.plugins:maven-clean-plugin from 3.4.0 to 3.4.1 (#1279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) from 3.4.0 to 3.4.1.
      Release notes

      Sourced from org.apache.maven.plugins:maven-clean-plugin's releases.

      3.4.1

      🚀 New features and improvements

      📦 Dependency updates

      👻 Maintenance

      Commits
      • 8211bc5 [maven-release-plugin] prepare release maven-clean-plugin-3.4.1
      • 92305ba Update scm tag according to branch
      • 9db0e77 PR Automation only on close event
      • 7065077 [MNGSITE-529] Rename "Goals" to "Plugin Documentation"
      • c003151 release-drafter configuration
      • a70d2e4 Use global release-drafter configuration
      • 5e797fc Bump org.apache.maven.resolver:maven-resolver-api from 1.1.1 to 1.9.22
      • e514d80 Bump mavenVersion from 3.6.3 to 3.9.9 (#77)
      • 9dc0953 Bump org.codehaus.plexus:plexus-testing from 1.3.0 to 1.4.0
      • dcc3b09 Fix license/notice (#48)
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-clean-plugin&package-manager=maven&previous-version=3.4.0&new-version=3.4.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1ec1fb04b..c288c0d80 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@
      maven-clean-plugin - 3.4.0 + 3.4.1 maven-site-plugin From 98452800dba104d769519d279cb52de4171fcafb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 10:19:20 +0100 Subject: [PATCH 531/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.13.0-alpha to 2.13.1-alpha (#1280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.13.0-alpha to 2.13.1-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.13.0

      This release targets the OpenTelemetry SDK 1.47.0.

      Note that many artifacts have the -alpha suffix attached to their version number, reflecting that they are still alpha quality and will continue to have breaking changes. Please see the VERSIONING.md for more details.

      Migration notes

      • io.opentelemetry.instrumentation.api.incubator.semconv.util.SpanNames has been deprecated, replaced by the stable io.opentelemetry.instrumentation.api.semconv.util.SpanNames
      • In preparation for stabilizing HTTP library instrumentation, the classes and methods that were deprecated in the prior two releases have now been removed (#13135, #13150)
      • Deprecated Dubbo instrumentation method was removed (#13076)

      🌟 New javaagent instrumentation

      • jdk.httpserver instrumentation (#13243)

      🌟 New library instrumentation

      • jdk.httpserver instrumentation (#13243)

      📈 Enhancements

      • Add database client metrics to Lettuce instrumentation (#13032)
      • Stabilize io.opentelemetry.instrumentation.api.semconv.util.SpanNames (#12487)
      • Implement ExtendedTextMapGetter in http server instrumentations (#13053)
      • Implement ExtendedTextMapGetter in kafka-clients instrumentation (#13068)
      • Scrub system property secrets from process resource attribute values (#13225)
      • Add database client metrics to AWS SDK 2.x DynamoDB instrumentation (#13283)
      • Add runtime metrics to Spring boot starter (#13173)

      🛠️ Bug fixes

      • Fix akka shutdown hanging (#13073)
      • Fix MalformedInputException on z/OS (#13042)
      • Fix scope leak in aws sdk instrumentation (#13129)
      • Fix MapConverter does not get initialized when OTEL_SDK_DISABLED is set to true (#13224)
      • Fix logback appender on android (#13234)
      • Fix Ktor 3 CallLogging and StatusPages don't have Trace IDs (#13239)
      • Fix Micrometer-bridge breaking Spring Actuator metrics (#13083)

      🙇 Thank you

      This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

      @​adrielp @​AlchemyDing @​bencehornak @​breedx-splk @​brunobat @​chalin @​e5l

      ... (truncated)

      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Migration notes

      • The java.net.http.HttpClient instrumentation package io.opentelemetry.instrumentation.httpclient was deprecated in favor of the new package name io.opentelemetry.instrumentation.javahttpclient

      Version 2.13.1 (2025-02-18)

      🛠️ Bug fixes

      • Backport: Fix double instrumentation of Java runtime metrics (#13339)

      Version 2.13.0 (2025-02-17)

      Migration notes

      • io.opentelemetry.instrumentation.api.incubator.semconv.util.SpanNames has been deprecated, replaced by the stable io.opentelemetry.instrumentation.api.semconv.util.SpanNames
      • In preparation for stabilizing HTTP library instrumentation, the classes and methods that were deprecated in the prior two releases have now been removed (#13135, #13150)
      • Deprecated Dubbo instrumentation method was removed (#13076)

      🌟 New javaagent instrumentation

      • jdk.httpserver instrumentation (#13243)

      🌟 New library instrumentation

      • jdk.httpserver instrumentation (#13243)

      📈 Enhancements

      • Add database client metrics to Lettuce instrumentation (#13032)
      • Stabilize io.opentelemetry.instrumentation.api.semconv.util.SpanNames (#12487)
      • Implement ExtendedTextMapGetter in http server instrumentations (#13053)
      • Implement ExtendedTextMapGetter in kafka-clients instrumentation (#13068)

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.13.0-alpha&new-version=2.13.1-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c288c0d80..4936f76bd 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ --module-name-need-to-be-overriden-- 33.4.0-jre 5.11.4 - 2.13.0-alpha + 2.13.1-alpha 8 0.70 false From a90cab5d7da3d44c9f54423384a1a802fb7170c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 14:49:36 +0100 Subject: [PATCH 532/980] Bump org.testcontainers:junit-jupiter from 1.20.4 to 1.20.5 (#1281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.20.4 to 1.20.5.
      Release notes

      Sourced from org.testcontainers:junit-jupiter's releases.

      1.20.5

      What's Changed

      🚀 Features & Enhancements

      🐛 Bug Fixes

      📖 Documentation

      🧹 Housekeeping

      📦 Dependency updates

      Commits
      • 13b6365 Rename Picone implementation
      • c34ed90 Rename EventHubs and ServiceBus implementations
      • aad1ee5 Add more configuration for LLdapContainer
      • 85697fd Add method to return LDAP URL to LLdapContainer
      • 2ac4ed6 Add ldap module (#9987)
      • aa7ddc0 Fix reuse support for CouchbaseContainer (#9957)
      • 2fa7f65 Don't extend configuration compileOnly and testCompile from shaded (#9579)
      • 99981f8 Fix typos (#9783)
      • df40cd8 Fix SolrContainer start parameters for version >= 9.7.0 (#9926)
      • 6139e5e Fix clickhouse authentication (#9942)
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.testcontainers:junit-jupiter&package-manager=maven&previous-version=1.20.4&new-version=1.20.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 41adf0e40..ec3362cd8 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -56,7 +56,7 @@ org.testcontainers junit-jupiter - 1.20.4 + 1.20.5 test From 3419df41745e1ad816c0437da2a150f8739cb3a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:02:21 -0500 Subject: [PATCH 533/980] Bump org.awaitility:awaitility from 4.2.2 to 4.3.0 (#1286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.awaitility:awaitility](https://github.com/awaitility/awaitility) from 4.2.2 to 4.3.0.
      Changelog

      Sourced from org.awaitility:awaitility's changelog.

      Changelog 4.3.0 (2025-02-21)

      • Support for kotlin.time.Duration in Kotlin DSL (thanks to Ivo Šmíd for PR)

      • Upgraded kotlin version in the awaitility-kotlin module to 2.1.10

      • Using a more descriptive error message when using VERY long wait conditions or poll durations (issue 290)

      • Added an overloaded method of untilAsserted(..) that takes a supplier and a consumer. Example lets say you have a class like this: public class MyClass { public String myFunction() { // Imagine stuff being executed in asynchrinously here and the result of this // operation is a string called "my value" return "my value" } }

        // Then in your test you can wait for the "myFunction" to be asserted by a "consumer" that uses // assertj to make sure that "myFunction" returns ""my value" await().untilAsserted(myClass::myFunction, value -> Assertions.assertThat(value).isEqualTo("my value"));

        This has also been implemented for all atomic, adder, and accumulator methods.

      Commits
      • e3ff879 [maven-release-plugin] prepare release awaitility-4.3.0
      • d116712 [ci skip] Preparing changelog for release
      • 4e186df Added kotlin source folder explicitly
      • e8d3ab7 Upgraded lots of plugin dependencies
      • a7a167a Added an overloaded method of untilAsserted(..) that takes a supplier and a c...
      • ef8f663 Make ConditionFactory safer to use in java 8
      • 5550079 Using a more descriptive error message when using VERY long wait conditions o...
      • 2a9814b Upgraded kotlin version in the awaitility-kotlin module to 2.1.10
      • 8f22c00 [ci skip] Updated changelog.txt to reflect latest changes
      • 6a35c24 #235 Support for kotlin.time.Duration in Kotlin DSL (#285)
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.awaitility:awaitility&package-manager=maven&previous-version=4.2.2&new-version=4.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index fb1561478..237ef4a91 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -85,7 +85,7 @@ org.awaitility awaitility - 4.2.2 + 4.3.0 test From c8d425b0f0a7b861daa31e6c6e74cd251f130af5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:02:35 -0500 Subject: [PATCH 534/980] Bump com.diffplug.spotless:spotless-maven-plugin from 2.44.2 to 2.44.3 (#1284) Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.44.2 to 2.44.3.
      Release notes

      Sourced from com.diffplug.spotless:spotless-maven-plugin's releases.

      Maven Plugin v2.44.3

      • Support for clang-format (#2406)
      • Adopt new version of maven-plugin-development from GradleX (#2395)
      Commits
      • 4dd0095 Published maven/2.44.3
      • 62eff17 Published lib/3.1.0
      • d88a76e feat: allow overriding JarSate classloader (to enable cli) (#2427)
      • 06c6ca8 chore: insert created PR#
      • 8ee1dfe chore: provide test to make sure overriding classloader works
      • 88d3c31 chore: update changelog for reflecting overridable classLoader in JarState
      • f519ed3 feat: allow overriding classLoader for jarstate
      • a410e9f adopt maven plugin development from gradle x (#2423 closes #2395)
      • fd5970c chore(deps): update plugin com.gradle.develocity to v3.19.2 (#2425)
      • cdb609e added changelog info in the right place
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.diffplug.spotless:spotless-maven-plugin&package-manager=maven&previous-version=2.44.2&new-version=2.44.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index d7e39b25f..973af1454 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -77,7 +77,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.2 + 2.44.3 diff --git a/pom.xml b/pom.xml index 4936f76bd..2a832a72d 100644 --- a/pom.xml +++ b/pom.xml @@ -215,7 +215,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.2 + 2.44.3
      From eaba6f89e7ecd5a3bccca326c407fd04afcf4ecd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 09:02:56 -0500 Subject: [PATCH 535/980] Bump org.apache.maven.plugins:maven-compiler-plugin from 3.13.0 to 3.14.0 (#1283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.13.0 to 3.14.0.
      Release notes

      Sourced from org.apache.maven.plugins:maven-compiler-plugin's releases.

      3.14.0

      🚀 New features and improvements

      🐛 Bug Fixes

      📦 Dependency updates

      👻 Maintenance

      🔧 Build

      Commits
      • b5e7d9b [maven-release-plugin] prepare release maven-compiler-plugin-3.14.0
      • 9134f12 Enable GitHub Issues
      • 19b8b12 Update scm tag according to branch
      • 09dce4e [MCOMPILER-579] allow module-version configuration (#273)
      • f7c3c5f Bump org.codehaus.plexus:plexus-java from 1.2.0 to 1.4.0
      • 764a54b [MNGSITE-529] Rename "Goals" to "Plugin Documentation"
      • cfacbc1 PR Automation only on close event
      • 5c26bba Use JUnit version from parent
      • 5449407 [MCOMPILER-529] Update docs about version schema (Maven 3)
      • 01d5b88 Bump mavenVersion from 3.6.3 to 3.9.9 (#283)
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-compiler-plugin&package-manager=maven&previous-version=3.13.0&new-version=3.14.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2a832a72d..ff5449582 100644 --- a/pom.xml +++ b/pom.xml @@ -151,7 +151,7 @@ maven-compiler-plugin - 3.13.0 + 3.14.0 maven-surefire-plugin From d88f624f7c29f5b149c7a2ce83db0880059d7851 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2025 10:53:05 +0100 Subject: [PATCH 536/980] Bump org.springframework.boot:spring-boot-starter-parent from 3.4.2 to 3.4.3 (#1285) Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.4.2 to 3.4.3.
      Release notes

      Sourced from org.springframework.boot:spring-boot-starter-parent's releases.

      v3.4.3

      :star: New Features

      • Add TWENTY_FOUR to JavaVersion enum #44209

      :lady_beetle: Bug Fixes

      • Console output may be lost when using Log4j2 with something that replaces System.out #44380
      • Maven plugin does not consistently use ArgFile for classpath argument on Windows #44328
      • Reactive Jetty web server does not fail fast when configured to use a server name bundle which Jetty does not support #44319
      • When web server application context refresh fails, the original failure is lost if stopping or destroying the web server throws an exception #44317
      • View resolver for Thymeleaf should back off if spring-webmvc is not present #44296
      • WebServer is not destroyed when ReactiveWebServerApplicationContext refresh fails #44294
      • Non-default DataSource candidates are not considered in H2ConsoleAutoConfiguration #44293
      • Banner placeholder and defaults do not work during development #44255
      • Mustache templates return with ISO-8859-1 charset rather than UTF-8 in Content-Type response header #44193
      • Servlet EndpointRequest doesn't match web server namespace correctly #44188
      • java.lang.ClassCastException when using default management security with WebFlux and health probes enabled #44052
      • Logback configuration that relies on inner-classes does not work in a native image #44025
      • IllegalStateException: Unable to register SSL bundle after 3.3.8 or 3.4.2 #43989
      • Metrics and health do not include non-default candidate beans #43481

      :notebook_with_decorative_cover: Documentation

      • Document that auto-configuration classes should be identified using their binary names #44303
      • Correct typo in MVC security when explaining when UserDetailsService auto-configuration will back off #44301
      • Link to JarLauncher's javadoc #44170
      • When using observability annotations, recommend that care is taken to avoid double instrumentation #44145
      • Fix typo in Running Your Application #44035
      • Document Kubernetes preStop handler when using a Docker image without a shell #44022
      • Source snippet in Developing Your First Spring Boot Application section uses the root package #43983
      • Correct the location of MyApplication.java in "Developing Your First Spring Boot Application" #43975
      • Add links to Jackson Javadoc #43971
      • Warn that some Quartz database schema scripts must be modified before use #43958

      :hammer: Dependency Upgrades

      • Upgrade to Commons Pool2 2.12.1 #44173
      • Upgrade to Couchbase Client 3.7.8 #44269
      • Upgrade to Groovy 4.0.25 #44174
      • Upgrade to Hibernate 6.6.8.Final #44332
      • Upgrade to HttpClient5 5.4.2 #44176
      • Upgrade to HttpCore5 5.3.3 #44177
      • Upgrade to Infinispan 15.0.13.Final #44178
      • Upgrade to jOOQ 3.19.19 #44368
      • Upgrade to Json-smart 2.5.2 #44264
      • Upgrade to Maven Clean Plugin 3.4.1 #44349
      • Upgrade to Micrometer 1.14.4 #44115
      • Upgrade to Micrometer Tracing 1.4.3 #44116
      • Upgrade to Native Build Tools Plugin 0.10.5 #44179

      ... (truncated)

      Commits
      • 2f53c0a Release v3.4.3
      • f99171f Merge branch '3.3.x' into 3.4.x
      • 70e0744 Next development version (v3.3.10-SNAPSHOT)
      • 07d9db3 Merge pull request #44380 from nosan
      • 2295809 Register Log42J StatusListener
      • 575655c Upgrade Tomcat 11 smoke tests to Tomcat 11.0.4
      • c74397a Merge branch '3.3.x' into 3.4.x
      • c718461 Protect against NoSuchMethodException on setReadOnly
      • 7dc9bf2 Upgrade to Testcontainers Redis Module 2.2.4
      • 7d1fc06 Upgrade to Testcontainers 1.20.5
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot:spring-boot-starter-parent&package-manager=maven&previous-version=3.4.2&new-version=3.4.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 973af1454..2e0c4e072 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.2 + 3.4.3 From ec99546c7b4e64426aa855804dba84b6dc44f530 Mon Sep 17 00:00:00 2001 From: Brian Zier Date: Mon, 24 Feb 2025 01:53:38 -0800 Subject: [PATCH 537/980] Fix documentation typo (#1282) `PromethesuRegistry` -> `PrometheusRegistry` Signed-off-by: Brian Zier --- docs/content/migration/simpleclient.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md index 82937a64b..27606dbb6 100644 --- a/docs/content/migration/simpleclient.md +++ b/docs/content/migration/simpleclient.md @@ -13,7 +13,7 @@ Migration using the Simpleclient Bridge Good news: Users of version 0.16.0 and older do not need to refactor all their instrumentation code to get started with 1.0.0. -We provide a migration module for bridging the old simpleclient `CollectorRegistry` to the new `PromethesuRegistry`. +We provide a migration module for bridging the old simpleclient `CollectorRegistry` to the new `PrometheusRegistry`. To use the bridge, add the following dependency: From e29cfaa0e47ec7cf586ec1d3ad98f0cd0dc2bbfe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 09:09:16 -0500 Subject: [PATCH 538/980] Bump org.slf4j:slf4j-simple from 2.0.16 to 2.0.17 (#1288) Bumps org.slf4j:slf4j-simple from 2.0.16 to 2.0.17. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.slf4j:slf4j-simple&package-manager=maven&previous-version=2.0.16&new-version=2.0.17)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff5449582..30b886e39 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ org.slf4j slf4j-simple - 2.0.16 + 2.0.17 test From f343790303f78e7bb63bd6e4e3f3a6435332d89b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:24:44 +0100 Subject: [PATCH 539/980] Bump org.apache.maven.plugins:maven-project-info-reports-plugin from 3.8.0 to 3.9.0 (#1290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-project-info-reports-plugin](https://github.com/apache/maven-project-info-reports-plugin) from 3.8.0 to 3.9.0.
      Release notes

      Sourced from org.apache.maven.plugins:maven-project-info-reports-plugin's releases.

      3.9.0

      🚀 New features and improvements

      📦 Dependency updates

      👻 Maintenance

      Commits
      • f89321c [maven-release-plugin] prepare release maven-project-info-reports-plugin-3.9.0
      • 3f47dd0 Enable GitHub Issues
      • e51cef8 [MPIR-478] Allow to save avatars images for team report during project build
      • 3a991e2 Upgrade dependencies for ITs
      • df61a5a Add Release Drafter
      • d4ae6c6 Remove empty javadoc tags on private methods (#100)
      • cbe9f0c Add PR Automation and Stale actions
      • c80a10d [MNGSITE-529] Rename "Goals" to "Plugin Documentation"
      • b1b55bb [MPIR-476] Remove direct usage of localRepository as Mojo parameter
      • 03b9832 [MPIR-475] Drop usage of maven-artifact-transfer
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-project-info-reports-plugin&package-manager=maven&previous-version=3.8.0&new-version=3.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 30b886e39..7dfab2a27 100644 --- a/pom.xml +++ b/pom.xml @@ -394,7 +394,7 @@ maven-project-info-reports-plugin - 3.8.0 + 3.9.0 maven-javadoc-plugin From b6c263ff7e724a5f4de2628de6dde2ce682e6ea9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:24:53 +0100 Subject: [PATCH 540/980] Bump org.apache.maven.plugins:maven-deploy-plugin from 3.1.3 to 3.1.4 (#1291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-deploy-plugin](https://github.com/apache/maven-deploy-plugin) from 3.1.3 to 3.1.4.
      Release notes

      Sourced from org.apache.maven.plugins:maven-deploy-plugin's releases.

      3.1.4

      🚀 New features and improvements

      📦 Dependency updates

      👻 Maintenance

      Commits
      • 538c67c [maven-release-plugin] prepare release maven-deploy-plugin-3.1.4
      • 6dd30b3 Enable GitHub Issues
      • 39f204c Bump resolverVersion from 1.9.18 to 1.9.22
      • 65c05b7 PR Automation only on close event
      • 69b6824 [MNGSITE-529] Rename "Goals" to "Plugin Documentation"
      • 66b357b Bump mavenVersion from 3.9.6 to 3.9.9
      • 386fcf9 Release drafter configuration and PR Automation
      • 2173944 Fix IT deploy-bom for Maven rc-2
      • 424f215 [maven-release-plugin] prepare for next development iteration
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-deploy-plugin&package-manager=maven&previous-version=3.1.3&new-version=3.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7dfab2a27..4ade13fd5 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@
      maven-deploy-plugin - 3.1.3 + 3.1.4 maven-clean-plugin From d97056ac4b9fe100cbb86dbd18a922d5aa0b0769 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:25:02 +0100 Subject: [PATCH 541/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.13.1-alpha to 2.13.2-alpha (#1289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.13.1-alpha to 2.13.2-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.13.1

      This is a patch release on the previous 2.13.0 release, fixing the issue(s) below.

      🛠️ Bug fixes

      • Backport: Fix double instrumentation of Java runtime metrics (#13339)
      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Migration notes

      • The java.net.http.HttpClient instrumentation package io.opentelemetry.instrumentation.httpclient was deprecated in favor of the new package name io.opentelemetry.instrumentation.javahttpclient

      Version 2.13.2 (2025-02-27)

      🛠️ Bug fixes

      • Backport: Fix Spring boot starter dependency resolution failure with Gradle and Java 11 (#13402)

      Version 2.13.1 (2025-02-18)

      🛠️ Bug fixes

      • Backport: Fix double instrumentation of Java runtime metrics (#13339)

      Version 2.13.0 (2025-02-17)

      Migration notes

      • io.opentelemetry.instrumentation.api.incubator.semconv.util.SpanNames has been deprecated, replaced by the stable io.opentelemetry.instrumentation.api.semconv.util.SpanNames
      • In preparation for stabilizing HTTP library instrumentation, the classes and methods that were deprecated in the prior two releases have now been removed (#13135, #13150)
      • Deprecated Dubbo instrumentation method was removed (#13076)

      🌟 New javaagent instrumentation

      • jdk.httpserver instrumentation (#13243)

      🌟 New library instrumentation

      • jdk.httpserver instrumentation (#13243)

      📈 Enhancements

      • Add database client metrics to Lettuce instrumentation

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.13.1-alpha&new-version=2.13.2-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ade13fd5..bbed050ea 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ --module-name-need-to-be-overriden-- 33.4.0-jre 5.11.4 - 2.13.1-alpha + 2.13.2-alpha 8 0.70 false From 25fe4d7dc010aa9243a9878eced974a9ae8db783 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 09:54:43 +0000 Subject: [PATCH 542/980] Bump junit-jupiter.version from 5.11.4 to 5.12.0 (#1287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps `junit-jupiter.version` from 5.11.4 to 5.12.0. Updates `org.junit.jupiter:junit-jupiter-engine` from 5.11.4 to 5.12.0
      Release notes

      Sourced from org.junit.jupiter:junit-jupiter-engine's releases.

      JUnit 5.12.0 = Platform 1.12.0 + Jupiter 5.12.0 + Vintage 5.12.0

      See Release Notes.

      New Contributors

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0

      JUnit 5.12.0-RC2 = Platform 1.12.0-RC2 + Jupiter 5.12.0-RC2 + Vintage 5.12.0-RC2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0-RC1...r5.12.0-RC2

      JUnit 5.12.0-RC1 = Platform 1.12.0-RC1 + Jupiter 5.12.0-RC1 + Vintage 5.12.0-RC1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0-M1...r5.12.0-RC1

      JUnit 5.12.0-M1 = Platform 1.12.0-M1 + Jupiter 5.12.0-M1 + Vintage 5.12.0-M1

      See Release Notes.

      New Contributors

      ... (truncated)

      Commits
      • 2750b04 Release 5.12.0
      • 9615490 Update log suppressions for tests
      • 0a8d65b Remove duplicated reference to SimpleArgumentConverter
      • cafbcdb Update open-test-reporting to 0.2.0
      • ed1773c Fix version references to be 1.x in Platform and 5.x in Jupiter
      • 1d2f982 Update open-test-reporting to 0.2.0-M3
      • 2b6bab5 Fix indentation
      • d1929bb Merge 5.12.0 release notes
      • 9b7a3c4 Back to snapshots for further development
      • a410c92 Release 5.12.0-RC2
      • Additional commits viewable in compare view

      Updates `org.junit.jupiter:junit-jupiter-params` from 5.11.4 to 5.12.0
      Release notes

      Sourced from org.junit.jupiter:junit-jupiter-params's releases.

      JUnit 5.12.0 = Platform 1.12.0 + Jupiter 5.12.0 + Vintage 5.12.0

      See Release Notes.

      New Contributors

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.11.4...r5.12.0

      JUnit 5.12.0-RC2 = Platform 1.12.0-RC2 + Jupiter 5.12.0-RC2 + Vintage 5.12.0-RC2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0-RC1...r5.12.0-RC2

      JUnit 5.12.0-RC1 = Platform 1.12.0-RC1 + Jupiter 5.12.0-RC1 + Vintage 5.12.0-RC1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0-M1...r5.12.0-RC1

      JUnit 5.12.0-M1 = Platform 1.12.0-M1 + Jupiter 5.12.0-M1 + Vintage 5.12.0-M1

      See Release Notes.

      New Contributors

      ... (truncated)

      Commits
      • 2750b04 Release 5.12.0
      • 9615490 Update log suppressions for tests
      • 0a8d65b Remove duplicated reference to SimpleArgumentConverter
      • cafbcdb Update open-test-reporting to 0.2.0
      • ed1773c Fix version references to be 1.x in Platform and 5.x in Jupiter
      • 1d2f982 Update open-test-reporting to 0.2.0-M3
      • 2b6bab5 Fix indentation
      • d1929bb Merge 5.12.0 release notes
      • 9b7a3c4 Back to snapshots for further development
      • a410c92 Release 5.12.0-RC2
      • Additional commits viewable in compare view

      Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index bbed050ea..a3c97e2ed 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - pom 4.0.0 @@ -18,7 +19,7 @@ UTF-8 --module-name-need-to-be-overriden-- 33.4.0-jre - 5.11.4 + 5.12.0 2.13.2-alpha 8 0.70 @@ -94,7 +95,7 @@ org.junit.jupiter - junit-jupiter-engine + junit-jupiter ${junit-jupiter.version} test @@ -317,7 +318,8 @@ - org.springframework.boot:spring-boot-maven-plugin + + org.springframework.boot:spring-boot-maven-plugin @@ -428,6 +430,17 @@ benchmarks integration-tests + + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + javadoc From 66a91af37dbaf52f0e7cac03fdaab0c8e4bbfcd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:40:19 +0100 Subject: [PATCH 543/980] Bump org.apache.maven.plugins:maven-install-plugin from 3.1.3 to 3.1.4 (#1294) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-install-plugin](https://github.com/apache/maven-install-plugin) from 3.1.3 to 3.1.4.
      Release notes

      Sourced from org.apache.maven.plugins:maven-install-plugin's releases.

      3.1.4

      🚀 New features and improvements

      📦 Dependency updates

      👻 Maintenance

      Commits
      • 29b220d [maven-release-plugin] prepare release maven-install-plugin-3.1.4
      • 0df7304 Enable GitHub Issues
      • 2fda8ce Bump resolverVersion from 1.9.18 to 1.9.22
      • 57b57dd [MNGSITE-529] Rename "Goals" to "Plugin Documentation"
      • 6894c0d PR Automation only on close event
      • d97234c Bump org.mockito:mockito-core from 4.8.1 to 4.11.0
      • f8aa35e Bump mavenVersion from 3.9.6 to 3.9.9
      • e2c6c78 Add release-drafter, PR automation
      • ef37684 Remove unused method
      • dcf39a0 [maven-release-plugin] prepare for next development iteration
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-install-plugin&package-manager=maven&previous-version=3.1.3&new-version=3.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a3c97e2ed..90f4db6fb 100644 --- a/pom.xml +++ b/pom.xml @@ -144,7 +144,7 @@ maven-install-plugin - 3.1.3 + 3.1.4 maven-resources-plugin From c8ab7dd48132e0f09b8fd5ccafc8f536885a2669 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:06:15 +0100 Subject: [PATCH 544/980] Bump org.mockito:mockito-core from 5.15.2 to 5.16.0 (#1297) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.15.2 to 5.16.0.
      Release notes

      Sourced from org.mockito:mockito-core's releases.

      v5.16.0

      Changelog generated by Shipkit Changelog Gradle Plugin

      5.16.0

      Commits
      • c81be5d Add support for including module-info in Mockito. (#3597)
      • d01ac9d Issue #3584 Improve Gradle Kotlin documentation to add agent
      • 83ee69b Bump com.gradle.develocity from 3.19 to 3.19.1 (#3579)
      • 289e971 Bump org.assertj:assertj-core from 3.27.2 to 3.27.3 (#3577)
      • 1ab8483 Bump com.diffplug.spotless:spotless-plugin-gradle from 7.0.1 to 7.0.2 (#3574)
      • fdb5df1 Bump com.diffplug.spotless:spotless-plugin-gradle from 6.25.0 to 7.0.1 (#3571)
      • e280630 Bump org.assertj:assertj-core from 3.27.1 to 3.27.2 (#3569)
      • 96c2095 Tweak documentation on mockito agent config for maven (#3568)
      • 1c3800d Add --info to diagnose release issues (#3567)
      • e9a4c77 Refine reflection when calling management factory (#3566)
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.mockito:mockito-core&package-manager=maven&previous-version=5.15.2&new-version=5.16.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90f4db6fb..3a17c9096 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.mockito mockito-core - 5.15.2 + 5.16.0 test From a5c3e3f0cefc984682df512934e6746d70af9a28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:06:31 +0100 Subject: [PATCH 545/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.13.2-alpha to 2.13.3-alpha (#1296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.13.2-alpha to 2.13.3-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.13.2

      This is a patch release on the previous 2.13.1 release, fixing the issue(s) below.

      🛠️ Bug fixes

      • Backport: Fix Spring boot starter dependency resolution failure with Gradle and Java 11 (#13402)
      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Migration notes

      • The java.net.http.HttpClient instrumentation package io.opentelemetry.instrumentation.httpclient was deprecated in favor of the new package name io.opentelemetry.instrumentation.javahttpclient

      Version 2.13.3 (2025-02-28)

      🛠️ Bug fixes

      • Backport: Fix failure to start when AWS Resource Provider is enabled (#13420)

      Version 2.13.2 (2025-02-27)

      🛠️ Bug fixes

      • Backport: Fix Spring boot starter dependency resolution failure with Gradle and Java 11 (#13402)

      Version 2.13.1 (2025-02-18)

      🛠️ Bug fixes

      • Backport: Fix double instrumentation of Java runtime metrics (#13339)

      Version 2.13.0 (2025-02-17)

      Migration notes

      • io.opentelemetry.instrumentation.api.incubator.semconv.util.SpanNames has been deprecated, replaced by the stable io.opentelemetry.instrumentation.api.semconv.util.SpanNames
      • In preparation for stabilizing HTTP library instrumentation, the classes and methods that were deprecated in the prior two releases have now been removed (#13135, #13150)
      • Deprecated Dubbo instrumentation method was removed (#13076)

      🌟 New javaagent instrumentation

      • jdk.httpserver instrumentation (#13243)

      🌟 New library instrumentation

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.13.2-alpha&new-version=2.13.3-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3a17c9096..5f2029594 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ --module-name-need-to-be-overriden-- 33.4.0-jre 5.12.0 - 2.13.2-alpha + 2.13.3-alpha 8 0.70 false From 31bd1a5938af9cf6262b58e7358ad2808cc02199 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 09:24:28 +0100 Subject: [PATCH 546/980] Bump org.testcontainers:junit-jupiter from 1.20.5 to 1.20.6 (#1298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.20.5 to 1.20.6.
      Release notes

      Sourced from org.testcontainers:junit-jupiter's releases.

      1.20.6

      What's Changed

      • Bump confluentinc/cp-kcat from 7.4.1 to 7.9.0 (#10000) @​julianladisch
      • Set sourceCompatibility and targetCompatibility to 1.8 in spock module
      Commits
      • cc1c13a Replace release by sourceCompatibility and targetCompatibility in spock
      • 93a2eda Update ubuntu version to 22.04
      • 576e65a Fix spock module to compile using Java 8
      • 6e104da Bump confluentinc/cp-kcat from 7.4.1 to 7.9.0 (#10000)
      • 5af66d7 [create-pull-request] automated change (#9996)
      • 6ed4821 [create-pull-request] automated change (#9995)
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.testcontainers:junit-jupiter&package-manager=maven&previous-version=1.20.5&new-version=1.20.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ec3362cd8..20d0f1f38 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -56,7 +56,7 @@ org.testcontainers junit-jupiter - 1.20.5 + 1.20.6 test From 100dec15aceec99e21026c5355117dbe2b32dec3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 09:24:38 +0100 Subject: [PATCH 547/980] Bump org.wiremock:wiremock from 3.12.0 to 3.12.1 (#1295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.wiremock:wiremock](https://github.com/wiremock/wiremock) from 3.12.0 to 3.12.1.
      Release notes

      Sourced from org.wiremock:wiremock's releases.

      3.12.1

      🐞 Bug fixes

      📖 OpenAPI updates

      • Use camel-case format for the fileName property in the request-pattern schema (#2966) @​picimako

      👻 Maintenance

      📦 Dependency updates

      ✍ Other changes

      Commits
      • 8251033 Merge pull request #2982 from wiremock/bump-patch
      • f04e530 bump patch version to 3.12.1
      • e03e4d2 Merge pull request #2981 from wiremock/xml-perf-improvements
      • f76cb7f perf: Reinstate improvements on EqualToXmlPattern
      • ee67c13 refactor: Extract DelegateDocumentBuilderFactory & subtypes
      • 66c9b9e Merge pull request #2977 from wiremock/thread-local-xml
      • 08a1a75 Merge pull request #2979 from wiremock/update-actions-cache-version
      • 6052951 Update actions/cache@v1 to use v4
      • b45bf62 Merge pull request #2978 from wiremock/dependabot/gradle/com.fasterxml.jackso...
      • 063cdf4 Bump com.fasterxml.jackson:jackson-bom from 2.18.2 to 2.18.3
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.wiremock:wiremock&package-manager=maven&previous-version=3.12.0&new-version=3.12.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 237ef4a91..4bf7e4bf4 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -73,7 +73,7 @@ org.wiremock wiremock - 3.12.0 + 3.12.1 test From d3b533aa151a74495b5d240c5367bbc158e533a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 14:51:18 +0100 Subject: [PATCH 548/980] Bump com.google.protobuf:protobuf-java from 4.29.3 to 4.30.0 (#1299) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.29.3 to 4.30.0.
      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.protobuf:protobuf-java&package-manager=maven&previous-version=4.29.3&new-version=4.30.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .tool-versions | 2 +- .../client/it/common/ExporterTest.java | 2 +- .../metrics/it/exporter/test/ExporterIT.java | 2 +- .../it/springboot/ApplicationTest.java | 2 +- .../metrics/core/metrics/CounterTest.java | 2 +- .../metrics/core/metrics/HistogramTest.java | 2 +- .../metrics/core/metrics/InfoTest.java | 2 +- .../generate-protobuf.sh | 1 + prometheus-metrics-exposition-formats/pom.xml | 2 +- .../Metrics.java | 2036 ++++++++--------- .../PrometheusProtobufWriterImpl.java | 2 +- .../ProtobufExpositionFormatsTest.java | 2 +- 12 files changed, 1029 insertions(+), 1028 deletions(-) rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_29_3 => com_google_protobuf_4_30_0}/Metrics.java (87%) diff --git a/.tool-versions b/.tool-versions index 58b0b2027..6e9434844 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ java temurin-17.0.13+11 -protoc 29.3 +protoc 30.0 diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java index 93b5b088a..88453fa56 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 67a4eec16..d7645a575 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -5,7 +5,7 @@ import com.google.common.io.Resources; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import java.io.IOException; import java.net.URISyntaxException; import java.net.URLEncoder; diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java index eac8232d8..64c843edb 100644 --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import java.io.IOException; import java.net.URL; import java.util.List; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index d05311307..c04055fc4 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.CounterSnapshot; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 514fd5b34..47b059588 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -8,7 +8,7 @@ import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index f78372545..275041724 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.Labels; diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index db27d9457..30e83cfa3 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -38,6 +38,7 @@ if [[ $GENERATED_WITH != "$PROTOBUF_VERSION" ]]; then echo "Generated protobuf sources version $GENERATED_WITH does not match provided version $PROTOBUF_VERSION" echo "Please update the protoc version .tool-versions to the latest version of https://github.com/protocolbuffers/protobuf/releases" echo "Please use https://github.com/asdf-vm/asdf - this will use the version specified in .tool-versions" + echo "Generated protobuf sources are not up-to-date. Please run 'PROTO_GENERATION=true mvn clean install' and commit the changes." exit 1 fi diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 9643998b2..56b7c6c4d 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -20,7 +20,7 @@ io.prometheus.metrics.expositionformats - 4.29.3 + 4.30.0 diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java similarity index 87% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java index c20c4a4ed..523e8fa3a 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_29_3/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java @@ -2,9 +2,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto -// Protobuf Java Version: 4.29.3 +// Protobuf Java Version: 4.30.0 -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3; +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0; public final class Metrics { private Metrics() {} @@ -12,8 +12,8 @@ private Metrics() {} com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Metrics.class.getName()); } @@ -85,8 +85,8 @@ public enum MetricType com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", MetricType.class.getName()); } @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.getDescriptor().getEnumTypes().get(0); + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.getDescriptor().getEnumTypes().get(0); } private static final MetricType[] VALUES = values(); @@ -265,8 +265,8 @@ public static final class LabelPair extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", LabelPair.class.getName()); } @@ -281,15 +281,15 @@ private LabelPair() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder.class); } private int bitField0_; @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair) obj; if (hasName() != other.hasName()) return false; if (hasName()) { @@ -475,44 +475,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -573,21 +573,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.newBuilder() private Builder() { } @@ -609,17 +609,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance()) return this; if (other.hasName()) { name_ = other.name_; bitField0_ |= 0x00000001; @@ -887,12 +887,12 @@ public Builder setValueBytes( } // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -961,8 +961,8 @@ public static final class Gauge extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Gauge.class.getName()); } @@ -975,15 +975,15 @@ private Gauge() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder.class); } private int bitField0_; @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1078,44 +1078,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.newBuilder() private Builder() { } @@ -1211,17 +1211,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1353,12 +1353,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar(); /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); /** * optional .google.protobuf.Timestamp created_timestamp = 3; @@ -1457,8 +1457,8 @@ public static final class Counter extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Counter.class.getName()); } @@ -1471,15 +1471,15 @@ private Counter() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder.class); } private int bitField0_; @@ -1503,7 +1503,7 @@ public double getValue() { } public static final int EXEMPLAR_FIELD_NUMBER = 2; - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1517,15 +1517,15 @@ public boolean hasExemplar() { * @return The exemplar. */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; } public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3; @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1658,44 +1658,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1783,8 +1783,8 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessage .alwaysUseFieldBuilders) { - getExemplarFieldBuilder(); - getCreatedTimestampFieldBuilder(); + internalGetExemplarFieldBuilder(); + internalGetCreatedTimestampFieldBuilder(); } } @java.lang.Override @@ -1808,17 +1808,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1909,14 +1909,14 @@ public Builder mergeFrom( } // case 9 case 18: { input.readMessage( - getExemplarFieldBuilder().getBuilder(), + internalGetExemplarFieldBuilder().getBuilder(), extensionRegistry); bitField0_ |= 0x00000002; break; } // case 18 case 26: { input.readMessage( - getCreatedTimestampFieldBuilder().getBuilder(), + internalGetCreatedTimestampFieldBuilder().getBuilder(), extensionRegistry); bitField0_ |= 0x00000004; break; @@ -1978,9 +1978,9 @@ public Builder clearValue() { return this; } - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_; private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarBuilder_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1992,9 +1992,9 @@ public boolean hasExemplar() { * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() { if (exemplarBuilder_ == null) { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; } else { return exemplarBuilder_.getMessage(); } @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) { + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com * optional .io.prometheus.client.Exemplar exemplar = 2; */ public Builder setExemplar( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) { if (exemplarBuilder_ == null) { exemplar_ = builderForValue.build(); } else { @@ -2032,11 +2032,11 @@ public Builder setExemplar( /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) { + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && exemplar_ != null && - exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) { + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) { getExemplarBuilder().mergeFrom(value); } else { exemplar_ = value; @@ -2066,31 +2066,31 @@ public Builder clearExemplar() { /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarBuilder() { bitField0_ |= 0x00000002; onChanged(); - return getExemplarFieldBuilder().getBuilder(); + return internalGetExemplarFieldBuilder().getBuilder(); } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { if (exemplarBuilder_ != null) { return exemplarBuilder_.getMessageOrBuilder(); } else { return exemplar_ == null ? - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; } } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> - getExemplarFieldBuilder() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> + internalGetExemplarFieldBuilder() { if (exemplarBuilder_ == null) { exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>( getExemplar(), getParentForChildren(), isClean()); @@ -2190,7 +2190,7 @@ public Builder clearCreatedTimestamp() { public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() { bitField0_ |= 0x00000004; onChanged(); - return getCreatedTimestampFieldBuilder().getBuilder(); + return internalGetCreatedTimestampFieldBuilder().getBuilder(); } /** * optional .google.protobuf.Timestamp created_timestamp = 3; @@ -2208,7 +2208,7 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { */ private com.google.protobuf.SingleFieldBuilder< com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> - getCreatedTimestampFieldBuilder() { + internalGetCreatedTimestampFieldBuilder() { if (createdTimestampBuilder_ == null) { createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder< com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>( @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2309,8 +2309,8 @@ public static final class Quantile extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Quantile.class.getName()); } @@ -2323,15 +2323,15 @@ private Quantile() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder.class); } private int bitField0_; @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile) obj; if (hasQuantile() != other.hasQuantile()) return false; if (hasQuantile()) { @@ -2463,44 +2463,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.newBuilder() private Builder() { } @@ -2597,17 +2597,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()) return this; if (other.hasQuantile()) { setQuantile(other.getQuantile()); } @@ -2791,12 +2791,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileOrBuilderList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index); /** @@ -2915,8 +2915,8 @@ public static final class Summary extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Summary.class.getName()); } @@ -2930,15 +2930,15 @@ private Summary() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder.class); } private int bitField0_; @@ -2982,19 +2982,19 @@ public double getSampleSum() { public static final int QUANTILE_FIELD_NUMBER = 3; @SuppressWarnings("serial") - private java.util.List quantile_; + private java.util.List quantile_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { return quantile_; } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List + public java.util.List getQuantileOrBuilderList() { return quantile_; } @@ -3009,14 +3009,14 @@ public int getQuantileCount() { * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index) { return quantile_.get(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { return quantile_.get(index); } @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary) obj; if (hasSampleCount() != other.hasSampleCount()) return false; if (hasSampleCount()) { @@ -3165,44 +3165,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3290,8 +3290,8 @@ private Builder( private void maybeForceBuilderInitialization() { if (com.google.protobuf.GeneratedMessage .alwaysUseFieldBuilders) { - getQuantileFieldBuilder(); - getCreatedTimestampFieldBuilder(); + internalGetQuantileFieldBuilder(); + internalGetCreatedTimestampFieldBuilder(); } } @java.lang.Override @@ -3318,17 +3318,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary(this); buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result) { + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result) { if (quantileBuilder_ == null) { if (((bitField0_ & 0x00000004) != 0)) { quantile_ = java.util.Collections.unmodifiableList(quantile_); @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance()) return this; if (other.hasSampleCount()) { setSampleCount(other.getSampleCount()); } @@ -3414,7 +3414,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g bitField0_ = (bitField0_ & ~0x00000004); quantileBuilder_ = com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? - getQuantileFieldBuilder() : null; + internalGetQuantileFieldBuilder() : null; } else { quantileBuilder_.addAllMessages(other.quantile_); } @@ -3460,9 +3460,9 @@ public Builder mergeFrom( break; } // case 17 case 26: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.parser(), + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.parser(), extensionRegistry); if (quantileBuilder_ == null) { ensureQuantileIsMutable(); @@ -3474,7 +3474,7 @@ public Builder mergeFrom( } // case 26 case 34: { input.readMessage( - getCreatedTimestampFieldBuilder().getBuilder(), + internalGetCreatedTimestampFieldBuilder().getBuilder(), extensionRegistry); bitField0_ |= 0x00000008; break; @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() { return this; } - private java.util.List quantile_ = + private java.util.List quantile_ = java.util.Collections.emptyList(); private void ensureQuantileIsMutable() { if (!((bitField0_ & 0x00000004) != 0)) { - quantile_ = new java.util.ArrayList(quantile_); + quantile_ = new java.util.ArrayList(quantile_); bitField0_ |= 0x00000004; } } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder> quantileBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder> quantileBuilder_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { if (quantileBuilder_ == null) { return java.util.Collections.unmodifiableList(quantile_); } else { @@ -3611,7 +3611,7 @@ public int getQuantileCount() { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3639,7 +3639,7 @@ public Builder setQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.set(index, builderForValue.build()); @@ -3652,7 +3652,7 @@ public Builder setQuantile( /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) { + public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3686,7 +3686,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(builderForValue.build()); @@ -3700,7 +3700,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(index, builderForValue.build()); @@ -3714,7 +3714,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addAllQuantile( - java.lang.Iterable values) { + java.lang.Iterable values) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder getQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder getQuantileBuilder( int index) { - return getQuantileFieldBuilder().getBuilder(index); + return internalGetQuantileFieldBuilder().getBuilder(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileOrBuilderList() { if (quantileBuilder_ != null) { return quantileBuilder_.getMessageOrBuilderList(); @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder addQuantileBuilder() { - return getQuantileFieldBuilder().addBuilder( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance()); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder addQuantileBuilder() { + return internalGetQuantileFieldBuilder().addBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder addQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder addQuantileBuilder( int index) { - return getQuantileFieldBuilder().addBuilder( - index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.getDefaultInstance()); + return internalGetQuantileFieldBuilder().addBuilder( + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileBuilderList() { - return getQuantileFieldBuilder().getBuilderList(); + return internalGetQuantileFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder> - getQuantileFieldBuilder() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder> + internalGetQuantileFieldBuilder() { if (quantileBuilder_ == null) { quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.QuantileOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder>( quantile_, ((bitField0_ & 0x00000004) != 0), getParentForChildren(), @@ -3907,7 +3907,7 @@ public Builder clearCreatedTimestamp() { public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() { bitField0_ |= 0x00000008; onChanged(); - return getCreatedTimestampFieldBuilder().getBuilder(); + return internalGetCreatedTimestampFieldBuilder().getBuilder(); } /** * optional .google.protobuf.Timestamp created_timestamp = 4; @@ -3925,7 +3925,7 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { */ private com.google.protobuf.SingleFieldBuilder< com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> - getCreatedTimestampFieldBuilder() { + internalGetCreatedTimestampFieldBuilder() { if (createdTimestampBuilder_ == null) { createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder< com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>( @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4015,8 +4015,8 @@ public static final class Untyped extends com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, - /* minor= */ 29, - /* patch= */ 3, + /* minor= */ 30, + /* patch= */ 0, /* suffix= */ "", Untyped.class.getName()); } @@ -4029,15 +4029,15 @@ private Untyped() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder.class); } private int bitField0_; @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -4132,44 +4132,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.newBuilder() private Builder() { } @@ -4265,17 +4265,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -4407,12 +4407,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends * * repeated .io.prometheus.client.Bucket bucket = 3; */ - java.util.List + java.util.List getBucketList(); /** *
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4929,8 +4929,8 @@ public static final class Histogram extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6040,11 +6040,11 @@ private Builder(
             private void maybeForceBuilderInitialization() {
               if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
      -          getBucketFieldBuilder();
      -          getCreatedTimestampFieldBuilder();
      -          getNegativeSpanFieldBuilder();
      -          getPositiveSpanFieldBuilder();
      -          getExemplarsFieldBuilder();
      +          internalGetBucketFieldBuilder();
      +          internalGetCreatedTimestampFieldBuilder();
      +          internalGetNegativeSpanFieldBuilder();
      +          internalGetPositiveSpanFieldBuilder();
      +          internalGetExemplarsFieldBuilder();
               }
             }
             @java.lang.Override
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6263,7 +6263,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00000008);
                     bucketBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getBucketFieldBuilder() : null;
      +                   internalGetBucketFieldBuilder() : null;
                   } else {
                     bucketBuilder_.addAllMessages(other.bucket_);
                   }
      @@ -6304,7 +6304,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00000200);
                     negativeSpanBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getNegativeSpanFieldBuilder() : null;
      +                   internalGetNegativeSpanFieldBuilder() : null;
                   } else {
                     negativeSpanBuilder_.addAllMessages(other.negativeSpan_);
                   }
      @@ -6352,7 +6352,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00001000);
                     positiveSpanBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getPositiveSpanFieldBuilder() : null;
      +                   internalGetPositiveSpanFieldBuilder() : null;
                   } else {
                     positiveSpanBuilder_.addAllMessages(other.positiveSpan_);
                   }
      @@ -6400,7 +6400,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00008000);
                     exemplarsBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getExemplarsFieldBuilder() : null;
      +                   internalGetExemplarsFieldBuilder() : null;
                   } else {
                     exemplarsBuilder_.addAllMessages(other.exemplars_);
                   }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6574,15 +6574,15 @@ public Builder mergeFrom(
                     } // case 114
                     case 122: {
                       input.readMessage(
      -                    getCreatedTimestampFieldBuilder().getBuilder(),
      +                    internalGetCreatedTimestampFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000010;
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,9 +6975,9 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
      -        return getBucketFieldBuilder().getBuilder(index);
      +        return internalGetBucketFieldBuilder().getBuilder(index);
             }
             /**
              * 
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder addBucketBuilder() {
      -        return getBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder addBucketBuilder() {
      +        return internalGetBucketFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
      -        return getBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance());
      +        return internalGetBucketFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
      -        return getBucketFieldBuilder().getBuilderList();
      +        return internalGetBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder> 
      -          getBucketFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder> 
      +          internalGetBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7148,7 +7148,7 @@ public Builder clearCreatedTimestamp() {
             public com.google.protobuf.Timestamp.Builder getCreatedTimestampBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
      -        return getCreatedTimestampFieldBuilder().getBuilder();
      +        return internalGetCreatedTimestampFieldBuilder().getBuilder();
             }
             /**
              * optional .google.protobuf.Timestamp created_timestamp = 15;
      @@ -7166,7 +7166,7 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() {
              */
             private com.google.protobuf.SingleFieldBuilder<
                 com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
      -          getCreatedTimestampFieldBuilder() {
      +          internalGetCreatedTimestampFieldBuilder() {
               if (createdTimestampBuilder_ == null) {
                 createdTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
                     com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,9 +7648,9 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
      -        return getNegativeSpanFieldBuilder().getBuilder(index);
      +        return internalGetNegativeSpanFieldBuilder().getBuilder(index);
             }
             /**
              * 
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      -        return getNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +        return internalGetNegativeSpanFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
      -        return getNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
      +        return internalGetNegativeSpanFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
      -        return getNegativeSpanFieldBuilder().getBuilderList();
      +        return internalGetNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> 
      -          getNegativeSpanFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> 
      +          internalGetNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,9 +8243,9 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
      -        return getPositiveSpanFieldBuilder().getBuilder(index);
      +        return internalGetPositiveSpanFieldBuilder().getBuilder(index);
             }
             /**
              * 
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      -        return getPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +        return internalGetPositiveSpanFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
      -        return getPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance());
      +        return internalGetPositiveSpanFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
      -        return getPositiveSpanFieldBuilder().getBuilderList();
      +        return internalGetPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder> 
      -          getPositiveSpanFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> 
      +          internalGetPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,9 +8814,9 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
      -        return getExemplarsFieldBuilder().getBuilder(index);
      +        return internalGetExemplarsFieldBuilder().getBuilder(index);
             }
             /**
              * 
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder addExemplarsBuilder() {
      -        return getExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +        return internalGetExemplarsFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
      -        return getExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance());
      +        return internalGetExemplarsFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
      -        return getExemplarsFieldBuilder().getBuilderList();
      +        return internalGetExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> 
      -          getExemplarsFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> 
      +          internalGetExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9040,8 +9040,8 @@ public static final class Bucket extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9426,7 +9426,7 @@ private Builder(
             private void maybeForceBuilderInitialization() {
               if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
      -          getExemplarFieldBuilder();
      +          internalGetExemplarFieldBuilder();
               }
             }
             @java.lang.Override
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9558,7 +9558,7 @@ public Builder mergeFrom(
                     } // case 17
                     case 26: {
                       input.readMessage(
      -                    getExemplarFieldBuilder().getBuilder(),
      +                    internalGetExemplarFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000008;
                       break;
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,31 +9841,31 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
      -        return getExemplarFieldBuilder().getBuilder();
      +        return internalGetExemplarFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder> 
      -          getExemplarFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> 
      +          internalGetExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9988,8 +9988,8 @@ public static final class BucketSpan extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10648,8 +10648,8 @@ public static final class Exemplar extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -10999,8 +10999,8 @@ private Builder(
             private void maybeForceBuilderInitialization() {
               if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
      -          getLabelFieldBuilder();
      -          getTimestampFieldBuilder();
      +          internalGetLabelFieldBuilder();
      +          internalGetTimestampFieldBuilder();
               }
             }
             @java.lang.Override
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11112,7 +11112,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getLabelFieldBuilder() : null;
      +                   internalGetLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
                   }
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11170,7 +11170,7 @@ public Builder mergeFrom(
                     } // case 17
                     case 26: {
                       input.readMessage(
      -                    getTimestampFieldBuilder().getBuilder(),
      +                    internalGetTimestampFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000004;
                       break;
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
      -        return getLabelFieldBuilder().getBuilder(index);
      +        return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder() {
      -        return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder() {
      +        return internalGetLabelFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
      -        return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
      +        return internalGetLabelFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
      -        return getLabelFieldBuilder().getBuilderList();
      +        return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> 
      -          getLabelFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> 
      +          internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11591,7 +11591,7 @@ public Builder clearTimestamp() {
             public com.google.protobuf.Timestamp.Builder getTimestampBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
      -        return getTimestampFieldBuilder().getBuilder();
      +        return internalGetTimestampFieldBuilder().getBuilder();
             }
             /**
              * 
      @@ -11617,7 +11617,7 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
              */
             private com.google.protobuf.SingleFieldBuilder<
                 com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
      -          getTimestampFieldBuilder() {
      +          internalGetTimestampFieldBuilder() {
               if (timestampBuilder_ == null) {
                 timestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<
                     com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11806,8 +11806,8 @@ public static final class Metric extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12312,12 +12312,12 @@ private Builder(
             private void maybeForceBuilderInitialization() {
               if (com.google.protobuf.GeneratedMessage
                       .alwaysUseFieldBuilders) {
      -          getLabelFieldBuilder();
      -          getGaugeFieldBuilder();
      -          getCounterFieldBuilder();
      -          getSummaryFieldBuilder();
      -          getUntypedFieldBuilder();
      -          getHistogramFieldBuilder();
      +          internalGetLabelFieldBuilder();
      +          internalGetGaugeFieldBuilder();
      +          internalGetCounterFieldBuilder();
      +          internalGetSummaryFieldBuilder();
      +          internalGetUntypedFieldBuilder();
      +          internalGetHistogramFieldBuilder();
               }
             }
             @java.lang.Override
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12473,7 +12473,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00000001);
                     labelBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getLabelFieldBuilder() : null;
      +                   internalGetLabelFieldBuilder() : null;
                   } else {
                     labelBuilder_.addAllMessages(other.label_);
                   }
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12538,28 +12538,28 @@ public Builder mergeFrom(
                     } // case 10
                     case 18: {
                       input.readMessage(
      -                    getGaugeFieldBuilder().getBuilder(),
      +                    internalGetGaugeFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000002;
                       break;
                     } // case 18
                     case 26: {
                       input.readMessage(
      -                    getCounterFieldBuilder().getBuilder(),
      +                    internalGetCounterFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000004;
                       break;
                     } // case 26
                     case 34: {
                       input.readMessage(
      -                    getSummaryFieldBuilder().getBuilder(),
      +                    internalGetSummaryFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000008;
                       break;
                     } // case 34
                     case 42: {
                       input.readMessage(
      -                    getUntypedFieldBuilder().getBuilder(),
      +                    internalGetUntypedFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000010;
                       break;
      @@ -12571,7 +12571,7 @@ public Builder mergeFrom(
                     } // case 48
                     case 58: {
                       input.readMessage(
      -                    getHistogramFieldBuilder().getBuilder(),
      +                    internalGetHistogramFieldBuilder().getBuilder(),
                           extensionRegistry);
                       bitField0_ |= 0x00000020;
                       break;
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
      -        return getLabelFieldBuilder().getBuilder(index);
      +        return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder() {
      -        return getLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder() {
      +        return internalGetLabelFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
      -        return getLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.getDefaultInstance());
      +        return internalGetLabelFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
      -        return getLabelFieldBuilder().getBuilderList();
      +        return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder> 
      -          getLabelFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> 
      +          internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,31 +12921,31 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
      -        return getGaugeFieldBuilder().getBuilder();
      +        return internalGetGaugeFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder> 
      -          getGaugeFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder> 
      +          internalGetGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,31 +13042,31 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
      -        return getCounterFieldBuilder().getBuilder();
      +        return internalGetCounterFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder> 
      -          getCounterFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder> 
      +          internalGetCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,31 +13163,31 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
      -        return getSummaryFieldBuilder().getBuilder();
      +        return internalGetSummaryFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder> 
      -          getSummaryFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder> 
      +          internalGetSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,31 +13284,31 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
      -        return getUntypedFieldBuilder().getBuilder();
      +        return internalGetUntypedFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder> 
      -          getUntypedFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder> 
      +          internalGetUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,31 +13405,31 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
      -        return getHistogramFieldBuilder().getBuilder();
      +        return internalGetHistogramFieldBuilder().getBuilder();
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder> 
      -          getHistogramFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder> 
      +          internalGetHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13631,8 +13631,8 @@ public static final class MetricFamily extends
             com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
      -        /* minor= */ 29,
      -        /* patch= */ 3,
      +        /* minor= */ 30,
      +        /* patch= */ 0,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14243,7 +14243,7 @@ public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_g
                     bitField0_ = (bitField0_ & ~0x00000008);
                     metricBuilder_ = 
                       com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
      -                   getMetricFieldBuilder() : null;
      +                   internalGetMetricFieldBuilder() : null;
                   } else {
                     metricBuilder_.addAllMessages(other.metric_);
                   }
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
      -        return getMetricFieldBuilder().getBuilder(index);
      +        return internalGetMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder addMetricBuilder() {
      -        return getMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance());
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder addMetricBuilder() {
      +        return internalGetMetricFieldBuilder().addBuilder(
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
      -        return getMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.getDefaultInstance());
      +        return internalGetMetricFieldBuilder().addBuilder(
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
      -        return getMetricFieldBuilder().getBuilderList();
      +        return internalGetMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder> 
      -          getMetricFieldBuilder() {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder> 
      +          internalGetMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_2
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_29_3Z:github.com/prometheus/clien" +
      +      "obuf_4_30_0Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index 608a13caa..9902dc9f1 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      index edb28ab67..4dc9b5d83 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_29_3.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.MetricSnapshot;
      
      From 929e1e63016d3f4066f5a9f1c08ee26aee4159bf Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Thu, 6 Mar 2025 16:38:15 +0100
      Subject: [PATCH 549/980] Bump jetty-server.version from 12.0.16 to 12.0.17
       (#1300)
      
      Bumps `jetty-server.version` from 12.0.16 to 12.0.17.
      Updates `org.eclipse.jetty:jetty-server` from 12.0.16 to 12.0.17
      
      Updates `org.eclipse.jetty.ee10:jetty-ee10-servlet` from 12.0.16 to
      12.0.17
      
      
      Dependabot will resolve any conflicts with this PR as long as you don't
      alter it yourself. You can also trigger a rebase manually by commenting
      `@dependabot rebase`.
      
      [//]: # (dependabot-automerge-start)
      [//]: # (dependabot-automerge-end)
      
      ---
      
      
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index fed800096..b16daa73d 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -15,7 +15,7 @@ Jetty Sample for the Exporter Integration Test - 12.0.16 + 12.0.17 17 From ef4b5bf826c6f2839813cde88edcda002931e03b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 16:38:24 +0100 Subject: [PATCH 550/980] Bump org.apache.tomcat.embed:tomcat-embed-core from 11.0.4 to 11.0.5 (#1301) Bumps org.apache.tomcat.embed:tomcat-embed-core from 11.0.4 to 11.0.5. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.tomcat.embed:tomcat-embed-core&package-manager=maven&previous-version=11.0.4&new-version=11.0.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 2530297a8..88f2c56b2 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.4 + 11.0.5 diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 7d0f49aff..98acbe4e8 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.4 + 11.0.5 diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 3632748fb..b30d8c5f8 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.4 + 11.0.5 diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index f320764a1..0930052c9 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -33,7 +33,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.4 + 11.0.5 From a4ef5f1b388762548d63816a04e26f5f3b5c754c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 10 Mar 2025 22:33:54 +1100 Subject: [PATCH 551/980] fix method name in two Histogram builder method javadocs (#1302) Signed-off-by: Benjamin Peterson --- .../java/io/prometheus/metrics/core/metrics/Histogram.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java index 8f76819f1..327867fd0 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/Histogram.java @@ -765,7 +765,7 @@ public Builder classicUpperBounds(double... upperBounds) { /** * Create classic histogram buckets with linear bucket boundaries. * - *

      Example: {@code withClassicLinearBuckets(1.0, 0.5, 10)} creates bucket boundaries {@code + *

      Example: {@code classicLinearUpperBounds(1.0, 0.5, 10)} creates bucket boundaries {@code * [[1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5]}. * * @param start is the first bucket boundary @@ -786,7 +786,7 @@ public Builder classicLinearUpperBounds(double start, double width, int count) { /** * Create classic histogram buckets with exponential boundaries. * - *

      Example: {@code withClassicExponentialBuckets(1.0, 2.0, 10)} creates bucket boundaries + *

      Example: {@code classicExponentialUpperBounds(1.0, 2.0, 10)} creates bucket boundaries * {@code [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0]} * * @param start is the first bucket boundary From 2d16e8ae4809eef5e116778ebb147ccd9bd8e669 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:44:10 +0100 Subject: [PATCH 552/980] Bump junit-jupiter.version from 5.12.0 to 5.12.1 (#1304) Bumps `junit-jupiter.version` from 5.12.0 to 5.12.1. Updates `org.junit.jupiter:junit-jupiter` from 5.12.0 to 5.12.1

      Release notes

      Sourced from org.junit.jupiter:junit-jupiter's releases.

      JUnit 5.12.1 = Platform 1.12.1 + Jupiter 5.12.1 + Vintage 5.12.1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1

      Commits
      • ba9c9ae Release 5.12.1
      • e28ad4a Finalize 5.12.1 release notes
      • 1044e2c Move entry to 5.12.1 release notes
      • bea821d Fix Javadoc formatting
      • 1a1a67d Set stable module name for the standalone JAR file
      • 062d3fa Remove internal packages from API reports
      • 74521ab Introduce ExtensionContext.getEnclosingTestClasses()
      • 1e135b9 Create initial 5.12.1 release notes from template
      • d540e4f Link to correct method
      • 31d60b7 Split API reports by module and package
      • Additional commits viewable in compare view

      Updates `org.junit.jupiter:junit-jupiter-params` from 5.12.0 to 5.12.1
      Release notes

      Sourced from org.junit.jupiter:junit-jupiter-params's releases.

      JUnit 5.12.1 = Platform 1.12.1 + Jupiter 5.12.1 + Vintage 5.12.1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1

      Commits
      • ba9c9ae Release 5.12.1
      • e28ad4a Finalize 5.12.1 release notes
      • 1044e2c Move entry to 5.12.1 release notes
      • bea821d Fix Javadoc formatting
      • 1a1a67d Set stable module name for the standalone JAR file
      • 062d3fa Remove internal packages from API reports
      • 74521ab Introduce ExtensionContext.getEnclosingTestClasses()
      • 1e135b9 Create initial 5.12.1 release notes from template
      • d540e4f Link to correct method
      • 31d60b7 Split API reports by module and package
      • Additional commits viewable in compare view

      Updates `org.junit:junit-bom` from 5.12.0 to 5.12.1
      Release notes

      Sourced from org.junit:junit-bom's releases.

      JUnit 5.12.1 = Platform 1.12.1 + Jupiter 5.12.1 + Vintage 5.12.1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1

      Commits
      • ba9c9ae Release 5.12.1
      • e28ad4a Finalize 5.12.1 release notes
      • 1044e2c Move entry to 5.12.1 release notes
      • bea821d Fix Javadoc formatting
      • 1a1a67d Set stable module name for the standalone JAR file
      • 062d3fa Remove internal packages from API reports
      • 74521ab Introduce ExtensionContext.getEnclosingTestClasses()
      • 1e135b9 Create initial 5.12.1 release notes from template
      • d540e4f Link to correct method
      • 31d60b7 Split API reports by module and package
      • Additional commits viewable in compare view

      Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5f2029594..edd9c7014 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ UTF-8 --module-name-need-to-be-overriden-- 33.4.0-jre - 5.12.0 + 5.12.1 2.13.3-alpha 8 0.70 From 7572b1faf599e13605a270152983bebd28adb516 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 11:59:07 +0100 Subject: [PATCH 553/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.13.3-alpha to 2.14.0-alpha (#1306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.13.3-alpha to 2.14.0-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.13.3

      This is a patch release on the previous 2.13.2 release, fixing the issue(s) below.

      🛠️ Bug fixes

      • Backport: Fix failure to start when AWS Resource Provider is enabled (#13420)
      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Version 2.14.0 (2025-03-13)

      Migration notes

      • The java.net.http.HttpClient instrumentation package io.opentelemetry.instrumentation.httpclient was deprecated in favor of the new package name io.opentelemetry.instrumentation.javahttpclient
      • The experimental opt-in jvm.buffer.memory.usage metric was renamed to jvm.buffer.memory.used in order to follow general semantic convention naming
      • The Http *TelemetryBuilder generic signatures were simplified (#12858)

      🌟 New javaagent instrumentation

      🌟 New library instrumentation

      📈 Enhancements

      • Support virtual threads in Spring Scheduling instrumentation (#13370)
      • Redact query string values for http client spans (#13114)
      • Support attribute lowercase modifier in JMX metrics yaml definitions (#13385)
      • Add tapir path matching within pekko instrumentation (#13386)
      • Support latest Axis2 version (#13490)

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.13.3-alpha&new-version=2.14.0-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index edd9c7014..5e6eb6987 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ --module-name-need-to-be-overriden-- 33.4.0-jre 5.12.1 - 2.13.3-alpha + 2.14.0-alpha 8 0.70 false From 3180503934e49e32a05d06f7d8e0e2caa8630e29 Mon Sep 17 00:00:00 2001 From: Edoardo Comar Date: Mon, 17 Mar 2025 13:04:44 +0000 Subject: [PATCH 554/980] Set a name to threads created by Scheduler Threadfactory (#1307) Use prefix "prometheus-metrics-scheduler-" plus counter. Used in conjunction with https://issues.apache.org/jira/browse/KAFKA-18982 --------- Signed-off-by: Edoardo Comar --- .../java/io/prometheus/metrics/core/util/Scheduler.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java index 96e0643c5..9dc6b79fe 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/util/Scheduler.java @@ -14,9 +14,15 @@ public class Scheduler { private static class DaemonThreadFactory implements ThreadFactory { + private static int threadNum; + + private static synchronized int nextThreadNum() { + return threadNum++; + } + @Override public Thread newThread(Runnable runnable) { - Thread thread = new Thread(runnable); + Thread thread = new Thread(runnable, "prometheus-metrics-scheduler-" + nextThreadNum()); thread.setDaemon(true); return thread; } From 294c8b6775b80186a0bf3e432c5a2a7f50c92d85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:05:53 +0100 Subject: [PATCH 555/980] Bump com.google.protobuf:protobuf-java from 4.30.0 to 4.30.1 (#1305) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.30.0 to 4.30.1.
      Commits
      • 0d815c5 Updating version.json and repo version numbers to: 30.1
      • ebb5224 Re-add system_python repo alias to MODULE.bazel (#20662)
      • 4747628 Remove Java runtime classes from kotlin release. (#20607)
      • 250c550 Fix python codegen crash when C++ features are used. (#20577)
      • 3576a1f Loosen py_proto_library check to be on the import path instead of full direct...
      • efa65c5 Merge pull request #20562 from protocolbuffers/30.x-202503042254
      • 63fc9d6 Updating version.json and repo version numbers to: 30.1-dev
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.protobuf:protobuf-java&package-manager=maven&previous-version=4.30.0&new-version=4.30.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/build.yml | 9 +- .tool-versions | 2 - CONTRIBUTING.md | 2 + .../client/it/common/ExporterTest.java | 2 +- .../metrics/it/exporter/test/ExporterIT.java | 2 +- .../it/springboot/ApplicationTest.java | 2 +- mise.toml | 15 + .../metrics/core/metrics/CounterTest.java | 2 +- .../metrics/core/metrics/HistogramTest.java | 2 +- .../metrics/core/metrics/InfoTest.java | 2 +- .../generate-protobuf.sh | 8 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- .../Metrics.java | 1810 ++++++++--------- .../PrometheusProtobufWriterImpl.java | 2 +- .../ProtobufExpositionFormatsTest.java | 2 +- 15 files changed, 938 insertions(+), 926 deletions(-) delete mode 100644 .tool-versions create mode 100644 mise.toml rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_30_0 => com_google_protobuf_4_30_1}/Metrics.java (89%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd607b3eb..63901f9f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,8 +11,7 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - name: Setup ASDF - uses: equisoft-actions/with-asdf-vm@v2 + - uses: jdx/mise-action@v2 - name: Cache local Maven repository uses: actions/cache@v4 with: @@ -24,7 +23,5 @@ jobs: env: PROTO_GENERATION: true REQUIRE_PROTO_UP_TO_DATE: true - run: | - mvn -v - ./mvnw clean install - ./mvnw javadoc:javadoc -P javadoc # just to check if javadoc is generated + run: mise run ci + diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 6e9434844..000000000 --- a/.tool-versions +++ /dev/null @@ -1,2 +0,0 @@ -java temurin-17.0.13+11 -protoc 30.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c27647e49..498aa945f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,6 +30,8 @@ If you're getting errors when running tests: - Use `-Dcheckstyle.skip=true` to skip the checkstyle check during development. - Use `-Dwarnings=-nowarn` to skip the warnings during development. +Combine all with `mvn test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn`. + ## Updating the Protobuf Java Classes Use `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java index 88453fa56..487eb55c4 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index d7645a575..47995b22d 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -5,7 +5,7 @@ import com.google.common.io.Resources; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import java.io.IOException; import java.net.URISyntaxException; import java.net.URLEncoder; diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java index 64c843edb..5e76d0983 100644 --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import java.io.IOException; import java.net.URL; import java.util.List; diff --git a/mise.toml b/mise.toml new file mode 100644 index 000000000..4d751096b --- /dev/null +++ b/mise.toml @@ -0,0 +1,15 @@ +[env] +PROTO_GENERATION = "true" + +[tools] +java = "temurin-17.0.13+11" +protoc = "30.1" + +[tasks.ci] +description = "CI Build" +run = [ + "./mvnw clean install", + # just to check if javadoc can be generated + "./mvnw javadoc:javadoc -P javadoc" +] +env = { PROTO_GENERATION = "true", REQUIRE_PROTO_UP_TO_DATE = "true" } diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index c04055fc4..2f765543c 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.CounterSnapshot; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index 47b059588..915548cef 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -8,7 +8,7 @@ import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index 275041724..ee3252317 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.Labels; diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index 30e83cfa3..26a1f05eb 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -36,15 +36,15 @@ GENERATED_WITH=$(grep -oP '\/\/ Protobuf Java Version: \K.*' "$TARGET_DIR/${PACK if [[ $GENERATED_WITH != "$PROTOBUF_VERSION" ]]; then echo "Generated protobuf sources version $GENERATED_WITH does not match provided version $PROTOBUF_VERSION" - echo "Please update the protoc version .tool-versions to the latest version of https://github.com/protocolbuffers/protobuf/releases" - echo "Please use https://github.com/asdf-vm/asdf - this will use the version specified in .tool-versions" - echo "Generated protobuf sources are not up-to-date. Please run 'PROTO_GENERATION=true mvn clean install' and commit the changes." + echo "Please use https://mise.jdx.dev/ - this will use the version specified in mise.toml" + echo "Generated protobuf sources are not up-to-date. Please run 'mise up && mvn clean install' and commit the changes." exit 1 fi STATUS=$(git status --porcelain) if [[ ${REQUIRE_PROTO_UP_TO_DATE:-false} == "true" && -n "$STATUS" ]]; then - echo "Generated protobuf sources are not up-to-date. Please run 'PROTO_GENERATION=true mvn clean install' and commit the changes." + echo "Please use https://mise.jdx.dev/ - this will use the version specified in mise.toml" + echo "Generated protobuf sources are not up-to-date. Please run 'mvn clean install' and commit the changes." echo "Local changes:" echo "$STATUS" exit 1 diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 56b7c6c4d..c6b9e47ca 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -20,7 +20,7 @@ io.prometheus.metrics.expositionformats - 4.30.0 + 4.30.1 diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java similarity index 89% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java index 523e8fa3a..88c93489b 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_0/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java @@ -2,9 +2,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto -// Protobuf Java Version: 4.30.0 +// Protobuf Java Version: 4.30.1 -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0; +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1; public final class Metrics { private Metrics() {} @@ -13,7 +13,7 @@ private Metrics() {} com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Metrics.class.getName()); } @@ -86,7 +86,7 @@ public enum MetricType com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", MetricType.class.getName()); } @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.getDescriptor().getEnumTypes().get(0); + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.getDescriptor().getEnumTypes().get(0); } private static final MetricType[] VALUES = values(); @@ -266,7 +266,7 @@ public static final class LabelPair extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", LabelPair.class.getName()); } @@ -281,15 +281,15 @@ private LabelPair() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder.class); } private int bitField0_; @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair) obj; if (hasName() != other.hasName()) return false; if (hasName()) { @@ -475,44 +475,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -573,21 +573,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.newBuilder() private Builder() { } @@ -609,17 +609,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance()) return this; if (other.hasName()) { name_ = other.name_; bitField0_ |= 0x00000001; @@ -887,12 +887,12 @@ public Builder setValueBytes( } // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -962,7 +962,7 @@ public static final class Gauge extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Gauge.class.getName()); } @@ -975,15 +975,15 @@ private Gauge() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder.class); } private int bitField0_; @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1078,44 +1078,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.newBuilder() private Builder() { } @@ -1211,17 +1211,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1353,12 +1353,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar(); /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); /** * optional .google.protobuf.Timestamp created_timestamp = 3; @@ -1458,7 +1458,7 @@ public static final class Counter extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Counter.class.getName()); } @@ -1471,15 +1471,15 @@ private Counter() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder.class); } private int bitField0_; @@ -1503,7 +1503,7 @@ public double getValue() { } public static final int EXEMPLAR_FIELD_NUMBER = 2; - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1517,15 +1517,15 @@ public boolean hasExemplar() { * @return The exemplar. */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3; @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1658,44 +1658,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1808,17 +1808,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1978,9 +1978,9 @@ public Builder clearValue() { return this; } - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_; private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarBuilder_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1992,9 +1992,9 @@ public boolean hasExemplar() { * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() { if (exemplarBuilder_ == null) { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } else { return exemplarBuilder_.getMessage(); } @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) { + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com * optional .io.prometheus.client.Exemplar exemplar = 2; */ public Builder setExemplar( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) { if (exemplarBuilder_ == null) { exemplar_ = builderForValue.build(); } else { @@ -2032,11 +2032,11 @@ public Builder setExemplar( /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) { + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && exemplar_ != null && - exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) { + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) { getExemplarBuilder().mergeFrom(value); } else { exemplar_ = value; @@ -2066,7 +2066,7 @@ public Builder clearExemplar() { /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarBuilder() { bitField0_ |= 0x00000002; onChanged(); return internalGetExemplarFieldBuilder().getBuilder(); @@ -2074,23 +2074,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { if (exemplarBuilder_ != null) { return exemplarBuilder_.getMessageOrBuilder(); } else { return exemplar_ == null ? - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; } } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> internalGetExemplarFieldBuilder() { if (exemplarBuilder_ == null) { exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>( getExemplar(), getParentForChildren(), isClean()); @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2310,7 +2310,7 @@ public static final class Quantile extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Quantile.class.getName()); } @@ -2323,15 +2323,15 @@ private Quantile() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder.class); } private int bitField0_; @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile) obj; if (hasQuantile() != other.hasQuantile()) return false; if (hasQuantile()) { @@ -2463,44 +2463,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.newBuilder() private Builder() { } @@ -2597,17 +2597,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()) return this; if (other.hasQuantile()) { setQuantile(other.getQuantile()); } @@ -2791,12 +2791,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileOrBuilderList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index); /** @@ -2916,7 +2916,7 @@ public static final class Summary extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Summary.class.getName()); } @@ -2930,15 +2930,15 @@ private Summary() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder.class); } private int bitField0_; @@ -2982,19 +2982,19 @@ public double getSampleSum() { public static final int QUANTILE_FIELD_NUMBER = 3; @SuppressWarnings("serial") - private java.util.List quantile_; + private java.util.List quantile_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { return quantile_; } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List + public java.util.List getQuantileOrBuilderList() { return quantile_; } @@ -3009,14 +3009,14 @@ public int getQuantileCount() { * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index) { return quantile_.get(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { return quantile_.get(index); } @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary) obj; if (hasSampleCount() != other.hasSampleCount()) return false; if (hasSampleCount()) { @@ -3165,44 +3165,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3318,17 +3318,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary(this); buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result) { + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result) { if (quantileBuilder_ == null) { if (((bitField0_ & 0x00000004) != 0)) { quantile_ = java.util.Collections.unmodifiableList(quantile_); @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance()) return this; if (other.hasSampleCount()) { setSampleCount(other.getSampleCount()); } @@ -3460,9 +3460,9 @@ public Builder mergeFrom( break; } // case 17 case 26: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.parser(), + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.parser(), extensionRegistry); if (quantileBuilder_ == null) { ensureQuantileIsMutable(); @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() { return this; } - private java.util.List quantile_ = + private java.util.List quantile_ = java.util.Collections.emptyList(); private void ensureQuantileIsMutable() { if (!((bitField0_ & 0x00000004) != 0)) { - quantile_ = new java.util.ArrayList(quantile_); + quantile_ = new java.util.ArrayList(quantile_); bitField0_ |= 0x00000004; } } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder> quantileBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder> quantileBuilder_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { if (quantileBuilder_ == null) { return java.util.Collections.unmodifiableList(quantile_); } else { @@ -3611,7 +3611,7 @@ public int getQuantileCount() { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3639,7 +3639,7 @@ public Builder setQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.set(index, builderForValue.build()); @@ -3652,7 +3652,7 @@ public Builder setQuantile( /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { + public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3686,7 +3686,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(builderForValue.build()); @@ -3700,7 +3700,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(index, builderForValue.build()); @@ -3714,7 +3714,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addAllQuantile( - java.lang.Iterable values) { + java.lang.Iterable values) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder getQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder getQuantileBuilder( int index) { return internalGetQuantileFieldBuilder().getBuilder(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileOrBuilderList() { if (quantileBuilder_ != null) { return quantileBuilder_.getMessageOrBuilderList(); @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder addQuantileBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder addQuantileBuilder() { return internalGetQuantileFieldBuilder().addBuilder( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder addQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder addQuantileBuilder( int index) { return internalGetQuantileFieldBuilder().addBuilder( - index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.getDefaultInstance()); + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileBuilderList() { return internalGetQuantileFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder> internalGetQuantileFieldBuilder() { if (quantileBuilder_ == null) { quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.QuantileOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder>( quantile_, ((bitField0_ & 0x00000004) != 0), getParentForChildren(), @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4016,7 +4016,7 @@ public static final class Untyped extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 0, + /* patch= */ 1, /* suffix= */ "", Untyped.class.getName()); } @@ -4029,15 +4029,15 @@ private Untyped() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder.class); } private int bitField0_; @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -4132,44 +4132,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.newBuilder() private Builder() { } @@ -4265,17 +4265,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -4407,12 +4407,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends * * repeated .io.prometheus.client.Bucket bucket = 3; */ - java.util.List + java.util.List getBucketList(); /** *
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4930,7 +4930,7 @@ public static final class Histogram extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6580,9 +6580,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,7 +6975,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return internalGetBucketFieldBuilder().getBuilder(index);
             }
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder addBucketBuilder() {
               return internalGetBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return internalGetBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return internalGetBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder> 
                 internalGetBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,7 +7648,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return internalGetNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return internalGetNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return internalGetNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return internalGetNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> 
                 internalGetNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,7 +8243,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return internalGetPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return internalGetPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return internalGetPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return internalGetPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> 
                 internalGetPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,7 +8814,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return internalGetExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return internalGetExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return internalGetExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return internalGetExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> 
                 internalGetExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9041,7 +9041,7 @@ public static final class Bucket extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,7 +9841,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return internalGetExemplarFieldBuilder().getBuilder();
      @@ -9849,23 +9849,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> 
                 internalGetExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9989,7 +9989,7 @@ public static final class BucketSpan extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10649,7 +10649,7 @@ public static final class Exemplar extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder() {
               return internalGetLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> 
                 internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11807,7 +11807,7 @@ public static final class Metric extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder() {
               return internalGetLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> 
                 internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,7 +12921,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return internalGetGaugeFieldBuilder().getBuilder();
      @@ -12929,23 +12929,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder> 
                 internalGetGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,7 +13042,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return internalGetCounterFieldBuilder().getBuilder();
      @@ -13050,23 +13050,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder> 
                 internalGetCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,7 +13163,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return internalGetSummaryFieldBuilder().getBuilder();
      @@ -13171,23 +13171,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder> 
                 internalGetSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,7 +13284,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return internalGetUntypedFieldBuilder().getBuilder();
      @@ -13292,23 +13292,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder> 
                 internalGetUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,7 +13405,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return internalGetHistogramFieldBuilder().getBuilder();
      @@ -13413,23 +13413,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder> 
                 internalGetHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13632,7 +13632,7 @@ public static final class MetricFamily extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 0,
      +        /* patch= */ 1,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return internalGetMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder addMetricBuilder() {
               return internalGetMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return internalGetMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return internalGetMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder> 
                 internalGetMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_30_0Z:github.com/prometheus/clien" +
      +      "obuf_4_30_1Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index 9902dc9f1..83476ad4b 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      index 4dc9b5d83..03000712d 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_0.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.MetricSnapshot;
      
      From 7adbe725fbfb8d8c392e1c83dd87e153d1acf58e Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 17 Mar 2025 14:30:19 +0100
      Subject: [PATCH 556/980] Bump org.mockito:mockito-core from 5.16.0 to 5.16.1
       (#1308)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito)
      from 5.16.0 to 5.16.1.
      
      Release notes

      Sourced from org.mockito:mockito-core's releases.

      v5.16.1

      Changelog generated by Shipkit Changelog Gradle Plugin

      5.16.1

      Commits
      • d000e63 Rework of injection strategy in the context of modules (#3608)
      • 0215884 Remove Arrays.asList from critical stubbing path in GenericMetadataSupport (#...
      • d185035 Add reference to Gradle documentation on how to make task relocatable (#3606)
      • See full diff in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.mockito:mockito-core&package-manager=maven&previous-version=5.16.0&new-version=5.16.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e6eb6987..206bd6faa 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.mockito mockito-core - 5.16.0 + 5.16.1 test From d6ee0e7f12c81026fad55701d0d3ec329482834d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:41:37 +0100 Subject: [PATCH 557/980] Bump jetty-server.version from 12.0.17 to 12.0.18 (#1309) Bumps `jetty-server.version` from 12.0.17 to 12.0.18. Updates `org.eclipse.jetty:jetty-server` from 12.0.17 to 12.0.18 Updates `org.eclipse.jetty.ee10:jetty-ee10-servlet` from 12.0.17 to 12.0.18 Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index b16daa73d..fc38eded2 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -15,7 +15,7 @@ Jetty Sample for the Exporter Integration Test - 12.0.17 + 12.0.18 17 From 8595e876d37f656800d8a2795910923a730470da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 08:34:03 +0100 Subject: [PATCH 558/980] Bump com.google.guava:guava from 33.4.0-jre to 33.4.5-jre (#1310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.0-jre to 33.4.5-jre.
      Release notes

      Sourced from com.google.guava:guava's releases.

      33.4.5

      For those upgrading from Guava 33.4.0 or earlier, be sure to read the release notes for Guava 33.4.1.

      Maven

      <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>33.4.5-jre</version>
        <!-- or, for Android: -->
        <version>33.4.5-android</version>
      </dependency>
      

      Jar files

      Guava requires one runtime dependency, which you can download here:

      Javadoc

      JDiff

      Changelog

      • Changed the Guava jar (plus guava-testlib and failureaccess jars) to be a modular jar. (7a71ea0bfa, 287c701a86)
      • Changed various classes to stop using sun.misc.Unsafe under Java 9+. (ee63055ddd, 80aab00dc5b7a36785f5e09b6a54397388980cde, 400af25292096746ed3f6164f0ff88209acbb19f, 71d0692d418a5dd001c9b3786275a5f1f94e1971, d1a3cd5037528a2ae990bfceed9cdd009fbc54de, b3bb29a54b8f13d6f6630b6cb929867adbf6b9a0, 1a300f6b2f7ba03ae9bc3620a80c4d4589c65b69)
        • Note that, if you use guava-android on the JVM (instead of using guava-jre), Guava will still try to use sun.misc.Unsafe. We will do further work on this in the future.
      • Belatedly updated the Public Suffix List data. (ee3b9c64382037f72b3a8341915cc64b87850b53, d25d62fc843ece1c3866859bc8639b815093eac8)

      Special thanks to @​sgammon for his modularization efforts.

      33.4.4

      This is one of a series of releases that improve Guava's nullness annotations. For more information, including troubleshooting help, see the release notes for Guava 33.4.1. Most users can update directly to Guava 33.4.5.

      Maven

      </tr></table>
      

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava&package-manager=maven&previous-version=33.4.0-jre&new-version=33.4.5-jre)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 206bd6faa..6799220d8 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- - 33.4.0-jre + 33.4.5-jre 5.12.1 2.14.0-alpha 8 From ac7fe5fa075eaae4612f1138f80ddf8d5412379f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Mar 2025 09:23:31 +0000 Subject: [PATCH 559/980] Bump com.google.errorprone:error_prone_core from 2.36.0 to 2.37.0 (#1311) Bumps [com.google.errorprone:error_prone_core](https://github.com/google/error-prone) from 2.36.0 to 2.37.0.
      Release notes

      Sourced from com.google.errorprone:error_prone_core's releases.

      Error Prone 2.37.0

      Changes:

      • The annotations that were previously in error_prone_type_annotations have been been merged into error_prone_annotations. error_prone_type_annotations is now deprecated, and will be removed in a future release.

      New checks:

      • AssignmentExpression - The use of an assignment expression can be surprising and hard to read; consider factoring out the assignment to a separate statement.
      • IntFloatConversion - Detect calls to scalb that should be using the double overload instead
      • InvalidSnippet - Detects snippets which omit the : required for inline code.
      • JUnit4EmptyMethods - Detects empty JUnit4 @Before, @After, @BeforeClass, and @AfterClass methods.
      • MockIllegalThrows - Detects cases where Mockito is configured to throw checked exception types which are impossible.
      • NegativeBoolean - Prefer positive boolean names.
      • RuleNotRun - Detects TestRules not annotated with @Rule, that won't be run.
      • StringConcatToTextBlock - Replaces concatenated multiline strings with text blocks.
      • TimeInStaticInitializer - Detects accesses of the system time in static contexts.

      Closed issues:

      • Propagate check flags in patch mode (#4699)
      • Fixes a crash in ComputeIfAbsentAmbiguousReference (#4736)
      • Show the field name in HidingField diagnostics (#4775)
      • Add support for jakarta annotations to some checks (#4782)
      • FloatingPointAssertionWithinEpsilonTest depends on default locale (#4815)
      • @InlineMe patching of Strings.repeat produces broken code (#4819)
      • Fix a crash in IdentifierName on unnamed (_) variables (#4847)
      • Fix a crash in ArgumentParameterSwap (#490)

      Full changelog: https://github.com/google/error-prone/compare/v2.36.0...v2.37.0

      Commits
      • a453935 Release Error Prone 2.37.0
      • 81faa5a Update JDK versions in release.yml
      • 62086b7 Handle multiple arguments in thenThrow.
      • 7440ff1 In StringConcatToTextBlock, don't assume that string literals always have sou...
      • 04fe835 Adds type_annotations back but as a relocation to annotations
      • 1ad73c2 Handle yield in Reachability
      • b1b521f Sniff out the canonical constructor using detective work rather than a flag w...
      • 86e5c95 Optimization: Abort class scan in JUnit4TestNotRun if all suspicious method...
      • c139e7f [StatementSwitchToExpressionSwitch] for the return switch pattern, fix a bug ...
      • 296fb4e Hardcode BoxedPrimitiveEquality:ExemptStaticConstants = false.
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.36.0&new-version=2.37.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- CONTRIBUTING.md | 2 +- mise.toml | 12 + pom.xml | 2 +- .../metrics/core/metrics/CounterTest.java | 38 +- .../metrics/core/metrics/GaugeTest.java | 38 +- .../metrics/core/metrics/HistogramTest.java | 34 +- .../exporter/httpserver/DefaultHandler.java | 3 +- .../ExpositionFormatsTest.java | 413 +++++++++++------- .../caffeine/CacheMetricsCollectorTest.java | 40 +- .../dropwizard5/DropwizardExportsTest.java | 112 ++--- .../labels/CustomLabelMapperTest.java | 60 ++- .../guava/CacheMetricsCollectorTest.java | 34 +- .../jvm/JvmBufferPoolMetricsTest.java | 32 +- .../jvm/JvmClassLoadingMetricsTest.java | 22 +- .../jvm/JvmCompilationMetricsTest.java | 12 +- .../jvm/JvmGarbageCollectorMetricsTest.java | 18 +- .../jvm/JvmMemoryMetricsTest.java | 130 +++--- .../jvm/JvmNativeMemoryMetricsTest.java | 292 +++++++------ .../jvm/JvmRuntimeInfoMetricTest.java | 10 +- .../jvm/JvmThreadsMetricsTest.java | 58 +-- .../jvm/ProcessMetricsTest.java | 64 +-- 21 files changed, 799 insertions(+), 627 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 498aa945f..c8f7501c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ If you're getting errors when running tests: - Use `-Dcheckstyle.skip=true` to skip the checkstyle check during development. - Use `-Dwarnings=-nowarn` to skip the warnings during development. -Combine all with `mvn test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn`. +Combine all with `./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn`. ## Updating the Protobuf Java Classes diff --git a/mise.toml b/mise.toml index 4d751096b..e4f7afcda 100644 --- a/mise.toml +++ b/mise.toml @@ -13,3 +13,15 @@ run = [ "./mvnw javadoc:javadoc -P javadoc" ] env = { PROTO_GENERATION = "true", REQUIRE_PROTO_UP_TO_DATE = "true" } + +[tasks.format] +description = "format source code" +run = "./mvnw spotless:apply" + +[tasks.test] +description = "run unit tests, ignoring formatting and linters" +run = "./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn" + +[tasks.test-all] +description = "run all tests" +run = "./mvnw verify" diff --git a/pom.xml b/pom.xml index 6799220d8..554045314 100644 --- a/pom.xml +++ b/pom.xml @@ -370,7 +370,7 @@ com.google.errorprone error_prone_core - 2.36.0 + 2.37.0

      ... (truncated)

      Commits
      • d4eb556 Increase Nexus timeouts
      • 0226b6a Release v3.4.4
      • 6ba94ae Merge branch '3.3.x' into 3.4.x
      • 36a5936 Next development version (v3.3.11-SNAPSHOT)
      • 375aba6 Upgrade to Spring Framework 6.2.5
      • 37e4a3c Merge branch '3.3.x' into 3.4.x
      • 99fa21c Upgrade to asciidoctor-extensions 1.0.0-alpha.17
      • f86a6fb Upgrade to Spring Batch 5.2.2
      • 6567609 Merge branch '3.3.x' into 3.4.x
      • 80b6c59 Improve debuggability of DockerComposeTestExtension
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot:spring-boot-starter-parent&package-manager=maven&previous-version=3.4.3&new-version=3.4.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 2e0c4e072..e249cedf6 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.3 + 3.4.4 From 059a1ce4f9ac735da0c00740e63e043a4f2b492f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Mar 2025 10:34:07 -0400 Subject: [PATCH 561/980] Bump com.google.guava:guava from 33.4.5-jre to 33.4.6-jre (#1313) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.5-jre to 33.4.6-jre.
      Release notes

      Sourced from com.google.guava:guava's releases.

      33.4.6

      Guava 33.4.6 fixes two problems that we introduced while modularizing Guava in 33.4.5.

      Even if you're not upgrading from Guava 33.4.0 or earlier, still read the release notes for Guava 33.4.1. Those release notes contain information about Guava 33.4.5 and 33.4.6's effect on the module system.

      Maven

      <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>33.4.6-jre</version>
        <!-- or, for Android: -->
        <version>33.4.6-android</version>
      </dependency>
      

      Jar files

      Guava requires one runtime dependency, which you can download here:

      Javadoc

      JDiff

      Changelog

      • Removed the extra copy of each class from the Guava jar. The extra copies were an accidental addition from the modularization work in Guava 33.4.5. (40485b93ce)
      • Fixed annotation-related warnings when using Guava in modular builds. The most common such warning is Cannot find annotation method 'value()' in type 'DoNotMock': .... (7e15ab3566)
      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava&package-manager=maven&previous-version=33.4.5-jre&new-version=33.4.6-jre)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 554045314..fd239c424 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- - 33.4.5-jre + 33.4.6-jre 5.12.1 2.14.0-alpha 8 From 09bcf7e02f6157d47872d1dea89cf2fde5a65115 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:15:26 +0200 Subject: [PATCH 562/980] Bump com.google.protobuf:protobuf-java from 4.30.1 to 4.30.2 (#1314) Bumps [com.google.protobuf:protobuf-java](https://github.com/protocolbuffers/protobuf) from 4.30.1 to 4.30.2.
      Commits
      • 43e1626 Updating version.json and repo version numbers to: 30.2
      • 7a4c63b Fix lite classes in the protobuf-java Maven release to be JDK8 compatible. (#...
      • 7831669 Remove dllexport attribute on variable definition. (#20833)
      • da9cadc Restore JDK8 compatibility in Bazel for libraries with dependencies from Mave...
      • 09b5078 Add protobuf_maven artifacts to protobuf_maven_dev as well so they can still ...
      • b7f06f1 Add volatile to featuresResolved (#20766)
      • b69f653 Restore generator headers in cmake install until the next breaking C++ releas...
      • f4b0a79 Restore custom protobuf maven namespaces to avoid polluting main maven namesp...
      • 2dc9f35 Fix Java concurrency issue in feature resolution for old <=3.25.x gencode usi...
      • 221b2a0 Change how we decide which empty string implementation to use. (#20708)
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.protobuf:protobuf-java&package-manager=maven&previous-version=4.30.1&new-version=4.30.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .github/workflows/build.yml | 3 - CONTRIBUTING.md | 2 +- .../client/it/common/ExporterTest.java | 2 +- .../metrics/it/exporter/test/ExporterIT.java | 2 +- .../it/springboot/ApplicationTest.java | 2 +- mise.lock | 10 + mise.toml | 5 +- .../metrics/core/metrics/CounterTest.java | 2 +- .../metrics/core/metrics/HistogramTest.java | 2 +- .../metrics/core/metrics/InfoTest.java | 2 +- .../generate-protobuf.sh | 4 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- .../Metrics.java | 1810 ++++++++--------- .../PrometheusProtobufWriterImpl.java | 2 +- .../ProtobufExpositionFormatsTest.java | 2 +- 15 files changed, 930 insertions(+), 922 deletions(-) create mode 100644 mise.lock rename prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/{com_google_protobuf_4_30_1 => com_google_protobuf_4_30_2}/Metrics.java (89%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 63901f9f4..e9f07e786 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,8 +20,5 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: Run the Maven verify phase - env: - PROTO_GENERATION: true - REQUIRE_PROTO_UP_TO_DATE: true run: mise run ci diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8f7501c7..ff9717f67 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,4 +34,4 @@ Combine all with `./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcove ## Updating the Protobuf Java Classes -Use `PROTO_GENERATION=true mvn clean install` to generate protobuf classes. +Use `mise up && mise run test` to generate protobuf classes. diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java index 487eb55c4..bda5fcc6f 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/ExporterTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java index 47995b22d..e938f8c4d 100644 --- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java +++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java @@ -5,7 +5,7 @@ import com.google.common.io.Resources; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import java.io.IOException; import java.net.URISyntaxException; import java.net.URLEncoder; diff --git a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java index 5e76d0983..9ada4c8ae 100644 --- a/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java +++ b/integration-tests/it-spring-boot-smoke-test/src/test/java/io/prometheus/metrics/it/springboot/ApplicationTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.prometheus.client.it.common.ExporterTest; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import java.io.IOException; import java.net.URL; import java.util.List; diff --git a/mise.lock b/mise.lock new file mode 100644 index 000000000..789ebabb2 --- /dev/null +++ b/mise.lock @@ -0,0 +1,10 @@ +[tools.java] +version = "temurin-17.0.13+11" +backend = "core:java" + +[tools.protoc] +version = "30.2" +backend = "aqua:protocolbuffers/protobuf/protoc" + +[tools.protoc.checksums] +"protoc-30.2-linux-x86_64.zip" = "sha256:327e9397c6fb3ea2a542513a3221334c6f76f7aa524a7d2561142b67b312a01f" diff --git a/mise.toml b/mise.toml index e4f7afcda..bf7a976de 100644 --- a/mise.toml +++ b/mise.toml @@ -3,7 +3,7 @@ PROTO_GENERATION = "true" [tools] java = "temurin-17.0.13+11" -protoc = "30.1" +protoc = "latest" [tasks.ci] description = "CI Build" @@ -12,7 +12,7 @@ run = [ # just to check if javadoc can be generated "./mvnw javadoc:javadoc -P javadoc" ] -env = { PROTO_GENERATION = "true", REQUIRE_PROTO_UP_TO_DATE = "true" } +env = { REQUIRE_PROTO_UP_TO_DATE = "true" } [tasks.format] description = "format source code" @@ -25,3 +25,4 @@ run = "./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=t [tasks.test-all] description = "run all tests" run = "./mvnw verify" + diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java index dedcb7a38..8d05811d0 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/CounterTest.java @@ -6,7 +6,7 @@ import static org.assertj.core.data.Offset.offset; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.CounterSnapshot; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java index be506e8ea..40b168285 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java @@ -8,7 +8,7 @@ import io.prometheus.metrics.core.datapoints.DistributionDataPoint; import io.prometheus.metrics.core.exemplars.ExemplarSamplerConfigTestUtil; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket; diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java index ee3252317..76854b034 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/InfoTest.java @@ -4,7 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics; import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl; import io.prometheus.metrics.expositionformats.internal.ProtobufUtil; import io.prometheus.metrics.model.snapshots.Labels; diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index 26a1f05eb..c92eaf790 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -37,14 +37,14 @@ GENERATED_WITH=$(grep -oP '\/\/ Protobuf Java Version: \K.*' "$TARGET_DIR/${PACK if [[ $GENERATED_WITH != "$PROTOBUF_VERSION" ]]; then echo "Generated protobuf sources version $GENERATED_WITH does not match provided version $PROTOBUF_VERSION" echo "Please use https://mise.jdx.dev/ - this will use the version specified in mise.toml" - echo "Generated protobuf sources are not up-to-date. Please run 'mise up && mvn clean install' and commit the changes." + echo "Generated protobuf sources are not up-to-date. Please run 'mise up && mise run test' and commit the changes." exit 1 fi STATUS=$(git status --porcelain) if [[ ${REQUIRE_PROTO_UP_TO_DATE:-false} == "true" && -n "$STATUS" ]]; then echo "Please use https://mise.jdx.dev/ - this will use the version specified in mise.toml" - echo "Generated protobuf sources are not up-to-date. Please run 'mvn clean install' and commit the changes." + echo "Generated protobuf sources are not up-to-date. Please run 'mise run test' and commit the changes." echo "Local changes:" echo "$STATUS" exit 1 diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index c6b9e47ca..69237e4bf 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -20,7 +20,7 @@ io.prometheus.metrics.expositionformats - 4.30.1 + 4.30.2 diff --git a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_2/Metrics.java similarity index 89% rename from prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java rename to prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_2/Metrics.java index 88c93489b..db5361389 100644 --- a/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_1/Metrics.java +++ b/prometheus-metrics-exposition-formats/src/main/generated/io/prometheus/metrics/expositionformats/generated/com_google_protobuf_4_30_2/Metrics.java @@ -2,9 +2,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: src/main/protobuf/metrics.proto -// Protobuf Java Version: 4.30.1 +// Protobuf Java Version: 4.30.2 -package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1; +package io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2; public final class Metrics { private Metrics() {} @@ -13,7 +13,7 @@ private Metrics() {} com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Metrics.class.getName()); } @@ -86,7 +86,7 @@ public enum MetricType com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", MetricType.class.getName()); } @@ -192,7 +192,7 @@ public MetricType findValueByNumber(int number) { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.getDescriptor().getEnumTypes().get(0); + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.getDescriptor().getEnumTypes().get(0); } private static final MetricType[] VALUES = values(); @@ -266,7 +266,7 @@ public static final class LabelPair extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", LabelPair.class.getName()); } @@ -281,15 +281,15 @@ private LabelPair() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder.class); } private int bitField0_; @@ -436,10 +436,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair) obj; if (hasName() != other.hasName()) return false; if (hasName()) { @@ -475,44 +475,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -520,26 +520,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -552,7 +552,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -573,21 +573,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.newBuilder() private Builder() { } @@ -609,17 +609,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -627,14 +627,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -650,16 +650,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance()) return this; if (other.hasName()) { name_ = other.name_; bitField0_ |= 0x00000001; @@ -887,12 +887,12 @@ public Builder setValueBytes( } // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -928,7 +928,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -962,7 +962,7 @@ public static final class Gauge extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Gauge.class.getName()); } @@ -975,15 +975,15 @@ private Gauge() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder.class); } private int bitField0_; @@ -1046,10 +1046,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1078,44 +1078,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1123,26 +1123,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1155,7 +1155,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1176,21 +1176,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.newBuilder() private Builder() { } @@ -1211,17 +1211,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Gauge_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1229,14 +1229,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1248,16 +1248,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1353,12 +1353,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -1394,7 +1394,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -1424,11 +1424,11 @@ public interface CounterOrBuilder extends * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar(); /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder(); /** * optional .google.protobuf.Timestamp created_timestamp = 3; @@ -1458,7 +1458,7 @@ public static final class Counter extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Counter.class.getName()); } @@ -1471,15 +1471,15 @@ private Counter() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder.class); } private int bitField0_; @@ -1503,7 +1503,7 @@ public double getValue() { } public static final int EXEMPLAR_FIELD_NUMBER = 2; - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar exemplar_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1517,15 +1517,15 @@ public boolean hasExemplar() { * @return The exemplar. */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_; } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_; } public static final int CREATED_TIMESTAMP_FIELD_NUMBER = 3; @@ -1608,10 +1608,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -1658,44 +1658,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1703,26 +1703,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -1735,7 +1735,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -1756,21 +1756,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -1808,17 +1808,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Counter_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Counter_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -1826,14 +1826,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -1857,16 +1857,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -1978,9 +1978,9 @@ public Builder clearValue() { return this; } - private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_; + private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar exemplar_; private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> exemplarBuilder_; /** * optional .io.prometheus.client.Exemplar exemplar = 2; * @return Whether the exemplar field is set. @@ -1992,9 +1992,9 @@ public boolean hasExemplar() { * optional .io.prometheus.client.Exemplar exemplar = 2; * @return The exemplar. */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar() { if (exemplarBuilder_ == null) { - return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; + return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_; } else { return exemplarBuilder_.getMessage(); } @@ -2002,7 +2002,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) { + public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -2019,7 +2019,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com * optional .io.prometheus.client.Exemplar exemplar = 2; */ public Builder setExemplar( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder builderForValue) { if (exemplarBuilder_ == null) { exemplar_ = builderForValue.build(); } else { @@ -2032,11 +2032,11 @@ public Builder setExemplar( /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) { + public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) { if (exemplarBuilder_ == null) { if (((bitField0_ & 0x00000002) != 0) && exemplar_ != null && - exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) { + exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance()) { getExemplarBuilder().mergeFrom(value); } else { exemplar_ = value; @@ -2066,7 +2066,7 @@ public Builder clearExemplar() { /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder getExemplarBuilder() { bitField0_ |= 0x00000002; onChanged(); return internalGetExemplarFieldBuilder().getBuilder(); @@ -2074,23 +2074,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() { if (exemplarBuilder_ != null) { return exemplarBuilder_.getMessageOrBuilder(); } else { return exemplar_ == null ? - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_; } } /** * optional .io.prometheus.client.Exemplar exemplar = 2; */ private com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> internalGetExemplarFieldBuilder() { if (exemplarBuilder_ == null) { exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder>( getExemplar(), getParentForChildren(), isClean()); @@ -2224,12 +2224,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2265,7 +2265,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2310,7 +2310,7 @@ public static final class Quantile extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Quantile.class.getName()); } @@ -2323,15 +2323,15 @@ private Quantile() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder.class); } private int bitField0_; @@ -2420,10 +2420,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile) obj; if (hasQuantile() != other.hasQuantile()) return false; if (hasQuantile()) { @@ -2463,44 +2463,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2508,26 +2508,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -2540,7 +2540,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -2561,21 +2561,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.newBuilder() private Builder() { } @@ -2597,17 +2597,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Quantile_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -2615,14 +2615,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -2638,16 +2638,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.getDefaultInstance()) return this; if (other.hasQuantile()) { setQuantile(other.getQuantile()); } @@ -2791,12 +2791,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -2832,7 +2832,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -2867,12 +2867,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getQuantile(int index); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @@ -2880,12 +2880,12 @@ public interface SummaryOrBuilder extends /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - java.util.List + java.util.List getQuantileOrBuilderList(); /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index); /** @@ -2916,7 +2916,7 @@ public static final class Summary extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Summary.class.getName()); } @@ -2930,15 +2930,15 @@ private Summary() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder.class); } private int bitField0_; @@ -2982,19 +2982,19 @@ public double getSampleSum() { public static final int QUANTILE_FIELD_NUMBER = 3; @SuppressWarnings("serial") - private java.util.List quantile_; + private java.util.List quantile_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { return quantile_; } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public java.util.List + public java.util.List getQuantileOrBuilderList() { return quantile_; } @@ -3009,14 +3009,14 @@ public int getQuantileCount() { * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getQuantile(int index) { return quantile_.get(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { return quantile_.get(index); } @@ -3108,10 +3108,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary) obj; if (hasSampleCount() != other.hasSampleCount()) return false; if (hasSampleCount()) { @@ -3165,44 +3165,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3210,26 +3210,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -3242,7 +3242,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -3263,21 +3263,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -3318,17 +3318,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Summary_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Summary_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -3336,15 +3336,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary(this); buildPartialRepeatedFields(result); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result) { + private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary result) { if (quantileBuilder_ == null) { if (((bitField0_ & 0x00000004) != 0)) { quantile_ = java.util.Collections.unmodifiableList(quantile_); @@ -3356,7 +3356,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats. } } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -3378,16 +3378,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance()) return this; if (other.hasSampleCount()) { setSampleCount(other.getSampleCount()); } @@ -3460,9 +3460,9 @@ public Builder mergeFrom( break; } // case 17 case 26: { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile m = + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile m = input.readMessage( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.parser(), + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.parser(), extensionRegistry); if (quantileBuilder_ == null) { ensureQuantileIsMutable(); @@ -3576,22 +3576,22 @@ public Builder clearSampleSum() { return this; } - private java.util.List quantile_ = + private java.util.List quantile_ = java.util.Collections.emptyList(); private void ensureQuantileIsMutable() { if (!((bitField0_ & 0x00000004) != 0)) { - quantile_ = new java.util.ArrayList(quantile_); + quantile_ = new java.util.ArrayList(quantile_); bitField0_ |= 0x00000004; } } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder> quantileBuilder_; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder> quantileBuilder_; /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List getQuantileList() { + public java.util.List getQuantileList() { if (quantileBuilder_ == null) { return java.util.Collections.unmodifiableList(quantile_); } else { @@ -3611,7 +3611,7 @@ public int getQuantileCount() { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile getQuantile(int index) { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile getQuantile(int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3622,7 +3622,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3639,7 +3639,7 @@ public Builder setQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder setQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.set(index, builderForValue.build()); @@ -3652,7 +3652,7 @@ public Builder setQuantile( /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { + public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3669,7 +3669,7 @@ public Builder addQuantile(io.prometheus.metrics.expositionformats.generated.com * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile value) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile value) { if (quantileBuilder_ == null) { if (value == null) { throw new NullPointerException(); @@ -3686,7 +3686,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(builderForValue.build()); @@ -3700,7 +3700,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addQuantile( - int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder builderForValue) { + int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder builderForValue) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); quantile_.add(index, builderForValue.build()); @@ -3714,7 +3714,7 @@ public Builder addQuantile( * repeated .io.prometheus.client.Quantile quantile = 3; */ public Builder addAllQuantile( - java.lang.Iterable values) { + java.lang.Iterable values) { if (quantileBuilder_ == null) { ensureQuantileIsMutable(); com.google.protobuf.AbstractMessageLite.Builder.addAll( @@ -3754,14 +3754,14 @@ public Builder removeQuantile(int index) { /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder getQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder getQuantileBuilder( int index) { return internalGetQuantileFieldBuilder().getBuilder(index); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder getQuantileOrBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder getQuantileOrBuilder( int index) { if (quantileBuilder_ == null) { return quantile_.get(index); } else { @@ -3771,7 +3771,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileOrBuilderList() { if (quantileBuilder_ != null) { return quantileBuilder_.getMessageOrBuilderList(); @@ -3782,31 +3782,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder addQuantileBuilder() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder addQuantileBuilder() { return internalGetQuantileFieldBuilder().addBuilder( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder addQuantileBuilder( + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder addQuantileBuilder( int index) { return internalGetQuantileFieldBuilder().addBuilder( - index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.getDefaultInstance()); + index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.getDefaultInstance()); } /** * repeated .io.prometheus.client.Quantile quantile = 3; */ - public java.util.List + public java.util.List getQuantileBuilderList() { return internalGetQuantileFieldBuilder().getBuilderList(); } private com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder> + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder> internalGetQuantileFieldBuilder() { if (quantileBuilder_ == null) { quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.QuantileOrBuilder>( + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Quantile.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.QuantileOrBuilder>( quantile_, ((bitField0_ & 0x00000004) != 0), getParentForChildren(), @@ -3941,12 +3941,12 @@ public com.google.protobuf.TimestampOrBuilder getCreatedTimestampOrBuilder() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -3982,7 +3982,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4016,7 +4016,7 @@ public static final class Untyped extends com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 30, - /* patch= */ 1, + /* patch= */ 2, /* suffix= */ "", Untyped.class.getName()); } @@ -4029,15 +4029,15 @@ private Untyped() { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder.class); } private int bitField0_; @@ -4100,10 +4100,10 @@ public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } - if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped)) { + if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped)) { return super.equals(obj); } - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped) obj; + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped) obj; if (hasValue() != other.hasValue()) return false; if (hasValue()) { @@ -4132,44 +4132,44 @@ public int hashCode() { return hash; } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom(byte[] data) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4177,26 +4177,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto .parseWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseDelimitedFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped parseFrom( + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -4209,7 +4209,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } - public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped prototype) { + public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override @@ -4230,21 +4230,21 @@ protected Builder newBuilderForType( public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped) - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable .ensureFieldAccessorsInitialized( - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder.class); + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder.class); } - // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.newBuilder() + // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.newBuilder() private Builder() { } @@ -4265,17 +4265,17 @@ public Builder clear() { @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Untyped_descriptor; } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstanceForType() { - return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getDefaultInstanceForType() { + return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance(); } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped build() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result = buildPartial(); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped build() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -4283,14 +4283,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3 } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped buildPartial() { - io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped(this); + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped buildPartial() { + io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } - private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped result) { + private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped result) { int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) != 0)) { @@ -4302,16 +4302,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped) { - return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped)other); + if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped) { + return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped other) { - if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance()) return this; + public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped other) { + if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance()) return this; if (other.hasValue()) { setValue(other.getValue()); } @@ -4407,12 +4407,12 @@ public Builder clearValue() { } // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped) - private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped DEFAULT_INSTANCE; + private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped DEFAULT_INSTANCE; static { - DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped(); + DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped(); } - public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstance() { + public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getDefaultInstance() { return DEFAULT_INSTANCE; } @@ -4448,7 +4448,7 @@ public com.google.protobuf.Parser getParserForType() { } @java.lang.Override - public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getDefaultInstanceForType() { + public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getDefaultInstanceForType() { return DEFAULT_INSTANCE; } @@ -4506,7 +4506,7 @@ public interface HistogramOrBuilder extends * * repeated .io.prometheus.client.Bucket bucket = 3; */ - java.util.List + java.util.List getBucketList(); /** *
      @@ -4515,7 +4515,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getBucket(int index);
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -4531,7 +4531,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    java.util.List 
      +    java.util.List 
               getBucketOrBuilderList();
           /**
            * 
      @@ -4540,7 +4540,7 @@ public interface HistogramOrBuilder extends
            *
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index);
       
           /**
      @@ -4649,7 +4649,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanList();
           /**
            * 
      @@ -4658,7 +4658,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getNegativeSpan(int index);
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -4674,7 +4674,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    java.util.List 
      +    java.util.List 
               getNegativeSpanOrBuilderList();
           /**
            * 
      @@ -4683,7 +4683,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index);
       
           /**
      @@ -4760,7 +4760,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanList();
           /**
            * 
      @@ -4772,7 +4772,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getPositiveSpan(int index);
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -4794,7 +4794,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    java.util.List 
      +    java.util.List 
               getPositiveSpanOrBuilderList();
           /**
            * 
      @@ -4806,7 +4806,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index);
       
           /**
      @@ -4880,7 +4880,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsList();
           /**
            * 
      @@ -4889,7 +4889,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplars(int index);
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -4905,7 +4905,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    java.util.List 
      +    java.util.List 
               getExemplarsOrBuilderList();
           /**
            * 
      @@ -4914,7 +4914,7 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            *
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index);
         }
         /**
      @@ -4930,7 +4930,7 @@ public static final class Histogram extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Histogram.class.getName());
           }
      @@ -4951,15 +4951,15 @@ private Histogram() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder.class);
           }
       
           private int bitField0_;
      @@ -5030,7 +5030,7 @@ public double getSampleSum() {
       
           public static final int BUCKET_FIELD_NUMBER = 3;
           @SuppressWarnings("serial")
      -    private java.util.List bucket_;
      +    private java.util.List bucket_;
           /**
            * 
            * Buckets for the conventional histogram.
      @@ -5039,7 +5039,7 @@ public double getSampleSum() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List getBucketList() {
      +    public java.util.List getBucketList() {
             return bucket_;
           }
           /**
      @@ -5050,7 +5050,7 @@ public java.util.Listrepeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getBucketOrBuilderList() {
             return bucket_;
           }
      @@ -5073,7 +5073,7 @@ public int getBucketCount() {
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getBucket(int index) {
             return bucket_.get(index);
           }
           /**
      @@ -5084,7 +5084,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.Bucket bucket = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder getBucketOrBuilder(
               int index) {
             return bucket_.get(index);
           }
      @@ -5233,7 +5233,7 @@ public double getZeroCountFloat() {
       
           public static final int NEGATIVE_SPAN_FIELD_NUMBER = 9;
           @SuppressWarnings("serial")
      -    private java.util.List negativeSpan_;
      +    private java.util.List negativeSpan_;
           /**
            * 
            * Negative buckets for the native histogram.
      @@ -5242,7 +5242,7 @@ public double getZeroCountFloat() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List getNegativeSpanList() {
      +    public java.util.List getNegativeSpanList() {
             return negativeSpan_;
           }
           /**
      @@ -5253,7 +5253,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getNegativeSpanOrBuilderList() {
             return negativeSpan_;
           }
      @@ -5276,7 +5276,7 @@ public int getNegativeSpanCount() {
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getNegativeSpan(int index) {
             return negativeSpan_.get(index);
           }
           /**
      @@ -5287,7 +5287,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.BucketSpan negative_span = 9;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
               int index) {
             return negativeSpan_.get(index);
           }
      @@ -5382,7 +5382,7 @@ public double getNegativeCount(int index) {
       
           public static final int POSITIVE_SPAN_FIELD_NUMBER = 12;
           @SuppressWarnings("serial")
      -    private java.util.List positiveSpan_;
      +    private java.util.List positiveSpan_;
           /**
            * 
            * Positive buckets for the native histogram.
      @@ -5394,7 +5394,7 @@ public double getNegativeCount(int index) {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List getPositiveSpanList() {
      +    public java.util.List getPositiveSpanList() {
             return positiveSpan_;
           }
           /**
      @@ -5408,7 +5408,7 @@ public java.util.Listrepeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getPositiveSpanOrBuilderList() {
             return positiveSpan_;
           }
      @@ -5437,7 +5437,7 @@ public int getPositiveSpanCount() {
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getPositiveSpan(int index) {
             return positiveSpan_.get(index);
           }
           /**
      @@ -5451,7 +5451,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.BucketSpan positive_span = 12;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
               int index) {
             return positiveSpan_.get(index);
           }
      @@ -5546,7 +5546,7 @@ public double getPositiveCount(int index) {
       
           public static final int EXEMPLARS_FIELD_NUMBER = 16;
           @SuppressWarnings("serial")
      -    private java.util.List exemplars_;
      +    private java.util.List exemplars_;
           /**
            * 
            * Only used for native histograms. These exemplars MUST have a timestamp.
      @@ -5555,7 +5555,7 @@ public double getPositiveCount(int index) {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List getExemplarsList() {
      +    public java.util.List getExemplarsList() {
             return exemplars_;
           }
           /**
      @@ -5566,7 +5566,7 @@ public java.util.Listrepeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getExemplarsOrBuilderList() {
             return exemplars_;
           }
      @@ -5589,7 +5589,7 @@ public int getExemplarsCount() {
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplars(int index) {
             return exemplars_.get(index);
           }
           /**
      @@ -5600,7 +5600,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
            * repeated .io.prometheus.client.Exemplar exemplars = 16;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
               int index) {
             return exemplars_.get(index);
           }
      @@ -5764,10 +5764,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram) obj;
       
             if (hasSampleCount() != other.hasSampleCount()) return false;
             if (hasSampleCount()) {
      @@ -5915,44 +5915,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5960,26 +5960,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -5992,7 +5992,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -6013,21 +6013,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -6101,17 +6101,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -6119,15 +6119,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram result) {
               if (bucketBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   bucket_ = java.util.Collections.unmodifiableList(bucket_);
      @@ -6166,7 +6166,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -6224,16 +6224,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance()) return this;
               if (other.hasSampleCount()) {
                 setSampleCount(other.getSampleCount());
               }
      @@ -6443,9 +6443,9 @@ public Builder mergeFrom(
                       break;
                     } // case 17
                     case 26: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.parser(),
                               extensionRegistry);
                       if (bucketBuilder_ == null) {
                         ensureBucketIsMutable();
      @@ -6481,9 +6481,9 @@ public Builder mergeFrom(
                       break;
                     } // case 65
                     case 74: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (negativeSpanBuilder_ == null) {
                         ensureNegativeSpanIsMutable();
      @@ -6527,9 +6527,9 @@ public Builder mergeFrom(
                       break;
                     } // case 90
                     case 98: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.parser(),
                               extensionRegistry);
                       if (positiveSpanBuilder_ == null) {
                         ensurePositiveSpanIsMutable();
      @@ -6580,9 +6580,9 @@ public Builder mergeFrom(
                       break;
                     } // case 122
                     case 130: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.parser(),
                               extensionRegistry);
                       if (exemplarsBuilder_ == null) {
                         ensureExemplarsIsMutable();
      @@ -6745,17 +6745,17 @@ public Builder clearSampleSum() {
               return this;
             }
       
      -      private java.util.List bucket_ =
      +      private java.util.List bucket_ =
               java.util.Collections.emptyList();
             private void ensureBucketIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          bucket_ = new java.util.ArrayList(bucket_);
      +          bucket_ = new java.util.ArrayList(bucket_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder> bucketBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder> bucketBuilder_;
       
             /**
              * 
      @@ -6764,7 +6764,7 @@ private void ensureBucketIsMutable() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List getBucketList() {
      +      public java.util.List getBucketList() {
               if (bucketBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(bucket_);
               } else {
      @@ -6792,7 +6792,7 @@ public int getBucketCount() {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getBucket(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getBucket(int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);
               } else {
      @@ -6807,7 +6807,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6828,7 +6828,7 @@ public Builder setBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder setBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.set(index, builderForValue.build());
      @@ -6845,7 +6845,7 @@ public Builder setBucket(
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
      +      public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6866,7 +6866,7 @@ public Builder addBucket(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket value) {
               if (bucketBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -6887,7 +6887,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(builderForValue.build());
      @@ -6905,7 +6905,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addBucket(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder builderForValue) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 bucket_.add(index, builderForValue.build());
      @@ -6923,7 +6923,7 @@ public Builder addBucket(
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
             public Builder addAllBucket(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (bucketBuilder_ == null) {
                 ensureBucketIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -6975,7 +6975,7 @@ public Builder removeBucket(int index) {
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder getBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder getBucketBuilder(
                 int index) {
               return internalGetBucketFieldBuilder().getBuilder(index);
             }
      @@ -6986,7 +6986,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder getBucketOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder getBucketOrBuilder(
                 int index) {
               if (bucketBuilder_ == null) {
                 return bucket_.get(index);  } else {
      @@ -7000,7 +7000,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketOrBuilderList() {
               if (bucketBuilder_ != null) {
                 return bucketBuilder_.getMessageOrBuilderList();
      @@ -7015,9 +7015,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder addBucketBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder addBucketBuilder() {
               return internalGetBucketFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7026,10 +7026,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder addBucketBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder addBucketBuilder(
                 int index) {
               return internalGetBucketFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.getDefaultInstance());
             }
             /**
              * 
      @@ -7038,16 +7038,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Bucket bucket = 3;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getBucketBuilderList() {
               return internalGetBucketFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder> 
                 internalGetBucketFieldBuilder() {
               if (bucketBuilder_ == null) {
                 bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder>(
                         bucket_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -7418,17 +7418,17 @@ public Builder clearZeroCountFloat() {
               return this;
             }
       
      -      private java.util.List negativeSpan_ =
      +      private java.util.List negativeSpan_ =
               java.util.Collections.emptyList();
             private void ensureNegativeSpanIsMutable() {
               if (!((bitField0_ & 0x00000200) != 0)) {
      -          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
      +          negativeSpan_ = new java.util.ArrayList(negativeSpan_);
                 bitField0_ |= 0x00000200;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder> negativeSpanBuilder_;
       
             /**
              * 
      @@ -7437,7 +7437,7 @@ private void ensureNegativeSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List getNegativeSpanList() {
      +      public java.util.List getNegativeSpanList() {
               if (negativeSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(negativeSpan_);
               } else {
      @@ -7465,7 +7465,7 @@ public int getNegativeSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getNegativeSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getNegativeSpan(int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);
               } else {
      @@ -7480,7 +7480,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7501,7 +7501,7 @@ public Builder setNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder setNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.set(index, builderForValue.build());
      @@ -7518,7 +7518,7 @@ public Builder setNegativeSpan(
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +      public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7539,7 +7539,7 @@ public Builder addNegativeSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (negativeSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -7560,7 +7560,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(builderForValue.build());
      @@ -7578,7 +7578,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addNegativeSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 negativeSpan_.add(index, builderForValue.build());
      @@ -7596,7 +7596,7 @@ public Builder addNegativeSpan(
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
             public Builder addAllNegativeSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (negativeSpanBuilder_ == null) {
                 ensureNegativeSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -7648,7 +7648,7 @@ public Builder removeNegativeSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder getNegativeSpanBuilder(
                 int index) {
               return internalGetNegativeSpanFieldBuilder().getBuilder(index);
             }
      @@ -7659,7 +7659,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getNegativeSpanOrBuilder(
                 int index) {
               if (negativeSpanBuilder_ == null) {
                 return negativeSpan_.get(index);  } else {
      @@ -7673,7 +7673,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanOrBuilderList() {
               if (negativeSpanBuilder_ != null) {
                 return negativeSpanBuilder_.getMessageOrBuilderList();
      @@ -7688,9 +7688,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder() {
               return internalGetNegativeSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7699,10 +7699,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder addNegativeSpanBuilder(
                 int index) {
               return internalGetNegativeSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -7711,16 +7711,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan negative_span = 9;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getNegativeSpanBuilderList() {
               return internalGetNegativeSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder> 
                 internalGetNegativeSpanFieldBuilder() {
               if (negativeSpanBuilder_ == null) {
                 negativeSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder>(
                         negativeSpan_,
                         ((bitField0_ & 0x00000200) != 0),
                         getParentForChildren(),
      @@ -7974,17 +7974,17 @@ public Builder clearNegativeCount() {
               return this;
             }
       
      -      private java.util.List positiveSpan_ =
      +      private java.util.List positiveSpan_ =
               java.util.Collections.emptyList();
             private void ensurePositiveSpanIsMutable() {
               if (!((bitField0_ & 0x00001000) != 0)) {
      -          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
      +          positiveSpan_ = new java.util.ArrayList(positiveSpan_);
                 bitField0_ |= 0x00001000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder> positiveSpanBuilder_;
       
             /**
              * 
      @@ -7996,7 +7996,7 @@ private void ensurePositiveSpanIsMutable() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List getPositiveSpanList() {
      +      public java.util.List getPositiveSpanList() {
               if (positiveSpanBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(positiveSpan_);
               } else {
      @@ -8030,7 +8030,7 @@ public int getPositiveSpanCount() {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getPositiveSpan(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getPositiveSpan(int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);
               } else {
      @@ -8048,7 +8048,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8072,7 +8072,7 @@ public Builder setPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder setPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.set(index, builderForValue.build());
      @@ -8092,7 +8092,7 @@ public Builder setPositiveSpan(
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +      public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8116,7 +8116,7 @@ public Builder addPositiveSpan(io.prometheus.metrics.expositionformats.generated
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan value) {
               if (positiveSpanBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8140,7 +8140,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(builderForValue.build());
      @@ -8161,7 +8161,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addPositiveSpan(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder builderForValue) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 positiveSpan_.add(index, builderForValue.build());
      @@ -8182,7 +8182,7 @@ public Builder addPositiveSpan(
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
             public Builder addAllPositiveSpan(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (positiveSpanBuilder_ == null) {
                 ensurePositiveSpanIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8243,7 +8243,7 @@ public Builder removePositiveSpan(int index) {
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder getPositiveSpanBuilder(
                 int index) {
               return internalGetPositiveSpanFieldBuilder().getBuilder(index);
             }
      @@ -8257,7 +8257,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder getPositiveSpanOrBuilder(
                 int index) {
               if (positiveSpanBuilder_ == null) {
                 return positiveSpan_.get(index);  } else {
      @@ -8274,7 +8274,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanOrBuilderList() {
               if (positiveSpanBuilder_ != null) {
                 return positiveSpanBuilder_.getMessageOrBuilderList();
      @@ -8292,9 +8292,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder() {
               return internalGetPositiveSpanFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8306,10 +8306,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder addPositiveSpanBuilder(
                 int index) {
               return internalGetPositiveSpanFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance());
             }
             /**
              * 
      @@ -8321,16 +8321,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.BucketSpan positive_span = 12;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getPositiveSpanBuilderList() {
               return internalGetPositiveSpanFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder> 
                 internalGetPositiveSpanFieldBuilder() {
               if (positiveSpanBuilder_ == null) {
                 positiveSpanBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder>(
                         positiveSpan_,
                         ((bitField0_ & 0x00001000) != 0),
                         getParentForChildren(),
      @@ -8584,17 +8584,17 @@ public Builder clearPositiveCount() {
               return this;
             }
       
      -      private java.util.List exemplars_ =
      +      private java.util.List exemplars_ =
               java.util.Collections.emptyList();
             private void ensureExemplarsIsMutable() {
               if (!((bitField0_ & 0x00008000) != 0)) {
      -          exemplars_ = new java.util.ArrayList(exemplars_);
      +          exemplars_ = new java.util.ArrayList(exemplars_);
                 bitField0_ |= 0x00008000;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> exemplarsBuilder_;
       
             /**
              * 
      @@ -8603,7 +8603,7 @@ private void ensureExemplarsIsMutable() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List getExemplarsList() {
      +      public java.util.List getExemplarsList() {
               if (exemplarsBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(exemplars_);
               } else {
      @@ -8631,7 +8631,7 @@ public int getExemplarsCount() {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplars(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplars(int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);
               } else {
      @@ -8646,7 +8646,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8667,7 +8667,7 @@ public Builder setExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder setExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.set(index, builderForValue.build());
      @@ -8684,7 +8684,7 @@ public Builder setExemplars(
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
      +      public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8705,7 +8705,7 @@ public Builder addExemplars(io.prometheus.metrics.expositionformats.generated.co
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) {
               if (exemplarsBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -8726,7 +8726,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(builderForValue.build());
      @@ -8744,7 +8744,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addExemplars(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 exemplars_.add(index, builderForValue.build());
      @@ -8762,7 +8762,7 @@ public Builder addExemplars(
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
             public Builder addAllExemplars(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (exemplarsBuilder_ == null) {
                 ensureExemplarsIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -8814,7 +8814,7 @@ public Builder removeExemplars(int index) {
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder getExemplarsBuilder(
                 int index) {
               return internalGetExemplarsFieldBuilder().getBuilder(index);
             }
      @@ -8825,7 +8825,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarsOrBuilder(
                 int index) {
               if (exemplarsBuilder_ == null) {
                 return exemplars_.get(index);  } else {
      @@ -8839,7 +8839,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsOrBuilderList() {
               if (exemplarsBuilder_ != null) {
                 return exemplarsBuilder_.getMessageOrBuilderList();
      @@ -8854,9 +8854,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder addExemplarsBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder addExemplarsBuilder() {
               return internalGetExemplarsFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8865,10 +8865,10 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder addExemplarsBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder addExemplarsBuilder(
                 int index) {
               return internalGetExemplarsFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance());
             }
             /**
              * 
      @@ -8877,16 +8877,16 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              *
              * repeated .io.prometheus.client.Exemplar exemplars = 16;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getExemplarsBuilderList() {
               return internalGetExemplarsFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> 
                 internalGetExemplarsFieldBuilder() {
               if (exemplarsBuilder_ == null) {
                 exemplarsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder>(
                         exemplars_,
                         ((bitField0_ & 0x00008000) != 0),
                         getParentForChildren(),
      @@ -8900,12 +8900,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -8941,7 +8941,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9017,11 +9017,11 @@ public interface BucketOrBuilder extends
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return The exemplar.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar();
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder();
         }
         /**
          * 
      @@ -9041,7 +9041,7 @@ public static final class Bucket extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Bucket.class.getName());
           }
      @@ -9054,15 +9054,15 @@ private Bucket() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder.class);
           }
       
           private int bitField0_;
      @@ -9148,7 +9148,7 @@ public double getUpperBound() {
           }
       
           public static final int EXEMPLAR_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar exemplar_;
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            * @return Whether the exemplar field is set.
      @@ -9162,15 +9162,15 @@ public boolean hasExemplar() {
            * @return The exemplar.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
           /**
            * optional .io.prometheus.client.Exemplar exemplar = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      -      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
           }
       
           private byte memoizedIsInitialized = -1;
      @@ -9234,10 +9234,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket) obj;
       
             if (hasCumulativeCount() != other.hasCumulativeCount()) return false;
             if (hasCumulativeCount()) {
      @@ -9296,44 +9296,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9341,26 +9341,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -9373,7 +9373,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -9399,21 +9399,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -9447,17 +9447,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -9465,14 +9465,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -9498,16 +9498,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket.getDefaultInstance()) return this;
               if (other.hasCumulativeCount()) {
                 setCumulativeCount(other.getCumulativeCount());
               }
      @@ -9753,9 +9753,9 @@ public Builder clearUpperBound() {
               return this;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar exemplar_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar exemplar_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> exemplarBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> exemplarBuilder_;
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return Whether the exemplar field is set.
      @@ -9767,9 +9767,9 @@ public boolean hasExemplar() {
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              * @return The exemplar.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getExemplar() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getExemplar() {
               if (exemplarBuilder_ == null) {
      -          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +          return exemplar_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               } else {
                 return exemplarBuilder_.getMessage();
               }
      @@ -9777,7 +9777,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
      +      public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -9794,7 +9794,7 @@ public Builder setExemplar(io.prometheus.metrics.expositionformats.generated.com
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             public Builder setExemplar(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder builderForValue) {
               if (exemplarBuilder_ == null) {
                 exemplar_ = builderForValue.build();
               } else {
      @@ -9807,11 +9807,11 @@ public Builder setExemplar(
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar value) {
      +      public Builder mergeExemplar(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar value) {
               if (exemplarBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   exemplar_ != null &&
      -            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) {
      +            exemplar_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance()) {
                   getExemplarBuilder().mergeFrom(value);
                 } else {
                   exemplar_ = value;
      @@ -9841,7 +9841,7 @@ public Builder clearExemplar() {
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder getExemplarBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder getExemplarBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return internalGetExemplarFieldBuilder().getBuilder();
      @@ -9849,23 +9849,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder getExemplarOrBuilder() {
               if (exemplarBuilder_ != null) {
                 return exemplarBuilder_.getMessageOrBuilder();
               } else {
                 return exemplar_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance() : exemplar_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance() : exemplar_;
               }
             }
             /**
              * optional .io.prometheus.client.Exemplar exemplar = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder> 
                 internalGetExemplarFieldBuilder() {
               if (exemplarBuilder_ == null) {
                 exemplarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder>(
                         getExemplar(),
                         getParentForChildren(),
                         isClean());
      @@ -9878,12 +9878,12 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9919,7 +9919,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Bucket getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Bucket getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -9989,7 +9989,7 @@ public static final class BucketSpan extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               BucketSpan.class.getName());
           }
      @@ -10002,15 +10002,15 @@ private BucketSpan() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder.class);
           }
       
           private int bitField0_;
      @@ -10115,10 +10115,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan) obj;
       
             if (hasOffset() != other.hasOffset()) return false;
             if (hasOffset()) {
      @@ -10154,44 +10154,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10199,26 +10199,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10231,7 +10231,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10261,21 +10261,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.BucketSpan)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpanOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpanOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_BucketSpan_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.newBuilder()
             private Builder() {
       
             }
      @@ -10297,17 +10297,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_BucketSpan_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -10315,14 +10315,14 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan(this);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -10338,16 +10338,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan.getDefaultInstance()) return this;
               if (other.hasOffset()) {
                 setOffset(other.getOffset());
               }
      @@ -10523,12 +10523,12 @@ public Builder clearLength() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.BucketSpan)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10564,7 +10564,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.BucketSpan getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.BucketSpan getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -10577,12 +10577,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -10590,12 +10590,12 @@ public interface ExemplarOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -10649,7 +10649,7 @@ public static final class Exemplar extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Exemplar.class.getName());
           }
      @@ -10663,33 +10663,33 @@ private Exemplar() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -10704,14 +10704,14 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
      @@ -10827,10 +10827,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -10874,44 +10874,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10919,26 +10919,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -10951,7 +10951,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -10972,21 +10972,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Exemplar)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.ExemplarOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.ExemplarOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Exemplar_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -11026,17 +11026,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Exemplar_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -11044,15 +11044,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -11064,7 +11064,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -11082,16 +11082,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -11151,9 +11151,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -11192,22 +11192,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -11227,7 +11227,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -11238,7 +11238,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11255,7 +11255,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -11268,7 +11268,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11285,7 +11285,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -11302,7 +11302,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -11316,7 +11316,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -11330,7 +11330,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -11370,14 +11370,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -11387,7 +11387,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -11398,31 +11398,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return internalGetLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder> 
                 internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -11633,12 +11633,12 @@ public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Exemplar)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11674,7 +11674,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Exemplar getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Exemplar getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -11687,12 +11687,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index);
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      @@ -11700,12 +11700,12 @@ public interface MetricOrBuilder extends
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    java.util.List 
      +    java.util.List 
               getLabelOrBuilderList();
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index);
       
           /**
      @@ -11717,11 +11717,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return The gauge.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getGauge();
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder getGaugeOrBuilder();
       
           /**
            * optional .io.prometheus.client.Counter counter = 3;
      @@ -11732,11 +11732,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            * optional .io.prometheus.client.Counter counter = 3;
            * @return The counter.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getCounter();
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder getCounterOrBuilder();
       
           /**
            * optional .io.prometheus.client.Summary summary = 4;
      @@ -11747,11 +11747,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            * optional .io.prometheus.client.Summary summary = 4;
            * @return The summary.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getSummary();
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder getSummaryOrBuilder();
       
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
      @@ -11762,11 +11762,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return The untyped.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getUntyped();
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder getUntypedOrBuilder();
       
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
      @@ -11777,11 +11777,11 @@ io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Met
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return The histogram.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getHistogram();
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder getHistogramOrBuilder();
       
           /**
            * optional int64 timestamp_ms = 6;
      @@ -11807,7 +11807,7 @@ public static final class Metric extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               Metric.class.getName());
           }
      @@ -11821,33 +11821,33 @@ private Metric() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder.class);
           }
       
           private int bitField0_;
           public static final int LABEL_FIELD_NUMBER = 1;
           @SuppressWarnings("serial")
      -    private java.util.List label_;
      +    private java.util.List label_;
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List getLabelList() {
      +    public java.util.List getLabelList() {
             return label_;
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getLabelOrBuilderList() {
             return label_;
           }
      @@ -11862,20 +11862,20 @@ public int getLabelCount() {
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index) {
             return label_.get(index);
           }
           /**
            * repeated .io.prometheus.client.LabelPair label = 1;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
               int index) {
             return label_.get(index);
           }
       
           public static final int GAUGE_FIELD_NUMBER = 2;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge gauge_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge gauge_;
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            * @return Whether the gauge field is set.
      @@ -11889,19 +11889,19 @@ public boolean hasGauge() {
            * @return The gauge.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getGauge() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
           /**
            * optional .io.prometheus.client.Gauge gauge = 2;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      -      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance() : gauge_;
           }
       
           public static final int COUNTER_FIELD_NUMBER = 3;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter counter_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter counter_;
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            * @return Whether the counter field is set.
      @@ -11915,19 +11915,19 @@ public boolean hasCounter() {
            * @return The counter.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getCounter() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
           /**
            * optional .io.prometheus.client.Counter counter = 3;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      -      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance() : counter_;
           }
       
           public static final int SUMMARY_FIELD_NUMBER = 4;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary summary_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary summary_;
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            * @return Whether the summary field is set.
      @@ -11941,19 +11941,19 @@ public boolean hasSummary() {
            * @return The summary.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getSummary() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
           /**
            * optional .io.prometheus.client.Summary summary = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      -      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance() : summary_;
           }
       
           public static final int UNTYPED_FIELD_NUMBER = 5;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped untyped_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped untyped_;
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            * @return Whether the untyped field is set.
      @@ -11967,19 +11967,19 @@ public boolean hasUntyped() {
            * @return The untyped.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getUntyped() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
           /**
            * optional .io.prometheus.client.Untyped untyped = 5;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      -      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance() : untyped_;
           }
       
           public static final int HISTOGRAM_FIELD_NUMBER = 7;
      -    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram histogram_;
      +    private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram histogram_;
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            * @return Whether the histogram field is set.
      @@ -11993,15 +11993,15 @@ public boolean hasHistogram() {
            * @return The histogram.
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getHistogram() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
           /**
            * optional .io.prometheus.client.Histogram histogram = 7;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      -      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance() : histogram_;
           }
       
           public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
      @@ -12105,10 +12105,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric) obj;
       
             if (!getLabelList()
                 .equals(other.getLabelList())) return false;
      @@ -12187,44 +12187,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12232,26 +12232,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -12264,7 +12264,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -12285,21 +12285,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.newBuilder()
             private Builder() {
               maybeForceBuilderInitialization();
             }
      @@ -12363,17 +12363,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -12381,15 +12381,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric result) {
               if (labelBuilder_ == null) {
                 if (((bitField0_ & 0x00000001) != 0)) {
                   label_ = java.util.Collections.unmodifiableList(label_);
      @@ -12401,7 +12401,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000002) != 0)) {
      @@ -12443,16 +12443,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.getDefaultInstance()) return this;
               if (labelBuilder_ == null) {
                 if (!other.label_.isEmpty()) {
                   if (label_.isEmpty()) {
      @@ -12524,9 +12524,9 @@ public Builder mergeFrom(
                       done = true;
                       break;
                     case 10: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.parser(),
                               extensionRegistry);
                       if (labelBuilder_ == null) {
                         ensureLabelIsMutable();
      @@ -12593,22 +12593,22 @@ public Builder mergeFrom(
             }
             private int bitField0_;
       
      -      private java.util.List label_ =
      +      private java.util.List label_ =
               java.util.Collections.emptyList();
             private void ensureLabelIsMutable() {
               if (!((bitField0_ & 0x00000001) != 0)) {
      -          label_ = new java.util.ArrayList(label_);
      +          label_ = new java.util.ArrayList(label_);
                 bitField0_ |= 0x00000001;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> labelBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder> labelBuilder_;
       
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List getLabelList() {
      +      public java.util.List getLabelList() {
               if (labelBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(label_);
               } else {
      @@ -12628,7 +12628,7 @@ public int getLabelCount() {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair getLabel(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair getLabel(int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);
               } else {
      @@ -12639,7 +12639,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12656,7 +12656,7 @@ public Builder setLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder setLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.set(index, builderForValue.build());
      @@ -12669,7 +12669,7 @@ public Builder setLabel(
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +      public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12686,7 +12686,7 @@ public Builder addLabel(io.prometheus.metrics.expositionformats.generated.com_go
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair value) {
               if (labelBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12703,7 +12703,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(builderForValue.build());
      @@ -12717,7 +12717,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addLabel(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder builderForValue) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 label_.add(index, builderForValue.build());
      @@ -12731,7 +12731,7 @@ public Builder addLabel(
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
             public Builder addAllLabel(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (labelBuilder_ == null) {
                 ensureLabelIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -12771,14 +12771,14 @@ public Builder removeLabel(int index) {
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder getLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder getLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder getLabelOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder getLabelOrBuilder(
                 int index) {
               if (labelBuilder_ == null) {
                 return label_.get(index);  } else {
      @@ -12788,7 +12788,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelOrBuilderList() {
               if (labelBuilder_ != null) {
                 return labelBuilder_.getMessageOrBuilderList();
      @@ -12799,31 +12799,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder addLabelBuilder() {
               return internalGetLabelFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder addLabelBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder addLabelBuilder(
                 int index) {
               return internalGetLabelFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.LabelPair label = 1;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getLabelBuilderList() {
               return internalGetLabelFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder> 
                 internalGetLabelFieldBuilder() {
               if (labelBuilder_ == null) {
                 labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.LabelPairOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPair.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.LabelPairOrBuilder>(
                         label_,
                         ((bitField0_ & 0x00000001) != 0),
                         getParentForChildren(),
      @@ -12833,9 +12833,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return labelBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge gauge_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge gauge_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder> gaugeBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder> gaugeBuilder_;
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return Whether the gauge field is set.
      @@ -12847,9 +12847,9 @@ public boolean hasGauge() {
              * optional .io.prometheus.client.Gauge gauge = 2;
              * @return The gauge.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge getGauge() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge getGauge() {
               if (gaugeBuilder_ == null) {
      -          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +          return gauge_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               } else {
                 return gaugeBuilder_.getMessage();
               }
      @@ -12857,7 +12857,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge value) {
      +      public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12874,7 +12874,7 @@ public Builder setGauge(io.prometheus.metrics.expositionformats.generated.com_go
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             public Builder setGauge(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder builderForValue) {
               if (gaugeBuilder_ == null) {
                 gauge_ = builderForValue.build();
               } else {
      @@ -12887,11 +12887,11 @@ public Builder setGauge(
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge value) {
      +      public Builder mergeGauge(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge value) {
               if (gaugeBuilder_ == null) {
                 if (((bitField0_ & 0x00000002) != 0) &&
                   gauge_ != null &&
      -            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance()) {
      +            gauge_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance()) {
                   getGaugeBuilder().mergeFrom(value);
                 } else {
                   gauge_ = value;
      @@ -12921,7 +12921,7 @@ public Builder clearGauge() {
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder getGaugeBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder getGaugeBuilder() {
               bitField0_ |= 0x00000002;
               onChanged();
               return internalGetGaugeFieldBuilder().getBuilder();
      @@ -12929,23 +12929,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
               if (gaugeBuilder_ != null) {
                 return gaugeBuilder_.getMessageOrBuilder();
               } else {
                 return gauge_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.getDefaultInstance() : gauge_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.getDefaultInstance() : gauge_;
               }
             }
             /**
              * optional .io.prometheus.client.Gauge gauge = 2;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder> 
                 internalGetGaugeFieldBuilder() {
               if (gaugeBuilder_ == null) {
                 gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.GaugeOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Gauge.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.GaugeOrBuilder>(
                         getGauge(),
                         getParentForChildren(),
                         isClean());
      @@ -12954,9 +12954,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return gaugeBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter counter_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter counter_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder> counterBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder> counterBuilder_;
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              * @return Whether the counter field is set.
      @@ -12968,9 +12968,9 @@ public boolean hasCounter() {
              * optional .io.prometheus.client.Counter counter = 3;
              * @return The counter.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter getCounter() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter getCounter() {
               if (counterBuilder_ == null) {
      -          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
      +          return counter_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance() : counter_;
               } else {
                 return counterBuilder_.getMessage();
               }
      @@ -12978,7 +12978,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter value) {
      +      public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -12995,7 +12995,7 @@ public Builder setCounter(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Counter counter = 3;
              */
             public Builder setCounter(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder builderForValue) {
               if (counterBuilder_ == null) {
                 counter_ = builderForValue.build();
               } else {
      @@ -13008,11 +13008,11 @@ public Builder setCounter(
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter value) {
      +      public Builder mergeCounter(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter value) {
               if (counterBuilder_ == null) {
                 if (((bitField0_ & 0x00000004) != 0) &&
                   counter_ != null &&
      -            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance()) {
      +            counter_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance()) {
                   getCounterBuilder().mergeFrom(value);
                 } else {
                   counter_ = value;
      @@ -13042,7 +13042,7 @@ public Builder clearCounter() {
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder getCounterBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder getCounterBuilder() {
               bitField0_ |= 0x00000004;
               onChanged();
               return internalGetCounterFieldBuilder().getBuilder();
      @@ -13050,23 +13050,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder getCounterOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder getCounterOrBuilder() {
               if (counterBuilder_ != null) {
                 return counterBuilder_.getMessageOrBuilder();
               } else {
                 return counter_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.getDefaultInstance() : counter_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.getDefaultInstance() : counter_;
               }
             }
             /**
              * optional .io.prometheus.client.Counter counter = 3;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder> 
                 internalGetCounterFieldBuilder() {
               if (counterBuilder_ == null) {
                 counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.CounterOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Counter.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.CounterOrBuilder>(
                         getCounter(),
                         getParentForChildren(),
                         isClean());
      @@ -13075,9 +13075,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return counterBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary summary_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary summary_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder> summaryBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder> summaryBuilder_;
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              * @return Whether the summary field is set.
      @@ -13089,9 +13089,9 @@ public boolean hasSummary() {
              * optional .io.prometheus.client.Summary summary = 4;
              * @return The summary.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary getSummary() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary getSummary() {
               if (summaryBuilder_ == null) {
      -          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
      +          return summary_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance() : summary_;
               } else {
                 return summaryBuilder_.getMessage();
               }
      @@ -13099,7 +13099,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary value) {
      +      public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13116,7 +13116,7 @@ public Builder setSummary(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Summary summary = 4;
              */
             public Builder setSummary(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder builderForValue) {
               if (summaryBuilder_ == null) {
                 summary_ = builderForValue.build();
               } else {
      @@ -13129,11 +13129,11 @@ public Builder setSummary(
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary value) {
      +      public Builder mergeSummary(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary value) {
               if (summaryBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0) &&
                   summary_ != null &&
      -            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance()) {
      +            summary_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance()) {
                   getSummaryBuilder().mergeFrom(value);
                 } else {
                   summary_ = value;
      @@ -13163,7 +13163,7 @@ public Builder clearSummary() {
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder getSummaryBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder getSummaryBuilder() {
               bitField0_ |= 0x00000008;
               onChanged();
               return internalGetSummaryFieldBuilder().getBuilder();
      @@ -13171,23 +13171,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
               if (summaryBuilder_ != null) {
                 return summaryBuilder_.getMessageOrBuilder();
               } else {
                 return summary_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.getDefaultInstance() : summary_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.getDefaultInstance() : summary_;
               }
             }
             /**
              * optional .io.prometheus.client.Summary summary = 4;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder> 
                 internalGetSummaryFieldBuilder() {
               if (summaryBuilder_ == null) {
                 summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.SummaryOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Summary.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.SummaryOrBuilder>(
                         getSummary(),
                         getParentForChildren(),
                         isClean());
      @@ -13196,9 +13196,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return summaryBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped untyped_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped untyped_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder> untypedBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder> untypedBuilder_;
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return Whether the untyped field is set.
      @@ -13210,9 +13210,9 @@ public boolean hasUntyped() {
              * optional .io.prometheus.client.Untyped untyped = 5;
              * @return The untyped.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped getUntyped() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped getUntyped() {
               if (untypedBuilder_ == null) {
      -          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +          return untyped_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               } else {
                 return untypedBuilder_.getMessage();
               }
      @@ -13220,7 +13220,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped value) {
      +      public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13237,7 +13237,7 @@ public Builder setUntyped(io.prometheus.metrics.expositionformats.generated.com_
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             public Builder setUntyped(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder builderForValue) {
               if (untypedBuilder_ == null) {
                 untyped_ = builderForValue.build();
               } else {
      @@ -13250,11 +13250,11 @@ public Builder setUntyped(
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped value) {
      +      public Builder mergeUntyped(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped value) {
               if (untypedBuilder_ == null) {
                 if (((bitField0_ & 0x00000010) != 0) &&
                   untyped_ != null &&
      -            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance()) {
      +            untyped_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance()) {
                   getUntypedBuilder().mergeFrom(value);
                 } else {
                   untyped_ = value;
      @@ -13284,7 +13284,7 @@ public Builder clearUntyped() {
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder getUntypedBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder getUntypedBuilder() {
               bitField0_ |= 0x00000010;
               onChanged();
               return internalGetUntypedFieldBuilder().getBuilder();
      @@ -13292,23 +13292,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
               if (untypedBuilder_ != null) {
                 return untypedBuilder_.getMessageOrBuilder();
               } else {
                 return untyped_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.getDefaultInstance() : untyped_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.getDefaultInstance() : untyped_;
               }
             }
             /**
              * optional .io.prometheus.client.Untyped untyped = 5;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder> 
                 internalGetUntypedFieldBuilder() {
               if (untypedBuilder_ == null) {
                 untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.UntypedOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Untyped.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.UntypedOrBuilder>(
                         getUntyped(),
                         getParentForChildren(),
                         isClean());
      @@ -13317,9 +13317,9 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
               return untypedBuilder_;
             }
       
      -      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram histogram_;
      +      private io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram histogram_;
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder> histogramBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder> histogramBuilder_;
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return Whether the histogram field is set.
      @@ -13331,9 +13331,9 @@ public boolean hasHistogram() {
              * optional .io.prometheus.client.Histogram histogram = 7;
              * @return The histogram.
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram getHistogram() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram getHistogram() {
               if (histogramBuilder_ == null) {
      -          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +          return histogram_ == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               } else {
                 return histogramBuilder_.getMessage();
               }
      @@ -13341,7 +13341,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram value) {
      +      public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -13358,7 +13358,7 @@ public Builder setHistogram(io.prometheus.metrics.expositionformats.generated.co
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             public Builder setHistogram(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder builderForValue) {
               if (histogramBuilder_ == null) {
                 histogram_ = builderForValue.build();
               } else {
      @@ -13371,11 +13371,11 @@ public Builder setHistogram(
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram value) {
      +      public Builder mergeHistogram(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram value) {
               if (histogramBuilder_ == null) {
                 if (((bitField0_ & 0x00000020) != 0) &&
                   histogram_ != null &&
      -            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance()) {
      +            histogram_ != io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance()) {
                   getHistogramBuilder().mergeFrom(value);
                 } else {
                   histogram_ = value;
      @@ -13405,7 +13405,7 @@ public Builder clearHistogram() {
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder getHistogramBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder getHistogramBuilder() {
               bitField0_ |= 0x00000020;
               onChanged();
               return internalGetHistogramFieldBuilder().getBuilder();
      @@ -13413,23 +13413,23 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
               if (histogramBuilder_ != null) {
                 return histogramBuilder_.getMessageOrBuilder();
               } else {
                 return histogram_ == null ?
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.getDefaultInstance() : histogram_;
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.getDefaultInstance() : histogram_;
               }
             }
             /**
              * optional .io.prometheus.client.Histogram histogram = 7;
              */
             private com.google.protobuf.SingleFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder> 
                 internalGetHistogramFieldBuilder() {
               if (histogramBuilder_ == null) {
                 histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.HistogramOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Histogram.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.HistogramOrBuilder>(
                         getHistogram(),
                         getParentForChildren(),
                         isClean());
      @@ -13482,12 +13482,12 @@ public Builder clearTimestampMs() {
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13523,7 +13523,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -13576,17 +13576,17 @@ public interface MetricFamilyOrBuilder extends
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType();
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType getType();
       
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index);
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getMetric(int index);
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      @@ -13594,12 +13594,12 @@ public interface MetricFamilyOrBuilder extends
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    java.util.List 
      +    java.util.List 
               getMetricOrBuilderList();
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
      -    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index);
       
           /**
      @@ -13632,7 +13632,7 @@ public static final class MetricFamily extends
               com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,
               /* major= */ 4,
               /* minor= */ 30,
      -        /* patch= */ 1,
      +        /* patch= */ 2,
               /* suffix= */ "",
               MetricFamily.class.getName());
           }
      @@ -13650,15 +13650,15 @@ private MetricFamily() {
       
           public static final com.google.protobuf.Descriptors.Descriptor
               getDescriptor() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
           }
       
           @java.lang.Override
           protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
               internalGetFieldAccessorTable() {
      -      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +      return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                 .ensureFieldAccessorsInitialized(
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.Builder.class);
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.Builder.class);
           }
       
           private int bitField0_;
      @@ -13773,26 +13773,26 @@ public java.lang.String getHelp() {
            * optional .io.prometheus.client.MetricType type = 3;
            * @return The type.
            */
      -    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType() {
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(type_);
      -      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.COUNTER : result;
      +    @java.lang.Override public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType getType() {
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType.forNumber(type_);
      +      return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType.COUNTER : result;
           }
       
           public static final int METRIC_FIELD_NUMBER = 4;
           @SuppressWarnings("serial")
      -    private java.util.List metric_;
      +    private java.util.List metric_;
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List getMetricList() {
      +    public java.util.List getMetricList() {
             return metric_;
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public java.util.List 
      +    public java.util.List 
               getMetricOrBuilderList() {
             return metric_;
           }
      @@ -13807,14 +13807,14 @@ public int getMetricCount() {
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index) {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getMetric(int index) {
             return metric_.get(index);
           }
           /**
            * repeated .io.prometheus.client.Metric metric = 4;
            */
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder getMetricOrBuilder(
               int index) {
             return metric_.get(index);
           }
      @@ -13933,10 +13933,10 @@ public boolean equals(final java.lang.Object obj) {
             if (obj == this) {
              return true;
             }
      -      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily)) {
      +      if (!(obj instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily)) {
               return super.equals(obj);
             }
      -      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily) obj;
      +      io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily other = (io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily) obj;
       
             if (hasName() != other.hasName()) return false;
             if (hasName()) {
      @@ -13995,44 +13995,44 @@ public int hashCode() {
             return hash;
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               java.nio.ByteBuffer data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.ByteString data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(byte[] data)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(byte[] data)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               byte[] data,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws com.google.protobuf.InvalidProtocolBufferException {
             return PARSER.parseFrom(data, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14040,26 +14040,26 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
                 .parseWithIOException(PARSER, input, extensionRegistry);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input);
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseDelimitedFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseDelimitedFrom(
               java.io.InputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input)
               throws java.io.IOException {
             return com.google.protobuf.GeneratedMessage
                 .parseWithIOException(PARSER, input);
           }
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily parseFrom(
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily parseFrom(
               com.google.protobuf.CodedInputStream input,
               com.google.protobuf.ExtensionRegistryLite extensionRegistry)
               throws java.io.IOException {
      @@ -14072,7 +14072,7 @@ public static io.prometheus.metrics.expositionformats.generated.com_google_proto
           public static Builder newBuilder() {
             return DEFAULT_INSTANCE.toBuilder();
           }
      -    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily prototype) {
      +    public static Builder newBuilder(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily prototype) {
             return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
           }
           @java.lang.Override
      @@ -14093,21 +14093,21 @@ protected Builder newBuilderForType(
           public static final class Builder extends
               com.google.protobuf.GeneratedMessage.Builder implements
               // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamilyOrBuilder {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamilyOrBuilder {
             public static final com.google.protobuf.Descriptors.Descriptor
                 getDescriptor() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
             protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
                 internalGetFieldAccessorTable() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
                   .ensureFieldAccessorsInitialized(
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.Builder.class);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.class, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.Builder.class);
             }
       
      -      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.newBuilder()
      +      // Construct using io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.newBuilder()
             private Builder() {
       
             }
      @@ -14138,17 +14138,17 @@ public Builder clear() {
             @java.lang.Override
             public com.google.protobuf.Descriptors.Descriptor
                 getDescriptorForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstanceForType() {
      -        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.getDefaultInstance();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily getDefaultInstanceForType() {
      +        return io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.getDefaultInstance();
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily build() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result = buildPartial();
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily build() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily result = buildPartial();
               if (!result.isInitialized()) {
                 throw newUninitializedMessageException(result);
               }
      @@ -14156,15 +14156,15 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             }
       
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily buildPartial() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily(this);
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily buildPartial() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily result = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily(this);
               buildPartialRepeatedFields(result);
               if (bitField0_ != 0) { buildPartial0(result); }
               onBuilt();
               return result;
             }
       
      -      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result) {
      +      private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily result) {
               if (metricBuilder_ == null) {
                 if (((bitField0_ & 0x00000008) != 0)) {
                   metric_ = java.util.Collections.unmodifiableList(metric_);
      @@ -14176,7 +14176,7 @@ private void buildPartialRepeatedFields(io.prometheus.metrics.expositionformats.
               }
             }
       
      -      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily result) {
      +      private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily result) {
               int from_bitField0_ = bitField0_;
               int to_bitField0_ = 0;
               if (((from_bitField0_ & 0x00000001) != 0)) {
      @@ -14200,16 +14200,16 @@ private void buildPartial0(io.prometheus.metrics.expositionformats.generated.com
       
             @java.lang.Override
             public Builder mergeFrom(com.google.protobuf.Message other) {
      -        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily) {
      -          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily)other);
      +        if (other instanceof io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily) {
      +          return mergeFrom((io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily)other);
               } else {
                 super.mergeFrom(other);
                 return this;
               }
             }
       
      -      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily other) {
      -        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily.getDefaultInstance()) return this;
      +      public Builder mergeFrom(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily other) {
      +        if (other == io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily.getDefaultInstance()) return this;
               if (other.hasName()) {
                 name_ = other.name_;
                 bitField0_ |= 0x00000001;
      @@ -14292,8 +14292,8 @@ public Builder mergeFrom(
                     } // case 18
                     case 24: {
                       int tmpRaw = input.readEnum();
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType tmpValue =
      -                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(tmpRaw);
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType tmpValue =
      +                    io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType.forNumber(tmpRaw);
                       if (tmpValue == null) {
                         mergeUnknownVarintField(3, tmpRaw);
                       } else {
      @@ -14303,9 +14303,9 @@ public Builder mergeFrom(
                       break;
                     } // case 24
                     case 34: {
      -                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric m =
      +                io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric m =
                           input.readMessage(
      -                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.parser(),
      +                        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.parser(),
                               extensionRegistry);
                       if (metricBuilder_ == null) {
                         ensureMetricIsMutable();
      @@ -14510,16 +14510,16 @@ public Builder setHelpBytes(
              * @return The type.
              */
             @java.lang.Override
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType getType() {
      -        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.forNumber(type_);
      -        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType.COUNTER : result;
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType getType() {
      +        io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType result = io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType.forNumber(type_);
      +        return result == null ? io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType.COUNTER : result;
             }
             /**
              * optional .io.prometheus.client.MetricType type = 3;
              * @param value The type to set.
              * @return This builder for chaining.
              */
      -      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricType value) {
      +      public Builder setType(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricType value) {
               if (value == null) {
                 throw new NullPointerException();
               }
      @@ -14539,22 +14539,22 @@ public Builder clearType() {
               return this;
             }
       
      -      private java.util.List metric_ =
      +      private java.util.List metric_ =
               java.util.Collections.emptyList();
             private void ensureMetricIsMutable() {
               if (!((bitField0_ & 0x00000008) != 0)) {
      -          metric_ = new java.util.ArrayList(metric_);
      +          metric_ = new java.util.ArrayList(metric_);
                 bitField0_ |= 0x00000008;
                }
             }
       
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder> metricBuilder_;
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder> metricBuilder_;
       
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List getMetricList() {
      +      public java.util.List getMetricList() {
               if (metricBuilder_ == null) {
                 return java.util.Collections.unmodifiableList(metric_);
               } else {
      @@ -14574,7 +14574,7 @@ public int getMetricCount() {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric getMetric(int index) {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric getMetric(int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);
               } else {
      @@ -14585,7 +14585,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14602,7 +14602,7 @@ public Builder setMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder setMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.set(index, builderForValue.build());
      @@ -14615,7 +14615,7 @@ public Builder setMetric(
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
      +      public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14632,7 +14632,7 @@ public Builder addMetric(io.prometheus.metrics.expositionformats.generated.com_g
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric value) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric value) {
               if (metricBuilder_ == null) {
                 if (value == null) {
                   throw new NullPointerException();
      @@ -14649,7 +14649,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(builderForValue.build());
      @@ -14663,7 +14663,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addMetric(
      -          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder builderForValue) {
      +          int index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder builderForValue) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 metric_.add(index, builderForValue.build());
      @@ -14677,7 +14677,7 @@ public Builder addMetric(
              * repeated .io.prometheus.client.Metric metric = 4;
              */
             public Builder addAllMetric(
      -          java.lang.Iterable values) {
      +          java.lang.Iterable values) {
               if (metricBuilder_ == null) {
                 ensureMetricIsMutable();
                 com.google.protobuf.AbstractMessageLite.Builder.addAll(
      @@ -14717,14 +14717,14 @@ public Builder removeMetric(int index) {
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder getMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder getMetricBuilder(
                 int index) {
               return internalGetMetricFieldBuilder().getBuilder(index);
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder getMetricOrBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder getMetricOrBuilder(
                 int index) {
               if (metricBuilder_ == null) {
                 return metric_.get(index);  } else {
      @@ -14734,7 +14734,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricOrBuilderList() {
               if (metricBuilder_ != null) {
                 return metricBuilder_.getMessageOrBuilderList();
      @@ -14745,31 +14745,31 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder addMetricBuilder() {
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder addMetricBuilder() {
               return internalGetMetricFieldBuilder().addBuilder(
      -            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance());
      +            io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder addMetricBuilder(
      +      public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder addMetricBuilder(
                 int index) {
               return internalGetMetricFieldBuilder().addBuilder(
      -            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.getDefaultInstance());
      +            index, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.getDefaultInstance());
             }
             /**
              * repeated .io.prometheus.client.Metric metric = 4;
              */
      -      public java.util.List 
      +      public java.util.List 
                  getMetricBuilderList() {
               return internalGetMetricFieldBuilder().getBuilderList();
             }
             private com.google.protobuf.RepeatedFieldBuilder<
      -          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder> 
      +          io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder> 
                 internalGetMetricFieldBuilder() {
               if (metricBuilder_ == null) {
                 metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
      -              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricOrBuilder>(
      +              io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.Metric.Builder, io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricOrBuilder>(
                         metric_,
                         ((bitField0_ & 0x00000008) != 0),
                         getParentForChildren(),
      @@ -14863,12 +14863,12 @@ public Builder setUnitBytes(
           }
       
           // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
      -    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily DEFAULT_INSTANCE;
      +    private static final io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily DEFAULT_INSTANCE;
           static {
      -      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily();
      +      DEFAULT_INSTANCE = new io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily();
           }
       
      -    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstance() {
      +    public static io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily getDefaultInstance() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -14904,7 +14904,7 @@ public com.google.protobuf.Parser getParserForType() {
           }
       
           @java.lang.Override
      -    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics.MetricFamily getDefaultInstanceForType() {
      +    public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics.MetricFamily getDefaultInstanceForType() {
             return DEFAULT_INSTANCE;
           }
       
      @@ -15029,7 +15029,7 @@ public io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_3
             "\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004\022\023\n\017GAUGE_H" +
             "ISTOGRAM\020\005B\212\001\nLio.prometheus.metrics.exp" +
             "ositionformats.generated.com_google_prot" +
      -      "obuf_4_30_1Z:github.com/prometheus/clien" +
      +      "obuf_4_30_2Z:github.com/prometheus/clien" +
             "t_model/go;io_prometheus_client"
           };
           descriptor = com.google.protobuf.Descriptors.FileDescriptor
      diff --git a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      index 83476ad4b..888c57ee4 100644
      --- a/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      +++ b/prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/internal/PrometheusProtobufWriterImpl.java
      @@ -4,7 +4,7 @@
       
       import com.google.protobuf.TextFormat;
       import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics;
       import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot;
       import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
      diff --git a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      index 03000712d..34dc4f163 100644
      --- a/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      +++ b/prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ProtobufExpositionFormatsTest.java
      @@ -2,7 +2,7 @@
       
       import static org.assertj.core.api.Assertions.assertThat;
       
      -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_1.Metrics;
      +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_30_2.Metrics;
       import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
       import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
       import io.prometheus.metrics.model.snapshots.MetricSnapshot;
      
      From 968de7efea42f5f228ed100ec538e42428d2ff53 Mon Sep 17 00:00:00 2001
      From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
      Date: Mon, 31 Mar 2025 16:01:54 +0200
      Subject: [PATCH 563/980] Bump org.apache.maven.plugins:maven-surefire-plugin
       from 3.5.2 to 3.5.3 (#1315)
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      Bumps
      [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire)
      from 3.5.2 to 3.5.3.
      
      Release notes

      Sourced from org.apache.maven.plugins:maven-surefire-plugin's releases.

      3.5.3

      🐛 Bug Fixes

      👻 Maintenance

      📦 Dependency updates

      Commits
      • 4434650 [maven-release-plugin] prepare release surefire-3.5.3
      • 1270950 use github directly
      • 59f3a1f release tag name backward compatible
      • dfbabe2 assertj-core must be test scope (#826)
      • e1f8119 back to 3.5.3-SNAPSHOT
      • c497559 [maven-release-plugin] prepare for next development iteration
      • 3962112 [maven-release-plugin] prepare release v3.5.3
      • 227c134 surefire shared utils version current version (#825)
      • 1d34c34 Bump org.htmlunit:htmlunit from 4.10.0 to 4.11.1
      • 906b65a Update site descriptors
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-surefire-plugin&package-manager=maven&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd239c424..95b1cf0e4 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ maven-surefire-plugin - 3.5.2 + 3.5.3 maven-jar-plugin From dc89b99b470558dff60c8e020722f8a8856b7f53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:52:46 +0200 Subject: [PATCH 564/980] Bump org.jacoco:jacoco-maven-plugin from 0.8.12 to 0.8.13 (#1318) Bumps [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) from 0.8.12 to 0.8.13.
      Release notes

      Sourced from org.jacoco:jacoco-maven-plugin's releases.

      0.8.13

      New Features

      • JaCoCo now officially supports Java 23 and Java 24 (GitHub #1757, #1631, #1867).
      • Experimental support for Java 25 class files (GitHub #1807).
      • Calculation of line coverage for Kotlin inline functions (GitHub #1670).
      • Calculation of line coverage for Kotlin inline functions with reified type parameter (GitHub #1670, #1700).
      • Calculation of coverage for Kotlin JvmSynthetic functions (GitHub #1700).
      • Part of bytecode generated by the Kotlin Compose compiler plugin is filtered out during generation of report (GitHub #1616).
      • Part of bytecode generated by the Kotlin compiler for inline value classes is filtered out during generation of report (GitHub #1475).
      • Part of bytecode generated by the Kotlin compiler for suspending lambdas without suspension points is filtered out during generation of report (GitHub #1283).
      • Part of bytecode generated by the Kotlin compiler for when expressions and statements with nullable enum subject is filtered out during generation of report (GitHub #1774).
      • Part of bytecode generated by the Kotlin compiler for when expressions and statements with nullable String subject is filtered out during generation of report (GitHub #1769).
      • Part of bytecode generated by the Kotlin compiler for chains of safe call operators is filtered out during generation of report (GitHub #1810, #1818).
      • Method getEntries generated by the Kotlin compiler for enum classes is filtered out during generation of report (GitHub #1625).
      • Methods generated by the Kotlin compiler for constructors and functions with JvmOverloads annotation are filtered out (GitHub #1768).

      Fixed bugs

      • Fixed interpretation of Kotlin SMAP (GitHub #1525).
      • File extensions are preserved in HTML report in case of clashes of normalized file names (GitHub #1660).

      Non-functional Changes

      • JaCoCo build now uses Maven Wrapper and requires at least Maven 3.9.9 (GitHub #1708, #1707, #1681).
      • JaCoCo now depends on ASM 9.8 (GitHub #1862).
      • More context information when IllegalArgumentException occurs during reading of zip file (GitHub #1833).
      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.jacoco:jacoco-maven-plugin&package-manager=maven&previous-version=0.8.12&new-version=0.8.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 95b1cf0e4..48a0f0f98 100644 --- a/pom.xml +++ b/pom.xml @@ -263,7 +263,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 ${coverage.skip} From c57106dbfeb61e0e463f1573028c63d3bd29d507 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:52:59 +0200 Subject: [PATCH 565/980] Bump org.apache.maven.plugins:maven-failsafe-plugin from 3.5.2 to 3.5.3 (#1316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) from 3.5.2 to 3.5.3.
      Release notes

      Sourced from org.apache.maven.plugins:maven-failsafe-plugin's releases.

      3.5.3

      🐛 Bug Fixes

      👻 Maintenance

      📦 Dependency updates

      Commits
      • 4434650 [maven-release-plugin] prepare release surefire-3.5.3
      • 1270950 use github directly
      • 59f3a1f release tag name backward compatible
      • dfbabe2 assertj-core must be test scope (#826)
      • e1f8119 back to 3.5.3-SNAPSHOT
      • c497559 [maven-release-plugin] prepare for next development iteration
      • 3962112 [maven-release-plugin] prepare release v3.5.3
      • 227c134 surefire shared utils version current version (#825)
      • 1d34c34 Bump org.htmlunit:htmlunit from 4.10.0 to 4.11.1
      • 906b65a Update site descriptors
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-failsafe-plugin&package-manager=maven&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 48a0f0f98..47869220a 100644 --- a/pom.xml +++ b/pom.xml @@ -181,7 +181,7 @@
      maven-failsafe-plugin - 3.5.2 + 3.5.3 maven-dependency-plugin From f9eabb55ff7bbf8a7757c0a2d1c2aa1f5cb6784c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 4 Apr 2025 14:14:47 +0200 Subject: [PATCH 566/980] use Mise (#1319) Signed-off-by: Gregor Zeitlinger --- .github/workflows/acceptance-tests.yml | 28 ++++--------------- .github/workflows/native-tests.yml | 14 ++++------ .gitignore | 1 + mise.lock | 4 +++ mise.toml | 26 +++++++++++++++-- .../generate-protobuf.sh | 1 + scripts/run-acceptance-tests.sh | 9 ------ scripts/run-native-tests.sh | 7 ----- 8 files changed, 39 insertions(+), 51 deletions(-) delete mode 100755 scripts/run-acceptance-tests.sh delete mode 100755 scripts/run-native-tests.sh diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 3baa62489..321d5b330 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -10,32 +10,14 @@ jobs: acceptance-tests: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Check out oats + - name: Check out uses: actions/checkout@v4 - with: - repository: grafana/oats - ref: v0.1.0 - path: oats - - name: Set up JDK - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: temurin - cache: 'maven' - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: '1.23' - cache-dependency-path: oats/go.sum - - name: Run the Maven verify phase - run: | - ./mvnw clean install -DskipTests + - uses: jdx/mise-action@v2 - name: Run acceptance tests - run: ./scripts/run-acceptance-tests.sh + run: mise run acceptance-test - name: upload log file uses: actions/upload-artifact@v4 if: failure() with: - name: OATS logs - path: oats/yaml/build/**/*.log + name: OATs logs + path: build/**/*.log diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index 9a4ed50a6..f124c8458 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -10,12 +10,8 @@ jobs: native-tests: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Set up JDK - uses: actions/setup-java@v4 - with: - java-version: '21' - distribution: graalvm - cache: 'maven' - - name: Run the Maven verify phase - run: ./scripts/run-native-tests.sh + - name: Check out + uses: actions/checkout@v4 + - uses: jdx/mise-action@v2 + - name: Run native tests + run: mise run native-test diff --git a/.gitignore b/.gitignore index 14ec2f863..ad343c1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.iml target/ +build/ simpleclient_pushgateway/mockserver.log simpleclient_pushgateway/mockserver_request.log nb-configuration.xml diff --git a/mise.lock b/mise.lock index 789ebabb2..4cdb5f57d 100644 --- a/mise.lock +++ b/mise.lock @@ -1,3 +1,7 @@ +[tools."go:github.com/grafana/oats"] +version = "0.2.0" +backend = "go:github.com/grafana/oats" + [tools.java] version = "temurin-17.0.13+11" backend = "core:java" diff --git a/mise.toml b/mise.toml index bf7a976de..e70b12fa8 100644 --- a/mise.toml +++ b/mise.toml @@ -2,15 +2,16 @@ PROTO_GENERATION = "true" [tools] +"go:github.com/grafana/oats" = "0.2.0" java = "temurin-17.0.13+11" protoc = "latest" [tasks.ci] description = "CI Build" run = [ - "./mvnw clean install", - # just to check if javadoc can be generated - "./mvnw javadoc:javadoc -P javadoc" + "./mvnw clean install", + # just to check if javadoc can be generated + "./mvnw javadoc:javadoc -P javadoc" ] env = { REQUIRE_PROTO_UP_TO_DATE = "true" } @@ -26,3 +27,22 @@ run = "./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=t description = "run all tests" run = "./mvnw verify" +[tasks.build] +description = "build all modules wihthout tests" +run = "./mvnw clean install -DskipTests" + +[tasks.acceptance-test] +description = "Run OATs acceptance tests" +depends = "build" +run = "oats -timeout 5m examples/" + +[tasks.native-test] +depends = "build" +tools.java = "graalvm-22.3.3+java17" +run = "../../mvnw test -PnativeTest" +dir = "integration-tests/it-spring-boot-smoke-test" + +[settings] +# to get lock file support and for go backend +experimental = true + diff --git a/prometheus-metrics-exposition-formats/generate-protobuf.sh b/prometheus-metrics-exposition-formats/generate-protobuf.sh index c92eaf790..7411626f4 100755 --- a/prometheus-metrics-exposition-formats/generate-protobuf.sh +++ b/prometheus-metrics-exposition-formats/generate-protobuf.sh @@ -41,6 +41,7 @@ if [[ $GENERATED_WITH != "$PROTOBUF_VERSION" ]]; then exit 1 fi +git checkout -- ../mise.lock # see https://github.com/jdx/mise/discussions/4782 STATUS=$(git status --porcelain) if [[ ${REQUIRE_PROTO_UP_TO_DATE:-false} == "true" && -n "$STATUS" ]]; then echo "Please use https://mise.jdx.dev/ - this will use the version specified in mise.toml" diff --git a/scripts/run-acceptance-tests.sh b/scripts/run-acceptance-tests.sh deleted file mode 100755 index f72b98573..000000000 --- a/scripts/run-acceptance-tests.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -cd oats/yaml -go install github.com/onsi/ginkgo/v2/ginkgo -export TESTCASE_TIMEOUT=5m -export TESTCASE_BASE_PATH=../../examples -ginkgo diff --git a/scripts/run-native-tests.sh b/scripts/run-native-tests.sh deleted file mode 100755 index 535bc136c..000000000 --- a/scripts/run-native-tests.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -./mvnw clean install -DskipTests -cd integration-tests/it-spring-boot-smoke-test -../../mvnw test -PnativeTest From 6006e474c2674bd55db21bbc20a2fa323da0dcaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:58:31 +0200 Subject: [PATCH 567/980] Bump org.mockito:mockito-core from 5.16.1 to 5.17.0 (#1320) Bumps [org.mockito:mockito-core](https://github.com/mockito/mockito) from 5.16.1 to 5.17.0.
      Release notes

      Sourced from org.mockito:mockito-core's releases.

      v5.17.0

      Changelog generated by Shipkit Changelog Gradle Plugin

      5.17.0

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.mockito:mockito-core&package-manager=maven&previous-version=5.16.1&new-version=5.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 47869220a..9ce73ed03 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ org.mockito mockito-core - 5.16.1 + 5.17.0 test From 9f8e9c10df8e5c73dd7103593d9ff2ca316f4d12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 17:28:17 +0200 Subject: [PATCH 568/980] Bump jetty-server.version from 12.0.18 to 12.0.19 (#1317) Bumps `jetty-server.version` from 12.0.18 to 12.0.19. Updates `org.eclipse.jetty:jetty-server` from 12.0.18 to 12.0.19 Updates `org.eclipse.jetty.ee10:jetty-ee10-servlet` from 12.0.18 to 12.0.19 Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../oats-tests/agent/example_target_info.json | 82 +++++++++++++++++++ .../agent/service-instance-id-check.py | 11 +-- .../it-exporter-servlet-jetty-sample/pom.xml | 2 +- 3 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 examples/example-exporter-opentelemetry/oats-tests/agent/example_target_info.json diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/example_target_info.json b/examples/example-exporter-opentelemetry/oats-tests/agent/example_target_info.json new file mode 100644 index 000000000..3be06bcb4 --- /dev/null +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/example_target_info.json @@ -0,0 +1,82 @@ +{ + "status": "success", + "data": { + "resultType": "vector", + "result": [ + { + "metric": { + "__name__": "target_info", + "container_id": "0282187277c5f259f3405455bd5094a936642415a02bd8dbbdb41a73987d8db7", + "host_arch": "amd64", + "host_name": "0282187277c5", + "instance": "6b3318d9-2b87-498b-a1a3-bbfaecc96374", + "job": "rolldice", + "os_description": "Linux 6.8.0-57-generic", + "os_type": "linux", + "process_command_args": "[\"/opt/java/openjdk/bin/java\",\"-jar\",\"./app.jar\"]", + "process_executable_path": "/opt/java/openjdk/bin/java", + "process_pid": "1", + "process_runtime_description": "Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.6+7-LTS", + "process_runtime_name": "OpenJDK Runtime Environment", + "process_runtime_version": "21.0.6+7-LTS", + "service_instance_id": "6b3318d9-2b87-498b-a1a3-bbfaecc96374", + "service_name": "rolldice", + "telemetry_distro_name": "opentelemetry-java-instrumentation", + "telemetry_distro_version": "2.8.0", + "telemetry_sdk_language": "java", + "telemetry_sdk_name": "opentelemetry", + "telemetry_sdk_version": "1.42.1" + }, + "value": [ + 1743776399.291, + "1" + ] + }, + { + "metric": { + "__name__": "target_info", + "http_scheme": "http", + "instance": "e6ff9e41-acdb-4c47-88b5-8112c831f5b5", + "job": "otelcol-contrib", + "net_host_port": "8888", + "server_port": "8888", + "service_instance_id": "e6ff9e41-acdb-4c47-88b5-8112c831f5b5", + "service_name": "otelcol-contrib", + "service_version": "0.122.1", + "url_scheme": "http" + }, + "value": [ + 1743776399.291, + "1" + ] + }, + { + "metric": { + "__name__": "target_info", + "container_id": "0282187277c5f259f3405455bd5094a936642415a02bd8dbbdb41a73987d8db7", + "host_arch": "amd64", + "host_name": "0282187277c5", + "instance": "6b3318d9-2b87-498b-a1a3-bbfaecc96374", + "job": "rolldice", + "os_description": "Linux 6.8.0-57-generic", + "os_type": "linux", + "process_command_line": "/opt/java/openjdk/bin/java -javaagent:/usr/src/app/opentelemetry-javaagent.jar -jar ./app.jar", + "process_executable_path": "/opt/java/openjdk/bin/java", + "process_pid": "1", + "process_runtime_description": "Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.6+7-LTS", + "process_runtime_name": "OpenJDK Runtime Environment", + "process_runtime_version": "21.0.6+7-LTS", + "service_instance_id": "6b3318d9-2b87-498b-a1a3-bbfaecc96374", + "service_name": "rolldice", + "telemetry_sdk_language": "java", + "telemetry_sdk_name": "opentelemetry", + "telemetry_sdk_version": "1.48.0" + }, + "value": [ + 1743776399.291, + "1" + ] + } + ] + } +} diff --git a/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py b/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py index 196c629c9..bcb7f1203 100755 --- a/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py +++ b/examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py @@ -7,14 +7,15 @@ import urllib.parse import json -url = ' http://localhost:9090/api/v1/label/instance/values' +url = ' http://localhost:9090/api/v1/query?query=target_info' res = json.loads(urlopen(url).read().decode('utf-8')) -values = list(res['data']) -print(values) +# uncomment the following line to use the local file instead of the url - for debugging +# with open('example_target_info.json') as f: +# res = json.load(f) -if "localhost:8888" in values: - values.remove("localhost:8888") +values = list({r['metric']['instance'] for r in res['data']['result'] if not r['metric']['service_name'] == 'otelcol-contrib'}) +print(values) # both the agent and the exporter should report the same instance id assert len(values) == 1 diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index fc38eded2..d6a9972ce 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -15,7 +15,7 @@ Jetty Sample for the Exporter Integration Test - 12.0.18 + 12.0.19 17 From 6d51883a3f5c22ef4c0904aa8bf83ee01726206e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:31:28 +0200 Subject: [PATCH 569/980] Bump com.diffplug.spotless:spotless-maven-plugin from 2.44.3 to 2.44.4 (#1322) Bumps [com.diffplug.spotless:spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.44.3 to 2.44.4.
      Release notes

      Sourced from com.diffplug.spotless:spotless-maven-plugin's releases.

      Maven Plugin v2.44.4

      Changed

      • Use palantir-java-format 2.57.0 on Java 21. (#2447)
      • Re-try npm install with --prefer-online after ERESOLVE error. (#2448)
      Commits
      • 0ca99e5 Published maven/2.44.4
      • 1b1a4fb Published gradle/7.0.3
      • 0fa3cab Published lib/3.1.1
      • 0fe8f9b Update README.md for android kotlin callouts (#2438)
      • d25f04d Minor tweak.
      • fa3fd1e Add the cool blockquote warning trick to the other Android spot.
      • 60993fd Fix the Android Kotlin warning and adjust its position.
      • 0426db1 Apply Gradle's strict plugin types validation to the Spotless plugin in prepa...
      • 48b4cde fix(deps): update dependency org.mockito:mockito-core to v5.17.0 (#2461)
      • 81f2f8b fix(deps): update dependency org.mockito:mockito-core to v5.17.0
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.diffplug.spotless:spotless-maven-plugin&package-manager=maven&previous-version=2.44.3&new-version=2.44.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index e249cedf6..4cc27292e 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -77,7 +77,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.3 + 2.44.4 diff --git a/pom.xml b/pom.xml index 9ce73ed03..c2619e425 100644 --- a/pom.xml +++ b/pom.xml @@ -216,7 +216,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.44.3 + 2.44.4 From 1ae726e30732060282396834f8aa379d56cc1591 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 15:45:21 +0200 Subject: [PATCH 570/980] Bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha from 2.14.0-alpha to 2.15.0-alpha (#1326) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.14.0-alpha to 2.15.0-alpha.
      Release notes

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's releases.

      Version 2.14.0

      This release targets the OpenTelemetry SDK 1.48.0.

      Note that many artifacts have the -alpha suffix attached to their version number, reflecting that they are still alpha quality and will continue to have breaking changes. Please see the VERSIONING.md for more details.

      Migration notes

      • The java.net.http.HttpClient instrumentation package io.opentelemetry.instrumentation.httpclient was deprecated in favor of the new package name io.opentelemetry.instrumentation.javahttpclient
      • The experimental opt-in jvm.buffer.memory.usage metric was renamed to jvm.buffer.memory.used in order to follow general semantic convention naming
      • The Http *TelemetryBuilder generic signatures were simplified (#12858)

      🌟 New javaagent instrumentation

      🌟 New library instrumentation

      📈 Enhancements

      • Support virtual threads in Spring Scheduling instrumentation (#13370)
      • Redact query string values for http client spans (#13114)
      • Support attribute lowercase modifier in JMX metrics yaml definitions (#13385)
      • Add tapir path matching within pekko instrumentation (#13386)
      • Support latest Axis2 version (#13490)
      • Add instrumentation for Lambda Java interface HandleStreamRequest (#13466)
      • Remove usage of gRPC internal api (#13510)
      • Add options to disable gRPC per-message events (#13443)
      • Add @​WithSpan option to break from existing context and start a new trace (#13112)

      🛠️ Bug fixes

      • Fix NoSuchElementException thrown by Akka instrumentation (#13360)
      • Fix Spring Boot Starter MDC instrumentation for Logback not injecting trace_id (#13391)
      • Fix opt-in invoke dynamic instrumentation mechanism in OpenJ9 (#13282)
      • Fix spans in Pekko instrumentation on server timeout (#13435)
      • Avoid overriding user's trace_id in Log4j MDC instrumentation (#13479)
      • Fix gRPC message ID attribute (#13443)

      🙇 Thank you

      This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

      @​123liuziming @​anuraaga @​breedx-splk @​chlos

      ... (truncated)

      Changelog

      Sourced from io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha's changelog.

      Changelog

      Unreleased

      Version 2.15.0 (2025-04-10)

      📈 Enhancements

      • Delete deprecated java http client classes (#13527)
      • Support latest version of kafka client library (#13544)
      • Implement genai events for bedrock (streaming) (#13507)
      • JMX metrics support unit conversion (#13448)
      • Rename experimental method, use Telemetry instead of Metrics (#13574)
      • End metric description with dot (#13559)
      • Add initial gen_ai instrumentation of bedrock InvokeModel (#13547)
      • Delete deprecated library instrumentation methods (#13575)
      • Add experimental http client url.template attribute (#13581)
      • Add error.type for JDBC under otel.semconv-stability.opt-in flag (#13331)
      • Add azure resource provider (#13627)
      • Remove aws.endpoint attribute from SQS instrumentation (#13620)
      • Avoid conflicts with user-defined Apache Dubbo filters with default order (#13625)
      • Support filtering negative values from JMX metrics (#13589)
      • Instrument bedrock InvokeModelWithResponseStream (#13607)
      • Use context instead of request attributes for servlet async instrumentation (#13493)
      • Improve handling of quoted table names (#13612)

      🛠️ Bug fixes

      • Fix aws timeseries requests misdetected as dynamodb (#13579)
      • Fix pekko route naming (#13491)
      • Fix route handling when local root span wasn't created by instrumentation api

      ... (truncated)

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha&package-manager=maven&previous-version=2.14.0-alpha&new-version=2.15.0-alpha)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2619e425..4ce721ea5 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ --module-name-need-to-be-overriden-- 33.4.6-jre 5.12.1 - 2.14.0-alpha + 2.15.0-alpha 8 0.70 false From 2059498982a041b79ca8aa9d2851c989c34f9363 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 16:23:01 +0200 Subject: [PATCH 571/980] Bump org.apache.tomcat.embed:tomcat-embed-core from 11.0.5 to 11.0.6 (#1324) Bumps org.apache.tomcat.embed:tomcat-embed-core from 11.0.5 to 11.0.6. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.tomcat.embed:tomcat-embed-core&package-manager=maven&previous-version=11.0.5&new-version=11.0.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index 88f2c56b2..a5c9d9ce4 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.5 + 11.0.6 diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 98acbe4e8..4b452182a 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.5 + 11.0.6 diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index b30d8c5f8..11ddaccef 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -38,7 +38,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.5 + 11.0.6 diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 0930052c9..048e9d976 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -33,7 +33,7 @@ org.apache.tomcat.embed tomcat-embed-core - 11.0.5 + 11.0.6 From 96e552d1c1680c93476e6c94735684bb2a11187e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 16:23:14 +0200 Subject: [PATCH 572/980] Bump com.google.guava:guava from 33.4.6-jre to 33.4.7-jre (#1323) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.6-jre to 33.4.7-jre.
      Release notes

      Sourced from com.google.guava:guava's releases.

      33.4.7

      Known issue: This release breaks the build of Android apps with a minSdkVersion below 26. We will publish a fixed version soon. Sorry again for the continuing trouble.

      Guava 33.4.7, like 33.4.6, fixes two problems that we introduced while modularizing Guava and migrating off Unsafe in 33.4.5.

      Even if you're not upgrading from Guava 33.4.0 or earlier, still read the release notes for Guava 33.4.1. Those release notes contain information about the effects of Guava 33.4.5 and higher on the module system.

      Maven

      <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>33.4.7-jre</version>
        <!-- or, for Android: -->
        <version>33.4.7-android</version>
      </dependency>
      

      Jar files

      Guava requires one runtime dependency, which you can download here:

      Javadoc

      JDiff

      Changelog

      • Modified the guava module's dependency on failureaccess to be transitive. Also, modified the guava-testlib module to make its dependency on guava transitive, to remove its dependency on failureaccess, and to add a dependency (transitive) on junit. (63ecdf2239)
      • util.concurrent: Modified our fast paths to ensure that they continue to work when run through optimizers, such as those commonly used by Android apps. This fixes problems that some users may have seen since Guava 33.4.5. (b8dcaede09bcf1c3bd5fc037690498f6ac560c54, f9eff73b8d)
      • util.concurrent: Changed the guava-android copy of AbstractFuture to try VarHandle before Unsafe, eliminating a warning under newer JDKs. (7336af1831)
      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava&package-manager=maven&previous-version=33.4.6-jre&new-version=33.4.7-jre)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ce721ea5..5e9cccc11 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- - 33.4.6-jre + 33.4.7-jre 5.12.1 2.15.0-alpha 8 From bdca41547478521d172bc8b579844eb87c51abf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:27:16 +0200 Subject: [PATCH 573/980] Bump junit-jupiter.version from 5.12.1 to 5.12.2 (#1327) Bumps `junit-jupiter.version` from 5.12.1 to 5.12.2. Updates `org.junit.jupiter:junit-jupiter` from 5.12.1 to 5.12.2
      Release notes

      Sourced from org.junit.jupiter:junit-jupiter's releases.

      JUnit 5.12.2 = Platform 1.12.2 + Jupiter 5.12.2 + Vintage 5.12.2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2

      Commits
      • 0a44659 Release 5.12.2
      • 4c7dfdc Finalize 5.12.2 release notes
      • 561613e Fix handling of CleanupMode.ON_SUCCESS
      • 19d07d2 Add 5.12.2 release notes from template
      • 803cbb6 Add build parameter for enabling dry-run mode for test execution
      • eb43e62 Back to snapshots for further development
      • See full diff in compare view

      Updates `org.junit.jupiter:junit-jupiter-params` from 5.12.1 to 5.12.2
      Release notes

      Sourced from org.junit.jupiter:junit-jupiter-params's releases.

      JUnit 5.12.2 = Platform 1.12.2 + Jupiter 5.12.2 + Vintage 5.12.2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2

      Commits
      • 0a44659 Release 5.12.2
      • 4c7dfdc Finalize 5.12.2 release notes
      • 561613e Fix handling of CleanupMode.ON_SUCCESS
      • 19d07d2 Add 5.12.2 release notes from template
      • 803cbb6 Add build parameter for enabling dry-run mode for test execution
      • eb43e62 Back to snapshots for further development
      • See full diff in compare view

      Updates `org.junit:junit-bom` from 5.12.1 to 5.12.2
      Release notes

      Sourced from org.junit:junit-bom's releases.

      JUnit 5.12.2 = Platform 1.12.2 + Jupiter 5.12.2 + Vintage 5.12.2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2

      Commits
      • 0a44659 Release 5.12.2
      • 4c7dfdc Finalize 5.12.2 release notes
      • 561613e Fix handling of CleanupMode.ON_SUCCESS
      • 19d07d2 Add 5.12.2 release notes from template
      • 803cbb6 Add build parameter for enabling dry-run mode for test execution
      • eb43e62 Back to snapshots for further development
      • See full diff in compare view

      Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e9cccc11..78c432785 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ UTF-8 --module-name-need-to-be-overriden-- 33.4.7-jre - 5.12.1 + 5.12.2 2.15.0-alpha 8 0.70 From 43c4c39ad794ef82de7fae221da935832a3ba6de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:27:34 +0200 Subject: [PATCH 574/980] Bump commons-io:commons-io from 2.18.0 to 2.19.0 (#1328) Bumps commons-io:commons-io from 2.18.0 to 2.19.0. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=commons-io:commons-io&package-manager=maven&previous-version=2.18.0&new-version=2.19.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 20d0f1f38..3a8d1343d 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -51,7 +51,7 @@ commons-io commons-io - 2.18.0 + 2.19.0 org.testcontainers From 610600476590878a6a62f3ea858c85c0ac68dbce Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 15 Apr 2025 14:41:17 +0200 Subject: [PATCH 575/980] add option to skip the shaded protobuf and otel libraries (#1293) Signed-off-by: Gregor Zeitlinger --- .github/workflows/acceptance-tests.yml | 6 - docs/content/exporters/formats.md | 80 ++++++++-- .../it-spring-boot-smoke-test/pom.xml | 27 +++- mise.lock | 2 +- mise.toml | 2 +- pom.xml | 3 + prometheus-metrics-bom/pom.xml | 10 ++ .../pom.xml | 148 ++++++++++++++++++ .../pom.xml | 122 +-------------- .../pom.xml | 95 +++++++++++ prometheus-metrics-exposition-formats/pom.xml | 49 +----- 11 files changed, 361 insertions(+), 183 deletions(-) create mode 100644 prometheus-metrics-exporter-opentelemetry-shaded/pom.xml create mode 100644 prometheus-metrics-exposition-formats-shaded/pom.xml diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 321d5b330..1f40d6e55 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -15,9 +15,3 @@ jobs: - uses: jdx/mise-action@v2 - name: Run acceptance tests run: mise run acceptance-test - - name: upload log file - uses: actions/upload-artifact@v4 - if: failure() - with: - name: OATs logs - path: build/**/*.log diff --git a/docs/content/exporters/formats.md b/docs/content/exporters/formats.md index 79ae46e06..189d13d56 100644 --- a/docs/content/exporters/formats.md +++ b/docs/content/exporters/formats.md @@ -32,14 +32,74 @@ You can exclude the protobuf exposition format by including the For example, in Maven: ```xml - - io.prometheus - prometheus-metrics-exporter-httpserver - - - io.prometheus - prometheus-metrics-exposition-formats - - - + + + io.prometheus + prometheus-metrics-exporter-httpserver + + + io.prometheus + prometheus-metrics-exposition-formats + + + + + io.prometheus + prometheus-metrics-exposition-textformats + + +``` + +## Exclude the shaded protobuf classes + +You can exclude the shaded protobuf classes including the +`prometheus-metrics-exposition-formats-no-protobuf` module and excluding the +`prometheus-metrics-exposition-formats` module in your build file. + +For example, in Maven: + +```xml + + + io.prometheus + prometheus-metrics-exporter-httpserver + + + io.prometheus + prometheus-metrics-exposition-formats + + + + + io.prometheus + prometheus-metrics-exposition-formats-no-protobuf + + +``` + +## Exclude the shaded otel classes + +You can exclude the shaded otel classes including the +`prometheus-metrics-exporter-opentelemetry-no-otel` module and excluding the +`prometheus-metrics-exporter-opentelemetry` module in your build file. + +For example, in Maven: + +```xml + + + io.prometheus + prometheus-metrics-exporter-opentelemetry + + + io.prometheus + prometheus-metrics-exporter-opentelemetry + + + + + io.prometheus + prometheus-metrics-exporter-opentelemetry-no-otel + + ``` diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 4cc27292e..286aa8802 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 @@ -21,10 +22,18 @@ 17 + 5.12.0 + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + io.prometheus prometheus-metrics-bom @@ -49,12 +58,26 @@ micrometer-registry-prometheus runtime - org.springframework.boot spring-boot-starter-test test + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.platform + junit-platform-launcher + test + io.prometheus it-common diff --git a/mise.lock b/mise.lock index 4cdb5f57d..049ab1acf 100644 --- a/mise.lock +++ b/mise.lock @@ -1,5 +1,5 @@ [tools."go:github.com/grafana/oats"] -version = "0.2.0" +version = "0.3.0" backend = "go:github.com/grafana/oats" [tools.java] diff --git a/mise.toml b/mise.toml index e70b12fa8..a59047096 100644 --- a/mise.toml +++ b/mise.toml @@ -2,7 +2,7 @@ PROTO_GENERATION = "true" [tools] -"go:github.com/grafana/oats" = "0.2.0" +"go:github.com/grafana/oats" = "latest" java = "temurin-17.0.13+11" protoc = "latest" diff --git a/pom.xml b/pom.xml index 78c432785..e2f5d01eb 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ UTF-8 --module-name-need-to-be-overriden-- + 4.30.2 33.4.7-jre 5.12.2 2.15.0-alpha @@ -68,12 +69,14 @@ prometheus-metrics-model prometheus-metrics-tracer prometheus-metrics-exposition-formats + prometheus-metrics-exposition-formats-shaded prometheus-metrics-exposition-textformats prometheus-metrics-exporter-common prometheus-metrics-exporter-servlet-jakarta prometheus-metrics-exporter-servlet-javax prometheus-metrics-exporter-httpserver prometheus-metrics-exporter-opentelemetry + prometheus-metrics-exporter-opentelemetry-shaded prometheus-metrics-exporter-opentelemetry-otel-agent-resources prometheus-metrics-exporter-pushgateway prometheus-metrics-instrumentation-caffeine diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index 496f2fc4f..e38595da0 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -47,6 +47,11 @@ prometheus-metrics-exporter-opentelemetry ${project.version} + + io.prometheus + prometheus-metrics-exporter-opentelemetry-no-otel + ${project.version} + io.prometheus prometheus-metrics-exporter-pushgateway @@ -62,6 +67,11 @@ prometheus-metrics-exporter-servlet-javax ${project.version} + + io.prometheus + prometheus-metrics-exposition-formats-no-protobuf + ${project.version} + io.prometheus prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml b/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml new file mode 100644 index 000000000..98c7966f8 --- /dev/null +++ b/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml @@ -0,0 +1,148 @@ + + + 4.0.0 + + + io.prometheus + client_java + 10.0.0-SNAPSHOT + + + prometheus-metrics-exporter-opentelemetry + bundle + + Prometheus Metrics to OpenTelemetry Exporter + + Converts Prometheus metrics to OpenTelemetry format and pushes them to an OTLP endpoint + + + + io.prometheus.metrics.exporter.opentelemetry + + + + + io.prometheus + prometheus-metrics-exporter-opentelemetry-no-otel + ${project.version} + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + regex-property + + regex-property + + + otel.instrumentation.string-version + ${otel.instrumentation.version} + [\.-] + _ + true + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + io.opentelemetry:* + io.opentelemetry.semconv:* + io.opentelemetry.instrumentation:* + com.squareup.*:* + org.jetbrains:* + org.jetbrains.*:* + + + + + io.opentelemetry + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version} + + + + io.opentelemetry.instrumentation + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.instrumentation + + + + io.opentelemetry.semconv + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.semconv + + + + okhttp3 + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okhttp3 + + + + kotlin + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.kotlin + + + + org.intellij + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.intellij + + + + org.jetbrains + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.jetbrains + + + + okio + + io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okio + + + + + + + + + *:* + + lib/opentelemetry-* + META-INF/maven/org.jctools/** + META-INF/maven/org.jetbrains/** + META-INF/versions/** + META-INF/native-image/** + META-INF/proguard/** + META-INF/*.kotlin_module + META-INF/MANIFEST.MF + + + + + + + + + + diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 4bf7e4bf4..fa02e3706 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -9,16 +9,16 @@ 10.0.0-SNAPSHOT - prometheus-metrics-exporter-opentelemetry + prometheus-metrics-exporter-opentelemetry-no-otel bundle - Prometheus Metrics to OpenTelemetry Exporter + Prometheus Metrics to OpenTelemetry Exporter without OTel shaded - Converts Prometheus metrics to OpenTelemetry format and pushes them to an OTLP endpoint + Converts Prometheus metrics to OpenTelemetry format and pushes them to an OTLP endpoint without shading OpenTelemetry. - io.prometheus.metrics.exporter.opentelemetry + io.prometheus.metrics.exporter.opentelemetry.no-otel @@ -108,119 +108,5 @@ true - - - org.codehaus.mojo - build-helper-maven-plugin - - - regex-property - - regex-property - - - otel.instrumentation.string-version - ${otel.instrumentation.version} - [\.-] - _ - true - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - - - io.opentelemetry:* - io.opentelemetry.semconv:* - io.opentelemetry.instrumentation:* - com.squareup.*:* - org.jetbrains:* - org.jetbrains.*:* - - - - - io.opentelemetry - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version} - - - - io.opentelemetry.instrumentation - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.instrumentation - - - - io.opentelemetry.semconv - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.semconv - - - - okhttp3 - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okhttp3 - - - - kotlin - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.kotlin - - - - org.intellij - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.intellij - - - - org.jetbrains - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.org.jetbrains - - - - okio - - io.prometheus.metrics.shaded.io_opentelemetry_${otel.instrumentation.string-version}.okio - - - - - - - - - *:* - - lib/opentelemetry-* - META-INF/maven/org.jctools/** - META-INF/maven/org.jetbrains/** - META-INF/versions/** - META-INF/native-image/** - META-INF/proguard/** - META-INF/*.kotlin_module - META-INF/MANIFEST.MF - - - - - - - - diff --git a/prometheus-metrics-exposition-formats-shaded/pom.xml b/prometheus-metrics-exposition-formats-shaded/pom.xml new file mode 100644 index 000000000..486336105 --- /dev/null +++ b/prometheus-metrics-exposition-formats-shaded/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + + io.prometheus + client_java + 10.0.0-SNAPSHOT + + + prometheus-metrics-exposition-formats + bundle + + Prometheus Metrics Exposition Formats + + Prometheus exposition formats. + + + + io.prometheus.metrics.expositionformats + + + + + io.prometheus + prometheus-metrics-exposition-formats-no-protobuf + ${project.version} + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + regex-property + + regex-property + + + protobuf-java.string-version + ${protobuf-java.version} + \. + _ + true + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + true + true + + + com.google.protobuf:protobuf-java + + + + + com.google.protobuf + + io.prometheus.metrics.shaded.com_google_protobuf_${protobuf-java.string-version} + + + + + + com.google.protobuf:protobuf-java + + META-INF/maven/com.google.protobuf/** + **/*.proto + META-INF/MANIFEST.MF + + + + + + + + + + diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 69237e4bf..0a00907bd 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -10,17 +10,16 @@ 10.0.0-SNAPSHOT - prometheus-metrics-exposition-formats + prometheus-metrics-exposition-formats-no-protobuf bundle - Prometheus Metrics Exposition Formats + Prometheus Metrics Exposition Formats no protobuf - Prometheus exposition formats. + Prometheus exposition formats without shaded Protobuf classes. - io.prometheus.metrics.expositionformats - 4.30.2 + io.prometheus.metrics.expositionformats.noprotobuf @@ -34,7 +33,6 @@ protobuf-java ${protobuf-java.version} - @@ -138,45 +136,6 @@ src/main/java;src/main/generated
      - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - true - true - - - com.google.protobuf:protobuf-java - - - - - com.google.protobuf - - io.prometheus.metrics.shaded.com_google_protobuf_${protobuf-java.string-version} - - - - - - com.google.protobuf:protobuf-java - - META-INF/maven/com.google.protobuf/** - **/*.proto - META-INF/MANIFEST.MF - - - - - - - From 61ae8168b9fcc3dbab7aa0e5c258a8ba6dc2d653 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 15 Apr 2025 16:09:08 +0200 Subject: [PATCH 576/980] fix timestamp representation (#1292) Fixes https://github.com/prometheus/client_java/issues/1277 --------- Signed-off-by: Gregor Zeitlinger --- .../benchmarks/TextFormatUtilBenchmark.java | 4 +- mise.toml | 10 +++- .../metrics/config/ExporterProperties.java | 29 +++++++++- .../config/ExporterPropertiesTest.java | 1 + .../exporter/pushgateway/PushGateway.java | 33 ++++++++++- .../pushgateway/BasicAuthPushGatewayTest.java | 1 + .../expositionformats/ExpositionFormats.java | 12 +++- .../OpenMetricsTextFormatWriter.java | 51 +++++++++++++--- .../PrometheusTextFormatWriter.java | 58 +++++++++++++++++-- .../expositionformats/TextFormatUtil.java | 15 ++++- .../ExpositionFormatWriterTest.java | 2 +- .../ExpositionFormatsTest.java | 26 ++++++--- .../expositionformats/TextFormatUtilTest.java | 13 +++++ 13 files changed, 219 insertions(+), 36 deletions(-) diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java index 03dcd0d07..dcacf9a76 100644 --- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java +++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/TextFormatUtilBenchmark.java @@ -50,9 +50,9 @@ public class TextFormatUtilBenchmark { } private static final ExpositionFormatWriter OPEN_METRICS_TEXT_FORMAT_WRITER = - new OpenMetricsTextFormatWriter(false, false); + OpenMetricsTextFormatWriter.create(); private static final ExpositionFormatWriter PROMETHEUS_TEXT_FORMAT_WRITER = - new PrometheusTextFormatWriter(false); + PrometheusTextFormatWriter.create(); @State(Scope.Benchmark) public static class WriterState { diff --git a/mise.toml b/mise.toml index a59047096..f1032d2a4 100644 --- a/mise.toml +++ b/mise.toml @@ -19,9 +19,13 @@ env = { REQUIRE_PROTO_UP_TO_DATE = "true" } description = "format source code" run = "./mvnw spotless:apply" +[tasks.compile] +description = "bare compile, ignoring formatting and linters" +run = "./mvnw install -DskipTests -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn" + [tasks.test] description = "run unit tests, ignoring formatting and linters" -run = "./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn" +run = "./mvnw test -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn" [tasks.test-all] description = "run all tests" @@ -29,7 +33,7 @@ run = "./mvnw verify" [tasks.build] description = "build all modules wihthout tests" -run = "./mvnw clean install -DskipTests" +run = "./mvnw install -DskipTests" [tasks.acceptance-test] description = "Run OATs acceptance tests" @@ -39,7 +43,7 @@ run = "oats -timeout 5m examples/" [tasks.native-test] depends = "build" tools.java = "graalvm-22.3.3+java17" -run = "../../mvnw test -PnativeTest" +run = "../../mvnw test -PnativeTest" dir = "integration-tests/it-spring-boot-smoke-test" [settings] diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java index 72c04c33b..d35f970ff 100644 --- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java +++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterProperties.java @@ -6,14 +6,21 @@ public class ExporterProperties { private static final String INCLUDE_CREATED_TIMESTAMPS = "includeCreatedTimestamps"; + // milliseconds is the default - we only provide a boolean flag to avoid a breaking change + private static final String PROMETHEUS_TIMESTAMPS_IN_MS = "prometheusTimestampsInMs"; private static final String EXEMPLARS_ON_ALL_METRIC_TYPES = "exemplarsOnAllMetricTypes"; private static final String PREFIX = "io.prometheus.exporter"; private final Boolean includeCreatedTimestamps; + private final Boolean prometheusTimestampsInMs; private final Boolean exemplarsOnAllMetricTypes; - private ExporterProperties(Boolean includeCreatedTimestamps, Boolean exemplarsOnAllMetricTypes) { + private ExporterProperties( + Boolean includeCreatedTimestamps, + Boolean prometheusTimestampsInMs, + Boolean exemplarsOnAllMetricTypes) { this.includeCreatedTimestamps = includeCreatedTimestamps; + this.prometheusTimestampsInMs = prometheusTimestampsInMs; this.exemplarsOnAllMetricTypes = exemplarsOnAllMetricTypes; } @@ -22,6 +29,11 @@ public boolean getIncludeCreatedTimestamps() { return includeCreatedTimestamps != null && includeCreatedTimestamps; } + /** Use milliseconds for timestamps in prometheus text format? Default is {@code false}. */ + public boolean getPrometheusTimestampsInMs() { + return prometheusTimestampsInMs != null && prometheusTimestampsInMs; + } + /** * Allow Exemplars on all metric types in OpenMetrics format? Default is {@code false}, which * means Exemplars will only be added for Counters and Histogram buckets. @@ -38,9 +50,12 @@ static ExporterProperties load(Map properties) throws PrometheusPropertiesException { Boolean includeCreatedTimestamps = Util.loadBoolean(PREFIX + "." + INCLUDE_CREATED_TIMESTAMPS, properties); + Boolean timestampsInMs = + Util.loadBoolean(PREFIX + "." + PROMETHEUS_TIMESTAMPS_IN_MS, properties); Boolean exemplarsOnAllMetricTypes = Util.loadBoolean(PREFIX + "." + EXEMPLARS_ON_ALL_METRIC_TYPES, properties); - return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); + return new ExporterProperties( + includeCreatedTimestamps, timestampsInMs, exemplarsOnAllMetricTypes); } public static Builder builder() { @@ -51,6 +66,7 @@ public static class Builder { private Boolean includeCreatedTimestamps; private Boolean exemplarsOnAllMetricTypes; + boolean prometheusTimestampsInMs; private Builder() {} @@ -66,8 +82,15 @@ public Builder exemplarsOnAllMetricTypes(boolean exemplarsOnAllMetricTypes) { return this; } + /** See {@link #getPrometheusTimestampsInMs()}. */ + public Builder prometheusTimestampsInMs(boolean prometheusTimestampsInMs) { + this.prometheusTimestampsInMs = prometheusTimestampsInMs; + return this; + } + public ExporterProperties build() { - return new ExporterProperties(includeCreatedTimestamps, exemplarsOnAllMetricTypes); + return new ExporterProperties( + includeCreatedTimestamps, prometheusTimestampsInMs, exemplarsOnAllMetricTypes); } } } diff --git a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java index c09bc12c3..190616292 100644 --- a/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java +++ b/prometheus-metrics-config/src/test/java/io/prometheus/metrics/config/ExporterPropertiesTest.java @@ -48,6 +48,7 @@ void builder() { ExporterProperties.builder() .includeCreatedTimestamps(true) .exemplarsOnAllMetricTypes(true) + .prometheusTimestampsInMs(false) .build(); assertThat(properties.getIncludeCreatedTimestamps()).isTrue(); assertThat(properties.getExemplarsOnAllMetricTypes()).isTrue(); diff --git a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java index 6c89185f1..1f7262368 100644 --- a/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java +++ b/prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java @@ -80,6 +80,7 @@ public class PushGateway { private final URL url; private final ExpositionFormatWriter writer; + private final boolean prometheusTimestampsInMs; private final Map requestHeaders; private final PrometheusRegistry registry; private final HttpConnectionFactory connectionFactory; @@ -89,20 +90,25 @@ private PushGateway( Format format, URL url, HttpConnectionFactory connectionFactory, - Map requestHeaders) { + Map requestHeaders, + boolean prometheusTimestampsInMs) { this.registry = registry; this.url = url; this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders)); this.connectionFactory = connectionFactory; + this.prometheusTimestampsInMs = prometheusTimestampsInMs; writer = getWriter(format); if (!writer.isAvailable()) { throw new RuntimeException(writer.getClass() + " is not available"); } } + @SuppressWarnings("deprecation") private ExpositionFormatWriter getWriter(Format format) { if (format == Format.PROMETHEUS_TEXT) { - return new PrometheusTextFormatWriter(false); + return PrometheusTextFormatWriter.builder() + .setTimestampsInMs(this.prometheusTimestampsInMs) + .build(); } else { // use reflection to avoid a compile-time dependency on the expositionformats module return new PrometheusProtobufWriter(); @@ -264,6 +270,7 @@ public static class Builder { private String address; private Scheme scheme; private String job; + private boolean prometheusTimestampsInMs; private final Map requestHeaders = new HashMap<>(); private PrometheusRegistry registry = PrometheusRegistry.defaultRegistry; private HttpConnectionFactory connectionFactory = new DefaultHttpConnectionFactory(); @@ -380,6 +387,21 @@ public Builder registry(PrometheusRegistry registry) { return this; } + /** + * Use milliseconds for timestamps in text format? Default is {@code false}. Can be overwritten + * at runtime with the {@code io.prometheus.exporter.timestampsInMs} property. + */ + public Builder prometheusTimestampsInMs(boolean prometheusTimestampsInMs) { + this.prometheusTimestampsInMs = prometheusTimestampsInMs; + return this; + } + + private boolean getPrometheusTimestampsInMs() { + // accept either to opt in to timestamps in milliseconds + return config.getExporterProperties().getPrometheusTimestampsInMs() + || this.prometheusTimestampsInMs; + } + private Scheme getScheme(ExporterPushgatewayProperties properties) { if (properties != null && properties.getScheme() != null) { return Scheme.valueOf(properties.getScheme()); @@ -453,7 +475,12 @@ public PushGateway build() { config == null ? null : config.getExporterPushgatewayProperties(); try { return new PushGateway( - registry, getFormat(), makeUrl(properties), connectionFactory, requestHeaders); + registry, + getFormat(), + makeUrl(properties), + connectionFactory, + requestHeaders, + getPrometheusTimestampsInMs()); } catch (MalformedURLException e) { throw new PrometheusPropertiesException( address + ": Invalid address. Expecting :"); diff --git a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java index 598172eaa..ce0fec354 100644 --- a/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java +++ b/prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/BasicAuthPushGatewayTest.java @@ -29,6 +29,7 @@ public void setUp() { .address("localhost:" + mockServerClient.getPort()) .basicAuth("testUser", "testPwd") .registry(registry) + .prometheusTimestampsInMs(true) .job("j") .build(); } diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java index 01ea9ef40..daec7677b 100644 --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/ExpositionFormats.java @@ -22,12 +22,18 @@ public static ExpositionFormats init() { return init(PrometheusProperties.get().getExporterProperties()); } + @SuppressWarnings("deprecation") public static ExpositionFormats init(ExporterProperties properties) { return new ExpositionFormats( new PrometheusProtobufWriter(), - new PrometheusTextFormatWriter(properties.getIncludeCreatedTimestamps()), - new OpenMetricsTextFormatWriter( - properties.getIncludeCreatedTimestamps(), properties.getExemplarsOnAllMetricTypes())); + PrometheusTextFormatWriter.builder() + .setIncludeCreatedTimestamps(properties.getIncludeCreatedTimestamps()) + .setTimestampsInMs(properties.getPrometheusTimestampsInMs()) + .build(), + OpenMetricsTextFormatWriter.builder() + .setCreatedTimestampsEnabled(properties.getIncludeCreatedTimestamps()) + .setExemplarsOnAllMetricTypesEnabled(properties.getExemplarsOnAllMetricTypes()) + .build()); } public ExpositionFormatWriter findWriter(String acceptHeader) { diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java index 0e34934d7..914b28515 100644 --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java @@ -4,7 +4,7 @@ import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeOpenMetricsTimestamp; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; @@ -37,14 +37,43 @@ */ public class OpenMetricsTextFormatWriter implements ExpositionFormatWriter { + public static class Builder { + boolean createdTimestampsEnabled; + boolean exemplarsOnAllMetricTypesEnabled; + + private Builder() {} + + /** + * @param createdTimestampsEnabled whether to include the _created timestamp in the output + */ + public Builder setCreatedTimestampsEnabled(boolean createdTimestampsEnabled) { + this.createdTimestampsEnabled = createdTimestampsEnabled; + return this; + } + + /** + * @param exemplarsOnAllMetricTypesEnabled whether to include exemplars in the output for all + * metric types + */ + public Builder setExemplarsOnAllMetricTypesEnabled(boolean exemplarsOnAllMetricTypesEnabled) { + this.exemplarsOnAllMetricTypesEnabled = exemplarsOnAllMetricTypesEnabled; + return this; + } + + public OpenMetricsTextFormatWriter build() { + return new OpenMetricsTextFormatWriter( + createdTimestampsEnabled, exemplarsOnAllMetricTypesEnabled); + } + } + public static final String CONTENT_TYPE = "application/openmetrics-text; version=1.0.0; charset=utf-8"; private final boolean createdTimestampsEnabled; private final boolean exemplarsOnAllMetricTypesEnabled; /** - * @param createdTimestampsEnabled defines if {@code _created} timestamps should be included in - * the output or not. + * @param createdTimestampsEnabled whether to include the _created timestamp in the output - This + * will produce an invalid OpenMetrics output, but is kept for backwards compatibility. */ public OpenMetricsTextFormatWriter( boolean createdTimestampsEnabled, boolean exemplarsOnAllMetricTypesEnabled) { @@ -52,6 +81,14 @@ public OpenMetricsTextFormatWriter( this.exemplarsOnAllMetricTypesEnabled = exemplarsOnAllMetricTypesEnabled; } + public static Builder builder() { + return new Builder(); + } + + public static OpenMetricsTextFormatWriter create() { + return builder().build(); + } + @Override public boolean accepts(String acceptHeader) { if (acceptHeader == null) { @@ -299,10 +336,10 @@ private void writeCreated(Writer writer, MetricMetadata metadata, DataPointSnaps throws IOException { if (createdTimestampsEnabled && data.hasCreatedTimestamp()) { writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); - writeTimestamp(writer, data.getCreatedTimestampMillis()); + writeOpenMetricsTimestamp(writer, data.getCreatedTimestampMillis()); if (data.hasScrapeTimestamp()) { writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); + writeOpenMetricsTimestamp(writer, data.getScrapeTimestampMillis()); } writer.write('\n'); } @@ -335,7 +372,7 @@ private void writeScrapeTimestampAndExemplar( Writer writer, DataPointSnapshot data, Exemplar exemplar) throws IOException { if (data.hasScrapeTimestamp()) { writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); + writeOpenMetricsTimestamp(writer, data.getScrapeTimestampMillis()); } if (exemplar != null) { writer.write(" # "); @@ -344,7 +381,7 @@ private void writeScrapeTimestampAndExemplar( writeDouble(writer, exemplar.getValue()); if (exemplar.hasTimestamp()) { writer.write(' '); - writeTimestamp(writer, exemplar.getTimestampMillis()); + writeOpenMetricsTimestamp(writer, exemplar.getTimestampMillis()); } } writer.write('\n'); diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java index 8602b0ba5..76a5e4228 100644 --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java @@ -4,7 +4,7 @@ import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeEscapedLabelValue; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLabels; import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeLong; -import static io.prometheus.metrics.expositionformats.TextFormatUtil.writeTimestamp; +import static io.prometheus.metrics.expositionformats.TextFormatUtil.writePrometheusTimestamp; import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets; import io.prometheus.metrics.model.snapshots.CounterSnapshot; @@ -36,9 +36,55 @@ public class PrometheusTextFormatWriter implements ExpositionFormatWriter { public static final String CONTENT_TYPE = "text/plain; version=0.0.4; charset=utf-8"; private final boolean writeCreatedTimestamps; + private final boolean timestampsInMs; + public static class Builder { + boolean includeCreatedTimestamps; + boolean timestampsInMs = true; + + private Builder() {} + + /** + * @param includeCreatedTimestamps whether to include the _created timestamp in the output + */ + public Builder setIncludeCreatedTimestamps(boolean includeCreatedTimestamps) { + this.includeCreatedTimestamps = includeCreatedTimestamps; + return this; + } + + @Deprecated + public Builder setTimestampsInMs(boolean timestampsInMs) { + this.timestampsInMs = timestampsInMs; + return this; + } + + public PrometheusTextFormatWriter build() { + return new PrometheusTextFormatWriter(includeCreatedTimestamps, timestampsInMs); + } + } + + /** + * @param writeCreatedTimestamps whether to include the _created timestamp in the output - This + * will produce an invalid OpenMetrics output, but is kept for backwards compatibility. + * @deprecated this constructor is deprecated and will be removed in the next major version - + * {@link #builder()} or {@link #create()} instead + */ + @Deprecated public PrometheusTextFormatWriter(boolean writeCreatedTimestamps) { + this(writeCreatedTimestamps, false); + } + + private PrometheusTextFormatWriter(boolean writeCreatedTimestamps, boolean timestampsInMs) { this.writeCreatedTimestamps = writeCreatedTimestamps; + this.timestampsInMs = timestampsInMs; + } + + public static PrometheusTextFormatWriter.Builder builder() { + return new Builder(); + } + + public static PrometheusTextFormatWriter create() { + return builder().build(); } @Override @@ -62,7 +108,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx // "summary". Writer writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { if (snapshot instanceof CounterSnapshot) { writeCounter(writer, (CounterSnapshot) snapshot); } else if (snapshot instanceof GaugeSnapshot) { @@ -82,7 +128,7 @@ public void write(OutputStream out, MetricSnapshots metricSnapshots) throws IOEx } if (writeCreatedTimestamps) { for (MetricSnapshot snapshot : metricSnapshots) { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { if (snapshot instanceof CounterSnapshot) { writeCreated(writer, snapshot); } else if (snapshot instanceof HistogramSnapshot) { @@ -106,14 +152,14 @@ public void writeCreated(Writer writer, MetricSnapshot snapshot) throws IOExcept metadataWritten = true; } writeNameAndLabels(writer, metadata.getPrometheusName(), "_created", data.getLabels()); - writeTimestamp(writer, data.getCreatedTimestampMillis()); + writePrometheusTimestamp(writer, data.getCreatedTimestampMillis(), timestampsInMs); writeScrapeTimestampAndNewline(writer, data); } } } private void writeCounter(Writer writer, CounterSnapshot snapshot) throws IOException { - if (snapshot.getDataPoints().size() > 0) { + if (!snapshot.getDataPoints().isEmpty()) { MetricMetadata metadata = snapshot.getMetadata(); writeMetadata(writer, "_total", "counter", metadata); for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) { @@ -363,7 +409,7 @@ private void writeScrapeTimestampAndNewline(Writer writer, DataPointSnapshot dat throws IOException { if (data.hasScrapeTimestamp()) { writer.write(' '); - writeTimestamp(writer, data.getScrapeTimestampMillis()); + writePrometheusTimestamp(writer, data.getScrapeTimestampMillis(), timestampsInMs); } writer.write('\n'); } diff --git a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java index dffa8ddef..787a11c01 100644 --- a/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java +++ b/prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java @@ -21,7 +21,20 @@ static void writeDouble(Writer writer, double d) throws IOException { } } - static void writeTimestamp(Writer writer, long timestampMs) throws IOException { + static void writePrometheusTimestamp(Writer writer, long timestampMs, boolean timestampsInMs) + throws IOException { + if (timestampsInMs) { + // correct for prometheus exposition format + // https://prometheus.io/docs/instrumenting/exposition_formats/#text-format-details + writer.write(Long.toString(timestampMs)); + } else { + // incorrect for prometheus exposition format - + // but we need to support it for backwards compatibility + writeOpenMetricsTimestamp(writer, timestampMs); + } + } + + static void writeOpenMetricsTimestamp(Writer writer, long timestampMs) throws IOException { writer.write(Long.toString(timestampMs / 1000L)); writer.write("."); long ms = timestampMs % 1000; diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java index 7fae4a2fb..aa50d9876 100644 --- a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatWriterTest.java @@ -7,7 +7,7 @@ class ExpositionFormatWriterTest { - private final ExpositionFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); + private final ExpositionFormatWriter writer = OpenMetricsTextFormatWriter.create(); @Test void toDebugString() { diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java index be6c42284..c0824c8e0 100644 --- a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java @@ -2739,7 +2739,8 @@ public void testLabelValueEscape() throws IOException { private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, false); + OpenMetricsTextFormatWriter writer = + OpenMetricsTextFormatWriter.builder().setCreatedTimestampsEnabled(true).build(); writer.write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } @@ -2747,7 +2748,11 @@ private void assertOpenMetricsText(String expected, MetricSnapshot snapshot) thr private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true); + OpenMetricsTextFormatWriter writer = + OpenMetricsTextFormatWriter.builder() + .setCreatedTimestampsEnabled(true) + .setExemplarsOnAllMetricTypesEnabled(true) + .build(); writer.write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } @@ -2755,23 +2760,30 @@ private void assertOpenMetricsTextWithExemplarsOnAllTimeSeries( private void assertOpenMetricsTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, false); + OpenMetricsTextFormatWriter writer = OpenMetricsTextFormatWriter.create(); writer.write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } private void assertPrometheusText(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(true); - writer.write(out, MetricSnapshots.of(snapshot)); + + getPrometheusWriter(PrometheusTextFormatWriter.builder().setIncludeCreatedTimestamps(true)) + .write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } + @SuppressWarnings("deprecation") + private static PrometheusTextFormatWriter getPrometheusWriter( + PrometheusTextFormatWriter.Builder builder) { + return builder.setTimestampsInMs(false).build(); + } + private void assertPrometheusTextWithoutCreated(String expected, MetricSnapshot snapshot) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrometheusTextFormatWriter writer = new PrometheusTextFormatWriter(false); - writer.write(out, MetricSnapshots.of(snapshot)); + getPrometheusWriter(PrometheusTextFormatWriter.builder()) + .write(out, MetricSnapshots.of(snapshot)); assertThat(out).hasToString(expected); } diff --git a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java index dece52abb..3f3558160 100644 --- a/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java +++ b/prometheus-metrics-exposition-textformats/src/test/java/io/prometheus/metrics/expositionformats/TextFormatUtilTest.java @@ -1,5 +1,6 @@ package io.prometheus.metrics.expositionformats; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; @@ -21,4 +22,16 @@ private static String escape(String s) throws IOException { TextFormatUtil.writeEscapedLabelValue(writer, s); return writer.toString(); } + + @Test + void testWritePrometheusTimestamp() throws IOException { + assertThat(writePrometheusTimestamp(true)).isEqualTo("1000"); + assertThat(writePrometheusTimestamp(false)).isEqualTo("1.000"); + } + + private static String writePrometheusTimestamp(boolean timestampsInMs) throws IOException { + StringWriter writer = new StringWriter(); + TextFormatUtil.writePrometheusTimestamp(writer, 1000, timestampsInMs); + return writer.toString(); + } } From 62561aa2baf26550c556d95c792ee4189a89309b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:14:40 +0200 Subject: [PATCH 577/980] Bump junit-jupiter.version from 5.12.2 to 5.12.2 (#1329) Bumps `junit-jupiter.version` from 5.12.2 to 5.12.2. Updates `org.junit.jupiter:junit-jupiter` from 5.12.2 to 5.12.2
      Commits

      Updates `org.junit.jupiter:junit-jupiter-params` from 5.12.2 to 5.12.2
      Commits

      Updates `org.junit:junit-bom` from 5.12.0 to 5.12.2
      Release notes

      Sourced from org.junit:junit-bom's releases.

      JUnit 5.12.2 = Platform 1.12.2 + Jupiter 5.12.2 + Vintage 5.12.2

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.1...r5.12.2

      JUnit 5.12.1 = Platform 1.12.1 + Jupiter 5.12.1 + Vintage 5.12.1

      See Release Notes.

      Full Changelog: https://github.com/junit-team/junit5/compare/r5.12.0...r5.12.1

      Commits
      • 0a44659 Release 5.12.2
      • 4c7dfdc Finalize 5.12.2 release notes
      • 561613e Fix handling of CleanupMode.ON_SUCCESS
      • 19d07d2 Add 5.12.2 release notes from template
      • 803cbb6 Add build parameter for enabling dry-run mode for test execution
      • eb43e62 Back to snapshots for further development
      • ba9c9ae Release 5.12.1
      • e28ad4a Finalize 5.12.1 release notes
      • 1044e2c Move entry to 5.12.1 release notes
      • bea821d Fix Javadoc formatting
      • Additional commits viewable in compare view

      Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 286aa8802..0fd3d26ba 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -22,7 +22,7 @@ 17 - 5.12.0 + 5.12.2 From 2838f6aa41496a06aec4663857e4bf70f690d1d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:14:46 +0200 Subject: [PATCH 578/980] Bump com.google.guava:guava from 33.4.7-jre to 33.4.8-jre (#1330) Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.4.7-jre to 33.4.8-jre.
      Release notes

      Sourced from com.google.guava:guava's releases.

      33.4.8

      Guava 33.4.8 fixes a problem that we introduced while starting to migrate guava-android off Unsafe in 33.4.7.

      Even if you're not upgrading from Guava 33.4.0 or earlier, still read the release notes for Guava 33.4.1. Those release notes contain information about the effects of Guava 33.4.5 and higher on the module system.

      Maven

      <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>33.4.8-jre</version>
        <!-- or, for Android: -->
        <version>33.4.8-android</version>
      </dependency>
      

      Jar files

      Guava requires one runtime dependency, which you can download here:

      Javadoc

      JDiff

      Changelog

      • util.concurrent: Removed our VarHandle code from guava-android. While the code was never used at runtime under Android, it was causing problems under the Android Gradle Plugin with a minSdkVersion below 26. To continue to avoid sun.misc.Unsafe under the JVM, guava-android will now always use AtomicReferenceFieldUpdater when run there. (75da92419a)
      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.guava:guava&package-manager=maven&previous-version=33.4.7-jre&new-version=33.4.8-jre)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e2f5d01eb..ab8b80faa 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ UTF-8 --module-name-need-to-be-overriden-- 4.30.2 - 33.4.7-jre + 33.4.8-jre 5.12.2 2.15.0-alpha 8 From 8d80d77da11ab94dbea6e6a52f8ab0e3a4b38c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20St=C3=A4ber?= Date: Tue, 15 Apr 2025 16:15:20 +0200 Subject: [PATCH 579/980] Fix next SNAPSHOT version (#1217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tiny fix. --------- Signed-off-by: Fabian Stäber Signed-off-by: Gregor Zeitlinger Co-authored-by: Gregor Zeitlinger --- benchmarks/pom.xml | 2 +- .../example-greeting-service/pom.xml | 2 +- .../example-hello-world-app/pom.xml | 2 +- examples/example-exemplars-tail-sampling/pom.xml | 2 +- examples/example-exporter-httpserver/pom.xml | 2 +- examples/example-exporter-multi-target/pom.xml | 2 +- examples/example-exporter-opentelemetry/pom.xml | 2 +- examples/example-exporter-servlet-tomcat/pom.xml | 2 +- examples/example-native-histogram/pom.xml | 2 +- examples/example-prometheus-properties/pom.xml | 2 +- examples/example-simpleclient-bridge/pom.xml | 2 +- examples/pom.xml | 2 +- integration-tests/it-common/pom.xml | 2 +- .../it-exporter/it-exporter-httpserver-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-jetty-sample/pom.xml | 2 +- .../it-exporter/it-exporter-servlet-tomcat-sample/pom.xml | 2 +- integration-tests/it-exporter/it-exporter-test/pom.xml | 2 +- integration-tests/it-exporter/it-no-protobuf-test/pom.xml | 2 +- integration-tests/it-exporter/pom.xml | 2 +- integration-tests/it-pushgateway/pom.xml | 2 +- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- integration-tests/pom.xml | 2 +- mise.toml | 3 +++ pom.xml | 2 +- prometheus-metrics-bom/pom.xml | 2 +- prometheus-metrics-config/pom.xml | 2 +- prometheus-metrics-core/pom.xml | 2 +- prometheus-metrics-exporter-common/pom.xml | 2 +- prometheus-metrics-exporter-httpserver/pom.xml | 2 +- .../pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry-shaded/pom.xml | 2 +- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- prometheus-metrics-exporter-pushgateway/pom.xml | 2 +- prometheus-metrics-exporter-servlet-jakarta/pom.xml | 2 +- prometheus-metrics-exporter-servlet-javax/pom.xml | 2 +- prometheus-metrics-exposition-formats-shaded/pom.xml | 2 +- prometheus-metrics-exposition-formats/pom.xml | 2 +- prometheus-metrics-exposition-textformats/pom.xml | 2 +- prometheus-metrics-instrumentation-caffeine/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard/pom.xml | 2 +- prometheus-metrics-instrumentation-dropwizard5/pom.xml | 2 +- prometheus-metrics-instrumentation-guava/pom.xml | 2 +- prometheus-metrics-instrumentation-jvm/pom.xml | 2 +- prometheus-metrics-model/pom.xml | 2 +- prometheus-metrics-simpleclient-bridge/pom.xml | 2 +- prometheus-metrics-tracer/pom.xml | 2 +- .../prometheus-metrics-tracer-common/pom.xml | 2 +- .../prometheus-metrics-tracer-initializer/pom.xml | 2 +- .../prometheus-metrics-tracer-otel-agent/pom.xml | 2 +- .../prometheus-metrics-tracer-otel/pom.xml | 2 +- 51 files changed, 53 insertions(+), 50 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 98d084787..8e476d5a6 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT benchmarks diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml index a5c9d9ce4..dfd151cb8 100644 --- a/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-greeting-service/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-greeting-service diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml index 4b452182a..475f10e91 100644 --- a/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml +++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/pom.xml @@ -5,7 +5,7 @@ io.prometheus example-exemplars-tail-sampling - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-hello-world-app diff --git a/examples/example-exemplars-tail-sampling/pom.xml b/examples/example-exemplars-tail-sampling/pom.xml index 3c62dfb66..84117e965 100644 --- a/examples/example-exemplars-tail-sampling/pom.xml +++ b/examples/example-exemplars-tail-sampling/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-exemplars-tail-sampling diff --git a/examples/example-exporter-httpserver/pom.xml b/examples/example-exporter-httpserver/pom.xml index 74124c6bd..575cc479a 100644 --- a/examples/example-exporter-httpserver/pom.xml +++ b/examples/example-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-exporter-httpserver diff --git a/examples/example-exporter-multi-target/pom.xml b/examples/example-exporter-multi-target/pom.xml index 8ba600b73..8b7382275 100644 --- a/examples/example-exporter-multi-target/pom.xml +++ b/examples/example-exporter-multi-target/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-exporter-multi-target diff --git a/examples/example-exporter-opentelemetry/pom.xml b/examples/example-exporter-opentelemetry/pom.xml index e8546c5a0..057022269 100644 --- a/examples/example-exporter-opentelemetry/pom.xml +++ b/examples/example-exporter-opentelemetry/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-exporter-opentelemetry diff --git a/examples/example-exporter-servlet-tomcat/pom.xml b/examples/example-exporter-servlet-tomcat/pom.xml index 11ddaccef..96ca3c3ca 100644 --- a/examples/example-exporter-servlet-tomcat/pom.xml +++ b/examples/example-exporter-servlet-tomcat/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-exporter-servlet-tomcat diff --git a/examples/example-native-histogram/pom.xml b/examples/example-native-histogram/pom.xml index 3aebe8278..0d17251ae 100644 --- a/examples/example-native-histogram/pom.xml +++ b/examples/example-native-histogram/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-native-histogram diff --git a/examples/example-prometheus-properties/pom.xml b/examples/example-prometheus-properties/pom.xml index 112b775d9..0c910483f 100644 --- a/examples/example-prometheus-properties/pom.xml +++ b/examples/example-prometheus-properties/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-prometheus-properties diff --git a/examples/example-simpleclient-bridge/pom.xml b/examples/example-simpleclient-bridge/pom.xml index abd461450..0e2607f1c 100644 --- a/examples/example-simpleclient-bridge/pom.xml +++ b/examples/example-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus examples - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT example-simpleclient-bridge diff --git a/examples/pom.xml b/examples/pom.xml index 3e7864ff1..db1b56b3e 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT examples diff --git a/integration-tests/it-common/pom.xml b/integration-tests/it-common/pom.xml index 511cf9a8c..57e8947c7 100644 --- a/integration-tests/it-common/pom.xml +++ b/integration-tests/it-common/pom.xml @@ -6,7 +6,7 @@ io.prometheus integration-tests - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-common diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml index 25696a247..e44f4396a 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter-httpserver-sample diff --git a/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml b/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml index 4a0dc8772..825081d3c 100644 --- a/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml +++ b/integration-tests/it-exporter/it-exporter-no-protobuf/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter-no-protobuf diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml index d6a9972ce..76334c3ff 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter-servlet-jetty-sample diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml index 048e9d976..534eeed9a 100644 --- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml +++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter-servlet-tomcat-sample diff --git a/integration-tests/it-exporter/it-exporter-test/pom.xml b/integration-tests/it-exporter/it-exporter-test/pom.xml index 5a6496ba2..13ade72d0 100644 --- a/integration-tests/it-exporter/it-exporter-test/pom.xml +++ b/integration-tests/it-exporter/it-exporter-test/pom.xml @@ -6,7 +6,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter-test diff --git a/integration-tests/it-exporter/it-no-protobuf-test/pom.xml b/integration-tests/it-exporter/it-no-protobuf-test/pom.xml index 8ceda5e8f..2e5599205 100644 --- a/integration-tests/it-exporter/it-no-protobuf-test/pom.xml +++ b/integration-tests/it-exporter/it-no-protobuf-test/pom.xml @@ -5,7 +5,7 @@ io.prometheus it-exporter - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-no-protobuf-test diff --git a/integration-tests/it-exporter/pom.xml b/integration-tests/it-exporter/pom.xml index 4ea63136e..685c8b0b0 100644 --- a/integration-tests/it-exporter/pom.xml +++ b/integration-tests/it-exporter/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-exporter diff --git a/integration-tests/it-pushgateway/pom.xml b/integration-tests/it-pushgateway/pom.xml index 15f99ff46..783f83bea 100644 --- a/integration-tests/it-pushgateway/pom.xml +++ b/integration-tests/it-pushgateway/pom.xml @@ -5,7 +5,7 @@ io.prometheus integration-tests - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT it-pushgateway diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 0fd3d26ba..2417246eb 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -14,7 +14,7 @@ io.prometheus it-spring-boot-smoke-test - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT Integration Test - Spring Smoke Tests diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 3a8d1343d..3b5f11ef3 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT integration-tests diff --git a/mise.toml b/mise.toml index f1032d2a4..cd4046f35 100644 --- a/mise.toml +++ b/mise.toml @@ -46,6 +46,9 @@ tools.java = "graalvm-22.3.3+java17" run = "../../mvnw test -PnativeTest" dir = "integration-tests/it-spring-boot-smoke-test" +[tasks.set-version] +run = 'mvn versions:set -DnewVersion={{arg(name="version")}}' + [settings] # to get lock file support and for go backend experimental = true diff --git a/pom.xml b/pom.xml index ab8b80faa..52e9cd642 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT Prometheus Metrics Library http://github.com/prometheus/client_java diff --git a/prometheus-metrics-bom/pom.xml b/prometheus-metrics-bom/pom.xml index e38595da0..baa52cd0e 100644 --- a/prometheus-metrics-bom/pom.xml +++ b/prometheus-metrics-bom/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-bom diff --git a/prometheus-metrics-config/pom.xml b/prometheus-metrics-config/pom.xml index 420ed8a13..a6c8e008f 100644 --- a/prometheus-metrics-config/pom.xml +++ b/prometheus-metrics-config/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-config diff --git a/prometheus-metrics-core/pom.xml b/prometheus-metrics-core/pom.xml index 7305675bd..1f1079992 100644 --- a/prometheus-metrics-core/pom.xml +++ b/prometheus-metrics-core/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-core diff --git a/prometheus-metrics-exporter-common/pom.xml b/prometheus-metrics-exporter-common/pom.xml index e54f925fd..4d8c5dde6 100644 --- a/prometheus-metrics-exporter-common/pom.xml +++ b/prometheus-metrics-exporter-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-common diff --git a/prometheus-metrics-exporter-httpserver/pom.xml b/prometheus-metrics-exporter-httpserver/pom.xml index 5e639f3f8..efeb6fc80 100644 --- a/prometheus-metrics-exporter-httpserver/pom.xml +++ b/prometheus-metrics-exporter-httpserver/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-httpserver diff --git a/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml index a1ee03d71..533b05956 100644 --- a/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry-otel-agent-resources/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry-otel-agent-resources diff --git a/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml b/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml index 98c7966f8..5c2c6e22a 100644 --- a/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry-shaded/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index fa02e3706..9fb29adbe 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-opentelemetry-no-otel diff --git a/prometheus-metrics-exporter-pushgateway/pom.xml b/prometheus-metrics-exporter-pushgateway/pom.xml index a3881f472..aa02be7c6 100644 --- a/prometheus-metrics-exporter-pushgateway/pom.xml +++ b/prometheus-metrics-exporter-pushgateway/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-pushgateway diff --git a/prometheus-metrics-exporter-servlet-jakarta/pom.xml b/prometheus-metrics-exporter-servlet-jakarta/pom.xml index 3cf77ca86..c8852f597 100644 --- a/prometheus-metrics-exporter-servlet-jakarta/pom.xml +++ b/prometheus-metrics-exporter-servlet-jakarta/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-jakarta diff --git a/prometheus-metrics-exporter-servlet-javax/pom.xml b/prometheus-metrics-exporter-servlet-javax/pom.xml index b5657ffb0..b173a3b07 100644 --- a/prometheus-metrics-exporter-servlet-javax/pom.xml +++ b/prometheus-metrics-exporter-servlet-javax/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exporter-servlet-javax diff --git a/prometheus-metrics-exposition-formats-shaded/pom.xml b/prometheus-metrics-exposition-formats-shaded/pom.xml index 486336105..eee3ea2db 100644 --- a/prometheus-metrics-exposition-formats-shaded/pom.xml +++ b/prometheus-metrics-exposition-formats-shaded/pom.xml @@ -7,7 +7,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exposition-formats diff --git a/prometheus-metrics-exposition-formats/pom.xml b/prometheus-metrics-exposition-formats/pom.xml index 0a00907bd..e174a254f 100644 --- a/prometheus-metrics-exposition-formats/pom.xml +++ b/prometheus-metrics-exposition-formats/pom.xml @@ -7,7 +7,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exposition-formats-no-protobuf diff --git a/prometheus-metrics-exposition-textformats/pom.xml b/prometheus-metrics-exposition-textformats/pom.xml index 13ab9e5e7..87ede09d6 100644 --- a/prometheus-metrics-exposition-textformats/pom.xml +++ b/prometheus-metrics-exposition-textformats/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-exposition-textformats diff --git a/prometheus-metrics-instrumentation-caffeine/pom.xml b/prometheus-metrics-instrumentation-caffeine/pom.xml index dd471254a..38236ebf2 100644 --- a/prometheus-metrics-instrumentation-caffeine/pom.xml +++ b/prometheus-metrics-instrumentation-caffeine/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-caffeine diff --git a/prometheus-metrics-instrumentation-dropwizard/pom.xml b/prometheus-metrics-instrumentation-dropwizard/pom.xml index 54c5c7ce2..050a07d15 100644 --- a/prometheus-metrics-instrumentation-dropwizard/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-dropwizard diff --git a/prometheus-metrics-instrumentation-dropwizard5/pom.xml b/prometheus-metrics-instrumentation-dropwizard5/pom.xml index e79f236ef..e377f78c2 100644 --- a/prometheus-metrics-instrumentation-dropwizard5/pom.xml +++ b/prometheus-metrics-instrumentation-dropwizard5/pom.xml @@ -6,7 +6,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-dropwizard5 diff --git a/prometheus-metrics-instrumentation-guava/pom.xml b/prometheus-metrics-instrumentation-guava/pom.xml index 06393868d..2381493bb 100644 --- a/prometheus-metrics-instrumentation-guava/pom.xml +++ b/prometheus-metrics-instrumentation-guava/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-guava diff --git a/prometheus-metrics-instrumentation-jvm/pom.xml b/prometheus-metrics-instrumentation-jvm/pom.xml index 24758db8c..ba28d9ad0 100644 --- a/prometheus-metrics-instrumentation-jvm/pom.xml +++ b/prometheus-metrics-instrumentation-jvm/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-instrumentation-jvm diff --git a/prometheus-metrics-model/pom.xml b/prometheus-metrics-model/pom.xml index 4e803ee5a..3c6af3fe3 100644 --- a/prometheus-metrics-model/pom.xml +++ b/prometheus-metrics-model/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-model diff --git a/prometheus-metrics-simpleclient-bridge/pom.xml b/prometheus-metrics-simpleclient-bridge/pom.xml index 76f0b203d..d81cd879e 100644 --- a/prometheus-metrics-simpleclient-bridge/pom.xml +++ b/prometheus-metrics-simpleclient-bridge/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-simpleclient-bridge diff --git a/prometheus-metrics-tracer/pom.xml b/prometheus-metrics-tracer/pom.xml index 885120d4a..6511d93ce 100644 --- a/prometheus-metrics-tracer/pom.xml +++ b/prometheus-metrics-tracer/pom.xml @@ -5,7 +5,7 @@ io.prometheus client_java - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-tracer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml index fcdf81d2f..40c3d566f 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-common/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-tracer-common diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml index 432fa0dfa..c32ab9aed 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-initializer/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-tracer-initializer diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml index d4efbd099..3ab18baf1 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel-agent/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel-agent diff --git a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml index 72fdb71d6..68dd6c81a 100644 --- a/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml +++ b/prometheus-metrics-tracer/prometheus-metrics-tracer-otel/pom.xml @@ -5,7 +5,7 @@ io.prometheus prometheus-metrics-tracer - 10.0.0-SNAPSHOT + 1.4.0-SNAPSHOT prometheus-metrics-tracer-otel From 8c551d6a4717f0d03ad73d478034d7935e74faf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:55:57 +0200 Subject: [PATCH 580/980] Bump com.google.errorprone:error_prone_core from 2.37.0 to 2.38.0 (#1332) Bumps [com.google.errorprone:error_prone_core](https://github.com/google/error-prone) from 2.37.0 to 2.38.0.
      Release notes

      Sourced from com.google.errorprone:error_prone_core's releases.

      Error Prone 2.38.0

      New checks:

      Closed issues: #4924, #4897, #4995

      Full changelog: https://github.com/google/error-prone/compare/v2.37.0...v2.38.0

      Commits
      • a07bd3e Release Error Prone 2.38.0
      • 09fd394 Fix typo in NullTernary.md
      • 4171fd7 FindIdentifiers: find binding variables declared by enclosing or earlier if...
      • d78f515 Audit each use of ElementKind.LOCAL_VARIABLE, and add BINDING_VARIABLE if app...
      • 6f94a97 Tolerate default cases in switches as being present to handle version skew
      • 0223abb Support @LenientFormatString in LenientFormatStringValidation.
      • cb7dfaf Remove the Side enum.
      • d64c9ce Promote error prone check TestExceptionChecker to ERROR within Google (blaze ...
      • c0ce475 Move TargetType to a top-level class alongside ASTHelpers.
      • 90b8efb Allow binding to BINDING_VARIABLEs in GuardedByBinder.
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_core&package-manager=maven&previous-version=2.37.0&new-version=2.38.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      --------- Signed-off-by: dependabot[bot] Signed-off-by: Gregor Zeitlinger Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Gregor Zeitlinger --- .../client/it/common/LogConsumer.java | 13 +++----- pom.xml | 2 +- .../snapshots/HistogramSnapshotTest.java | 32 +++++++++---------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java index 0e6cfbcc6..a57c5a7f3 100644 --- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java +++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java @@ -19,15 +19,10 @@ public static LogConsumer withPrefix(String prefix) { @Override public void accept(OutputFrame outputFrame) { switch (outputFrame.getType()) { - case STDOUT: - System.out.print(prefix + " - " + outputFrame.getUtf8String()); - break; - case END: - System.out.println(prefix + " - END"); - break; - default: // STDERR or unexpected - System.err.print(prefix + " - " + outputFrame.getUtf8String()); - break; + case STDOUT -> System.out.print(prefix + " - " + outputFrame.getUtf8String()); + case END -> System.out.println(prefix + " - END"); + default -> // STDERR or unexpected + System.err.print(prefix + " - " + outputFrame.getUtf8String()); } } } diff --git a/pom.xml b/pom.xml index 52e9cd642..664c51873 100644 --- a/pom.xml +++ b/pom.xml @@ -373,7 +373,7 @@ com.google.errorprone error_prone_core - 2.37.0 + 2.38.0

      🚀 New Features

      🐞 Bug fixes

      ✍ Other changes

      📦 Dependency updates

      ... (truncated)

      Commits
      • e948a9f Bump the version for the latest release
      • 7767f2f Merge pull request #2927 from wernerblanck/master
      • df1f4f9 Always use the system default DocumentBuilderFactory, TransformerFactory ...
      • 0da30c8 Merge pull request #3026 from Vodafone/feature/add_truncation_of_long_tails_t...
      • 32e3995 Merge pull request #2997 from wiremock/basic-auth-case-fix
      • 4da8c0f Merge pull request #2991 from MasonM/remove-unused-mappings
      • 8a796d5 Merge pull request #3014 from lhcopetti/include-client-ip-matcher
      • ec515d7 Merge pull request #3022 from ns-amosc/bugfix/multipart-related-template-dupl...
      • c5ee8a1 Fix code formatting to comply with Spotless rules
      • b632839 feat: document new clientIp matcher in openapi
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.wiremock:wiremock&package-manager=maven&previous-version=3.12.1&new-version=3.13.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- prometheus-metrics-exporter-opentelemetry/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/pom.xml b/prometheus-metrics-exporter-opentelemetry/pom.xml index 9fb29adbe..8d9b4fdb6 100644 --- a/prometheus-metrics-exporter-opentelemetry/pom.xml +++ b/prometheus-metrics-exporter-opentelemetry/pom.xml @@ -73,7 +73,7 @@ org.wiremock wiremock - 3.12.1 + 3.13.0 test From 785f1638e54588ea74fe8feaa2e518b54b1249ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Apr 2025 13:36:49 +0000 Subject: [PATCH 582/980] Bump org.testcontainers:junit-jupiter from 1.20.6 to 1.21.0 (#1333) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.20.6 to 1.21.0.
      Release notes

      Sourced from org.testcontainers:junit-jupiter's releases.

      1.21.0

      What's Changed

      ⚠️ Breaking API changes

      🚀 Features & Enhancements

      ☠️ Deprecations

      🐛 Bug Fixes

      📖 Documentation

      🧹 Housekeeping

      📦 Dependency updates

      Commits

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.testcontainers:junit-jupiter&package-manager=maven&previous-version=1.20.6&new-version=1.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 3b5f11ef3..d408995e9 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -56,7 +56,7 @@ org.testcontainers junit-jupiter - 1.20.6 + 1.21.0 test From 365d2056c2ae2036d622a8e86e97ab0da003ede2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 10:04:36 +0200 Subject: [PATCH 583/980] Bump org.springframework.boot:spring-boot-starter-parent from 3.4.4 to 3.4.5 (#1336) Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.4.4 to 3.4.5.
      Release notes

      Sourced from org.springframework.boot:spring-boot-starter-parent's releases.

      v3.4.5

      :lady_beetle: Bug Fixes

      • Spring Boot with native image container image build fails on podman due to directory permissions #45256
      • Neo4jReactiveDataAutoConfiguration assumes that certain beans are available #45235
      • Wrong jOOQ exception translator with empty db name #45219
      • MessageSourceMessageInterpolator does not replace a parameter when the message matches its code #45213
      • IntegrationMbeanExporter is not eligible for getting processed by all BeanPostProcessors warnings are shown when using JMX #45194
      • OAuth2AuthorizationServerJwtAutoConfiguration uses @ConditionalOnClass incorrectly #45178
      • MongoDB's dependency management is missing Kotlin coroutine driver modules #45159
      • ImagePlatform can cause "OS must not be empty" IllegalArgumentException #45153
      • TypeUtils does not handle generics with identical names in different positions #45039
      • HttpClient5 5.4.3 breaks local Docker transport #45028
      • spring.datasource.hikari.data-source-class-name cannot be used as a driver class name is always required and Hikari does not accept both #45002
      • Post-processing to apply custom JdbcConnectionDetails triggers an NPE in Hikari if the JDBC URL is for an unknown driver #44998
      • DataSourceBuilder triggers an NPE in Hikari when trying to build a DataSource with a JDBC URL for an unknown driver #44995
      • SSL config does not watch for symlink file changes #44887
      • EmbeddedLdapAutoConfiguration should not rely on PreDestroy #44874
      • DataSourceTransactionManagerAutoConfiguration should run after DataSourceAutoConfiguration #44819
      • JsonValueWriter can throw StackOverflowError on deeply nested items #44627
      • In a reactive web app, SslBundle can no longer open store file locations without using a 'file:' prefix #44535
      • Logging a Path object using structured logging throws StackOverflowError #44507

      :notebook_with_decorative_cover: Documentation

      • Make @Component a javadoc link #45258
      • Fix documentation links to buildpacks.io #45241
      • Clarify the use of multiple profile expressions with "spring.config.activate.on-profile" #45224
      • Show the use of token properties in authorization server clients configuration example #45176
      • Add details of the purpose of the metrics endpoint #45047
      • Escape the asterisk in spring-application.adoc #45033
      • Add reference to Styra (OPA) Spring Boot SDK #44976
      • Update CDS documentation to cover AOTCache #44970
      • WebFlux security documentation incorrectly links to servlet classes #44966
      • Replace mentions of deprecated MockBean annotation #44947
      • TaskExecution documentation should describe what happens when multiple Executor beans are present #44908
      • Documentation lists coordinates for some dependencies that are not actually managed #44879
      • Polish javadoc of SpringProfileAction #44826

      :hammer: Dependency Upgrades

      • Upgrade to AspectJ 1.9.24 #45184
      • Upgrade to Couchbase Client 3.7.9 #45072
      • Upgrade to Hibernate 6.6.13.Final #45073
      • Upgrade to HttpClient5 5.4.3 #45074
      • Upgrade to HttpCore5 5.3.4 #45075
      • Upgrade to Jaybird 5.0.7.java11 #45076
      • Upgrade to Jetty 12.0.19 #45077
      • Upgrade to jOOQ 3.19.22 #45078
      • Upgrade to Lombok 1.18.38 #45079

      ... (truncated)

      Commits
      • b882c29 Release v3.4.5
      • 918066f Merge branch '3.3.x' into 3.4.x
      • ab0c332 Next development version (v3.3.12-SNAPSHOT)
      • 71acf93 Merge branch '3.3.x' into 3.4.x
      • d2eaac6 Revert "Upgrade to Netty 4.1.120.Final"
      • d24a38f Merge branch '3.3.x' into 3.4.x
      • 933572a Upgrade to Netty 4.1.120.Final
      • 016b3de Upgrade to Netty 4.1.120.Final
      • 46a709a Merge branch '3.3.x' into 3.4.x
      • 55f67c9 Fix potential null problem in actuator
      • Additional commits viewable in compare view

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.springframework.boot:spring-boot-starter-parent&package-manager=maven&previous-version=3.4.4&new-version=3.4.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
      Dependabot commands and options
      You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
      Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration-tests/it-spring-boot-smoke-test/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/it-spring-boot-smoke-test/pom.xml b/integration-tests/it-spring-boot-smoke-test/pom.xml index 2417246eb..21622e7a0 100644 --- a/integration-tests/it-spring-boot-smoke-test/pom.xml +++ b/integration-tests/it-spring-boot-smoke-test/pom.xml @@ -8,7 +8,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.4 + 3.4.5 From 2625cb1974123b026b68e5f2d0f82f0658cccac0 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 29 Apr 2025 03:19:27 -0700 Subject: [PATCH 584/980] Eagerly reject null label values (#1335) Scraping generally doesn't support null label values and can throw NPEs at various points. It's easiest to debug such problems at the point null is introduced. Signed-off-by: Benjamin Peterson Signed-off-by: Benjamin Peterson --- .../metrics/core/metrics/StatefulMetric.java | 15 ++++++++++++++- .../metrics/core/metrics/StatefulMetricTest.java | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java index d7fb3afd0..87e8429f1 100644 --- a/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java +++ b/prometheus-metrics-core/src/main/java/io/prometheus/metrics/core/metrics/StatefulMetric.java @@ -112,7 +112,20 @@ public D labelValues(String... labelValues) { "Expected " + labelNames.length + " label values, but got " + labelValues.length + "."); } } - return data.computeIfAbsent(Arrays.asList(labelValues), l -> newDataPoint()); + return data.computeIfAbsent( + Arrays.asList(labelValues), + l -> { + for (int i = 0; i < l.size(); i++) { + if (l.get(i) == null) { + throw new IllegalArgumentException( + "null label value for metric " + + getMetadata().getName() + + " and label " + + labelNames[i]); + } + } + return newDataPoint(); + }); } /** diff --git a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java index 1120b06a3..e12618436 100644 --- a/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java +++ b/prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/StatefulMetricTest.java @@ -1,6 +1,7 @@ package io.prometheus.metrics.core.metrics; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.lang.reflect.Field; import java.util.Map; @@ -67,4 +68,12 @@ public void testClearNoLabels() { assertThat(counter.collect().getDataPoints()).hasSize(1); assertThat(counter.collect().getDataPoints().get(0).getValue()).isEqualTo(1.0); } + + @Test + public void testNullLabel() { + Counter counter = Counter.builder().name("test").labelNames("l1", "l2").build(); + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> counter.labelValues("l1", null)) + .withMessage("null label value for metric test and label l2"); + } } From 8f75de40e952cb33a306b4d4c95cdb9969655e90 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 29 Apr 2025 13:27:00 +0200 Subject: [PATCH 585/980] add Zizmor (#1337) Signed-off-by: Gregor Zeitlinger --- .github/workflows/acceptance-tests.yml | 6 ++- .github/workflows/build.yml | 6 ++- .github/workflows/github-pages.yaml | 55 ++++++++------------------ .github/workflows/lint.yml | 20 ++++++++++ .github/workflows/native-tests.yml | 6 ++- .github/workflows/release.yml | 8 +++- mise.lock | 12 ++++++ mise.toml | 33 ++++++++++++++++ scripts/build-release.sh | 1 - 9 files changed, 103 insertions(+), 44 deletions(-) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 1f40d6e55..334602715 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -6,12 +6,16 @@ on: pull_request: branches: [ "main" ] +permissions: {} + jobs: acceptance-tests: runs-on: ubuntu-24.04 steps: - name: Check out + with: + persist-credentials: false uses: actions/checkout@v4 - - uses: jdx/mise-action@v2 + - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 - name: Run acceptance tests run: mise run acceptance-test diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9f07e786..679ce1752 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,12 +6,16 @@ on: pull_request: branches: [ "main" ] +permissions: {} + jobs: build: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - uses: jdx/mise-action@v2 + with: + persist-credentials: false + - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 - name: Cache local Maven repository uses: actions/cache@v4 with: diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 46fe56c96..0f1b8ac5c 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -11,11 +11,7 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write +permissions: {} # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. @@ -32,55 +28,38 @@ jobs: # Build job build: runs-on: ubuntu-24.04 - env: - HUGO_VERSION: 0.115.4 steps: - uses: actions/checkout@v4 with: + persist-credentials: false fetch-tags: 'true' fetch-depth: 0 - - name: Set up JDK - uses: actions/setup-java@v4 + - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 with: - java-version: 17 - distribution: temurin - cache: 'maven' - - name: Set release version - run: ./scripts/set-release-version-github-pages.sh - - name: Install Hugo CLI - run: | - wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ - && sudo dpkg -i ${{ runner.temp }}/hugo.deb - - name: Make Javadoc - run: ./mvnw -B clean compile javadoc:javadoc javadoc:aggregate -P javadoc - - name: Move the Javadoc to docs/static/api/ - run: mv ./target/reports/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api + cache: 'false' + - name: Prepare GitHub Pages + run: mise run prepare-gh-pages + with: + permissions: block - name: Setup Pages id: pages uses: actions/configure-pages@v5 - - name: Install Node.js dependencies - run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" - working-directory: ./docs - - name: Build with Hugo - env: - # For maximum backward compatibility with Hugo modules - HUGO_ENVIRONMENT: production - HUGO_ENV: production - run: | - hugo \ - --gc \ - --minify \ - --baseURL "${{ steps.pages.outputs.base_url }}/" - working-directory: ./docs - - name: ls ./docs/public/api - run: echo 'ls ./docs/public/api' && ls ./docs/public/api + - name: Build GitHub Pages + run: mise run build-gh-pages + with: + permissions: block - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: ./docs/public + # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages # Deployment job deploy: + permissions: + contents: read + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..ee3cffab2 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,20 @@ +--- +name: Acceptance Tests + +on: [pull_request] + +permissions: {} + +jobs: + acceptance-tests: + permissions: {} + runs-on: ubuntu-24.04 + steps: + - name: Check out + with: + persist-credentials: false + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 + - name: Lint + run: mise run lint-all + diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index f124c8458..6d21a5faa 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -6,12 +6,16 @@ on: pull_request: branches: [ "main" ] +permissions: {} + jobs: native-tests: runs-on: ubuntu-24.04 steps: - name: Check out + with: + persist-credentials: false uses: actions/checkout@v4 - - uses: jdx/mise-action@v2 + - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 - name: Run native tests run: mise run native-test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bf63247f3..bf0e60d02 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,7 @@ jobs: deploy: if: ${{ github.repository == 'prometheus/client_java' }} runs-on: ubuntu-24.04 + permissions: {} steps: - name: Debug gpg key - remove after debugging @@ -19,16 +20,19 @@ jobs: echo "$GPG_SIGNING_KEY" | gpg --batch --import-options import-show --import - name: Checkout Plugin Repository uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set Up JDK uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin - cache: 'maven' - name: Build with Maven - run: ./scripts/build-release.sh ${{ github.ref_name }} + run: ./scripts/build-release.sh + env: + TAG: ${{ github.ref_name }} - name: Set up Apache Maven Central uses: actions/setup-java@v4 diff --git a/mise.lock b/mise.lock index 049ab1acf..d06f9f801 100644 --- a/mise.lock +++ b/mise.lock @@ -1,3 +1,11 @@ +[tools."cargo:zizmor"] +version = "1.6.0" +backend = "cargo:zizmor" + +[tools."go:github.com/gohugoio/hugo"] +version = "v0.147.0" +backend = "go:github.com/gohugoio/hugo" + [tools."go:github.com/grafana/oats"] version = "0.3.0" backend = "go:github.com/grafana/oats" @@ -6,6 +14,10 @@ backend = "go:github.com/grafana/oats" version = "temurin-17.0.13+11" backend = "core:java" +[tools.node] +version = "23.10.0" +backend = "core:node" + [tools.protoc] version = "30.2" backend = "aqua:protocolbuffers/protobuf/protoc" diff --git a/mise.toml b/mise.toml index cd4046f35..86ef33f8a 100644 --- a/mise.toml +++ b/mise.toml @@ -2,8 +2,11 @@ PROTO_GENERATION = "true" [tools] +"cargo:zizmor" = "latest" +"go:github.com/gohugoio/hugo" = "latest" "go:github.com/grafana/oats" = "latest" java = "temurin-17.0.13+11" +node = "latest" protoc = "latest" [tasks.ci] @@ -35,6 +38,12 @@ run = "./mvnw verify" description = "build all modules wihthout tests" run = "./mvnw install -DskipTests" +[tasks.lint-gh-actions] +run = "zizmor .github/" + +[tasks.lint-all] +depends = ["lint-gh-actions"] + [tasks.acceptance-test] description = "Run OATs acceptance tests" depends = "build" @@ -49,6 +58,30 @@ dir = "integration-tests/it-spring-boot-smoke-test" [tasks.set-version] run = 'mvn versions:set -DnewVersion={{arg(name="version")}}' +[tasks.javadoc] +run = [ + "./mvnw -B clean compile javadoc:javadoc javadoc:aggregate -P javadoc", + "mv ./target/reports/apidocs ./docs/static/api && echo && echo 'ls ./docs/static/api' && ls ./docs/static/api" +] + +[tasks.set-gh-pages-version] +run = "./scripts/set-release-version-github-pages.sh" + +[tasks.prepare-gh-pages] +description = "Prepare GitHub pages" +depends = ["javadoc", "set-gh-pages-version"] + +[tasks.build-gh-pages] +description = "Build GitHub pages" +# For maximum backward compatibility with Hugo modules +env = { HUGO_ENVIRONMENT = "production", HUGO_ENV = "production" } +dir = "docs" +run = [ + "npm ci", + "hugo --gc --minify --baseURL ${BASE_URL}/", + "echo 'ls ./docs/public/api' && ls ./docs/public/api" +] + [settings] # to get lock file support and for go backend experimental = true diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 8cbc50a61..df4e83645 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -2,7 +2,6 @@ set -euo pipefail -TAG=$1 VERSION=${TAG#v} mvn versions:set -DnewVersion=$VERSION From f08dab81769f07d22fa96b496f7577fb0bb18145 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 30 Apr 2025 17:41:02 +0200 Subject: [PATCH 586/980] fix gh pages, add super linter (#1338) Signed-off-by: Gregor Zeitlinger --- .editorconfig | 10 + .github/dependabot.yml | 7 +- .github/super-linter.env | 34 + .github/workflows/acceptance-tests.yml | 5 +- .github/workflows/build.yml | 6 +- .github/workflows/github-pages.yaml | 14 +- .github/workflows/{lint.yml => lint-rest.yml} | 4 +- .github/workflows/native-tests.yml | 5 +- .github/workflows/release.yml | 11 +- .github/workflows/super-linter.yml | 31 + .gitignore | 2 + .gitleaksignore | 2 + .yaml-lint.yml | 5 + CODE_OF_CONDUCT.md | 3 +- CONTRIBUTING.md | 13 +- MAINTAINERS.md | 10 +- README.md | 20 +- RELEASING.md | 7 +- benchmarks/README.md | 25 +- benchmarks/pom.xml | 229 +- .../client/CKMSQuantileBenchmark.java | 238 +- .../client/benchmark/CounterBenchmark.java | 42 +- .../client/benchmark/ExemplarsBenchmark.java | 42 +- .../client/benchmark/GaugeBenchmark.java | 57 +- .../SanitizeMetricNameBenchmark.java | 32 +- .../client/benchmark/SummaryBenchmark.java | 58 +- checkstyle.xml | 77 +- docs/README.md | 51 +- docs/content/_index.md | 44 +- docs/content/config/config.md | 201 +- docs/content/exporters/filter.md | 14 +- docs/content/exporters/formats.md | 21 +- docs/content/exporters/httpserver.md | 38 +- docs/content/exporters/pushgateway.md | 47 +- docs/content/exporters/servlet.md | 35 +- docs/content/exporters/spring.md | 82 +- docs/content/getting-started/callbacks.md | 23 +- docs/content/getting-started/labels.md | 54 +- docs/content/getting-started/metric-types.md | 159 +- docs/content/getting-started/multi-target.md | 176 +- docs/content/getting-started/performance.md | 34 +- docs/content/getting-started/quickstart.md | 52 +- docs/content/getting-started/registry.md | 34 +- docs/content/instrumentation/caffeine.md | 52 +- docs/content/instrumentation/guava.md | 24 +- docs/content/instrumentation/jvm.md | 146 +- docs/content/internals/model.md | 33 +- docs/content/migration/simpleclient.md | 151 +- docs/content/otel/names.md | 40 +- docs/content/otel/otlp.md | 36 +- docs/content/otel/tracing.md | 60 +- docs/themes/hugo-geekdoc/data/assets.json | 2 +- docs/themes/hugo-geekdoc/i18n/nl.yaml | 2 +- .../layouts/partials/language.html | 2 +- .../partials/microformats/opengraph.html | 2 +- .../partials/microformats/twitter_cards.html | 2 +- .../hugo-geekdoc/static/favicon/manifest.json | 2 +- .../static/js/116-341f79d9.chunk.min.js | 10871 ++- .../static/js/118-f1de6a20.chunk.min.js | 1788 +- .../static/js/19-86f47ecd.chunk.min.js | 1504 +- .../static/js/361-f7cd601a.chunk.min.js | 3737 +- .../static/js/423-897d7f17.chunk.min.js | 1866 +- .../static/js/430-cc171d93.chunk.min.js | 1567 +- .../static/js/433-f2655a46.chunk.min.js | 419 +- .../static/js/438-760c9ed3.chunk.min.js | 1150 +- .../static/js/476-86e5cf96.chunk.min.js | 495 +- .../static/js/506-6950d52c.chunk.min.js | 2920 +- .../static/js/519-8d0cec7f.chunk.min.js | 464 +- .../static/js/535-dcead599.chunk.min.js | 1380 +- .../static/js/545-8e970b03.chunk.min.js | 3020 +- .../static/js/546-560b35c2.chunk.min.js | 746 +- .../static/js/579-9222afff.chunk.min.js | 1099 +- .../static/js/626-1706197a.chunk.min.js | 231 +- .../static/js/637-86fbbecd.chunk.min.js | 13646 ++- .../static/js/639-88c6538a.chunk.min.js | 74386 +++++++++++++++- .../static/js/642-12e7dea2.chunk.min.js | 459 +- .../static/js/662-17acb8f4.chunk.min.js | 21856 ++++- .../static/js/728-5df4a5e5.chunk.min.js | 430 +- .../static/js/729-32b017b3.chunk.min.js | 2021 +- .../static/js/747-b55f0f97.chunk.min.js | 234 +- .../static/js/76-732e78f1.chunk.min.js | 1825 +- .../static/js/771-942a62df.chunk.min.js | 3177 +- .../static/js/773-8f0c4fb8.chunk.min.js | 2053 +- .../static/js/81-4e653aac.chunk.min.js | 426 +- .../static/js/813-0d3c16f5.chunk.min.js | 2894 +- .../static/js/940-25dfc794.chunk.min.js | 980 +- .../js/colortheme-d3e4d351.bundle.min.js | 301 +- .../static/js/katex-d4d5881d.bundle.min.js | 356 +- .../static/js/main-924a1933.bundle.min.js | 543 +- .../static/js/mermaid-d305d450.bundle.min.js | 460 +- .../static/js/search-9719be99.bundle.min.js | 3313 +- .../example-exemplars-tail-sampling/README.md | 134 +- .../config/grafana-dashboards.yaml | 2 +- .../config/grafana-datasources.yaml | 2 +- .../config/grafana-example-dashboard.json | 4 +- .../config/k6-script.js | 22 +- .../config/otelcol-config.yaml | 8 +- .../example-greeting-service/pom.xml | 126 +- .../example-hello-world-app/pom.xml | 126 +- .../example-exemplars-tail-sampling/pom.xml | 42 +- .../example-exporter-httpserver/README.md | 21 +- examples/example-exporter-httpserver/pom.xml | 109 +- .../example-exporter-multi-target/README.md | 24 +- .../example-exporter-multi-target/pom.xml | 109 +- .../example-exporter-opentelemetry/README.md | 9 +- .../oats-tests/agent/docker-compose.yml | 4 +- .../oats-tests/agent/example_target_info.json | 15 +- .../oats-tests/agent/oats.yaml | 10 +- .../agent/service-instance-id-check.py | 34 - .../agent/service_instance_id_check.py | 48 + .../oats-tests/http/docker-compose.yml | 4 +- .../oats-tests/http/oats.yaml | 8 +- .../example-exporter-opentelemetry/pom.xml | 109 +- .../example-exporter-servlet-tomcat/README.md | 55 +- .../example-exporter-servlet-tomcat/pom.xml | 124 +- examples/example-native-histogram/README.md | 18 +- .../grafana-dashboard-classic-histogram.json | 4 +- .../docker-compose/grafana-dashboards.yaml | 4 +- .../docker-compose/grafana-datasources.yaml | 1 - .../docker-compose/prometheus.yml | 4 +- examples/example-native-histogram/pom.xml | 108 +- .../example-prometheus-properties/README.md | 19 +- .../example-prometheus-properties/pom.xml | 108 +- .../example-simpleclient-bridge/README.md | 15 +- examples/example-simpleclient-bridge/pom.xml | 108 +- examples/pom.xml | 53 +- integration-tests/it-common/pom.xml | 78 +- .../test/resources/project_version.properties | 5 +- .../it-exporter-httpserver-sample/pom.xml | 98 +- .../it-exporter-no-protobuf/pom.xml | 120 +- .../it-exporter-servlet-jetty-sample/pom.xml | 127 +- .../it-exporter-servlet-tomcat-sample/pom.xml | 115 +- .../it-exporter/it-exporter-test/pom.xml | 40 +- .../metrics/it/exporter/test/ExporterIT.java | 12 +- .../it-exporter/it-no-protobuf-test/pom.xml | 43 +- integration-tests/it-exporter/pom.xml | 43 +- integration-tests/it-pushgateway/pom.xml | 136 +- .../test/resources/prometheus-basicauth.yaml | 4 +- .../src/test/resources/prometheus-ssl.yaml | 2 +- .../src/test/resources/prometheus.yaml | 2 +- .../test/resources/pushgateway-basicauth.yaml | 9 +- .../src/test/resources/pushgateway-ssl.yaml | 5 +- .../src/main/resources/application.yaml | 2 +- .../it/springboot/ApplicationTest.java | 3 +- integration-tests/pom.xml | 116 +- lychee.toml | 5 + mise.lock | 6 +- mise.toml | 18 +- mvnw | 248 +- pom.xml | 1042 +- prometheus-metrics-bom/pom.xml | 271 +- prometheus-metrics-config/pom.xml | 33 +- .../config/ExporterPropertiesTest.java | 6 +- .../ExporterPushgatewayPropertiesTest.java | 3 +- .../metrics/config/MetricsPropertiesTest.java | 6 +- .../PrometheusPropertiesLoaderTest.java | 3 +- prometheus-metrics-core/pom.xml | 90 +- .../core/metrics/CKMSQuantilesTest.java | 3 +- .../core/metrics/CallbackMetricTest.java | 9 +- .../metrics/core/metrics/HistogramTest.java | 6 +- .../metrics/core/metrics/InfoTest.java | 15 +- .../metrics/core/metrics/StateSetTest.java | 3 +- prometheus-metrics-exporter-common/pom.xml | 69 +- .../pom.xml | 49 +- .../pom.xml | 110 +- .../ResourceAttributesFromOtelAgent.java | 2 +- .../pom.xml | 276 +- .../pom.xml | 201 +- .../instrumentationScope.properties | 3 +- .../PrometheusInstrumentationScopeTest.java | 6 +- .../pom.xml | 68 +- .../pom.xml | 58 +- .../pom.xml | 73 +- .../pom.xml | 168 +- .../generate-protobuf.sh | 36 +- prometheus-metrics-exposition-formats/pom.xml | 256 +- .../pom.xml | 86 +- .../ExpositionFormatsTest.java | 40 +- .../pom.xml | 103 +- .../caffeine/CacheMetricsCollectorTest.java | 38 +- .../pom.xml | 135 +- .../dropwizard/DropwizardExportsTest.java | 156 +- .../pom.xml | 114 +- .../dropwizard5/DropwizardExportsTest.java | 115 +- .../labels/CustomLabelMapperTest.java | 60 +- .../pom.xml | 85 +- .../pom.xml | 75 +- .../jvm/JvmClassLoadingMetricsTest.java | 22 +- .../jvm/JvmCompilationMetricsTest.java | 12 +- .../jvm/JvmMemoryMetricsTest.java | 130 +- .../jvm/JvmNativeMemoryMetricsTest.java | 104 +- .../jvm/JvmRuntimeInfoMetricTest.java | 10 +- .../jvm/JvmThreadsMetricsTest.java | 58 +- prometheus-metrics-model/pom.xml | 34 +- .../pom.xml | 95 +- prometheus-metrics-tracer/pom.xml | 23 +- .../prometheus-metrics-tracer-common/pom.xml | 3 +- .../pom.xml | 3 +- .../pom.xml | 4 +- .../prometheus-metrics-tracer-otel/pom.xml | 3 +- scripts/build-release.sh | 2 +- scripts/super-linter.sh | 16 + simpleclient-archive/README.md | 8 +- .../integration_tests/it_common/pom.xml.bak | 3 +- .../client/it/common/Downloader.java | 49 +- .../client/it/common/LogConsumer.java | 47 +- .../prometheus/client/it/common/Scraper.java | 87 +- .../prometheus/client/it/common/Version.java | 14 +- .../prometheus/client/it/common/Volume.java | 145 +- .../test/resources/project_version.properties | 5 +- .../it_exemplars_otel_agent/pom.xml.bak | 3 +- .../ExampleSpringBootApp.java | 75 +- .../ExemplarsOpenTelemetryAgentIT.java | 131 +- .../it_exemplars_otel_sdk/pom.xml.bak | 3 +- .../it/exemplars_otel/ExampleApplication.java | 13 +- .../ExemplarsOpenTelemetrySdkIT.java | 231 +- .../it_java_versions/pom.xml.bak | 3 +- .../it/java_versions/ExampleApplication.java | 12 +- .../it/java_versions/JavaVersionsIT.java | 65 +- .../integration_tests/it_log4j2/pom.xml.bak | 3 +- .../client/it/log4j2/ExampleApplication.java | 7 +- .../prometheus/client/it/log4j2/Log4j2IT.java | 95 +- .../it_pushgateway/pom.xml.bak | 3 +- .../it/pushgateway/ExampleBatchJob.java | 53 +- .../client/it/pushgateway/PushGatewayIT.java | 144 +- .../src/test/resources/web-config.yml | 6 +- .../pom.xml.bak | 3 +- .../it/servlet/jakarta/ExampleServlet.java | 26 +- .../src/main/webapp/WEB-INF/web.xml | 83 +- .../ServletJakartaExporterWebXmlIT.java | 180 +- .../integration_tests/pom.xml.bak | 3 +- .../simpleclient_graphite_bridge/pom.xml.bak | 3 +- .../io/prometheus/client/bridge/Graphite.java | 54 +- .../client/bridge/GraphiteTest.java | 35 +- .../simpleclient_hibernate/pom.xml.bak | 3 +- .../HibernateStatisticsCollector.java | 373 +- .../HibernateStatisticsCollectorTest.java | 107 +- .../simpleclient_httpserver/pom.xml.bak | 3 +- .../client/exporter/HTTPServer.java | 812 +- .../exporter/SampleNameFilterSupplier.java | 26 +- .../client/exporter/ExampleExporter.java | 26 +- .../client/exporter/HttpRequest.java | 395 +- .../client/exporter/HttpResponse.java | 168 +- .../client/exporter/TestDaemonFlags.java | 59 +- .../client/exporter/TestHTTPServer.java | 264 +- .../simpleclient_jetty/pom.xml.bak | 3 +- .../jetty/JettyStatisticsCollector.java | 124 +- .../jetty/JettyStatisticsCollectorTest.java | 76 +- .../simpleclient_jetty_jdk8/pom.xml.bak | 3 +- .../QueuedThreadPoolStatisticsCollector.java | 31 +- ...euedThreadPoolStatisticsCollectorTest.java | 23 +- .../simpleclient_log4j/pom.xml.bak | 3 +- .../client/log4j/InstrumentedAppender.java | 17 +- .../log4j/InstrumentedAppenderTest.java | 7 +- .../simpleclient_log4j2/pom.xml.bak | 3 +- .../client/log4j2/InstrumentedAppender.java | 99 +- .../log4j2/InstrumentedAppenderTest.java | 98 +- .../simpleclient_logback/pom.xml.bak | 3 +- .../client/logback/InstrumentedAppender.java | 18 +- .../logback/InstrumentedAppenderTest.java | 8 +- .../client/exporter/MetricsServlet.java | 21 +- .../client/filter/MetricsFilter.java | 123 +- .../prometheus/client/internal/Adapter.java | 159 +- .../client/exporter/ExampleBenchmark.java | 73 +- .../client/exporter/ExampleExporter.java | 1 - .../common/adapter/FilterConfigAdapter.java | 2 +- .../adapter/HttpServletRequestAdapter.java | 14 +- .../adapter/HttpServletResponseAdapter.java | 11 +- .../common/adapter/ServletConfigAdapter.java | 2 +- .../servlet/common/exporter/Exporter.java | 46 +- .../ServletConfigurationException.java | 3 +- .../client/servlet/common/filter/Filter.java | 285 +- .../filter/FilterConfigurationException.java | 10 +- .../servlet/common/exporter/ExporterTest.java | 61 +- .../servlet/common/filter/FilterTest.java | 448 +- .../client/servlet/jakarta/Adapter.java | 155 +- .../servlet/jakarta/filter/MetricsFilter.java | 111 +- .../client/exporter/ExampleBenchmark.java | 78 +- .../client/exporter/ExampleExporter.java | 1 - .../spring/web/EnablePrometheusTiming.java | 14 +- .../client/spring/web/MethodTimer.java | 179 +- .../spring/web/PrometheusTimeMethod.java | 34 +- .../client/spring/web/MethodTimerAppTest.java | 23 +- .../client/spring/web/MethodTimerTest.java | 398 +- .../client/vertx/MetricsHandler.java | 38 +- .../client/vertx/ExampleExporter.java | 1 - .../client/vertx/MetricsHandlerTest.java | 29 +- .../client/vertx/MetricsHandler.java | 38 +- .../client/vertx/ExampleExporter.java | 1 - .../client/vertx/MetricsHandlerTest.java | 29 +- 290 files changed, 171271 insertions(+), 7905 deletions(-) create mode 100644 .github/super-linter.env rename .github/workflows/{lint.yml => lint-rest.yml} (88%) create mode 100644 .github/workflows/super-linter.yml create mode 100644 .gitleaksignore create mode 100644 .yaml-lint.yml delete mode 100755 examples/example-exporter-opentelemetry/oats-tests/agent/service-instance-id-check.py create mode 100755 examples/example-exporter-opentelemetry/oats-tests/agent/service_instance_id_check.py create mode 100644 lychee.toml create mode 100755 scripts/super-linter.sh diff --git a/.editorconfig b/.editorconfig index b33efbd87..1ade83fa3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,5 +4,15 @@ root = true max_line_length = 100 indent_size = 2 +[{version-rules.xml,maven-wrapper.properties,checkstyle.xml,docker-compose.yaml,docker-compose.yml,Dockerfile,example_target_info.json,mise.toml,mise.lock,mvnm,mvnw.cmd,generate-protobuf.sh,super-linter.env,.gitleaksignore}] +max_line_length = 200 + +[{grafana-dashboard-*.json,.editorconfig}] +max_line_length = 300 + [pom.xml] +max_line_length = 110 + +[*.py] +# checked by black indent_size = 4 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 505013ce1..c6485ad12 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +--- version: 2 updates: - package-ecosystem: "github-actions" @@ -5,8 +6,10 @@ updates: schedule: interval: weekly - package-ecosystem: maven - # excluding simpleclient_archive from the update is not possible, only includes are supported - # when we use includes, we run into https://github.com/dependabot/dependabot-core/issues/10415 - + # excluding simpleclient_archive from the update is not possible, + # only includes are supported + # when we use includes, + # we run into https://github.com/dependabot/dependabot-core/issues/10415 # even if we limit to 1 PR at a time # therefore we just rename pom.xml in simpleclient_archive for now # if this becomes a problem, we can move to renovate diff --git a/.github/super-linter.env b/.github/super-linter.env new file mode 100644 index 000000000..8d10a7d3b --- /dev/null +++ b/.github/super-linter.env @@ -0,0 +1,34 @@ +FILTER_REGEX_EXCLUDE=mvnw|src/main/generated/.*|docs/themes/.*|keystore.pkcs12|.*.java|prometheus-metrics-exporter-opentelemetry-shaded/pom.xml +IGNORE_GITIGNORED_FILES=true +JAVA_FILE_NAME=google_checks.xml +# disable kubernetes linter - complains about resource limits, etc +VALIDATE_CHECKOV=false +VALIDATE_CSS=false +VALIDATE_CSS_PRETTIER=false +VALIDATE_DOCKERFILE_HADOLINT=false +VALIDATE_GIT_COMMITLINT=false +# done by maven +VALIDATE_GOOGLE_JAVA_FORMAT=false +# times out +VALIDATE_GO_MODULES=false +VALIDATE_HTML=false +# done by checkstyle +VALIDATE_JAVA=false +# contradicting with prettier +VALIDATE_JAVASCRIPT_STANDARD=false +# we have many duplicate code in our codebase for demo purposes +VALIDATE_JSCPD=false +VALIDATE_PYTHON_PYLINT=false + +FIX_ENV=true +FIX_GO=true +FIX_JAVASCRIPT_PRETTIER=true +FIX_JSON=true +FIX_JSONC=true +FIX_JSONC_PRETTIER=true +FIX_JSON_PRETTIER=true +FIX_MARKDOWN=true +FIX_MARKDOWN_PRETTIER=true +FIX_PYTHON_BLACK=true +FIX_SHELL_SHFMT=true +FIX_YAML_PRETTIER=true diff --git a/.github/workflows/acceptance-tests.yml b/.github/workflows/acceptance-tests.yml index 334602715..c114d177a 100644 --- a/.github/workflows/acceptance-tests.yml +++ b/.github/workflows/acceptance-tests.yml @@ -1,10 +1,11 @@ +--- name: OpenTelemetry Acceptance Tests on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] permissions: {} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 679ce1752..09cfd7e15 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,11 @@ +--- name: Build on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] permissions: {} @@ -25,4 +26,3 @@ jobs: ${{ runner.os }}-maven- - name: Run the Maven verify phase run: mise run ci - diff --git a/.github/workflows/github-pages.yaml b/.github/workflows/github-pages.yaml index 0f1b8ac5c..5cba7fea6 100644 --- a/.github/workflows/github-pages.yaml +++ b/.github/workflows/github-pages.yaml @@ -13,8 +13,10 @@ on: permissions: {} -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +# Allow only one concurrent deployment, skipping runs queued between +# the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow +# these production deployments to complete. concurrency: group: "pages" cancel-in-progress: false @@ -32,22 +34,18 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - fetch-tags: 'true' + fetch-tags: "true" fetch-depth: 0 - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 with: - cache: 'false' + cache: "false" - name: Prepare GitHub Pages run: mise run prepare-gh-pages - with: - permissions: block - name: Setup Pages id: pages uses: actions/configure-pages@v5 - name: Build GitHub Pages run: mise run build-gh-pages - with: - permissions: block - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint-rest.yml similarity index 88% rename from .github/workflows/lint.yml rename to .github/workflows/lint-rest.yml index ee3cffab2..8a747cf94 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint-rest.yml @@ -7,7 +7,6 @@ permissions: {} jobs: acceptance-tests: - permissions: {} runs-on: ubuntu-24.04 steps: - name: Check out @@ -16,5 +15,4 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: jdx/mise-action@7a111ead46986ccad89a74ad013ba2a7c08c9e67 # v2.1.1 - name: Lint - run: mise run lint-all - + run: mise run lint-rest diff --git a/.github/workflows/native-tests.yml b/.github/workflows/native-tests.yml index 6d21a5faa..d5b3927db 100644 --- a/.github/workflows/native-tests.yml +++ b/.github/workflows/native-tests.yml @@ -1,10 +1,11 @@ +--- name: GraalVM Native Tests on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] permissions: {} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bf0e60d02..087356453 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +--- name: Deploy to Maven Central on: @@ -14,10 +15,10 @@ jobs: steps: - name: Debug gpg key - remove after debugging env: - GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} run: | - echo "$GPG_SIGNING_KEY" | wc -c - echo "$GPG_SIGNING_KEY" | gpg --batch --import-options import-show --import + echo "${#GPG_SIGNING_KEY}" + echo "${GPG_SIGNING_KEY}" | gpg --batch --import-options import-show --import - name: Checkout Plugin Repository uses: actions/checkout@v4 with: @@ -37,8 +38,8 @@ jobs: - name: Set up Apache Maven Central uses: actions/setup-java@v4 with: - distribution: 'temurin' - java-version: '17' + distribution: "temurin" + java-version: "17" server-id: ossrh server-username: MAVEN_USERNAME server-password: MAVEN_CENTRAL_TOKEN diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml new file mode 100644 index 000000000..102695d4b --- /dev/null +++ b/.github/workflows/super-linter.yml @@ -0,0 +1,31 @@ +--- +name: Lint + +on: + pull_request: + +jobs: + lint: + runs-on: ubuntu-24.04 + + permissions: + contents: read + packages: read + # To report GitHub Actions status checks + statuses: write + + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Load super-linter configuration + run: grep -v '^#' .github/super-linter.env | grep -v 'FIX_' >> "$GITHUB_ENV" + + - name: Super-linter + uses: super-linter/super-linter@4e8a7c2bf106c4c766c816b35ec612638dc9b6b2 # v7.3.0 + env: + # To report GitHub Actions status checks + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index ad343c1bd..b727017a9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ dependency-reduced-pom.xml **/.classpath **.project **/.settings/ +docs/public +.lycheecache diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 000000000..605fefa97 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,2 @@ +/tmp/lint/integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml:private-key:36 +/github/workspace/integration-tests/it-pushgateway/src/test/resources/pushgateway-ssl.yaml:private-key:36 diff --git a/.yaml-lint.yml b/.yaml-lint.yml new file mode 100644 index 000000000..a06ffeed5 --- /dev/null +++ b/.yaml-lint.yml @@ -0,0 +1,5 @@ +extends: relaxed + +rules: + line-length: + max: 120 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index d325872bd..524d1ab50 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,3 +1,4 @@ # Prometheus Community Code of Conduct -Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). +Prometheus follows the +[CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff9717f67..aaa08ea7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,18 +2,19 @@ Prometheus uses GitHub to manage reviews of pull requests. -* If you have a trivial fix or improvement, go ahead and create a pull request, +- If you have a trivial fix or improvement, go ahead and create a pull request, addressing (with `@...`) the maintainer of this repository (see [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request. -* If you plan to do something more involved, first discuss your ideas +- If you plan to do something more involved, first discuss your ideas 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. +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. @@ -21,7 +22,8 @@ Run `./mvnw spotless:apply` to format the code (only changed files) before commi If you're getting errors when running tests: -- Make sure that the IDE uses only the "Maven Shade" dependency of "prometheus-metrics-exposition-formats" and the "prometheus-metrics-tracer*" dependencies. +- Make sure that the IDE uses only the "Maven Shade" dependency of " + prometheus-metrics-exposition-formats" and the "prometheus-metrics-tracer\*" dependencies. ### Avoid failures while running tests @@ -30,7 +32,8 @@ If you're getting errors when running tests: - Use `-Dcheckstyle.skip=true` to skip the checkstyle check during development. - Use `-Dwarnings=-nowarn` to skip the warnings during development. -Combine all with `./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn`. +Combine all with +`./mvnw test -DskipTests=true -Dspotless.check.skip=true -Dcoverage.skip=true -Dcheckstyle.skip=true -Dwarnings=-nowarn`. # editorconfig-checker-disable-line ## Updating the Protobuf Java Classes diff --git a/MAINTAINERS.md b/MAINTAINERS.md index dae5c71de..cf0a885eb 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,4 +1,6 @@ -* Fabian Stäber @fstab -* Doug Hoard @dhoard -* Tom Wilkie @tomwilkie -* Gregor Zeitlinger @zeitlinger +# Maintainers + +- Fabian Stäber @fstab +- Doug Hoard @dhoard +- Tom Wilkie @tomwilkie +- Gregor Zeitlinger @zeitlinger diff --git a/README.md b/README.md index f03a3e2a6..6e62e3577 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,25 @@ # Prometheus Java Metrics Library -[![Build](https://github.com/prometheus/client_java/actions/workflows/build.yml/badge.svg)](https://github.com/prometheus/client_java/actions/workflows/build.yml) java 8+ Apache 2.0 +[![Build](https://github.com/prometheus/client_java/actions/workflows/build.yml/badge.svg)](https://github.com/prometheus/client_java/actions/workflows/build.yml) java 8+ Apache 2.0 # editorconfig-checker-disable-line -# Documentation +## Documentation [https://prometheus.github.io/client_java](https://prometheus.github.io/client_java) -# Contributing and community +## Contributing and community -See [CONTRIBUTING.md](CONTRIBUTING.md) and the [community section](http://prometheus.io/community/) of the Prometheus homepage. +See [CONTRIBUTING.md](CONTRIBUTING.md) and the [community section](http://prometheus.io/community/) +of the Prometheus homepage. -The Prometheus Java community is present on the [CNCF Slack](https://cloud-native.slack.com) on `#prometheus-java`, and we have a fortnightly community call in the [Prometheus public calendar](https://prometheus.io/community/). +The Prometheus Java community is present on the [CNCF Slack](https://cloud-native.slack.com) on +`#prometheus-java`, and we have a fortnightly community call in +the [Prometheus public calendar](https://prometheus.io/community/). -# Previous Releases +## Previous Releases -The source code for 0.16.0 and older is on the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) branch. +The source code for 0.16.0 and older is on +the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) branch. -# License +## License Apache License 2.0, see [LICENSE](LICENSE). diff --git a/RELEASING.md b/RELEASING.md index eadbb8a76..151fae720 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,6 +1,7 @@ -## Create a Release +# Create a Release -1. Go to https://github.com/prometheus/client_java/releases/new +1. Go to 2. Click on "Choose a tag", enter the tag name (e.g. `v0.1.0`), and click "Create a new tag". -3. Click on "Generate release notes" to auto-generate the release notes based on the commits since the last release. +3. Click on "Generate release notes" to auto-generate the release notes based on the commits since + the last release. 4. Click on "Publish release". diff --git a/benchmarks/README.md b/benchmarks/README.md index 36300e4d1..cb445c7bf 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,15 +1,14 @@ -Benchmarks ----------- +# Benchmarks ## How to Run -``` +```shell java -jar ./benchmarks/target/benchmarks.jar ``` Run only one specific benchmark: -``` +```shell java -jar ./benchmarks/target/benchmarks.jar CounterBenchmark ``` @@ -17,16 +16,22 @@ java -jar ./benchmarks/target/benchmarks.jar CounterBenchmark See Javadoc of the benchmark classes: -* [CounterBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java) -* [HistogramBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java) +- [CounterBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/CounterBenchmark.java) +- [HistogramBenchmark](https://github.com/prometheus/client_java/blob/1.0.x/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/HistogramBenchmark.java) ## What Prometheus Java client optimizes for concurrent updates of metrics in multi-threaded applications. -If your application is single-threaded and uses only one processor core, your application isn't performance critical anyway. -If your application is designed to use all available processor cores for maximum performance, then you want a metric library that doesn't slow your application down. -Prometheus client Java metrics support concurrent updates and scrapes. This shows in benchmarks with multiple threads recording data in shared metrics. +If your application is single-threaded and uses only one processor core, your application isn't +performance critical anyway. +If your application is designed to use all available processor cores for maximum performance, then +you want a metric library that doesn't slow your +application down. +Prometheus client Java metrics support concurrent updates and scrapes. This shows in benchmarks with +multiple threads recording data in shared +metrics. ## Archive -The `src/main/archive/` directory contains the old benchmarks from 0.16.0 and earlier. It will be removed as soon as all benchmarks are ported to the 1.0.0 release. +The `src/main/archive/` directory contains the old benchmarks from 0.16.0 and earlier. It will be +removed as soon as all benchmarks are ported to the 1.0.0 release. diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 8e476d5a6..3cdbc09c0 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -1,122 +1,125 @@ - - 4.0.0 + + 4.0.0 - - io.prometheus - client_java - 1.4.0-SNAPSHOT - + + io.prometheus + client_java + 1.4.0-SNAPSHOT + - benchmarks + benchmarks - Prometheus Java Client Benchmarks - - Benchmarks of client performance, and comparison to other systems. - + Prometheus Java Client Benchmarks + + Benchmarks of client performance, and comparison to other systems. + - - 1.37 - 0.16.0 - 3.0.2 - true - - - - - - io.opentelemetry.instrumentation - opentelemetry-instrumentation-bom-alpha - ${otel.instrumentation.version} - pom - import - - - + + 1.37 + 0.16.0 + 3.0.2 + true + + - - org.openjdk.jmh - jmh-core - ${jmh.version} - - - io.prometheus - prometheus-metrics-core - ${project.version} - - - io.prometheus - prometheus-metrics-exposition-textformats - ${project.version} - - - io.prometheus - simpleclient - ${simpleclient.version} - - - com.codahale.metrics - metrics-core - ${codahale.version} - - - io.opentelemetry - opentelemetry-api - - - io.opentelemetry - opentelemetry-sdk - - - io.opentelemetry - opentelemetry-sdk-testing - + + io.opentelemetry.instrumentation + opentelemetry-instrumentation-bom-alpha + ${otel.instrumentation.version} + pom + import + - - ${project.artifactId} - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - -parameters - - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - package - - shade - - - benchmarks - - - io.prometheus.metrics.benchmarks.BenchmarkRunner - - - - - - - - + + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + io.prometheus + prometheus-metrics-core + ${project.version} + + + io.prometheus + prometheus-metrics-exposition-textformats + ${project.version} + + + io.prometheus + simpleclient + ${simpleclient.version} + + + com.codahale.metrics + metrics-core + ${codahale.version} + + + io.opentelemetry + opentelemetry-api + + + io.opentelemetry + opentelemetry-sdk + + + io.opentelemetry + opentelemetry-sdk-testing + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + -parameters + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + benchmarks + + + io.prometheus.metrics.benchmarks.BenchmarkRunner + + + + + + + + + diff --git a/benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java index 530810481..ab383d327 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/CKMSQuantileBenchmark.java @@ -1,6 +1,11 @@ package io.prometheus.client; import io.prometheus.client.CKMSQuantiles.Quantile; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; import org.openjdk.jmh.runner.Runner; @@ -8,131 +13,120 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; -import java.util.concurrent.TimeUnit; - public class CKMSQuantileBenchmark { - @State(Scope.Benchmark) - public static class EmptyBenchmarkState { - @Param({"10000", "100000", "1000000"}) - public int value; - - List quantiles; - Random rand = new Random(0); - - List shuffle; - - Quantile mean = new Quantile(0.50, 0.050); - Quantile q90 = new Quantile(0.90, 0.010); - Quantile q95 = new Quantile(0.95, 0.005); - Quantile q99 = new Quantile(0.99, 0.001); - - @Setup(Level.Trial) - public void setup() { - quantiles = new ArrayList(); - quantiles.add(mean); - quantiles.add(q90); - quantiles.add(q95); - quantiles.add(q99); - - shuffle = new ArrayList(value); - for (int i = 0; i < value; i++) { - shuffle.add((double) i); - } - Collections.shuffle(shuffle, rand); - } - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.MILLISECONDS) - public void ckmsQuantileInsertBenchmark(EmptyBenchmarkState state) { - CKMSQuantiles q = new CKMSQuantiles(state.quantiles.toArray(new Quantile[]{})); - for (Double l : state.shuffle) { - q.insert(l); - } - } - - /** prefilled benchmark, means that we already have a filled and compressed samples available */ - @State(Scope.Benchmark) - public static class PrefilledBenchmarkState { - @Param({"10000", "100000", "1000000"}) - public int value; - - - CKMSQuantiles ckmsQuantiles; - - List quantiles; - Random rand = new Random(0); - - Quantile mean = new Quantile(0.50, 0.050); - Quantile q90 = new Quantile(0.90, 0.010); - Quantile q95 = new Quantile(0.95, 0.005); - Quantile q99 = new Quantile(0.99, 0.001); - List shuffle; - - int rank = (int) (value * q95.quantile); - - - @Setup(Level.Trial) - public void setup() { - quantiles = new ArrayList(); - quantiles.add(mean); - quantiles.add(q90); - quantiles.add(q95); - quantiles.add(q99); - - shuffle = new ArrayList(value); - for (int i = 0; i < value; i++) { - shuffle.add((double) i); - } - Collections.shuffle(shuffle, rand); - - - ckmsQuantiles = new CKMSQuantiles(quantiles.toArray(new Quantile[]{})); - for (Double l : shuffle) { - ckmsQuantiles.insert(l); - } - // make sure we inserted all 'hanging' samples (count % 128) - ckmsQuantiles.get(0); - // compress everything so we have a similar samples size regardless of n. - ckmsQuantiles.compress(); - System.out.println("Sample size is: " + ckmsQuantiles.samples.size()); - } - - } - - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void ckmsQuantileGetBenchmark(Blackhole blackhole, PrefilledBenchmarkState state) { - blackhole.consume(state.ckmsQuantiles.get(state.q90.quantile)); + @State(Scope.Benchmark) + public static class EmptyBenchmarkState { + @Param({"10000", "100000", "1000000"}) + public int value; + + List quantiles; + Random rand = new Random(0); + + List shuffle; + + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); + + @Setup(Level.Trial) + public void setup() { + quantiles = new ArrayList(); + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); + } + Collections.shuffle(shuffle, rand); } - - /** - * benchmark for the f method. - */ - @Benchmark - @BenchmarkMode({Mode.AverageTime}) - @OutputTimeUnit(TimeUnit.NANOSECONDS) - public void ckmsQuantileF(Blackhole blackhole, PrefilledBenchmarkState state) { - blackhole.consume(state.ckmsQuantiles.f(state.rank)); + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public void ckmsQuantileInsertBenchmark(EmptyBenchmarkState state) { + CKMSQuantiles q = new CKMSQuantiles(state.quantiles.toArray(new Quantile[] {})); + for (Double l : state.shuffle) { + q.insert(l); } - - public static void main(String[] args) throws RunnerException { - - Options opt = new OptionsBuilder() - .include(CKMSQuantileBenchmark.class.getSimpleName()) - .warmupIterations(5) - .measurementIterations(4) - .threads(1) - .forks(1) - .build(); - - new Runner(opt).run(); + } + + /** prefilled benchmark, means that we already have a filled and compressed samples available */ + @State(Scope.Benchmark) + public static class PrefilledBenchmarkState { + @Param({"10000", "100000", "1000000"}) + public int value; + + CKMSQuantiles ckmsQuantiles; + + List quantiles; + Random rand = new Random(0); + + Quantile mean = new Quantile(0.50, 0.050); + Quantile q90 = new Quantile(0.90, 0.010); + Quantile q95 = new Quantile(0.95, 0.005); + Quantile q99 = new Quantile(0.99, 0.001); + List shuffle; + + int rank = (int) (value * q95.quantile); + + @Setup(Level.Trial) + public void setup() { + quantiles = new ArrayList(); + quantiles.add(mean); + quantiles.add(q90); + quantiles.add(q95); + quantiles.add(q99); + + shuffle = new ArrayList(value); + for (int i = 0; i < value; i++) { + shuffle.add((double) i); + } + Collections.shuffle(shuffle, rand); + + ckmsQuantiles = new CKMSQuantiles(quantiles.toArray(new Quantile[] {})); + for (Double l : shuffle) { + ckmsQuantiles.insert(l); + } + // make sure we inserted all 'hanging' samples (count % 128) + ckmsQuantiles.get(0); + // compress everything so we have a similar samples size regardless of n. + ckmsQuantiles.compress(); + System.out.println("Sample size is: " + ckmsQuantiles.samples.size()); } + } + + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void ckmsQuantileGetBenchmark(Blackhole blackhole, PrefilledBenchmarkState state) { + blackhole.consume(state.ckmsQuantiles.get(state.q90.quantile)); + } + + /** benchmark for the f method. */ + @Benchmark + @BenchmarkMode({Mode.AverageTime}) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void ckmsQuantileF(Blackhole blackhole, PrefilledBenchmarkState state) { + blackhole.consume(state.ckmsQuantiles.f(state.rank)); + } + + public static void main(String[] args) throws RunnerException { + + Options opt = + new OptionsBuilder() + .include(CKMSQuantileBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .threads(1) + .forks(1) + .build(); + + new Runner(opt).run(); + } } diff --git a/benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java index 592efc6f2..c37076156 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/benchmark/CounterBenchmark.java @@ -1,6 +1,7 @@ package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -13,8 +14,6 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.concurrent.TimeUnit; - @State(Scope.Benchmark) public class CounterBenchmark { @@ -28,16 +27,16 @@ public class CounterBenchmark { @Setup public void setup() { - prometheusSimpleCounter = io.prometheus.client.Counter.build() - .name("name") - .help("some description..") - .labelNames("some", "group").create(); + prometheusSimpleCounter = + io.prometheus.client.Counter.build() + .name("name") + .help("some description..") + .labelNames("some", "group") + .create(); prometheusSimpleCounterChild = prometheusSimpleCounter.labels("test", "group"); - prometheusSimpleCounterNoLabels = io.prometheus.client.Counter.build() - .name("name") - .help("some description..") - .create(); + prometheusSimpleCounterNoLabels = + io.prometheus.client.Counter.build().name("name").help("some description..").create(); registry = new MetricRegistry(); codahaleCounter = registry.counter("counter"); @@ -48,21 +47,21 @@ public void setup() { @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleCounterIncBenchmark() { - prometheusSimpleCounter.labels("test", "group").inc(); + prometheusSimpleCounter.labels("test", "group").inc(); } - + @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleCounterChildIncBenchmark() { - prometheusSimpleCounterChild.inc(); + prometheusSimpleCounterChild.inc(); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleCounterNoLabelsIncBenchmark() { - prometheusSimpleCounterNoLabels.inc(); + prometheusSimpleCounterNoLabels.inc(); } @Benchmark @@ -81,13 +80,14 @@ public void codahaleMeterMarkBenchmark() { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(CounterBenchmark.class.getSimpleName()) - .warmupIterations(5) - .measurementIterations(4) - .threads(4) - .forks(1) - .build(); + Options opt = + new OptionsBuilder() + .include(CounterBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .threads(4) + .forks(1) + .build(); new Runner(opt).run(); } diff --git a/benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java index 7d033afcd..a3fa45ae1 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/benchmark/ExemplarsBenchmark.java @@ -3,6 +3,7 @@ import io.prometheus.client.Counter; import io.prometheus.client.exemplars.DefaultExemplarSampler; import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -11,8 +12,6 @@ import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; -import java.util.concurrent.TimeUnit; - @State(Scope.Benchmark) public class ExemplarsBenchmark { @@ -23,25 +22,28 @@ public class ExemplarsBenchmark { @Setup public void setup() { - counter = Counter.build() - .name("counter_total") - .help("Total number of requests.") - .labelNames("path") - .create(); + counter = + Counter.build() + .name("counter_total") + .help("Total number of requests.") + .labelNames("path") + .create(); - counterWithExemplars = Counter.build() - .name("counter_with_exemplars_total") - .help("Total number of requests.") - .labelNames("path") - .withExemplarSampler(new DefaultExemplarSampler(new MockSpanContextSupplier())) - .create(); + counterWithExemplars = + Counter.build() + .name("counter_with_exemplars_total") + .help("Total number of requests.") + .labelNames("path") + .withExemplarSampler(new DefaultExemplarSampler(new MockSpanContextSupplier())) + .create(); - counterWithoutExemplars = Counter.build() - .name("counter_without_exemplars_total") - .help("Total number of requests.") - .labelNames("path") - .withoutExemplars() - .create(); + counterWithoutExemplars = + Counter.build() + .name("counter_without_exemplars_total") + .help("Total number of requests.") + .labelNames("path") + .withoutExemplars() + .create(); } @Benchmark @@ -79,7 +81,7 @@ public String getSpanId() { @Override public boolean isSampled() { - return true; + return true; } } } diff --git a/benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java index d088d280d..a8eb03c83 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/benchmark/GaugeBenchmark.java @@ -1,6 +1,7 @@ package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -13,8 +14,6 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.concurrent.TimeUnit; - @State(Scope.Benchmark) public class GaugeBenchmark { @@ -27,16 +26,16 @@ public class GaugeBenchmark { @Setup public void setup() { - prometheusSimpleGauge = io.prometheus.client.Gauge.build() - .name("name") - .help("some description..") - .labelNames("some", "group").create(); + prometheusSimpleGauge = + io.prometheus.client.Gauge.build() + .name("name") + .help("some description..") + .labelNames("some", "group") + .create(); prometheusSimpleGaugeChild = prometheusSimpleGauge.labels("test", "group"); - prometheusSimpleGaugeNoLabels = io.prometheus.client.Gauge.build() - .name("name") - .help("some description..") - .create(); + prometheusSimpleGaugeNoLabels = + io.prometheus.client.Gauge.build().name("name").help("some description..").create(); registry = new MetricRegistry(); codahaleCounter = registry.counter("name"); @@ -47,21 +46,21 @@ public void setup() { @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeIncBenchmark() { - prometheusSimpleGauge.labels("test", "group").inc(); + prometheusSimpleGauge.labels("test", "group").inc(); } - + @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeChildIncBenchmark() { - prometheusSimpleGaugeChild.inc(); + prometheusSimpleGaugeChild.inc(); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeNoLabelsIncBenchmark() { - prometheusSimpleGaugeNoLabels.inc(); + prometheusSimpleGaugeNoLabels.inc(); } @Benchmark @@ -71,27 +70,26 @@ public void codahaleCounterIncBenchmark() { codahaleCounter.inc(); } - // Decrement. @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeDecBenchmark() { - prometheusSimpleGauge.labels("test", "group").dec(); + prometheusSimpleGauge.labels("test", "group").dec(); } - + @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeChildDecBenchmark() { - prometheusSimpleGaugeChild.dec(); + prometheusSimpleGaugeChild.dec(); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeNoLabelsDecBenchmark() { - prometheusSimpleGaugeNoLabels.dec(); + prometheusSimpleGaugeNoLabels.dec(); } @Benchmark @@ -106,9 +104,9 @@ public void codahaleCounterDecBenchmark() { @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeSetBenchmark() { - prometheusSimpleGauge.labels("test", "group").set(42); + prometheusSimpleGauge.labels("test", "group").set(42); } - + @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) @@ -120,18 +118,19 @@ public void prometheusSimpleGaugeChildSetBenchmark() { @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleGaugeNoLabelsSetBenchmark() { - prometheusSimpleGaugeNoLabels.set(42); + prometheusSimpleGaugeNoLabels.set(42); } public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(GaugeBenchmark.class.getSimpleName()) - .warmupIterations(5) - .measurementIterations(4) - .threads(4) - .forks(1) - .build(); + Options opt = + new OptionsBuilder() + .include(GaugeBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .threads(4) + .forks(1) + .build(); new Runner(opt).run(); } diff --git a/benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java index d89e676e5..cb5f300ce 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SanitizeMetricNameBenchmark.java @@ -1,12 +1,12 @@ package io.prometheus.client.benchmark; -import com.codahale.metrics.MetricRegistry; +import io.prometheus.client.Collector; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; @@ -14,23 +14,18 @@ import org.openjdk.jmh.runner.options.OptionsBuilder; import org.openjdk.jmh.runner.options.TimeValue; -import io.prometheus.client.Collector; - -import java.util.Random; -import java.util.concurrent.TimeUnit; - @State(Scope.Benchmark) public class SanitizeMetricNameBenchmark { @Benchmark - @BenchmarkMode({ Mode.AverageTime }) + @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void sanitizeSanitizedName() { Collector.sanitizeMetricName("good_name"); } @Benchmark - @BenchmarkMode({ Mode.AverageTime }) + @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void sanitizeNonSanitizedName() { Collector.sanitizeMetricName("9not_good_name!"); @@ -38,15 +33,16 @@ public void sanitizeNonSanitizedName() { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(SanitizeMetricNameBenchmark.class.getSimpleName()) - .warmupIterations(5) - .measurementIterations(4) - .measurementTime(TimeValue.seconds(1)) - .warmupTime(TimeValue.seconds(1)) - .threads(4) - .forks(1) - .build(); + Options opt = + new OptionsBuilder() + .include(SanitizeMetricNameBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .measurementTime(TimeValue.seconds(1)) + .warmupTime(TimeValue.seconds(1)) + .threads(4) + .forks(1) + .build(); new Runner(opt).run(); } diff --git a/benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java index 973106c68..2964b8ea8 100644 --- a/benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java +++ b/benchmarks/src/archive/java/io/prometheus/client/benchmark/SummaryBenchmark.java @@ -1,6 +1,7 @@ package io.prometheus.client.benchmark; import com.codahale.metrics.MetricRegistry; +import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -13,8 +14,6 @@ import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import java.util.concurrent.TimeUnit; - @State(Scope.Benchmark) public class SummaryBenchmark { @@ -30,27 +29,27 @@ public class SummaryBenchmark { @Setup public void setup() { - prometheusSimpleSummary = io.prometheus.client.Summary.build() - .name("name") - .help("some description..") - .labelNames("some", "group").create(); + prometheusSimpleSummary = + io.prometheus.client.Summary.build() + .name("name") + .help("some description..") + .labelNames("some", "group") + .create(); prometheusSimpleSummaryChild = prometheusSimpleSummary.labels("test", "group"); - prometheusSimpleSummaryNoLabels = io.prometheus.client.Summary.build() - .name("name") - .help("some description..") - .create(); + prometheusSimpleSummaryNoLabels = + io.prometheus.client.Summary.build().name("name").help("some description..").create(); - prometheusSimpleHistogram = io.prometheus.client.Histogram.build() - .name("name") - .help("some description..") - .labelNames("some", "group").create(); + prometheusSimpleHistogram = + io.prometheus.client.Histogram.build() + .name("name") + .help("some description..") + .labelNames("some", "group") + .create(); prometheusSimpleHistogramChild = prometheusSimpleHistogram.labels("test", "group"); - prometheusSimpleHistogramNoLabels = io.prometheus.client.Histogram.build() - .name("name") - .help("some description..") - .create(); + prometheusSimpleHistogramNoLabels = + io.prometheus.client.Histogram.build().name("name").help("some description..").create(); registry = new MetricRegistry(); codahaleHistogram = registry.histogram("name"); @@ -60,28 +59,28 @@ public void setup() { @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleSummaryBenchmark() { - prometheusSimpleSummary.labels("test", "group").observe(1) ; + prometheusSimpleSummary.labels("test", "group").observe(1); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleSummaryChildBenchmark() { - prometheusSimpleSummaryChild.observe(1); + prometheusSimpleSummaryChild.observe(1); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleSummaryNoLabelsBenchmark() { - prometheusSimpleSummaryNoLabels.observe(1); + prometheusSimpleSummaryNoLabels.observe(1); } @Benchmark @BenchmarkMode({Mode.AverageTime}) @OutputTimeUnit(TimeUnit.NANOSECONDS) public void prometheusSimpleHistogramBenchmark() { - prometheusSimpleHistogram.labels("test", "group").observe(1) ; + prometheusSimpleHistogram.labels("test", "group").observe(1); } @Benchmark @@ -107,13 +106,14 @@ public void codahaleHistogramBenchmark() { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(SummaryBenchmark.class.getSimpleName()) - .warmupIterations(5) - .measurementIterations(4) - .threads(4) - .forks(1) - .build(); + Options opt = + new OptionsBuilder() + .include(SummaryBenchmark.class.getSimpleName()) + .warmupIterations(5) + .measurementIterations(4) + .threads(4) + .forks(1) + .build(); new Runner(opt).run(); } diff --git a/checkstyle.xml b/checkstyle.xml index fd483abfa..cac6be8d3 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -30,7 +30,7 @@ + default="checkstyle-suppressions.xml"/> @@ -44,7 +44,7 @@ + value="^package.*|^import.*|a href|href|http://|https://|ftp://|# HELP.*|jvm_runtime_info\{"/> @@ -64,9 +64,9 @@ + value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/> + value="Consider using special escape sequence instead of octal value or Unicode escaped value."/> @@ -81,15 +81,15 @@ + value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/> + value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/> @@ -117,7 +117,7 @@ @@ -128,7 +128,7 @@ + value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may + only be represented as '{}' when not part of a multi-block statement (4.1.3)"/> + value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/> @@ -148,7 +149,7 @@ @@ -184,76 +185,76 @@ + value="Type name ''{0}'' must match pattern ''{1}''."/> + value="Member name ''{0}'' must match pattern ''{1}''."/> + value="Logger fields must be named ''logger''."/> + value="Parameter name ''{0}'' must match pattern ''{1}''."/> + value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/> + value="Catch parameter name ''{0}'' must match pattern ''{1}''."/> + value="Local variable name ''{0}'' must match pattern ''{1}''."/> + value="Pattern variable name ''{0}'' must match pattern ''{1}''."/> + value="Class type name ''{0}'' must match pattern ''{1}''."/> + value="Record type name ''{0}'' must match pattern ''{1}''."/> + value="Method type name ''{0}'' must match pattern ''{1}''."/> + value="Interface type name ''{0}'' must match pattern ''{1}''."/> + value="GenericWhitespace ''{0}'' is followed by whitespace."/> + value="GenericWhitespace ''{0}'' is preceded with whitespace."/> + value="GenericWhitespace ''{0}'' should followed by whitespace."/> + value="GenericWhitespace ''{0}'' is not preceded with whitespace."/> @@ -273,18 +274,18 @@ @@ -321,7 +322,7 @@ + value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/> @@ -342,7 +343,7 @@ + value="Method name ''{0}'' must match pattern ''{1}''."/> + default="checkstyle-xpath-suppressions.xml"/> diff --git a/docs/README.md b/docs/README.md index 294c9a622..8ca147236 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,59 +1,60 @@ -Docs ----- +# Docs -This directory contains [hugo](https://gohugo.io) documentation to be published in Github pages. +This directory contains [hugo](https://gohugo.io) documentation to be published in GitHub pages. -Run Locally ------------ +## Run Locally -``` +```shell hugo server -D ``` This will serve the docs on [http://localhost:1313](http://localhost:1313). -Deploy to Github Pages ----------------------- +## Deploy to GitHub Pages -Changes to the `main` branch will be deployed automatically with Github actions. +Changes to the `main` branch will be deployed automatically with GitHub Actions. -Update Javadoc --------------- +## Update Javadoc -Javadoc are not checked-in to the Github repository. -They are generated on the fly by Github actions when the docs are updated. +Javadoc are not checked-in to the GitHub repository. +They are generated on the fly by GitHub Actions when the docs are updated. To view locally, run the following: -``` -# note that the 'compile' in the following command is necessary for Javadoc to detect the module structure +```shell +# note that the 'compile' in the following command is necessary for +# Javadoc to detect the module structure ./mvnw clean compile javadoc:javadoc javadoc:aggregate rm -r ./docs/static/api mv ./target/site/apidocs ./docs/static/api ``` -Github pages are in the `/client_java/` folder, so we link to `/client_java/api` rather than `/api`. +GitHub pages are in the `/client_java/` folder, so we link to `/client_java/api` rather than `/api`. To make JavaDoc work locally, create a link: -``` +```shell mkdir ./docs/static/client_java ln -s ../api ./docs/static/client_java/api ``` -Update Geekdocs ---------------- +## Update Geekdocs -The docs use the [Geekdocs](https://geekdocs.de/) theme. The theme is checked in to Github in the `./docs/themes/hugo-geekdoc/` folder. To update [Geekdocs](https://geekdocs.de/), remove the current folder and create a new one with the latest [release](https://github.com/thegeeklab/hugo-geekdoc/releases). There are no local modifications in `./docs/themes/hugo-geekdoc/`. +The docs use the [Geekdocs](https://geekdocs.de/) theme. The theme is checked in to GitHub in the +`./docs/themes/hugo-geekdoc/` folder. To update [Geekdocs](https://geekdocs.de/), remove the current +folder and create a new one with the +latest [release](https://github.com/thegeeklab/hugo-geekdoc/releases). There are no local +modifications in `./docs/themes/hugo-geekdoc/`. -Notes ------ +## Notes Here's how the initial `docs/` folder was set up: -``` +```shell hugo new site docs cd docs/ mkdir -p themes/hugo-geekdoc/ -curl -L https://github.com/thegeeklab/hugo-geekdoc/releases/download/v0.41.1/hugo-geekdoc.tar.gz | tar -xz -C themes/hugo-geekdoc/ --strip-components=1 +curl -L https://github.com/thegeeklab/hugo-geekdoc/releases/download/v0.41.1/hugo-geekdoc.tar.gz \ + | tar -xz -C themes/hugo-geekdoc/ --strip-components=1 ``` -Create the initial `hugo.toml` file as described in [https://geekdocs.de/usage/getting-started/](https://geekdocs.de/usage/getting-started/). +Create the initial `hugo.toml` file as described +in [https://geekdocs.de/usage/getting-started/](https://geekdocs.de/usage/getting-started/). diff --git a/docs/content/_index.md b/docs/content/_index.md index 9de934995..3b8966cf3 100644 --- a/docs/content/_index.md +++ b/docs/content/_index.md @@ -2,32 +2,54 @@ title: "client_java" --- -This is the documentation for the [Prometheus Java client library](https://github.com/prometheus/client_java) version 1.0.0 and higher. +This is the documentation for the +[Prometheus Java client library](https://github.com/prometheus/client_java) +version 1.0.0 and higher. The main new features of the 1.0.0 release are: -* **Prometheus native histograms:** Support for the new Prometheus histogram type. -* **OpenTelemetry Exporter:** Push metrics in OTLP format to an OpenTelemetry endpoint. -* **Runtime configuration:** Configure metrics, exporters, and more at runtime using a properties file or system properties. +- **Prometheus native histograms:** Support for the new Prometheus histogram type. +- **OpenTelemetry Exporter:** Push metrics in OTLP format to an OpenTelemetry endpoint. +- **Runtime configuration:** Configure metrics, exporters, and more at runtime using a properties + file or system properties. **Documentation and Examples** -In addition to this documentation page we created an [examples/](https://github.com/prometheus/client_java/tree/main/examples) directory with end-to-end scenarios (Docker compose) illustrating new features. +In addition to this documentation page we created an +[examples/](https://github.com/prometheus/client_java/tree/main/examples) directory with end-to-end +scenarios (Docker compose) illustrating new features. **Performance Benchmarks** -Initial performance benchmarks are looking great: All core metric types (including native histograms) allow concurrent updates, so if you instrument a performance critical Web service that utilizes all processor cores in parallel the metrics library will not introduce additional synchronization. See Javadoc comments in [benchmarks/](https://github.com/prometheus/client_java/tree/main/benchmarks) for benchmark results. +Initial performance benchmarks are looking great: All core metric types (including native +histograms) allow concurrent updates, so if you instrument a performance critical Web service +that utilizes all processor cores in parallel the metrics library will not introduce additional +synchronization. See Javadoc comments in +[benchmarks/](https://github.com/prometheus/client_java/tree/main/benchmarks) for benchmark results. **More Info** -The Grafana Labs Blog has a post [Introducing the Prometheus Java Client 1.0.0](https://grafana.com/blog/2023/09/27/introducing-the-prometheus-java-client-1.0.0/) with a good overview of the release. +The Grafana Labs Blog has a post +[Introducing the Prometheus Java Client 1.0.0](https://grafana.com/blog/2023/09/27/introducing-the-prometheus-java-client-1.0.0/) +with a good overview of the release. -There will also be a presentation at the [PromCon](https://promcon.io) conference on 29 Sep 2023. Tune in to the live stream on [https://promcon.io](https://promcon.io) or watch the recording on YouTube. +There will also be a presentation at the [PromCon](https://promcon.io) conference on 29 Sep 2023. +Tune in to the live stream on [https://promcon.io](https://promcon.io) +or watch the recording on YouTube. **For users of the 0.16.0 version and older** -Updating to the 1.0.0 version is a breaking change. However, there's a `prometheus-metrics-simpleclient-bridge` module available that allows you to use your existing simpleclient 0.16.0 metrics with the new 1.0.0 `PrometheusRegistry`. So you don't need to upgrade your instrumentation code, you can keep using your existing metrics. See the [compatibility > simpleclient](https://prometheus.github.io/client_java/migration/simpleclient/) in the menu on the left. +Updating to the 1.0.0 version is a breaking change. However, there's a +`prometheus-metrics-simpleclient-bridge` module available that allows you to use your existing +simpleclient 0.16.0 metrics with the new 1.0.0 `PrometheusRegistry`. +So you don't need to upgrade your instrumentation code, you can keep using your existing metrics. +See the +[compatibility > simpleclient](https://prometheus.github.io/client_java/migration/simpleclient/) +in the menu on the left. -The pre 1.0.0 code is now maintained on the [simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) feature branch. +The pre 1.0.0 code is now maintained on the +[simpleclient](https://github.com/prometheus/client_java/tree/simpleclient) feature branch. -Not all `simpleclient` modules from 0.16.0 are included in the initial 1.0.0 release. Over the next couple of weeks we will work on porting the remaining modules, starting with `pushgateway` and the Servlet filter. +Not all `simpleclient` modules from 0.16.0 are included in the initial 1.0.0 release. +Over the next couple of weeks we will work on porting the remaining modules, +starting with `pushgateway` and the Servlet filter. diff --git a/docs/content/config/config.md b/docs/content/config/config.md index a7e57ac0d..a56b33da2 100644 --- a/docs/content/config/config.md +++ b/docs/content/config/config.md @@ -7,67 +7,76 @@ weight: 1 The Prometheus metrics library provides multiple options how to override configuration at runtime: -* Properties file -* System properties +- Properties file +- System properties Future releases will add more options, like configuration via environment variables. Example: -``` +```properties io.prometheus.exporter.httpServer.port = 9401 ``` -The property above changes the port for the [HTTPServer exporter]({{< relref "/exporters/httpserver.md" >}}) to _9401_. +The property above changes the port for the +[HTTPServer exporter]({{< relref "/exporters/httpserver.md" >}}) to _9401_. -* Properties file: Add the line above to the properties file. -* System properties: Use the command line parameter `-Dio.prometheus.exporter.httpServer.port=9401` when starting your application. +- Properties file: Add the line above to the properties file. +- System properties: Use the command line parameter `-Dio.prometheus.exporter.httpServer.port=9401` +- when starting your application. -Location of the Properties File -------------------------------- +## Location of the Properties File The properties file is searched in the following locations: -* `/prometheus.properties` in the classpath. This is for bundling a properties file with your application. -* System property `-Dprometheus.config=/path/to/prometheus.properties`. -* Environment variable `PROMETHEUS_CONFIG=/path/to/prometheus.properties`. - -Metrics Properties ------------------- - -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()](/client_java/api/io/prometheus/metrics/core/metrics/Counter.Builder.html#withExemplars()) | (1) (2) | -| io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()) | (2) | -| io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) | (2) | -| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicUpperBounds()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicUpperBounds(double...)) | (3) | -| io.prometheus.metrics.histogramNativeInitialSchema | [Histogram.Builder.nativeInitialSchema()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeInitialSchema(int)) | | -| io.prometheus.metrics.histogramNativeMinZeroThreshold | [Histogram.Builder.nativeMinZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMinZeroThreshold(double)) | | -| io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxZeroThreshold(double)) | | -| io.prometheus.metrics.histogramNativeMaxNumberOfBuckets | [Histogram.Builder.nativeMaxNumberOfBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeMaxNumberOfBuckets(int)) | | -| io.prometheus.metrics.histogramNativeResetDurationSeconds | [Histogram.Builder.nativeResetDuration()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeResetDuration(long,java.util.concurrent.TimeUnit)) | | -| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double)) | (4) | -| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#quantile(double,double)) | (5) | -| io.prometheus.metrics.summaryMaxAgeSeconds | [Summary.Builder.maxAgeSeconds()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#maxAgeSeconds(long)) | | -| io.prometheus.metrics.summaryNumberOfAgeBuckets | [Summary.Builder.numberOfAgeBuckets()](/client_java/api/io/prometheus/metrics/core/metrics/Summary.Builder.html#numberOfAgeBuckets(int)) | | +- `/prometheus.properties` in the classpath. This is for bundling a properties file + with your application. +- System property `-Dprometheus.config=/path/to/prometheus.properties`. +- Environment variable `PROMETHEUS_CONFIG=/path/to/prometheus.properties`. + +## Metrics Properties + + + +| Name | Javadoc | Note | +| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| io.prometheus.metrics.exemplarsEnabled | [Counter.Builder.withExemplars()]() | (1) (2) | +| io.prometheus.metrics.histogramNativeOnly | [Histogram.Builder.nativeOnly()]() | (2) | +| io.prometheus.metrics.histogramClassicOnly | [Histogram.Builder.classicOnly()]() | (2) | +| io.prometheus.metrics.histogramClassicUpperBounds | [Histogram.Builder.classicUpperBounds()]() | (3) | +| io.prometheus.metrics.histogramNativeInitialSchema | [Histogram.Builder.nativeInitialSchema()]() | | +| io.prometheus.metrics.histogramNativeMinZeroThreshold | [Histogram.Builder.nativeMinZeroThreshold()]() | | +| io.prometheus.metrics.histogramNativeMaxZeroThreshold | [Histogram.Builder.nativeMaxZeroThreshold()]() | | +| io.prometheus.metrics.histogramNativeMaxNumberOfBuckets | [Histogram.Builder.nativeMaxNumberOfBuckets()]() | | +| io.prometheus.metrics.histogramNativeResetDurationSeconds | [Histogram.Builder.nativeResetDuration()]() | | +| io.prometheus.metrics.summaryQuantiles | [Summary.Builder.quantile(double)]() | (4) | +| io.prometheus.metrics.summaryQuantileErrors | [Summary.Builder.quantile(double, double)]() | (5) | +| io.prometheus.metrics.summaryMaxAgeSeconds | [Summary.Builder.maxAgeSeconds()]() | | +| io.prometheus.metrics.summaryNumberOfAgeBuckets | [Summary.Builder.numberOfAgeBuckets()]() | | + + **Notes** -(1) _withExemplars()_ and _withoutExemplars()_ are available for all metric types, not just for counters
      +(1) _withExemplars()_ and _withoutExemplars()_ are available for all metric types, +not just for counters
      (2) Boolean value. Format: `property=true` or `property=false`.
      (3) Comma-separated list. Example: `.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10`.
      (4) Comma-separated list. Example: `0.5, 0.95, 0.99`.
      -(5) Comma-separated list. If specified, the list must have the same length as `io.prometheus.metrics.summaryQuantiles`. Example: `0.01, 0.005, 0.005`. +(5) Comma-separated list. If specified, the list must have the same length as +`io.prometheus.metrics.summaryQuantiles`. Example: `0.01, 0.005, 0.005`. -There's one special feature about metric properties: You can set a property for one specific metric only by specifying the metric name. Example: Let's say you have a histogram named `latency_seconds`. +There's one special feature about metric properties: You can set a property for one specific +metric only by specifying the metric name. Example: +Let's say you have a histogram named `latency_seconds`. -``` +```properties io.prometheus.metrics.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0 ``` The line above sets histogram buckets for all histograms. However: -``` +```properties io.prometheus.metrics.latency_seconds.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0 ``` @@ -75,75 +84,95 @@ The line above sets histogram buckets only for the histogram named `latency_seco This works for all Metrics properties. -Exemplar Properties -------------------- +## Exemplar Properties + + + +| Name | Javadoc | Note | +| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exemplars.minRetentionPeriodSeconds | [ExemplarsProperties.getMinRetentionPeriodSeconds()]() | | +| io.prometheus.exemplars.maxRetentionPeriodSeconds | [ExemplarsProperties.getMaxRetentionPeriodSeconds()]() | | +| io.prometheus.exemplars.sampleIntervalMilliseconds | [ExemplarsProperties.getSampleIntervalMilliseconds()]() | | -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.exemplars.minRetentionPeriodSeconds | [ExemplarsProperties.getMinRetentionPeriodSeconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getMinRetentionPeriodSeconds()) | | -| io.prometheus.exemplars.maxRetentionPeriodSeconds | [ExemplarsProperties.getMaxRetentionPeriodSeconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getMaxRetentionPeriodSeconds()) | | -| io.prometheus.exemplars.sampleIntervalMilliseconds | [ExemplarsProperties.getSampleIntervalMilliseconds()](/client_java/api/io/prometheus/metrics/config/ExemplarsProperties.html#getSampleIntervalMilliseconds()) | | + -Exporter Properties -------------------- +## Exporter Properties -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.exporter.includeCreatedTimestamps | [ExporterProperties.getIncludeCreatedTimestamps()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getIncludeCreatedTimestamps()) | (1) | -| io.prometheus.exporter.exemplarsOnAllMetricTypes | [ExporterProperties.getExemplarsOnAllMetricTypes()](/client_java/api/io/prometheus/metrics/config/ExporterProperties.html#getExemplarsOnAllMetricTypes()) | (1) | + + +| Name | Javadoc | Note | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exporter.includeCreatedTimestamps | [ExporterProperties.getIncludeCreatedTimestamps()]() | (1) | +| io.prometheus.exporter.exemplarsOnAllMetricTypes | [ExporterProperties.getExemplarsOnAllMetricTypes()]() | (1) | + + (1) Boolean value, `true` or `false`. Default see Javadoc. -Exporter Filter Properties --------------------------- +## Exporter Filter Properties + + + +| Name | Javadoc | Note | +| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exporter.filter.metricNameMustBeEqualTo | [ExporterFilterProperties.getAllowedMetricNames()]() | (1) | +| io.prometheus.exporter.filter.metricNameMustNotBeEqualTo | [ExporterFilterProperties.getExcludedMetricNames()]() | (2) | +| io.prometheus.exporter.filter.metricNameMustStartWith | [ExporterFilterProperties.getAllowedMetricNamePrefixes()]() | (3) | +| io.prometheus.exporter.filter.metricNameMustNotStartWith | [ExporterFilterProperties.getExcludedMetricNamePrefixes()]() | (4) | -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.exporter.filter.metricNameMustBeEqualTo | [ExporterFilterProperties.getAllowedMetricNames()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getAllowedMetricNames()) | (1) | -| io.prometheus.exporter.filter.metricNameMustNotBeEqualTo | [ExporterFilterProperties.getExcludedMetricNames()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getExcludedMetricNames()) | (2) | -| io.prometheus.exporter.filter.metricNameMustStartWith | [ExporterFilterProperties.getAllowedMetricNamePrefixes()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getAllowedMetricNamePrefixes()) | (3) | -| io.prometheus.exporter.filter.metricNameMustNotStartWith | [ExporterFilterProperties.getExcludedMetricNamePrefixes()](/client_java/api/io/prometheus/metrics/config/ExporterFilterProperties.html#getExcludedMetricNamePrefixes()) | (4) | + (1) Comma sparated list of allowed metric names. Only these metrics will be exposed.
      (2) Comma sparated list of excluded metric names. These metrics will not be exposed.
      (3) Comma sparated list of prefixes. Only metrics starting with these prefixes will be exposed.
      (4) Comma sparated list of prefixes. Metrics starting with these prefixes will not be exposed.
      -Exporter HTTPServer Properties ------------------------------- - -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.exporter.httpServer.port | [HTTPServer.Builder.port()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#port(int)) | | - -Exporter OpenTelemetry Properties ---------------------------------- - -| Name | Javadoc | Note | -| --------------- | --------|------| -| io.prometheus.exporter.opentelemetry.protocol | [OpenTelemetryExporter.Builder.protocol()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#protocol(java.lang.String)) | (1) | -| io.prometheus.exporter.opentelemetry.endpoint | [OpenTelemetryExporter.Builder.endpoint()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#endpoint(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.headers | [OpenTelemetryExporter.Builder.headers()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#header(java.lang.String,java.lang.String)) | (2) | -| io.prometheus.exporter.opentelemetry.intervalSeconds | [OpenTelemetryExporter.Builder.intervalSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#intervalSeconds(int)) | | -| io.prometheus.exporter.opentelemetry.timeoutSeconds | [OpenTelemetryExporter.Builder.timeoutSeconds()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#timeoutSeconds(int)) | | -| io.prometheus.exporter.opentelemetry.serviceName | [OpenTelemetryExporter.Builder.serviceName()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceName(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.serviceNamespace | [OpenTelemetryExporter.Builder.serviceNamespace()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceNamespace(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.serviceInstanceId | [OpenTelemetryExporter.Builder.serviceInstanceId()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceInstanceId(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.serviceVersion | [OpenTelemetryExporter.Builder.serviceVersion()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceVersion(java.lang.String)) | | -| io.prometheus.exporter.opentelemetry.resourceAttributes | [OpenTelemetryExporter.Builder.resourceAttributes()](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#resourceAttribute(java.lang.String,java.lang.String)) | (3) | +## Exporter HTTPServer Properties + + + +| Name | Javadoc | Note | +| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exporter.httpServer.port | [HTTPServer.Builder.port()]() | | + + + +## Exporter OpenTelemetry Properties + + + +| Name | Javadoc | Note | +| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exporter.opentelemetry.protocol | [OpenTelemetryExporter.Builder.protocol()]() | (1) | +| io.prometheus.exporter.opentelemetry.endpoint | [OpenTelemetryExporter.Builder.endpoint()]() | | +| io.prometheus.exporter.opentelemetry.headers | [OpenTelemetryExporter.Builder.headers()]() | (2) | +| io.prometheus.exporter.opentelemetry.intervalSeconds | [OpenTelemetryExporter.Builder.intervalSeconds()]() | | +| io.prometheus.exporter.opentelemetry.timeoutSeconds | [OpenTelemetryExporter.Builder.timeoutSeconds()]() | | +| io.prometheus.exporter.opentelemetry.serviceName | [OpenTelemetryExporter.Builder.serviceName()]() | | +| io.prometheus.exporter.opentelemetry.serviceNamespace | [OpenTelemetryExporter.Builder.serviceNamespace()]() | | +| io.prometheus.exporter.opentelemetry.serviceInstanceId | [OpenTelemetryExporter.Builder.serviceInstanceId()]() | | +| io.prometheus.exporter.opentelemetry.serviceVersion | [OpenTelemetryExporter.Builder.serviceVersion()]() | | +| io.prometheus.exporter.opentelemetry.resourceAttributes | [OpenTelemetryExporter.Builder.resourceAttributes()]() | (3) | + + (1) Protocol can be `grpc` or `http/protobuf`.
      (2) Format: `key1=value1,key2=value2`
      (3) Format: `key1=value1,key2=value2` -Many of these attributes can alternatively be configured via OpenTelemetry environment variables, like `OTEL_EXPORTER_OTLP_ENDPOINT`. The Prometheus metrics library has support for OpenTelemetry environment variables. See Javadoc for details. +Many of these attributes can alternatively be configured via OpenTelemetry environment variables, +like `OTEL_EXPORTER_OTLP_ENDPOINT`. +The Prometheus metrics library has support for OpenTelemetry environment variables. +See Javadoc for details. + +## Exporter PushGateway Properties -Exporter PushGateway Properties -------------------------------- + -| Name | Javadoc | Note | -|--------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|------| -| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#address(java.lang.String)) | | -| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#scheme(java.lang.String)) | | -| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#job(java.lang.String)) | | +| Name | Javadoc | Note | +| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | +| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()]() | | +| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()]() | | +| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()]() | | + diff --git a/docs/content/exporters/filter.md b/docs/content/exporters/filter.md index 32dc0a56d..01ac48e69 100644 --- a/docs/content/exporters/filter.md +++ b/docs/content/exporters/filter.md @@ -5,14 +5,16 @@ weight: 2 All exporters support a `name[]` URL parameter for querying only specific metric names. Examples: -* `/metrics?name[]=jvm_threads_current` will query the metric named `jvm_threads_current`. -* `/metrics?name[]=jvm_threads_current&name[]=jvm_threads_daemon` will query two metrics, `jvm_threads_current` and `jvm_threads_daemon`. +- `/metrics?name[]=jvm_threads_current` will query the metric named `jvm_threads_current`. +- `/metrics?name[]=jvm_threads_current&name[]=jvm_threads_daemon` will query two metrics, + `jvm_threads_current` and `jvm_threads_daemon`. -Add the following to the scape job configuration in `prometheus.yml` to make the Prometheus server send the `name[]` parameter: +Add the following to the scape job configuration in `prometheus.yml` +to make the Prometheus server send the `name[]` parameter: ```yaml params: - name[]: - - jvm_threads_current - - jvm_threads_daemon + name[]: + - jvm_threads_current + - jvm_threads_daemon ``` diff --git a/docs/content/exporters/formats.md b/docs/content/exporters/formats.md index 189d13d56..a6485c84c 100644 --- a/docs/content/exporters/formats.md +++ b/docs/content/exporters/formats.md @@ -5,23 +5,28 @@ weight: 1 All exporters the following exposition formats: -* OpenMetrics text format -* Prometheus text format -* Prometheus protobuf format +- OpenMetrics text format +- Prometheus text format +- Prometheus protobuf format Moreover, gzip encoding is supported for each of these formats. ## Scraping with a Prometheus server -The Prometheus server sends an `Accept` header to specify which format is requested. By default, the Prometheus server will scrape OpenMetrics text format with gzip encoding. If the Prometheus server is started with `--enable-feature=native-histograms`, it will scrape Prometheus protobuf format instead. +The Prometheus server sends an `Accept` header to specify which format is requested. By default, the +Prometheus server will scrape OpenMetrics text format with gzip encoding. If the Prometheus server +is started with `--enable-feature=native-histograms`, it will scrape Prometheus protobuf format +instead. ## Viewing with a Web Browser -If you view the `/metrics` endpoint with your Web browser you will see Prometheus text format. For quick debugging of the other formats, exporters provide a `debug` URL parameter: +If you view the `/metrics` endpoint with your Web browser you will see Prometheus text format. For +quick debugging of the other formats, exporters provide a `debug` URL parameter: -* `/metrics?debug=openmetrics`: View OpenMetrics text format. -* `/metrics?debug=text`: View Prometheus text format. -* `/metrics?debug=prometheus-protobuf`: View a text representation of the Prometheus protobuf format. +- `/metrics?debug=openmetrics`: View OpenMetrics text format. +- `/metrics?debug=text`: View Prometheus text format. +- `/metrics?debug=prometheus-protobuf`: View a text representation of the Prometheus protobuf + format. ## Exclude protobuf exposition format diff --git a/docs/content/exporters/httpserver.md b/docs/content/exporters/httpserver.md index e524b4cd1..4d0aab5f2 100644 --- a/docs/content/exporters/httpserver.md +++ b/docs/content/exporters/httpserver.md @@ -3,35 +3,41 @@ title: HTTPServer weight: 3 --- -The `HTTPServer` is a standalone server for exposing a metric endpoint. A minimal example application for `HTTPServer` can be found in the [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory. +The `HTTPServer` is a standalone server for exposing a metric endpoint. A minimal example +application for `HTTPServer` can be found in +the [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory. ```java HTTPServer server = HTTPServer.builder() - .port(9400) - .buildAndStart(); + .port(9400) + .buildAndStart(); ``` -By default, `HTTPServer` binds to any IP address, you can change this with [hostname()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#hostname(java.lang.String)) or [inetAddress()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#inetAddress(java.net.InetAddress)). +By default, `HTTPServer` binds to any IP address, you can change this with +[hostname()]() +or [inetAddress()](). `HTTPServer` is configured with three endpoints: -* `/metrics` for Prometheus scraping. -* `/-/healthy` for simple health checks. -* `/` the default handler is a static HTML page. +- `/metrics` for Prometheus scraping. +- `/-/healthy` for simple health checks. +- `/` the default handler is a static HTML page. -The default handler can be changed with [defaultHandler()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#defaultHandler(com.sun.net.httpserver.HttpHandler)). +The default handler can be changed +with [defaultHandler()](). -Authentication and HTTPS ------------------------- +## Authentication and HTTPS -* [authenticator()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#authenticator(com.sun.net.httpserver.Authenticator)) is for configuring authentication. -* [httpsConfigurator()](/client_java/api/io/prometheus/metrics/exporter/httpserver/HTTPServer.Builder.html#httpsConfigurator(com.sun.net.httpserver.HttpsConfigurator)) is for configuring HTTPS. +- [authenticator()]() + is for configuring authentication. +- [httpsConfigurator()]() + is for configuring HTTPS. -You can find an example of authentication and SSL in the [jmx_exporter](https://github.com/prometheus/jmx_exporter). +You can find an example of authentication and SSL in the +[jmx_exporter](https://github.com/prometheus/jmx_exporter). -Properties ----------- +## Properties See _config_ section (_todo_) on runtime configuration options. -* `io.prometheus.exporter.httpServer.port`: The port to bind to. +- `io.prometheus.exporter.httpServer.port`: The port to bind to. diff --git a/docs/content/exporters/pushgateway.md b/docs/content/exporters/pushgateway.md index 1ca2946b1..b4c531022 100644 --- a/docs/content/exporters/pushgateway.md +++ b/docs/content/exporters/pushgateway.md @@ -3,23 +3,28 @@ title: Pushgateway weight: 5 --- -The [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) exists to allow ephemeral and batch jobs to expose their metrics to Prometheus. -Since these kinds of jobs may not exist long enough to be scraped, they can instead push their metrics to a Pushgateway. +The [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) exists to allow ephemeral +and batch jobs to expose their metrics to Prometheus. +Since these kinds of jobs may not exist long enough to be scraped, they can instead push their +metrics to a Pushgateway. The Pushgateway then exposes these metrics to Prometheus. -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) Java class allows you to push metrics to a Prometheus Pushgateway. +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) Java +class allows you to push metrics to a Prometheus Pushgateway. -Example -------- +## Example {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-core:1.3.0' implementation 'io.prometheus:prometheus-metrics-exporter-pushgateway:1.3.0' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -32,6 +37,7 @@ implementation 'io.prometheus:prometheus-metrics-exporter-pushgateway:1.3.0' 1.3.0 ``` + {{< /tab >}} {{< /tabs >}} @@ -66,10 +72,10 @@ public class ExampleBatchJob { } ``` -Basic Auth ----------- +## Basic Auth -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports basic authentication. +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) +supports basic authentication. ```java PushGateway pushGateway = PushGateway.builder() @@ -80,10 +86,10 @@ PushGateway pushGateway = PushGateway.builder() The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. -Bearer token ----------- +## Bearer token -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports Bearer token authentication. +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) +supports Bearer token authentication. ```java PushGateway pushGateway = PushGateway.builder() @@ -94,11 +100,10 @@ PushGateway pushGateway = PushGateway.builder() The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. +## SSL -SSL ---- - -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports SSL. +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) +supports SSL. ```java PushGateway pushGateway = PushGateway.builder() @@ -109,10 +114,12 @@ PushGateway pushGateway = PushGateway.builder() However, this requires that the JVM can validate the server certificate. -If you want to skip certificate verification, you need to provide your own [HttpConnectionFactory](/client_java/api/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.html). +If you want to skip certificate verification, you need to provide your own +[HttpConnectionFactory](/client_java/api/io/prometheus/metrics/exporter/pushgateway/HttpConnectionFactory.html). The `PushGatewayTestApp` in `integration-tests/it-pushgateway` has a complete example of this. -Configuration Properties ------------------------- +## Configuration Properties -The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) supports a couple of properties that can be configured at runtime. See [config](../../config/config). +The [PushGateway](/client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.html) +supports a couple of properties that can be configured at runtime. +See [config]({{< relref "../config/config.md" >}}). diff --git a/docs/content/exporters/servlet.md b/docs/content/exporters/servlet.md index 36a5161cf..93b870b1d 100644 --- a/docs/content/exporters/servlet.md +++ b/docs/content/exporters/servlet.md @@ -3,13 +3,16 @@ title: Servlet weight: 4 --- -The [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) is a [Jakarta Servlet](https://jakarta.ee/specifications/servlet/) for exposing a metric endpoint. +The +[PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) +is a [Jakarta Servlet](https://jakarta.ee/specifications/servlet/) for exposing a metric endpoint. -web.xml -------- +## web.xml The old-school way of configuring a servlet is in a `web.xml` file: + + ```xml ``` -Programmatic ------------- - -Today, most Servlet applications use an embedded Servlet container and configure Servlets programmatically rather than via `web.xml`. -The API for that depends on the Servlet container. -The [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory has an example of an embedded [Tomcat](https://tomcat.apache.org/) container with the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) configured. + -Spring ------- +## Programmatic -You can use the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) in Spring applications. See [our Spring doc]({{< relref "spring.md" >}}). +Today, most Servlet applications use an embedded Servlet container and configure Servlets +programmatically rather than via `web.xml`. +The API for that depends on the Servlet container. +The [examples](https://github.com/prometheus/client_java/tree/1.0.x/examples) directory has an +example of an embedded +[Tomcat](https://tomcat.apache.org/) container with the +[PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) +configured. + +## Spring + +You can use +the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) +in Spring applications. +See [our Spring doc]({{< relref "spring.md" >}}). diff --git a/docs/content/exporters/spring.md b/docs/content/exporters/spring.md index 73e4b2549..fc0d946dd 100644 --- a/docs/content/exporters/spring.md +++ b/docs/content/exporters/spring.md @@ -3,33 +3,40 @@ title: Spring weight: 5 --- -Alternative: Use Spring's Built-in Metrics Library --------------------------------------------------- +## Alternative: Use Spring's Built-in Metrics Library -[Spring Boot](https://spring.io/projects/spring-boot) has a built-in metric library named [Micrometer](https://micrometer.io/), which supports Prometheus exposition format and can be set up in three simple steps: +[Spring Boot](https://spring.io/projects/spring-boot) has a built-in metric library named +[Micrometer](https://micrometer.io/), which supports Prometheus +exposition format and can be set up in three simple steps: 1. Add the `org.springframework.boot:spring-boot-starter-actuator` dependency. 2. Add the `io.micrometer:micrometer-registry-prometheus` as a _runtime_ dependency. -3. Enable the Prometheus endpoint by adding the line `management.endpoints.web.exposure.include=prometheus` to `application.properties`. +3. Enable the Prometheus endpoint by adding the line + `management.endpoints.web.exposure.include=prometheus` to `application.properties`. Note that Spring's default Prometheus endpoint is `/actuator/prometheus`, not `/metrics`. -In most cases the built-in Spring metrics library will work for you and you don't need the Prometheus Java library in Spring applications. +In most cases the built-in Spring metrics library will work for you and you don't need the +Prometheus Java library in Spring applications. -Use the Prometheus Metrics Library in Spring --------------------------------------------- +## Use the Prometheus Metrics Library in Spring -However, you may have your reasons why you want to use the Prometheus metrics library in Spring anyway. Maybe you want full support for all Prometheus metric types, or you want to use the new Prometheus native histograms. +However, you may have your reasons why you want to use the Prometheus metrics library in +Spring anyway. Maybe you want full support for all Prometheus metric types, +or you want to use the new Prometheus native histograms. -The easiest way to use the Prometheus metrics library in Spring is to configure the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics. +The easiest way to use the Prometheus metrics library in Spring is to configure the +[PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) +to expose metrics. Dependencies: -* `prometheus-metrics-core`: The core metrics library. -* `prometheus-metrics-exporter-servlet-jakarta`: For providing the `/metrics` endpoint. -* `prometheus-metrics-instrumentation-jvm`: Optional - JVM metrics +- `prometheus-metrics-core`: The core metrics library. +- `prometheus-metrics-exporter-servlet-jakarta`: For providing the `/metrics` endpoint. +- `prometheus-metrics-instrumentation-jvm`: Optional - JVM metrics -The following is the complete source code of a Spring Boot REST service using the Prometheus metrics library: +The following is the complete source code of a Spring Boot REST service using +the Prometheus metrics library: ```java import io.prometheus.metrics.core.metrics.Counter; @@ -46,35 +53,40 @@ import org.springframework.web.bind.annotation.RestController; @RestController public class DemoApplication { - private static final Counter requestCount = Counter.builder() - .name("requests_total") - .register(); - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - JvmMetrics.builder().register(); - } - - @GetMapping("/") - public String sayHello() throws InterruptedException { - requestCount.inc(); - return "Hello, World!\n"; - } - - @Bean - public ServletRegistrationBean createPrometheusMetricsEndpoint() { - return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); - } + private static final Counter requestCount = Counter.builder() + .name("requests_total") + .register(); + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + JvmMetrics.builder().register(); + } + + @GetMapping("/") + public String sayHello() throws InterruptedException { + requestCount.inc(); + return "Hello, World!\n"; + } + + @Bean + public ServletRegistrationBean createPrometheusMetricsEndpoint() { + return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); + } } ``` -The important part are the last three lines: They configure the [PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) to expose metrics on `/metrics`: +The important part are the last three lines: They configure the +[PrometheusMetricsServlet](/client_java/api/io/prometheus/metrics/exporter/servlet/jakarta/PrometheusMetricsServlet.html) +to expose metrics on `/metrics`: ```java + @Bean public ServletRegistrationBean createPrometheusMetricsEndpoint() { - return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); + return new ServletRegistrationBean<>(new PrometheusMetricsServlet(), "/metrics/*"); } ``` -The example provides a _Hello, world!_ endpoint on [http://localhost:8080](http://localhost:8080), and Prometheus metrics on [http://localhost:8080/metrics](http://localhost:8080/metrics). +The example provides a _Hello, world!_ endpoint on +[http://localhost:8080](http://localhost:8080), and Prometheus metrics on +[http://localhost:8080/metrics](http://localhost:8080/metrics). diff --git a/docs/content/getting-started/callbacks.md b/docs/content/getting-started/callbacks.md index b94033fc5..514d74c2a 100644 --- a/docs/content/getting-started/callbacks.md +++ b/docs/content/getting-started/callbacks.md @@ -3,11 +3,14 @@ title: Callbacks weight: 5 --- -The section on [metric types](../metric-types) showed how to use metrics that actively maintain their state. +The section on [metric types]({{< relref "metric-types.md" >}}) +showed how to use metrics that actively maintain their state. -This section shows how to create callback-based metrics, i.e. metrics that invoke a callback at scrape time to get the current values. +This section shows how to create callback-based metrics, i.e. metrics that invoke a callback +at scrape time to get the current values. -For example, let's assume we have two instances of a `Cache`, a `coldCache` and a `hotCache`. The following implements a callback-based `cache_size_bytes` metric: +For example, let's assume we have two instances of a `Cache`, a `coldCache` and a `hotCache`. +The following implements a callback-based `cache_size_bytes` metric: ```java Cache coldCache = new Cache(); @@ -27,7 +30,7 @@ GaugeWithCallback.builder() The resulting text format looks like this: -``` +```text # TYPE cache_size_bytes gauge # UNIT cache_size_bytes bytes # HELP cache_size_bytes Size of the cache in Bytes. @@ -35,15 +38,17 @@ cache_size_bytes{state="cold"} 78.0 cache_size_bytes{state="hot"} 83.0 ``` -Better examples of callback metrics can be found in the `prometheus-metrics-instrumentation-jvm` module. +Better examples of callback metrics can be found in the `prometheus-metrics-instrumentation-jvm` +module. The available callback metric types are: -* `GaugeWithCallback` for gauges. -* `CounterWithCallback` for counters. -* `SummaryWithCallback` for summaries. +- `GaugeWithCallback` for gauges. +- `CounterWithCallback` for counters. +- `SummaryWithCallback` for summaries. -The API for gauges and counters is very similar. For summaries the callback has a few more parameters, because it accepts a count, a sum, and quantiles: +The API for gauges and counters is very similar. For summaries the callback has a few more +parameters, because it accepts a count, a sum, and quantiles: ```java SummaryWithCallback.builder() diff --git a/docs/content/getting-started/labels.md b/docs/content/getting-started/labels.md index 5aeb5f215..d056a6ce6 100644 --- a/docs/content/getting-started/labels.md +++ b/docs/content/getting-started/labels.md @@ -5,7 +5,7 @@ weight: 3 The following shows an example of a Prometheus metric in text format: -``` +```text # HELP payments_total total number of payments # TYPE payments_total counter payments_total{status="error",type="paypal"} 1.0 @@ -13,12 +13,14 @@ payments_total{status="success",type="credit card"} 3.0 payments_total{status="success",type="paypal"} 2.0 ``` -The example shows a counter metric named `payments_total` with two labels: `status` and `type`. Each individual data point (each line in text format) is identified by the unique combination of its metric name and its label name/value pairs. +The example shows a counter metric named `payments_total` with two labels: `status` and `type`. +Each individual data point (each line in text format) is identified by the unique combination of +its metric name and its label name/value pairs. -Creating a Metric with Labels ------------------------------ +## Creating a Metric with Labels -Labels are supported for all metric types. We are using counters in this example, however the `labelNames()` and `labelValues()` methods are the same for other metric types. +Labels are supported for all metric types. We are using counters in this example, however the +`labelNames()` and `labelValues()` methods are the same for other metric types. The following code creates the counter above. @@ -34,10 +36,10 @@ counter.labelValues("paypal", "success").inc(2.0); counter.labelValues("paypal", "error").inc(1.0); ``` -The label names have to be specified when the metric is created and cannot change. The label values are created on demand when values are observed. +The label names have to be specified when the metric is created and cannot change. The label values +are created on demand when values are observed. -Creating a Metric without Labels --------------------------------- +## Creating a Metric without Labels Labels are optional. The following example shows a metric without labels: @@ -50,12 +52,13 @@ Counter counter = Counter.builder() counter.inc(3.0); ``` -Cardinality Explosion ---------------------- +## Cardinality Explosion -Each combination of label names and values will result in a new data point, i.e. a new line in text format. +Each combination of label names and values will result in a new data point, i.e. a new line in text +format. Therefore, a good label should have only a small number of possible values. -If you select labels with many possible values, like unique IDs or timestamps, you may end up with an enormous number of data points. +If you select labels with many possible values, like unique IDs or timestamps, +you may end up with an enormous number of data points. This is called cardinality explosion. Here's a bad example, don't do this: @@ -73,12 +76,12 @@ String timestamp = Long.toString(System.currentTimeMillis()); loginCount.labelValues(userId, timestamp).inc(); ``` -Initializing Label Values -------------------------- +## Initializing Label Values If you register a metric without labels, it will show up immediately with initial value of zero. -However, metrics with labels only show up after the label values are first used. In the example above +However, metrics with labels only show up after the label values are first used. In the example +above ```java counter.labelValues("paypal", "error").inc(); @@ -86,13 +89,14 @@ counter.labelValues("paypal", "error").inc(); The data point -``` +```text payments_total{status="error",type="paypal"} 1.0 ``` will jump from non-existent to value 1.0. You will never see it with value 0.0. -This is usually not an issue. However, if you find this annoying and want to see all possible label values from the start, you can initialize label values with `initLabelValues()` like this: +This is usually not an issue. However, if you find this annoying and want to see all possible label +values from the start, you can initialize label values with `initLabelValues()` like this: ```java Counter counter = Counter.builder() @@ -109,7 +113,7 @@ counter.initLabelValues("paypal", "error"); Now the four combinations will be visible from the start with initial value zero. -``` +```text # HELP payments_total total number of payments # TYPE payments_total counter payments_total{status="error",type="credit card"} 0.0 @@ -118,10 +122,10 @@ payments_total{status="success",type="credit card"} 0.0 payments_total{status="success",type="paypal"} 0.0 ``` -Expiring Unused Label Values ----------------------------- +## Expiring Unused Label Values -There is no automatic expiry of unused label values (yet). Once a set of label values is used, it will remain there forever. +There is no automatic expiry of unused label values (yet). Once a set of label values is used, it +will remain there forever. However, you can programmatically remove label values like this: @@ -130,8 +134,7 @@ counter.remove("paypal", "error"); counter.remove("paypal", "success"); ``` -Const Labels ------------- +## Const Labels If you have labels values that never change, you can specify them in the builder as `constLabels()`: @@ -144,6 +147,7 @@ Counter counter = Counter.builder() .register(); ``` -However, most use cases for `constLabels()` are better covered by target labels set by the scraping Prometheus server, +However, most use cases for `constLabels()` are better covered by target labels set by the scraping +Prometheus server, or by one specific metric (e.g. a `build_info` or a `machine_role` metric). See also -[target labels, not static scraped labels](https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels). +[target labels, not static scraped labels](https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels). diff --git a/docs/content/getting-started/metric-types.md b/docs/content/getting-started/metric-types.md index e10d51e9a..3bcda84fe 100644 --- a/docs/content/getting-started/metric-types.md +++ b/docs/content/getting-started/metric-types.md @@ -1,19 +1,25 @@ --- -title: 'Metric Types' +title: "Metric Types" weight: 4 --- -The Prometheus Java metrics library implements the metric types defined in the [OpenMetrics](https://openmetrics.io) standard: +The Prometheus Java metrics library implements the metric types defined in +the [OpenMetrics](https://openmetrics.io) standard: {{< toc >}} -Counter -------- +## Counter -Counter is the most common and useful metric type. Counters can only increase, but never decrease. In the Prometheus query language, the [rate()](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) function is often used for counters to calculate the average increase per second. +Counter is the most common and useful metric type. Counters can only increase, but never decrease. +In the Prometheus query language, +the [rate()](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) function is +often used for counters to calculate the average increase per second. {{< hint type=note >}} -Counter values do not need to be integers. In many cases counters represent a number of events (like the number of requests), and in that case the counter value is an integer. However, counters can also be used for something like "total time spent doing something" in which case the counter value is a floating point number. +Counter values do not need to be integers. In many cases counters represent a number of events (like +the number of requests), and in that case the counter value is an integer. However, counters can +also be used for something like "total time spent doing something" in which case the counter value +is a floating point number. {{< /hint >}} Here's an example of a counter: @@ -28,12 +34,14 @@ Counter serviceTimeSeconds = Counter.builder() serviceTimeSeconds.inc(Unit.millisToSeconds(200)); ``` -The resulting counter has the value `0.2`. As `SECONDS` is the standard time unit in Prometheus, the `Unit` utility class has methods to convert other time units to seconds. +The resulting counter has the value `0.2`. As `SECONDS` is the standard time unit in Prometheus, the +`Unit` utility class has methods to convert other time units to seconds. -As defined in [OpenMetrics](https://openmetrics.io/), counter metric names must have the `_total` suffix. If you create a counter without the `_total` suffix the suffix will be appended automatically. +As defined in [OpenMetrics](https://openmetrics.io/), counter metric names must have the `_total` +suffix. If you create a counter without the `_total` suffix the suffix will be appended +automatically. -Gauge ------ +## Gauge Gauges are current measurements, such as the current temperature in Celsius. @@ -48,27 +56,36 @@ Gauge temperature = Gauge.builder() temperature.labelValues("Berlin").set(22.3); ``` -Histogram ---------- +## Histogram -Histograms are for observing distributions, like latency distributions for HTTP services or the distribution of request sizes. -Unlike with counters and gauges, each histogram data point has a complex data structure representing different aspects of the distribution: +Histograms are for observing distributions, like latency distributions for HTTP services or the +distribution of request sizes. +Unlike with counters and gauges, each histogram data point has a complex data structure representing +different aspects of the distribution: -* Count: The total number of observations. -* Sum: The sum of all observed values, e.g. the total time spent serving requests. -* Buckets: The histogram buckets representing the distribution. +- Count: The total number of observations. +- Sum: The sum of all observed values, e.g. the total time spent serving requests. +- Buckets: The histogram buckets representing the distribution. Prometheus supports two flavors of histograms: -* Classic histograms: Bucket boundaries are explicitly defined when the histogram is created. -* Native histograms (exponential histograms): Infinitely many virtual buckets. +- Classic histograms: Bucket boundaries are explicitly defined when the histogram is created. +- Native histograms (exponential histograms): Infinitely many virtual buckets. -By default, histograms maintain both flavors. Which one is used depends on the scrape request from the Prometheus server. -* By default, the Prometheus server will scrape metrics in OpenMetrics format and get the classic histogram flavor. -* If the Prometheus server is started with `--enable-feature=native-histograms`, it will request metrics in Prometheus protobuf format and ingest the native histogram. -* If the Prometheus server is started with `--enable-feature=native-histogram` and the scrape config has the option `scrape_classic_histograms: true`, it will request metrics in Prometheus protobuf format and ingest both, the classic and the native flavor. This is great for migrating from classic histograms to native histograms. +By default, histograms maintain both flavors. Which one is used depends on the scrape request from +the Prometheus server. -See [examples/example-native-histogram](https://github.com/prometheus/client_java/tree/1.0.x/examples/example-native-histogram) for an example. +- By default, the Prometheus server will scrape metrics in OpenMetrics format and get the classic + histogram flavor. +- If the Prometheus server is started with `--enable-feature=native-histograms`, it will request + metrics in Prometheus protobuf format and ingest the native histogram. +- If the Prometheus server is started with `--enable-feature=native-histogram` and the scrape config + has the option `scrape_classic_histograms: true`, it will request metrics in Prometheus protobuf + format and ingest both, the classic and the native flavor. This is great for migrating from + classic histograms to native histograms. + +See [examples/example-native-histogram](https://github.com/prometheus/client_java/tree/1.0.x/examples/example-native-histogram) +for an example. ```java Histogram duration = Histogram.builder() @@ -83,17 +100,30 @@ long start = System.nanoTime(); duration.labelValues("GET", "/", "200").observe(Unit.nanosToSeconds(System.nanoTime() - start)); ``` -Histograms implement the [TimerApi](/client_java/api/io/prometheus/metrics/core/datapoints/TimerApi.html) interface, which provides convenience methods for measuring durations. +Histograms implement +the [TimerApi](/client_java/api/io/prometheus/metrics/core/datapoints/TimerApi.html) interface, +which provides convenience methods for measuring durations. -The histogram builder provides a lot of configuration for fine-tuning the histogram behavior. In most cases you don't need them, defaults are good. The following is an incomplete list showing the most important options: +The histogram builder provides a lot of configuration for fine-tuning the histogram behavior. In +most cases you don't need them, defaults are good. The following is an incomplete list showing the +most important options: -* `nativeOnly()` / `classicOnly()`: Create a histogram with one representation only. -* `classicBuckets(...)`: Set the classic bucket boundaries. Default buckets are `.005`, `.01`, `.025`, `.05`, `.1`, `.25`, `.5`, `1`, `2.5`, `5`, `and 10`. The default bucket boundaries are designed for measuring request durations in seconds. -* `nativeMaxNumberOfBuckets()`: Upper limit for the number of native histogram buckets. Default is 160. When the maximum is reached, the native histogram automatically reduces resolution to stay below the limit. +- `nativeOnly()` / `classicOnly()`: Create a histogram with one representation only. +- `classicBuckets(...)`: Set the classic bucket boundaries. Default buckets are `.005`, `.01`, + `.025`, `.05`, `.1`, `.25`, `.5`, `1`, `2.5`, `5`, `and 10`. The default bucket boundaries are + designed for measuring request durations in seconds. +- `nativeMaxNumberOfBuckets()`: Upper limit for the number of native histogram buckets. + Default is 160. When the maximum is reached, the native histogram automatically + reduces resolution to stay below the limit. -See Javadoc for [Histogram.Builder](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html) for a complete list of options. Some options can be configured at runtime, see [config](../../config/config). +See Javadoc +for [Histogram.Builder](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html) +for a complete list of options. Some options can be configured at runtime, +see [config]({{< relref "../config/config.md" >}}). -Histograms and summaries are both used for observing distributions. Therefore, the both implement the `DistributionDataPoint` interface. Using the `DistributionDataPoint` interface directly gives you the option to switch between histograms and summaries later with minimal code changes. +Histograms and summaries are both used for observing distributions. Therefore, the both implement +the `DistributionDataPoint` interface. Using the `DistributionDataPoint` interface directly gives +you the option to switch between histograms and summaries later with minimal code changes. Example of using the `DistributionDataPoint` interface for a histogram without labels: @@ -128,10 +158,10 @@ successfulEvents.observe(0.7); erroneousEvents.observe(0.2); ``` -Summary -------- +## Summary -Like histograms, summaries are for observing distributions. Each summary data point has a count and a sum like a histogram data point. +Like histograms, summaries are for observing distributions. Each summary data point has a count and +a sum like a histogram data point. However, rather than histogram buckets summaries maintain quantiles. ```java @@ -148,26 +178,37 @@ Summary requestLatency = Summary.builder() requestLatency.labelValues("ok").observe(2.7); ``` -The example above creates a summary with the 50th percentile (median), the 95th percentile, and the 99th percentile. Quantiles are optional, you can create a summary without quantiles if all you need is the count and the sum. +The example above creates a summary with the 50th percentile (median), the 95th percentile, and the +99th percentile. Quantiles are optional, you can create a summary without quantiles if all you need +is the count and the sum. {{< hint type=note >}} -The terms "percentile" and "quantile" mean the same thing. We use percentile when we express it as a number in [0, 100], and we use quantile when we express it as a number in [0.0, 1.0]. +The terms "percentile" and "quantile" mean the same thing. We use percentile when we express it as a +number in [0, 100], and we use quantile when we express it as a number in [0.0, 1.0]. {{< /hint >}} -The second parameter to `quantile()` is the maximum acceptable error. The call `.quantile(0.5, 0.01)` means that the actual quantile is somewhere in [0.49, 0.51]. Higher precision means higher memory usage. +The second parameter to `quantile()` is the maximum acceptable error. The call +`.quantile(0.5, 0.01)` means that the actual quantile is somewhere in [0.49, 0.51]. Higher precision +means higher memory usage. -The 0.0 quantile (min value) and the 1.0 quantile (max value) are special cases because you can get the precise values (error 0.0) with almost no memory overhead. +The 0.0 quantile (min value) and the 1.0 quantile (max value) are special cases because you can get +the precise values (error 0.0) with almost no memory overhead. -Quantile values are calculated based on a 5 minutes moving time window. The default time window can be changed with `maxAgeSeconds()` and `numberOfAgeBuckets()`. +Quantile values are calculated based on a 5 minutes moving time window. The default time window can +be changed with `maxAgeSeconds()` and `numberOfAgeBuckets()`. -Some options can be configured at runtime, see [config](../../config/config). +Some options can be configured at runtime, see [config]({{< relref "../config/config.md" >}}). -In general you should prefer histograms over summaries. The Prometheus query language has a function [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for calculating quantiles from histograms. The advantage of query-time quantile calculation is that you can aggregate histograms before calculating the quantile. With summaries you must use the quantile with all its labels as it is. +In general you should prefer histograms over summaries. The Prometheus query language has a +function [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) +for calculating quantiles from histograms. The advantage of query-time quantile calculation is that +you can aggregate histograms before calculating the quantile. With summaries you must use the +quantile with all its labels as it is. -Info ----- +## Info -Info metrics are used to expose textual information which should not change during process lifetime. The value of an Info metric is always `1`. +Info metrics are used to expose textual information which should not change during process lifetime. +The value of an Info metric is always `1`. ```java Info info = Info.builder() @@ -185,20 +226,27 @@ info.setLabelValues(version, vendor, runtime); The info above looks as follows in OpenMetrics text format: -``` + + +```text # TYPE jvm_runtime info # HELP jvm_runtime JVM runtime info jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1 ``` -The example is taken from the `prometheus-metrics-instrumentation-jvm` module, so if you have `JvmMetrics` registered you should have a `jvm_runtime_info` metric out-of-the-box. + -As defined in [OpenMetrics](https://openmetrics.io/), info metric names must have the `_info` suffix. If you create a counter without the `_info` suffix the suffix will be appended automatically. +The example is taken from the `prometheus-metrics-instrumentation-jvm` module, so if you have +`JvmMetrics` registered you should have a `jvm_runtime_info` metric out-of-the-box. -StateSet --------- +As defined in [OpenMetrics](https://openmetrics.io/), info metric names must have the `_info` +suffix. If you create a counter without the `_info` suffix the suffix will be appended +automatically. -StateSet are a niche metric type in the OpenMetrics standard that is rarely used. The main use case is to signal which feature flags are enabled. +## StateSet + +StateSet are a niche metric type in the OpenMetrics standard that is rarely used. The main use case +is to signal which feature flags are enabled. ```java StateSet stateSet = StateSet.builder() @@ -214,16 +262,17 @@ stateSet.labelValues("dev").setTrue("feature2"); The OpenMetrics text format looks like this: -``` +```text # TYPE feature_flags stateset # HELP feature_flags Feature flags feature_flags{env="dev",feature_flags="feature1"} 0 feature_flags{env="dev",feature_flags="feature2"} 1 ``` -GaugeHistogram and Unknown --------------------------- +## GaugeHistogram and Unknown -These types are defined in the [OpenMetrics](https://openmetrics.io/) standard but not implemented in the `prometheus-metrics-core` API. +These types are defined in the [OpenMetrics](https://openmetrics.io/) standard but not implemented +in the `prometheus-metrics-core` API. However, `prometheus-metrics-model` implements the underlying data model for these types. -To use these types, you need to implement your own `Collector` where the `collect()` method returns an `UnknownSnapshot` or a `HistogramSnapshot` with `.gaugeHistogram(true)`. +To use these types, you need to implement your own `Collector` where the `collect()` method returns +an `UnknownSnapshot` or a `HistogramSnapshot` with `.gaugeHistogram(true)`. diff --git a/docs/content/getting-started/multi-target.md b/docs/content/getting-started/multi-target.md index 93e37d9af..16f85ac40 100644 --- a/docs/content/getting-started/multi-target.md +++ b/docs/content/getting-started/multi-target.md @@ -7,108 +7,118 @@ weight: 7 This is for the upcoming release 1.1.0. {{< /hint >}} -To support multi-target pattern you can create a custom collector overriding the purposed internal method in ExtendedMultiCollector +To support multi-target pattern you can create a custom collector overriding the purposed internal +method in ExtendedMultiCollector see SampleExtendedMultiCollector in io.prometheus.metrics.examples.httpserver + + ```java public class SampleExtendedMultiCollector extends ExtendedMultiCollector { - public SampleExtendedMultiCollector() { - super(); - } - - @Override - protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { - - GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); - gaugeBuilder.name("x_load").help("process load"); - - CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); - counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); - - String[] targetNames = scrapeRequest.getParameterValues("target"); - String targetName; - String[] procs = scrapeRequest.getParameterValues("proc"); - if (targetNames == null || targetNames.length == 0) { - targetName = "defaultTarget"; - procs = null; //ignore procs param - } else { - targetName = targetNames[0]; - } - Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); - io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); - Labels lbls = Labels.of("target", targetName); - - if (procs == null || procs.length == 0) { - counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); - gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); - counterDataPointBuilder.value(70); - gaugeDataPointBuilder.value(Math.random()); - - counterBuilder.dataPoint(counterDataPointBuilder.build()); - gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); - - } else { - for (int i = 0; i < procs.length; i++) { - counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); - gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); - counterDataPointBuilder.value(Math.random()); - gaugeDataPointBuilder.value(Math.random()); - - counterBuilder.dataPoint(counterDataPointBuilder.build()); - gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); - } - } - Collection snaps = new ArrayList(); - snaps.add(counterBuilder.build()); - snaps.add(gaugeBuilder.build()); - MetricSnapshots msnaps = new MetricSnapshots(snaps); - return msnaps; - } - - public List getPrometheusNames() { - List names = new ArrayList(); - names.add("x_calls_total"); - names.add("x_load"); - return names; - } + public SampleExtendedMultiCollector() { + super(); + } + + @Override + protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) { + + GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder(); + gaugeBuilder.name("x_load").help("process load"); + + CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder(); + counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations"); + + String[] targetNames = scrapeRequest.getParameterValues("target"); + String targetName; + String[] procs = scrapeRequest.getParameterValues("proc"); + if (targetNames == null || targetNames.length == 0) { + targetName = "defaultTarget"; + procs = null; //ignore procs param + } else { + targetName = targetNames[0]; + } + Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder(); + io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder(); + Labels lbls = Labels.of("target", targetName); + + if (procs == null || procs.length == 0) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc"))); + counterDataPointBuilder.value(70); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + + } else { + for (int i = 0; i < procs.length; i++) { + counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i]))); + counterDataPointBuilder.value(Math.random()); + gaugeDataPointBuilder.value(Math.random()); + + counterBuilder.dataPoint(counterDataPointBuilder.build()); + gaugeBuilder.dataPoint(gaugeDataPointBuilder.build()); + } + } + Collection snaps = new ArrayList(); + snaps.add(counterBuilder.build()); + snaps.add(gaugeBuilder.build()); + MetricSnapshots msnaps = new MetricSnapshots(snaps); + return msnaps; + } + + public List getPrometheusNames() { + List names = new ArrayList(); + names.add("x_calls_total"); + names.add("x_load"); + return names; + } } ``` -`PrometheusScrapeRequest` provides methods to access http-related infos from the request originally received by the endpoint + + + +`PrometheusScrapeRequest` provides methods to access http-related infos from the request originally +received by the endpoint ```java public interface PrometheusScrapeRequest { - String getRequestURI(); + String getRequestURI(); - String[] getParameterValues(String name); + String[] getParameterValues(String name); } ``` - Sample Prometheus scrape_config +```yaml +- job_name: "multi-target" + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + params: + proc: [proc1, proc2] + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - source_labels: [__param_target] + target_label: instance + - target_label: __address__ + replacement: localhost:9401 + static_configs: + - targets: ["target1", "target2"] ``` - - job_name: "multi-target" - - # metrics_path defaults to '/metrics' - # scheme defaults to 'http'. - params: - proc: [proc1, proc2] - relabel_configs: - - source_labels: [__address__] - target_label: __param_target - - source_labels: [__param_target] - target_label: instance - - target_label: __address__ - replacement: localhost:9401 - static_configs: - - targets: ["target1", "target2"] -``` + It's up to the specific MultiCollector implementation how to interpret the _target_ parameter. -It might be an explicit real target (i.e. via host name/ip address) or as an alias in some internal configuration. -The latter is more suitable when the MultiCollector implementation is a proxy (see https://github.com/prometheus/snmp_exporter) -In this case, invoking real target might require extra parameters (e.g. credentials) that might be complex to manage in Prometheus configuration +It might be an explicit real target (i.e. via host name/ip address) or as an alias in some internal +configuration. +The latter is more suitable when the MultiCollector implementation is a proxy ( +see ) +In this case, invoking real target might require extra parameters (e.g. credentials) that might be +complex to manage in Prometheus configuration (not considering the case where the proxy might become an "open relay") diff --git a/docs/content/getting-started/performance.md b/docs/content/getting-started/performance.md index 43e95c430..31b8de162 100644 --- a/docs/content/getting-started/performance.md +++ b/docs/content/getting-started/performance.md @@ -5,10 +5,10 @@ weight: 6 This section has tips on how to use the Prometheus Java client in high performance applications. -Specify Label Values Only Once ------------------------------- +## Specify Label Values Only Once -For high performance applications, we recommend to specify label values only once, and then use the data point directly. +For high performance applications, we recommend to specify label values only once, and then use the +data point directly. This applies to all metric types. Let's use a counter as an example here: @@ -26,7 +26,8 @@ You could increment the counter above like this: requestCount.labelValue("/", "200").inc(); ``` -However, the line above does not only increment the counter, it also looks up the label values to find the right data point. +However, the line above does not only increment the counter, it also looks up the label values to +find the right data point. In high performance applications you can optimize this by looking up the data point only once: @@ -40,16 +41,21 @@ Now, you can increment the data point directly, which is a highly optimized oper successfulCalls.inc(); ``` -Enable Only One Histogram Representation ----------------------------------------- +## Enable Only One Histogram Representation -By default, histograms maintain two representations under the hood: The classic histogram representation with static buckets, and the native histogram representation with dynamic buckets. +By default, histograms maintain two representations under the hood: The classic histogram +representation with static buckets, and the native histogram representation with dynamic buckets. -While this default provides the flexibility to scrape different representations at runtime, it comes at a cost, because maintaining multiple representations causes performance overhead. +While this default provides the flexibility to scrape different representations at runtime, it comes +at a cost, because maintaining multiple representations causes performance overhead. -In performance critical applications we recommend to use either the classic representation or the native representation, but not both. +In performance critical applications we recommend to use either the classic representation or the +native representation, but not both. -You can either configure this in code for each histogram by calling [classicOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#classicOnly()) or [nativeOnly()](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.Builder.html#nativeOnly()), or you use the corresponding [config options](../../config/config/). +You can either configure this in code for each histogram by +calling [classicOnly()]() +or [nativeOnly()](), +or you use the corresponding [config options]({{< relref "../config/config.md" >}}). One way to do this is with system properties in the command line when you start your application @@ -63,7 +69,10 @@ or java -Dio.prometheus.metrics.histogramNativeOnly=true my-app.jar ``` -If you don't want to add a command line parameter every time you start your application, you can add a `prometheus.properties` file to your classpath (put it in the `src/main/resources/` directory so that it gets packed into your JAR file). The `prometheus.properties` file should have the following line: +If you don't want to add a command line parameter every time you start your application, you can add +a `prometheus.properties` file to your classpath (put it in the `src/main/resources/` directory so +that it gets packed into your JAR file). The `prometheus.properties` file should have the following +line: ```properties io.prometheus.metrics.histogramClassicOnly=true @@ -75,4 +84,5 @@ or io.prometheus.metrics.histogramNativeOnly=true ``` -Future releases will add more configuration options, like support for configuration via environment variable`IO_PROMETHEUS_METRICS_HISTOGRAM_NATIVE_ONLY=true`. +Future releases will add more configuration options, like support for configuration via environment +variable`IO_PROMETHEUS_METRICS_HISTOGRAM_NATIVE_ONLY=true`. diff --git a/docs/content/getting-started/quickstart.md b/docs/content/getting-started/quickstart.md index 27b7c13f5..7974b26c9 100644 --- a/docs/content/getting-started/quickstart.md +++ b/docs/content/getting-started/quickstart.md @@ -7,22 +7,26 @@ This tutorial shows the quickest way to get started with the Prometheus Java met {{< toc >}} -# Dependencies +## Dependencies We use the following dependencies: -* `prometheus-metrics-core` is the actual metrics library. -* `prometheus-metrics-instrumentation-jvm` provides out-of-the-box JVM metrics. -* `prometheus-metrics-exporter-httpserver` is a standalone HTTP server for exposing Prometheus metrics. -{{< tabs "deps" >}} -{{< tab "Gradle" >}} -``` +- `prometheus-metrics-core` is the actual metrics library. +- `prometheus-metrics-instrumentation-jvm` provides out-of-the-box JVM metrics. +- `prometheus-metrics-exporter-httpserver` is a standalone HTTP server for exposing Prometheus + metrics. + {{< tabs "deps" >}} + {{< tab "Gradle" >}} + +```groovy implementation 'io.prometheus:prometheus-metrics-core:$version' implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm:$version' implementation 'io.prometheus:prometheus-metrics-exporter-httpserver:$version' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -40,25 +44,29 @@ implementation 'io.prometheus:prometheus-metrics-exporter-httpserver:$version' $version ``` + {{< /tab >}} {{< /tabs >}} -There are alternative exporters as well, for example if you are using a Servlet container like Tomcat or Undertow you might want to use `prometheus-exporter-servlet-jakarta` rather than a standalone HTTP server. +There are alternative exporters as well, for example if you are using a Servlet container like +Tomcat or Undertow you might want to use `prometheus-exporter-servlet-jakarta` rather than a +standalone HTTP server. {{< hint type=note >}} If you do not use the protobuf exposition format, you can -[exclude](../../exporters/formats#exclude-protobuf-exposition-format) +[exclude]({{< relref "quickstart.md#exclude-protobuf-exposition-format" >}}) it from the dependencies. {{< /hint >}} -# Dependency management +## Dependency management A Bill of Material -([BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms)) +([BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms)) ensures that versions of dependencies (including transitive ones) are aligned. -This is especially important when using Spring Boot, which manages some of the dependencies of the project. +This is especially important when using Spring Boot, which manages some of the dependencies of the +project. You should omit the version number of the dependencies in your build file if you are using a BOM. @@ -138,7 +146,7 @@ The following example shows how to import the Prometheus Java metrics BOMs using {{< /tab >}} {{< /tabs >}} -# Example Application +## Example Application ```java import io.prometheus.metrics.core.metrics.Counter; @@ -167,34 +175,38 @@ public class App { .port(9400) .buildAndStart(); - System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + System.out.println("HTTPServer listening on port http://localhost:" + + server.getPort() + "/metrics"); Thread.currentThread().join(); // sleep forever } } ``` -# Result +## Result -Run the application and view [http://localhost:9400/metrics](http://localhost:9400/metrics) with your browser to see the raw metrics. You should see the `my_count_total` metric as shown below plus the `jvm_` and `process_` metrics coming from `JvmMetrics`. +Run the application and view [http://localhost:9400/metrics](http://localhost:9400/metrics) with +your browser to see the raw metrics. You should see the `my_count_total` metric as shown below plus +the `jvm_` and `process_` metrics coming from `JvmMetrics`. -``` +```text # HELP my_count_total example counter # TYPE my_count_total counter my_count_total{status="error"} 1.0 my_count_total{status="ok"} 2.0 ``` -# Prometheus Configuration +## Prometheus Configuration -To scrape the metrics with a Prometheus server, download the latest Prometheus server [release](https://github.com/prometheus/prometheus/releases), and configure the `prometheus.yml` file as follows: +To scrape the metrics with a Prometheus server, download the latest Prometheus +server [release](https://github.com/prometheus/prometheus/releases), and configure the +`prometheus.yml` file as follows: ```yaml global: scrape_interval: 10s # short interval for manual testing scrape_configs: - - job_name: "java-example" static_configs: - targets: ["localhost:9400"] diff --git a/docs/content/getting-started/registry.md b/docs/content/getting-started/registry.md index 7ae1bcbff..afebbb304 100644 --- a/docs/content/getting-started/registry.md +++ b/docs/content/getting-started/registry.md @@ -3,10 +3,10 @@ title: Registry weight: 2 --- -In order to expose metrics, you need to register them with a `PrometheusRegistry`. We are using a counter as an example here, but the `register()` method is the same for all metric types. +In order to expose metrics, you need to register them with a `PrometheusRegistry`. We are using a +counter as an example here, but the `register()` method is the same for all metric types. -Registering a Metrics with the Default Registry ------------------------------------------------ +## Registering a Metrics with the Default Registry ```java Counter eventsTotal = Counter.builder() @@ -15,10 +15,10 @@ Counter eventsTotal = Counter.builder() .register(); // <-- implicitly uses PrometheusRegistry.defaultRegistry ``` -The `register()` call above builds the counter and registers it with the global static `PrometheusRegistry.defaultRegistry`. Using the default registry is recommended. +The `register()` call above builds the counter and registers it with the global static +`PrometheusRegistry.defaultRegistry`. Using the default registry is recommended. -Registering a Metrics with a Custom Registry --------------------------------------------- +## Registering a Metrics with a Custom Registry You can also register your metric with a custom registry: @@ -31,10 +31,10 @@ Counter eventsTotal = Counter.builder() .register(myRegistry); ``` -Registering a Metric with Multiple Registries ---------------------------------------------- +## Registering a Metric with Multiple Registries -As an alternative to calling `register()` directly, you can `build()` metrics without registering them, +As an alternative to calling `register()` directly, you can `build()` metrics without registering +them, and register them later: ```java @@ -51,7 +51,7 @@ Counter eventsTotal = Counter.builder() PrometheusRegistry.defaultRegistry.register(eventsTotal); // register the counter with a custom registry. -// This is ok, you can register a metric with multiple registries. +// This is OK, you can register a metric with multiple registries. PrometheusRegistry myRegistry = new PrometheusRegistry(); myRegistry.register(eventsTotal); @@ -60,10 +60,10 @@ myRegistry.register(eventsTotal); Custom registries are useful if you want to maintain different scopes of metrics, like a debug registry with a lot of metrics, and a default registry with only a few metrics. -IllegalArgumentException: Duplicate Metric Name in Registry ------------------------------------------------------------ +## IllegalArgumentException: Duplicate Metric Name in Registry -While it is ok to register the same metric with multiple registries, it is illegal to register the same metric name multiple times with the same registry. +While it is OK to register the same metric with multiple registries, it is illegal to register the +same metric name multiple times with the same registry. The following code will throw an `IllegalArgumentException`: ```java @@ -75,13 +75,13 @@ Counter eventsTotal1 = Counter.builder() Counter eventsTotal2 = Counter.builder() .name("events_total") .help("Total number of events") - .register(); // <-- IllegalArgumentException, because a metric with that name is already registered + .register(); // IllegalArgumentException, because a metric with that name is already registered ``` -Unregistering a Metric ----------------------- +## Unregistering a Metric -There is no automatic expiry of unused metrics (yet), once a metric is registered it will remain registered forever. +There is no automatic expiry of unused metrics (yet), once a metric is registered it will remain +registered forever. However, you can programmatically unregistered an obsolete metric like this: diff --git a/docs/content/instrumentation/caffeine.md b/docs/content/instrumentation/caffeine.md index dde7e561a..104a9b9fa 100644 --- a/docs/content/instrumentation/caffeine.md +++ b/docs/content/instrumentation/caffeine.md @@ -8,11 +8,14 @@ provided by caffeine `Cache` objects into prometheus metrics. {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-instrumentation-caffeine:1.3.2' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -20,17 +23,18 @@ implementation 'io.prometheus:prometheus-metrics-instrumentation-caffeine:1.3.2' 1.3.2 ``` + {{< /tab >}} {{< /tabs >}} In order to collect metrics: - * A single `CacheMetricsCollector` instance must be registered with the registry; - * Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; - * The `Cache` object must be instantiated with the `recordStats()` option, and then added to the - `CacheMetricsCollector` instance with a unique name, which will be used as the value of the - `cache` label on the exported metrics; - * If the `recordStats` option is not set, most metrics will only return zero values; +- A single `CacheMetricsCollector` instance must be registered with the registry; + - Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; +- The `Cache` object must be instantiated with the `recordStats()` option, and then added to the + `CacheMetricsCollector` instance with a unique name, which will be used as the value of the + `cache` label on the exported metrics; + - If the `recordStats` option is not set, most metrics will only return zero values; ```java var cache = Caffeine.newBuilder().recordStats().build(); @@ -48,12 +52,11 @@ does not exist, i.e. a constructor call `new CacheMetricsCollector()` is the onl All example metrics on this page will use the `mycache` label value. -Generic Cache Metrics ---------------------- +## Generic Cache Metrics For all cache instances, the following metrics will be available: -``` +```text # TYPE caffeine_cache_hit counter # HELP caffeine_cache_hit Cache hit totals caffeine_cache_hit_total{cache="mycache"} 10.0 @@ -71,14 +74,13 @@ caffeine_cache_eviction_total{cache="mycache"} 1.0 caffeine_cache_estimated_size{cache="mycache"} 5.0 ``` -Loading Cache Metrics ---------------------- +## Loading Cache Metrics If the cache is an instance of `LoadingCache`, i.e. it is built with a `loader` function that is managed by the cache library, then metrics for observing load time and load failures become available: -``` +```text # TYPE caffeine_cache_load_failure counter # HELP caffeine_cache_load_failure Cache load failures caffeine_cache_load_failure_total{cache="mycache"} 10.0 @@ -91,14 +93,14 @@ caffeine_cache_load_duration_seconds_count{cache="mycache"} 7.0 caffeine_cache_load_duration_seconds_sum{cache="mycache"} 0.0034 ``` -Weighted Cache Metrics ----------------------- +## Weighted Cache Metrics Two metrics exist for observability specifically of caches that define a `weigher`: -``` +```text # TYPE caffeine_cache_eviction_weight counter -# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries +# HELP caffeine_cache_eviction_weight Weight of evicted cache entries, doesn't include manually removed entries // editorconfig-checker-disable-line + caffeine_cache_eviction_weight_total{cache="mycache"} 5.0 # TYPE caffeine_cache_weighted_size gauge # HELP caffeine_cache_weighted_size Approximate accumulated weight of cache entries @@ -113,14 +115,14 @@ caffeine_cache_weighted_size{cache="mycache"} 30.0 Up to version 1.3.5 and older, the weighted metrics had a different behavior: - * `caffeine_cache_weighted_size` was not implemented; - * `caffeine_cache_eviction_weight` was exposed as a `gauge`; +- `caffeine_cache_weighted_size` was not implemented; +- `caffeine_cache_eviction_weight` was exposed as a `gauge`; It is possible to restore the behavior of version 1.3.5 and older, by either: - * Using the deprecated `new CacheMetricsCollector()` constructor; - * Using the flags provided on the `CacheMetricsCollector.Builder` object to opt-out of each of the - elements of the post-1.3.5 behavior: - * `builder.collectWeightedSize(false)` will disable collection of `caffeine_cache_weighted_size`; - * `builder.collectEvictionWeightAsCounter(false)` will expose `caffeine_cache_eviction_weight` as - a `gauge` metric; +- Using the deprecated `new CacheMetricsCollector()` constructor; +- Using the flags provided on the `CacheMetricsCollector.Builder` object to opt-out of each of the + elements of the post-1.3.5 behavior: + - `builder.collectWeightedSize(false)` will disable collection of `caffeine_cache_weighted_size`; + - `builder.collectEvictionWeightAsCounter(false)` will expose `caffeine_cache_eviction_weight` as + a `gauge` metric; diff --git a/docs/content/instrumentation/guava.md b/docs/content/instrumentation/guava.md index 33cadae97..ffc8f0ab2 100644 --- a/docs/content/instrumentation/guava.md +++ b/docs/content/instrumentation/guava.md @@ -8,11 +8,14 @@ provided by Guava `Cache` objects into prometheus metrics. {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-instrumentation-guava:1.3.2' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -20,17 +23,18 @@ implementation 'io.prometheus:prometheus-metrics-instrumentation-guava:1.3.2' 1.3.2 ``` + {{< /tab >}} {{< /tabs >}} In order to collect metrics: -* A single `CacheMetricsCollector` instance must be registered with the registry; - * Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; -* The `Cache` object must be instantiated with the `recordStats()` option, and then added to the +- A single `CacheMetricsCollector` instance must be registered with the registry; + - Multiple `CacheMetricsCollector` instances cannot be registered with the same registry; +- The `Cache` object must be instantiated with the `recordStats()` option, and then added to the `CacheMetricsCollector` instance with a unique name, which will be used as the value of the `cache` label on the exported metrics; - * If the `recordStats` option is not set, most metrics will only return zero values; + - If the `recordStats` option is not set, most metrics will only return zero values; ```java var cache = CacheBuilder.newBuilder().recordStats().build(); @@ -41,12 +45,11 @@ cacheMetrics.addCache("mycache", cache); All example metrics on this page will use the `mycache` label value. -Generic Cache Metrics ---------------------- +## Generic Cache Metrics For all cache instances, the following metrics will be available: -``` +```text # TYPE guava_cache_hit counter # HELP guava_cache_hit Cache hit totals guava_cache_hit_total{cache="mycache"} 10.0 @@ -64,14 +67,13 @@ guava_cache_eviction_total{cache="mycache"} 1.0 guava_cache_size{cache="mycache"} 5.0 ``` -Loading Cache Metrics ---------------------- +## Loading Cache Metrics If the cache is an instance of `LoadingCache`, i.e. it is built with a `loader` function that is managed by the cache library, then metrics for observing load time and load failures become available: -``` +```text # TYPE guava_cache_load_failure counter # HELP guava_cache_load_failure Cache load failures guava_cache_load_failure_total{cache="mycache"} 10.0 diff --git a/docs/content/instrumentation/jvm.md b/docs/content/instrumentation/jvm.md index 4b6f90cc7..804c1b09b 100644 --- a/docs/content/instrumentation/jvm.md +++ b/docs/content/instrumentation/jvm.md @@ -3,15 +3,19 @@ title: JVM weight: 1 --- -The JVM instrumentation module provides a variety of out-of-the-box JVM and process metrics. To use it, add the following dependency: +The JVM instrumentation module provides a variety of out-of-the-box JVM and process metrics. To use +it, add the following dependency: {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm:1.0.0' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -19,6 +23,7 @@ implementation 'io.prometheus:prometheus-metrics-instrumentation-jvm:1.0.0' 1.0.0 ``` + {{< /tab >}} {{< /tabs >}} @@ -28,16 +33,23 @@ Now, you can register the JVM metrics as follows: JvmMetrics.builder().register(); ``` -The line above will initialize all JVM metrics and register them with the default registry. If you want to register the metrics with a custom `PrometheusRegistry`, you can pass the registry as parameter to the `register()` call. +The line above will initialize all JVM metrics and register them with the default registry. If you +want to register the metrics with a custom `PrometheusRegistry`, you can pass the registry as +parameter to the `register()` call. -The sections below describe the individual classes providing JVM metrics. If you don't want to register all JVM metrics, you can register each of these classes individually rather than using `JvmMetrics`. +The sections below describe the individual classes providing JVM metrics. If you don't want to +register all JVM metrics, you can register each of these classes individually rather than using +`JvmMetrics`. -JVM Buffer Pool Metrics ------------------------ +## JVM Buffer Pool Metrics -JVM buffer pool metrics are provided by the [JvmBufferPoolMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.html) class. The data is coming from the [BufferPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/BufferPoolMXBean.html). Example metrics: +JVM buffer pool metrics are provided by +the [JvmBufferPoolMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmBufferPoolMetrics.html) +class. The data is coming from +the [BufferPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/BufferPoolMXBean.html). +Example metrics: -``` +```text # HELP jvm_buffer_pool_capacity_bytes Bytes capacity of a given JVM buffer pool. # TYPE jvm_buffer_pool_capacity_bytes gauge jvm_buffer_pool_capacity_bytes{pool="direct"} 8192.0 @@ -52,12 +64,17 @@ jvm_buffer_pool_used_bytes{pool="direct"} 8192.0 jvm_buffer_pool_used_bytes{pool="mapped"} 0.0 ``` -JVM Class Loading Metrics -------------------------- +## JVM Class Loading Metrics -JVM class loading metrics are provided by the [JvmClassLoadingMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.html) class. The data is coming from the [ClassLoadingMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ClassLoadingMXBean.html). Example metrics: +JVM class loading metrics are provided by +the [JvmClassLoadingMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmClassLoadingMetrics.html) +class. The data is coming from +the [ClassLoadingMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ClassLoadingMXBean.html). +Example metrics: -``` + + +```text # HELP jvm_classes_currently_loaded The number of classes that are currently loaded in the JVM # TYPE jvm_classes_currently_loaded gauge jvm_classes_currently_loaded 1109.0 @@ -69,23 +86,35 @@ jvm_classes_loaded_total 1109.0 jvm_classes_unloaded_total 0.0 ``` -JVM Compilation Metrics ------------------------ + -JVM compilation metrics are provided by the [JvmCompilationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.html) class. The data is coming from the [CompilationMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/CompilationMXBean.html). Example metrics: +## JVM Compilation Metrics -``` +JVM compilation metrics are provided by +the [JvmCompilationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmCompilationMetrics.html) +class. The data is coming from +the [CompilationMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/CompilationMXBean.html). +Example metrics: + + + +```text # HELP jvm_compilation_time_seconds_total The total time in seconds taken for HotSpot class compilation # TYPE jvm_compilation_time_seconds_total counter jvm_compilation_time_seconds_total 0.152 ``` -JVM Garbage Collector Metrics ------------------------------ + -JVM garbage collector metrics are provided by the [JvmGarbageCollectorMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.html) class. The data is coming from the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). Example metrics: +## JVM Garbage Collector Metrics -``` +JVM garbage collector metrics are provided by +the [JvmGarbageCollectorMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmGarbageCollectorMetrics.html) +class. The data is coming from +the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). +Example metrics: + +```text # HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds. # TYPE jvm_gc_collection_seconds summary jvm_gc_collection_seconds_count{gc="PS MarkSweep"} 0 @@ -94,12 +123,18 @@ jvm_gc_collection_seconds_count{gc="PS Scavenge"} 0 jvm_gc_collection_seconds_sum{gc="PS Scavenge"} 0.0 ``` -JVM Memory Metrics ------------------- +## JVM Memory Metrics -JVM memory metrics are provided by the [JvmMemoryMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.html) class. The data is coming from the [MemoryMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryMXBean.html) and the [MemoryPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html). Example metrics: +JVM memory metrics are provided by +the [JvmMemoryMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryMetrics.html) +class. The data is coming from +the [MemoryMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryMXBean.html) +and the [MemoryPoolMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html). +Example metrics: -``` + + +```text # HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area. # TYPE jvm_memory_committed_bytes gauge jvm_memory_committed_bytes{area="heap"} 4.98597888E8 @@ -173,12 +208,20 @@ jvm_memory_used_bytes{area="heap"} 9051232.0 jvm_memory_used_bytes{area="nonheap"} 1.1490688E7 ``` -JVM Memory Pool Allocation Metrics ----------------------------------- + -JVM memory pool allocation metrics are provided by the [JvmMemoryPoolAllocationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.html) class. The data is obtained by adding a [NotificationListener](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/javax/management/NotificationListener.html) to the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). Example metrics: +## JVM Memory Pool Allocation Metrics -``` +JVM memory pool allocation metrics are provided by +the [JvmMemoryPoolAllocationMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmMemoryPoolAllocationMetrics.html) +class. The data is obtained by adding +a [NotificationListener](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/javax/management/NotificationListener.html) +to the [GarbageCollectorMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/GarbageCollectorMXBean.html). +Example metrics: + + + +```text # HELP jvm_memory_pool_allocated_bytes_total Total bytes allocated in a given JVM memory pool. Only updated after GC, not continuously. # TYPE jvm_memory_pool_allocated_bytes_total counter jvm_memory_pool_allocated_bytes_total{pool="Code Cache"} 4336448.0 @@ -189,24 +232,36 @@ jvm_memory_pool_allocated_bytes_total{pool="PS Old Gen"} 1428888.0 jvm_memory_pool_allocated_bytes_total{pool="PS Survivor Space"} 4115280.0 ``` -JVM Runtime Info Metric ------------------------ + +## JVM Runtime Info Metric -The JVM runtime info metric is provided by the [JvmRuntimeInfoMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.html) class. The data is obtained via system properties and will not change throughout the lifetime of the application. Example metric: +The JVM runtime info metric is provided by +the [JvmRuntimeInfoMetric](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmRuntimeInfoMetric.html) +class. The data is obtained via system properties and will not change throughout the lifetime of the +application. Example metric: -``` + + +```text # TYPE jvm_runtime info # HELP jvm_runtime JVM runtime info jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1 ``` -JVM Thread Metrics ------------------- + -JVM thread metrics are provided by the [JvmThreadsMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.html) class. The data is coming from the [ThreadMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ThreadMXBean.html). Example metrics: +## JVM Thread Metrics -``` +JVM thread metrics are provided by +the [JvmThreadsMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/JvmThreadsMetrics.html) +class. The data is coming from +the [ThreadMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/ThreadMXBean.html). +Example metrics: + + + +```text # HELP jvm_threads_current Current thread count of a JVM # TYPE jvm_threads_current gauge jvm_threads_current 10.0 @@ -236,12 +291,23 @@ jvm_threads_state{state="UNKNOWN"} 0.0 jvm_threads_state{state="WAITING"} 3.0 ``` -Process Metrics ---------------- + -Process metrics are provided by the [ProcessMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.html) class. The data is coming from the [OperatingSystemMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html), the [RuntimeMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/RuntimeMXBean.html), and from the `/proc/self/status` file on Linux. The metrics with prefix `process_` are not specific to Java, but should be provided by every Prometheus client library, see [Process Metrics](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) in the Prometheus [writing client libraries](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) documentation. Example metrics: +## Process Metrics -``` +Process metrics are provided by +the [ProcessMetrics](/client_java/api/io/prometheus/metrics/instrumentation/jvm/ProcessMetrics.html) +class. The data is coming from +the [OperatingSystemMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/OperatingSystemMXBean.html), +the [RuntimeMXBean](https://docs.oracle.com/en/java/javase/21/docs/api/java.management/java/lang/management/RuntimeMXBean.html), +and from the `/proc/self/status` file on Linux. The metrics with prefix `process_` are not specific +to Java, but should be provided by every Prometheus client library, +see [Process Metrics](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) +in the +Prometheus [writing client libraries](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics) +documentation. Example metrics: + +```text # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. # TYPE process_cpu_seconds_total counter process_cpu_seconds_total 1.63 diff --git a/docs/content/internals/model.md b/docs/content/internals/model.md index c1f1e7b6a..c54e79ee3 100644 --- a/docs/content/internals/model.md +++ b/docs/content/internals/model.md @@ -9,21 +9,36 @@ The illustration below shows the internal architecture of the Prometheus Java cl ## prometheus-metrics-core -This is the user facing metrics library, implementing the core metric types, like [Counter](/client_java/api/io/prometheus/metrics/core/metrics/Counter.html), [Gauge](/client_java/api/io/prometheus/metrics/core/metrics/Gauge.html) [Histogram](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.html), and so on. - -All metric types implement the [Collector](/client_java/api/io/prometheus/metrics/model/registry/Collector.html) interface, i.e. they provide a [collect()](/client_java/api/io/prometheus/metrics/model/registry/Collector.html#collect()) method to produce snapshots. +This is the user facing metrics library, implementing the core metric types, +like [Counter](/client_java/api/io/prometheus/metrics/core/metrics/Counter.html), +[Gauge](/client_java/api/io/prometheus/metrics/core/metrics/Gauge.html) +[Histogram](/client_java/api/io/prometheus/metrics/core/metrics/Histogram.html), +and so on. + +All metric types implement +the [Collector](/client_java/api/io/prometheus/metrics/model/registry/Collector.html) interface, +i.e. they provide +a [collect()]() +method to produce snapshots. ## prometheus-metrics-model -The model is an internal library, implementing read-only immutable snapshots. These snapshots are returned by the [Collector.collect()](/client_java/api/io/prometheus/metrics/model/registry/Collector.html#collect()) method. +The model is an internal library, implementing read-only immutable snapshots. These snapshots are +returned by +the [Collector.collect()]() +method. -There is no need for users to use `prometheus-metrics-model` directly. Users should use the API provided by `prometheus-metrics-core`, which includes the core metrics as well as callback metrics. +There is no need for users to use `prometheus-metrics-model` directly. Users should use the API +provided by `prometheus-metrics-core`, which includes the core metrics as well as callback metrics. -However, maintainers of 3rd party metrics libraries might want to use `prometheus-metrics-model` if they want to add Prometheus exposition formats to their metrics library. +However, maintainers of third-party metrics libraries might want to use `prometheus-metrics-model` +if they want to add Prometheus exposition formats to their metrics library. ## Exporters and exposition formats -The `prometheus-metrics-exposition-formats` module converts snapshots to Prometheus exposition formats, like text format, OpenMetrics text format, or Prometheus protobuf format. - -The exporters like `prometheus-metrics-exporter-httpserver` or `prometheus-metrics-exporter-servlet-jakarta` use this to convert snapshots into the right format depending on the `Accept` header in the scrape request. +The `prometheus-metrics-exposition-formats` module converts snapshots to Prometheus exposition +formats, like text format, OpenMetrics text format, or Prometheus protobuf format. +The exporters like `prometheus-metrics-exporter-httpserver` or +`prometheus-metrics-exporter-servlet-jakarta` use this to convert snapshots into the right format +depending on the `Accept` header in the scrape request. diff --git a/docs/content/migration/simpleclient.md b/docs/content/migration/simpleclient.md index 27606dbb6..6d0580571 100644 --- a/docs/content/migration/simpleclient.md +++ b/docs/content/migration/simpleclient.md @@ -3,34 +3,53 @@ title: Simpleclient weight: 1 --- -The Prometheus Java client library 1.0.0 is a complete rewrite of the underlying data model, and is not backwards compatible with releases 0.16.0 and older for a variety of reasons: - -* The old data model was based on [OpenMetrics](https://openmetrics.io). Native histograms don't fit with the OpenMetrics model because they don't follow the "every sample has exactly one double value" paradigm. It was a lot cleaner to implement a dedicated `prometheus-metrics-model` than trying to fit native histograms into the existing OpenMetrics-based model. -* Version 0.16.0 and older has multiple Maven modules sharing the same Java package name. This is not supported by the Java module system. To support users of Java modules, we renamed all packages and made sure no package is reused across multiple Maven modules. - -Migration using the Simpleclient Bridge ---------------------------------------- - -Good news: Users of version 0.16.0 and older do not need to refactor all their instrumentation code to get started with 1.0.0. - -We provide a migration module for bridging the old simpleclient `CollectorRegistry` to the new `PrometheusRegistry`. +The Prometheus Java client library 1.0.0 is a complete rewrite of the underlying data model, and is +not backward +compatible with releases 0.16.0 and older for a variety of reasons: + +- The old data model was based on [OpenMetrics](https://openmetrics.io). Native histograms don't fit + with the + OpenMetrics model because they don't follow the "every sample has exactly one double value" + paradigm. It was a lot + cleaner to implement a dedicated `prometheus-metrics-model` than trying to fit native histograms + into the existing + OpenMetrics-based model. +- Version 0.16.0 and older has multiple Maven modules sharing the same Java package name. This is + not supported by the + Java module system. To support users of Java modules, we renamed all packages and made sure no + package is reused + across multiple Maven modules. + +## Migration using the Simpleclient Bridge + +Good news: Users of version 0.16.0 and older do not need to refactor all their instrumentation code +to get started with +1.0.0. + +We provide a migration module for bridging the old simpleclient `CollectorRegistry` to the new +`PrometheusRegistry`. To use the bridge, add the following dependency: {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-simpleclient-bridge:1.0.0' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml + - io.prometheus - prometheus-metrics-simpleclient-bridge - 1.0.0 + io.prometheus + prometheus-metrics-simpleclient-bridge + 1.0.0 ``` + {{< /tab >}} {{< /tabs >}} @@ -40,7 +59,9 @@ Then add the following to your code: SimpleclientCollector.builder().register(); ``` -This will make all metrics registered with simpleclient's `CollectorRegistry.defaultRegistry` available in the new `PrometheusRegistry.defaultRegistry`. +This will make all metrics registered with simpleclient's `CollectorRegistry.defaultRegistry` +available in the new +`PrometheusRegistry.defaultRegistry`. If you are using custom registries, you can specify them like this: @@ -49,23 +70,27 @@ CollectorRegistry simpleclientRegistry = ...; PrometheusRegistry prometheusRegistry = ...; SimpleclientCollector.builder() - .collectorRegistry(simpleclientRegistry) - .register(prometheusRegistry); + .collectorRegistry(simpleclientRegistry) + .register(prometheusRegistry); ``` -Refactoring the Instrumentation Code ------------------------------------- +## Refactoring the Instrumentation Code -If you decide to get rid of the old 0.16.0 dependencies and use 1.0.0 only, you need to refactor your code: +If you decide to get rid of the old 0.16.0 dependencies and use 1.0.0 only, you need to refactor +your code: Dependencies: -* `simpleclient` -> `prometheus-metrics-core` -* `simpleclient_hotspot` -> `prometheus-metrics-instrumentation-jvm` -* `simpleclient_httpserver` -> `prometheus-metrics-exporter-httpserver` -* `simpleclient_servlet_jakarta` -> `prometheus-metrics-exporter-servlet-jakarta` +- `simpleclient` -> `prometheus-metrics-core` +- `simpleclient_hotspot` -> `prometheus-metrics-instrumentation-jvm` +- `simpleclient_httpserver` -> `prometheus-metrics-exporter-httpserver` +- `simpleclient_servlet_jakarta` -> `prometheus-metrics-exporter-servlet-jakarta` -As long as you are using high-level metric API like `Counter`, `Gauge`, `Histogram`, and `Summary` converting code to the new API is relatively straightforward. You will need to adapt the package name and apply some minor changes like using `builder()` instead of `build()` or using `labelValues()` instead of `labels()`. +As long as you are using high-level metric API like `Counter`, `Gauge`, `Histogram`, and `Summary` +converting code to +the new API is relatively straightforward. You will need to adapt the package name and apply some +minor changes like +using `builder()` instead of `build()` or using `labelValues()` instead of `labels()`. Example of the old 0.16.0 API: @@ -73,10 +98,10 @@ Example of the old 0.16.0 API: import io.prometheus.client.Counter; Counter counter = Counter.build() - .name("test") - .help("test counter") - .labelNames("path") - .register(); + .name("test") + .help("test counter") + .labelNames("path") + .register(); counter.labels("/hello-world").inc(); ``` @@ -87,20 +112,31 @@ Example of the new 1.0.0 API: import io.prometheus.metrics.core.metrics.Counter; Counter counter = Counter.builder() - .name("test") - .help("test counter") - .labelNames("path") - .register(); + .name("test") + .help("test counter") + .labelNames("path") + .register(); counter.labelValues("/hello-world").inc(); ``` -Reasons why we changed the API: Changing the package names was a necessity because the previous package names were incompatible with the Java module system. However, renaming packages requires changing code anyway, so we decided to clean up some things. For example, the name `builder()` for a builder method is very common in the Java ecosystem, it's used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library more aligned with the broader Java ecosystem. +Reasons why we changed the API: Changing the package names was a necessity because the previous +package names were +incompatible with the Java module system. However, renaming packages requires changing code anyway, +so we decided to +clean up some things. For example, the name `builder()` for a builder method is very common in the +Java ecosystem, it's +used in Spring, Lombok, and so on. So naming the method `builder()` makes the Prometheus library +more aligned with the +broader Java ecosystem. -If you are using the low level `Collector` API directly, you should have a look at the new callback metric types, see [/getting-started/callbacks/](../../getting-started/callbacks/). Chances are good that the new callback metrics have an easier way to achieve what you need than the old 0.16.0 code. +If you are using the low level `Collector` API directly, you should have a look at the new callback +metric types, +see [/getting-started/callbacks/]({{< relref "../getting-started/callbacks.md" >}}). Chances are +good that the new callback metrics have +an easier way to achieve what you need than the old 0.16.0 code. -JVM Metrics ------------ +## JVM Metrics Version 0.16.0 provided the `simpleclient_hotspot` module for exposing built-in JVM metrics: @@ -108,25 +144,30 @@ Version 0.16.0 provided the `simpleclient_hotspot` module for exposing built-in DefaultExports.initialize(); ``` -With version 1.0.0 these metrics moved to the `prometheus-metrics-instrumentation-jvm` module and are initialized as follows: +With version 1.0.0 these metrics moved to the `prometheus-metrics-instrumentation-jvm` module and +are initialized as follows: ```java JvmMetrics.builder().register(); ``` -A full list of the available JVM metrics can be found on [/instrumentation/jvm](../../instrumentation/jvm/). - -Most JVM metric names remained the same, except for a few cases where the old 0.16.0 metric names were not compliant with the [OpenMetrics](https://openmetrics.io) specification. OpenMetrics requires the unit to be a suffix, so we renamed metrics where the unit was in the middle of the metric name and moved the unit to the end of the metric name. The following metric names changed: - -* `jvm_memory_bytes_committed` -> `jvm_memory_committed_bytes` -* `jvm_memory_bytes_init` -> `jvm_memory_init_bytes` -* `jvm_memory_bytes_max` -> `jvm_memory_max_bytes` -* `jvm_memory_pool_bytes_committed` -> `jvm_memory_pool_committed_bytes` -* `jvm_memory_pool_bytes_init` -> `jvm_memory_pool_init_bytes` -* `jvm_memory_pool_bytes_max` -> `jvm_memory_pool_max_bytes` -* `jvm_memory_pool_bytes_used` -> `jvm_memory_pool_used_bytes` -* `jvm_memory_pool_collection_bytes_committed` -> `jvm_memory_pool_collection_committed_bytes` -* `jvm_memory_pool_collection_bytes_init` -> `jvm_memory_pool_collection_init_bytes` -* `jvm_memory_pool_collection_bytes_max` -> `jvm_memory_pool_collection_max_bytes` -* `jvm_memory_pool_collection_bytes_used` -> `jvm_memory_pool_collection_used_bytes` -* `jvm_info` -> `jvm_runtime_info` +A full list of the available JVM metrics can be found +on [/instrumentation/jvm]({{< relref "../instrumentation/jvm.md" >}}). + +Most JVM metric names remained the same, except for a few cases where the old 0.16.0 metric names +were not compliant with the [OpenMetrics](https://openmetrics.io) specification. OpenMetrics +requires the unit to be a suffix, so we renamed metrics where the unit was in the middle of the +metric name and moved the unit to the end of the metric name. The following metric names changed: + +- `jvm_memory_bytes_committed` -> `jvm_memory_committed_bytes` +- `jvm_memory_bytes_init` -> `jvm_memory_init_bytes` +- `jvm_memory_bytes_max` -> `jvm_memory_max_bytes` +- `jvm_memory_pool_bytes_committed` -> `jvm_memory_pool_committed_bytes` +- `jvm_memory_pool_bytes_init` -> `jvm_memory_pool_init_bytes` +- `jvm_memory_pool_bytes_max` -> `jvm_memory_pool_max_bytes` +- `jvm_memory_pool_bytes_used` -> `jvm_memory_pool_used_bytes` +- `jvm_memory_pool_collection_bytes_committed` -> `jvm_memory_pool_collection_committed_bytes` +- `jvm_memory_pool_collection_bytes_init` -> `jvm_memory_pool_collection_init_bytes` +- `jvm_memory_pool_collection_bytes_max` -> `jvm_memory_pool_collection_max_bytes` +- `jvm_memory_pool_collection_bytes_used` -> `jvm_memory_pool_collection_used_bytes` +- `jvm_info` -> `jvm_runtime_info` diff --git a/docs/content/otel/names.md b/docs/content/otel/names.md index 3d25dd3d4..2945d70e9 100644 --- a/docs/content/otel/names.md +++ b/docs/content/otel/names.md @@ -3,26 +3,40 @@ title: Names weight: 3 --- -OpenTelemetry naming conventions are different from Prometheus naming conventions. The mapping from OpenTelemetry metric names to Prometheus metric names is well defined in OpenTelemetry's [Prometheus and OpenMetrics Compatibility](https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/) spec, and the [OpenTelemetryExporter](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.html) implements that specification. +OpenTelemetry naming conventions are different from Prometheus naming conventions. The mapping from +OpenTelemetry metric names to Prometheus metric names is well defined in +OpenTelemetry's [Prometheus and OpenMetrics Compatibility](https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/) +spec, and +the [OpenTelemetryExporter](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.html) +implements that specification. -The goal is, if you set up a pipeline as illustrated below, you will see the same metric names in the Prometheus server as if you had exposed Prometheus metrics directly. +The goal is, if you set up a pipeline as illustrated below, you will see the same metric names in +the Prometheus server as if you had exposed Prometheus metrics directly. -![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) The main steps when converting OpenTelemetry metric names to Prometheus metric names are: -* Replace dots with underscores. -* If the metric has a unit, append the unit to the metric name, like `_seconds`. -* If the metric type has a suffix, append it, like `_total` for counters. +- Replace dots with underscores. +- If the metric has a unit, append the unit to the metric name, like `_seconds`. +- If the metric type has a suffix, append it, like `_total` for counters. -Dots in Metric and Label Names ------------------------------- +## Dots in Metric and Label Names -OpenTelemetry defines not only a line protocol, but also _semantic conventions_, i.e. standardized metric and label names. For example, OpenTelemetry's [Semantic Conventions for HTTP Metrics](https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/http-metrics/) say that if you instrument an HTTP server with OpenTelemetry, you must have a histogram named `http.server.duration`. +OpenTelemetry defines not only a line protocol, but also _semantic conventions_, i.e. standardized +metric and label names. For example, +OpenTelemetry's [Semantic Conventions for HTTP Metrics](https://opentelemetry.io/docs/specs/otel/metrics/semantic_conventions/http-metrics/) +say that if you instrument an HTTP server with OpenTelemetry, you must have a histogram named +`http.server.duration`. -Most names defined in semantic conventions use dots. In the Prometheus server, the dot is an illegal character (this might change in future versions of the Prometheus server). +Most names defined in semantic conventions use dots. In the Prometheus server, the dot is an illegal +character (this might change in future versions of the Prometheus server). -The Prometheus Java client library allows dots, so that you can use metric names and label names as defined in OpenTelemetry's semantic conventions. -The dots will automatically be replaced with underscores if you expose metrics in Prometheus format, but you will see the original names with dots if you push your metrics in OpenTelemetry format. +The Prometheus Java client library allows dots, so that you can use metric names and label names as +defined in OpenTelemetry's semantic conventions. +The dots will automatically be replaced with underscores if you expose metrics in Prometheus format, +but you will see the original names with dots if you push your metrics in OpenTelemetry format. -That way, you can use OTel-compliant metric and label names today when instrumenting your application with the Prometheus Java client, and you are prepared in case your monitoring backend adds features in the future that require OTel-compliant instrumentation. +That way, you can use OTel-compliant metric and label names today when instrumenting your +application with the Prometheus Java client, and you are prepared in case your monitoring backend +adds features in the future that require OTel-compliant instrumentation. diff --git a/docs/content/otel/otlp.md b/docs/content/otel/otlp.md index ea39f178f..2a6f8da9b 100644 --- a/docs/content/otel/otlp.md +++ b/docs/content/otel/otlp.md @@ -3,19 +3,23 @@ title: OTLP weight: 1 --- -The Prometheus Java client library allows you to push metrics to an OpenTelemetry endpoint using the OTLP protocol. +The Prometheus Java client library allows you to push metrics to an OpenTelemetry endpoint using the +OTLP protocol. -![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) +![Image of a with the Prometheus client library pushing metrics to an OpenTelemetry collector](/client_java/images/otel-pipeline.png) To implement this, you need to include `prometheus-metrics-exporter` as a dependency {{< tabs "uniqueid" >}} {{< tab "Gradle" >}} -``` + +```groovy implementation 'io.prometheus:prometheus-metrics-exporter-opentelemetry:1.0.0' ``` + {{< /tab >}} {{< tab "Maven" >}} + ```xml io.prometheus @@ -23,6 +27,7 @@ implementation 'io.prometheus:prometheus-metrics-exporter-opentelemetry:1.0.0' 1.0.0 ``` + {{< /tab >}} {{< /tabs >}} @@ -34,8 +39,23 @@ OpenTelemetryExporter.builder() .buildAndStart(); ``` -By default, the `OpenTelemetryExporter` will push metrics every 60 seconds to `localhost:4317` using `grpc` protocol. You can configure this in code using the [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html), or at runtime via [`io.prometheus.exporter.opentelemetry.*`](../../config/config/#exporter-opentelemetry-properties) properties. - -In addition to the Prometheus Java client configuration, the exporter also recognizes standard OpenTelemetry configuration. For example, you can set the [OTEL_EXPORTER_OTLP_METRICS_ENDPOINT](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/#otel_exporter_otlp_metrics_endpoint) environment variable to configure the endpoint. The Javadoc for [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html) shows which settings have corresponding OTel configuration. The intended use case is that if you attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) for tracing, and use the Prometheus Java client for metrics, it is sufficient to configure the OTel agent because the Prometheus library will pick up the same configuration. - -The [examples/example-exporter-opentelemetry](https://github.com/prometheus/client_java/tree/main/examples/example-exporter-opentelemetry) folder has a docker compose with a complete end-to-end example, including a Java app, the OTel collector, and a Prometheus server. +By default, the `OpenTelemetryExporter` will push metrics every 60 seconds to `localhost:4317` using +`grpc` protocol. You can configure this in code using +the [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html), +or at runtime via [`io.prometheus.exporter.opentelemetry.*`]({{< relref "../config/config.md#exporter-opentelemetry-properties" >}}) +properties. + +In addition to the Prometheus Java client configuration, the exporter also recognizes standard +OpenTelemetry configuration. For example, you can set +the [OTEL_EXPORTER_OTLP_METRICS_ENDPOINT](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration/#otel_exporter_otlp_metrics_endpoint) +environment variable to configure the endpoint. The Javadoc +for [OpenTelemetryExporter.Builder](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html) +shows which settings have corresponding OTel configuration. The intended use case is that if you +attach the +[OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) +for tracing, and use the Prometheus Java client for metrics, it is sufficient to configure the OTel +agent because the Prometheus library will pick up the same configuration. + +The [examples/example-exporter-opentelemetry](https://github.com/prometheus/client_java/tree/main/examples/example-exporter-opentelemetry) +folder has a docker compose with a complete end-to-end example, including a Java app, the OTel +collector, and a Prometheus server. diff --git a/docs/content/otel/tracing.md b/docs/content/otel/tracing.md index 406575a63..0e3fb72fa 100644 --- a/docs/content/otel/tracing.md +++ b/docs/content/otel/tracing.md @@ -3,9 +3,21 @@ title: Tracing weight: 2 --- -OpenTelemetry’s [vision statement](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md) says that [telemetry should be loosely coupled](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md#telemetry-should-be-loosely-coupled), allowing end users to pick and choose from the pieces they want without having to bring in the rest of the project, too. In that spirit, you might choose to instrument your Java application with the Prometheus Java client library for metrics, and attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) to get distributed tracing. +OpenTelemetry’s +[vision statement](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md) +says that +[telemetry should be loosely coupled](https://github.com/open-telemetry/community/blob/main/mission-vision-values.md#telemetry-should-be-loosely-coupled), +allowing end users to pick and choose from the pieces they want without having to bring in the rest +of the project, too. In that spirit, you might choose to instrument your Java application with the +Prometheus Java client library for metrics, and attach the +[OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) +to get distributed tracing. -First, if you attach the [OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) you might want to turn off OTel's built-in metrics, because otherwise you get metrics from both the Prometheus Java client library and the OpenTelemetry agent (technically it's no problem to get both metrics, it's just not a common use case). +First, if you attach the +[OpenTelemetry Java agent](https://github.com/open-telemetry/opentelemetry-java-instrumentation/) +you might want to turn off OTel's built-in metrics, because otherwise you get metrics from both the +Prometheus Java client library and the OpenTelemetry agent (technically it's no problem to get both +metrics, it's just not a common use case). ```bash # This will tell the OpenTelemetry agent not to send metrics, just traces and logs. @@ -18,19 +30,34 @@ Now, start your application with the OpenTelemetry Java agent attached for trace java -javaagent:path/to/opentelemetry-javaagent.jar -jar myapp.jar ``` -With the OpenTelemetry Java agent attached, the Prometheus client library will do a lot of magic under the hood. +With the OpenTelemetry Java agent attached, the Prometheus client library will do a lot of magic +under the hood. -* `service.name` and `service.instance.id` are used in OpenTelemetry to uniquely identify a service instance. The Prometheus client library will automatically use the same `service.name` and `service.instance.id` as the agent when pushing metrics in OpenTelemetry format. That way the monitoring backend will see that the metrics and the traces are coming from the same instance. -* Exemplars are added automatically if a Prometheus metric is updated in the context of a distributed OpenTelemetry trace. -* If a Span is used as an Exemplar, the Span is marked with the Span attribute `exemplar="true"`. This can be used in the OpenTelemetry's sampling policy to make sure Exemplars are always sampled. +- `service.name` and `service.instance.id` are used in OpenTelemetry to uniquely identify a service + instance. The Prometheus client library will automatically use the same `service.name` and + `service.instance.id` as the agent when pushing metrics in OpenTelemetry format. That way the + monitoring backend will see that the metrics and the traces are coming from the same instance. +- Exemplars are added automatically if a Prometheus metric is updated in the context of a + distributed OpenTelemetry trace. +- If a Span is used as an Exemplar, the Span is marked with the Span attribute `exemplar="true"`. + This can be used in the OpenTelemetry's sampling policy to make sure Exemplars are always sampled. -Here's more context on the `exemplar="true"` Span attribute: Many users of tracing libraries don't keep 100% of their trace data, because traces are very repetitive. It is very common to sample only 10% of traces and discard 90%. However, this can be an issue with Exemplars: In 90% of the cases Exemplars would point to a trace that has been thrown away. +Here's more context on the `exemplar="true"` Span attribute: Many users of tracing libraries don't +keep 100% of their trace data, because traces are very repetitive. It is very common to sample only +10% of traces and discard 90%. However, this can be an issue with Exemplars: In 90% of the cases +Exemplars would point to a trace that has been thrown away. -To solve this, the Prometheus Java client library annotates each Span that has been used as an Exemplar with the `exemplar="true"` Span attribute. +To solve this, the Prometheus Java client library annotates each Span that has been used as an +Exemplar with the `exemplar="true"` Span attribute. -The sampling policy in the OpenTelemetry collector can be configured to keep traces with this attribute. There's no risk that this results in a significant increase in trace data, because new Exemplars are only selected every [`minRetentionPeriodSeconds`](../../config/config/#exemplar-properties) seconds. +The sampling policy in the OpenTelemetry collector can be configured to keep traces with this +attribute. There's no risk that this results in a significant increase in trace data, because new +Exemplars are only selected every +[`minRetentionPeriodSeconds`]({{< relref "../config/config.md#exemplar-properties" >}}) seconds. -Here's an example of how to configure OpenTelemetry's [tail sampling processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/) to sample all Spans marked with `exemplar="true"`, and then discard 90% of the traces: +Here's an example of how to configure OpenTelemetry's +[tail sampling processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/) +to sample all Spans marked with `exemplar="true"`, and then discard 90% of the traces: ```yaml policies: @@ -38,14 +65,13 @@ policies: { name: keep-exemplars, type: string_attribute, - string_attribute: { key: "exemplar", values: [ "true" ] } - }, - { - name: keep-10-percent, - type: probabilistic, - probabilistic: { sampling_percentage: 10 } + string_attribute: { key: "exemplar", values: ["true"] }, }, + { name: keep-10-percent, type: probabilistic, probabilistic: { sampling_percentage: 10 } }, ] ``` -The [examples/example-exemplar-tail-sampling/](https://github.com/prometheus/client_java/tree/main/examples/example-exemplars-tail-sampling) directory has a complete end-to-end example, with a distributed Java application with two services, an OpenTelemetry collector, Prometheus, Tempo as a trace database, and Grafana dashboards. Use docker-compose as described in the example's README to run the example and explore the results. +The [examples/example-exemplar-tail-sampling/](https://github.com/prometheus/client_java/tree/main/examples/example-exemplars-tail-sampling) +directory has a complete end-to-end example, with a distributed Java application with two services, +an OpenTelemetry collector, Prometheus, Tempo as a trace database, and Grafana dashboards. Use +docker-compose as described in the example's readme to run the example and explore the results. diff --git a/docs/themes/hugo-geekdoc/data/assets.json b/docs/themes/hugo-geekdoc/data/assets.json index 9a34ed54d..81541fbbc 100644 --- a/docs/themes/hugo-geekdoc/data/assets.json +++ b/docs/themes/hugo-geekdoc/data/assets.json @@ -155,4 +155,4 @@ "src": "custom.css", "integrity": "sha512-1kALo+zc1L2u1rvyxPIew+ZDPWhnIA1Ei2rib3eHHbskQW+EMxfI9Ayyva4aV+YRrHvH0zFxvPSFIuZ3mfsbRA==" } -} \ No newline at end of file +} diff --git a/docs/themes/hugo-geekdoc/i18n/nl.yaml b/docs/themes/hugo-geekdoc/i18n/nl.yaml index 8e24d62a4..240bcea5a 100644 --- a/docs/themes/hugo-geekdoc/i18n/nl.yaml +++ b/docs/themes/hugo-geekdoc/i18n/nl.yaml @@ -36,7 +36,7 @@ posts_tagged_with: Alle berichten gemarkeerd met '{{ . }}' footer_build_with: > Gebouwd met Hugo en - + footer_legal_notice: Juridische mededeling footer_privacy_policy: Privacybeleid footer_content_license_prefix: > diff --git a/docs/themes/hugo-geekdoc/layouts/partials/language.html b/docs/themes/hugo-geekdoc/layouts/partials/language.html index fdcafd2b2..8ad972d07 100644 --- a/docs/themes/hugo-geekdoc/layouts/partials/language.html +++ b/docs/themes/hugo-geekdoc/layouts/partials/language.html @@ -1,4 +1,4 @@ -{{ if .Site.IsMultiLingual }} +{{ if .IsTranslated }}